コード例 #1
0
ファイル: dlg_replication.c プロジェクト: austin98x/opensips
/**
 * receive_binary_packet (callback) - receives a cmd_type, specifying the
 * purpose of the data encoded in the received UDP packet
 */
void receive_binary_packet(int info_type)
{
	int rc;

	LM_DBG("Received a binary packet!\n");

	switch (info_type) {
	case REPLICATION_DLG_CREATED:
		rc = dlg_replicated_create(NULL, NULL, NULL, 1);
		if_update_stat(dlg_enable_stats, create_recv, 1);
		break;

	case REPLICATION_DLG_UPDATED:
		rc = dlg_replicated_update();
		if_update_stat(dlg_enable_stats, update_recv, 1);
		break;

	case REPLICATION_DLG_DELETED:
		rc = dlg_replicated_delete();
		if_update_stat(dlg_enable_stats, delete_recv, 1);
		break;

	default:
		rc = -1;
		LM_ERR("Invalid dialog binary packet command: %d\n", info_type);
	}

	if (rc != 0)
		LM_ERR("Failed to process a binary packet!\n");
}
コード例 #2
0
ファイル: dlg_replication.c プロジェクト: SimleCat/opensips
void receive_dlg_binary_packet(int packet_type, struct receive_info *ri, void *att)
{
	int rc;
	char *ip;
	unsigned short port;
	int server_id;

	rc = bin_pop_int(&server_id);
	if (rc < 0)
		return;

	LM_DBG("Received a binary packet!\n");

	if(get_bin_pkg_version() != BIN_VERSION){
		LM_ERR("incompatible bin protocol version\n");
		return;
	}

	if (!accept_replicated_dlg) {
		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("Unwanted dialog packet received from %s:%hu (type=%d)\n",
				ip, port, packet_type);
		return;
	}

	if(!clusterer_api.check(accept_replicated_dlg, &ri->src_su, server_id, ri->proto))
		return;

	switch (packet_type) {
	case REPLICATION_DLG_CREATED:
		LM_DBG("AAAA dlg_replicated_create\n");
		rc = dlg_replicated_create(NULL, NULL, NULL, 1);
		if_update_stat(dlg_enable_stats, create_recv, 1);
		break;

	case REPLICATION_DLG_UPDATED:
		LM_DBG("AAAA dlg_replicated_update\n");
		rc = dlg_replicated_update();
		if_update_stat(dlg_enable_stats, update_recv, 1);
		break;

	case REPLICATION_DLG_DELETED:
		LM_DBG("AAAA dlg_replicated_deleted\n");
		rc = dlg_replicated_delete();
		if_update_stat(dlg_enable_stats, delete_recv, 1);
		break;

	default:
		rc = -1;
		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("Invalid dialog binary packet command: %d (from %s:%hu)\n",
			packet_type, ip, port);
	}

	if (rc != 0)
		LM_ERR("Failed to process a binary packet!\n");
}
コード例 #3
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
void receive_dlg_repl(bin_packet_t *packet)
{
	int rc = 0;
	bin_packet_t *pkt;

	for (pkt = packet; pkt; pkt = pkt->next) {
		switch (pkt->type) {
		case REPLICATION_DLG_CREATED:
			rc = dlg_replicated_create(pkt, NULL, NULL, NULL, 1);
			if_update_stat(dlg_enable_stats, create_recv, 1);
			break;
		case REPLICATION_DLG_UPDATED:
			rc = dlg_replicated_update(pkt);
			if_update_stat(dlg_enable_stats, update_recv, 1);
			break;
		case REPLICATION_DLG_DELETED:
			rc = dlg_replicated_delete(pkt);
			if_update_stat(dlg_enable_stats, delete_recv, 1);
			break;
		case DLG_SHARING_TAG_ACTIVE:
			rc = receive_shtag_active_msg(pkt);
			break;
		case SYNC_PACKET_TYPE:
			while (clusterer_api.sync_chunk_iter(pkt))
				if (dlg_replicated_create(pkt, NULL, NULL, NULL, 1) < 0) {
					LM_ERR("Failed to process sync packet\n");
					return;
				}
			break;
		default:
			rc = -1;
			LM_WARN("Invalid dialog binary packet command: %d "
				"(from node: %d in cluster: %d)\n", pkt->type, pkt->src_id,
				dialog_repl_cluster);
		}

		if (rc != 0)
			LM_ERR("Failed to process a binary packet!\n");
	}
}
コード例 #4
0
/**
 * receive_binary_packet (callback) - receives a cmd_type, specifying the
 * purpose of the data encoded in the received UDP packet
 */
void receive_binary_packet(int packet_type, struct receive_info *ri)
{
	int rc;
	char *ip;
	unsigned short port;

	LM_DBG("Received a binary packet!\n");

	if(get_bin_pkg_version() != BIN_VERSION){
		LM_ERR("incompatible bin protocol version\n");
		return;
	}

	if (accept_repl_profiles && packet_type == REPLICATION_DLG_PROFILE) {
		/* TODO: handle this */
		dlg_replicated_profiles(ri);
		return;
	}
	if (!accept_replicated_dlg) {
		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("Unwanted dialog packet received from %s:%hu (type=%d)\n",
				ip, port, packet_type);
		return;
	}


	switch (packet_type) {
	case REPLICATION_DLG_CREATED:
		rc = dlg_replicated_create(NULL, NULL, NULL, 1);
		if_update_stat(dlg_enable_stats, create_recv, 1);
		break;

	case REPLICATION_DLG_UPDATED:
		rc = dlg_replicated_update();
		if_update_stat(dlg_enable_stats, update_recv, 1);
		break;

	case REPLICATION_DLG_DELETED:
		rc = dlg_replicated_delete();
		if_update_stat(dlg_enable_stats, delete_recv, 1);
		break;

	default:
		rc = -1;
		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("Invalid dialog binary packet command: %d (from %s:%hu)\n",
				packet_type, ip, port);
	}

	if (rc != 0)
		LM_ERR("Failed to process a binary packet!\n");
}
コード例 #5
0
ファイル: dlg_replication.c プロジェクト: austin98x/opensips
/**
 * replicates the remote update of an ongoing dialog locally
 * by reading the relevant information using the Binary Packet Interface
 */
int dlg_replicated_update(void)
{
	struct dlg_cell *dlg;
	str call_id, from_tag, to_tag, from_uri, to_uri, vars, profiles;
	unsigned int dir, dst_leg;
	int timeout, h_entry;
	str st;
	struct dlg_entry *d_entry;

	bin_pop_str(&call_id);
	bin_pop_str(&from_tag);
	bin_pop_str(&to_tag);
	bin_pop_str(&from_uri);
	bin_pop_str(&to_uri);

	LM_DBG("replicated update for ['%.*s' '%.*s' '%.*s' '%.*s' '%.*s']\n",
	call_id.len, call_id.s, from_tag.len, from_tag.s, to_tag.len, to_tag.s,
	from_uri.len, from_uri.s, to_uri.len, to_uri.s);

	dlg = get_dlg(&call_id, &from_tag, &to_tag, &dir, &dst_leg);

	h_entry = dlg_hash(&call_id);
	d_entry = &d_table->entries[h_entry];

	dlg_lock(d_table, d_entry);

	if (!dlg) {
		/* TODO: change to LM_DBG */
		LM_ERR("dialog not found, building new\n");

		dlg = build_new_dlg(&call_id, &from_uri, &to_uri, &from_tag);
		if (!dlg) {
			LM_ERR("Failed to create replicated dialog!\n");
			goto error;
		}

		return dlg_replicated_create(dlg, &from_tag, &to_tag, 0);
	}

	bin_skip_int(2);
	bin_pop_int(&dlg->state);

	bin_skip_str(2);

	bin_pop_str(&st);
	if (dlg_update_cseq(dlg, DLG_CALLER_LEG, &st, 0) != 0) {
		LM_ERR("failed to update caller cseq\n");
		goto error;
	}

	bin_pop_str(&st);
	if (dlg_update_cseq(dlg, callee_idx(dlg), &st, 0) != 0) {
		LM_ERR("failed to update callee cseq\n");
		goto error;
	}

	bin_skip_str(6);
	bin_pop_str(&vars);
	bin_pop_str(&profiles);
	bin_pop_int(&dlg->user_flags);
	bin_pop_int(&dlg->flags);

	bin_pop_int(&timeout);
	bin_skip_int(2);

	timeout -= time(0);
	LM_DBG("Received updated timeout of %d for dialog %.*s\n",timeout,call_id.len,call_id.s);

	if (dlg->lifetime != timeout) {
		dlg->lifetime = timeout;
		if (update_dlg_timer(&dlg->tl, dlg->lifetime) == -1)
			LM_ERR("failed to update dialog lifetime!\n");
	}

	unref_dlg_unsafe(dlg, 1, d_entry);

	if (vars.s && vars.len != 0)
		read_dialog_vars(vars.s, vars.len, dlg);

	dlg_unlock(d_table, d_entry);

	if (profiles.s && profiles.len != 0)
		read_dialog_profiles(profiles.s, profiles.len, dlg, 1, 1);

	return 0;

error:
	dlg_unlock(d_table, d_entry);
	return -1;
}
コード例 #6
0
ファイル: dlg_replication.c プロジェクト: NormB/opensips
/**
 * replicates the remote update of an ongoing dialog locally
 * by reading the relevant information using the Binary Packet Interface
 */
int dlg_replicated_update(bin_packet_t *packet)
{
	struct dlg_cell *dlg;
	str call_id, from_tag, to_tag, from_uri, to_uri, vars, profiles;
	unsigned int dir, dst_leg;
	int timeout, h_entry;
	str st;
	struct dlg_entry *d_entry;
	int rcv_flags, save_new_flag;

	bin_pop_str(packet, &call_id);
	bin_pop_str(packet, &from_tag);
	bin_pop_str(packet, &to_tag);
	bin_pop_str(packet, &from_uri);
	bin_pop_str(packet, &to_uri);

	LM_DBG("replicated update for ['%.*s' '%.*s' '%.*s' '%.*s' '%.*s']\n",
		call_id.len, call_id.s, from_tag.len, from_tag.s, to_tag.len, to_tag.s,
		from_uri.len, from_uri.s, to_uri.len, to_uri.s);

	dlg = get_dlg(&call_id, &from_tag, &to_tag, &dir, &dst_leg);

	h_entry = dlg_hash(&call_id);
	d_entry = &d_table->entries[h_entry];

	dlg_lock(d_table, d_entry);

	if (!dlg) {
		LM_DBG("dialog not found, building new\n");

		dlg = build_new_dlg(&call_id, &from_uri, &to_uri, &from_tag);
		if (!dlg) {
			LM_ERR("Failed to create replicated dialog!\n");
			goto error;
		}

		return dlg_replicated_create(packet ,dlg, &from_tag, &to_tag, 0);
	}

	bin_skip_int(packet, 2);
	bin_pop_int(packet, &dlg->state);

	bin_skip_str(packet, 2);

	bin_pop_str(packet, &st);
	if (dlg_update_cseq(dlg, DLG_CALLER_LEG, &st, 0) != 0) {
		LM_ERR("failed to update caller cseq\n");
		goto error;
	}

	bin_pop_str(packet, &st);
	if (dlg_update_cseq(dlg, callee_idx(dlg), &st, 0) != 0) {
		LM_ERR("failed to update callee cseq\n");
		goto error;
	}

	bin_skip_str(packet, 6);
	bin_pop_str(packet, &vars);
	bin_pop_str(packet, &profiles);
	bin_pop_int(packet, &dlg->user_flags);
	bin_pop_int(packet, &dlg->mod_flags);

	bin_pop_int(packet, &rcv_flags);
	/* make sure an update received immediately after a create can't
	 * incorrectly erase the DLG_FLAG_NEW before locally writing to DB */
	save_new_flag = dlg->flags & DLG_FLAG_NEW;
	dlg->flags = rcv_flags;
	dlg->flags |= ((save_new_flag ? DLG_FLAG_NEW : 0) | DLG_FLAG_CHANGED);

	bin_pop_int(packet, &timeout);
	bin_skip_int(packet, 2);

	timeout -= time(0);
	LM_DBG("Received updated timeout of %d for dialog %.*s\n",
		timeout, call_id.len, call_id.s);

	if (dlg->lifetime != timeout) {
		dlg->lifetime = timeout;
		switch (update_dlg_timer(&dlg->tl, dlg->lifetime) ) {
		case -1:
			LM_ERR("failed to update dialog lifetime!\n");
			/* continue */
		case 0:
			/* timeout value was updated */
			break;
		case 1:
			/* dlg inserted in timer list with new expire (reference it)*/
			ref_dlg(dlg,1);
		}
	}

	unref_dlg_unsafe(dlg, 1, d_entry);

	if (vars.s && vars.len != 0)
		read_dialog_vars(vars.s, vars.len, dlg);

	dlg->flags |= DLG_FLAG_VP_CHANGED;

	dlg_unlock(d_table, d_entry);

	if (profiles.s && profiles.len != 0)
		read_dialog_profiles(profiles.s, profiles.len, dlg, 1, 1);

	return 0;

error:
	dlg_unlock(d_table, d_entry);
	return -1;
}