Browse code

tm: backup X/AVP lists when building new T in t_uac()

- build_cell() is setting core X/AVP lists to new T structure, losing
the lists that existed in case another T was set already. This is in
t_uac() which is used for local generated requests, such as
uac_req_send(), presence notifications, msilo...
- a revious patch was backing up only X/AVPs lists for
execution of event_route[tm:local-request]
- reported by Vitaliy Aleksandrov

Daniel-Constantin Mierla authored on 14/09/2011 16:39:37
Showing 3 changed files
... ...
@@ -492,10 +492,10 @@ error0:
492 492
  * - mode = 0 - from msg context to _txdata and use T lists
493 493
  * - mode = 1 - restore to msg context from _txdata
494 494
  */
495
-void tm_xdata_swap(tm_cell_t *t, tm_xdata_t *xd, int mode)
495
+void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode)
496 496
 {
497
-	static tm_xdata_t _txdata;
498
-	tm_xdata_t *x;
497
+	static tm_xlinks_t _txdata;
498
+	tm_xlinks_t *x;
499 499
 
500 500
 	if(xd==NULL)
501 501
 		x = &_txdata;
... ...
@@ -528,3 +528,41 @@ void tm_xdata_swap(tm_cell_t *t, tm_xdata_t *xd, int mode)
528 528
 	}
529 529
 
530 530
 }
531
+
532
+/**
533
+ * replace existing lists with newxd and backup in bakxd or restore from bakxd
534
+ */
535
+void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd)
536
+{
537
+	if(newxd==NULL && bakxd!=NULL) {
538
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, bakxd->uri_avps_from);
539
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, bakxd->uri_avps_to);
540
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, bakxd->user_avps_from);
541
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, bakxd->user_avps_to);
542
+		set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, bakxd->domain_avps_from);
543
+		set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, bakxd->domain_avps_to);
544
+#ifdef WITH_XAVP
545
+		xavp_set_list(bakxd->xavps_list);
546
+#endif
547
+		return;
548
+	}
549
+
550
+	if(newxd!=NULL && bakxd!=NULL) {
551
+		bakxd->uri_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI,
552
+				&newxd->uri_avps_from);
553
+		bakxd->uri_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI,
554
+				&newxd->uri_avps_to);
555
+		bakxd->user_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER,
556
+				&newxd->user_avps_from);
557
+		bakxd->user_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER,
558
+				&newxd->user_avps_to);
559
+		bakxd->domain_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN,
560
+				&newxd->domain_avps_from);
561
+		bakxd->domain_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN,
562
+				&newxd->domain_avps_to);
563
+#ifdef WITH_XAVP
564
+		bakxd->xavps_list = xavp_set_list(&newxd->xavps_list);
565
+#endif
566
+		return;
567
+	}
568
+}
... ...
@@ -299,13 +299,30 @@ struct totag_elem {
299 299
  * max retr. = 65 s which should be enough and saves us 2*2 bytes */
300 300
 typedef unsigned short retr_timeout_t;
301 301
 
302
-
303 302
 /**
304 303
  * extra data from SIP message context to transaction storage
305 304
  */
306 305
 typedef struct tm_xdata
307 306
 {
308 307
 	/* lists with avps */
308
+	struct usr_avp *uri_avps_from;
309
+	struct usr_avp *uri_avps_to;
310
+	struct usr_avp *user_avps_from;
311
+	struct usr_avp *user_avps_to;
312
+	struct usr_avp *domain_avps_from;
313
+	struct usr_avp *domain_avps_to;
314
+#ifdef WITH_XAVP
315
+	sr_xavp_t **xavps_list;
316
+#endif
317
+} tm_xdata_t;
318
+
319
+
320
+/**
321
+ * links to extra data from SIP message context to transaction storage
322
+ */
323
+typedef struct tm_xlinks
324
+{
325
+	/* links to lists with avps */
309 326
 	struct usr_avp **uri_avps_from;
310 327
 	struct usr_avp **uri_avps_to;
311 328
 	struct usr_avp **user_avps_from;
... ...
@@ -315,7 +332,7 @@ typedef struct tm_xdata
315 332
 #ifdef WITH_XAVP
316 333
 	sr_xavp_t **xavps_list;
317 334
 #endif
318
-} tm_xdata_t;
335
+} tm_xlinks_t;
319 336
 
320 337
 
321 338
 /* transaction context */
... ...
@@ -564,7 +581,9 @@ inline static void remove_from_hash_table_unsafe( struct cell * p_cell)
564 581
 /**
565 582
  * backup xdata from/to msg context to local var and use T lists
566 583
  */
567
-void tm_xdata_swap(tm_cell_t *t, tm_xdata_t *xd, int mode);
584
+void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode);
585
+
586
+void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd);
568 587
 
569 588
 #endif
570 589
 
... ...
@@ -216,7 +216,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
216 216
 	int backup_route_type;
217 217
 #endif
218 218
 	snd_flags_t snd_flags;
219
-	tm_xdata_t backup_xd;
219
+	tm_xlinks_t backup_xd;
220
+	tm_xdata_t local_xd;
220 221
 
221 222
 	ret=-1;
222 223
 	hi=0; /* make gcc happy */
... ...
@@ -276,7 +277,13 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
276 277
 	}
277 278
 #endif /* USE_DNS_FAILOVER */
278 279
 
280
+	/* build cell sets X/AVP lists to new transaction structure
281
+	 * => bakup in a tmp struct and restore afterwards */
282
+	memset(&local_xd, 0, sizeof(tm_xdata_t));
283
+	tm_xdata_replace(&local_xd, &backup_xd);
279 284
 	new_cell = build_cell(0); 
285
+	tm_xdata_replace(0, &backup_xd);
286
+
280 287
 	if (!new_cell) {
281 288
 		ret=E_OUT_OF_MEM;
282 289
 		LOG(L_ERR, "t_uac: short of cell shmem\n");