Beispiel #1
0
int rtjson_init_routes(sip_msg_t *msg, str *rdoc)
{
	sr_xavp_t *xavp=NULL;
	str xname;
	sr_xval_t xval;
	srjson_doc_t tdoc;

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, rdoc->s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", rdoc->s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	/* basic validation */

	srjson_DestroyDoc(&tdoc);

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_INT;
	xval.v.i = 0;
	xname.s = "idx";
	xname.len = 3;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_STR;
	xval.v.s = *rdoc;
	xname.s = "json";
	xname.len = 4;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_XAVP;
	xval.v.xavp = xavp;
	if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) {
		goto error;
	}

	return 0;

error:
	if(xavp) xavp_destroy_list(&xavp);
	return -1;
}
Beispiel #2
0
/**
* @brief ht dmq callback
*/
int dlg_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	dlg_cell_t *dlg;
	int unref = 0;
	int ret;
	srjson_doc_t jdoc, prof_jdoc;
	srjson_t *it = NULL;

	dlg_dmq_action_t action = DLG_DMQ_NONE;
	dlg_iuid_t iuid;
	str profiles = {0, 0}, callid = {0, 0}, tag1 = {0,0}, tag2 = {0,0},
		contact1 = {0,0}, contact2 = {0,0}, k={0,0}, v={0,0};
	str cseq1 = {0,0}, cseq2 = {0,0}, route_set1 = {0,0}, route_set2 = {0,0},
		from_uri = {0,0}, to_uri = {0,0}, req_uri = {0,0};
	unsigned int init_ts = 0, start_ts = 0, lifetime = 0;
	unsigned int state = 1;
	srjson_t *vj;

	/* received dmq message */
	LM_DBG("dmq message received\n");

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid2;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid2;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	/* parse body */
	LM_DBG("body: %.*s\n", body.len, body.s);

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;

	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if ((it->string == NULL) || (strcmp(it->string, "vars")==0)) continue;

		LM_DBG("found field: %s\n", it->string);

		if (strcmp(it->string, "action")==0) {
			action = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_entry")==0) {
			iuid.h_entry = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_id")==0) {
			iuid.h_id = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "init_ts")==0) {
			init_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "start_ts")==0) {
			start_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "state")==0) {
			state = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "lifetime")==0) {
			lifetime = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "profiles")==0) {
			profiles.s = it->valuestring;
			profiles.len = strlen(profiles.s);
		} else if (strcmp(it->string, "tag1")==0) {
			tag1.s = it->valuestring;
			tag1.len = strlen(tag1.s);
		} else if (strcmp(it->string, "tag2")==0) {
			tag2.s = it->valuestring;
			tag2.len = strlen(tag2.s);
		} else if (strcmp(it->string, "cseq1")==0) {
			cseq1.s = it->valuestring;
			cseq1.len = strlen(cseq1.s);
		} else if (strcmp(it->string, "cseq2")==0) {
			cseq2.s = it->valuestring;
			cseq2.len = strlen(cseq2.s);
		} else if (strcmp(it->string, "route_set1")==0) {
			route_set1.s = it->valuestring;
			route_set1.len = strlen(route_set1.s);
		} else if (strcmp(it->string, "route_set2")==0) {
			route_set2.s = it->valuestring;
			route_set2.len = strlen(route_set2.s);
		} else if (strcmp(it->string, "contact1")==0) {
			contact1.s = it->valuestring;
			contact1.len = strlen(contact1.s);
		} else if (strcmp(it->string, "contact2")==0) {
			contact2.s = it->valuestring;
			contact2.len = strlen(contact2.s);
		} else if (strcmp(it->string, "from_uri")==0) {
			from_uri.s = it->valuestring;
			from_uri.len = strlen(from_uri.s);
		} else if (strcmp(it->string, "to_uri")==0) {
			to_uri.s = it->valuestring;
			to_uri.len = strlen(to_uri.s);
		} else if (strcmp(it->string, "req_uri")==0) {
			req_uri.s = it->valuestring;
			req_uri.len = strlen(req_uri.s);
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}

	dlg = dlg_get_by_iuid(&iuid);
	if (dlg) {
		LM_DBG("found dialog [%u:%u] at %p\n", iuid.h_entry, iuid.h_id, dlg);
		unref++;
	}

	switch(action) {
		case DLG_DMQ_UPDATE:
			LM_DBG("Updating dlg [%u:%u] with callid [%.*s]\n", iuid.h_entry, iuid.h_id,
					callid.len, callid.s);
			if (!dlg) {
				dlg = build_new_dlg(&callid, &from_uri, &to_uri, &tag1, &req_uri);
				if (!dlg) {
					LM_ERR("failed to build new dialog\n");
					goto error;
				}

				if(dlg->h_entry != iuid.h_entry){
					LM_ERR("inconsistent hash data from peer: "
						"make sure all Kamailio's use the same hash size\n");
					shm_free(dlg);
					goto error;
				}

				/* link the dialog */
				link_dlg(dlg, 0, 0);
				dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
				/* override generated h_id */
				dlg->h_id = iuid.h_id;
				/* prevent DB sync */
				dlg->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED);
				dlg->iflags |= DLG_IFLAG_DMQ_SYNC;
			} else {
				/* remove existing profiles */
				if (dlg->profile_links!=NULL) {
					destroy_linkers(dlg->profile_links);
					dlg->profile_links = NULL;
				}
			}

			dlg->init_ts = init_ts;
			dlg->start_ts = start_ts;

			vj = srjson_GetObjectItem(&jdoc, jdoc.root, "vars");
			if(vj!=NULL) {
				for(it=vj->child; it; it = it->next)
				{
					k.s = it->string;        k.len = strlen(k.s);
					v.s = it->valuestring;   v.len = strlen(v.s);
					set_dlg_variable(dlg, &k, &v);
				}
			}
			/* add profiles */
			if(profiles.s!=NULL) {
				srjson_InitDoc(&prof_jdoc, NULL);
				prof_jdoc.buf = profiles;
				dlg_json_to_profiles(dlg, &prof_jdoc);
				srjson_DestroyDoc(&prof_jdoc);
			}
			if (state == dlg->state) {
				break;
			}
			/* intentional fallthrough */

		case DLG_DMQ_STATE:
			if (!dlg) {
				LM_ERR("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			if (state < dlg->state) {
				LM_NOTICE("Ignoring backwards state change on dlg [%u:%u]"
						" with callid [%.*s] from state [%u] to state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
				break;
			}
			LM_DBG("State update dlg [%u:%u] with callid [%.*s] from state [%u]"
					" to state [%u]\n", iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
			switch (state) {
				case DLG_STATE_EARLY:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					break;
				case DLG_STATE_CONFIRMED:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					dlg_set_leg_info(dlg, &tag2, &route_set2, &contact2, &cseq2, 1);
					if (insert_dlg_timer( &dlg->tl, dlg->lifetime ) != 0) {
						LM_CRIT("Unable to insert dlg timer %p [%u:%u]\n",
							dlg, dlg->h_entry, dlg->h_id);
					} else {
						/* dialog pointer inserted in timer list */
						dlg_ref(dlg, 1);
					}
					break;
				case DLG_STATE_DELETED:
					if (dlg->state == DLG_STATE_CONFIRMED) {
						ret = remove_dialog_timer(&dlg->tl);
						if (ret == 0) {
							/* one extra unref due to removal from timer list */
							unref++;
						} else if (ret < 0) {
							LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
								dlg, dlg->h_entry, dlg->h_id);
						}
					}
					/* prevent DB sync */
					dlg->dflags |= DLG_FLAG_NEW;
					/* keep dialog around for a bit, to prevent out-of-order
					 * syncs to reestablish the dlg */
					dlg->init_ts = time(NULL);
					break;
				default:
					LM_ERR("unhandled state update to state %u\n", state);
					dlg_unref(dlg, unref);
					goto error;
			}
			dlg->state = state;
			break;

		case DLG_DMQ_RM:
			if (!dlg) {
				LM_DBG("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			LM_DBG("Removed dlg [%u:%u] with callid [%.*s] int state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state);
			if (dlg->state==DLG_STATE_CONFIRMED
					|| dlg->state==DLG_STATE_EARLY) {
				ret = remove_dialog_timer(&dlg->tl);
				if (ret == 0) {
					/* one extra unref due to removal from timer list */
					unref++;
				} else if (ret < 0) {
					LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
						dlg, dlg->h_entry, dlg->h_id);
				}
			}
			/* prevent DB sync */
			dlg->dflags |= DLG_FLAG_NEW;
			unref++;
			break;

		case DLG_DMQ_SYNC:
			dmq_send_all_dlgs(0);
			break;

		case DLG_DMQ_NONE:
			break;
	}
	if (dlg && unref)
		dlg_unref(dlg, unref);

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
invalid2:
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
Beispiel #3
0
/**
 * json de-serialization of dialog profiles
 */
int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc)
{
	srjson_t *aj = NULL;
	srjson_t *it = NULL;
	srjson_t *jt = NULL;
	dlg_profile_table_t *profile;
	str name;
	str val;
	str puid;
	time_t expires;
	int flags;

	if(dlg==NULL || jdoc==NULL || jdoc->buf.s==NULL)
		return -1;

	if(jdoc->root == NULL)
	{
		jdoc->root = srjson_Parse(jdoc, jdoc->buf.s);
		if(jdoc->root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc->buf.s);
			return -1;
		}
	}
	aj = srjson_GetObjectItem(jdoc, jdoc->root, "profiles");
	if(aj!=NULL)
	{
		for(it=aj->child; it; it = it->next)
		{
			name.s = val.s = puid.s = NULL;
			expires = 0; flags = 0;
			for(jt = it->child; jt; jt = jt->next) {
				if(strcmp(jt->string, "name")==0) {
					name.s = jt->valuestring;
					name.len = strlen(name.s);
				} else if(strcmp(jt->string, "value")==0) {
					val.s = jt->valuestring;
					val.len = strlen(val.s);
				} else if(strcmp(jt->string, "puid")==0) {
					puid.s = jt->valuestring;
					puid.len = strlen(puid.s);
				} else if(strcmp(jt->string, "expires")==0) {
					expires = (time_t)SRJSON_GET_ULONG(jt);
				} else if(strcmp(jt->string, "flags")==0) {
					flags = SRJSON_GET_UINT(jt);
				}
			}
			if(name.s==NULL)
				continue;
			profile = search_dlg_profile(&name);
			if(profile==NULL)
			{
				LM_ERR("profile [%.*s] not found\n", name.len, name.s);
				continue;
			}
			if(val.s!=NULL) {
				if(profile->has_value)
				{
					if(dlg_add_profile(dlg, &val, profile, &puid, expires, flags) < 0)
						LM_ERR("dynamic profile cannot be added, ignore!\n");
					else
						LM_DBG("dynamic profile added [%s : %s]\n", name.s, val.s);
				}
			} else {
				if(!profile->has_value)
				{
					if(dlg_add_profile(dlg, NULL, profile, &puid, expires, flags) < 0)
						LM_ERR("static profile cannot be added, ignore!\n");
					else
						LM_DBG("static profile added [%s]\n", name.s);
				}
			}
		}
	}
	return 0;
}
Beispiel #4
0
/**
* @brief ht dmq callback
*/
int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	srjson_doc_t jdoc;
	srjson_t *it = NULL;
	static ucontact_info_t ci;

	int action, expires, cseq, flags, cflags, q, last_modified, methods, reg_id;
	str aor, ruid, c, received, path, callid, user_agent, instance;

	parse_from_header(msg);
	body = ((struct to_body*)msg->from->parsed)->uri;

	LM_DBG("dmq message received from %.*s\n", body.len, body.s);

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;
	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if (it->string == NULL) continue;

		if (strcmp(it->string, "action")==0) {
			action = it->valueint;
		} else if (strcmp(it->string, "aor")==0) {
			aor.s = it->valuestring;
			aor.len = strlen(aor.s);
		} else if (strcmp(it->string, "ruid")==0) {
			ruid.s = it->valuestring;
			ruid.len = strlen(ruid.s);
		} else if (strcmp(it->string, "c")==0) {
			c.s = it->valuestring;
			c.len = strlen(c.s);
		} else if (strcmp(it->string, "received")==0) {
			received.s = it->valuestring;
			received.len = strlen(received.s);
		} else if (strcmp(it->string, "path")==0) {
			path.s = it->valuestring;
			path.len = strlen(path.s);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "user_agent")==0) {
			user_agent.s = it->valuestring;
			user_agent.len = strlen(user_agent.s);
		} else if (strcmp(it->string, "instance")==0) {
			instance.s = it->valuestring;
			instance.len = strlen(instance.s);
		} else if (strcmp(it->string, "expires")==0) { //
			expires = it->valueint;
		} else if (strcmp(it->string, "cseq")==0) {
			cseq = it->valueint;
		} else if (strcmp(it->string, "flags")==0) {
			flags = it->valueint;
		} else if (strcmp(it->string, "cflags")==0) {
			cflags = it->valueint;
		} else if (strcmp(it->string, "q")==0) {
			q = it->valueint;
		} else if (strcmp(it->string, "last_modified")==0) {
			last_modified = it->valueint;
		} else if (strcmp(it->string, "methods")==0) {
			methods = it->valueint;
		} else if (strcmp(it->string, "reg_id")==0) {
			reg_id = it->valueint;
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}
	memset( &ci, 0, sizeof(ucontact_info_t));
	ci.ruid = ruid;
	ci.c = &c;
	ci.received = received;
	ci.path = &path;
	ci.expires = expires;
	ci.q = q;
	ci.callid = &callid;
	ci.cseq = cseq;
	ci.flags = flags;
	ci.flags |= FL_RPL;
	ci.cflags = cflags;
	ci.user_agent = &user_agent;
	ci.methods = methods;
	ci.instance = instance;
	ci.reg_id = reg_id;
	ci.tcpconn_id = -1;
	ci.last_modified = last_modified;

	switch(action) {
		case DMQ_UPDATE:
			LM_DBG("Received DMQ_UPDATE. Update contact info...\n");
			add_contact(aor, &ci);
			break;
		case DMQ_RM:
			LM_DBG("Received DMQ_RM. Delete contact info...\n");
			delete_contact(aor, &ci);
			break;
		case DMQ_SYNC:
			LM_DBG("Received DMQ_SYNC. Sending all contacts...\n");
			usrloc_get_all_ucontact(node);
			break;
		case DMQ_NONE:
			LM_DBG("Received DMQ_NONE. Not used...\n");
			break;
		default:
			goto invalid;
	}

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
Beispiel #5
0
/**
 * json de-serialization of dialog profiles
 */
int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc)
{
	srjson_t *sj = NULL;
	srjson_t *dj = NULL;
	srjson_t *it = NULL;
	dlg_profile_table_t *profile;
	str name;
	str val;

	if(dlg==NULL || jdoc==NULL || jdoc->buf.s==NULL)
		return -1;

	if(jdoc->root == NULL)
	{
		jdoc->root = srjson_Parse(jdoc, jdoc->buf.s);
		if(jdoc->root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc->buf.s);
			return -1;
		}
	}
	dj = srjson_GetObjectItem(jdoc, jdoc->root, "dprofiles");
	sj = srjson_GetObjectItem(jdoc, jdoc->root, "sprofiles");
	if(dj!=NULL)
	{
		for(it=dj->child; it; it = it->next)
		{
			name.s = it->string;
			name.len = strlen(name.s);
			val.s = it->valuestring;
			val.len = strlen(val.s);
			profile = search_dlg_profile(&name);
			if(profile==NULL)
			{
				LM_ERR("profile [%.*s] not found\n", name.len, name.s);
				continue;
			}
			if(profile->has_value)
			{
				if(dlg_add_profile(dlg, &val, profile) < 0)
					LM_ERR("dynamic profile cannot be added, ignore!\n");
				else
					LM_DBG("dynamic profile added [%s : %s]\n", name.s, val.s);
			}
		}
	}
	if(sj!=NULL)
	{
		for(it=sj->child; it; it = it->next)
		{
			name.s = it->valuestring;
			name.len = strlen(name.s);
			profile = search_dlg_profile(&name);
			if(profile==NULL)
			{
				LM_ERR("profile [%.*s] not found\n", name.len, name.s);
				continue;
			}
			if(!profile->has_value)
			{
				if(dlg_add_profile(dlg, NULL, profile) < 0)
					LM_ERR("static profile cannot be added, ignore!\n");
				else
					LM_DBG("static profile added [%s]\n", name.s);
			}
		}
	}
	return 0;
}
Beispiel #6
0
int rtjson_update_branch(sip_msg_t *msg)
{
	sr_xavp_t *javp = NULL;
	sr_xavp_t *iavp = NULL;
	srjson_doc_t tdoc;
	srjson_t *tj = NULL;
	srjson_t *nj = NULL;
	str val;
	str xname;
	int i;

	xname.s = "json";
	xname.len = 4;
	javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname);
	if(javp==NULL || javp->val.v.s.len<=0) {
		LM_WARN("no json for routing\n");
		return -1;
	}

	xname.s = "idx";
	xname.len = 3;
	iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname);
	if(iavp==NULL) {
		LM_WARN("no idx for routing\n");
		return -1;
	}
	if(iavp->val.v.i<=0) {
		LM_WARN("invalid branch idx for routing\n");
		return -1;
	}

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing");
	if(nj==NULL || nj->valuestring==NULL) {
		LM_ERR("missing or invalid routing field\n");
		goto error;
	}
	val.s = nj->valuestring;
	val.len = strlen(val.s);

	if(val.len!=6 || strncmp(val.s, "serial", 6)!=0) {
		LM_DBG("not serial routing [%.*s]\n", val.len, val.s);
		goto error;
	}

	tj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
	if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
		LM_ERR("missing or invalid routes field\n");
		goto error;
	}
	nj = tj->child;

	i = 0;
	/* stop at number of branches - 1 */
	while(nj && i<iavp->val.v.i-1) {
		nj = nj->next;
		i++;
	}
	if(nj==NULL)
		goto error;

	if(rtjson_prepare_branch(msg, &tdoc, nj)<0)
		goto error;

	srjson_DestroyDoc(&tdoc);
	return 0;

error:
	srjson_DestroyDoc(&tdoc);
	return -1;

}
Beispiel #7
0
int rtjson_push_routes(sip_msg_t *msg)
{
	sr_xavp_t *javp = NULL;
	sr_xavp_t *iavp = NULL;
	srjson_doc_t tdoc;
	srjson_t *nj = NULL;
	str val;
	str xname;
	int ret;

	xname.s = "json";
	xname.len = 4;
	javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname);
	if(javp==NULL || javp->val.v.s.len<=0) {
		LM_WARN("no json for routing\n");
		return -1;
	}

	xname.s = "idx";
	xname.len = 3;
	iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname);
	if(iavp==NULL) {
		LM_WARN("no idx for routing\n");
		return -1;
	}

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing");
	if(nj==NULL || nj->valuestring==NULL) {
		LM_ERR("missing or invalid routing field\n");
		goto error;
	}
	val.s = nj->valuestring;
	val.len = strlen(val.s);

	if(val.len==6 && strncmp(val.s, "serial", 6)==0) {
		LM_DBG("supported routing [%.*s]\n", val.len, val.s);
		ret = rtjson_init_serial(msg, &tdoc, iavp);
	} else if(val.len==8 && strncmp(val.s, "parallel", 8)==0) {
		LM_DBG("supported routing [%.*s]\n", val.len, val.s);
		ret = rtjson_init_parallel(msg, &tdoc, iavp);
	} else {
		LM_ERR("unsupported routing [%.*s]\n", val.len, val.s);
		goto error;
	}

	srjson_DestroyDoc(&tdoc);
	return ret;

error:
	srjson_DestroyDoc(&tdoc);
	return -1;
}
Beispiel #8
0
int rtjson_init_routes(sip_msg_t *msg, str *rdoc)
{
	srjson_Hooks jhooks;
	srjson_doc_t *tdoc = NULL;
	sr_data_t *xdata = NULL;
	rtjson_data_t *rdata = NULL;
	sr_xavp_t *xavp=NULL;
	str xname;
	sr_xval_t xval;


	memset(&jhooks, 0, sizeof(srjson_Hooks));
	jhooks.malloc_fn = rtjson_malloc;
	jhooks.free_fn = rtjson_free;

	tdoc = srjson_NewDoc(&jhooks);

	if(tdoc==NULL) {
		LM_ERR("no more shm\n");
		return -1;
	}
	tdoc->root = srjson_Parse(tdoc, rdoc->s);
	if(tdoc->root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", rdoc->s);
		srjson_DeleteDoc(tdoc);
		return -1;
	}
	xdata = shm_malloc(sizeof(sr_data_t));
	if(xdata==NULL) {
		LM_ERR("no more shm\n");
		srjson_DeleteDoc(tdoc);
		return -1;
	}
	memset(xdata, 0, sizeof(sr_data_t));
	rdata = shm_malloc(sizeof(rtjson_data_t));
	if(rdata==NULL) {
		LM_ERR("no more shm\n");
		srjson_DeleteDoc(tdoc);
		shm_free(xdata);
		return -1;
	}
	memset(rdata, 0, sizeof(rtjson_data_t));

	rdata->jdoc = tdoc;
	xdata->p = rdata;
	xdata->pfree = rtjson_data_free;

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_STR;
	xval.v.s = *rdoc;
	xname.s = "json";
	xname.len = 4;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_DATA;
	xval.v.data = xdata;
	xname.s = "data";
	xname.len = 4;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}
	/* reset pointers - they are linked inside xavp now */
	tdoc = NULL;
	xdata = NULL;
	rdata = NULL;

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_XAVP;
	xval.v.xavp = xavp;
	if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) {
		goto error;
	}

	return 0;
error:
	if(xavp) xavp_destroy_list(&xavp);
	if(rdata) shm_free(rdata);
	if(xdata) shm_free(xdata);
	if(tdoc) srjson_DeleteDoc(tdoc);
	return -1;
}
Beispiel #9
0
/**
 * @brief ht dmq callback
 */
int ht_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* dmq_node)
{
    int content_length;
    str body;
    ht_dmq_action_t action = HT_DMQ_NONE;
    str htname, cname;
    int type = 0, mode = 0;
    int_str val;
    srjson_doc_t jdoc;
    srjson_t *it = NULL;

    /* received dmq message */
    LM_DBG("dmq message received\n");

    if(!msg->content_length) {
        LM_ERR("no content length header found\n");
        goto invalid;
    }
    content_length = get_content_length(msg);
    if(!content_length) {
        LM_DBG("content length is 0\n");
        goto invalid;
    }

    body.s = get_body(msg);
    body.len = content_length;

    if (!body.s) {
        LM_ERR("unable to get body\n");
        goto error;
    }

    /* parse body */
    LM_DBG("body: %.*s\n", body.len, body.s);

    srjson_InitDoc(&jdoc, NULL);
    jdoc.buf = body;

    if(jdoc.root == NULL) {
        jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
        if(jdoc.root == NULL)
        {
            LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
            goto invalid;
        }
    }

    for(it=jdoc.root->child; it; it = it->next)
    {
        LM_DBG("found field: %s\n", it->string);
        if (strcmp(it->string, "action")==0) {
            action = it->valueint;
        } else if (strcmp(it->string, "htname")==0) {
            htname.s = it->valuestring;
            htname.len = strlen(htname.s);
        } else if (strcmp(it->string, "cname")==0) {
            cname.s = it->valuestring;
            cname.len = strlen(cname.s);
        } else if (strcmp(it->string, "type")==0) {
            type = it->valueint;
        } else if (strcmp(it->string, "strval")==0) {
            val.s.s = it->valuestring;
            val.s.len = strlen(val.s.s);
        } else if (strcmp(it->string, "intval")==0) {
            val.n = it->valueint;
        } else if (strcmp(it->string, "mode")==0) {
            mode = it->valueint;
        } else {
            LM_ERR("unrecognized field in json object\n");
            goto invalid;
        }
    }

    if (ht_dmq_replay_action(action, &htname, &cname, type, &val, mode)!=0) {
        LM_ERR("failed to replay action\n");
        goto error;
    }

    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_200_rpl;
    resp->resp_code = 200;
    return 0;

invalid:
    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_400_rpl;
    resp->resp_code = 400;
    return 0;

error:
    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_500_rpl;
    resp->resp_code = 500;
    return 0;
}