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