Browse code

modules/tm: copy user-agent string retrieved from usrloc into branches when serial forking

Peter Dunkley authored on 17/05/2013 23:15:59
Showing 3 changed files
... ...
@@ -231,6 +231,7 @@ typedef struct ua_client
231 231
 	str path;
232 232
 	str instance;
233 233
 	str ruid;
234
+	str location_ua;
234 235
 	/* if we don't store, we at least want to know the status */
235 236
 	int             last_received;
236 237
 
... ...
@@ -188,7 +188,8 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
188 188
 									struct socket_info* fsocket,
189 189
 									snd_flags_t snd_flags,
190 190
 									int fproto, int flags,
191
-									str *instance, str *ruid)
191
+									str *instance, str *ruid,
192
+									str *location_ua)
192 193
 {
193 194
 	char *shbuf;
194 195
 	struct lump* add_rm_backup, *body_lumps_backup;
... ...
@@ -205,6 +206,8 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
205 205
 	int free_instance;
206 206
 	str ruid_bak;
207 207
 	int free_ruid;
208
+	str ua_bak;
209
+	int free_ua;
208 210
 	int backup_route_type;
209 211
 	snd_flags_t fwd_snd_flags_bak;
210 212
 	snd_flags_t rpl_snd_flags_bak;
... ...
@@ -230,6 +233,9 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
230 230
 	ruid_bak.s=0;
231 231
 	ruid_bak.len=0;
232 232
 	free_ruid=0;
233
+	ua_bak.s=0;
234
+	ua_bak.len=0;
235
+	free_ua=0;
233 236
 	dst=&t->uac[branch].request.dst;
234 237
 
235 238
 	/* ... we calculate branch ... */	
... ...
@@ -272,6 +278,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
272 272
 	path_bak=i_req->path_vec;
273 273
 	instance_bak=i_req->instance;
274 274
 	ruid_bak=i_req->ruid;
275
+	ua_bak=i_req->location_ua;
275 276
 	
276 277
 	if (unlikely(branch_route || has_tran_tmcbs(t, TMCB_REQUEST_FWDED))){
277 278
 		/* dup uris, path a.s.o. if we have a branch route or callback */
... ...
@@ -336,6 +343,22 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
336 336
 			}
337 337
 			free_ruid=1;
338 338
 		}
339
+
340
+		/* update location_ua */
341
+		/* if location_ua points to msg location_ua, it needs to be "fixed" so that we 
342
+		   can change/update msg->location_ua */
343
+		if (location_ua==&i_req->location_ua)
344
+			location_ua=&ua_bak;
345
+		/* zero it first so that set_ua will work */
346
+		i_req->location_ua.s=0;
347
+		i_req->location_ua.len=0;
348
+		if (unlikely(location_ua)){
349
+			if (unlikely(set_ua(i_req, location_ua)<0)){
350
+				ret=E_OUT_OF_MEM;
351
+				goto error03;
352
+			}
353
+			free_ua=1;
354
+		}
339 355
 	
340 356
 		/* backup dst uri  & zero it*/
341 357
 		dst_uri_bak=i_req->dst_uri;
... ...
@@ -455,6 +478,13 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
455 455
 			i_req->ruid.s=0;
456 456
 			i_req->ruid.len=0;
457 457
 		}
458
+		if (unlikely(location_ua && (i_req->location_ua.s!=location_ua->s ||
459
+							  i_req->location_ua.len!=location_ua->len))){
460
+			i_req->location_ua=*location_ua;
461
+		}else if (unlikely(location_ua==0 && i_req->location_ua.len!=0)){
462
+			i_req->location_ua.s=0;
463
+			i_req->location_ua.len=0;
464
+		}
458 465
 	}
459 466
 	
460 467
 	if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
... ...
@@ -552,6 +582,21 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
552 552
 		t->uac[branch].ruid.s[i_req->ruid.len]=0;
553 553
 		memcpy( t->uac[branch].ruid.s, i_req->ruid.s, i_req->ruid.len);
554 554
 	}
555
+	if (unlikely(i_req->location_ua.s && i_req->location_ua.len)){
556
+		t->uac[branch].location_ua.s=shm_malloc(i_req->location_ua.len+1);
557
+		if (unlikely(t->uac[branch].location_ua.s==0)) {
558
+			shm_free(shbuf);
559
+			t->uac[branch].request.buffer=0;
560
+			t->uac[branch].request.buffer_len=0;
561
+			t->uac[branch].uri.s=0;
562
+			t->uac[branch].uri.len=0;
563
+			ret=E_OUT_OF_MEM;
564
+			goto error01;
565
+		}
566
+		t->uac[branch].location_ua.len=i_req->location_ua.len;
567
+		t->uac[branch].location_ua.s[i_req->location_ua.len]=0;
568
+		memcpy( t->uac[branch].location_ua.s, i_req->location_ua.s, i_req->location_ua.len);
569
+	}
555 570
 	ret=0;
556 571
 
557 572
 error01:
... ...
@@ -569,6 +614,9 @@ error03:
569 569
 	if (unlikely(free_ruid)){
570 570
 		reset_ruid(i_req);
571 571
 	}
572
+	if (unlikely(free_ua)){
573
+		reset_ua(i_req);
574
+	}
572 575
 	if (dst_uri_backed_up){
573 576
 		reset_dst_uri(i_req); /* free dst_uri */
574 577
 		i_req->dst_uri=dst_uri_bak;
... ...
@@ -579,7 +627,7 @@ error03:
579 579
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
580 580
 	i_req->path_vec=path_bak;
581 581
 	i_req->instance=instance_bak;
582
-	i_req->ruid=ruid_bak;
582
+	i_req->location_ua=ua_bak;
583 583
 	
584 584
 	/* Delete the duplicated lump lists, this will also delete
585 585
 	 * all lumps created here, such as lumps created in per-branch
... ...
@@ -743,7 +791,8 @@ int add_blind_uac( /*struct cell *t*/ )
743 743
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
744 744
 					str* next_hop, str* path, struct proxy_l *proxy,
745 745
 					struct socket_info* fsocket, snd_flags_t snd_flags,
746
-					int proto, int flags, str *instance, str *ruid)
746
+					int proto, int flags, str *instance, str *ruid,
747
+					str *location_ua)
747 748
 {
748 749
 
749 750
 	int ret;
... ...
@@ -788,7 +837,8 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
788 788
 	/* now message printing starts ... */
789 789
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
790 790
 										next_hop, fsocket, snd_flags,
791
-										proto, flags, instance, ruid)) < 0)){
791
+										proto, flags, instance, ruid,
792
+										location_ua)) < 0)){
792 793
 		ser_error=ret;
793 794
 		goto error01;
794 795
 	}
... ...
@@ -829,7 +879,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
829 829
 								snd_flags_t send_flags,
830 830
 								int proto,
831 831
 								char *buf, short buf_len,
832
-								str *instance, str *ruid)
832
+								str *instance, str *ruid,
833
+								str *location_ua)
833 834
 {
834 835
 
835 836
 	int ret;
... ...
@@ -932,6 +983,22 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
932 932
 		t->uac[branch].ruid.s[ruid->len]=0;
933 933
 		memcpy( t->uac[branch].ruid.s, ruid->s, ruid->len);
934 934
 	}
935
+	/* copy the location_ua */
936
+	if (unlikely(location_ua && location_ua->s)){
937
+		t->uac[branch].location_ua.s=shm_malloc(location_ua->len+1);
938
+		if (unlikely(t->uac[branch].location_ua.s==0)) {
939
+			shm_free(shbuf);
940
+			t->uac[branch].request.buffer=0;
941
+			t->uac[branch].request.buffer_len=0;
942
+			t->uac[branch].uri.s=0;
943
+			t->uac[branch].uri.len=0;
944
+			ret=ser_error=E_OUT_OF_MEM;
945
+			goto error;
946
+		}
947
+		t->uac[branch].location_ua.len=location_ua->len;
948
+		t->uac[branch].location_ua.s[location_ua->len]=0;
949
+		memcpy( t->uac[branch].location_ua.s, location_ua->s, location_ua->len);
950
+	}
935 951
 	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
936 952
 					   to be sure everything above is fully written before
937 953
 					   updating branches no. */
... ...
@@ -1004,7 +1071,8 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
1004 1004
 							old_uac->request.dst.proto,
1005 1005
 							old_uac->request.buffer,
1006 1006
 							old_uac->request.buffer_len,
1007
-							&old_uac->instance, &old_uac->ruid);
1007
+							&old_uac->instance, &old_uac->ruid,
1008
+							&old_uac->location_ua);
1008 1009
 			}else
1009 1010
 				/* add_uac will use dns_h => next_hop will be ignored.
1010 1011
 				 * Unfortunately we can't reuse the old buffer, the branch id
... ...
@@ -1016,7 +1084,8 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
1016 1016
 									old_uac->request.dst.send_sock:0,
1017 1017
 							old_uac->request.dst.send_flags,
1018 1018
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F,
1019
-							&old_uac->instance, &old_uac->ruid);
1019
+							&old_uac->instance, &old_uac->ruid,
1020
+							&old_uac->location_ua);
1020 1021
 
1021 1022
 			if (ret<0){
1022 1023
 				/* failed, delete the copied dns_h */
... ...
@@ -1092,7 +1161,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
1092 1092
 									&t_invite->uac[branch].uri,
1093 1093
 									&t_invite->uac[branch].path,
1094 1094
 									0, 0, snd_flags, PROTO_NONE, 0,
1095
-									NULL, NULL)) <0)){
1095
+									NULL, NULL, NULL)) <0)){
1096 1096
 			ser_error=ret;
1097 1097
 			goto error;
1098 1098
 		}
... ...
@@ -1551,7 +1620,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1551 1551
 	int success_branch;
1552 1552
 	int try_new;
1553 1553
 	int lock_replies;
1554
-	str dst_uri, path, instance, ruid;
1554
+	str dst_uri, path, instance, ruid, location_ua;
1555 1555
 	struct socket_info* si;
1556 1556
 	flag_t backup_bflags = 0;
1557 1557
 	flag_t bflags = 0;
... ...
@@ -1617,7 +1686,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1617 1617
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
1618 1618
 							&p_msg->path_vec, proxy, p_msg->force_send_socket,
1619 1619
 							p_msg->fwd_send_flags, proto,
1620
-							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance, &p_msg->ruid);
1620
+							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance,
1621
+							&p_msg->ruid, &p_msg->location_ua);
1621 1622
 		if (branch_ret>=0) 
1622 1623
 			added_branches |= 1<<branch_ret;
1623 1624
 		else
... ...
@@ -1626,14 +1696,15 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1626 1626
 
1627 1627
 	init_branch_iterator();
1628 1628
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
1629
-										&bflags, &si, &ruid, &instance))) {
1629
+										&bflags, &si, &ruid, &instance, &location_ua))) {
1630 1630
 		try_new++;
1631 1631
 		setbflagsval(0, bflags);
1632 1632
 
1633 1633
 		branch_ret=add_uac( t, p_msg, &current_uri,
1634 1634
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
1635 1635
 							&path, proxy, si, p_msg->fwd_send_flags,
1636
-							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, &ruid);
1636
+							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
1637
+							&ruid, &location_ua);
1637 1638
 		/* pick some of the errors in case things go wrong;
1638 1639
 		   note that picking lowest error is just as good as
1639 1640
 		   any other algorithm which picks any other negative
... ...
@@ -51,6 +51,7 @@ struct contact {
51 51
     struct socket_info* sock;
52 52
     str instance;
53 53
     str ruid;
54
+    str location_ua;
54 55
     unsigned int flags;
55 56
     unsigned short q_flag;
56 57
     struct contact *next;
... ...
@@ -94,10 +95,11 @@ static str instance_name = {"instance", 8};
94 94
 static str flags_name = {"flags", 5};
95 95
 static str q_flag_name = {"q_flag", 6};
96 96
 static str ruid_name = {"ruid", 4};
97
+static str ua_name = {"ua", 2};
97 98
 
98 99
 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
99 100
 		      unsigned int flags, unsigned int q_flag, str *instance,
100
-		      str *ruid)
101
+		      str *ruid, str *location_ua)
101 102
 {
102 103
     sr_xavp_t *record;
103 104
     sr_xval_t val;
... ...
@@ -145,6 +147,12 @@ void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
145 145
 	xavp_add_value(&ruid_name, &val, &record);
146 146
     }
147 147
 
148
+    if (location_ua->len > 0) {
149
+	val.type = SR_XTYPE_STR;
150
+	val.v.s = *location_ua;
151
+	xavp_add_value(&ua_name, &val, &record);
152
+    }
153
+
148 154
     val.type = SR_XTYPE_XAVP;
149 155
     val.v.xavp = record;
150 156
     xavp_add_value(&contacts_avp, &val, NULL);
... ...
@@ -202,6 +210,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
202 202
 	contacts->q = get_ruri_q();
203 203
 	contacts->instance = msg->instance;
204 204
         contacts->ruid = msg->ruid;
205
+	contacts->location_ua = msg->location_ua;
205 206
 	first_idx = 0;
206 207
     } else {
207 208
 	/* Insert first branch to first contact */
... ...
@@ -219,6 +228,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
219 219
 	contacts->instance.len = branch->instance_len;
220 220
         contacts->ruid.s = branch->ruid;
221 221
         contacts->ruid.len = branch->ruid_len;
222
+	contacts->location_ua.s = branch->location_ua;
223
+	contacts->location_ua.len = branch->location_ua_len;
222 224
 	first_idx = 1;
223 225
     }
224 226
 
... ...
@@ -247,6 +258,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
247 247
 	next->instance.len = branch->instance_len;
248 248
 	next->ruid.s = branch->ruid;
249 249
 	next->ruid.len = branch->ruid_len;
250
+	next->location_ua.s = branch->location_ua;
251
+	next->location_ua.len = branch->location_ua_len;
250 252
 	next->next = (struct contact *)0;
251 253
 
252 254
 	prev = (struct contact *)0;
... ...
@@ -299,7 +312,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
299 299
 
300 300
 	add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
301 301
 			 &sock_str, curr->flags, curr->q_flag,
302
-			 &(curr->instance), &(curr->ruid));
302
+			 &(curr->instance), &(curr->ruid), &(curr->location_ua));
303 303
 
304 304
 	curr = curr->next;
305 305
     }
... ...
@@ -314,7 +327,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
314 314
 }
315 315
 
316 316
 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
317
-			   unsigned int flags, str *instance, str *ruid)
317
+			   unsigned int flags, str *instance, str *ruid,
318
+			   str *location_ua)
318 319
 {
319 320
     sr_xavp_t *record;
320 321
     sr_xval_t val;
... ...
@@ -354,6 +368,12 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
354 354
 	xavp_add_value(&ruid_name, &val, &record);
355 355
     }
356 356
 
357
+    if (location_ua->len > 0) {
358
+	val.type = SR_XTYPE_STR;
359
+	val.v.s = *location_ua;
360
+	xavp_add_value(&ua_name, &val, &record);
361
+    }
362
+
357 363
     val.type = SR_XTYPE_INT;
358 364
     val.v.i = flags;
359 365
     xavp_add_value(&flags_name, &val, &record);
... ...
@@ -376,7 +396,7 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
376 376
  * there was nothing to do. Returns -1 in case of an error. */
377 377
 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
378 378
 {
379
-    str uri, dst_uri, path, instance, host, sock_str, ruid;
379
+    str uri, dst_uri, path, instance, host, sock_str, ruid, location_ua;
380 380
     struct socket_info *sock;
381 381
     unsigned int flags, q_flag;
382 382
     sr_xavp_t *xavp_list, *xavp, *prev_xavp, *vavp;
... ...
@@ -471,6 +491,9 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
471 471
     vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
472 472
     ruid = vavp->val.v.s;
473 473
 
474
+    vavp = xavp_get(&ua_name, xavp->val.v.xavp);
475
+    location_ua = vavp->val.v.s;
476
+
474 477
     /* Rewrite Request-URI */
475 478
     rewrite_uri(msg, &uri);
476 479
 
... ...
@@ -492,6 +515,8 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
492 492
 
493 493
     set_ruid(msg, &ruid);
494 494
 
495
+    set_ua(msg, &location_ua);
496
+
495 497
     /* Check if there was only one contact at this priority */
496 498
     if (q_flag) {
497 499
 	xavp_rm(xavp, NULL);
... ...
@@ -556,6 +581,9 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
556 556
 	vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
557 557
 	ruid = vavp->val.v.s;
558 558
 
559
+	vavp = xavp_get(&ua_name, xavp->val.v.xavp);
560
+	location_ua = vavp->val.v.s;
561
+
559 562
 	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
560 563
 	if (vavp != NULL) {
561 564
 	    instance = vavp->val.v.s;
... ...
@@ -568,7 +596,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
568 568
 	    }
569 569
 	    if (ilp) {
570 570
 		add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
571
-				      flags, &instance, &ruid);
571
+				      flags, &instance, &ruid, &location_ua);
572 572
 		goto check_q_flag;
573 573
 	    }
574 574
 	    if (!q_flag) {
... ...
@@ -595,14 +623,15 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
595 595
 		instance.len = 0;
596 596
 	}
597 597
 
598
-	LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s' ruid-'%.*s'\n",
598
+	LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s'"
599
+		" ruid-'%.*s' location_ua-'%.*s'\n",
599 600
 		uri.len, uri.s,
600 601
 		dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
601 602
 		path.len, (path.len>0)?path.s:"",
602 603
 		instance.len, (instance.len>0)?instance.s:"",
603
-		ruid.len, ruid.s);
604
+		ruid.len, ruid.s, location_ua.len, location_ua.s);
604 605
 	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
605
-			  &ruid) != 1) {
606
+			  &ruid, &location_ua) != 1) {
606 607
 	    LM_ERR("appending branch failed\n");
607 608
 	    free_instance_list(il);
608 609
 	    xavp_destroy_list(&xavp_list);
... ...
@@ -637,7 +666,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
637 637
  * there was nothing to do. Returns -1 in case of an error. */
638 638
 int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
639 639
 {
640
-    str uri, dst_uri, path, instance, host, ruid;
640
+    str uri, dst_uri, path, instance, host, ruid, location_ua;
641 641
 	str this_instance;
642 642
     struct socket_info *sock;
643 643
     unsigned int flags;
... ...
@@ -728,14 +757,18 @@ int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
728 728
 		vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
729 729
 		ruid = vavp->val.v.s;
730 730
 
731
-		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s' ruid-'%.*s'\n",
731
+		vavp = xavp_get(&ua_name, xavp->val.v.xavp);
732
+		location_ua = vavp->val.v.s;
733
+
734
+		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s'"
735
+			" inst-'%.*s' ruid-'%.*s' location_ua-'%.*s'\n",
732 736
 			uri.len, uri.s,
733 737
 			dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
734 738
 			path.len, (path.len>0)?path.s:"",
735 739
 			instance.len, (instance.len>0)?instance.s:"",
736
-			ruid.len, ruid.s);
740
+			ruid.len, ruid.s, location_ua.len, location_ua.s);
737 741
 		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
738
-			  &ruid) != 1) {
742
+			  &ruid, &location_ua) != 1) {
739 743
 			LM_ERR("appending branch failed\n");
740 744
 			xavp_destroy_list(&xavp_list);
741 745
 			return -1;