示例#1
0
void reg_ul_expired_contact(ucontact_t* ptr, int type, void* param)
{
	str profile = {"exp", 3};
	regpv_profile_t *rpp;
	ucontact_t* c0;
	int backup_rt;
	struct run_act_ctx ctx;
	sip_msg_t *fmsg;
	int olen;
	int ilen;
	char *p;

	if(reg_expire_event_rt<0)
		return;

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

	rpp = regpv_get_profile(&profile);
	if(rpp==0)
	{
		LM_ERR("error getting profile structure\n");
		return;
	}
	/* check and free if profile already set */
	if(rpp->flags)
		regpv_free_profile(rpp);

	/* copy aor and ul domain */
	rpp->aor.s = (char*)pkg_malloc(ptr->aor->len*sizeof(char));
	if(rpp->aor.s==NULL)
	{
		LM_ERR("no more pkg\n");
		return;
	}
	memcpy(rpp->aor.s, ptr->aor->s, ptr->aor->len);
	rpp->aor.len = ptr->aor->len;
	rpp->domain = *ptr->domain;
	rpp->flags = 1;

	/* copy contact */
	ilen = sizeof(ucontact_t);

	olen = (ptr->c.len + ptr->received.len + ptr->path.len
			+ ptr->callid.len + ptr->user_agent.len + ptr->ruid.len
			+ ptr->instance.len)*sizeof(char) + ilen;
	c0 = (ucontact_t*)pkg_malloc(olen);
	if(c0==NULL)
	{
		LM_ERR("no more pkg\n");
		goto error;
	}
	memcpy(c0, ptr, ilen);
	c0->domain = NULL;
	c0->aor = NULL;
	c0->next = NULL;
	c0->prev = NULL;

	c0->c.s = (char*)c0 + ilen;
	memcpy(c0->c.s, ptr->c.s, ptr->c.len);
	c0->c.len = ptr->c.len;
	p = c0->c.s + c0->c.len;

	if(ptr->received.s!=NULL)
	{
		c0->received.s = p;
		memcpy(c0->received.s, ptr->received.s, ptr->received.len);
		c0->received.len = ptr->received.len;
		p += c0->received.len;
	}
	if(ptr->path.s!=NULL)
	{
		c0->path.s = p;
		memcpy(c0->path.s, ptr->path.s, ptr->path.len);
		c0->path.len = ptr->path.len;
		p += c0->path.len;
	}
	c0->callid.s = p;
	memcpy(c0->callid.s, ptr->callid.s, ptr->callid.len);
	c0->callid.len = ptr->callid.len;
	p += c0->callid.len;
	if(ptr->user_agent.s!=NULL)
	{
		c0->user_agent.s = p;
		memcpy(c0->user_agent.s, ptr->user_agent.s, ptr->user_agent.len);
		c0->user_agent.len = ptr->user_agent.len;
		p += c0->user_agent.len;
	}
	if(ptr->ruid.s!=NULL)
	{
		c0->ruid.s = p;
		memcpy(c0->ruid.s, ptr->ruid.s, ptr->ruid.len);
		c0->ruid.len = ptr->ruid.len;
		p += c0->ruid.len;
	}
	if(ptr->instance.s!=NULL)
	{
		c0->instance.s = p;
		memcpy(c0->instance.s, ptr->instance.s, ptr->instance.len);
		c0->instance.len = ptr->instance.len;
		p += c0->instance.len;
	}

	rpp->contacts = c0;
	rpp->nrc = 1;
	LM_DBG("saved contact for <%.*s> in [%.*s]\n",
			ptr->aor->len, ptr->aor->s, rpp->pname.len, rpp->pname.s);

	fmsg = faked_msg_next();
	backup_rt = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	run_top_route(event_rt.rlist[reg_expire_event_rt], fmsg, 0);
	set_route_type(backup_rt);

	return;
error:
	regpv_free_profile(rpp);
	return;
}
示例#2
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;

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

	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)
		{
			dlg_bye_all(dlg, NULL);
			/* run event route for end of dlg */
			dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
			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);
	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, 0);

		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;
}
示例#3
0
int th_execute_event_route(sip_msg_t *msg, sr_event_param_t *evp)
{
	struct sip_msg *fmsg;
	struct run_act_ctx ctx;
	int rtb;
	sr_kemi_eng_t *keng = NULL;
	struct onsend_info onsnd_info = {0};

	if(_th_eventrt_outgoing<0) {
		if(_th_eventrt_callback.s!=NULL || _th_eventrt_callback.len>0) {
			keng = sr_kemi_eng_get();
			if(keng==NULL) {
				LM_DBG("event callback (%s) set, but no cfg engine\n",
						_th_eventrt_callback.s);
				goto done;
			}
		}
	}

	if(_th_eventrt_outgoing<0 && keng==NULL) {
		return 0;
	}

	LM_DBG("executing event_route[topoh:...] (%d)\n",
			_th_eventrt_outgoing);
	fmsg = faked_msg_next();

	onsnd_info.to = &evp->dst->to;
	onsnd_info.send_sock = evp->dst->send_sock;
	if(msg!=NULL) {
		onsnd_info.buf = msg->buf;
		onsnd_info.len = msg->len;
		onsnd_info.msg = msg;
	} else {
		onsnd_info.buf = fmsg->buf;
		onsnd_info.len = fmsg->len;
		onsnd_info.msg = fmsg;
	}
	p_onsend = &onsnd_info;

	rtb = get_route_type();
	set_route_type(REQUEST_ROUTE);
	init_run_actions_ctx(&ctx);
	if(_th_eventrt_outgoing>=0) {
		run_top_route(event_rt.rlist[_th_eventrt_outgoing], fmsg, &ctx);
	} else {
		if(keng!=NULL) {
			if(sr_kemi_ctx_route(keng, &ctx, fmsg, EVENT_ROUTE,
						&_th_eventrt_callback, &_th_eventrt_name)<0) {
				LM_ERR("error running event route kemi callback\n");
				p_onsend=NULL;
				return -1;
			}
		}
	}
	set_route_type(rtb);
	if(ctx.run_flags&DROP_R_F) {
		LM_DBG("exit due to 'drop' in event route\n");
		p_onsend=NULL;
		return 1;
	}

done:
	p_onsend=NULL;
	return 0;
}
示例#4
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);

		/* set end time */
		dlg->end_ts = (unsigned int)(time(0));

		/* 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;
}