[sr-dev] git:andrei/path: core: path support when forwarding

Andrei Pelinescu-Onciul andrei at iptel.org
Tue Sep 8 19:26:19 CEST 2009


Module: sip-router
Branch: andrei/path
Commit: d64d6bb9dd10499b83aa811557beb77714b74c5f
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d64d6bb9dd10499b83aa811557beb77714b74c5f

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Tue Sep  8 19:21:49 2009 +0200

core: path support when forwarding

Path support compatible with kamailio (although there might be
differences in the added Route header position).

---

 msg_translator.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 msg_translator.h |    3 +-
 2 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/msg_translator.c b/msg_translator.c
index e486579..42c1cf1 100644
--- a/msg_translator.c
+++ b/msg_translator.c
@@ -1495,7 +1495,9 @@ error:
 /** builds a request in memory from another sip request.
   *
   * Side-effects: - it adds lumps to the msg which are _not_ cleaned.
-  * All the added lumps are HDR_VIA_T.
+  * The added lumps are HDR_VIA_T (almost always added), HDR_CONTENLENGTH_T
+  * and HDR_ROUTE_T (when a Route: header is added as a result of a non-null
+  * msg->path_vec).
   *               - it might change send_info->proto and send_info->send_socket
   *                 if proto fallback is enabled (see below).
   *
@@ -1516,8 +1518,16 @@ error:
   *                       message > mtu and send_info->proto==PROTO_UDP. 
   *                       It will also update send_info->proto.
   *                     - FL_FORCE_RPORT: add rport to via
+  * @param mode - flags for building the message, can be a combination of:
+  *                 * BUILD_NO_LOCAL_VIA - don't add a local via
+  *                 * BUILD_NO_VIA1_UPDATE - don't update first via (rport,
+  *                    received a.s.o)
+  *                 * BUILD_NO_PATH - don't add a Route: header with the 
+  *                   msg->path_vec content.
+  *                 * BUILD_IN_SHM - build the result in shm memory
   *
-  * @return pointer to the new request (pkg_malloc'ed, needs freeing when
+  * @return pointer to the new request (pkg_malloc'ed or shm_malloc'ed,
+  * depending on the presence of the BUILD_IN_SHM flag, needs freeing when
   *   done) and sets returned_len or 0 on error.
   */
 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,
 	char* rport_buf;
 	char* new_buf;
 	char* buf;
+	str path_buf;
 	unsigned int offset, s_offset, size;
 	struct lump* via_anchor;
 	struct lump* via_lump;
 	struct lump* via_insert_param;
+	struct lump* path_anchor;
+	struct lump* path_lump;
 	str branch;
 	unsigned int flags;
 	unsigned int udp_mtu;
@@ -1552,6 +1565,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 	rport_buf=0;
 	line_buf=0;
 	via_len=0;
+	path_buf.s=0;
+	path_buf.len=0;
 
 	flags=msg->msg_flags|global_req_flags;
 	/* Calculate message body difference and adjust Content-Length */
@@ -1653,6 +1668,42 @@ after_local_via:
 	}
 
 after_update_via1:
+	/* add route with path content */
+	if(unlikely(!(mode&BUILD_NO_PATH) && msg->path_vec.s &&
+					msg->path_vec.len)){
+		path_buf.len=ROUTE_PREFIX_LEN+msg->path_vec.len+CRLF_LEN;
+		path_buf.s=pkg_malloc(path_buf.len+1);
+		if (unlikely(path_buf.s==0)){
+			LOG(L_ERR, "out of memory\n");
+			ser_error=E_OUT_OF_MEM;
+			goto error00;
+		}
+		memcpy(path_buf.s, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN, msg->path_vec.s,
+					msg->path_vec.len);
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN+msg->path_vec.len, CRLF, CRLF_LEN);
+		path_buf.s[path_buf.len]=0;
+		/* insert Route header either before the other routes
+		   (if present & parsed) or after the local via */
+		if (msg->route){
+			path_anchor=anchor_lump(msg, msg->route->name.s-buf, 0, 
+									HDR_ROUTE_T);
+		}else if (likely(msg->via1)){
+			path_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, 
+									HDR_ROUTE_T);
+		}else{
+			/* if no via1 (theoretically possible for non-sip messages,
+			   e.g. http xmlrpc) */
+			path_anchor=anchor_lump(msg, msg->headers->name.s-buf, 0, 
+									HDR_ROUTE_T);
+		}
+		if (unlikely(path_anchor==0))
+			goto error05;
+		if (unlikely((path_lump=insert_new_lump_after(path_anchor, path_buf.s,
+														path_buf.len,
+														HDR_ROUTE_T))==0))
+			goto error05;
+	}
 	/* compute new msg len and fix overlapping zones*/
 	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info)+via_len;
 #ifdef XL_DEBUG
@@ -1767,6 +1818,8 @@ error03:
 	if (rport_buf) pkg_free(rport_buf);
 error04:
 	if (line_buf) pkg_free(line_buf);
+error05:
+	if (path_buf.s) pkg_free(path_buf.s);
 error00:
 	*returned_len=0;
 	return 0;
diff --git a/msg_translator.h b/msg_translator.h
index 95758df..d381f18 100644
--- a/msg_translator.h
+++ b/msg_translator.h
@@ -50,7 +50,8 @@
 
 #define BUILD_NO_LOCAL_VIA		(1<<0)
 #define BUILD_NO_VIA1_UPDATE	(1<<1)
-#define BUILD_IN_SHM			(1<<2)
+#define BUILD_NO_PATH			(1<<2)
+#define BUILD_IN_SHM			(1<<7)
 
 #include "parser/msg_parser.h"
 #include "ip_addr.h"




More information about the sr-dev mailing list