コード例 #1
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
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;
}
コード例 #2
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
/**
 * 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");
}
コード例 #3
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
/**
 * 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;
}
コード例 #4
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
/**
 * 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;
}
コード例 #5
0
ファイル: lb_replication.c プロジェクト: NormB/opensips
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);
}
コード例 #6
0
ファイル: ureplication.c プロジェクト: NormB/opensips
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);
}
コード例 #7
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
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;
}
コード例 #8
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
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
}
コード例 #9
0
ファイル: ratelimit_helper.c プロジェクト: OpenSIPS/opensips
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);
}
コード例 #10
0
ファイル: ureplication.c プロジェクト: NormB/opensips
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);
}