Browse code

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

Victor Seva authored on 28/10/2021 09:21:58
Showing 4 changed files
... ...
@@ -14,6 +14,10 @@ XML2CFG=$(shell \
14 14
 		echo 'pkg-config libxml-2.0'; \
15 15
 	fi)
16 16
 endif
17
+BUILDER=$(shell \
18
+	if pkg-config --exists uuid; then \
19
+		echo 'pkg-config uuid'; \
20
+	fi)
17 21
 endif
18 22
 
19 23
 ifneq ($(XML2CFG),)
... ...
@@ -24,4 +28,11 @@ else
24 28
 	LIBS+=-L$(LOCALBASE)/lib -lxml2
25 29
 endif
26 30
 
31
+ifneq ($(BUILDER),)
32
+	DEFS += $(shell $(BUILDER) --cflags )
33
+	LIBS += $(shell $(BUILDER) --libs)
34
+else
35
+  LIBS+=-luuid
36
+endif
37
+
27 38
 include ../../Makefile.modules
... ...
@@ -87,7 +87,7 @@ static xmlAttrPtr puadi_xmlNewPropStr(xmlNodePtr node, char *name, str *sval)
87 87
 
88 88
 str* build_dialoginfo(char *state, str *entity, str *peer, str *callid,
89 89
 		unsigned int initiator, str *localtag, str *remotetag,
90
-		str *localtarget, str *remotetarget)
90
+		str *localtarget, str *remotetarget, str *uuid)
91 91
 {
92 92
 	xmlDocPtr  doc = NULL;
93 93
 	xmlNodePtr root_node = NULL;
... ...
@@ -141,7 +141,7 @@ str* build_dialoginfo(char *state, str *entity, str *peer, str *callid,
141 141
 		goto error;
142 142
 	}
143 143
 
144
-	if(puadi_xmlNewPropStr(dialog_node, "id", callid)==NULL) {
144
+	if(puadi_xmlNewPropStr(dialog_node, "id", uuid)==NULL) {
145 145
 		goto error;
146 146
 	}
147 147
 
... ...
@@ -289,7 +289,7 @@ error:
289 289
 void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
290 290
 		unsigned int initiator, unsigned int lifetime, str *localtag,
291 291
 		str *remotetag, str *localtarget, str *remotetarget,
292
-		unsigned short do_pubruri_localcheck)
292
+		unsigned short do_pubruri_localcheck, str* uuid)
293 293
 {
294 294
 	str* body= NULL;
295 295
 	str uri= {NULL, 0};
... ...
@@ -319,7 +319,7 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
319 319
 	content_type.len= 27;
320 320
 
321 321
 	body= build_dialoginfo(state, entity, peer, callid, initiator, localtag,
322
-			remotetag, localtarget, remotetarget);
322
+			remotetag, localtarget, remotetarget, uuid);
323 323
 	if(body == NULL || body->s == NULL)
324 324
 		goto error;
325 325
 
... ...
@@ -328,7 +328,7 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
328 328
 	size= sizeof(publ_info_t)
329 329
 		+ sizeof(str) 			/* *pres_uri */
330 330
 		+ ( ruri->len 		/* pres_uri->s */
331
-				+ callid->len + 16	/* id.s */
331
+				+ uuid->len + 16	/* id.s */
332 332
 				+ content_type.len	/* content_type.s */
333 333
 			)*sizeof(char);
334 334
 
... ...
@@ -363,8 +363,8 @@ void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
363 363
 	}
364 364
 	publ->id.s= (char*)publ+ size;
365 365
 	memcpy(publ->id.s, "DIALOG_PUBLISH.", 15);
366
-	memcpy(publ->id.s+15, callid->s, callid->len);
367
-	publ->id.len= 15+ callid->len;
366
+	memcpy(publ->id.s+15, uuid->s, callid->len);
367
+	publ->id.len= 15+ uuid->len;
368 368
 	size+= publ->id.len;
369 369
 
370 370
 	publ->content_type.s= (char*)publ+ size;
... ...
@@ -411,14 +411,14 @@ void dialog_publish_multi(char *state, struct str_list* ruris, str *entity,
411 411
 		str *peer, str *callid, unsigned int initiator, unsigned int lifetime,
412 412
 		str *localtag, str *remotetag,
413 413
 		str *localtarget, str *remotetarget, unsigned short
414
-		do_pubruri_localcheck)
414
+		do_pubruri_localcheck, str *uuid)
415 415
 {
416 416
 	while(ruris) {
417 417
 		LM_DBG("CALLING dialog_publish for URI %.*s\n",
418 418
 				ruris->s.len, ruris->s.s);
419 419
 		dialog_publish(state,&(ruris->s),entity,peer,callid,initiator,
420 420
 				lifetime,localtag,remotetag,localtarget,remotetarget,
421
-				do_pubruri_localcheck);
421
+				do_pubruri_localcheck,uuid);
422 422
 		ruris=ruris->next;
423 423
 	}
424 424
 }
... ...
@@ -28,6 +28,7 @@
28 28
 #include <string.h>
29 29
 #include <libxml/parser.h>
30 30
 #include <time.h>
31
+#include <uuid/uuid.h>
31 32
 
32 33
 #include "../../core/script_cb.h"
33 34
 #include "../../core/sr_module.h"
... ...
@@ -302,14 +303,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
302 303
 				dialog_publish_multi("terminated", dlginfo->pubruris_caller,
303 304
 						&identity_local, &uri, &(dlginfo->callid), 1,
304 305
 						10, 0, 0, &(dlginfo->from_contact),
305
-						&target, send_publish_flag==-1?1:0);
306
+						&target, send_publish_flag==-1?1:0,&(dlginfo->uuid));
306 307
 			}
307 308
 			if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
308 309
 						&& (request->flags & (1<<disable_callee_publish_flag))))) {
309 310
 				dialog_publish_multi("terminated", dlginfo->pubruris_callee,
310 311
 						&uri, &identity_local, &(dlginfo->callid), 0,
311 312
 						10, 0, 0, &target, &(dlginfo->from_contact),
312
-						send_publish_flag==-1?1:0);
313
+						send_publish_flag==-1?1:0,&(dlginfo->uuid));
313 314
 			}
314 315
 			break;
315 316
 		case DLGCB_CONFIRMED:
... ...
@@ -322,14 +323,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
322 323
 				dialog_publish_multi("confirmed", dlginfo->pubruris_caller,
323 324
 						&identity_local, &uri, &(dlginfo->callid), 1,
324 325
 						dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target,
325
-						send_publish_flag==-1?1:0);
326
+						send_publish_flag==-1?1:0,&(dlginfo->uuid));
326 327
 			}
327 328
 			if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
328 329
 						&& (request->flags & (1<<disable_callee_publish_flag))))) {
329 330
 				dialog_publish_multi("confirmed", dlginfo->pubruris_callee, &uri,
330 331
 						&identity_local, &(dlginfo->callid), 0,
331 332
 						dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact),
332
-						send_publish_flag==-1?1:0);
333
+						send_publish_flag==-1?1:0,&(dlginfo->uuid));
333 334
 			}
334 335
 			break;
335 336
 		case DLGCB_EARLY:
... ...
@@ -370,13 +371,13 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
370 371
 								&identity_local, &uri, &(dlginfo->callid), 1,
371 372
 								dlginfo->lifetime, &(dlginfo->from_tag), &tag,
372 373
 								&(dlginfo->from_contact), &target,
373
-								send_publish_flag==-1?1:0);
374
+								send_publish_flag==-1?1:0,&(dlginfo->uuid));
374 375
 					} else {
375 376
 						dialog_publish_multi("early", dlginfo->pubruris_caller,
376 377
 								&identity_local, &uri, &(dlginfo->callid), 1,
377 378
 								dlginfo->lifetime, &(dlginfo->from_tag), &tag,
378 379
 								&(dlginfo->from_contact), &target,
379
-								send_publish_flag==-1?1:0);
380
+								send_publish_flag==-1?1:0,&(dlginfo->uuid));
380 381
 					}
381 382
 				}
382 383
 				if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
... ...
@@ -384,7 +385,7 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
384 385
 					dialog_publish_multi("early", dlginfo->pubruris_callee, &uri,
385 386
 							&identity_local, &(dlginfo->callid), 0,
386 387
 							dlginfo->lifetime, &tag, &(dlginfo->from_tag), &target,
387
-							&(dlginfo->from_contact), send_publish_flag==-1?1:0);
388
+							&(dlginfo->from_contact), send_publish_flag==-1?1:0,&(dlginfo->uuid));
388 389
 				}
389 390
 
390 391
 			} else {
... ...
@@ -394,22 +395,22 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
394 395
 						dialog_publish_multi("confirmed", dlginfo->pubruris_caller,
395 396
 								&identity_local, &uri, &(dlginfo->callid), 1,
396 397
 								dlginfo->lifetime, 0, 0, &(dlginfo->from_contact),
397
-								&target, send_publish_flag==-1?1:0);
398
+								&target, send_publish_flag==-1?1:0,&(dlginfo->uuid));
398 399
 
399 400
 					} else {
400 401
 						dialog_publish_multi("early", dlginfo->pubruris_caller,
401 402
 								&identity_local, &uri, &(dlginfo->callid), 1,
402 403
 								dlginfo->lifetime, 0, 0, &(dlginfo->from_contact),
403
-								&target, send_publish_flag==-1?1:0);
404
+								&target, send_publish_flag==-1?1:0,&(dlginfo->uuid));
404 405
 					}
405 406
 				}
406
-                                if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
407
-                                                && (request->flags & (1<<disable_callee_publish_flag)))))
407
+				if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
408
+					&& (request->flags & (1<<disable_callee_publish_flag)))))
408 409
 				{
409 410
 					dialog_publish_multi("early", dlginfo->pubruris_callee, &uri,
410 411
 							&identity_local, &(dlginfo->callid), 0,
411 412
 							dlginfo->lifetime, 0, 0, &target,
412
-							&(dlginfo->from_contact), send_publish_flag==-1?1:0);
413
+							&(dlginfo->from_contact), send_publish_flag==-1?1:0,&(dlginfo->uuid));
413 414
 				}
414 415
 			}
415 416
 			break;
... ...
@@ -421,14 +422,14 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
421 422
 				dialog_publish_multi("terminated", dlginfo->pubruris_caller,
422 423
 						&identity_local, &uri, &(dlginfo->callid), 1,
423 424
 						10, 0, 0, &(dlginfo->from_contact), &target,
424
-						send_publish_flag==-1?1:0);
425
+						send_publish_flag==-1?1:0,&(dlginfo->uuid));
425 426
 			}
426 427
 			if ((!dlginfo->disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
427 428
 					&& (request->flags & (1<<disable_callee_publish_flag))))) {
428 429
 				dialog_publish_multi("terminated", dlginfo->pubruris_callee, &uri,
429 430
 						&identity_local, &(dlginfo->callid), 0,
430 431
 						10, 0, 0, &target, &(dlginfo->from_contact),
431
-						send_publish_flag==-1?1:0);
432
+						send_publish_flag==-1?1:0,&(dlginfo->uuid));
432 433
 			}
433 434
 	}
434 435
 }
... ...
@@ -487,6 +488,7 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
487 488
 	struct dlginfo_cell *dlginfo;
488 489
 	int len;
489 490
 	str* s=NULL;
491
+	uuid_t binuuid;
490 492
 
491 493
 	/* create dlginfo structure to store important data inside the module*/
492 494
 	len = sizeof(struct dlginfo_cell)
... ...
@@ -495,7 +497,8 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
495 497
 		+ dlg->callid.len
496 498
 		+ dlg->tag[0].len
497 499
 		+ dlg->req_uri.len
498
-		+ dlg->contact[0].len;
500
+		+ dlg->contact[0].len
501
+		+ UUID_STR_LEN;
499 502
 
500 503
 	dlginfo = (struct dlginfo_cell*)shm_malloc( len );
501 504
 	if (dlginfo==0) {
... ...
@@ -520,6 +523,8 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
520 523
 	dlginfo->req_uri.len  = dlg->req_uri.len;
521 524
 	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
522 525
 	dlginfo->from_contact.len = dlg->contact[0].len;
526
+	dlginfo->uuid.s = dlginfo->from_contact.s + dlginfo->from_contact.len;
527
+	dlginfo->uuid.len = UUID_STR_LEN;
523 528
 
524 529
 	memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.len);
525 530
 	memcpy(dlginfo->to_uri.s, dlg->to_uri.s, dlg->to_uri.len);
... ...
@@ -528,6 +533,12 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable
528 533
 	memcpy(dlginfo->req_uri.s, dlg->req_uri.s, dlg->req_uri.len);
529 534
 	memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].len);
530 535
 
536
+	// generate new random uuid
537
+	uuid_generate_random(binuuid);
538
+	uuid_unparse(binuuid, dlginfo->uuid.s);
539
+	LM_DBG("uuid generated: '%.*s'\n",
540
+		dlginfo->uuid.len, dlginfo->uuid.s);
541
+
531 542
 	if (use_pubruri_avps) {
532 543
 		if(type==DLGCB_CREATED) {
533 544
 			dlginfo->pubruris_caller = get_str_list(pubruri_caller_avp_type,
... ...
@@ -675,7 +686,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
675 686
 		disable_callee_publish=1;
676 687
 	}
677 688
 
678
-        dlginfo=get_dialog_data(dlg, type, disable_caller_publish, disable_callee_publish);
689
+	dlginfo=get_dialog_data(dlg, type, disable_caller_publish, disable_callee_publish);
679 690
 	if(dlginfo==NULL)
680 691
 		return;
681 692
 
... ...
@@ -697,7 +708,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
697 708
 				&identity_local,
698 709
 				&identity_remote,
699 710
 				&(dlg->callid), 1, dlginfo->lifetime,
700
-				0, 0, 0, 0, (send_publish_flag==-1)?1:0);
711
+				0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid));
701 712
 	}
702 713
 
703 714
 	if (callee_trying && ((!disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request
... ...
@@ -706,7 +717,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
706 717
 				&identity_remote,
707 718
 				&identity_local,
708 719
 				&(dlg->callid), 0, dlginfo->lifetime,
709
-				0, 0, 0, 0, (send_publish_flag==-1)?1:0);
720
+				0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid));
710 721
 	}
711 722
 }
712 723
 
... ...
@@ -29,7 +29,7 @@ extern send_publish_t pua_send_publish;
29 29
 
30 30
 void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid,
31 31
 	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
32
-	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck);
32
+	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck, str *uuid);
33 33
 
34 34
 /* store the important data locally to avoid reading the data from the
35 35
  * dlg_cell during the callback (as this could create a race condition
... ...
@@ -45,9 +45,10 @@ struct dlginfo_cell {
45 45
 	struct str_list* pubruris_caller;
46 46
 	struct str_list* pubruris_callee;
47 47
 	unsigned int lifetime;
48
-        /*dialog module does not always resend all flags, so we use flags set on first request*/
49
-        int disable_caller_publish;
50
-        int disable_callee_publish;
48
+	/*dialog module does not always resend all flags, so we use flags set on first request*/
49
+	int disable_caller_publish;
50
+	int disable_callee_publish;
51
+	str uuid;
51 52
 };
52 53
 
53 54