Browse code

Merge remote branch 'origin/sr_3.0'

latest sr_3.0 fixes.

* origin/sr_3.0: (36 commits)
core: added id to every field of gw table schema
tcp: use the forced socket ip as source
tmx: pv_t_copy_msg: copy also the send flags
textops(k): msg_apply_changes: preserve the send flags
seas: use set_force_socket()
rr(k): use set_force_socket()
registrar(k): use set_force_socket()
pv: use set_force_socket()
kex: use set_force_socket()
domainpolicy: use set_force_socket()
rr(s): use set_force_socket()
registrar(s): use set_force_socket()
tm: use set_force_socket() instead of msg->force_send_socket
tm: preserve forced sockets and send flags during dns failover
core: extra flag when forcing a socket
core: kamailio mode config parser fix
core: PAI and PPI parsing support fixed
core: dset minor cleanups
core: append_branch() sets also the send_socket, path & flags
remove extra backslash in make modules-doc action
...

Andrei Pelinescu-Onciul authored on 06/11/2009 07:56:40
Showing 28 changed files
... ...
@@ -527,7 +527,7 @@ $(1)-doc: modules.lst
527 527
 	@for r in $($(1)) "" ; do \
528 528
 		if [ -n "$$$$r" ]; then \
529 529
 			$(call oecho, "" ;) \
530
-			$(call oecho, "" ;) \\
530
+			$(call oecho, "" ;) \
531 531
 			$(MAKE) -C $$$$r/doc $(doc_format) $$(mk_params); \
532 532
 		fi ; \
533 533
 	done
... ...
@@ -347,15 +347,16 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
347 347
 
348 348
 		/* jku -- introduce a new branch */
349 349
 		case APPEND_BRANCH_T:
350
-			if ((a->val[0].type!=STRING_ST)) {
350
+			if (unlikely(a->val[0].type!=STR_ST)) {
351 351
 				LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
352 352
 					a->val[0].type );
353 353
 				ret=E_BUG;
354 354
 				goto error;
355 355
 			}
356
-			ret=ser_append_branch( msg, a->val[0].u.string,
357
-					   a->val[0].u.string ? strlen(a->val[0].u.string):0,
358
-					   0, 0, a->val[1].u.number, 0);
356
+			getbflagsval(0, (flag_t*)&flags);
357
+			ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
358
+								&msg->path_vec, a->val[1].u.number,
359
+								(flag_t)flags, msg->force_send_socket);
359 360
 			break;
360 361
 
361 362
 		/* jku begin: is_length_greater_than */
... ...
@@ -1208,7 +1209,7 @@ match_cleanup:
1208 1208
 				ret=E_BUG;
1209 1209
 				goto error;
1210 1210
 			}
1211
-			msg->force_send_socket=(struct socket_info*)a->val[0].u.data;
1211
+			set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
1212 1212
 			ret=1; /* continue processing */
1213 1213
 			break;
1214 1214
 
... ...
@@ -962,10 +962,16 @@ EAT_ABLE	[\ \t\b\r]
962 962
 <PVAR_P>{LPAREN}			{ p_nest++; yymore(); }
963 963
 <PVAR_P>.					{ yymore(); }
964 964
 
965
-<PVARID>{ID}|'.'			{yymore(); }
965
+<PVARID>{ID}|'\.'			{yymore(); }
966 966
 <PVARID>{LPAREN}			{	state = PVAR_P_S; BEGIN(PVAR_P);
967 967
 								p_nest=1; yymore(); }
968
-<PVARID>.					{ yyless(0); state=INITIAL_S; BEGIN(INITIAL);
968
+<PVARID>.					{	yyless(yyleng-1);
969
+								count();
970
+								addstr(&s_buf, yytext, yyleng);
971
+								yylval.strval=s_buf.s;
972
+								memset(&s_buf, 0, sizeof(s_buf));
973
+								state=INITIAL_S;
974
+								BEGIN(INITIAL);
969 975
 								return PVAR;
970 976
 							}
971 977
 
... ...
@@ -238,6 +238,7 @@ void clear_branches(void)
238 238
 {
239 239
 	nr_branches = 0;
240 240
 	ruri_q = Q_UNSPECIFIED;
241
+	ruri_bflags = 0;
241 242
 }
242 243
 
243 244
 
... ...
@@ -443,24 +444,6 @@ qvalue_t get_ruri_q(void)
443 443
 
444 444
 
445 445
 /*
446
- * Get actual Request-URI
447
- */
448
-int get_request_uri(struct sip_msg* _m, str* _u)
449
-{
450
-	     /* Use new_uri if present */
451
-	if (_m->new_uri.s) {
452
-		_u->s = _m->new_uri.s;
453
-		_u->len = _m->new_uri.len;
454
-	} else {
455
-		_u->s = _m->first_line.u.request.uri.s;
456
-		_u->len = _m->first_line.u.request.uri.len;
457
-	}
458
-
459
-	return 0;
460
-}
461
-
462
-
463
-/*
464 446
  * Rewrite Request-URI
465 447
  */
466 448
 int rewrite_uri(struct sip_msg* _m, str* _s)
... ...
@@ -484,8 +467,6 @@ int rewrite_uri(struct sip_msg* _m, str* _s)
484 484
         _m->new_uri.s = buf;
485 485
         _m->new_uri.len = _s->len;
486 486
 
487
-        DBG("rewrite_uri: Rewriting Request-URI with '%.*s'\n", _s->len, 
488
-																		   buf);
489 487
         return 1;
490 488
 }
491 489
 
... ...
@@ -33,8 +33,8 @@
33 33
 #include "ip_addr.h"
34 34
 #include "qvalue.h"
35 35
 #include "flags.h"
36
+#include "parser/msg_parser.h"
36 37
 
37
-struct sip_msg;
38 38
 
39 39
 extern unsigned int nr_branches;
40 40
 
... ...
@@ -118,7 +118,19 @@ void set_ruri_q(qvalue_t q);
118 118
  */
119 119
 qvalue_t get_ruri_q(void);
120 120
 
121
-int get_request_uri(struct sip_msg* _m, str* _u);
121
+
122
+
123
+/*
124
+ * Get actual Request-URI
125
+ */
126
+inline static int get_request_uri(struct sip_msg* _m, str* _u)
127
+{
128
+	*_u=*GET_RURI(_m);
129
+	return 0;
130
+}
131
+
132
+
133
+
122 134
 int rewrite_uri(struct sip_msg* _m, str* _s);
123 135
 
124 136
 /*! \brief
... ...
@@ -123,6 +123,11 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
123 123
 {
124 124
 	struct dest_info new_dst;
125 125
 	str outb;
126
+#ifdef USE_TCP 
127
+	union sockaddr_union* from;
128
+	union sockaddr_union local_addr;
129
+#endif
130
+	
126 131
 	outb.s = buf;
127 132
 	outb.len = len;
128 133
 	sr_event_exec(SREV_NET_DATA_OUT, (void*)&outb);
... ...
@@ -152,7 +157,14 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
152 152
 					" support is disabled\n");
153 153
 			goto error;
154 154
 		}else{
155
-			if (unlikely(tcp_send(dst, 0, outb.s, outb.len)<0)){
155
+			from=0;
156
+			if (unlikely((dst->send_flags & SND_F_FORCE_SOCKET) &&
157
+						dst->send_sock)) {
158
+				local_addr=dst->send_sock->su;
159
+				su_setport(&local_addr, 0); /* any local port will do */
160
+				from=&local_addr;
161
+			}
162
+			if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
156 163
 				STATS_TX_DROPS;
157 164
 				LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
158 165
 				goto error;
... ...
@@ -167,7 +179,14 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
167 167
 					" support is disabled\n");
168 168
 			goto error;
169 169
 		}else{
170
-			if (unlikely(tcp_send(dst, 0, outb.s, outb.len)<0)){
170
+			from=0;
171
+			if (unlikely((dst->send_flags & SND_F_FORCE_SOCKET) &&
172
+						dst->send_sock)) {
173
+				local_addr=dst->send_sock->su;
174
+				su_setport(&local_addr, 0); /* any local port will do */
175
+				from=&local_addr;
176
+			}
177
+			if (unlikely(tcp_send(dst, from, outb.s, outb.len)<0)){
171 178
 				STATS_TX_DROPS;
172 179
 				LOG(L_ERR, "msg_send: ERROR: tcp_send failed\n");
173 180
 				goto error;
... ...
@@ -140,6 +140,7 @@ struct receive_info{
140 140
 /* send flags */
141 141
 #define SND_F_FORCE_CON_REUSE	1 /* reuse an existing connection or fail */
142 142
 #define SND_F_CON_CLOSE			2 /* close the connection after sending */
143
+#define SND_F_FORCE_SOCKET		4 /* send socket in dst is forced */
143 144
 
144 145
 typedef unsigned char  snd_flags_t;
145 146
 
... ...
@@ -47,14 +47,14 @@
47 47
         <description>ID of gateway's group</description>
48 48
     </column>
49 49
 
50
-    <column>
50
+    <column id="ip_addr">
51 51
         <name>ip_addr</name>
52 52
         <type>string</type>
53 53
         <size>15</size>
54 54
         <description>IP Address of the gateway</description>
55 55
     </column>
56 56
 
57
-    <column>
57
+    <column id="hostname">
58 58
         <name>hostname</name>
59 59
         <type>string</type>
60 60
         <size>64</size>
... ...
@@ -62,35 +62,35 @@
62 62
         <description>Hostname of the gateway</description>
63 63
     </column>
64 64
 
65
-    <column>
65
+    <column id="port">
66 66
         <name>port</name>
67 67
         <type>unsigned short</type>
68 68
         <null/>
69 69
         <description>Port of the gateway</description>
70 70
     </column>
71 71
 
72
-    <column>
72
+    <column id="uri_scheme">
73 73
         <name>uri_scheme</name>
74 74
         <type>unsigned char</type>
75 75
         <null/>
76 76
         <description>URI scheme of gateway</description>
77 77
     </column>
78 78
 
79
-    <column>
79
+    <column id="transport">
80 80
         <name>transport</name>
81 81
         <type>unsigned char</type>
82 82
         <null/>
83 83
         <description>Transport type to be used for the gateway</description>
84 84
     </column>
85 85
 
86
-    <column>
86
+    <column id="strip">
87 87
         <name>strip</name>
88 88
         <type>unsigned char</type>
89 89
         <null/>
90 90
         <description>The number of digits to strip from Request URI user part before inserting tag</description>
91 91
     </column>
92 92
 
93
-    <column>
93
+    <column id="tag">
94 94
         <name>tag</name>
95 95
         <type>string</type>
96 96
         <size>16</size>
... ...
@@ -99,21 +99,21 @@
99 99
         <description>Request URI user part tag</description>
100 100
     </column>
101 101
 
102
-    <column>
102
+    <column id="weight">
103 103
         <name>weight</name>
104 104
         <type>unsigned int</type>
105 105
         <null/>
106 106
         <description>Weight of gateway within gw_grp.  Valid values are 1-254.</description>
107 107
     </column>
108 108
 
109
-    <column>
109
+    <column id="flags">
110 110
         <name>flags</name>
111 111
         <type>unsigned int</type>
112 112
         <default>&DEFAULT_FLAGS;</default>
113 113
         <description>Gateway specific flags</description>
114 114
     </column>
115 115
 
116
-    <column>
116
+    <column id="defunct">
117 117
         <name>defunct</name>
118 118
         <type>unsigned int</type>
119 119
         <null/>
... ...
@@ -122,10 +122,19 @@
122 122
     </column>
123 123
 
124 124
     <index>
125
-        <name>lcr_id_gw_name_idx</name>
125
+        <name>lcr_id_grp_id_gw_name_idx</name>
126 126
         <colref linkend="lcr_id"/>
127
+        <colref linkend="grp_id"/>
127 128
         <colref linkend="gw_name"/>
128 129
         <unique/>
129 130
     </index>
130 131
 
132
+    <index>
133
+        <name>lcr_id_grp_id_ip_addr_idx</name>
134
+        <colref linkend="lcr_id"/>
135
+        <colref linkend="grp_id"/>
136
+        <colref linkend="ip_addr"/>
137
+        <unique/>
138
+    </index>
139
+
131 140
 </table>
... ...
@@ -167,7 +167,7 @@ struct matched_gw_info {
167 167
     unsigned short prefix_len;
168 168
     unsigned short priority;
169 169
     unsigned int weight;
170
-    unsigned int defunct_until;
170
+    unsigned short duplicate;
171 171
 };
172 172
 
173 173
 /*
... ...
@@ -1428,7 +1428,7 @@ int mi_print_gws(struct mi_node* rpl)
1428 1428
 	    attr = add_mi_attr(node, MI_DUP_VALUE, "TAG", 3,
1429 1429
 			       gws[i].tag, gws[i].tag_len);
1430 1430
 	    if (attr == NULL) goto err;
1431
-	    
1431
+
1432 1432
 	    p = int2str((unsigned long)gws[i].weight, &len);
1433 1433
 	    attr = add_mi_attr(node, MI_DUP_VALUE, "WEIGHT", 6, p, len);
1434 1434
 	    if (attr == NULL) goto err;
... ...
@@ -1674,6 +1674,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
1674 1674
     delete_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp);
1675 1675
 
1676 1676
     for (i = 0; i < gw_cnt; i++) {
1677
+	if (matched_gws[i].duplicate == 1) continue;
1677 1678
 	index = matched_gws[i].gw_index;
1678 1679
       	hostname_len = gws[index].hostname_len;
1679 1680
 	strip = gws[index].strip;
... ...
@@ -1700,7 +1701,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
1700 1700
 	add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
1701 1701
 
1702 1702
 	LM_DBG("added gw_uri_avp <%.*s> with weight <%u>\n",
1703
-		value.len, value.s, matched_gws[i].weight);
1703
+	       value.len, value.s, matched_gws[i].weight);
1704 1704
     skip:
1705 1705
 	continue;
1706 1706
     }
... ...
@@ -1713,8 +1714,8 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
1713 1713
 static int load_gws(struct sip_msg* _m, char *_lcr_id, char *_from_uri)
1714 1714
 {
1715 1715
     str ruri_user, from_uri;
1716
-    unsigned int j, k, gw_index, gw_count, now;
1717
-    int lcr_id;
1716
+    int i, j, lcr_id;
1717
+    unsigned int gw_index, gw_count, now, ip_addr;
1718 1718
     int_str val;
1719 1719
     struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1];
1720 1720
     struct lcr_info **lcrs, *lcr_rec, *pl;
... ...
@@ -1786,18 +1787,12 @@ static int load_gws(struct sip_msg* _m, char *_lcr_id, char *_from_uri)
1786 1786
 		    while (j) {
1787 1787
                         /* If this gw is defunct, skip it */
1788 1788
 		        if (gws[j].defunct_until > now) goto gw_found;
1789
-			for (k = 0; k < gw_index; k++) {
1790
-			    if (gws[j].ip_addr ==
1791
-				gws[matched_gws[k].gw_index].ip_addr)
1792
-				/* Skip already existing gw */
1793
-				goto gw_found;
1794
-			}
1795
-			/* This is a new gw */
1796 1789
 			matched_gws[gw_index].gw_index = j;
1797 1790
 			matched_gws[gw_index].prefix_len = pl->prefix_len;
1798 1791
 			matched_gws[gw_index].priority = lcr_rec->priority;
1799 1792
 			matched_gws[gw_index].weight = gws[j].weight *
1800 1793
 			    (rand() >> 8);
1794
+			matched_gws[gw_index].duplicate = 0;
1801 1795
 			LM_DBG("added matched_gws[%d]=[%u, %u, %u, %u]\n",
1802 1796
 			       gw_index, j, pl->prefix_len, lcr_rec->priority,
1803 1797
 			       matched_gws[gw_index].weight);
... ...
@@ -1812,9 +1807,21 @@ static int load_gws(struct sip_msg* _m, char *_lcr_id, char *_from_uri)
1812 1812
 	pl = pl->next;
1813 1813
     }
1814 1814
 
1815
-    /* Sort gateways based on prefix_len, priority, and randomized weight */
1815
+    /* Sort gateways in reverse order based on prefix_len, priority,
1816
+       and randomized weight */
1816 1817
     qsort(matched_gws, gw_index, sizeof(struct matched_gw_info), comp_matched);
1817 1818
 
1819
+    /* Remove duplicate gws */
1820
+    for (i = gw_index - 1; i >= 0; i--) {
1821
+	if (matched_gws[i].duplicate == 1) continue;
1822
+	ip_addr = gws[matched_gws[i].gw_index].ip_addr;
1823
+	for (j = i - 1; j >= 0; j--) {
1824
+	    if (gws[matched_gws[j].gw_index].ip_addr == ip_addr) {
1825
+		matched_gws[j].duplicate = 1;
1826
+	    }
1827
+	}
1828
+    }
1829
+
1818 1830
     /* Add gateways into gw_uris_avp */
1819 1831
     add_gws_into_avps(gws, matched_gws, gw_index, &ruri_user);
1820 1832
 
... ...
@@ -81,7 +81,7 @@ static void dump_gws(rpc_t* rpc, void* c)
81 81
 		if (rpc->add(c, "{", &st) < 0) return;
82 82
 		rpc->struct_add(st, "d", "lcr_id", j);
83 83
 		rpc->struct_add(st, "d", "grp_id", gws[i].grp_id);
84
-		rpc->struct_printf(st,   "ip_addr", "%d.%d.%d.%d",
84
+		rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d",
85 85
 				   (gws[i].ip_addr << 24) >> 24,
86 86
 				   ((gws[i].ip_addr >> 8) << 24) >> 24,
87 87
 				   ((gws[i].ip_addr >> 16) << 24) >> 24,
... ...
@@ -117,9 +117,9 @@ static void dump_gws(rpc_t* rpc, void* c)
117 117
 		tag.len=gws[i].tag_len;
118 118
 		rpc->struct_add(st, "dSddd",
119 119
 				"strip",  gws[i].strip,
120
-				"tag",    gws[i].tag, /* FIXME */
120
+				"tag",    &tag,
121 121
 				"weight", gws[i].weight,
122
-				"flags",  &tag,
122
+				"flags",  gws[i].flags,
123 123
 				"defunct_until",  &gws[i].defunct_until
124 124
 				);
125 125
 	    }
... ...
@@ -159,7 +159,7 @@ unsigned int get_on_branch(void)
159 159
    the sending information: t->uac[branch].request.dst, branch buffer, uri
160 160
    path vector a.s.o.) and runs the on_branch route.
161 161
  * t->uac[branch].request.dst will be filled if next_hop !=0 with the result
162
- * of the DNS resolution (next_hop and fproto).
162
+ * of the DNS resolution (next_hop, fproto and fsocket).
163 163
  * If next_hop is 0 all the dst members except the send_flags are read-only
164 164
  * (send_flags it's updated) and are supposed to be pre-filled.
165 165
  *
... ...
@@ -174,6 +174,8 @@ unsigned int get_on_branch(void)
174 174
  *              for DNS resolution and the branch request.dst structure will
175 175
  *              be filled. If 0 the branch must already have
176 176
  *              a pre-filled valid request.dst.
177
+ * @param fsocket - forced send socket for forwarding.
178
+ * @param send_flags - special flags for sending (see SND_F_* / snd_flags_t).
177 179
  * @param fproto - forced proto for forwarding. Used only if next_hop!=0.
178 180
  * @param flags - 0 or UAC_DNS_FAILOVER_F for now.
179 181
  *
... ...
@@ -181,8 +183,10 @@ unsigned int get_on_branch(void)
181 181
  */
182 182
 static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
183 183
 									int branch, str *uri, str* path,
184
-									str* next_hop, int fproto,
185
-									int flags)
184
+									str* next_hop,
185
+									struct socket_info* fsocket,
186
+									snd_flags_t snd_flags,
187
+									int fproto, int flags)
186 188
 {
187 189
 	char *shbuf;
188 190
 	struct lump* add_rm_backup, *body_lumps_backup;
... ...
@@ -198,6 +202,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
198 198
 	int backup_route_type;
199 199
 	snd_flags_t fwd_snd_flags_bak;
200 200
 	snd_flags_t rpl_snd_flags_bak;
201
+	struct socket_info *force_send_socket_bak;
201 202
 	struct dest_info *dst;
202 203
 
203 204
 	shbuf=0;
... ...
@@ -232,8 +237,6 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
232 232
 #endif
233 233
 	add_rm_backup = i_req->add_rm;
234 234
 	body_lumps_backup = i_req->body_lumps;
235
-	i_req->add_rm=0;
236
-	i_req->body_lumps=0;
237 235
 	if (unlikely(i_req->add_rm)){
238 236
 		i_req->add_rm = dup_lump_list(i_req->add_rm);
239 237
 		if (unlikely(i_req->add_rm==0)){
... ...
@@ -323,17 +326,22 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
323 323
 			   (
324 324
 			 */
325 325
 			if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
326
-				/* backup ireq msg send flags */
326
+				/* backup ireq msg send flags and force_send_socket*/
327 327
 				fwd_snd_flags_bak=i_req->fwd_send_flags;;
328 328
 				rpl_snd_flags_bak=i_req->rpl_send_flags;
329
-				i_req->fwd_send_flags=dst->send_flags /* intial value  */;
329
+				force_send_socket_bak=i_req->force_send_socket;
330
+				/* set the new values */
331
+				i_req->fwd_send_flags=snd_flags /* intial value  */;
332
+				set_force_socket(i_req, fsocket);
330 333
 				if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0)
331 334
 				{
332 335
 					LOG(L_ERR, "Error in run_top_route\n");
333 336
 				}
334
-				/* update dst send_flags */
335
-				dst->send_flags=i_req->fwd_send_flags;
336
-				/* restore ireq_msg flags */
337
+				/* update dst send_flags  and send socket*/
338
+				snd_flags=i_req->fwd_send_flags;
339
+				fsocket=i_req->force_send_socket;
340
+				/* restore ireq_msg force_send_socket & flags */
341
+				set_force_socket(i_req, force_send_socket_bak);
337 342
 				i_req->fwd_send_flags=fwd_snd_flags_bak;
338 343
 				i_req->rpl_send_flags=rpl_snd_flags_bak;
339 344
 				exec_post_script_cb(i_req, BRANCH_CB_TYPE);
... ...
@@ -378,11 +386,12 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
378 378
 	if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
379 379
 		/* next_hop present => use it for dns resolution */
380 380
 #ifdef USE_DNS_FAILOVER
381
-		if (uri2dst(&t->uac[branch].dns_h, dst, i_req,
381
+		if (uri2dst2(&t->uac[branch].dns_h, dst, fsocket, snd_flags,
382 382
 							next_hop?next_hop:uri, fproto) == 0)
383 383
 #else
384 384
 		/* dst filled from the uri & request (send_socket) */
385
-		if (uri2dst(dst, i_req, next_hop?next_hop:uri, fproto)==0)
385
+		if (uri2dst2(dst, fsocket, snd_flags,
386
+							next_hop?next_hop:uri, fproto)==0)
386 387
 #endif
387 388
 		{
388 389
 			ret=E_BAD_ADDRESS;
... ...
@@ -454,6 +463,7 @@ error03:
454 454
 	i_req->parsed_uri=parsed_uri_bak;
455 455
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
456 456
 	i_req->path_vec=path_bak;
457
+	
457 458
 	/* Delete the duplicated lump lists, this will also delete
458 459
 	 * all lumps created here, such as lumps created in per-branch
459 460
 	 * routing sections, Via, and Content-Length headers created in
... ...
@@ -605,6 +615,8 @@ int add_blind_uac( /*struct cell *t*/ )
605 605
  *                     uri format, e.g.: "<sip:1.2.3.4;lr>, <sip:5.6.7.8;lr>").
606 606
  *  @param proxy    - proxy structure. If non-null it takes precedence over
607 607
  *                    next_hop/uri and it will be used for forwarding.
608
+ *  @param fsocket  - forced forward send socket (can be 0).
609
+ *  @param snd_flags - special send flags (see SND_F_* / snd_flags_t)
608 610
  *  @param proto    - forced protocol for forwarding (overrides the protocol
609 611
  *                    in next_hop/uri or proxy if != PROTO_NONE).
610 612
  *  @param flags    - special flags passed to prepare_new_uac().
... ...
@@ -613,6 +625,7 @@ int add_blind_uac( /*struct cell *t*/ )
613 613
 */
614 614
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
615 615
 					str* next_hop, str* path, struct proxy_l *proxy,
616
+					struct socket_info* fsocket, snd_flags_t snd_flags,
616 617
 					int proto, int flags)
617 618
 {
618 619
 
... ...
@@ -655,7 +668,8 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
655 655
 
656 656
 	/* now message printing starts ... */
657 657
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
658
-											next_hop, proto, flags)) < 0)){
658
+										next_hop, fsocket, snd_flags,
659
+										proto, flags)) < 0)){
659 660
 		ser_error=ret;
660 661
 		goto error01;
661 662
 	}
... ...
@@ -691,7 +705,10 @@ error:
691 691
    the failed branch to construct the new message in case of DNS failover.
692 692
 */
693 693
 static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
694
-								str *uri, str* path, int proto,
694
+								str *uri, str* path,
695
+								struct socket_info* fsocket,
696
+								snd_flags_t send_flags,
697
+								int proto,
695 698
 								char *buf, short buf_len)
696 699
 {
697 700
 
... ...
@@ -715,8 +732,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
715 715
 		goto error;
716 716
 	}
717 717
 
718
-	if (uri2dst(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
719
-				request, uri, proto) == 0)
718
+	if (uri2dst2(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
719
+					fsocket, send_flags, uri, proto) == 0)
720 720
 	{
721 721
 		ret=ser_error=E_BAD_ADDRESS;
722 722
 		goto error;
... ...
@@ -822,21 +839,29 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
822 822
 			dns_srv_handle_cpy(&t->uac[t->nr_of_outgoings].dns_h,
823 823
 								&old_uac->dns_h);
824 824
 
825
-			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover))
825
+			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover)){
826 826
 				/* Reuse the old buffer and only replace the via header.
827 827
 				 * The drawback is that the send_socket is not corrected
828 828
 				 * in the rest of the message, only in the VIA HF (Miklos) */
829 829
 				ret=add_uac_from_buf(t,  msg, &old_uac->uri,
830 830
 							&old_uac->path,
831
+							 (old_uac->request.dst.send_flags &
832
+								SND_F_FORCE_SOCKET)?
833
+									old_uac->request.dst.send_sock:0,
834
+							old_uac->request.dst.send_flags,
831 835
 							old_uac->request.dst.proto,
832 836
 							old_uac->request.buffer,
833 837
 							old_uac->request.buffer_len);
834
-			else
838
+			}else
835 839
 				/* add_uac will use dns_h => next_hop will be ignored.
836 840
 				 * Unfortunately we can't reuse the old buffer, the branch id
837 841
 				 *  must be changed and the send_socket might be different =>
838 842
 				 *  re-create the whole uac */
839 843
 				ret=add_uac(t,  msg, &old_uac->uri, 0, &old_uac->path, 0,
844
+							 (old_uac->request.dst.send_flags &
845
+								SND_F_FORCE_SOCKET)?
846
+									old_uac->request.dst.send_sock:0,
847
+							old_uac->request.dst.send_flags,
840 848
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F);
841 849
 
842 850
 			if (ret<0){
... ...
@@ -908,7 +933,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
908 908
 		if (unlikely((ret=prepare_new_uac( t_cancel, cancel_msg, branch,
909 909
 									&t_invite->uac[branch].uri,
910 910
 									&t_invite->uac[branch].path,
911
-									0, PROTO_NONE, 0)) <0)){
911
+									0, 0, 0, PROTO_NONE, 0)) <0)){
912 912
 			ser_error=ret;
913 913
 			goto error;
914 914
 		}
... ...
@@ -1244,7 +1269,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1244 1244
 	int try_new;
1245 1245
 	int lock_replies;
1246 1246
 	str dst_uri, path;
1247
-	struct socket_info* si, *backup_si;
1247
+	struct socket_info* si;
1248 1248
 	flag_t backup_bflags = 0;
1249 1249
 	flag_t bflags = 0;
1250 1250
 	
... ...
@@ -1269,7 +1294,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1269 1269
 		}
1270 1270
 	}
1271 1271
 
1272
-	backup_si = p_msg->force_send_socket;
1273 1272
 	getbflagsval(0, &backup_bflags);
1274 1273
 
1275 1274
 	/* if no more specific error code is known, use this */
... ...
@@ -1305,7 +1329,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1305 1305
 #endif
1306 1306
 		try_new=1;
1307 1307
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
1308
-							&p_msg->path_vec, proxy, proto, 0);
1308
+							&p_msg->path_vec, proxy, p_msg->force_send_socket,
1309
+							p_msg->fwd_send_flags, proto, 0);
1309 1310
 		if (branch_ret>=0) 
1310 1311
 			added_branches |= 1<<branch_ret;
1311 1312
 		else
... ...
@@ -1316,12 +1341,12 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1316 1316
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
1317 1317
 										&bflags, &si))) {
1318 1318
 		try_new++;
1319
-		p_msg->force_send_socket = si;
1320 1319
 		setbflagsval(0, bflags);
1321 1320
 
1322 1321
 		branch_ret=add_uac( t, p_msg, &current_uri,
1323 1322
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
1324
-							&path, proxy, proto, 0);
1323
+							&path, proxy, si, p_msg->fwd_send_flags,
1324
+							proto, 0);
1325 1325
 		/* pick some of the errors in case things go wrong;
1326 1326
 		   note that picking lowest error is just as good as
1327 1327
 		   any other algorithm which picks any other negative
... ...
@@ -1334,7 +1359,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1334 1334
 	/* consume processed branches */
1335 1335
 	clear_branches();
1336 1336
 
1337
-	p_msg->force_send_socket = backup_si;
1338 1337
 	setbflagsval(0, backup_bflags);
1339 1338
 
1340 1339
 	/* don't forget to clear all branches processed so far */
... ...
@@ -447,7 +447,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
447 447
 		else reset_dst_uri(msg);
448 448
 		if (path.s && path.len) set_path_vector(msg, &path);
449 449
 		else reset_path_vector(msg);
450
-		msg->force_send_socket = sock;
450
+		set_force_socket(msg, sock);
451 451
 		setbflagsval(0, flags);
452 452
 
453 453
 		if (avp->flags & Q_FLAG) {
... ...
@@ -850,7 +850,7 @@ int dp_apply_policy(struct sip_msg* _msg, char* _s1, char* _s2) {
850 850
 		}
851 851
 		si = grep_sock_info( &host, (unsigned short) port, (unsigned short) proto);
852 852
 		if (si) {
853
-			_msg->force_send_socket = si;
853
+			set_force_socket(_msg, si);
854 854
 		} else {
855 855
 			LM_WARN("could not find socket for"
856 856
 					"send_socket '%.*s'\n", val.s.len, ZSW(val.s.s));
... ...
@@ -44,7 +44,7 @@ int w_km_append_branch(struct sip_msg *msg, char *uri, str *sq)
44 44
 		ret = km_append_branch(msg, 0, &msg->dst_uri, &msg->path_vec,
45 45
 			q, branch_flags, msg->force_send_socket);
46 46
 		/* reset all branch info */
47
-		msg->force_send_socket = 0;
47
+		reset_force_socket(msg);
48 48
 		setbflagsval(0, 0);
49 49
 		if(msg->dst_uri.s!=0)
50 50
 			pkg_free(msg->dst_uri.s);
... ...
@@ -1882,7 +1882,7 @@ int pv_set_force_sock(struct sip_msg* msg, pv_param_t *param,
1882 1882
 
1883 1883
 	if(val==NULL || (val->flags&PV_VAL_NULL))
1884 1884
 	{
1885
-		msg->force_send_socket = NULL;
1885
+		reset_force_socket(msg);
1886 1886
 		return 0;
1887 1887
 	}
1888 1888
 
... ...
@@ -1904,7 +1904,7 @@ int pv_set_force_sock(struct sip_msg* msg, pv_param_t *param,
1904 1904
 	si = grep_sock_info(&host, (unsigned short)port, (unsigned short)proto);
1905 1905
 	if (si!=NULL)
1906 1906
 	{
1907
-		msg->force_send_socket = si;
1907
+		set_force_socket(msg, si);
1908 1908
 	} else {
1909 1909
 		LM_WARN("no socket found to match [%.*s]\n",
1910 1910
 				val->rs.len, val->rs.s);
... ...
@@ -134,7 +134,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
134 134
 		setbflagsval( 0, ptr->cflags);
135 135
 
136 136
 		if (ptr->sock)
137
-			_m->force_send_socket = ptr->sock;
137
+			set_force_socket(_m, ptr->sock);
138 138
 
139 139
 		ptr = ptr->next;
140 140
 	}
... ...
@@ -280,7 +280,7 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
280 280
 
281 281
 		/* set flags */
282 282
 		ci.flags  = _f;
283
-		getbflagsval(0, &ci.flags);
283
+		getbflagsval(0, &ci.cflags);
284 284
 
285 285
 		/* get received */
286 286
 		if (path_received.len && path_received.s) {
... ...
@@ -597,7 +597,7 @@ static inline int after_strict(struct sip_msg* _m)
597 597
 		 * send interface the one advertise in second Route */
598 598
 		si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
599 599
 		if (si) {
600
-			_m->force_send_socket = si;
600
+			set_force_socket(_m, si);
601 601
 		} else {
602 602
 			LM_WARN("no socket found for match second RR\n");
603 603
 		}
... ...
@@ -813,7 +813,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
813 813
 			}
814 814
 			si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
815 815
 			if (si) {
816
-				_m->force_send_socket = si;
816
+				set_force_socket(_m, si);
817 817
 			} else {
818 818
 				LM_WARN("no socket found for match second RR\n");
819 819
 			}
... ...
@@ -817,7 +817,9 @@ int ac_sl_msg(as_p the_as,char *action,int len)
817 817
    }else{
818 818
       uri = GET_RURI(my_msg);
819 819
    }
820
-   my_msg->force_send_socket=grep_sock_info(&my_msg->via1->host,my_msg->via1->port,my_msg->via1->proto);
820
+   set_force_socket(my_msg, grep_sock_info(&my_msg->via1->host,
821
+                                            my_msg->via1->port,
822
+                                            my_msg->via1->proto) );
821 823
    /* or also could be:
822 824
       my_msg->force_send_socket=the_as->binds[processor_id].bind_address;
823 825
       not sure which is better...
... ...
@@ -1903,6 +1903,8 @@ static int msg_apply_changes_f(sip_msg_t *msg, char *str1, char *str2)
1903 1903
 	msg->flags              = tmp.flags;
1904 1904
 	msg->msg_flags          = tmp.msg_flags;
1905 1905
 	msg->force_send_socket  = tmp.force_send_socket;
1906
+	msg->fwd_send_flags     = tmp.fwd_send_flags;
1907
+	msg->rpl_send_flags     = tmp.rpl_send_flags;
1906 1908
 	msg->dst_uri            = tmp.dst_uri;
1907 1909
 	msg->path_vec           = tmp.path_vec;
1908 1910
 
... ...
@@ -52,6 +52,8 @@ int pv_t_copy_msg(struct sip_msg *src, struct sip_msg *dst)
52 52
 	dst->set_global_address=src->set_global_address;
53 53
 	dst->set_global_port=src->set_global_port;
54 54
 	dst->flags = src->flags;
55
+	dst->fwd_send_flags = src->fwd_send_flags;
56
+	dst->rpl_send_flags = src->rpl_send_flags;
55 57
 	dst->force_send_socket = src->force_send_socket;
56 58
 
57 59
 	if (parse_msg(dst->buf, dst->len, dst)!=0)
... ...
@@ -139,7 +139,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
139 139
 		}
140 140
 
141 141
 		if (ptr->sock) {
142
-			_m->force_send_socket = ptr->sock;
142
+			set_force_socket(_m, ptr->sock);
143 143
 		}
144 144
 
145 145
 skip_rewrite_uri:
... ...
@@ -302,7 +302,7 @@ int lookup2(struct sip_msg* msg, char* table, char* p2)
302 302
 		}
303 303
 
304 304
 		if (ptr->sock) {
305
-			msg->force_send_socket = ptr->sock;
305
+			set_force_socket(msg, ptr->sock);
306 306
 		}
307 307
 
308 308
 skip_rewrite_uri:
... ...
@@ -901,9 +901,9 @@ static inline int after_loose(struct sip_msg* _m, struct sip_uri* _pru, int _rou
901 901
 					LOG(L_ERR, "after_loose: Error while parsing the second route header\n");
902 902
 					return RR_ERROR;
903 903
 				}
904
-				_m->force_send_socket = grep_sock_info(&parsed_uri.host,
905
-								parsed_uri.port_no,
906
-								parsed_uri.proto);
904
+				set_force_socket(_m, grep_sock_info(&parsed_uri.host,
905
+													parsed_uri.port_no,
906
+													parsed_uri.proto) );
907 907
 				if (_m->force_send_socket == 0)
908 908
 					LOG(L_WARN, "after_loose: send socket cannot be set"
909 909
 						" based on the second route header\n");
... ...
@@ -221,6 +221,15 @@ void clean_hdr_field(struct hdr_field* hf)
221 221
 		case HDR_PATH_T:
222 222
 		case HDR_PRIVACY_T:
223 223
 			break;
224
+
225
+		case HDR_PPI_T:
226
+			free_to(hf->parsed);
227
+			break;
228
+
229
+		case HDR_PAI_T:
230
+			free_to(hf->parsed);
231
+			break;
232
+
224 233
 		default:
225 234
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
226 235
 			    hf->type);
... ...
@@ -255,6 +255,8 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
255 255
 		case HDR_PROXY_AUTHENTICATE_T:
256 256
 	    case HDR_PATH_T:
257 257
 	    case HDR_PRIVACY_T:
258
+	    case HDR_PAI_T:
259
+	    case HDR_PPI_T:
258 260
 		case HDR_OTHER_T:
259 261
 			/* just skip over it */
260 262
 			hdr->body.s=tmp;
... ...
@@ -540,6 +542,14 @@ int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next)
540 540
 				if (msg->privacy==0) msg->privacy=hf;
541 541
 				msg->parsed_flag|=HDR_PRIVACY_F;
542 542
 				break;
543
+		    case HDR_PAI_T:
544
+				if (msg->pai==0) msg->pai=hf;
545
+				msg->parsed_flag|=HDR_PAI_F;
546
+				break;
547
+		    case HDR_PPI_T:
548
+				if (msg->ppi==0) msg->ppi=hf;
549
+				msg->parsed_flag|=HDR_PPI_F;
550
+				break;
543 551
 			default:
544 552
 				LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
545 553
 							hf->type);
... ...
@@ -472,4 +472,23 @@ int set_path_vector(struct sip_msg* msg, str* path);
472 472
 
473 473
 void reset_path_vector(struct sip_msg* msg);
474 474
 
475
+
476
+/** force a specific send socket for forwarding a request.
477
+ * @param msg - sip msg.
478
+ * @param fsocket - forced socket, pointer to struct socket_info, can be 0 (in
479
+ *                  which case it's equivalent to reset_force_socket()).
480
+ */
481
+#define set_force_socket(msg, fsocket) \
482
+	do { \
483
+		(msg)->force_send_socket=(fsocket); \
484
+		if ((msg)->force_send_socket) \
485
+			(msg)->fwd_send_flags |= SND_F_FORCE_SOCKET; \
486
+		else \
487
+			(msg)->fwd_send_flags &= ~SND_F_FORCE_SOCKET; \
488
+	} while (0)
489
+
490
+/** reset a previously forced send socket. */
491
+#define reset_force_socket(msg) set_force_socket(msg, 0)
492
+
493
+
475 494
 #endif
... ...
@@ -170,6 +170,24 @@ static inline char* skip_ws(char* p, unsigned int size)
170 170
         }
171 171
 
172 172
 
173
+int hdr_update_type(struct hdr_field* hdr)
174
+{
175
+	if(hdr==0 || hdr->name.s==0)
176
+		return -1;
177
+	switch(hdr->name.len) {
178
+		case 19:
179
+			if(strncasecmp(hdr->name.s, "P-Asserted-Identity", 19)==0)
180
+				hdr->type = HDR_PAI_T;
181
+		break;
182
+		case 20:
183
+			if(strncasecmp(hdr->name.s, "P-Preferred-Identity", 20)==0)
184
+				hdr->type = HDR_PPI_T;
185
+		break;
186
+	}
187
+
188
+	return 0;
189
+}
190
+
173 191
 char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
174 192
 {
175 193
 	register char* p;
... ...
@@ -249,6 +267,8 @@ char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
249 249
 	} else {
250 250
 		hdr->type = HDR_OTHER_T;
251 251
 		hdr->name.len = p - hdr->name.s;
252
+		hdr_update_type(hdr);
252 253
 		return (p + 1);
253 254
 	}
254 255
 }
256
+
... ...
@@ -983,6 +983,17 @@ int fix_actions(struct action* a)
983 983
 									(unsigned int)t->val[0].u.number);
984 984
 				}
985 985
 				break;
986
+			case APPEND_BRANCH_T:
987
+				if (t->val[0].type!=STRING_ST){
988
+					BUG("invalid subtype%d for append_branch_t\n",
989
+								t->val[0].type);
990
+					return E_BUG;
991
+				}
992
+				s.s=t->val[0].u.string;
993
+				s.len=(s.s)?strlen(s.s):0;
994
+				t->val[0].u.str=s;
995
+				t->val[0].type=STR_ST;
996
+				break;
986 997
 			default:
987 998
 				/* no fixup required for the rest */
988 999
 				break;