示例#1
0
/* run reply route functions */
int run_reply_route(struct sip_msg *_rpl, struct cell *_t, int index)
{
	avp_list_t	*backup_uri_from, *backup_uri_to;
	avp_list_t	*backup_user_from, *backup_user_to;
	avp_list_t	*backup_domain_from, *backup_domain_to;
	struct run_act_ctx	ra_ctx;

	if (!_t || (index < 0)) return -1;

	/* set the avp_list the one from transaction */
	backup_uri_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &_t->uri_avps_from );
	backup_uri_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &_t->uri_avps_to );
	backup_user_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &_t->user_avps_from );
	backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &_t->user_avps_to );
	backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &_t->domain_avps_from );
	backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &_t->domain_avps_to );

	init_run_actions_ctx(&ra_ctx);
	if (run_actions(&ra_ctx, onreply_rt.rlist[index], _rpl)<0)
		LOG(L_ERR, "ERROR: run_reply_route(): on_reply processing failed\n");

	/* restore original avp list */
	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from );
	set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to );
	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_USER, backup_user_from );
	set_avp_list( AVP_TRACK_TO | AVP_CLASS_USER, backup_user_to );
	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_DOMAIN, backup_domain_from );
	set_avp_list( AVP_TRACK_TO | AVP_CLASS_DOMAIN, backup_domain_to );

	return 0;
}
示例#2
0
int nsq_consumer_fire_event(char *routename)
{
	struct sip_msg *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;

	LM_DBG("searching event_route[%s]\n", routename);
	rt = route_get(&event_rt, routename);
	if (rt < 0 || event_rt.rlist[rt] == NULL) {
		LM_DBG("route %s does not exist\n", routename);
		return -2;
	}
	LM_DBG("executing event_route[%s] (%d)\n", routename, rt);
	if (faked_msg_init()<0) {
		return -2;
	}
	fmsg = faked_msg_next();
	rtb = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(rtb);

	return 0;
}
示例#3
0
void uac_req_run_event_route(sip_msg_t *msg, uac_send_info_t *tp, int rcode)
{
	char *evrtname = "uac:reply";
	int rt, backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;

	rt = route_get(&event_rt, evrtname);
	if (rt < 0 || event_rt.rlist[rt] == NULL)
	{
		LM_DBG("event_route[uac:reply] does not exist\n");
		return;
	}

	uac_send_info_copy(tp, &_uac_req);
	_uac_req.evcode = rcode;
	if(msg==NULL)
	{
		_uac_req.evtype = 2;
		fmsg = faked_msg_get_next();
	} else {
		_uac_req.evtype = 1;
		fmsg = msg;
	}

	backup_rt = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(backup_rt);
}
示例#4
0
static int dbops_foreach_func(struct sip_msg* m, char* handle, char* route_no) {
	int res;
	db_rec_t* rec;
	struct dbops_handle *a = (void *) handle;
	struct run_act_ctx ra_ctx;
	
	if ((long)route_no >= main_rt.idx) {
		BUG("invalid routing table number #%ld of %d\n", (long) route_no, main_rt.idx);
		return -1;
	}
	if (!main_rt.rlist[(long) route_no]) {
		WARN(MODULE_NAME": route not declared (hash:%ld)\n", (long) route_no);
		return -1;
	}
	res = check_query_opened(a, "for_each");
	if (res < 0) return res;

	res = -1;
	a->cur_row_no = 0;
	for(rec = db_first(a->result);
			rec != NULL;
			rec = db_next(a->result),
			a->cur_row_no++) {
		/* exec the routing script */
		init_run_actions_ctx(&ra_ctx);
		res = run_actions(&ra_ctx, main_rt.rlist[(long) route_no], m);
		if (res <= 0) break;
	}
	if (!rec) a->cur_row_no = -1;
	return res;
}
示例#5
0
文件: ws_conn.c 项目: SipSeb/kamailio
static void wsconn_run_route(ws_connection_t *wsc)
{
	int rt, backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;

	LM_DBG("wsconn_run_route event_route[websocket:closed]\n");

	rt = route_get(&event_rt, "websocket:closed");
	if (rt < 0 || event_rt.rlist[rt] == NULL)
	{
		LM_DBG("route does not exist");
		return;
	}

	if (faked_msg_init() < 0)
	{
		LM_ERR("faked_msg_init() failed\n");
		return;
	}
	
	fmsg = faked_msg_next();
	wsc->rcv.proto_reserved1 = wsc->id;
	fmsg->rcv = wsc->rcv;

	backup_rt = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(backup_rt);
}
示例#6
0
static void tcpops_tcp_closed_run_route(struct tcp_connection *con)
{
	int rt, backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;
	LM_DBG("tcp_closed_run_route event_route[tcp:closed]\n");

	rt = route_get(&event_rt, "tcp:closed");
	if (rt < 0 || event_rt.rlist[rt] == NULL)
	{
		LM_DBG("route does not exist");
		return;
	}

	if (faked_msg_init() < 0)
	{
		LM_ERR("faked_msg_init() failed\n");
		return;
	}
	fmsg = faked_msg_next();
	fmsg->rcv = con->rcv;

	backup_rt = get_route_type();
	set_route_type(EVENT_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(backup_rt);
}
示例#7
0
int evapi_run_cfg_route(evapi_env_t *evenv, int rt)
{
	int backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;
	sip_msg_t tmsg;

	if(evenv==0 || evenv->eset==0) {
		LM_ERR("evapi env not set\n");
		return -1;
	}

	if(rt<0)
		return 0;

	fmsg = faked_msg_next();
	memcpy(&tmsg, fmsg, sizeof(sip_msg_t));
	fmsg = &tmsg;
	evapi_set_msg_env(fmsg, evenv);
	backup_rt = get_route_type();
	set_route_type(EVENT_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(backup_rt);
	evapi_set_msg_env(fmsg, NULL);
	return 0;
}
示例#8
0
static int lua_sr_sethost (lua_State *L)
{
	struct action  act;
	struct run_act_ctx h;
	str uri;
	sr_lua_env_t *env_L;

	env_L = sr_lua_env_get();
	uri.s = (char*)lua_tostring(L, -1);
	if(uri.s==NULL)
	{
		LM_ERR("invalid uri parameter\n");
		return app_lua_return_false(L);
	}
	uri.len = strlen(uri.s);

	if(env_L->msg==NULL)
	{
		LM_WARN("invalid parameters from Lua env\n");
		return app_lua_return_false(L);
	}

	memset(&act, 0, sizeof(act));
	act.val[0].type = STRING_ST;
	act.val[0].u.string = uri.s;
	act.type = SET_HOST_T;
	init_run_actions_ctx(&h);
	if (do_action(&h, &act, env_L->msg)<0)
	{
		LM_ERR("do action failed\n");
		return app_lua_return_false(L);
	}
	return app_lua_return_true(L);
}
示例#9
0
static int fire_init_event(int rank)
{
	struct sip_msg *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;

	LM_DBG("rank is (%d)\n", rank);
	if (rank!=PROC_INIT)
		return 0;

	rt = route_get(&event_rt, "kazoo:mod-init");
	if(rt>=0 && event_rt.rlist[rt]!=NULL) {
		LM_DBG("executing event_route[kazoo:mod-init] (%d)\n", rt);
		if(faked_msg_init()<0)
			return -1;
		fmsg = faked_msg_next();
		rtb = get_route_type();
		set_route_type(REQUEST_ROUTE);
		init_run_actions_ctx(&ctx);
		run_top_route(event_rt.rlist[rt], fmsg, &ctx);
		if(ctx.run_flags&DROP_R_F)
		{
			LM_ERR("exit due to 'drop' in event route\n");
			return -1;
		}
		set_route_type(rtb);
	}

	return 0;
}
示例#10
0
static int xhttp_process_request(sip_msg_t* orig_msg, 
							  char* new_buf, unsigned int new_len)
{
	int ret;
	sip_msg_t tmp_msg, *msg;
	struct run_act_ctx ra_ctx;
	
	ret=0;
	if (new_buf && new_len)
	{
		memset(&tmp_msg, 0, sizeof(sip_msg_t));
		tmp_msg.buf = new_buf;
		tmp_msg.len = new_len;
		tmp_msg.rcv = orig_msg->rcv;
		tmp_msg.id = orig_msg->id;
		tmp_msg.set_global_address = orig_msg->set_global_address;
		tmp_msg.set_global_port = orig_msg->set_global_port;
		if (parse_msg(new_buf, new_len, &tmp_msg) != 0)
		{
			LM_ERR("parse_msg failed\n");
			goto error;
		}
		msg = &tmp_msg;
	} else {
		msg = orig_msg;
	}
	
	if ((msg->first_line.type != SIP_REQUEST) || (msg->via1 == 0) ||
		(msg->via1->error != PARSE_OK))
	{
		LM_CRIT("strange message: %.*s\n", msg->len, msg->buf);
		goto error;
	}
	if (exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0)
	{
		goto done;
	}

	init_run_actions_ctx(&ra_ctx);
	if (run_actions(&ra_ctx, event_rt.rlist[xhttp_route_no], msg) < 0)
	{
		ret=-1;
		LM_DBG("error while trying script\n");
		goto done;
	}

done:
	exec_post_script_cb(msg, REQUEST_CB_TYPE);
	if (msg != orig_msg)
	{
		free_sip_msg(msg);
	}
	return ret;

error:
	return -1;
}
示例#11
0
文件: pdt.c 项目: adubovikov/kamailio
/**
 * change the uri according to update mode
 */
static int update_new_uri(struct sip_msg *msg, int plen, str *d, int mode)
{
	struct action act;
	struct run_act_ctx ra_ctx;
	if(msg==NULL || d==NULL)
	{
		LM_ERR("bad parameters\n");
		return -1;
	}
	
	if(mode==0 || (mode==1 && pdt_prefix.len>0))
	{
		memset(&act, '\0', sizeof(act));
		act.type = STRIP_T;
		act.val[0].type = NUMBER_ST;
		if(mode==0)
			act.val[0].u.number = plen + pdt_prefix.len;
		else
			act.val[0].u.number = pdt_prefix.len;

		init_run_actions_ctx(&ra_ctx);
		if (do_action(&ra_ctx, &act, msg) < 0)
		{
			LM_ERR("failed to remove prefix parameter\n");
			return -1;
		}
	}
	
	memset(&act, '\0', sizeof(act));
	act.type = SET_HOSTALL_T;
	act.val[0].type = STRING_ST;
	act.val[0].u.string = d->s;
	init_run_actions_ctx(&ra_ctx);
	if (do_action(&ra_ctx, &act, msg) < 0)
	{
		LM_ERR("failed to change domain\n");
		return -1;
	}

	LM_DBG("len=%d uri=%.*s\n", msg->new_uri.len, 
			msg->new_uri.len, msg->new_uri.s);
	
	return 0;
}
示例#12
0
文件: avp.c 项目: 2pac/kamailio
static int attr2uri(struct sip_msg* msg, char* p1, char* p2)
{
    int_str value;
    avp_t* avp_entry;
    struct action act;
	struct run_act_ctx ra_ctx;
    int pnr;
    unsigned int u;
    
    if (p2) {
		pnr = ((fparam_t*)p2)->v.i;
    } else {
		pnr = SET_URI_T;
    }
    
    avp_entry = search_avp(((fparam_t*)p1)->v.avp, &value, NULL);
    if (avp_entry == 0) {
		ERR("attr2uri: AVP '%s' not found\n", ((fparam_t*)p1)->orig);
		return -1;
    }
    
    memset(&act, 0, sizeof(act));
	
    if ((pnr == STRIP_T) || (pnr == STRIP_TAIL_T)) {
		/* we need integer value for these actions */
        if (avp_entry->flags & AVP_VAL_STR) {
			if (str2int(&value.s, &u)) {
				ERR("not an integer value: %.*s\n",
					value.s.len, value.s.s);
				return -1;
			}
			act.val[0].u.number = u;
		} else {
			act.val[0].u.number = value.n;
		}
		act.val[0].type = NUMBER_ST;
    } else {
		/* we need string value */
		if ((avp_entry->flags & AVP_VAL_STR) == 0) {
			act.val[0].u.string = int2str(value.n, NULL);
		} else {
			act.val[0].u.string = value.s.s;
		}
		act.val[0].type = STRING_ST;
    }
    act.type = pnr;
    init_run_actions_ctx(&ra_ctx);
    if (do_action(&ra_ctx, &act, msg) < 0) {
		ERR("failed to change ruri part.\n");
		return -1;
    }
    return 1;
}
示例#13
0
static void wsconn_run_route(ws_connection_t *wsc)
{
	int rt, backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;
	sr_kemi_eng_t *keng = NULL;
	str evrtname = str_init("websocket:closed");

	LM_DBG("wsconn_run_route event_route[websocket:closed]\n");

	rt = route_lookup(&event_rt, evrtname.s);
	if (rt < 0 || event_rt.rlist[rt] == NULL)
	{
		if(ws_event_callback.len<=0 || ws_event_callback.s==NULL) {
			LM_DBG("event route does not exist");
			return;
		}
		keng = sr_kemi_eng_get();
		if(keng==NULL) {
			LM_DBG("event route callback engine does not exist");
			return;
		} else {
			rt = -1;
		}
	}

	if (faked_msg_init() < 0)
	{
		LM_ERR("faked_msg_init() failed\n");
		return;
	}

	fmsg = faked_msg_next();
	wsc->rcv.proto_reserved1 = wsc->id;
	fmsg->rcv = wsc->rcv;

	backup_rt = get_route_type();
	set_route_type(EVENT_ROUTE);
	init_run_actions_ctx(&ctx);
	if(rt<0) {
		/* kemi script event route callback */
		if(keng && keng->froute(fmsg, EVENT_ROUTE,
					&ws_event_callback, &evrtname)<0) {
			LM_ERR("error running event route kemi callback\n");
		}
	} else {
		/* native cfg event route */
		run_top_route(event_rt.rlist[rt], fmsg, 0);
	}
	set_route_type(backup_rt);
}
示例#14
0
文件: msrp_mod.c 项目: halan/kamailio
static int msrp_frame_received(void *data)
{
	tcp_event_info_t *tev;
	static msrp_frame_t mf;
	sip_msg_t *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;


	tev = (tcp_event_info_t*)data;

	if(tev==NULL || tev->buf==NULL || tev->len<=0)
	{
		LM_DBG("invalid parameters\n");
		return -1;
	}

	memset(&mf, 0, sizeof(msrp_frame_t));
	mf.buf.s = tev->buf;
	mf.buf.len = tev->len;
	mf.tcpinfo = tev;
	if(msrp_parse_frame(&mf)<0)
	{
		LM_ERR("error parsing msrp frame\n");
		return -1;
	}
	msrp_reset_env();
	msrp_set_current_frame(&mf);
	rt = route_get(&event_rt, "msrp:frame-in");
	if(rt>=0 && event_rt.rlist[rt]!=NULL) {
		LM_DBG("executing event_route[msrp:frame-in] (%d)\n", rt);
		fmsg = msrp_fake_sipmsg(&mf);
		if(fmsg!=NULL)
			fmsg->rcv = *tev->rcv;
		rtb = get_route_type();
		set_route_type(REQUEST_ROUTE);
		init_run_actions_ctx(&ctx);
		run_top_route(event_rt.rlist[rt], fmsg, &ctx);
		if(ctx.run_flags&DROP_R_F)
		{
			LM_DBG("exit due to 'drop' in event route\n");
		}
		set_route_type(rtb);
		if(fmsg!=NULL)
			free_sip_msg(fmsg);
	}
	msrp_reset_env();
	msrp_destroy_frame(&mf);
	return 0;
}
示例#15
0
文件: corex_nio.c 项目: 2pac/kamailio
int nio_msg_received(void *data)
{
    sip_msg_t msg;
    str *obuf;
    char *nbuf = NULL;
    int_str avp_value;
    struct usr_avp *avp;
    struct run_act_ctx ra_ctx;

    obuf = (str*)data;

    if (obuf->len < nio_min_msg_len) {
        return -1;
    }

    memset(&msg, 0, sizeof(sip_msg_t));
    msg.buf = obuf->s;
    msg.len = obuf->len;

    nio_is_incoming = 1;
    init_run_actions_ctx(&ra_ctx);
    run_actions(&ra_ctx, event_rt.rlist[nio_route_no], &msg);

    if(nio_msg_avp_name.n!=0) {
        avp = NULL;
        avp=search_first_avp(nio_msg_avp_type, nio_msg_avp_name,
            &avp_value, 0);
        if(avp!=NULL && is_avp_str_val(avp)) {
            msg.buf = avp_value.s.s;
            msg.len = avp_value.s.len;
            nbuf = nio_msg_update(&msg, (unsigned int*)&obuf->len);
            if(obuf->len>=BUF_SIZE) {
                LM_ERR("new buffer overflow (%d)\n", obuf->len);
                pkg_free(nbuf);
                return -1;
            }
            memcpy(obuf->s, nbuf, obuf->len);
            obuf->s[obuf->len] = '\0';
        } else {
            LM_WARN("no value set for AVP %.*s, using unmodified message\n",
                nio_msg_avp_param.len, nio_msg_avp_param.s);
        }
    }

    if(nbuf!=NULL)
        pkg_free(nbuf);
    free_sip_msg(&msg);
    return 0;
}
示例#16
0
/*! Run a request route block if it exists
 */
static int w_route_exists(struct sip_msg *msg, char *route)
{
	struct run_act_ctx ctx;
	int newroute, backup_rt, ret;

	newroute = route_lookup(&main_rt, route);
	if (newroute<0) {
		return -1;
	}
	backup_rt = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	ret = run_top_route(main_rt.rlist[newroute], msg, &ctx);
	set_route_type(backup_rt);
	return ret;
}
示例#17
0
文件: alookup.c 项目: kiryu/kamailio
/**
 * Rewrite Request-URI
 */
static inline int rewrite_ruri(struct sip_msg* _m, char* _s)
{
	struct action act;
	struct run_act_ctx ra_ctx;

	memset(&act, 0, sizeof(act));
	act.type = SET_URI_T;
	act.val[0].type = STRING_ST;
	act.val[0].u.string = _s;
	init_run_actions_ctx(&ra_ctx);
	if (do_action(&ra_ctx, &act, _m) < 0)
	{
		LM_ERR("do_action failed\n");
		return -1;
	}
	return 0;
}
示例#18
0
static int child_init(int rank)
{
	struct sip_msg *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;
	int i;

	LM_DBG("rank is (%d)\n", rank);

	if(rank==PROC_MAIN) {
		if(ht_timer_procs>0) {
			for(i=0; i<ht_timer_procs; i++) {
				if(fork_sync_timer(PROC_TIMER, "HTable Timer", 1 /*socks flag*/,
						ht_timer, (void*)(long)i, ht_timer_interval)<0) {
					LM_ERR("failed to start timer routine as process\n");
					return -1; /* error */
				}
			}
		}
	}

	if (rank!=PROC_INIT)
		return 0;

	rt = route_get(&event_rt, "htable:mod-init");
	if(rt>=0 && event_rt.rlist[rt]!=NULL) {
		LM_DBG("executing event_route[htable:mod-init] (%d)\n", rt);
		if(faked_msg_init()<0)
			return -1;
		fmsg = faked_msg_next();
		rtb = get_route_type();
		set_route_type(REQUEST_ROUTE);
		init_run_actions_ctx(&ctx);
		run_top_route(event_rt.rlist[rt], fmsg, &ctx);
		if(ctx.run_flags&DROP_R_F)
		{
			LM_ERR("exit due to 'drop' in event route\n");
			return -1;
		}
		set_route_type(rtb);
	}

	return 0;
}
示例#19
0
int tls_run_event_routes(struct tcp_connection *c)
{
	int backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t tmsg;

	if(_tls_evrt_connection_out<0)
		return 0;
	if(p_onsend==0 || p_onsend->msg==0)
		return 0;

	backup_rt = get_route_type();
	set_route_type(LOCAL_ROUTE);
	init_run_actions_ctx(&ctx);
	tls_set_pv_con(c);
	run_top_route(event_rt.rlist[_tls_evrt_connection_out], &tmsg, 0);
	tls_set_pv_con(0);
	set_route_type(backup_rt);
	return 0;
}
示例#20
0
文件: corex_nio.c 项目: 2pac/kamailio
int nio_msg_sent(void *data)
{
    sip_msg_t msg;
    str *obuf;
    int_str avp_value;
    struct usr_avp *avp;
    struct run_act_ctx ra_ctx;

    obuf = (str*)data;

    if (obuf->len < nio_min_msg_len) {
        return -1;
    }

    memset(&msg, 0, sizeof(sip_msg_t));
    msg.buf = obuf->s;
    msg.len = obuf->len;

    nio_is_incoming = 0;
    init_run_actions_ctx(&ra_ctx);
    run_actions(&ra_ctx, event_rt.rlist[nio_route_no], &msg);

    if(nio_msg_avp_name.n!=0) {
        avp = NULL;
        avp=search_first_avp(nio_msg_avp_type, nio_msg_avp_name,
                &avp_value, 0);
        if(avp!=NULL && is_avp_str_val(avp)) {
            msg.buf = avp_value.s.s;
            msg.len = avp_value.s.len;
            obuf->s = nio_msg_update(&msg, (unsigned int*)&obuf->len);
        } else {
            LM_WARN("no value set for AVP %.*s, using unmodified message\n",
                nio_msg_avp_param.len, nio_msg_avp_param.s);
        }
    }

    free_sip_msg(&msg);
    return 0;
}
示例#21
0
/*! Run a request route block if it exists
 */
static int w_route_exists(struct sip_msg *msg, char *route)
{
	struct run_act_ctx ctx;
	int newroute, ret;
	str s;

	if (fixup_get_svalue(msg, (gparam_p) route, &s) != 0) {
			LM_ERR("invalid route parameter\n");
			return -1;
	}

	newroute = route_lookup(&main_rt, s.s);
	if (newroute<0) {
		return -1;
	}
	init_run_actions_ctx(&ctx);
	ret=run_actions(&ctx, main_rt.rlist[newroute], msg);
	if (ctx.run_flags & EXIT_R_F) {
		return 0;
	}
	return ret;
}
示例#22
0
static PyObject *
msg_rewrite_ruri(msgobject *self, PyObject *args)
{
    char *ruri;
    struct action act;
    struct run_act_ctx ra_ctx;

    if (self->msg == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
        Py_INCREF(Py_None);
        return Py_None;
    }

    if ((self->msg->first_line).type != SIP_REQUEST) {
        PyErr_SetString(PyExc_RuntimeError, "Not a request message - "
          "rewrite is not possible.\n");
        Py_INCREF(Py_None);
        return Py_None;
    }

    if(!PyArg_ParseTuple(args, "s:rewrite_ruri", &ruri))
        return NULL;

    memset(&act, '\0', sizeof(act));

    act.type = SET_URI_T;
    act.val[0].type = STR_ST;
    act.val[0].u.str.s = ruri;
    act.val[0].u.str.len = strlen(ruri);

    init_run_actions_ctx(&ra_ctx);
    if (do_action(&ra_ctx, &act, self->msg) < 0) {
        LM_ERR("Error in do_action\n");
        PyErr_SetString(PyExc_RuntimeError, "Error in do_action\n");
    }

    Py_INCREF(Py_None);
    return Py_None;
}
示例#23
0
static void tcpops_tcp_closed_run_route(tcp_closed_event_info_t *tev)
{
	int rt, backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;

	rt = tcp_closed_routes[tev->reason];
	if (rt == -1) return;

	if (faked_msg_init() < 0)
	{
		LM_ERR("faked_msg_init() failed\n");
		return;
	}
	fmsg = faked_msg_next();
	fmsg->rcv = tev->con->rcv;

	backup_rt = get_route_type();
	set_route_type(EVENT_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[rt], fmsg, 0);
	set_route_type(backup_rt);
}
示例#24
0
/**
 * rewrites the request URI of msg after determining the
 * new destination URI
 *
 * @param _msg the current SIP message
 * @param _carrier the requested carrier
 * @param _domain the requested routing domain
 * @param _prefix_matching the user to be used for prefix matching
 * @param _rewrite_user the localpart of the URI to be rewritten
 * @param _hsrc the SIP header used for hashing
 * @param _halg the hash algorithm used for hashing
 * @param _dstavp the name of the destination AVP where the used host name is stored
 *
 * @return 1 on success, -1 on failure
 */
int cr_do_route(struct sip_msg * _msg, gparam_t *_carrier,
		gparam_t *_domain, gparam_t *_prefix_matching,
		gparam_t *_rewrite_user, enum hash_source _hsrc,
		enum hash_algorithm _halg, gparam_t *_dstavp) {

	int carrier_id, domain_id, ret = -1;
	str rewrite_user, prefix_matching, dest;
	flag_t flags;
	struct route_data_t * rd;
	struct carrier_data_t * carrier_data;
	struct domain_data_t * domain_data;
	struct action act;
	struct run_act_ctx ra_ctx;

	if (fixup_get_svalue(_msg, _rewrite_user, &rewrite_user)<0) {
		LM_ERR("cannot print the rewrite_user\n");
		return -1;
	}

	if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
		LM_ERR("cannot print the prefix_matching\n");
		return -1;
	}

	flags = _msg->flags;

	do {
		rd = get_data();
	} while (rd == NULL);

	carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
	if (carrier_id < 0) {
		LM_ERR("invalid carrier id %d\n", carrier_id);
		release_data(rd);
		return -1;
	}

	domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
	if (domain_id < 0) {
		LM_ERR("invalid domain id %d\n", domain_id);
		release_data(rd);
		return -1;
	}
	
	carrier_data=NULL;
	if (carrier_id < 0) {
		if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
			LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
			carrier_data = get_carrier_data(rd, rd->default_carrier_id);
		}
	} else if (carrier_id == 0) {
		carrier_data = get_carrier_data(rd, rd->default_carrier_id);
	} else {
		carrier_data = get_carrier_data(rd, carrier_id);
		if (carrier_data == NULL) {
			if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
				LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
				carrier_data = get_carrier_data(rd, rd->default_carrier_id);
			}
		}
	}
	if (carrier_data == NULL) {
		LM_ERR("cannot get carrier data\n");
		goto unlock_and_out;
	}

	domain_data = get_domain_data(carrier_data, domain_id);
	if (domain_data == NULL) {
		LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
			prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	if (rewrite_uri_recursor(domain_data->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) {
		/* this is not necessarily an error, rewrite_recursor does already some error logging */
		LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len,
			prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	LM_INFO("uri %.*s was rewritten to %.*s, carrier %d, domain %d\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s, carrier_id, domain_id);

	memset(&act, 0, sizeof(act));
	act.type = SET_URI_T;
	act.val[0].type = STRING_ST;
	act.val[0].u.string = dest.s;
	init_run_actions_ctx(&ra_ctx);
	ret = do_action(&ra_ctx, &act, _msg);
	if (ret < 0) {
		LM_ERR("Error in do_action()\n");
	}

unlock_and_out:
	release_data(rd);
	return ret;
}
示例#25
0
int uac_reg_request_to(struct sip_msg *msg, str *src, unsigned int mode)
{
	char ruri[MAX_URI_SIZE];
	struct sip_uri puri;
	reg_uac_t *reg = NULL;
	pv_value_t val;
	struct action act;
	struct run_act_ctx ra_ctx;

	switch(mode)
	{
		case 0:
			reg = reg_ht_get_byuuid(src);
			break;
		case 1:
			if(reg_use_domain)
			{
				if (parse_uri(src->s, src->len, &puri)!=0)
				{
					LM_ERR("failed to parse uri\n");
					return -2;
				}
				reg = reg_ht_get_byuser(&puri.user, &puri.host);
			} else {
				reg = reg_ht_get_byuser(src, NULL);
			}
			break;
		default:
			LM_ERR("unknown mode: %d\n", mode);
			return -1;
	}

	if(reg==NULL)
	{
		LM_DBG("no user: %.*s\n", src->len, src->s);
		return -1;
	}

	// Set uri ($ru)
	snprintf(ruri, MAX_URI_SIZE, "sip:%.*s@%.*s",
		reg->r_username.len, reg->r_username.s,
		reg->r_domain.len, reg->r_domain.s);
	memset(&act, 0, sizeof(act));
	act.type = SET_URI_T;
	act.val[0].type = STRING_ST;
	act.val[0].u.string = ruri;
	init_run_actions_ctx(&ra_ctx);
	if (do_action(&ra_ctx, &act, msg) < 0) {
		LM_ERR("error while setting request uri\n");
		return -1;
	}

	// Set auth_proxy ($du)
	if (set_dst_uri(msg, &reg->auth_proxy) < 0) {
		LM_ERR("error while setting outbound proxy\n");
		return -1;
	}

	memset(&val, 0, sizeof(pv_value_t));
	val.flags |= PV_VAL_STR;

	// Set auth_realm
	val.rs = reg->realm;
	if(pv_set_spec_value(msg, &auth_realm_spec, 0, &val)!=0) {
		LM_ERR("error while setting auth_realm\n");
		return -1;
	}

	// Set auth_username
	val.rs = reg->auth_username;
	if(pv_set_spec_value(msg, &auth_username_spec, 0, &val)!=0) {
		LM_ERR("error while setting auth_username\n");
		return -1;
	}

	// Set auth_password
	val.rs = reg->auth_password;
	if(pv_set_spec_value(msg, &auth_password_spec, 0, &val)!=0) {
		LM_ERR("error while setting auth_password\n");
		return -1;
	}

	return 1;
}
示例#26
0
static ticks_t timer_handler(ticks_t ticks, struct timer_ln* tl, void* data) {
	/*?min length of first line of message is 16 char!?*/
	#define MSG "GET /timer HTTP/0.9\n\n"
	struct sip_msg* msg;
	struct timer_action *a;
	struct run_act_ctx ra_ctx;

	a = data;
	if (!a->disable_itself) {

		DEBUG(MODULE_NAME": handler: called at %d ticks, timer: '%s', pid:%d\n", ticks, a->timer_name, getpid());

		if (a->route_no >= main_rt.idx) {
			BUG(MODULE_NAME": invalid routing table number #%d of %d\n", a->route_no, main_rt.idx);
			goto err2;
		}
		if (!main_rt.rlist[a->route_no]) {
			WARN(MODULE_NAME": route not declared (hash:%d)\n", a->route_no);
			goto err2;
		}
		msg=pkg_malloc(sizeof(struct sip_msg));
		if (msg==0) {
			ERR(MODULE_NAME": handler: no mem for sip_msg\n");
			goto err2;
		}
		timer_msg_no++;
		memset(msg, 0, sizeof(struct sip_msg)); /* init everything to 0 */

		msg->buf=MSG;
		msg->len=sizeof(MSG)-1;

		msg->rcv= rcv_info;
		msg->id=timer_msg_no;
		msg->set_global_address=default_global_address;
		msg->set_global_port=default_global_port;

		if (parse_msg(msg->buf, msg->len, msg)!=0){
			ERR(MODULE_NAME": handler: parse_msg failed\n");
			goto err;
		}
		/* ... clear branches from previous message */
		clear_branches();
		reset_static_buffer();
		if (exec_pre_req_cb(msg)==0 )
			goto end; /* drop the request */
		/* exec the routing script */
		timer_executed = a;
		init_run_actions_ctx(&ra_ctx);
		run_actions(&ra_ctx, main_rt.rlist[a->route_no], msg);
		timer_executed = 0;
		/* execute post request-script callbacks */
		exec_post_req_cb(msg);
	end:
		reset_avps();
		DEBUG(MODULE_NAME": handler: cleaning up\n");
	err:
		free_sip_msg(msg);
		pkg_free(msg);
	err2:	;
	}
        /* begin critical section */
	if (a->disable_itself) {

		timer_allow_del(a->link);
		timer_del(a->link);
		timer_reinit(a->link);
		a->disable_itself = 0;
	        /* end critical section */
		return 0;   /* do no call more */
	}
	else
        	return (ticks_t)(-1); /* periodical */
}
示例#27
0
文件: exec.c 项目: btriller/kamailio
int exec_str(struct sip_msg *msg, char *cmd, char *param, int param_len)
{

	struct action act;
	struct run_act_ctx ra_ctx;
	int cmd_len;
	FILE *pipe;
	char *cmd_line;
	int ret;
	int l1;
	static char uri_line[MAX_URI_SIZE + 1];
	int uri_cnt;
	str uri;
	int exit_status;

	/* pessimist: assume error by default */
	ret = -1;

	l1 = strlen(cmd);
	if(param_len > 0)
		cmd_len = l1 + param_len + 4;
	else
		cmd_len = l1 + 1;
	cmd_line = pkg_malloc(cmd_len);
	if(cmd_line == 0) {
		ret = ser_error = E_OUT_OF_MEM;
		LM_ERR("no pkg mem for command\n");
		goto error00;
	}

	/* 'command parameter \0' */
	memcpy(cmd_line, cmd, l1);
	if(param_len > 0) {
		cmd_line[l1] = ' ';
		cmd_line[l1 + 1] = '\'';
		memcpy(cmd_line + l1 + 2, param, param_len);
		cmd_line[l1 + param_len + 2] = '\'';
		cmd_line[l1 + param_len + 3] = 0;
	} else {
		cmd_line[l1] = 0;
	}

	pipe = popen(cmd_line, "r");
	if(pipe == NULL) {
		LM_ERR("cannot open pipe: %s\n", cmd_line);
		ser_error = E_EXEC;
		goto error01;
	}

	/* read now line by line */
	uri_cnt = 0;
	while(fgets(uri_line, MAX_URI_SIZE, pipe) != NULL) {
		uri.s = uri_line;
		uri.len = strlen(uri.s);
		/* trim from right */
		while(uri.len
				&& (uri.s[uri.len - 1] == '\r' || uri.s[uri.len - 1] == '\n'
						   || uri.s[uri.len - 1] == '\t'
						   || uri.s[uri.len - 1] == ' ')) {
			LM_DBG("rtrim\n");
			uri.len--;
		}
		/* skip empty line */
		if(uri.len == 0)
			continue;
		/* ZT */
		uri.s[uri.len] = 0;
		if(uri_cnt == 0) {
			memset(&act, 0, sizeof(act));
			act.type = SET_URI_T;
			act.val[0].type = STRING_ST;
			act.val[0].u.string = uri.s;
			init_run_actions_ctx(&ra_ctx);
			if(do_action(&ra_ctx, &act, msg) < 0) {
				LM_ERR("the action for has failed\n");
				ser_error = E_OUT_OF_MEM;
				goto error02;
			}
		} else {
			if(append_branch(msg, &uri, 0, 0, Q_UNSPECIFIED, 0, 0, 0, 0, 0, 0)
					== -1) {
				LM_ERR("append_branch failed; too many or too long URIs?\n");
				goto error02;
			}
		}
		uri_cnt++;
	}
	if(uri_cnt == 0) {
		LM_ERR("no uri from %s\n", cmd_line);
		goto error02;
	}
	/* success */
	ret = 1;

error02:
	if(ferror(pipe)) {
		LM_ERR("in pipe: %s\n", strerror(errno));
		ser_error = E_EXEC;
		ret = -1;
	}
	exit_status = pclose(pipe);
	if(WIFEXITED(exit_status)) { /* exited properly .... */
		/* return false if script exited with non-zero status */
		if(WEXITSTATUS(exit_status) != 0)
			ret = -1;
	} else { /* exited erroneously */
		LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd,
				exit_status, errno, strerror(errno));
		ret = -1;
	}
error01:
	pkg_free(cmd_line);
error00:
	return ret;
}
示例#28
0
void async_cdp_uar_callback(int is_timeout, void *param, AAAMessage *uaa, long elapsed_msecs) {
    struct run_act_ctx ra_ctx;
    str server_name;
    int *m_capab = 0, m_capab_cnt = 0;
    int *o_capab = 0, o_capab_cnt = 0;
    str *p_server_names = 0;
    int p_server_names_cnt = 0;
    int rc = -1, experimental_rc = -1;
    saved_uar_transaction_t* data = (saved_uar_transaction_t*) param;
    struct cell *t = 0;
    int result = CSCF_RETURN_TRUE;
    scscf_entry *list = 0;

    if (tmb.t_lookup_ident(&t, data->tindex, data->tlabel) < 0) {
        LM_ERR("ERROR: t_continue: transaction not found\n");
        //result = CSCF_RETURN_ERROR;//not needed we set by default to error!
        goto error;
    }

    if (is_timeout != 0) {
        LM_ERR("Error timeout when  sending message via CDP\n");
        update_stat(stat_uar_timeouts, 1);
        goto error;
    }

    //update stats on response time
    update_stat(uar_replies_received, 1);
    update_stat(uar_replies_response_time, elapsed_msecs);

    if (!uaa) {
        LM_ERR("Error sending message via CDP\n");
        //result = CSCF_RETURN_ERROR;//not needed we set by default to error!
        goto error;
    }

    server_name = cxdx_get_server_name(uaa);
    if (!server_name.len) {
        cxdx_get_capabilities(uaa, &m_capab, &m_capab_cnt, &o_capab,
                &o_capab_cnt, &p_server_names, &p_server_names_cnt);
    }

    cxdx_get_result_code(uaa, &rc);
    cxdx_get_experimental_result_code(uaa, &experimental_rc);

    if (rc && !experimental_rc) {
        LM_ERR("No result code or experimental result code - responding 480\n");
        cscf_reply_transactional_async(t, t->uas.request, 480, MSG_480_DIAMETER_MISSING_AVP);
        result = CSCF_RETURN_FALSE;
        goto done;
    }

    switch (rc) {
        case -1:
            switch (experimental_rc) {
                case RC_IMS_DIAMETER_ERROR_USER_UNKNOWN:
                    /* Check, if route is set: */
                    if (route_uar_user_unknown_no >= 0) {
                        /* exec routing script */
                        init_run_actions_ctx(&ra_ctx);
                        if (run_actions(&ra_ctx, main_rt.rlist[route_uar_user_unknown_no], t->uas.request) < 0) {
                            LM_DBG("ims_icscf: error while trying script\n");
                        }
                    } else {
                        cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_USER_UNKNOWN);
                    }
                    LM_ERR("RC_IMS_DIAMETER_ERROR_USER_UNKNOWN\n");
                    result = CSCF_RETURN_FALSE;
                    goto done;
                case RC_IMS_DIAMETER_ERROR_IDENTITIES_DONT_MATCH:
                    LM_ERR("RC_IMS_DIAMETER_ERROR_IDENTITIES_DONT_MATCH returning 403\n");
                    cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_IDENTITIES_DONT_MATCH);
                    result = CSCF_RETURN_FALSE;
                    goto done;
                case RC_IMS_DIAMETER_ERROR_ROAMING_NOT_ALLOWED:
                    LM_ERR("RC_IMS_DIAMETER_ERROR_ROAMING_NOT_ALLOWED returning 403\n");
                    cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_ROAMING_NOT_ALLOWED);
                    result = CSCF_RETURN_FALSE;
                    goto done;
                case RC_IMS_DIAMETER_ERROR_IDENTITY_NOT_REGISTERED:
                    LM_ERR("RC_IMS_DIAMETER_ERROR_IDENTITY_NOT_REGISTERED returning 403\n");
                    cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_IDENTITY_NOT_REGISTERED);
                    result = CSCF_RETURN_FALSE;
                    goto done;
                case RC_IMS_DIAMETER_FIRST_REGISTRATION:
                    goto success;
                case RC_IMS_DIAMETER_SUBSEQUENT_REGISTRATION:
                    goto success;
                case RC_IMS_DIAMETER_SERVER_SELECTION:
                    goto success;

                default:
                    LM_ERR("MSG_403_UNKOWN_EXPERIMENTAL_RC returning 500\n");
                    cscf_reply_transactional_async(t, t->uas.request, 500, MSG_500_UNKOWN_EXPERIMENTAL_RC);
                    result = CSCF_RETURN_FALSE;
                    goto done;
            }
            break;

        case AAA_AUTHORIZATION_REJECTED:
            LM_ERR("AAA_AUTHORIZATION_REJECTED returning 403\n");
            cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_AUTHORIZATION_REJECTED);
            result = CSCF_RETURN_FALSE;
            goto done;
        case AAA_UNABLE_TO_COMPLY:
            LM_ERR("AAA_UNABLE_TO_COMPLY returning 403\n");
            cscf_reply_transactional_async(t, t->uas.request, 500, MSG_500_UNABLE_TO_COMPLY);
            result = CSCF_RETURN_FALSE;
            goto done;

        case AAA_SUCCESS:
            goto success;

        default:
            LM_ERR("MSG_403_UNKOWN_RC returning 403\n");
            cscf_reply_transactional_async(t, t->uas.request, 403, MSG_403_UNKOWN_RC);
            result = CSCF_RETURN_FALSE;
            goto done;
    }

success:
    LM_DBG("successful UAA response\n");
    list = I_get_capab_ordered(server_name, m_capab, m_capab_cnt, o_capab, o_capab_cnt, p_server_names, p_server_names_cnt, 0);

    if (!list) {
        LM_ERR("Empty capability list returning 600\n");
        cscf_reply_transactional_async(t, t->uas.request, 600, MSG_600_EMPTY_LIST);
        result = CSCF_RETURN_FALSE;
        goto done;
    }

    if (!data->callid.len || !add_scscf_list(data->callid, list)) {
        LM_ERR("Error saving capability list 500\n");
        cscf_reply_transactional_async(t, t->uas.request, 500, MSG_500_ERROR_SAVING_LIST);
        result = CSCF_RETURN_FALSE;
        goto done;
    }

    result = CSCF_RETURN_TRUE;

done:
	//free capabilities if they exist
	if (m_capab) shm_free(m_capab);
	if (o_capab) shm_free(o_capab);
	if (p_server_names) shm_free(p_server_names);

    LM_DBG("DBG:UAR Async CDP callback: ... Done resuming transaction\n");
    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from);
    set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to);
    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from);
    set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to);
    set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from);
    set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to);

    create_uaa_return_code(result);

    if (t)tmb.unref_cell(t);
    //free memory
    if (uaa) cdpb.AAAFreeMessage(&uaa);

    tmb.t_continue(data->tindex, data->tlabel, data->act);
    free_saved_uar_transaction_data(data);
    return;

error:
    if (t)tmb.unref_cell(t);
    //free memory
    if (uaa) cdpb.AAAFreeMessage(&uaa);

    tmb.t_continue(data->tindex, data->tlabel, data->act);
    free_saved_uar_transaction_data(data);


}
示例#29
0
文件: htable.c 项目: SipSeb/kamailio
static int child_init(int rank)
{
	struct sip_msg *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;
	int i;
	sr_kemi_eng_t *keng = NULL;
	str evname = str_init("htable:mod-init");

	LM_DBG("rank is (%d)\n", rank);

	if(rank==PROC_MAIN) {
		if(ht_timer_procs>0) {
			for(i=0; i<ht_timer_procs; i++) {
				if(fork_sync_timer(PROC_TIMER, "HTable Timer", 1 /*socks flag*/,
						ht_timer, (void*)(long)i, ht_timer_interval)<0) {
					LM_ERR("failed to start timer routine as process\n");
					return -1; /* error */
				}
			}
		}
	}

	if (rank!=PROC_INIT)
		return 0;


	rt = -1;
	if(ht_event_callback.s==NULL || ht_event_callback.len<=0) {
		rt = route_lookup(&event_rt, evname.s);
		if(rt<0 || event_rt.rlist[rt]==NULL) {
			rt = -1;
		}
	} else {
		keng = sr_kemi_eng_get();
		if(keng==NULL) {
			LM_DBG("event callback (%s) set, but no cfg engine\n",
					ht_event_callback.s);
			goto done;
		}
	}
	if(rt>=0 || ht_event_callback.len>0) {
		LM_DBG("executing event_route[%s] (%d)\n", evname.s, rt);
		if(faked_msg_init()<0)
			return -1;
		fmsg = faked_msg_next();
		rtb = get_route_type();
		set_route_type(REQUEST_ROUTE);
		init_run_actions_ctx(&ctx);
		if(rt>=0) {
			run_top_route(event_rt.rlist[rt], fmsg, &ctx);
		} else {
			if(keng!=NULL) {
				if(keng->froute(fmsg, EVENT_ROUTE,
							&ht_event_callback, &evname)<0) {
					LM_ERR("error running event route kemi callback\n");
					return -1;
				}
			}
		}
		set_route_type(rtb);
		if(ctx.run_flags&DROP_R_F) {
			LM_ERR("exit due to 'drop' in event route\n");
			return -1;
		}
	}

done:
	return 0;
}
示例#30
0
static int msrp_frame_received(sr_event_param_t *evp)
{
	tcp_event_info_t *tev;
	static msrp_frame_t mf;
	sip_msg_t *fmsg;
	struct run_act_ctx ctx;
	int rtb, rt;
	sr_kemi_eng_t *keng = NULL;
	str evname = str_init("msrp:frame-in");

	tev = (tcp_event_info_t*)evp->data;

	if(tev==NULL || tev->buf==NULL || tev->len<=0)
	{
		LM_DBG("invalid parameters\n");
		return -1;
	}

	memset(&mf, 0, sizeof(msrp_frame_t));
	mf.buf.s = tev->buf;
	mf.buf.len = tev->len;
	mf.tcpinfo = tev;
	if(msrp_parse_frame(&mf)<0)
	{
		LM_ERR("error parsing msrp frame\n");
		return -1;
	}
	msrp_reset_env();
	msrp_set_current_frame(&mf);
	fmsg = msrp_fake_sipmsg(&mf);
	if(fmsg != NULL)
		fmsg->rcv = *tev->rcv;
	rtb = get_route_type();
	set_route_type(EVENT_ROUTE);
	init_run_actions_ctx(&ctx);
	if(msrp_event_callback.s == NULL || msrp_event_callback.len <= 0) {
		/* native cfg script execution */
		rt = route_get(&event_rt, evname.s);
		LM_DBG("executing event_route[msrp:frame-in] (%d)\n", rt);
		if(rt >= 0 && event_rt.rlist[rt] != NULL) {
			run_top_route(event_rt.rlist[rt], fmsg, &ctx);
		} else {
			LM_ERR("empty event route block for msrp handling\n");
		}
	} else {
		/* kemi script execution */
		keng = sr_kemi_eng_get();
		if(keng==NULL) {
			LM_ERR("event callback (%s) set, but no cfg engine\n",
					msrp_event_callback.s);
		} else {
			if(sr_kemi_ctx_route(keng, &ctx, fmsg, EVENT_ROUTE,
						&msrp_event_callback, &evname)<0) {
				LM_ERR("error running event route kemi callback\n");
			}
		}
	}
	if(ctx.run_flags & DROP_R_F) {
		LM_DBG("exit due to 'drop' in event route\n");
	}
	set_route_type(rtb);
	if(fmsg != NULL)
		free_sip_msg(fmsg);
	msrp_reset_env();
	msrp_destroy_frame(&mf);
	return 0;
}