From 7a10c72e1fdf0f072e41c98aa39423ba8fc527db Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Thu, 28 Oct 2021 11:21:58 +0200 Subject: [PATCH] pua_dialoginfo: generate uuid as id instead of use callid value This change solves the issue of parallel forking, subscriber was receiving NOTIFY messages with the same id for different branches fixes #2906 --- src/modules/pua_dialoginfo/dialog_publish.c | 18 +++---- src/modules/pua_dialoginfo/pua_dialoginfo.c | 52 ++++++++++++++------- src/modules/pua_dialoginfo/pua_dialoginfo.h | 9 ++-- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/modules/pua_dialoginfo/dialog_publish.c b/src/modules/pua_dialoginfo/dialog_publish.c index 7eaf27b8558..7f2751ffcaf 100644 --- a/src/modules/pua_dialoginfo/dialog_publish.c +++ b/src/modules/pua_dialoginfo/dialog_publish.c @@ -87,7 +87,7 @@ static xmlAttrPtr puadi_xmlNewPropStr(xmlNodePtr node, char *name, str *sval) str* build_dialoginfo(char *state, str *entity, str *peer, str *callid, unsigned int initiator, str *localtag, str *remotetag, - str *localtarget, str *remotetarget) + str *localtarget, str *remotetarget, str *uuid) { xmlDocPtr doc = NULL; xmlNodePtr root_node = NULL; @@ -141,7 +141,7 @@ str* build_dialoginfo(char *state, str *entity, str *peer, str *callid, goto error; } - if(puadi_xmlNewPropStr(dialog_node, "id", callid)==NULL) { + if(puadi_xmlNewPropStr(dialog_node, "id", uuid)==NULL) { goto error; } @@ -289,7 +289,7 @@ str* build_dialoginfo(char *state, str *entity, str *peer, str *callid, void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid, unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag, str *localtarget, str *remotetarget, - unsigned short do_pubruri_localcheck) + unsigned short do_pubruri_localcheck, str* uuid) { str* body= NULL; str uri= {NULL, 0}; @@ -319,7 +319,7 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid, content_type.len= 27; body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, - remotetag, localtarget, remotetarget); + remotetag, localtarget, remotetarget, uuid); if(body == NULL || body->s == NULL) goto error; @@ -328,7 +328,7 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid, size= sizeof(publ_info_t) + sizeof(str) /* *pres_uri */ + ( ruri->len /* pres_uri->s */ - + callid->len + 16 /* id.s */ + + uuid->len + 16 /* id.s */ + content_type.len /* content_type.s */ )*sizeof(char); @@ -363,8 +363,8 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid, } publ->id.s= (char*)publ+ size; memcpy(publ->id.s, "DIALOG_PUBLISH.", 15); - memcpy(publ->id.s+15, callid->s, callid->len); - publ->id.len= 15+ callid->len; + memcpy(publ->id.s+15, uuid->s, callid->len); + publ->id.len= 15+ uuid->len; size+= publ->id.len; publ->content_type.s= (char*)publ+ size; @@ -411,14 +411,14 @@ void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid, unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag, str *localtarget, str *remotetarget, unsigned short - do_pubruri_localcheck) + do_pubruri_localcheck, str *uuid) { while(ruris) { LM_DBG("CALLING dialog_publish for URI %.*s\n", ruris->s.len, ruris->s.s); dialog_publish(state,&(ruris->s),entity,peer,callid,initiator, lifetime,localtag,remotetag,localtarget,remotetarget, - do_pubruri_localcheck); + do_pubruri_localcheck,uuid); ruris=ruris->next; } } diff --git a/src/modules/pua_dialoginfo/pua_dialoginfo.c b/src/modules/pua_dialoginfo/pua_dialoginfo.c index 7e7afe2eae6..9af25b4b1db 100644 --- a/src/modules/pua_dialoginfo/pua_dialoginfo.c +++ b/src/modules/pua_dialoginfo/pua_dialoginfo.c @@ -41,6 +41,7 @@ #include "../../core/str_list.h" #include "../../core/mem/mem.h" #include "../../core/pt.h" +#include "../../core/utils/sruid.h" #include "../dialog/dlg_load.h" #include "../dialog/dlg_hash.h" #include "../pua/pua_bind.h" @@ -78,6 +79,7 @@ unsigned short pubruri_caller_avp_type; int_str pubruri_caller_avp_name; unsigned short pubruri_callee_avp_type; int_str pubruri_callee_avp_name; +sruid_t _puadi_sruid; static str caller_dlg_var = {0, 0}; /* pubruri_caller */ static str callee_dlg_var = {0, 0}; /* pubruri_callee */ @@ -302,14 +304,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para dialog_publish_multi("terminated", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, 10, 0, 0, &(dlginfo->from_contact), - &target, send_publish_flag==-1?1:0); + &target, send_publish_flag==-1?1:0,&(dlginfo->uuid)); } if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request && (request->flags & (1<pubruris_callee, &uri, &identity_local, &(dlginfo->callid), 0, 10, 0, 0, &target, &(dlginfo->from_contact), - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } break; case DLGCB_CONFIRMED: @@ -322,14 +324,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para dialog_publish_multi("confirmed", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request && (request->flags & (1<pubruris_callee, &uri, &identity_local, &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact), - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } break; case DLGCB_EARLY: @@ -370,13 +372,13 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para &identity_local, &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target, - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } else { dialog_publish_multi("early", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target, - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } } if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request @@ -384,7 +386,7 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para dialog_publish_multi("early", dlginfo->pubruris_callee, &uri, &identity_local, &(dlginfo->callid), 0, dlginfo->lifetime, &tag, &(dlginfo->from_tag), &target, - &(dlginfo->from_contact), send_publish_flag==-1?1:0); + &(dlginfo->from_contact), send_publish_flag==-1?1:0,&(dlginfo->uuid)); } } else { @@ -394,22 +396,22 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para dialog_publish_multi("confirmed", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), - &target, send_publish_flag==-1?1:0); + &target, send_publish_flag==-1?1:0,&(dlginfo->uuid)); } else { dialog_publish_multi("early", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), - &target, send_publish_flag==-1?1:0); + &target, send_publish_flag==-1?1:0,&(dlginfo->uuid)); } } - if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request - && (request->flags & (1<disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request + && (request->flags & (1<pubruris_callee, &uri, &identity_local, &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, - &(dlginfo->from_contact), send_publish_flag==-1?1:0); + &(dlginfo->from_contact), send_publish_flag==-1?1:0,&(dlginfo->uuid)); } } break; @@ -421,14 +423,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para dialog_publish_multi("terminated", dlginfo->pubruris_caller, &identity_local, &uri, &(dlginfo->callid), 1, 10, 0, 0, &(dlginfo->from_contact), &target, - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request && (request->flags & (1<pubruris_callee, &uri, &identity_local, &(dlginfo->callid), 0, 10, 0, 0, &target, &(dlginfo->from_contact), - send_publish_flag==-1?1:0); + send_publish_flag==-1?1:0,&(dlginfo->uuid)); } } } @@ -495,7 +497,8 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable + dlg->callid.len + dlg->tag[0].len + dlg->req_uri.len - + dlg->contact[0].len; + + dlg->contact[0].len + + SRUID_SIZE; dlginfo = (struct dlginfo_cell*)shm_malloc( len ); if (dlginfo==0) { @@ -520,6 +523,8 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable dlginfo->req_uri.len = dlg->req_uri.len; dlginfo->from_contact.s = dlginfo->req_uri.s + dlginfo->req_uri.len; dlginfo->from_contact.len = dlg->contact[0].len; + dlginfo->uuid.s = dlginfo->from_contact.s + dlginfo->from_contact.len; + dlginfo->uuid.len = SRUID_SIZE; memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.len); memcpy(dlginfo->to_uri.s, dlg->to_uri.s, dlg->to_uri.len); @@ -528,6 +533,13 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable memcpy(dlginfo->req_uri.s, dlg->req_uri.s, dlg->req_uri.len); memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].len); + // generate new random uuid + sruid_next_safe(&_puadi_sruid); + strcpy(dlginfo->uuid.s, _puadi_sruid.uid.s); + dlginfo->uuid.len = _puadi_sruid.uid.len; + LM_DBG("uuid generated: '%.*s'\n", + dlginfo->uuid.len, dlginfo->uuid.s); + if (use_pubruri_avps) { if(type==DLGCB_CREATED) { dlginfo->pubruris_caller = get_str_list(pubruri_caller_avp_type, @@ -675,7 +687,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) disable_callee_publish=1; } - dlginfo=get_dialog_data(dlg, type, disable_caller_publish, disable_callee_publish); + dlginfo=get_dialog_data(dlg, type, disable_caller_publish, disable_callee_publish); if(dlginfo==NULL) return; @@ -697,7 +709,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) &identity_local, &identity_remote, &(dlg->callid), 1, dlginfo->lifetime, - 0, 0, 0, 0, (send_publish_flag==-1)?1:0); + 0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid)); } if (callee_trying && ((!disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request @@ -706,7 +718,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) &identity_remote, &identity_local, &(dlg->callid), 0, dlginfo->lifetime, - 0, 0, 0, 0, (send_publish_flag==-1)?1:0); + 0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid)); } } @@ -738,6 +750,10 @@ static int mod_init(void) pv_spec_t avp_spec; struct sip_uri ruri_uri; + if(sruid_init(&_puadi_sruid, (char)'-', "padi", SRUID_INC)<0) { + return -1; + } + if(caller_dlg_var.len<=0) { LM_WARN("pubruri_caller_dlg_var is not set" " - restore on restart disabled\n"); diff --git a/src/modules/pua_dialoginfo/pua_dialoginfo.h b/src/modules/pua_dialoginfo/pua_dialoginfo.h index 2551beb4fa9..d86799adeec 100644 --- a/src/modules/pua_dialoginfo/pua_dialoginfo.h +++ b/src/modules/pua_dialoginfo/pua_dialoginfo.h @@ -29,7 +29,7 @@ extern send_publish_t pua_send_publish; void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid, unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag, - str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck); + str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck, str *uuid); /* store the important data locally to avoid reading the data from the * dlg_cell during the callback (as this could create a race condition @@ -45,9 +45,10 @@ struct dlginfo_cell { struct str_list* pubruris_caller; struct str_list* pubruris_callee; unsigned int lifetime; - /*dialog module does not always resend all flags, so we use flags set on first request*/ - int disable_caller_publish; - int disable_callee_publish; + /*dialog module does not always resend all flags, so we use flags set on first request*/ + int disable_caller_publish; + int disable_callee_publish; + str uuid; };