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 206
 	int free_instance;
206 207
 	str ruid_bak;
207 208
 	int free_ruid;
209
+	str ua_bak;
210
+	int free_ua;
208 211
 	int backup_route_type;
209 212
 	snd_flags_t fwd_snd_flags_bak;
210 213
 	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 233
 	ruid_bak.s=0;
231 234
 	ruid_bak.len=0;
232 235
 	free_ruid=0;
236
+	ua_bak.s=0;
237
+	ua_bak.len=0;
238
+	free_ua=0;
233 239
 	dst=&t->uac[branch].request.dst;
234 240
 
235 241
 	/* ... we calculate branch ... */	
... ...
@@ -272,6 +278,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
272 278
 	path_bak=i_req->path_vec;
273 279
 	instance_bak=i_req->instance;
274 280
 	ruid_bak=i_req->ruid;
281
+	ua_bak=i_req->location_ua;
275 282
 	
276 283
 	if (unlikely(branch_route || has_tran_tmcbs(t, TMCB_REQUEST_FWDED))){
277 284
 		/* 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 343
 			}
337 344
 			free_ruid=1;
338 345
 		}
346
+
347
+		/* update location_ua */
348
+		/* if location_ua points to msg location_ua, it needs to be "fixed" so that we 
349
+		   can change/update msg->location_ua */
350
+		if (location_ua==&i_req->location_ua)
351
+			location_ua=&ua_bak;
352
+		/* zero it first so that set_ua will work */
353
+		i_req->location_ua.s=0;
354
+		i_req->location_ua.len=0;
355
+		if (unlikely(location_ua)){
356
+			if (unlikely(set_ua(i_req, location_ua)<0)){
357
+				ret=E_OUT_OF_MEM;
358
+				goto error03;
359
+			}
360
+			free_ua=1;
361
+		}
339 362
 	
340 363
 		/* backup dst uri  & zero it*/
341 364
 		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 478
 			i_req->ruid.s=0;
456 479
 			i_req->ruid.len=0;
457 480
 		}
481
+		if (unlikely(location_ua && (i_req->location_ua.s!=location_ua->s ||
482
+							  i_req->location_ua.len!=location_ua->len))){
483
+			i_req->location_ua=*location_ua;
484
+		}else if (unlikely(location_ua==0 && i_req->location_ua.len!=0)){
485
+			i_req->location_ua.s=0;
486
+			i_req->location_ua.len=0;
487
+		}
458 488
 	}
459 489
 	
460 490
 	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 582
 		t->uac[branch].ruid.s[i_req->ruid.len]=0;
553 583
 		memcpy( t->uac[branch].ruid.s, i_req->ruid.s, i_req->ruid.len);
554 584
 	}
585
+	if (unlikely(i_req->location_ua.s && i_req->location_ua.len)){
586
+		t->uac[branch].location_ua.s=shm_malloc(i_req->location_ua.len+1);
587
+		if (unlikely(t->uac[branch].location_ua.s==0)) {
588
+			shm_free(shbuf);
589
+			t->uac[branch].request.buffer=0;
590
+			t->uac[branch].request.buffer_len=0;
591
+			t->uac[branch].uri.s=0;
592
+			t->uac[branch].uri.len=0;
593
+			ret=E_OUT_OF_MEM;
594
+			goto error01;
595
+		}
596
+		t->uac[branch].location_ua.len=i_req->location_ua.len;
597
+		t->uac[branch].location_ua.s[i_req->location_ua.len]=0;
598
+		memcpy( t->uac[branch].location_ua.s, i_req->location_ua.s, i_req->location_ua.len);
599
+	}
555 600
 	ret=0;
556 601
 
557 602
 error01:
... ...
@@ -569,6 +614,9 @@ error03:
569 614
 	if (unlikely(free_ruid)){
570 615
 		reset_ruid(i_req);
571 616
 	}
617
+	if (unlikely(free_ua)){
618
+		reset_ua(i_req);
619
+	}
572 620
 	if (dst_uri_backed_up){
573 621
 		reset_dst_uri(i_req); /* free dst_uri */
574 622
 		i_req->dst_uri=dst_uri_bak;
... ...
@@ -579,7 +627,7 @@ error03:
579 627
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
580 628
 	i_req->path_vec=path_bak;
581 629
 	i_req->instance=instance_bak;
582
-	i_req->ruid=ruid_bak;
630
+	i_req->location_ua=ua_bak;
583 631
 	
584 632
 	/* Delete the duplicated lump lists, this will also delete
585 633
 	 * all lumps created here, such as lumps created in per-branch
... ...
@@ -743,7 +791,8 @@ int add_blind_uac( /*struct cell *t*/ )
743 791
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
744 792
 					str* next_hop, str* path, struct proxy_l *proxy,
745 793
 					struct socket_info* fsocket, snd_flags_t snd_flags,
746
-					int proto, int flags, str *instance, str *ruid)
794
+					int proto, int flags, str *instance, str *ruid,
795
+					str *location_ua)
747 796
 {
748 797
 
749 798
 	int ret;
... ...
@@ -788,7 +837,8 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
788 837
 	/* now message printing starts ... */
789 838
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
790 839
 										next_hop, fsocket, snd_flags,
791
-										proto, flags, instance, ruid)) < 0)){
840
+										proto, flags, instance, ruid,
841
+										location_ua)) < 0)){
792 842
 		ser_error=ret;
793 843
 		goto error01;
794 844
 	}
... ...
@@ -829,7 +879,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
829 879
 								snd_flags_t send_flags,
830 880
 								int proto,
831 881
 								char *buf, short buf_len,
832
-								str *instance, str *ruid)
882
+								str *instance, str *ruid,
883
+								str *location_ua)
833 884
 {
834 885
 
835 886
 	int ret;
... ...
@@ -932,6 +983,22 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
932 983
 		t->uac[branch].ruid.s[ruid->len]=0;
933 984
 		memcpy( t->uac[branch].ruid.s, ruid->s, ruid->len);
934 985
 	}
986
+	/* copy the location_ua */
987
+	if (unlikely(location_ua && location_ua->s)){
988
+		t->uac[branch].location_ua.s=shm_malloc(location_ua->len+1);
989
+		if (unlikely(t->uac[branch].location_ua.s==0)) {
990
+			shm_free(shbuf);
991
+			t->uac[branch].request.buffer=0;
992
+			t->uac[branch].request.buffer_len=0;
993
+			t->uac[branch].uri.s=0;
994
+			t->uac[branch].uri.len=0;
995
+			ret=ser_error=E_OUT_OF_MEM;
996
+			goto error;
997
+		}
998
+		t->uac[branch].location_ua.len=location_ua->len;
999
+		t->uac[branch].location_ua.s[location_ua->len]=0;
1000
+		memcpy( t->uac[branch].location_ua.s, location_ua->s, location_ua->len);
1001
+	}
935 1002
 	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
936 1003
 					   to be sure everything above is fully written before
937 1004
 					   updating branches no. */
... ...
@@ -1004,7 +1071,8 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
1004 1071
 							old_uac->request.dst.proto,
1005 1072
 							old_uac->request.buffer,
1006 1073
 							old_uac->request.buffer_len,
1007
-							&old_uac->instance, &old_uac->ruid);
1074
+							&old_uac->instance, &old_uac->ruid,
1075
+							&old_uac->location_ua);
1008 1076
 			}else
1009 1077
 				/* add_uac will use dns_h => next_hop will be ignored.
1010 1078
 				 * 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 1084
 									old_uac->request.dst.send_sock:0,
1017 1085
 							old_uac->request.dst.send_flags,
1018 1086
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F,
1019
-							&old_uac->instance, &old_uac->ruid);
1087
+							&old_uac->instance, &old_uac->ruid,
1088
+							&old_uac->location_ua);
1020 1089
 
1021 1090
 			if (ret<0){
1022 1091
 				/* failed, delete the copied dns_h */
... ...
@@ -1092,7 +1161,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
1092 1161
 									&t_invite->uac[branch].uri,
1093 1162
 									&t_invite->uac[branch].path,
1094 1163
 									0, 0, snd_flags, PROTO_NONE, 0,
1095
-									NULL, NULL)) <0)){
1164
+									NULL, NULL, NULL)) <0)){
1096 1165
 			ser_error=ret;
1097 1166
 			goto error;
1098 1167
 		}
... ...
@@ -1551,7 +1620,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1551 1620
 	int success_branch;
1552 1621
 	int try_new;
1553 1622
 	int lock_replies;
1554
-	str dst_uri, path, instance, ruid;
1623
+	str dst_uri, path, instance, ruid, location_ua;
1555 1624
 	struct socket_info* si;
1556 1625
 	flag_t backup_bflags = 0;
1557 1626
 	flag_t bflags = 0;
... ...
@@ -1617,7 +1686,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1617 1686
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
1618 1687
 							&p_msg->path_vec, proxy, p_msg->force_send_socket,
1619 1688
 							p_msg->fwd_send_flags, proto,
1620
-							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance, &p_msg->ruid);
1689
+							(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F, &p_msg->instance,
1690
+							&p_msg->ruid, &p_msg->location_ua);
1621 1691
 		if (branch_ret>=0) 
1622 1692
 			added_branches |= 1<<branch_ret;
1623 1693
 		else
... ...
@@ -1626,14 +1696,15 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1626 1696
 
1627 1697
 	init_branch_iterator();
1628 1698
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
1629
-										&bflags, &si, &ruid, &instance))) {
1699
+										&bflags, &si, &ruid, &instance, &location_ua))) {
1630 1700
 		try_new++;
1631 1701
 		setbflagsval(0, bflags);
1632 1702
 
1633 1703
 		branch_ret=add_uac( t, p_msg, &current_uri,
1634 1704
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
1635 1705
 							&path, proxy, si, p_msg->fwd_send_flags,
1636
-							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance, &ruid);
1706
+							proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
1707
+							&ruid, &location_ua);
1637 1708
 		/* pick some of the errors in case things go wrong;
1638 1709
 		   note that picking lowest error is just as good as
1639 1710
 		   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 95
 static str flags_name = {"flags", 5};
95 96
 static str q_flag_name = {"q_flag", 6};
96 97
 static str ruid_name = {"ruid", 4};
98
+static str ua_name = {"ua", 2};
97 99
 
98 100
 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
99 101
 		      unsigned int flags, unsigned int q_flag, str *instance,
100
-		      str *ruid)
102
+		      str *ruid, str *location_ua)
101 103
 {
102 104
     sr_xavp_t *record;
103 105
     sr_xval_t val;
... ...
@@ -145,6 +147,12 @@ void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
145 147
 	xavp_add_value(&ruid_name, &val, &record);
146 148
     }
147 149
 
150
+    if (location_ua->len > 0) {
151
+	val.type = SR_XTYPE_STR;
152
+	val.v.s = *location_ua;
153
+	xavp_add_value(&ua_name, &val, &record);
154
+    }
155
+
148 156
     val.type = SR_XTYPE_XAVP;
149 157
     val.v.xavp = record;
150 158
     xavp_add_value(&contacts_avp, &val, NULL);
... ...
@@ -202,6 +210,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
202 210
 	contacts->q = get_ruri_q();
203 211
 	contacts->instance = msg->instance;
204 212
         contacts->ruid = msg->ruid;
213
+	contacts->location_ua = msg->location_ua;
205 214
 	first_idx = 0;
206 215
     } else {
207 216
 	/* Insert first branch to first contact */
... ...
@@ -219,6 +228,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
219 228
 	contacts->instance.len = branch->instance_len;
220 229
         contacts->ruid.s = branch->ruid;
221 230
         contacts->ruid.len = branch->ruid_len;
231
+	contacts->location_ua.s = branch->location_ua;
232
+	contacts->location_ua.len = branch->location_ua_len;
222 233
 	first_idx = 1;
223 234
     }
224 235
 
... ...
@@ -247,6 +258,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
247 258
 	next->instance.len = branch->instance_len;
248 259
 	next->ruid.s = branch->ruid;
249 260
 	next->ruid.len = branch->ruid_len;
261
+	next->location_ua.s = branch->location_ua;
262
+	next->location_ua.len = branch->location_ua_len;
250 263
 	next->next = (struct contact *)0;
251 264
 
252 265
 	prev = (struct contact *)0;
... ...
@@ -299,7 +312,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
299 312
 
300 313
 	add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
301 314
 			 &sock_str, curr->flags, curr->q_flag,
302
-			 &(curr->instance), &(curr->ruid));
315
+			 &(curr->instance), &(curr->ruid), &(curr->location_ua));
303 316
 
304 317
 	curr = curr->next;
305 318
     }
... ...
@@ -314,7 +327,8 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
314 327
 }
315 328
 
316 329
 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
317
-			   unsigned int flags, str *instance, str *ruid)
330
+			   unsigned int flags, str *instance, str *ruid,
331
+			   str *location_ua)
318 332
 {
319 333
     sr_xavp_t *record;
320 334
     sr_xval_t val;
... ...
@@ -354,6 +368,12 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
354 368
 	xavp_add_value(&ruid_name, &val, &record);
355 369
     }
356 370
 
371
+    if (location_ua->len > 0) {
372
+	val.type = SR_XTYPE_STR;
373
+	val.v.s = *location_ua;
374
+	xavp_add_value(&ua_name, &val, &record);
375
+    }
376
+
357 377
     val.type = SR_XTYPE_INT;
358 378
     val.v.i = flags;
359 379
     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 396
  * there was nothing to do. Returns -1 in case of an error. */
377 397
 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
378 398
 {
379
-    str uri, dst_uri, path, instance, host, sock_str, ruid;
399
+    str uri, dst_uri, path, instance, host, sock_str, ruid, location_ua;
380 400
     struct socket_info *sock;
381 401
     unsigned int flags, q_flag;
382 402
     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 491
     vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
472 492
     ruid = vavp->val.v.s;
473 493
 
494
+    vavp = xavp_get(&ua_name, xavp->val.v.xavp);
495
+    location_ua = vavp->val.v.s;
496
+
474 497
     /* Rewrite Request-URI */
475 498
     rewrite_uri(msg, &uri);
476 499
 
... ...
@@ -492,6 +515,8 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
492 515
 
493 516
     set_ruid(msg, &ruid);
494 517
 
518
+    set_ua(msg, &location_ua);
519
+
495 520
     /* Check if there was only one contact at this priority */
496 521
     if (q_flag) {
497 522
 	xavp_rm(xavp, NULL);
... ...
@@ -556,6 +581,9 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
556 581
 	vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
557 582
 	ruid = vavp->val.v.s;
558 583
 
584
+	vavp = xavp_get(&ua_name, xavp->val.v.xavp);
585
+	location_ua = vavp->val.v.s;
586
+
559 587
 	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
560 588
 	if (vavp != NULL) {
561 589
 	    instance = vavp->val.v.s;
... ...
@@ -568,7 +596,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
568 596
 	    }
569 597
 	    if (ilp) {
570 598
 		add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
571
-				      flags, &instance, &ruid);
599
+				      flags, &instance, &ruid, &location_ua);
572 600
 		goto check_q_flag;
573 601
 	    }
574 602
 	    if (!q_flag) {
... ...
@@ -595,14 +623,15 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
595 623
 		instance.len = 0;
596 624
 	}
597 625
 
598
-	LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s' ruid-'%.*s'\n",
626
+	LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s'"
627
+		" ruid-'%.*s' location_ua-'%.*s'\n",
599 628
 		uri.len, uri.s,
600 629
 		dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
601 630
 		path.len, (path.len>0)?path.s:"",
602 631
 		instance.len, (instance.len>0)?instance.s:"",
603
-		ruid.len, ruid.s);
632
+		ruid.len, ruid.s, location_ua.len, location_ua.s);
604 633
 	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
605
-			  &ruid) != 1) {
634
+			  &ruid, &location_ua) != 1) {
606 635
 	    LM_ERR("appending branch failed\n");
607 636
 	    free_instance_list(il);
608 637
 	    xavp_destroy_list(&xavp_list);
... ...
@@ -637,7 +666,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
637 666
  * there was nothing to do. Returns -1 in case of an error. */
638 667
 int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
639 668
 {
640
-    str uri, dst_uri, path, instance, host, ruid;
669
+    str uri, dst_uri, path, instance, host, ruid, location_ua;
641 670
 	str this_instance;
642 671
     struct socket_info *sock;
643 672
     unsigned int flags;
... ...
@@ -728,14 +757,18 @@ int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
728 757
 		vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
729 758
 		ruid = vavp->val.v.s;
730 759
 
731
-		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s' ruid-'%.*s'\n",
760
+		vavp = xavp_get(&ua_name, xavp->val.v.xavp);
761
+		location_ua = vavp->val.v.s;
762
+
763
+		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s'"
764
+			" inst-'%.*s' ruid-'%.*s' location_ua-'%.*s'\n",
732 765
 			uri.len, uri.s,
733 766
 			dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
734 767
 			path.len, (path.len>0)?path.s:"",
735 768
 			instance.len, (instance.len>0)?instance.s:"",
736
-			ruid.len, ruid.s);
769
+			ruid.len, ruid.s, location_ua.len, location_ua.s);
737 770
 		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
738
-			  &ruid) != 1) {
771
+			  &ruid, &location_ua) != 1) {
739 772
 			LM_ERR("appending branch failed\n");
740 773
 			xavp_destroy_list(&xavp_list);
741 774
 			return -1;