Module: kamailio Branch: master Commit: a051bd98652dd92a93175b7cab1e239bab851160 URL: https://github.com/kamailio/kamailio/commit/a051bd98652dd92a93175b7cab1e239b...
Author: rdboisvert rdbprog@gmail.com Committer: GitHub noreply@github.com Date: 2016-09-07T16:39:21-04:00
mohqueue: prevent calls sticking in queue
- query RTP to see if the link is active - update user-agent version - fixed edge case where REFER response arrives after call closed
---
Modified: modules/mohqueue/mohq.c Modified: modules/mohqueue/mohq.h Modified: modules/mohqueue/mohq_funcs.c
---
Diff: https://github.com/kamailio/kamailio/commit/a051bd98652dd92a93175b7cab1e239b... Patch: https://github.com/kamailio/kamailio/commit/a051bd98652dd92a93175b7cab1e239b...
---
diff --git a/modules/mohqueue/mohq.c b/modules/mohqueue/mohq.c index bc54aca..55a85ea 100644 --- a/modules/mohqueue/mohq.c +++ b/modules/mohqueue/mohq.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-15 Robert Boisvert + * Copyright (C) 2013-16 Robert Boisvert * * This file is part of the mohqueue module for Kamailio, a free SIP server. * @@ -42,6 +42,7 @@ static int mod_init (void); **********/
mod_data *pmod_data; +pv_spec_t *prtp_pv;
/********** * module exports @@ -98,6 +99,12 @@ struct module_exports exports = { };
/********** +* local constants +**********/ + +str prtpstat [1] = {STR_STATIC_INIT ("$rtpstat")}; + +/********** * local functions **********/
@@ -349,6 +356,8 @@ return; int mod_init (void)
{ +int rtplen; + /********** * o allocate shared mem and init * o init configuration data @@ -431,6 +440,23 @@ if (!pmod_data->fn_rtp_destroy) }
/********** +* get RTPSTAT pv spec +**********/ + +rtplen = pv_locate_name (prtpstat); +if(rtplen != prtpstat->len) + { + LM_ERR ("Unable to find RTPSTAT pv!\n"); + goto initerr; + } +prtp_pv = pv_cache_get (&prtpstat); +if(!prtp_pv) + { + LM_ERR ("Unable to find pv spec for RTPSTAT!\n"); + goto initerr; + } + +/********** * init MOH and call queue locks **********/
diff --git a/modules/mohqueue/mohq.h b/modules/mohqueue/mohq.h index 207bcba..de2ef66 100644 --- a/modules/mohqueue/mohq.h +++ b/modules/mohqueue/mohq.h @@ -131,6 +131,7 @@ typedef struct **********/
extern mod_data *pmod_data; +extern pv_spec_t *prtp_pv; extern rtpmap prtpmap [];
#endif /* MOHQ_H */ \ No newline at end of file diff --git a/modules/mohqueue/mohq_funcs.c b/modules/mohqueue/mohq_funcs.c index 86699ae..3722e00 100644 --- a/modules/mohqueue/mohq_funcs.c +++ b/modules/mohqueue/mohq_funcs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-15 Robert Boisvert + * Copyright (C) 2013-16 Robert Boisvert * * This file is part of the mohqueue module for Kamailio, a free SIP server. * @@ -32,7 +32,7 @@ #define ALLOWHDR "Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, PRACK" #define CLENHDR "Content-Length" #define SIPEOL "\r\n" -#define USRAGNT "Kamailio MOH Queue v1.2" +#define USRAGNT "Kamailio MOH Queue v1.3"
/********** * local constants @@ -404,6 +404,26 @@ return; }
/********** +* Check if RTP Still Active +* +* INPUT: +* Arg (1) = SIP message pointer +* OUTPUT: =0 if inactive +**********/ + +int chk_rtpstat (sip_msg_t *pmsg) + +{ +pv_value_t pval [1]; +memset (pval, 0, sizeof (pv_value_t)); +if (pv_get_spec_value (pmsg, prtp_pv, pval)) + { return 0; } +if (pval->flags & PV_VAL_NULL) + { return 0; } +return 1; +} + +/********** * Close the Call * * INPUT: @@ -1664,10 +1684,23 @@ return nret;
static void refer_cb (struct cell *ptrans, int ntype, struct tmcb_params *pcbp) - { char *pfncname = "refer_cb: "; call_lst *pcall = (call_lst *)*pcbp->param; +if (pcall->call_state != CLSTA_REFER) + { + if (!pcall->call_state) + { + LM_ERR + ("%sREFER response ignored because call not in queue!\n", pfncname); + } + else + { + LM_ERR ("%sCall (%s) ignored because not in REFER state!\n", pfncname, + pcall->call_from); + } + return; + } if ((ntype == TMCB_ON_FAILURE) || (pcbp->req == FAKED_REPLY)) { LM_ERR ("%sCall (%s) did not respond to REFER!\n", pfncname, @@ -1676,6 +1709,11 @@ if ((ntype == TMCB_ON_FAILURE) || (pcbp->req == FAKED_REPLY)) delete_call (pcall); return; } + +/********** +* check reply +**********/ + int nreply = pcbp->code; if ((nreply / 100) == 2) { @@ -1692,8 +1730,17 @@ else { delete_call (pcall); } else { - pcall->call_state = CLSTA_INQUEUE; - update_call_rec (pcall); + if (!chk_rtpstat (pcbp->req)) + { + LM_ERR ("%sRTP for call (%s) no longer active!\n", + pfncname, pcall->call_from); + delete_call (pcall); + } + else + { + pcall->call_state = CLSTA_INQUEUE; + update_call_rec (pcall); + } } } return;