Blob Blame History Raw
From: Liviu Chircu <liviu@opensips.org>
Date: Thu, 24 May 2018 18:23:28 +0300
Subject: [PATCH] path: Fix "use_path_received" in double-Path scenarios

Due to the fact that run_rr_callbacks() returns the 2nd Route (Path)
header field value when previously having done protocol switching (thus
having inserted two Path headers), the "use_path_received" feature of
the path module would not work -- it wouldn't set the $du at all.

The reason for this is that add_path_received() appends its ";received="
to inside Path #1 (the outbound path of the registration / the inbound
path of future requests) when doing double-Path recording.

This patch simply moves the ";received=" append operation performed by
add_path_received() into Path #2 (inbound path of registration /
outbound path of future requests), and adapts other code that needs it
(e.g. save("location", "p1v")) to properly be able to fetch it.

Reported by @futsystems

Fixes #1358

(cherry picked from commit 71c7d75f66c8f0dc4ce411fd97d2dc867b39ce8d)

diff --git a/lib/path.c b/lib/path.c
index 9f8d33fdb..e559664e5 100644
--- a/lib/path.c
+++ b/lib/path.c
@@ -55,14 +55,17 @@ static int build_path(struct sip_msg* _m, struct lump* l, struct lump* l2,
 		memcpy(prefix + prefix_len - 1, "@", 1);
 	}
 
-	suffix_len = PATH_LR_PARAM_LEN + (recv ? PATH_RC_PARAM_LEN : 0);
+	suffix_len = PATH_LR_PARAM_LEN +
+		((recv && (!double_path || _inbound == INBOUND)) ?
+			PATH_RC_PARAM_LEN : 0);
+
 	suffix = pkg_malloc(suffix_len);
 	if (!suffix) {
 		LM_ERR("no pkg memory left for suffix\n");
 		goto out1;
 	}
 	memcpy(suffix, PATH_LR_PARAM, PATH_LR_PARAM_LEN);
-	if(recv)
+	if (recv && (!double_path || _inbound == INBOUND))
 		memcpy(suffix+PATH_LR_PARAM_LEN, PATH_RC_PARAM, PATH_RC_PARAM_LEN);
 
 	crlf = pkg_malloc(PATH_CRLF_LEN);
@@ -95,7 +98,7 @@ static int build_path(struct sip_msg* _m, struct lump* l, struct lump* l2,
 	}
 	l2 = insert_new_lump_before(l2, suffix, suffix_len, 0);
 	if (!l) goto out3;
-	if (recv) {
+	if (recv && (!double_path || _inbound == INBOUND)) {
 		/* TODO: agranig: optimize this one! */
 		src_ip = ip_addr2a(&_m->rcv.src_ip);
 		rcv_addr.s = pkg_malloc(4 + IP_ADDR_MAX_STR_SIZE + 7 +
@@ -206,7 +209,7 @@ int prepend_path(struct sip_msg* _m, str *user, int recv, int double_path)
 			LM_ERR("failed to insert conditional lump\n");
 			return -5;
 		}
-		if (build_path(_m, l, l2, user, 0, INBOUND, double_path) < 0) {
+		if (build_path(_m, l, l2, user, recv, INBOUND, double_path) < 0) {
 			LM_ERR("failed to insert inbound Path");
 			return -6;
 		}
diff --git a/lib/reg/path.c b/lib/reg/path.c
index 02cf7f880..336d8787d 100644
--- a/lib/reg/path.c
+++ b/lib/reg/path.c
@@ -87,6 +87,22 @@ int build_path_vector(struct sip_msg *_m, str *path, str *received,
 			param_hooks_t hooks;
 			param_t *params;
 
+			if (parse_params(&(puri.params),CLASS_URI,&hooks,&params)!=0){
+				LM_ERR("failed to parse parameters of first hop\n");
+				goto error;
+			}
+
+			/* we have a double-Path OpenSIPS in front of us - skip 1st Path */
+			if (hooks.uri.r2 && route->next) {
+				if (parse_uri(route->next->nameaddr.uri.s,
+				              route->next->nameaddr.uri.len, &puri) < 0) {
+					LM_ERR("failed to parse the 2nd Path URI\n");
+					goto error;
+				}
+			}
+
+			free_params(params);
+
 			if (parse_params(&(puri.params),CLASS_CONTACT,&hooks,&params)!=0){
 				LM_ERR("failed to parse parameters of first hop\n");
 				goto error;