Browse code

Merge commit 'origin/andrei/path'

* commit 'origin/andrei/path':
core: add path route headers after local via
core: path support when forwarding
tm: path support
xlog(s): updated to the new next_branch()
registrar(s): updated to the new append_branch()
permissions(s): updated to the new next_branch()
osp(s): updated to the new append_branch()
exec(s): use ser_append_branch() instead of append_branch()
cpl-c(s): updated to the new append_branch()
tm: updated to the new append_branch() & next_branch()
enum: s/km_append_brach/append_branch/
avpops: updated to the new append_branch()
core: append_branch & next_branch api changes

Conflicts:
modules/tm/sip_msg.c
modules/tm/t_fwd.c

Andrei Pelinescu-Onciul authored on 18/09/2009 11:36:33
Showing 20 changed files
... ...
@@ -345,7 +345,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
345 345
 				ret=E_BUG;
346 346
 				goto error;
347 347
 			}
348
-			ret=append_branch( msg, a->val[0].u.string,
348
+			ret=ser_append_branch( msg, a->val[0].u.string,
349 349
 					   a->val[0].u.string ? strlen(a->val[0].u.string):0,
350 350
 					   0, 0, a->val[1].u.number, 0);
351 351
 			break;
... ...
@@ -160,41 +160,6 @@ int get_branch_iterator(void)
160 160
 	return branch_iterator;
161 161
 }
162 162
 
163
-/*
164
- * Return the next branch from the dset
165
- * array, 0 is returned if there are no
166
- * more branches
167
- */
168
-char* next_branch(int* len, qvalue_t* q, char** dst_uri, int* dst_len, struct socket_info** force_socket)
169
-{
170
-	unsigned int i;
171
-
172
-	i = branch_iterator;
173
-	if (i < nr_branches) {
174
-		branch_iterator++;
175
-		*len = branches[i].len;
176
-		*q = branches[i].q;
177
-		if (dst_uri && dst_len) {
178
-			*dst_uri = branches[i].dst_uri;
179
-			*dst_len = branches[i].dst_uri_len;
180
-		}
181
-		if (force_socket) {
182
-			*force_socket = branches[i].force_send_socket;
183
-		}
184
-		return branches[i].uri;
185
-	} else {
186
-		*len = 0;
187
-		*q = Q_UNSPECIFIED;
188
-		if (dst_uri && dst_len) {
189
-			*dst_uri = 0;
190
-			*dst_len = 0;
191
-		}
192
-		if (force_socket) {
193
-			*force_socket = 0;
194
-		}
195
-		return 0;
196
-	}
197
-}
198 163
 
199 164
 
200 165
 /** \brief Get a branch from the destination set
... ...
@@ -203,7 +168,8 @@ char* next_branch(int* len, qvalue_t* q, char** dst_uri, int* dst_len, struct so
203 203
  * more branches
204 204
  */
205 205
 char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
206
-				 str* path, unsigned int *flags, struct socket_info** force_socket)
206
+				 str* path, unsigned int *flags,
207
+				 struct socket_info** force_socket)
207 208
 {
208 209
 	if (i < nr_branches) {
209 210
 		*len = branches[i].len;
... ...
@@ -228,6 +194,10 @@ char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
228 228
 			dst_uri->s = 0;
229 229
 			dst_uri->len = 0;
230 230
 		}
231
+		if (path) {
232
+			path->s = 0;
233
+			path->len = 0;
234
+		}
231 235
 		if (force_socket)
232 236
 			*force_socket = 0;
233 237
 		if (flags)
... ...
@@ -237,6 +207,23 @@ char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
237 237
 }
238 238
 
239 239
 
240
+
241
+/** Return the next branch from the dset array.
242
+ * 0 is returned if there are no more branches
243
+ */
244
+char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
245
+					unsigned int* flags, struct socket_info** force_socket)
246
+{
247
+	char* ret;
248
+	
249
+	ret=get_branch(branch_iterator, len, q, dst_uri, path, flags,
250
+					force_socket);
251
+	if (likely(ret))
252
+		branch_iterator++;
253
+	return ret;
254
+}
255
+
256
+
240 257
 /*
241 258
  * Empty the dset array
242 259
  */
... ...
@@ -247,84 +234,32 @@ void clear_branches(void)
247 247
 }
248 248
 
249 249
 
250
-/* 
251
- * Add a new branch to current transaction 
252
- */
253
-int append_branch(struct sip_msg* msg, char* uri, int uri_len, char* dst_uri, int dst_uri_len, 
254
-		  qvalue_t q, struct socket_info* force_socket)
255
-{
256
-	     /* if we have already set up the maximum number
257
-	      * of branches, don't try new ones 
258
-	      */
259
-	if (nr_branches == MAX_BRANCHES - 1) {
260
-		LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
261
-		ser_error = E_TOO_MANY_BRANCHES;
262
-		return -1;
263
-	}
264
-
265
-	if (uri_len > MAX_URI_SIZE - 1) {
266
-		LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
267
-		    uri_len, uri);
268
-		return -1;
269
-	}
270
-	
271
-	if (dst_uri_len > MAX_URI_SIZE - 1) {
272
-		LOG(L_ERR, "ERROR: append_branch: too long dst_uri: %.*s\n",
273
-		    dst_uri_len, ZSW(dst_uri));
274
-		return -1;
275
-	}
276
-
277
-	     /* if not parameterized, take current uri */
278
-	if (uri == 0) {
279
-		if (msg->new_uri.s) { 
280
-			uri = msg->new_uri.s;
281
-			uri_len = msg->new_uri.len;
282
-		} else {
283
-			uri = msg->first_line.u.request.uri.s;
284
-			uri_len = msg->first_line.u.request.uri.len;
285
-		}
286
-	}
287
-	
288
-	memcpy(branches[nr_branches].uri, uri, uri_len);
289
-	     /* be safe -- add zero termination */
290
-	branches[nr_branches].uri[uri_len] = 0;
291
-	branches[nr_branches].len = uri_len;
292
-	branches[nr_branches].q = q;
293
-	
294
- 	if (dst_uri && dst_uri_len) {
295
-  		memcpy(branches[nr_branches].dst_uri, dst_uri, dst_uri_len);
296
-  		branches[nr_branches].dst_uri[dst_uri_len] = 0;
297
-  		branches[nr_branches].dst_uri_len = dst_uri_len;
298
- 	} else {
299
- 		branches[nr_branches].dst_uri[0] = '\0';
300
- 		branches[nr_branches].dst_uri_len = 0;
301
-	}
302
-
303
-	branches[nr_branches].force_send_socket = force_socket;
304
-	
305
-	nr_branches++;
306
-	return 1;
307
-}
308
-
309 250
 
310
-/* ! \brief
311
- * Add a new branch to current transaction using str parameters
312
- * Kamailio compatibility version
251
+/**  Add a new branch to the current transaction.
252
+ * @param msg - sip message, used for getting the uri if not specified (0).
253
+ * @param uri - uri, can be 0 (in which case the uri is taken from msg)
254
+ * @param dst_uri - destination uri, can be 0.
255
+ * @param path - path vector (passed in a string), can be 0.
256
+ * @param q  - q value.
257
+ * @param flags - per branch flags.
258
+ * @param force_socket - socket that should be used when sending.
259
+ *
260
+ * @return  <0 (-1) on failure, 1 on success (script convention).
313 261
  */
314
-int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
262
+int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
315 263
 		qvalue_t q, unsigned int flags, struct socket_info* force_socket)
316 264
 {
317 265
 	str luri;
318 266
 
319 267
 #ifdef USE_LOCAL_ROUTE
320
-	if (dset_state==0)
268
+	if (unlikely(dset_state==0))
321 269
 		return -1;
322 270
 #endif
323 271
 
324 272
 	/* if we have already set up the maximum number
325 273
 	 * of branches, don't try new ones 
326 274
 	 */
327
-	if (nr_branches == MAX_BRANCHES - 1) {
275
+	if (unlikely(nr_branches == MAX_BRANCHES - 1)) {
328 276
 		LOG(L_ERR, "max nr of branches exceeded\n");
329 277
 		ser_error = E_TOO_MANY_BRANCHES;
330 278
 		return -1;
... ...
@@ -340,16 +275,15 @@ int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
340 340
 		luri = *uri;
341 341
 	}
342 342
 
343
-	if (luri.len > MAX_URI_SIZE - 1) {
343
+	if (unlikely(luri.len > MAX_URI_SIZE - 1)) {
344 344
 		LOG(L_ERR, "too long uri: %.*s\n", luri.len, luri.s);
345 345
 		return -1;
346 346
 	}
347 347
 
348 348
 	/* copy the dst_uri */
349 349
 	if (dst_uri && dst_uri->len && dst_uri->s) {
350
-		if (dst_uri->len > MAX_URI_SIZE - 1) {
351
-			LOG(L_ERR, "too long dst_uri: %.*s\n",
352
-				dst_uri->len, dst_uri->s);
350
+		if (unlikely(dst_uri->len > MAX_URI_SIZE - 1)) {
351
+			LOG(L_ERR, "too long dst_uri: %.*s\n", dst_uri->len, dst_uri->s);
353 352
 			return -1;
354 353
 		}
355 354
 		memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
... ...
@@ -361,8 +295,8 @@ int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
361 361
 	}
362 362
 
363 363
 	/* copy the path string */
364
-	if (path && path->len && path->s) {
365
-		if (path->len > MAX_PATH_SIZE - 1) {
364
+	if (unlikely(path && path->len && path->s)) {
365
+		if (unlikely(path->len > MAX_PATH_SIZE - 1)) {
366 366
 			LOG(L_ERR, "too long path: %.*s\n", path->len, path->s);
367 367
 			return -1;
368 368
 		}
... ...
@@ -413,7 +347,7 @@ char* print_dset(struct sip_msg* msg, int* len)
413 413
 	}
414 414
 
415 415
 	init_branch_iterator();
416
-	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
416
+	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) {
417 417
 		cnt++;
418 418
 		*len += uri.len;
419 419
 		if (q != Q_UNSPECIFIED) {
... ...
@@ -454,7 +388,7 @@ char* print_dset(struct sip_msg* msg, int* len)
454 454
 	}
455 455
 
456 456
 	init_branch_iterator();
457
-	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) {
457
+	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) {
458 458
 		if (i) {
459 459
 			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
460 460
 			p += CONTACT_DELIM_LEN;
... ...
@@ -37,18 +37,39 @@ struct sip_msg;
37 37
 extern unsigned int nr_branches;
38 38
 
39 39
 
40
-/* 
40
+
41
+/*
41 42
  * Add a new branch to current transaction 
42 43
  */
43
-int append_branch(struct sip_msg* msg, char* uri, int uri_len, char* dst_uri, int dst_uri_len, 
44
-		  qvalue_t q, struct socket_info* force_socket);
44
+int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
45
+					 qvalue_t q, unsigned int flags,
46
+					 struct socket_info* force_socket);
45 47
 
48
+/* kamailio compatible version */
49
+#define km_append_branch(msg, uri, dst_uri, path, q, flags, force_socket) \
50
+	append_branch(msg, uri, dst_uri, path, q, flags, force_socket)
46 51
 
47
-int km_append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
48
-					 qvalue_t q, unsigned int flags, struct socket_info* force_socket);
52
+/** ser compatible append_branch version.
53
+ *  append_branch version compatible with ser: no path or branch flags support
54
+ *  and no str parameters.
55
+ */
56
+static inline int ser_append_branch(struct sip_msg* msg,
57
+									char* uri, int uri_len,
58
+									char* dst_uri, int dst_uri_len,
59
+									qvalue_t q,
60
+									struct socket_info* force_socket)
61
+{
62
+	str s_uri, s_dst_uri;
63
+	s_uri.s=uri;
64
+	s_uri.len=uri_len;
65
+	s_dst_uri.s=dst_uri;
66
+	s_dst_uri.len=dst_uri_len;
67
+	return append_branch(msg, &s_uri, &s_dst_uri, 0, q, 0, force_socket);
68
+}
49 69
 
50 70
 
51
-/* 
71
+
72
+/*
52 73
  * Iterate through the list of transaction branches 
53 74
  */
54 75
 void init_branch_iterator(void);
... ...
@@ -58,14 +79,19 @@ void init_branch_iterator(void);
58 58
  */
59 59
 int get_branch_iterator(void);
60 60
 
61
-/*
62
- * Get the next branch in the current transaction
61
+
62
+/** Get the next branch in the current transaction.
63
+ * @return pointer to the uri of the next branch (which the length written in
64
+ *  *len) or 0 if there are no more branches.
63 65
  */
64
-char* next_branch(int* len, qvalue_t* q, char** dst_uri, int* dst_len, struct socket_info** force_socket);
66
+char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
67
+					unsigned int* flags, struct socket_info** force_socket);
65 68
 
66 69
 
67 70
 char* get_branch( unsigned int i, int* len, qvalue_t* q, str* dst_uri,
68
-				  str* path, unsigned int *flags, struct socket_info** force_socket);
71
+				  str* path, unsigned int *flags,
72
+				  struct socket_info** force_socket);
73
+
69 74
 
70 75
 
71 76
 /*
... ...
@@ -998,7 +998,7 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst,
998 998
 			{
999 999
 				/* if is not the first modification, push the current uri as
1000 1000
 				 * branch */
1001
-				if (append_branch( msg, 0, 0, 0, 0, Q_UNSPECIFIED, 0)!=1 )
1001
+				if (append_branch( msg, 0, 0, 0, Q_UNSPECIFIED, 0, 0)!=1 )
1002 1002
 				{
1003 1003
 					LM_ERR("append_branch action failed\n");
1004 1004
 					goto error;
... ...
@@ -1021,8 +1021,8 @@ int ops_pushto_avp (struct sip_msg* msg, struct fis_param* dst,
1021 1021
 				goto error;
1022 1022
 			}
1023 1023
 		} else if (dst->opd&AVPOPS_USE_BRANCH) {
1024
-			if (append_branch( msg, val.s, val.len, 0, 0, Q_UNSPECIFIED,
1025
-			msg->force_send_socket)!=1 )
1024
+			if (append_branch( msg, &val, 0, 0, Q_UNSPECIFIED, 0,
1025
+								msg->force_send_socket)!=1 )
1026 1026
 			{
1027 1027
 				LM_ERR("append_branch action failed\n");
1028 1028
 				goto error;
... ...
@@ -662,7 +662,7 @@ int do_query(struct sip_msg* _msg, char *user, char *name, str *service) {
662 662
 		q = q - 10;
663 663
 		curr_prio = priority;
664 664
 	    }
665
-	    if (km_append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
665
+	    if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
666 666
 		goto done;
667 667
 	    }
668 668
 	}
... ...
@@ -1105,7 +1105,7 @@ int enum_pv_query_3(struct sip_msg* _msg, char* _sp, char* _suffix,
1105 1105
 				q = q - 10;
1106 1106
 				curr_prio = priority;
1107 1107
 			}
1108
-			if (km_append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
1108
+			if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
1109 1109
 				goto done;
1110 1110
 			}
1111 1111
 		}
... ...
@@ -182,6 +182,9 @@ void free_cell( struct cell* dead_cell )
182 182
 		}
183 183
 		dns_srv_handle_put_shm_unsafe(&dead_cell->uac[i].dns_h);
184 184
 #endif
185
+		if (unlikely(dead_cell->uac[i].path.s)) {
186
+			shm_free_unsafe(dead_cell->uac[i].path.s);
187
+		}
185 188
 	}
186 189
 
187 190
 #ifdef WITH_AS_SUPPORT
... ...
@@ -219,7 +219,8 @@ typedef struct ua_client
219 219
 #ifdef USE_DNS_FAILOVER
220 220
 	struct dns_srv_handle dns_h;
221 221
 #endif
222
-	str              uri;
222
+	str uri;
223
+	str path;
223 224
 	/* if we don't store, we at least want to know the status */
224 225
 	int             last_received;
225 226
 
... ...
@@ -145,7 +145,7 @@ unsigned int get_on_branch(void)
145 145
 
146 146
 
147 147
 static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
148
-	int branch, str *uri, unsigned int *len, struct dest_info* dst)
148
+	int branch, str *uri, str* path, unsigned int *len, struct dest_info* dst)
149 149
 {
150 150
 	char *buf, *shbuf;
151 151
 	str* msg_uri;
... ...
@@ -153,6 +153,8 @@ static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
153 153
 	struct sip_uri parsed_uri_bak;
154 154
 	int parsed_uri_ok_bak, uri_backed_up;
155 155
 	str msg_uri_bak;
156
+	str path_bak;
157
+	int path_backed_up;
156 158
 	int backup_route_type;
157 159
 
158 160
 	shbuf=0;
... ...
@@ -160,6 +162,9 @@ static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
160 160
 	msg_uri_bak.len=0;
161 161
 	parsed_uri_ok_bak=0;
162 162
 	uri_backed_up=0;
163
+	path_bak.s=0;
164
+	path_bak.len=0;
165
+	path_backed_up=0;
163 166
 
164 167
 	/* ... we calculate branch ... */	
165 168
 	if (!t_calc_branch(t, branch, i_req->add_to_branch_s,
... ...
@@ -179,6 +184,13 @@ static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
179 179
 		i_req->parsed_uri_ok=0;
180 180
 		uri_backed_up=1;
181 181
 	}
182
+	/* update path_vec */
183
+	if (unlikely((i_req->path_vec.s!=path->s) ||
184
+					(i_req->path_vec.len!=path->len))){
185
+		path_bak=i_req->path_vec;
186
+		i_req->path_vec=*path;
187
+		path_backed_up=1;
188
+	}
182 189
 
183 190
 #ifdef POSTPONE_MSG_CLONING
184 191
 	/* lumps can be set outside of the lock, make sure that we read
... ...
@@ -191,13 +203,13 @@ static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
191 191
 	i_req->body_lumps = dup_lump_list(i_req->body_lumps);
192 192
 
193 193
 	if (unlikely(branch_route)) {
194
-		     /* run branch_route actions if provided */
194
+		/* run branch_route actions if provided */
195 195
 		backup_route_type = get_route_type();
196 196
 		set_route_type(BRANCH_ROUTE);
197 197
 		tm_ctx_set_branch_index(branch+1);
198 198
 		if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
199 199
 			if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0) {
200
-				LOG(L_ERR, "ERROR: print_uac_request: Error in run_top_route\n");
200
+				LOG(L_ERR, "Error in run_top_route\n");
201 201
 			}
202 202
 			exec_post_script_cb(i_req, BRANCH_CB_TYPE);
203 203
 		}		
... ...
@@ -251,17 +263,22 @@ error01:
251 251
 		i_req->parsed_uri=parsed_uri_bak;
252 252
 		i_req->parsed_uri_ok=parsed_uri_ok_bak;
253 253
 	}
254
+	if (unlikely(path_backed_up)){
255
+		i_req->path_vec=path_bak;
256
+	}
254 257
 
255
- error00:
258
+error00:
256 259
 	return shbuf;
257 260
 }
258 261
 
259 262
 #ifdef USE_DNS_FAILOVER
260
-/* Similar to print_uac_request(), but this function uses the outgoing message buffer of
261
-   the failed branch to construt the new message in case of DNS failover.
263
+/* Similar to print_uac_request(), but this function uses the outgoing message
264
+   buffer of the failed branch to construct the new message in case of DNS 
265
+   failover.
262 266
 
263 267
    WARNING: only the first VIA header is replaced in the buffer, the rest
264
-   of the message is untuched, thus, the send socket is corrected only in the VIA HF.
268
+   of the message is untouched, thus, the send socket is corrected only in the
269
+   VIA HF.
265 270
 */
266 271
 static char *print_uac_request_from_buf( struct cell *t, struct sip_msg *i_req,
267 272
 	int branch, str *uri, unsigned int *len, struct dest_info* dst,
... ...
@@ -381,7 +398,7 @@ int add_blind_uac( /*struct cell *t*/ )
381 381
    On error returns <0 & sets ser_error to the same value
382 382
 */
383 383
 int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
384
-	struct proxy_l *proxy, int proto )
384
+				str* path, struct proxy_l *proxy, int proto )
385 385
 {
386 386
 
387 387
 	int ret;
... ...
@@ -441,7 +458,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
441 441
 	}
442 442
 
443 443
 	/* now message printing starts ... */
444
-	shbuf=print_uac_request( t, request, branch, uri, 
444
+	shbuf=print_uac_request(t, request, branch, uri, path,
445 445
 							&len, &t->uac[branch].request.dst);
446 446
 	if (!shbuf) {
447 447
 		ret=ser_error=E_OUT_OF_MEM;
... ...
@@ -454,6 +471,21 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
454 454
 	t->uac[branch].uri.s=t->uac[branch].request.buffer+
455 455
 		request->first_line.u.request.method.len+1;
456 456
 	t->uac[branch].uri.len=uri->len;
457
+	if (unlikely(path && path->s)){
458
+		t->uac[branch].path.s=shm_malloc(path->len+1);
459
+		if (unlikely(t->uac[branch].path.s==0)) {
460
+			shm_free(shbuf);
461
+			t->uac[branch].request.buffer=0;
462
+			t->uac[branch].request.buffer_len=0;
463
+			t->uac[branch].uri.s=0;
464
+			t->uac[branch].uri.len=0;
465
+			ret=ser_error=E_OUT_OF_MEM;
466
+			goto error01;
467
+		}
468
+		t->uac[branch].path.len=path->len;
469
+		t->uac[branch].path.s[path->len]=0;
470
+		memcpy( t->uac[branch].path.s, path->s, path->len);
471
+	}
457 472
 #ifdef TM_UAC_FLAGS
458 473
 	len = count_applied_lumps(request->add_rm, HDR_RECORDROUTE_T);
459 474
 	if(len==1)
... ...
@@ -483,10 +515,11 @@ error:
483 483
 
484 484
 #ifdef USE_DNS_FAILOVER
485 485
 /* Similar to add_uac(), but this function uses the outgoing message buffer of
486
-   the failed branch to construt the new message in case of DNS failover.
486
+   the failed branch to construct the new message in case of DNS failover.
487 487
 */
488
-static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri, int proto,
489
-			char *buf, short buf_len)
488
+static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
489
+								str *uri, str* path, int proto,
490
+								char *buf, short buf_len)
490 491
 {
491 492
 
492 493
 	int ret;
... ...
@@ -496,7 +529,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri,
496 496
 
497 497
 	branch=t->nr_of_outgoings;
498 498
 	if (branch==MAX_BRANCHES) {
499
-		LOG(L_ERR, "ERROR: add_uac_from_buf: maximum number of branches exceeded\n");
499
+		LOG(L_ERR, "ERROR: add_uac_from_buf: maximum number of branches"
500
+					" exceeded\n");
500 501
 		ret=ser_error=E_TOO_MANY_BRANCHES;
501 502
 		goto error;
502 503
 	}
... ...
@@ -526,7 +560,7 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri,
526 526
 	}
527 527
 
528 528
 	/* now message printing starts ... */
529
-	shbuf=print_uac_request_from_buf( t, request, branch, uri, 
529
+	shbuf=print_uac_request_from_buf( t, request, branch, uri,
530 530
 							&len, &t->uac[branch].request.dst,
531 531
 							buf, buf_len);
532 532
 	if (!shbuf) {
... ...
@@ -540,6 +574,22 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri,
540 540
 	t->uac[branch].uri.s=t->uac[branch].request.buffer+
541 541
 		request->first_line.u.request.method.len+1;
542 542
 	t->uac[branch].uri.len=uri->len;
543
+	/* copy the path */
544
+	if (unlikely(path && path->s)){
545
+		t->uac[branch].path.s=shm_malloc(path->len+1);
546
+		if (unlikely(t->uac[branch].path.s==0)) {
547
+			shm_free(shbuf);
548
+			t->uac[branch].request.buffer=0;
549
+			t->uac[branch].request.buffer_len=0;
550
+			t->uac[branch].uri.s=0;
551
+			t->uac[branch].uri.len=0;
552
+			ret=ser_error=E_OUT_OF_MEM;
553
+			goto error;
554
+		}
555
+		t->uac[branch].path.len=path->len;
556
+		t->uac[branch].path.s[path->len]=0;
557
+		memcpy( t->uac[branch].path.s, path->s, path->len);
558
+	}
543 559
 	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
544 560
 					   to be sure everything above is fully written before
545 561
 					   updating branches no. */
... ...
@@ -564,7 +614,7 @@ error:
564 564
    already held, e.g. in failure route/handlers (WARNING: using 1 in a 
565 565
    failure route will cause a deadlock).
566 566
 */
567
-int add_uac_dns_fallback( struct cell *t, struct sip_msg* msg, 
567
+int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
568 568
 									struct ua_client* old_uac,
569 569
 									int lock_replies)
570 570
 {
... ...
@@ -600,9 +650,10 @@ int add_uac_dns_fallback( struct cell *t, struct sip_msg* msg,
600 600
 
601 601
 			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover))
602 602
 				/* Reuse the old buffer and only replace the via header.
603
-				 * The drowback is that the send_socket is not corrected
603
+				 * The drawback is that the send_socket is not corrected
604 604
 				 * in the rest of the message, only in the VIA HF (Miklos) */
605
-				ret=add_uac_from_buf(t,  msg, &old_uac->uri, 
605
+				ret=add_uac_from_buf(t,  msg, &old_uac->uri,
606
+							&old_uac->path,
606 607
 							old_uac->request.dst.proto,
607 608
 							old_uac->request.buffer,
608 609
 							old_uac->request.buffer_len);
... ...
@@ -611,7 +662,7 @@ int add_uac_dns_fallback( struct cell *t, struct sip_msg* msg,
611 611
 				 * Unfortunately we can't reuse the old buffer, the branch id
612 612
 				 *  must be changed and the send_socket might be different =>
613 613
 				 *  re-create the whole uac */
614
-				ret=add_uac(t,  msg, &old_uac->uri, 0, 0, 
614
+				ret=add_uac(t,  msg, &old_uac->uri, 0, &old_uac->path, 0,
615 615
 							old_uac->request.dst.proto);
616 616
 
617 617
 			if (ret<0){
... ...
@@ -666,9 +717,10 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
666 666
 
667 667
 	} else {
668 668
 		/* buffer is constructed from the received CANCEL with applying lumps */
669
-		shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
670
-							&t_invite->uac[branch].uri, &len, 
671
-							&t_invite->uac[branch].request.dst);
669
+		shbuf=print_uac_request( t_cancel, cancel_msg, branch,
670
+							&t_invite->uac[branch].uri,
671
+							&t_invite->uac[branch].path,
672
+							&len, &t_invite->uac[branch].request.dst);
672 673
 	}
673 674
 
674 675
 	if (!shbuf) {
... ...
@@ -1015,7 +1067,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1015 1015
 	int success_branch;
1016 1016
 	int try_new;
1017 1017
 	int lock_replies;
1018
-	str dst_uri;
1018
+	str dst_uri, path;
1019 1019
 	struct socket_info* si, *backup_si;
1020 1020
 	flag_t backup_bflags = 0;
1021 1021
 	flag_t bflags = 0;
... ...
@@ -1077,7 +1129,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1077 1077
 #endif
1078 1078
 		try_new=1;
1079 1079
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
1080
-							proxy, proto );
1080
+							&p_msg->path_vec, proxy, proto );
1081 1081
 		if (branch_ret>=0) 
1082 1082
 			added_branches |= 1<<branch_ret;
1083 1083
 		else
... ...
@@ -1085,16 +1137,15 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1085 1085
 	} else try_new=0;
1086 1086
 
1087 1087
 	init_branch_iterator();
1088
-	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri.s,
1089
-										&dst_uri.len, &si))) {
1088
+	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
1089
+										&bflags, &si))) {
1090 1090
 		try_new++;
1091 1091
 		p_msg->force_send_socket = si;
1092
-		getbflagsval(get_branch_iterator(), &bflags);
1093 1092
 		setbflagsval(0, bflags);
1094 1093
 
1095
-		branch_ret=add_uac( t, p_msg, &current_uri, 
1096
-							(dst_uri.len) ? (&dst_uri) : &current_uri, 
1097
-							proxy, proto);
1094
+		branch_ret=add_uac( t, p_msg, &current_uri,
1095
+							(dst_uri.len) ? (&dst_uri) : &current_uri,
1096
+							&path, proxy, proto);
1098 1097
 		/* pick some of the errors in case things go wrong;
1099 1098
 		   note that picking lowest error is just as good as
1100 1099
 		   any other algorithm which picks any other negative
... ...
@@ -59,8 +59,8 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
59 59
 */
60 60
 void e2e_cancel( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite );
61 61
 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch );
62
-int add_uac(	struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
63
-				struct proxy_l *proxy, int proto );
62
+int add_uac(struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
63
+				str* path, struct proxy_l *proxy, int proto );
64 64
 #ifdef USE_DNS_FAILOVER
65 65
 int add_uac_dns_fallback( struct cell *t, struct sip_msg* msg, 
66 66
 									struct ua_client* old_uac,
... ...
@@ -448,7 +448,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
448 448
 				return -1;
449 449
 			}
450 450
 
451
-			if (km_append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
451
+			if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
452 452
 				LM_ERR("appending branch failed\n");
453 453
 				destroy_avp(avp);
454 454
 				return -1;
... ...
@@ -488,8 +488,8 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
488 488
 				destroy_avp(avp);
489 489
 				return -1;
490 490
 			}
491
-	    
492
-			if (km_append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
491
+	
492
+			if (append_branch(msg, &uri, &dst, &path, 0, flags, sock) != 1) {
493 493
 				LM_ERR("appending branch failed\n");
494 494
 				destroy_avp(avp);
495 495
 				return -1;
... ...
@@ -83,7 +83,8 @@ int cpl_proxy_to_loc_set( struct sip_msg *msg, struct location **locs,
83 83
 	while(*locs) {
84 84
 		DBG("DEBUG:cpl_c:cpl_proxy_to_loc_set: appending branch "
85 85
 			"<%.*s>\n",(*locs)->addr.uri.len,(*locs)->addr.uri.s);
86
-		if(append_branch(msg,(*locs)->addr.uri.s,(*locs)->addr.uri.len,0, 0, Q_UNSPECIFIED, 0)==-1){
86
+		if(append_branch(msg, &(*locs)->addr.uri,
87
+							0, 0, Q_UNSPECIFIED, 0,  0)==-1){
87 88
 			LOG(L_ERR,"ERROR:cpl_c:cpl_proxy_to_loc_set: failed when "
88 89
 				"appending branch <%s>\n",(*locs)->addr.uri.s);
89 90
 			goto error;
... ...
@@ -171,7 +171,8 @@ int exec_str(struct sip_msg *msg, str* cmd, char *param, int param_len) {
171 171
 				goto error02;
172 172
 			}
173 173
 		} else {
174
-			if (append_branch(msg, uri_line, uri_len, 0, 0, Q_UNSPECIFIED, 0)==-1) {
174
+			if (ser_append_branch(msg, uri_line, uri_len, 0, 0,
175
+									Q_UNSPECIFIED, 0)==-1) {
175 176
 				LOG(L_ERR, "ERROR: exec_str: append_branch failed;"
176 177
 					" too many or too long URIs?\n");
177 178
 				goto error02;
... ...
@@ -452,7 +452,8 @@ static int ospPrepareDestination(
452 452
             if (isfirst == OSP_FIRST_ROUTE) {
453 453
                 rewrite_uri(msg, &newuri);
454 454
             } else {
455
-                append_branch(msg, newuri.s, newuri.len, NULL, 0, Q_UNSPECIFIED, NULL);
455
+                append_branch(msg, &newuri, NULL, NULL, Q_UNSPECIFIED,
456
+                              0, NULL);
456 457
             }
457 458
 
458 459
             result = MODULE_RETURNCODE_TRUE;
... ...
@@ -351,7 +351,7 @@ int check_routing(struct sip_msg* msg, int idx)
351 351
 
352 352
  check_branches:
353 353
         init_branch_iterator();
354
-        while((branch.s = next_branch(&branch.len, &q, 0, 0, 0))) {
354
+        while((branch.s = next_branch(&branch.len, &q, 0, 0, 0, 0))) {
355 355
                 uri_str = get_plain_uri(&branch);
356 356
                 if (!uri_str) {
357 357
                         LOG(L_ERR, "check_uri(): Error while extracting plain URI\n");
... ...
@@ -164,7 +164,7 @@ skip_rewrite_uri:
164 164
 					LOG(L_ERR, "ERROR: lookup(): branch: out of memory\n");
165 165
 					goto cont; /* try to continue */
166 166
 				}
167
-				if (append_branch(_m, new_uri.s, new_uri.len, 0, 0, ptr->q, 0) == -1) {
167
+				if (append_branch(_m, &new_uri, 0, 0, ptr->q, 0, 0) == -1) {
168 168
 					LOG(L_ERR, "lookup(): Error while appending a branch\n");
169 169
 					pkg_free(new_uri.s);
170 170
 					if (ser_error==E_TOO_MANY_BRANCHES) goto skip;
... ...
@@ -173,8 +173,8 @@ skip_rewrite_uri:
173 173
 				}
174 174
 				pkg_free(new_uri.s); /* append_branch doesn't free it */
175 175
 			}else{
176
-				if (append_branch(_m, ptr->c.s, ptr->c.len, ptr->received.s,
177
-							ptr->received.len, ptr->q, ptr->sock) == -1) {
176
+				if (append_branch(_m, &ptr->c, &ptr->received, 0 /* path */,
177
+									ptr->q, 0 /* brflags*/, ptr->sock) == -1) {
178 178
 					LOG(L_ERR, "lookup(): Error while appending a branch\n");
179 179
 					goto skip; /* Return OK here so the function succeeds */
180 180
 				}
... ...
@@ -326,7 +326,7 @@ skip_rewrite_uri:
326 326
 					ERR("branch: out of memory\n");
327 327
 					goto cont; /* try to continue */
328 328
 				}
329
-				if (append_branch(msg, new_uri.s, new_uri.len, 0, 0, ptr->q, 0) == -1) {
329
+				if (append_branch(msg, &new_uri, 0, 0, ptr->q, 0, 0) == -1) {
330 330
 					ERR("Error while appending a branch\n");
331 331
 					pkg_free(new_uri.s);
332 332
 					if (ser_error == E_TOO_MANY_BRANCHES) goto skip;
... ...
@@ -335,8 +335,8 @@ skip_rewrite_uri:
335 335
 				}
336 336
 				pkg_free(new_uri.s); /* append_branch doesn't free it */
337 337
 			} else {
338
-				if (append_branch(msg, ptr->c.s, ptr->c.len, ptr->received.s,
339
-							ptr->received.len, ptr->q, ptr->sock) == -1) {
338
+				if (append_branch(msg, &ptr->c, &ptr->received, 0 /* path */,
339
+									 ptr->q, 0, ptr->sock) == -1) {
340 340
 					ERR("Error while appending a branch\n");
341 341
 					goto skip; /* Return OK here so the function succeeds */
342 342
 				}
... ...
@@ -699,7 +699,7 @@ static int xl_get_branch(struct sip_msg *msg, str *res, str *hp, int hi, int hf)
699 699
 
700 700
 
701 701
 	init_branch_iterator();
702
-	branch.s = next_branch(&branch.len, &q, 0, 0, 0);
702
+	branch.s = next_branch(&branch.len, &q, 0, 0, 0, 0);
703 703
 	if (!branch.s) {
704 704
 		return xl_get_null(msg, res, hp, hi, hf);
705 705
 	}
... ...
@@ -730,7 +730,7 @@ static int xl_get_branches(struct sip_msg *msg, str *res, str *hp, int hi, int h
730 730
 	cnt = len = 0;
731 731
 
732 732
 	init_branch_iterator();
733
-	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0)))
733
+	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0)))
734 734
 	{
735 735
 		cnt++;
736 736
 		len += uri.len;
... ...
@@ -755,7 +755,7 @@ static int xl_get_branches(struct sip_msg *msg, str *res, str *hp, int hi, int h
755 755
 	p = local_buf;
756 756
 
757 757
 	init_branch_iterator();
758
-	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0)))
758
+	while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0)))
759 759
 	{
760 760
 		if (i)
761 761
 		{
... ...
@@ -1495,7 +1495,9 @@ error:
1495 1495
 /** builds a request in memory from another sip request.
1496 1496
   *
1497 1497
   * Side-effects: - it adds lumps to the msg which are _not_ cleaned.
1498
-  * All the added lumps are HDR_VIA_T.
1498
+  * The added lumps are HDR_VIA_T (almost always added), HDR_CONTENLENGTH_T
1499
+  * and HDR_ROUTE_T (when a Route: header is added as a result of a non-null
1500
+  * msg->path_vec).
1499 1501
   *               - it might change send_info->proto and send_info->send_socket
1500 1502
   *                 if proto fallback is enabled (see below).
1501 1503
   *
... ...
@@ -1516,8 +1518,16 @@ error:
1516 1516
   *                       message > mtu and send_info->proto==PROTO_UDP. 
1517 1517
   *                       It will also update send_info->proto.
1518 1518
   *                     - FL_FORCE_RPORT: add rport to via
1519
+  * @param mode - flags for building the message, can be a combination of:
1520
+  *                 * BUILD_NO_LOCAL_VIA - don't add a local via
1521
+  *                 * BUILD_NO_VIA1_UPDATE - don't update first via (rport,
1522
+  *                    received a.s.o)
1523
+  *                 * BUILD_NO_PATH - don't add a Route: header with the 
1524
+  *                   msg->path_vec content.
1525
+  *                 * BUILD_IN_SHM - build the result in shm memory
1519 1526
   *
1520
-  * @return pointer to the new request (pkg_malloc'ed, needs freeing when
1527
+  * @return pointer to the new request (pkg_malloc'ed or shm_malloc'ed,
1528
+  * depending on the presence of the BUILD_IN_SHM flag, needs freeing when
1521 1529
   *   done) and sets returned_len or 0 on error.
1522 1530
   */
1523 1531
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
... ...
@@ -1532,10 +1542,13 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1532 1532
 	char* rport_buf;
1533 1533
 	char* new_buf;
1534 1534
 	char* buf;
1535
+	str path_buf;
1535 1536
 	unsigned int offset, s_offset, size;
1536 1537
 	struct lump* via_anchor;
1537 1538
 	struct lump* via_lump;
1538 1539
 	struct lump* via_insert_param;
1540
+	struct lump* path_anchor;
1541
+	struct lump* path_lump;
1539 1542
 	str branch;
1540 1543
 	unsigned int flags;
1541 1544
 	unsigned int udp_mtu;
... ...
@@ -1550,8 +1563,11 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1550 1550
 	new_buf=0;
1551 1551
 	received_buf=0;
1552 1552
 	rport_buf=0;
1553
+	via_anchor=0;
1553 1554
 	line_buf=0;
1554 1555
 	via_len=0;
1556
+	path_buf.s=0;
1557
+	path_buf.len=0;
1555 1558
 
1556 1559
 	flags=msg->msg_flags|global_req_flags;
1557 1560
 	/* Calculate message body difference and adjust Content-Length */
... ...
@@ -1569,8 +1585,10 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1569 1569
 	branch.s=msg->add_to_branch_s;
1570 1570
 	branch.len=msg->add_to_branch_len;
1571 1571
 
1572
+	via_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA_T);
1573
+	if (unlikely(via_anchor==0)) goto error00;
1572 1574
 	line_buf = create_via_hf( &via_len, msg, send_info, &branch);
1573
-	if (!line_buf){
1575
+	if (unlikely(!line_buf)){
1574 1576
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: "
1575 1577
 					"memory allocation failure\n");
1576 1578
 		goto error00;
... ...
@@ -1653,6 +1671,45 @@ after_local_via:
1653 1653
 	}
1654 1654
 
1655 1655
 after_update_via1:
1656
+	/* add route with path content */
1657
+	if(unlikely(!(mode&BUILD_NO_PATH) && msg->path_vec.s &&
1658
+					msg->path_vec.len)){
1659
+		path_buf.len=ROUTE_PREFIX_LEN+msg->path_vec.len+CRLF_LEN;
1660
+		path_buf.s=pkg_malloc(path_buf.len+1);
1661
+		if (unlikely(path_buf.s==0)){
1662
+			LOG(L_ERR, "out of memory\n");
1663
+			ser_error=E_OUT_OF_MEM;
1664
+			goto error00;
1665
+		}
1666
+		memcpy(path_buf.s, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
1667
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN, msg->path_vec.s,
1668
+					msg->path_vec.len);
1669
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN+msg->path_vec.len, CRLF, CRLF_LEN);
1670
+		path_buf.s[path_buf.len]=0;
1671
+		/* insert Route header either before the other routes
1672
+		   (if present & parsed), after the local via or after in front of
1673
+		    the first via if we don't add a local via*/
1674
+		if (msg->route){
1675
+			path_anchor=anchor_lump(msg, msg->route->name.s-buf, 0, 
1676
+									HDR_ROUTE_T);
1677
+		}else if (likely(via_anchor)){
1678
+			path_anchor=via_anchor;
1679
+		}else if (likely(msg->via1)){
1680
+			path_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, 
1681
+									HDR_ROUTE_T);
1682
+		}else{
1683
+			/* if no via1 (theoretically possible for non-sip messages,
1684
+			   e.g. http xmlrpc) */
1685
+			path_anchor=anchor_lump(msg, msg->headers->name.s-buf, 0, 
1686
+									HDR_ROUTE_T);
1687
+		}
1688
+		if (unlikely(path_anchor==0))
1689
+			goto error05;
1690
+		if (unlikely((path_lump=insert_new_lump_after(path_anchor, path_buf.s,
1691
+														path_buf.len,
1692
+														HDR_ROUTE_T))==0))
1693
+			goto error05;
1694
+	}
1656 1695
 	/* compute new msg len and fix overlapping zones*/
1657 1696
 	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info)+via_len;
1658 1697
 #ifdef XL_DEBUG
... ...
@@ -1704,8 +1761,6 @@ after_update_via1:
1704 1704
 	/* try to add it before msg. 1st via */
1705 1705
 	/* add first via, as an anchor for second via*/
1706 1706
 	if(likely(line_buf)) {
1707
-		via_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA_T);
1708
-		if (via_anchor==0) goto error04;
1709 1707
 		if ((via_lump=insert_new_lump_before(via_anchor, line_buf, via_len,
1710 1708
 											HDR_VIA_T))==0)
1711 1709
 			goto error04;
... ...
@@ -1767,6 +1822,8 @@ error03:
1767 1767
 	if (rport_buf) pkg_free(rport_buf);
1768 1768
 error04:
1769 1769
 	if (line_buf) pkg_free(line_buf);
1770
+error05:
1771
+	if (path_buf.s) pkg_free(path_buf.s);
1770 1772
 error00:
1771 1773
 	*returned_len=0;
1772 1774
 	return 0;
... ...
@@ -50,7 +50,8 @@
50 50
 
51 51
 #define BUILD_NO_LOCAL_VIA		(1<<0)
52 52
 #define BUILD_NO_VIA1_UPDATE	(1<<1)
53
-#define BUILD_IN_SHM			(1<<2)
53
+#define BUILD_NO_PATH			(1<<2)
54
+#define BUILD_IN_SHM			(1<<7)
54 55
 
55 56
 #include "parser/msg_parser.h"
56 57
 #include "ip_addr.h"
... ...
@@ -1672,7 +1672,7 @@ int select_branch_uri(str* res, select_t* s, struct sip_msg* msg) {
1672 1672
 		char *c;
1673 1673
 		init_branch_iterator();
1674 1674
 		len = 0;
1675
-		while ((c = next_branch(&l, &q, &dst_uri.s, &dst_uri.len, 0))) {
1675
+		while ((c = next_branch(&l, &q, &dst_uri, 0, 0, 0))) {
1676 1676
 
1677 1677
 			if (s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
1678 1678
 				l = dst_uri.len;
... ...
@@ -1696,7 +1696,7 @@ int select_branch_uri(str* res, select_t* s, struct sip_msg* msg) {
1696 1696
 		init_branch_iterator();
1697 1697
 		res->len = 0;
1698 1698
 		n = 0;
1699
-		while ((c = next_branch(&l, &q, &dst_uri.s, &dst_uri.len, 0))) {
1699
+		while ((c = next_branch(&l, &q, &dst_uri, 0, 0, 0))) {
1700 1700
 			if (s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
1701 1701
 				l = dst_uri.len;
1702 1702
 				c = dst_uri.s;
... ...
@@ -1738,7 +1738,7 @@ int select_branch_uri(str* res, select_t* s, struct sip_msg* msg) {
1738 1738
 		if (n < 0 || n >= nr_branches) 
1739 1739
 			return -1;
1740 1740
 		init_branch_iterator();
1741
-		for (; (c = next_branch(&l, &q, &dst_uri.s, &dst_uri.len, 0)) && n; n--);
1741
+		for (; (c = next_branch(&l, &q, &dst_uri, 0, 0, 0)) && n; n--);
1742 1742
 		if (!c) return 1;
1743 1743
 		
1744 1744
 		if (s->params[SEL_POS].v.i & SEL_BRANCH_DST_URI) {
... ...
@@ -527,6 +527,9 @@ struct sip_msg*  sip_msg_shm_clone( struct sip_msg *org_msg, int *sip_msg_len,
527 527
 		memcpy( p , org_msg->dst_uri.s , org_msg->dst_uri.len);
528 528
 		p += ROUND4(org_msg->dst_uri.len);
529 529
 	}
530
+	/* path_vec is not cloned (it's reset instead) */
531
+	new_msg->path_vec.s=0;
532
+	new_msg->path_vec.len=0;
530 533
 	/* message buffers(org and scratch pad) */
531 534
 	memcpy( p , org_msg->buf, org_msg->len);
532 535
 	/* ZT to be safer */