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; }
/** * 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"); }
/** * replicates a locally created dialog to all the destinations * specified with the 'replicate_dialogs' modparam */ void replicate_dialog_created(struct dlg_cell *dlg) { int rc; bin_packet_t packet; dlg_lock_dlg(dlg); if (dlg->state != DLG_STATE_CONFIRMED_NA && dlg->state != DLG_STATE_CONFIRMED) { /* we don't need to replicate when in deleted state */ LM_WARN("not replicating dlg create message due to bad state %d (%.*s)\n", dlg->state, dlg->callid.len, dlg->callid.s); goto no_send; } if (dlg->replicated) { /* already created - must be a retransmission */ LM_DBG("not replicating retransmission for %p (%.*s)\n", dlg, dlg->callid.len, dlg->callid.s); goto no_send; } if (bin_init(&packet, &dlg_repl_cap, REPLICATION_DLG_CREATED, BIN_VERSION, 0) != 0) goto init_error; bin_push_dlg(&packet, dlg); dlg->replicated = 1; dlg_unlock_dlg(dlg); 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; case CLUSTERER_DEST_DOWN: LM_INFO("All destinations in cluster: %d are down or probing\n", dialog_repl_cluster); goto error; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", dialog_repl_cluster); goto error; } if_update_stat(dlg_enable_stats,create_sent,1); bin_free_packet(&packet); return; error: bin_free_packet(&packet); LM_ERR("Failed to replicate created dialog\n"); return; init_error: LM_ERR("Failed to replicate created dialog\n"); no_send: dlg_unlock_dlg(dlg); return; }
/** * replicates a local dialog update in the cluster */ void replicate_dialog_updated(struct dlg_cell *dlg) { int rc; bin_packet_t packet; dlg_lock_dlg(dlg); if (dlg->state == DLG_STATE_DELETED) { /* we no longer need to update anything */ LM_WARN("not replicating dlg update message due to bad state %d (%.*s)\n", dlg->state, dlg->callid.len, dlg->callid.s); goto end; } if (bin_init(&packet, &dlg_repl_cap, REPLICATION_DLG_UPDATED, BIN_VERSION, 0) != 0) goto init_error; bin_push_dlg(&packet, dlg); dlg->replicated = 1; dlg_unlock_dlg(dlg); 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; case CLUSTERER_DEST_DOWN: LM_ERR("All destinations in cluster: %d are down or probing\n", dialog_repl_cluster); goto error; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", dialog_repl_cluster); goto error; } if_update_stat(dlg_enable_stats,update_sent,1); bin_free_packet(&packet); return; error: LM_ERR("Failed to replicate updated dialog\n"); bin_free_packet(&packet); return; init_error: LM_ERR("Failed to replicate updated dialog\n"); end: dlg_unlock_dlg(dlg); return; }
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); }
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); }
int repl_prof_remove(str *name, str *value) { bin_packet_t packet; if (profile_repl_cluster <= 0) return 0; if (bin_init(&packet, &prof_repl_cap, REPLICATION_DLG_PROFILE, BIN_VERSION, 1024) < 0) { LM_ERR("cannot initiate bin buffer\n"); return -1; } if (repl_prof_add(&packet, name, value?1:0, value, 0) < 0) return -1; dlg_replicate_profiles(&packet); bin_free_packet(&packet); return 0; }
static void broadcast_profiles(utime_t ticks, void *param) { #define REPL_PROF_TRYSEND() \ do { \ nr++; \ if (ret > repl_prof_buffer_th) { \ /* send the buffer */ \ if (nr) \ dlg_replicate_profiles(&packet); \ bin_reset_back_pointer(&packet); \ nr = 0; \ } \ } while (0) struct dlg_profile_table *profile; map_iterator_t it; unsigned int count; int i; int nr = 0; int ret; void **dst; str *value; bin_packet_t packet; if (bin_init(&packet, &prof_repl_cap, REPLICATION_DLG_PROFILE, BIN_VERSION, 0) < 0) { LM_ERR("cannot initiate bin buffer\n"); return; } for (profile = profiles; profile; profile = profile->next) { if (!(profile->repl_type&REPL_PROTOBIN)) continue; count = 0; if (!profile->has_value) { count = noval_get_local_count(profile); if ((ret = repl_prof_add(&packet, &profile->name, 0, NULL, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); } else { for (i = 0; i < profile->size; i++) { lock_set_get(profile->locks, i); if (map_first(profile->entries[i], &it) < 0) { LM_ERR("map does not exist\n"); goto next_entry; } while (iterator_is_valid(&it)) { dst = iterator_val(&it); if (!dst || !*dst) { LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_val; } value = iterator_key(&it); if (!value) { LM_ERR("cannot retrieve profile's key\n"); goto next_val; } count = prof_val_get_local_count(dst); if ((ret = repl_prof_add(&packet, &profile->name, 1, value, count)) < 0) goto error; /* check if the profile should be sent */ REPL_PROF_TRYSEND(); next_val: if (iterator_next(&it) < 0) break; } next_entry: lock_set_release(profile->locks, i); } } } goto done; error: LM_ERR("cannot add any more profiles in buffer\n"); bin_free_packet(&packet); done: /* check if there is anything else left to replicate */ if (nr) dlg_replicate_profiles(&packet); bin_free_packet(&packet); #undef REPL_PROF_TRYSEND }
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); }
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); }