Module: kamailio Branch: master Commit: e349af55168e6b4de97a36d35b475dc295edc2e2 URL: https://github.com/kamailio/kamailio/commit/e349af55168e6b4de97a36d35b475dc2...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2016-08-26T14:43:13+02:00
dialog: refresh cseq update if it was incremented in the past
- reported by GH #752
---
Modified: modules/dialog/dlg_cseq.c Modified: modules/dialog/dlg_cseq.h Modified: modules/dialog/dlg_handlers.c
---
Diff: https://github.com/kamailio/kamailio/commit/e349af55168e6b4de97a36d35b475dc2... Patch: https://github.com/kamailio/kamailio/commit/e349af55168e6b4de97a36d35b475dc2...
---
diff --git a/modules/dialog/dlg_cseq.c b/modules/dialog/dlg_cseq.c index d902ae9..ad915bd 100644 --- a/modules/dialog/dlg_cseq.c +++ b/modules/dialog/dlg_cseq.c @@ -186,6 +186,61 @@ int dlg_cseq_update(sip_msg_t *msg) return -1; }
+ +/** + * + */ +int dlg_cseq_refresh(sip_msg_t *msg, dlg_cell_t *dlg, + unsigned int direction) +{ + str nval; + str *pval; + + if(dlg_cseq_prepare_msg(msg)!=0) { + goto error; + } + if(msg->first_line.type==SIP_REPLY) { + /* nothing to do for outgoing replies */ + goto done; + } + + LM_DBG("initiating cseq refresh\n"); + + /* supported only for downstrem direction */ + if(direction != DLG_DIR_DOWNSTREAM) { + LM_DBG("request not going downstream (%u)\n", direction); + goto done; + } + + /* take the increment value from dialog */ + if(!((dlg->iflags&DLG_IFLAG_CSEQ_DIFF)==DLG_IFLAG_CSEQ_DIFF)) { + LM_DBG("no cseq refresh required\n"); + goto done; + } + + /* get dialog variable holding cseq diff */ + pval = get_dlg_variable(dlg, &_dlg_cseq_diff_var_name); + if(pval==NULL || pval->s==NULL || pval->len<=0) { + LM_DBG("dialog marked with cseq diff but no variable set yet\n"); + goto done; + } + + nval = *pval; + trim(&nval); + + LM_DBG("adding cseq refresh header value: %.*s\n", nval.len, nval.s); + parse_headers(msg, HDR_EOH_F, 0); + sr_hdr_add_zs(msg, "P-K-CSeq-Refresh", &nval); + +done: + if(dlg!=NULL) dlg_release(dlg); + return 0; + +error: + if(dlg!=NULL) dlg_release(dlg); + return -1; +} + /** * */ @@ -319,16 +374,23 @@ int dlg_cseq_msg_sent(void *data) parse_headers(&msg, HDR_EOH_F, 0); hfk = sr_hdr_get_z(&msg, "P-K-Auth-CSeq"); if(hfk!=NULL) { - LM_DBG("uac auth request - cseq inc needed\n"); + LM_DBG("new cseq inc requested\n"); nval = hfk->body; trim(&nval); } else { - LM_DBG("uac auth request - cseq inc not needed\n"); - goto done; + LM_DBG("new cseq inc not requested\n"); } }
if(nval.len<=0) { + hfk = sr_hdr_get_z(&msg, "P-K-CSeq-Refresh"); + if(hfk!=NULL) { + LM_DBG("cseq refresh requested\n"); + nval = hfk->body; + trim(&nval); + } + } + if(nval.len<=0) { goto done; }
diff --git a/modules/dialog/dlg_cseq.h b/modules/dialog/dlg_cseq.h index cee9e34..a2b5e01 100644 --- a/modules/dialog/dlg_cseq.h +++ b/modules/dialog/dlg_cseq.h @@ -32,9 +32,12 @@ #define _DLG_CSEQ_H_
#include "../../parser/msg_parser.h" +#include "dlg_hash.h"
int dlg_register_cseq_callbacks(void);
int dlg_cseq_update(sip_msg_t *msg); +int dlg_cseq_refresh(sip_msg_t *msg, dlg_cell_t *dlg, + unsigned int direction);
#endif diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c index cb3523d..59393dc 100644 --- a/modules/dialog/dlg_handlers.c +++ b/modules/dialog/dlg_handlers.c @@ -48,6 +48,7 @@ #include "dlg_hash.h" #include "dlg_timer.h" #include "dlg_cb.h" +#include "dlg_cseq.h" #include "dlg_handlers.h" #include "dlg_req_within.h" #include "dlg_db_handler.h" @@ -1158,7 +1159,7 @@ dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg)
/*! * \brief Function that is registered as RR callback for dialog tracking - * + * * Function that is registered as RR callback for dialog tracking. It * sets the appropriate events after the SIP method and run the state * machine to update the dialog state. It updates then the saved @@ -1250,7 +1251,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) }
if (dlg==0) { - if (pre_match_parse( req, &callid, &ftag, &ttag, 1)<0) + if (pre_match_parse(req, &callid, &ftag, &ttag, 1)<0) return; /* TODO - try to use the RR dir detection to speed up here the * search -bogdan */ @@ -1267,6 +1268,12 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) _dlg_ctx.iuid.h_entry = dlg->h_entry; _dlg_ctx.iuid.h_id = dlg->h_id;
+ if(dlg->iflags & DLG_IFLAG_CSEQ_DIFF) { + if(dlg_cseq_refresh(req, dlg, dir)<0) { + LM_ERR("failed to refresh cseq update\n"); + } + } + if (req->first_line.u.request.method_value != METHOD_ACK) { iuid = dlg_get_iuid_shm_clone(dlg); if(iuid!=NULL)