/** * replicates a local dialog delete event to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_deleted(struct dlg_cell *dlg) { int rc; bin_packet_t packet; if (bin_init(&packet, &dlg_repl_cap, REPLICATION_DLG_DELETED, BIN_VERSION, 1024) != 0) goto error; bin_push_str(&packet, &dlg->callid); bin_push_str(&packet, &dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&packet, &dlg->legs[callee_idx(dlg)].tag); rc = clusterer_api.send_all(&packet, dialog_repl_cluster); switch (rc) { case CLUSTERER_CURR_DISABLED: LM_INFO("Current node is disabled in cluster: %d\n", dialog_repl_cluster); goto error_free; case CLUSTERER_DEST_DOWN: LM_ERR("All destinations in cluster: %d are down or probing\n", dialog_repl_cluster); goto error_free; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", dialog_repl_cluster); goto error_free; } if_update_stat(dlg_enable_stats, delete_sent, 1); bin_free_packet(&packet); return; error_free: bin_free_packet(&packet); error: LM_ERR("Failed to replicate deleted dialog\n"); }
int send_shtag_active_info(str *tag_name, int node_id) { bin_packet_t packet; if (bin_init(&packet, &dlg_repl_cap, DLG_SHARING_TAG_ACTIVE, BIN_VERSION, 0) < 0) { LM_ERR("Failed to init bin packet"); return -1; } bin_push_str(&packet, tag_name); if (node_id) { if (clusterer_api.send_to(&packet, dialog_repl_cluster, node_id) != CLUSTERER_SEND_SUCCES) { bin_free_packet(&packet); return -1; } } else if (clusterer_api.send_all(&packet, dialog_repl_cluster) != CLUSTERER_SEND_SUCCES) { bin_free_packet(&packet); return -1; } bin_free_packet(&packet); return 0; }
void replicate_lb_status(struct lb_dst *dst) { bin_packet_t packet; int rc; if (bin_init(&packet, &status_repl_cap, REPL_LB_STATUS_UPDATE, BIN_VERSION, 0)!=0){ LM_ERR("failed to replicate this event\n"); return; } bin_push_int(&packet, dst->group); bin_push_str(&packet, &dst->uri); bin_push_int(&packet, dst->flags&LB_DST_STAT_MASK); rc = clusterer_api.send_all(&packet, lb_repl_cluster); switch (rc) { case CLUSTERER_CURR_DISABLED: LM_INFO("Current node is disabled in cluster: %d\n", lb_repl_cluster); break; case CLUSTERER_DEST_DOWN: LM_INFO("All destinations in cluster: %d are down or probing\n", lb_repl_cluster); break; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", lb_repl_cluster); break; } bin_free_packet(&packet); }
static int repl_prof_add(str *name, int has_value, str *value, unsigned int count) { int ret = 0; if (bin_push_str(name) < 0) return -1; /* extra size to add the value indication but it's good * for servers profiles consistency checks */ if (bin_push_int(has_value) < 0) return -1; /* the other end should already know if the profile has a value or not */ if (value && bin_push_str(value) < 0) return -1; if (bin_push_int(count) < 0) return -1; return ret; }
/** * replicates a local dialog delete event to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_deleted(struct dlg_cell *dlg) { struct replication_dest *d; static str module_name = str_init("dialog"); if (bin_init(&module_name, REPLICATION_DLG_DELETED) != 0) goto error; bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_idx(dlg)].tag); for (d = replication_dests; d; d = d->next) bin_send(&d->to); if_update_stat(dlg_enable_stats,delete_sent,1); return; error: LM_ERR("Failed to replicate deleted dialog\n"); }
/** * replicates a local dialog delete event to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_deleted(struct dlg_cell *dlg) { static str module_name = str_init("dialog"); if (bin_init(&module_name, REPLICATION_DLG_DELETED, BIN_VERSION) != 0) goto error; bin_push_int(clusterer_api.get_my_id()); bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_idx(dlg)].tag); if (clusterer_api.send_to(dialog_replicate_cluster, PROTO_BIN) < 0) { goto error; } return; error: LM_ERR("Failed to replicate deleted dialog\n"); }
void replicate_ucontact_delete(urecord_t *r, ucontact_t *c) { int rc; bin_packet_t packet; if (bin_init(&packet, &contact_repl_cap, REPL_UCONTACT_DELETE, BIN_VERSION, 0) != 0) { LM_ERR("failed to replicate this event\n"); return; } bin_push_str(&packet, r->domain); bin_push_str(&packet, &r->aor); bin_push_str(&packet, &c->c); bin_push_str(&packet, &c->callid); bin_push_int(&packet, c->cseq); if (cluster_mode == CM_FEDERATION_CACHEDB) rc = clusterer_api.send_all_having(&packet, location_cluster, NODE_CMP_EQ_SIP_ADDR); else rc = clusterer_api.send_all(&packet, location_cluster); switch (rc) { case CLUSTERER_CURR_DISABLED: LM_INFO("Current node is disabled in cluster: %d\n", location_cluster); goto error; case CLUSTERER_DEST_DOWN: LM_INFO("All destinations in cluster: %d are down or probing\n", location_cluster); goto error; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", location_cluster); goto error; } bin_free_packet(&packet); return; error: LM_ERR("replicate ucontact delete failed\n"); bin_free_packet(&packet); }
/** * replicates a local dialog delete event to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_deleted(struct dlg_cell *dlg) { struct replication_dest *d; static str module_name = str_init("dialog"); str send_buffer; if (bin_init(&module_name, REPLICATION_DLG_DELETED, BIN_VERSION) != 0) goto error; bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_idx(dlg)].tag); bin_get_buffer(&send_buffer); for (d = replication_dests; d; d = d->next) msg_send(0,PROTO_BIN,&d->to,0,send_buffer.s,send_buffer.len,0); if_update_stat(dlg_enable_stats,delete_sent,1); return; error: LM_ERR("Failed to replicate deleted dialog\n"); }
/** * replicates a local dialog update to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_updated(struct dlg_cell *dlg) { struct replication_dest *d; static str module_name = str_init("dialog"); int callee_leg; str *vars, *profiles; if (bin_init(&module_name, REPLICATION_DLG_UPDATED) != 0) goto error; callee_leg = callee_idx(dlg); bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_leg].tag); bin_push_str(&dlg->from_uri); bin_push_str(&dlg->to_uri); bin_push_int(dlg->h_id); bin_push_int(dlg->start_ts); bin_push_int(dlg->state); bin_push_str(&dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str); if (dlg->legs[callee_leg].bind_addr) bin_push_str(&dlg->legs[callee_leg].bind_addr->sock_str); else bin_push_str(NULL); bin_push_str(&dlg->legs[DLG_CALLER_LEG].r_cseq); bin_push_str(&dlg->legs[callee_leg].r_cseq); bin_push_str(&dlg->legs[DLG_CALLER_LEG].route_set); bin_push_str(&dlg->legs[callee_leg].route_set); bin_push_str(&dlg->legs[DLG_CALLER_LEG].contact); bin_push_str(&dlg->legs[callee_leg].contact); bin_push_str(&dlg->legs[callee_leg].from_uri); bin_push_str(&dlg->legs[callee_leg].to_uri); /* XXX: on shutdown only? */ vars = write_dialog_vars(dlg->vals); profiles = write_dialog_profiles(dlg->profile_links); bin_push_str(vars); bin_push_str(profiles); bin_push_int(dlg->user_flags); bin_push_int(dlg->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED)); bin_push_int((unsigned int)time(0) + dlg->tl.timeout - get_ticks()); bin_push_int(dlg->legs[DLG_CALLER_LEG].last_gen_cseq); bin_push_int(dlg->legs[callee_leg].last_gen_cseq); for (d = replication_dests; d; d = d->next) bin_send(&d->to); if_update_stat(dlg_enable_stats,update_sent,1); return; error: LM_ERR("Failed to replicate updated dialog\n"); }
void bin_push_dlg(bin_packet_t *packet, struct dlg_cell *dlg) { int callee_leg; str *vars, *profiles; callee_leg = callee_idx(dlg); bin_push_str(packet, &dlg->callid); bin_push_str(packet, &dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(packet, &dlg->legs[callee_leg].tag); bin_push_str(packet, &dlg->from_uri); bin_push_str(packet, &dlg->to_uri); bin_push_int(packet, dlg->h_id); bin_push_int(packet, dlg->start_ts); bin_push_int(packet, dlg->state); bin_push_str(packet, &dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str); if (dlg->legs[callee_leg].bind_addr) bin_push_str(packet, &dlg->legs[callee_leg].bind_addr->sock_str); else bin_push_str(packet, NULL); bin_push_str(packet, &dlg->legs[DLG_CALLER_LEG].r_cseq); bin_push_str(packet, &dlg->legs[callee_leg].r_cseq); bin_push_str(packet, &dlg->legs[DLG_CALLER_LEG].route_set); bin_push_str(packet, &dlg->legs[callee_leg].route_set); bin_push_str(packet, &dlg->legs[DLG_CALLER_LEG].contact); bin_push_str(packet, &dlg->legs[callee_leg].contact); bin_push_str(packet, &dlg->legs[callee_leg].from_uri); bin_push_str(packet, &dlg->legs[callee_leg].to_uri); /* give modules the chance to write values/profiles before replicating */ run_dlg_callbacks(DLGCB_WRITE_VP, dlg, NULL, DLG_DIR_NONE, NULL, 1); vars = write_dialog_vars(dlg->vals); profiles = write_dialog_profiles(dlg->profile_links); bin_push_str(packet, vars); bin_push_str(packet, profiles); bin_push_int(packet, dlg->user_flags); bin_push_int(packet, dlg->mod_flags); bin_push_int(packet, dlg->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED|DLG_FLAG_FROM_DB)); bin_push_int(packet, (unsigned int)time(0) + dlg->tl.timeout - get_ticks()); bin_push_int(packet, dlg->legs[DLG_CALLER_LEG].last_gen_cseq); bin_push_int(packet, dlg->legs[callee_leg].last_gen_cseq); }
void rl_timer_repl(utime_t ticks, void *param) { static str module_name = str_init("ratelimit"); unsigned int i = 0; map_iterator_t it; rl_pipe_t **pipe; str *key; int nr = 0; int ret; if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } /* iterate through each map */ for (i = 0; i < rl_htable.size; i++) { RL_GET_LOCK(i); /* iterate through all the entries */ if (map_first(rl_htable.maps[i], &it) < 0) { LM_ERR("map doesn't exist\n"); goto next_map; } for (; iterator_is_valid(&it);) { pipe = (rl_pipe_t **)iterator_val(&it); if (!pipe || !*pipe) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } /* ignore cachedb replicated stuff */ if (RL_USE_CDB(*pipe)) goto next_pipe; key = iterator_key(&it); if (!key) { LM_ERR("cannot retrieve pipe key\n"); goto next_pipe; } if (bin_push_str(key) < 0) goto error; if (bin_push_int((*pipe)->algo) < 0) goto error; if (bin_push_int((*pipe)->limit) < 0) goto error; if ((ret = bin_push_int((*pipe)->counter)) < 0) goto error; nr++; if (ret > rl_buffer_th) { /* send the buffer */ if (nr) rl_replicate(); if (bin_init(&module_name, RL_PIPE_COUNTER) < 0) { LM_ERR("cannot initiate bin buffer\n"); RL_RELEASE_LOCK(i); return; } nr = 0; } next_pipe: if (iterator_next(&it) < 0) break; } next_map: RL_RELEASE_LOCK(i); } /* if there is anything else to send, do it now */ if (nr) rl_replicate(); return; error: LM_ERR("cannot add pipe info in buffer\n"); RL_RELEASE_LOCK(i); if (nr) rl_replicate(); }
void rl_timer_repl(utime_t ticks, void *param) { unsigned int i = 0; map_iterator_t it; rl_pipe_t **pipe; str *key; int nr = 0; int ret; bin_packet_t packet; if (bin_init(&packet, &pipe_repl_cap, RL_PIPE_COUNTER, BIN_VERSION, 0) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } /* iterate through each map */ for (i = 0; i < rl_htable.size; i++) { RL_GET_LOCK(i); /* iterate through all the entries */ if (map_first(rl_htable.maps[i], &it) < 0) { LM_ERR("map doesn't exist\n"); goto next_map; } for (; iterator_is_valid(&it);) { pipe = (rl_pipe_t **) iterator_val(&it); if (!pipe || !*pipe) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } /* ignore cachedb replicated stuff */ if (RL_USE_CDB(*pipe)) goto next_pipe; key = iterator_key(&it); if (!key) { LM_ERR("cannot retrieve pipe key\n"); goto next_pipe; } if (bin_push_str(&packet, key) < 0) goto error; if (bin_push_int(&packet, (*pipe)->algo) < 0) goto error; if (bin_push_int(&packet, (*pipe)->limit) < 0) goto error; /* * for the SBT algorithm it is safe to replicate the current * counter, since it is always updating according to the window */ if ((ret = bin_push_int(&packet, ((*pipe)->algo == PIPE_ALGO_HISTORY ? (*pipe)->counter : (*pipe)->my_last_counter))) < 0) goto error; nr++; if (ret > rl_buffer_th) { /* send the buffer */ if (nr) rl_replicate(&packet); bin_reset_back_pointer(&packet); nr = 0; } next_pipe: if (iterator_next(&it) < 0) break; } next_map: RL_RELEASE_LOCK(i); } /* if there is anything else to send, do it now */ if (nr) rl_replicate(&packet); bin_free_packet(&packet); return; error: LM_ERR("cannot add pipe info in buffer\n"); RL_RELEASE_LOCK(i); if (nr) rl_replicate(&packet); bin_free_packet(&packet); }
static int receive_sync_request(int node_id) { bin_packet_t *sync_packet; dlist_t *dl; udomain_t *dom; map_iterator_t it; struct urecord *r; ucontact_t* c; str st; void **p; int i; for (dl = root; dl; dl = dl->next) { dom = dl->d; for(i = 0; i < dom->size; i++) { lock_ulslot(dom, i); for (map_first(dom->table[i].records, &it); iterator_is_valid(&it); iterator_next(&it)) { p = iterator_val(&it); if (p == NULL) goto error_unlock; r = (urecord_t *)*p; sync_packet = clusterer_api.sync_chunk_start(&contact_repl_cap, location_cluster, node_id); if (!sync_packet) goto error_unlock; /* urecord in this chunk */ bin_push_int(sync_packet, 0); bin_push_str(sync_packet, r->domain); bin_push_str(sync_packet, &r->aor); for (c = r->contacts; c; c = c->next) { sync_packet = clusterer_api.sync_chunk_start(&contact_repl_cap, location_cluster, node_id); if (!sync_packet) goto error_unlock; /* contact in this chunk */ bin_push_int(sync_packet, 1); bin_push_str(sync_packet, r->domain); bin_push_str(sync_packet, &r->aor); bin_push_str(sync_packet, &c->c); bin_push_str(sync_packet, &c->callid); bin_push_str(sync_packet, &c->user_agent); bin_push_str(sync_packet, &c->path); bin_push_str(sync_packet, &c->attr); bin_push_str(sync_packet, &c->received); bin_push_str(sync_packet, &c->instance); st.s = (char *)&c->expires; st.len = sizeof c->expires; bin_push_str(sync_packet, &st); st.s = (char *)&c->q; st.len = sizeof c->q; bin_push_str(sync_packet, &st); bin_push_str(sync_packet, c->sock?&c->sock->sock_str:NULL); bin_push_int(sync_packet, c->cseq); bin_push_int(sync_packet, c->flags); bin_push_int(sync_packet, c->cflags); bin_push_int(sync_packet, c->methods); st.s = (char *)&c->last_modified; st.len = sizeof c->last_modified; bin_push_str(sync_packet, &st); } } unlock_ulslot(dom, i); } } return 0; error_unlock: unlock_ulslot(dom, i); return -1; }
void replicate_ucontact_update(urecord_t *r, ucontact_t *ct) { str st; int rc; bin_packet_t packet; if (bin_init(&packet, &contact_repl_cap, REPL_UCONTACT_UPDATE, BIN_VERSION, 0) != 0) { LM_ERR("failed to replicate this event\n"); return; } bin_push_str(&packet, r->domain); bin_push_str(&packet, &r->aor); bin_push_str(&packet, &ct->c); bin_push_str(&packet, &ct->callid); bin_push_str(&packet, &ct->user_agent); bin_push_str(&packet, &ct->path); bin_push_str(&packet, &ct->attr); bin_push_str(&packet, &ct->received); bin_push_str(&packet, &ct->instance); st.s = (char *) &ct->expires; st.len = sizeof ct->expires; bin_push_str(&packet, &st); st.s = (char *) &ct->q; st.len = sizeof ct->q; bin_push_str(&packet, &st); bin_push_str(&packet, ct->sock?&ct->sock->sock_str:NULL); bin_push_int(&packet, ct->cseq); bin_push_int(&packet, ct->flags); bin_push_int(&packet, ct->cflags); bin_push_int(&packet, ct->methods); st.s = (char *)&ct->last_modified; st.len = sizeof ct->last_modified; bin_push_str(&packet, &st); st = store_serialize(ct->kv_storage); if (ZSTR(st)) LM_ERR("oom\n"); bin_push_str(&packet, &st); store_free_buffer(&st); if (cluster_mode == CM_FEDERATION_CACHEDB) rc = clusterer_api.send_all_having(&packet, location_cluster, NODE_CMP_EQ_SIP_ADDR); else rc = clusterer_api.send_all(&packet, location_cluster); switch (rc) { case CLUSTERER_CURR_DISABLED: LM_INFO("Current node is disabled in cluster: %d\n", location_cluster); goto error; case CLUSTERER_DEST_DOWN: LM_INFO("All destinations in cluster: %d are down or probing\n", location_cluster); goto error; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", location_cluster); goto error; } bin_free_packet(&packet); return; error: LM_ERR("replicate ucontact update failed\n"); bin_free_packet(&packet); }
/** * replicates a locally created dialog to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_created(struct dlg_cell *dlg) { static str module_name = str_init("dialog"); int callee_leg; str *vars, *profiles; if (bin_init(&module_name, REPLICATION_DLG_CREATED, BIN_VERSION) != 0) goto error; bin_push_int(clusterer_api.get_my_id()); callee_leg = callee_idx(dlg); bin_push_str(&dlg->callid); bin_push_str(&dlg->legs[DLG_CALLER_LEG].tag); bin_push_str(&dlg->legs[callee_leg].tag); bin_push_str(&dlg->from_uri); bin_push_str(&dlg->to_uri); bin_push_int(dlg->h_id); bin_push_int(dlg->start_ts); bin_push_int(dlg->state); bin_push_str(&dlg->legs[DLG_CALLER_LEG].bind_addr->sock_str); if (dlg->legs[callee_leg].bind_addr) bin_push_str(&dlg->legs[callee_leg].bind_addr->sock_str); else bin_push_str(NULL); bin_push_str(&dlg->legs[DLG_CALLER_LEG].r_cseq); bin_push_str(&dlg->legs[callee_leg].r_cseq); bin_push_str(&dlg->legs[DLG_CALLER_LEG].route_set); bin_push_str(&dlg->legs[callee_leg].route_set); bin_push_str(&dlg->legs[DLG_CALLER_LEG].contact); bin_push_str(&dlg->legs[callee_leg].contact); bin_push_str(&dlg->legs[callee_leg].from_uri); bin_push_str(&dlg->legs[callee_leg].to_uri); /* XXX: on shutdown only? */ vars = write_dialog_vars(dlg->vals); dlg_lock_dlg(dlg); profiles = write_dialog_profiles(dlg->profile_links); dlg_unlock_dlg(dlg); bin_push_str(vars); bin_push_str(profiles); bin_push_int(dlg->user_flags); bin_push_int(dlg->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED)); bin_push_int((unsigned int)time(0) + dlg->tl.timeout - get_ticks()); bin_push_int(dlg->legs[DLG_CALLER_LEG].last_gen_cseq); bin_push_int(dlg->legs[callee_leg].last_gen_cseq); if (clusterer_api.send_to(dialog_replicate_cluster, PROTO_BIN) < 0) goto error; if_update_stat(dlg_enable_stats,create_sent,1); return; error: LM_ERR("Failed to replicate created dialog\n"); }