Browse code

core: path support when forwarding

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

Andrei Pelinescu-Onciul authored on 08/09/2009 17:21:49
Showing 2 changed files
... ...
@@ -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;
... ...
@@ -1552,6 +1565,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1552 1552
 	rport_buf=0;
1553 1553
 	line_buf=0;
1554 1554
 	via_len=0;
1555
+	path_buf.s=0;
1556
+	path_buf.len=0;
1555 1557
 
1556 1558
 	flags=msg->msg_flags|global_req_flags;
1557 1559
 	/* Calculate message body difference and adjust Content-Length */
... ...
@@ -1653,6 +1668,42 @@ 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) or after the local via */
1673
+		if (msg->route){
1674
+			path_anchor=anchor_lump(msg, msg->route->name.s-buf, 0, 
1675
+									HDR_ROUTE_T);
1676
+		}else if (likely(msg->via1)){
1677
+			path_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, 
1678
+									HDR_ROUTE_T);
1679
+		}else{
1680
+			/* if no via1 (theoretically possible for non-sip messages,
1681
+			   e.g. http xmlrpc) */
1682
+			path_anchor=anchor_lump(msg, msg->headers->name.s-buf, 0, 
1683
+									HDR_ROUTE_T);
1684
+		}
1685
+		if (unlikely(path_anchor==0))
1686
+			goto error05;
1687
+		if (unlikely((path_lump=insert_new_lump_after(path_anchor, path_buf.s,
1688
+														path_buf.len,
1689
+														HDR_ROUTE_T))==0))
1690
+			goto error05;
1691
+	}
1656 1692
 	/* compute new msg len and fix overlapping zones*/
1657 1693
 	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info)+via_len;
1658 1694
 #ifdef XL_DEBUG
... ...
@@ -1767,6 +1818,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"