Пример #1
0
void ht_expired_run_event_route(int routeid)
{
	int backup_rt;
	sip_msg_t *fmsg;

	if (routeid < 0 || event_rt.rlist[routeid] == NULL)
	{
		LM_DBG("route does not exist\n");
		return;
	}

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

	backup_rt = get_route_type();

	set_route_type(EVENT_ROUTE);
	run_top_route(event_rt.rlist[routeid], fmsg, 0);

	set_route_type(backup_rt);
}
Пример #2
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;
}
Пример #3
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);
}
Пример #4
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;
}
Пример #5
0
static inline void run_resume_route( int resume_route, struct sip_msg *msg)
{
    /* run the resume route and if it ends the msg handling (no other aysnc
     * started), run the post script callbacks. */
    if ( (run_top_route(rlist[resume_route].a, msg) & ACT_FL_TBCONT) == 0 )
        exec_post_req_cb(msg);
}
Пример #6
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);
}
Пример #7
0
void ht_expired_run_event_route(char *route)
{
	int rt, backup_rt;
	sip_msg_t *fmsg;

	if (route == NULL)
	{
		LM_ERR("bad route\n");
	}

	LM_DBG("ht_expired_run_event_route event_route[%s]\n", route);

	rt = route_get(&event_rt, route);

	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->parsed_orig_ruri_ok = 0;

	backup_rt = get_route_type();

	set_route_type(EVENT_ROUTE);
	run_top_route(event_rt.rlist[rt], fmsg, 0);

	set_route_type(backup_rt);
}
Пример #8
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;
}
Пример #9
0
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);
}
Пример #10
0
static int scriptroute_raise(struct sip_msg *msg, str* ev_name,
							 evi_reply_sock *sock, evi_params_t *params)
{
	evi_params_t * backup_params;
	str * backup_name;

	if (!sock || !(sock->flags & EVI_PARAMS)) {
		LM_ERR("no socket found\n");
		return -1;
	}

	/* check the socket type */
	if (!(sock->flags & SCRIPTROUTE_FLAG)) {
		LM_ERR("invalid socket type\n");
		return -1;
	}

	/* save the previous parameters */
	backup_params = parameters;
	backup_name = event_name;

	parameters = params;
	event_name = ev_name;

	run_top_route(event_rlist[SR_SOCK_ROUTE(sock)].a, msg);

	/* restore previous parameters */
	parameters = backup_params;
	event_name = backup_name;

	return 0;
}
Пример #11
0
void route_timer_f(unsigned int ticks, void* param)
{
    struct action* a = (struct action*)param;
    static struct sip_msg* req= NULL;

    if(req == NULL)
    {
        req = (struct sip_msg*)pkg_malloc(sizeof(struct sip_msg));
        if(req == NULL)
        {
            LM_ERR("No more memory\n");
            return;
        }
        memset(req, 0, sizeof(struct sip_msg));
        req->first_line.type = SIP_REQUEST;
        req->first_line.u.request.method.s= "DUMMY";
        req->first_line.u.request.method.len= 5;
        req->first_line.u.request.uri.s= "sip:[email protected]";
        req->first_line.u.request.uri.len= 19;
    }

    if(a == NULL) {
        LM_ERR("NULL action\n");
        return;
    }

    run_top_route(a, req);

    /* clean whatever extra structures were added by script functions */
    free_sip_msg(req);
    /* remove all added AVP - here we use all the time the default AVP list */
    reset_avps( );
}
Пример #12
0
void evrexec_process(evrexec_task_t *it, int idx)
{
	sip_msg_t *fmsg;
	sr_kemi_eng_t *keng = NULL;
	str sidx = STR_NULL;

	if(it!=NULL) {
		fmsg = faked_msg_next();
		set_route_type(LOCAL_ROUTE);
		if(it->wait>0) sleep_us(it->wait);
		keng = sr_kemi_eng_get();
		if(keng==NULL) {
			if(it->rtid>=0 && event_rt.rlist[it->rtid]!=NULL) {
				run_top_route(event_rt.rlist[it->rtid], fmsg, 0);
			} else {
				LM_WARN("empty event route block [%.*s]\n",
						it->ename.len, it->ename.s);
			}
		} else {
			sidx.s = int2str(idx, &sidx.len);
			if(sr_kemi_route(keng, fmsg, EVENT_ROUTE,
						&it->ename, &sidx)<0) {
				LM_ERR("error running event route kemi callback\n");
			}
		}
	}
	/* avoid exiting the process */
	while(1) { sleep(3600); }
}
Пример #13
0
void rpc_evr_run(rpc_t *rpc, void *c)
{
	str evr_name = STR_NULL;
	str evr_data = STR_NULL;
	int ret = 0;
	int evr_id = -1;
	sr_kemi_eng_t *keng = NULL;
	sip_msg_t *fmsg = NULL;
	int rtbk = 0;
	char evr_buf[2];

	ret = rpc->scan(c, "s*s", &evr_name.s, &evr_data.s);
	if(ret<1) {
		LM_ERR("failed getting the parameters");
		rpc->fault(c, 500, "Invalid parameters");
		return;
	}
	evr_name.len = strlen(evr_name.s);
	if(ret<2) {
		evr_buf[0] = '\0';
		evr_data.s = evr_buf;
		evr_data.len = 0;
	} else {
		evr_data.len = strlen(evr_data.s);
	}

	pv_evr_data = &evr_data;
	keng = sr_kemi_eng_get();
	if(keng==NULL) {
		evr_id = route_lookup(&event_rt, evr_name.s);
		if(evr_id == -1) {
			pv_evr_data = NULL;
			LM_ERR("event route not found: %.*s\n", evr_name.len, evr_name.s);
			rpc->fault(c, 500, "Event route not found");
			return;
		}
	} else {
		evr_id = -1;
	}

	fmsg = faked_msg_next();
	rtbk = get_route_type();
	set_route_type(LOCAL_ROUTE);

	if(evr_id>=0) {
		if(event_rt.rlist[evr_id]!=NULL) {
			run_top_route(event_rt.rlist[evr_id], fmsg, 0);
		} else {
			LM_WARN("empty event route block [%.*s]\n",
					evr_name.len, evr_name.s);
		}
	} else {
		if(sr_kemi_route(keng, fmsg, EVENT_ROUTE, &evr_name, &evr_data)<0) {
			LM_ERR("error running event route kemi callback\n");
		}
	}
	set_route_type(rtbk);
	pv_evr_data = NULL;
}
Пример #14
0
/* return 1 if a failure_route processes */
static inline int run_failure_handlers(struct cell *t)
{
	static struct sip_msg faked_req;
	struct sip_msg *shmem_msg;
	struct ua_client *uac;
	int on_failure;

	shmem_msg = t->uas.request;
	uac = &t->uac[picked_branch];

	/* failure_route for a local UAC? */
	if (!shmem_msg || REQ_LINE(shmem_msg).method_value==METHOD_CANCEL ) {
		LM_WARN("no UAC or CANCEL support (%d, %d) \n",
				t->on_negative, t->tmcb_hl.reg_types);
		return 0;
	}

	/* don't start faking anything if we don't have to */
	if ( !has_tran_tmcbs( t, TMCB_ON_FAILURE) && !t->on_negative ) {
		LM_WARN("no negative handler (%d, %d)\n",t->on_negative, 
			t->tmcb_hl.reg_types);
		return 1;
	}

	if (!fake_req(&faked_req, shmem_msg, &t->uas, uac)) {
		LM_ERR("fake_req failed\n");
		return 0;
	}
	/* fake also the env. conforming to the fake msg */
	faked_env( t, &faked_req);

	/* DONE with faking ;-) -> run the failure handlers */
	if ( has_tran_tmcbs( t, TMCB_ON_FAILURE) ) {
		run_trans_callbacks( TMCB_ON_FAILURE, t, &faked_req,
				uac->reply, uac->last_received);
	}
	if (t->on_negative) {
		/* update flags in transaction if changed by callbacks */
		shmem_msg->flags = faked_req.flags;
		/* avoid recursion -- if failure_route forwards, and does not 
		 * set next failure route, failure_route will not be reentered
		 * on failure */
		on_failure = t->on_negative;
		t->on_negative=0;
		/* run a reply_route action if some was marked */
		run_top_route(failure_rlist[on_failure].a, &faked_req);
	}

	/* restore original environment and free the fake msg */
	faked_env( t, 0);
	free_faked_req(&faked_req,t);

	/* if failure handler changed flag, update transaction context */
	shmem_msg->flags = faked_req.flags;
	/* branch flags do not need to be updated as this branch will be never
	 * used again */
	return 1;
}
Пример #15
0
int run_pike_route( struct sip_msg *msg, void *rt ) {
	/* the check was dropped */
	if ( run_top_route( rlist[(int)(long)rt].a, msg)&ACT_FL_DROP)
		return SCB_RUN_ALL;

	/* run the check */
	if (pike_check_req(msg)<0)
		return SCB_DROP_MSG;

	return SCB_RUN_ALL;
}
Пример #16
0
void ht_handle_expired_record(ht_t *ht, ht_cell_t *cell)
{
	int backup_rt;
	sip_msg_t *fmsg;
	sr_kemi_eng_t *keng = NULL;

	if(ht_event_callback.s==NULL || ht_event_callback.len<=0) {
		if (ht->evex_index < 0 || event_rt.rlist[ht->evex_index] == NULL) {
			LM_DBG("route does not exist\n");
			return;
		}
	} else {
		keng = sr_kemi_eng_get();
		if(keng==NULL) {
			LM_DBG("event callback (%s) set, but no cfg engine\n",
					ht_event_callback.s);
			return;
		}
	}

	LM_DBG("running event_route[htable:expired:%.*s]\n",
			ht->name.len, ht->name.s);

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

	ht_expired_cell = cell;

	fmsg = faked_msg_next();
	fmsg->parsed_orig_ruri_ok = 0;

	backup_rt = get_route_type();

	set_route_type(EVENT_ROUTE);
	if(ht->evex_index >= 0) {
		run_top_route(event_rt.rlist[ht->evex_index], fmsg, 0);
	} else {
		if(keng!=NULL) {
			if(keng->froute(fmsg, EVENT_ROUTE,
						&ht_event_callback, &ht->evex_name)<0) {
				LM_ERR("error running event route kemi callback\n");
			}
		}
	}

	set_route_type(backup_rt);

	ht_expired_cell = NULL;
}
Пример #17
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);
}
Пример #18
0
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;
}
Пример #19
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;
}
Пример #20
0
/*!
 * \brief Timer function that removes expired dialogs, run timeout route
 * \param tl dialog timer list
 */
void dlg_ontimeout(struct dlg_tl *tl) {
    struct dlg_cell *dlg;
    int new_state, old_state, unref;
    struct sip_msg *fmsg;

    /* get the dialog tl payload */
    dlg = ((struct dlg_cell*) ((char *) (tl) -
            (unsigned long) (&((struct dlg_cell*) 0)->tl)));

    if (dlg->toroute > 0 && dlg->toroute < main_rt.entries
            && main_rt.rlist[dlg->toroute] != NULL) {
        fmsg = faked_msg_next();
        if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE) > 0) {
            dlg_set_ctx_dialog(dlg);
            LM_DBG("executing route %d on timeout\n", dlg->toroute);
            set_route_type(REQUEST_ROUTE);
            run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
            dlg_set_ctx_dialog(0);
            exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
        }
    }

    if ((dlg->dflags & DLG_FLAG_TOBYE)
            && (dlg->state == DLG_STATE_CONFIRMED)) {
        //TODO: dlg_bye_all(dlg, NULL);
        unref_dlg(dlg, 1);
        return;
    }

    next_state_dlg(dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref, 0);

    if (new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) {
        LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s'\n",
                dlg->callid.len, dlg->callid.s,
                dlg->from_tag.len, dlg->from_tag.s);


        /* dialog timeout */
        run_dlg_callbacks(DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, 0);

        unref_dlg(dlg, unref + 1);
    } else {
        unref_dlg(dlg, 1);
    }

    return;
}
Пример #21
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;
}
Пример #22
0
/* Returns:
    0  : ACK to a local reply
    -1 : error
    1  : is not an ACK  or a non-local ACK
*/
int sl_filter_ACK(struct sip_msg *msg, unsigned int flags, void *bar )
{
    str *tag_str;

    if (msg->first_line.u.request.method_value!=METHOD_ACK)
        goto pass_it;

    /*check the timeout value*/
    if ( *(sl_timeout)<= get_ticks() )
    {
        DBG("DEBUG : sl_filter_ACK: to late to be a local ACK!\n");
        goto pass_it;
    }

    /*force to parse to header -> we need it for tag param*/
    if (parse_headers( msg, HDR_TO_F, 0 )==-1)
    {
        LOG(L_ERR,"ERROR : SL_FILTER_ACK: unable to parse To header\n");
        return -1;
    }

    if (msg->to) {
        tag_str = &(get_to(msg)->tag_value);
        if ( tag_str->len==TOTAG_VALUE_LEN )
        {
            /* calculate the variable part of to-tag */
            calc_crc_suffix(msg, tag_suffix);
            /* test whether to-tag equal now */
            if (memcmp(tag_str->s,sl_tag.s,sl_tag.len)==0) {
                LM_DBG("SL local ACK found -> dropping it!\n" );
                update_sl_filtered_acks();
                sl_run_callbacks(SLCB_ACK_FILTERED, msg, 0, 0, 0, 0);
                if(unlikely(_sl_filtered_ack_route>=0)) {
                    run_top_route(event_rt.rlist[_sl_filtered_ack_route],
                                  msg, 0);
                }
                return 0;
            }
        }
    }

pass_it:
    return 1;
}
Пример #23
0
/*!
 * \brief Execute event routes based on new state
 *
 */
void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate)
{
	sip_msg_t *fmsg;
	int rt;
	int bkroute;

	if(dlg==NULL)
		return;
	if(ostate==nstate)
		return;

	rt = -1;
	if(nstate==DLG_STATE_CONFIRMED_NA) {
		rt = dlg_event_rt[DLG_EVENTRT_START];
	} else if(nstate==DLG_STATE_DELETED) {
		if(ostate==DLG_STATE_CONFIRMED || ostate==DLG_STATE_CONFIRMED_NA)
			rt = dlg_event_rt[DLG_EVENTRT_END];
		else if(ostate==DLG_STATE_UNCONFIRMED || ostate==DLG_STATE_EARLY)
			rt = dlg_event_rt[DLG_EVENTRT_FAILED];
	}

	if(rt==-1 || event_rt.rlist[rt]==NULL)
		return;

	if(msg==NULL)
		fmsg = faked_msg_next();
	else
		fmsg = msg;

	if (exec_pre_script_cb(fmsg, LOCAL_CB_TYPE)>0)
	{
		dlg_ref(dlg, 1);
		dlg_set_ctx_iuid(dlg);
		LM_DBG("executing event_route %d on state %d\n", rt, nstate);
		bkroute = get_route_type();
		set_route_type(LOCAL_ROUTE);
		run_top_route(event_rt.rlist[rt], fmsg, 0);
		dlg_reset_ctx_iuid();
		exec_post_script_cb(fmsg, LOCAL_CB_TYPE);
		dlg_unref(dlg, 1);
		set_route_type(bkroute);
	}
}
Пример #24
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;
}
Пример #25
0
void stm_timer_exec(unsigned int ticks, void *param)
{
	stm_timer_t *it;
	stm_route_t *rt;
	sip_msg_t *fmsg;

	if(param==NULL)
		return;
	it = (stm_timer_t*)param;
	if(it->rt==NULL)
		return;

	for(rt=it->rt; rt; rt=rt->next)
	{
		fmsg = faked_msg_next();
		if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)==0 )
			continue; /* drop the request */
		set_route_type(REQUEST_ROUTE);
		run_top_route(main_rt.rlist[rt->route], fmsg, 0);
		exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
	}
}
Пример #26
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);
}
Пример #27
0
void event_route_handler(int rank)
{
	/* init blocking reader */
	route_init_reader();
	route_send_t *route_s;
	struct sip_msg* dummy_req;

	dummy_req = (struct sip_msg*)pkg_malloc(sizeof(struct sip_msg));
	if (dummy_req == NULL) {
		LM_ERR("oom\n");
		return;
	}
	memset(dummy_req, 0, sizeof(struct sip_msg));
	dummy_req->first_line.type = SIP_REQUEST;
	dummy_req->first_line.u.request.method.s= "DUMMY";
	dummy_req->first_line.u.request.method.len= 5;
	dummy_req->first_line.u.request.uri.s= "sip:[email protected]";
	dummy_req->first_line.u.request.uri.len= 19;


	/* waiting for commands */
	for (;;) {
		route_s = route_receive();
		if (!route_s) {
			LM_ERR("invalid receive sock info\n");
			goto end;
		}

		event_name = &route_s->event;
		parameters = &route_s->params;
		run_top_route(route_s->a, dummy_req);
end:
		if (route_s)
			shm_free(route_s);
	}
}
Пример #28
0
/* WARNING: buf must be 0 terminated (buf[len]=0) or some things might 
 * break (e.g.: modules/textops)
 */
int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
{
	struct sip_msg* msg;
	struct run_act_ctx ctx;
	int ret;
#ifdef STATS
	int skipped = 1;
	struct timeval tvb, tve;	
	struct timezone tz;
	unsigned int diff;
#endif
	str inb;

	inb.s = buf;
	inb.len = len;
	sr_event_exec(SREV_NET_DATA_IN, (void*)&inb);
	len = inb.len;

	msg=pkg_malloc(sizeof(struct sip_msg));
	if (msg==0) {
		LOG(L_ERR, "ERROR: receive_msg: no mem for sip_msg\n");
		goto error00;
	}
	msg_no++;
	/* number of vias parsed -- good for diagnostic info in replies */
	via_cnt=0;

	memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
	/* fill in msg */
	msg->buf=buf;
	msg->len=len;
	/* zero termination (termination of orig message bellow not that
	   useful as most of the work is done with scratch-pad; -jiri  */
	/* buf[len]=0; */ /* WARNING: zero term removed! */
	msg->rcv=*rcv_info;
	msg->id=msg_no;
	msg->pid=my_pid();
	msg->set_global_address=default_global_address;
	msg->set_global_port=default_global_port;
	
	if(likely(sr_msg_time==1)) msg_set_time(msg);

	if (parse_msg(buf,len, msg)!=0){
		if(sr_event_exec(SREV_RCV_NOSIP, (void*)msg)!=0) {
			LOG(cfg_get(core, core_cfg, corelog),
				"core parsing of SIP message failed (%s:%d/%d)\n",
				ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
				(int)msg->rcv.proto);
			sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
		}
		goto error02;
	}
	DBG("After parse_msg...\n");


	/* ... clear branches from previous message */
	clear_branches();

	if (msg->first_line.type==SIP_REQUEST){
		ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
		if (!IS_SIP(msg)){
			if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
				if (unlikely(ret==NONSIP_MSG_ERROR))
					goto error03;
				goto end; /* drop the message */
			}
		}
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
			STATS_BAD_MSG();
			goto error02;
		}
		/* check if necessary to add receive?->moved to forward_req */
		/* check for the alias stuff */
#ifdef USE_TCP
		if (msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases) && 
				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
#ifdef USE_TLS
					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
#endif
				)
			){
			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
									rcv_info->proto)!=0){
				LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
				/* continue */
			}
		}
#endif

	/*	skip: */
		DBG("preparing to run routing scripts...\n");
#ifdef  STATS
		gettimeofday( & tvb, &tz );
#endif
		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		   script processing, don't do so
		   if we are here basic sanity checks are already done
		   (like presence of at least one via), so you can count
		   on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
		{
			STATS_REQ_FWD_DROP();
			goto end; /* drop the request */
		}

		set_route_type(REQUEST_ROUTE);
		/* exec the routing script */
		if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
			LOG(L_WARN, "WARNING: receive_msg: "
					"error while trying script\n");
			goto error_req;
		}

#ifdef STATS
		gettimeofday( & tve, &tz );
		diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
		stats->processed_requests++;
		stats->acc_req_time += diff;
		DBG("successfully ran routing scripts...(%d usec)\n", diff);
		STATS_RX_REQUEST( msg->first_line.u.request.method_value );
#endif

		/* execute post request-script callbacks */
		exec_post_script_cb(msg, REQUEST_CB_TYPE);
	}else if (msg->first_line.type==SIP_REPLY){
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
			STATS_BAD_RPL();
			goto error02;
		}

#ifdef STATS
		gettimeofday( & tvb, &tz );
		STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
#endif
		
		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		   script processing, don't do so
		   if we are here basic sanity checks are already done
		   (like presence of at least one via), so you can count
		   on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
		{
			STATS_RPL_FWD_DROP();
			goto end; /* drop the reply */
		}

		/* exec the onreply routing script */
		if (onreply_rt.rlist[DEFAULT_RT]){
			set_route_type(CORE_ONREPLY_ROUTE);
			ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
#ifndef NO_ONREPLY_ROUTE_ERROR
			if (unlikely(ret<0)){
				LOG(L_WARN, "WARNING: receive_msg: "
						"error while trying onreply script\n");
				goto error_rpl;
			}else
#endif /* NO_ONREPLY_ROUTE_ERROR */
			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
				STATS_RPL_FWD_DROP();
				goto skip_send_reply; /* drop the message, no error */
			}
		}
		/* send the msg */
		forward_reply(msg);
	skip_send_reply:
#ifdef STATS
		gettimeofday( & tve, &tz );
		diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
		stats->processed_responses++;
		stats->acc_res_time+=diff;
		DBG("successfully ran reply processing...(%d usec)\n", diff);
#endif

		/* execute post reply-script callbacks */
		exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	}

end:
#ifdef STATS
	skipped = 0;
#endif
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	DBG("receive_msg: cleaning up\n");
	free_sip_msg(msg);
	pkg_free(msg);
#ifdef STATS
	if (skipped) STATS_RX_DROPS;
#endif
	return 0;
#ifndef NO_ONREPLY_ROUTE_ERROR
error_rpl:
	/* execute post reply-script callbacks */
	exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	goto error02;
#endif /* NO_ONREPLY_ROUTE_ERROR */
error_req:
	DBG("receive_msg: error:...\n");
	/* execute post request-script callbacks */
	exec_post_script_cb(msg, REQUEST_CB_TYPE);
error03:
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
error02:
	free_sip_msg(msg);
	pkg_free(msg);
error00:
	STATS_RX_DROPS;
	return -1;
}
Пример #29
0
/*  This function is called whenever a reply for our module is received; 
  * we need to register  this function on module initialization;
  *  Returns :   0 - core router stops
  *              1 - core router relay statelessly
  */
int reply_received( struct sip_msg  *p_msg )
{
	int msg_status;
	int last_uac_status;
	int branch;
	int reply_status;
	utime_t timer;
	/* has the transaction completed now and we need to clean-up? */
	branch_bm_t cancel_bitmap;
	struct ua_client *uac;
	struct cell *t;
	struct usr_avp **backup_list;
	unsigned int has_reply_route;

	set_t(T_UNDEFINED);

	/* make sure we know the associated transaction ... */
	if (t_check(p_msg, &branch ) == -1) goto not_found;

	/*... if there is none, tell the core router to fwd statelessly */
	t = get_t();
	if ((t == 0) || (t == T_UNDEFINED)) goto not_found;

	cancel_bitmap=0;
	msg_status=p_msg->REPLY_STATUS;

	uac=&t->uac[branch];
	LM_DBG("org. status uas=%d, uac[%d]=%d local=%d is_invite=%d)\n",
		t->uas.status, branch, uac->last_received, 
		is_local(t), is_invite(t));
	last_uac_status=uac->last_received;
	if_update_stat( tm_enable_stats, tm_rcv_rpls , 1);

	/* it's a cancel which is not e2e ? */
	if ( get_cseq(p_msg)->method_id==METHOD_CANCEL && is_invite(t) ) {
		/* ... then just stop timers */
		reset_timer( &uac->local_cancel.retr_timer);
		if ( msg_status >= 200 ) {
				reset_timer( &uac->local_cancel.fr_timer);
		}
		LM_DBG("reply to local CANCEL processed\n");
		goto done;
	}

	/* *** stop timers *** */
	/* stop retransmission */
	reset_timer(&uac->request.retr_timer);

	/* stop final response timer only if I got a final response */
	if ( msg_status >= 200 ) {
		reset_timer( &uac->request.fr_timer);
	}

	/* acknowledge negative INVITE replies (do it before detailed
	 * on_reply processing, which may take very long, like if it
	 * is attempted to establish a TCP connection to a fail-over dst */
	if (is_invite(t) && ((msg_status >= 300) ||
	(is_local(t) && !no_autoack(t) && msg_status >= 200) )) {
		if (send_ack(p_msg, t, branch)!=0)
			LM_ERR("failed to send ACK (local=%s)\n", is_local(t)?"yes":"no");
	}

	_tm_branch_index = branch;

	/* processing of on_reply block */
	has_reply_route = (t->on_reply) || (t->uac[branch].on_reply);
	if (has_reply_route) {
		if (onreply_avp_mode) {
			/* lock the reply*/
			LOCK_REPLIES( t );
			/* set the as avp_list the one from transaction */
			backup_list = set_avp_list(&t->user_avps);
		} else {
			backup_list = 0;
		}
		/* transfer transaction flag to branch context */
		p_msg->flags = t->uas.request->flags;
		setb0flags(t->uac[branch].br_flags);
		/* run block - first per branch and then global one */
		if ( t->uac[branch].on_reply &&
		(run_top_route(onreply_rlist[t->uac[branch].on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		if ( t->on_reply && (run_top_route(onreply_rlist[t->on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		/* transfer current message context back to t */
		t->uac[branch].br_flags = getb0flags();
		t->uas.request->flags = p_msg->flags;
		if (onreply_avp_mode)
			/* restore original avp list */
			set_avp_list( backup_list );
	}

	if (!onreply_avp_mode || !has_reply_route)
		/* lock the reply*/
		LOCK_REPLIES( t );

	/* mark that the UAC received replies */
	uac->flags |= T_UAC_HAS_RECV_REPLY;

	/* we fire a cancel on spot if (a) branch is marked "to be canceled" or (b)
	 * the whole transaction was canceled (received cancel) and no cancel sent
	 * yet on this branch; and of course, only if a provisional reply :) */
	if (t->uac[branch].flags&T_UAC_TO_CANCEL_FLAG ||
	((t->flags&T_WAS_CANCELLED_FLAG) && !t->uac[branch].local_cancel.buffer.s)) {
		if ( msg_status < 200 )
			/* reply for an UAC with a pending cancel -> do cancel now */
			cancel_branch(t, branch);
		/* reset flag */
		t->uac[branch].flags &= ~(T_UAC_TO_CANCEL_FLAG);
	}

	if (is_local(t)) {
		reply_status = local_reply(t,p_msg, branch,msg_status,&cancel_bitmap);
		if (reply_status == RPS_COMPLETED) {
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* There is no need to call set_final_timer because we know
			 * that the transaction is local */
			put_on_wait(t);
		}
	} else {
		reply_status = relay_reply(t,p_msg,branch,msg_status,&cancel_bitmap);
		/* clean-up the transaction when transaction completed */
		if (reply_status == RPS_COMPLETED) {
			/* no more UAC FR/RETR (if I received a 2xx, there may
			 * be still pending branches ...
			 */
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* FR for negative INVITES, WAIT anything else */
			/* set_final_timer(t); */
		}
	}
	
	if (reply_status!=RPS_PROVISIONAL)
		goto done;
	
	/* update FR/RETR timers on provisional replies */
	if (msg_status < 200 && (restart_fr_on_each_reply ||
	((last_uac_status<msg_status) &&
	((msg_status >= 180) || (last_uac_status == 0)))
	) ) { /* provisional now */
		if (is_invite(t)) {
			/* invite: change FR to longer FR_INV, do not
			 * attempt to restart retransmission any more
			 */
			backup_list = set_avp_list(&t->user_avps);
			if (!fr_inv_avp2timer(&timer)) {
				LM_DBG("FR_INV_TIMER = %lld\n", timer);
				set_timer(&uac->request.fr_timer,
					FR_INV_TIMER_LIST, &timer);
			} else {
				set_timer(& uac->request.fr_timer, FR_INV_TIMER_LIST, 0);
			}
			set_avp_list(backup_list);
		} else {
			/* non-invite: restart retransmissions (slow now) */
			uac->request.retr_list = RT_T2;
			set_timer(&uac->request.retr_timer, RT_T2, 0);
		}
	} /* provisional replies */
	
done:
	/* we are done with the transaction, so unref it - the reference
	 * was incremented by t_check() function -bogdan*/
	t_unref(p_msg);
	/* don't try to relay statelessly neither on success
	 * (we forwarded statefully) nor on error; on troubles, 
	 * simply do nothing; that will make the other party to 
	 * retransmit; hopefuly, we'll then be better off 
	 */
	_tm_branch_index = 0;
	return 0;
not_found:
	set_t(T_UNDEFINED);
	return 1;
}
Пример #30
0
/*!
 * \brief Timer function that removes expired dialogs, run timeout route
 * \param tl dialog timer list
 */
void dlg_ontimeout(struct dlg_tl *tl)
{
	dlg_cell_t *dlg;
	int new_state, old_state, unref;
	sip_msg_t *fmsg;
	void* timeout_cb = 0;

	/* get the dialog tl payload */
	dlg = ((struct dlg_cell*)((char *)(tl) -
			(unsigned long)(&((struct dlg_cell*)0)->tl)));

	/* mark dialog as expired */
	dlg->dflags |= DLG_FLAG_EXPIRED;

	if(dlg->state==DLG_STATE_CONFIRMED_NA
				|| dlg->state==DLG_STATE_CONFIRMED)
	{
		if(dlg->toroute>0 && dlg->toroute<main_rt.entries
			&& main_rt.rlist[dlg->toroute]!=NULL)
		{
			fmsg = faked_msg_next();
			if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
			{
				dlg_ref(dlg, 1);
				dlg_set_ctx_iuid(dlg);
				LM_DBG("executing route %d on timeout\n", dlg->toroute);
				set_route_type(REQUEST_ROUTE);
				run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
				dlg_reset_ctx_iuid();
				exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
				dlg_unref(dlg, 1);
			}
		}

		if(dlg->iflags&DLG_IFLAG_TIMEOUTBYE)
		{
			/* set the dialog context so that it's available in
			 * tm:local-request event route */
			dlg_set_ctx_iuid(dlg);
			if(dlg_bye_all(dlg, NULL)<0)
				dlg_unref(dlg, 1);
			dlg_reset_ctx_iuid();	

			dlg_unref(dlg, 1);
			if_update_stat(dlg_enable_stats, expired_dlgs, 1);
			return;
		}
	}

	next_state_dlg( dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref);
    /* used for computing duration for timed out acknowledged dialog */
	if (DLG_STATE_CONFIRMED == old_state) {
		timeout_cb = (void *)CONFIRMED_DIALOG_STATE;
	}	

	dlg_run_event_route(dlg, NULL, old_state, new_state);

	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
		LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s' '%.*s'\n",
			dlg->callid.len, dlg->callid.s,
			dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
			dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);

		/* dialog timeout */
		run_dlg_callbacks( DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, timeout_cb);

		dlg_unref(dlg, unref+1);

		if_update_stat( dlg_enable_stats, expired_dlgs, 1);
		if_update_stat( dlg_enable_stats, active_dlgs, -1);
	} else {
		dlg_unref(dlg, 1);
	}

	return;
}