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 1518
   *                       message > mtu and send_info->proto==PROTO_UDP. 
1517 1519
   *                       It will also update send_info->proto.
1518 1520
   *                     - FL_FORCE_RPORT: add rport to via
1521
+  * @param mode - flags for building the message, can be a combination of:
1522
+  *                 * BUILD_NO_LOCAL_VIA - don't add a local via
1523
+  *                 * BUILD_NO_VIA1_UPDATE - don't update first via (rport,
1524
+  *                    received a.s.o)
1525
+  *                 * BUILD_NO_PATH - don't add a Route: header with the 
1526
+  *                   msg->path_vec content.
1527
+  *                 * BUILD_IN_SHM - build the result in shm memory
1519 1528
   *
1520
-  * @return pointer to the new request (pkg_malloc'ed, needs freeing when
1529
+  * @return pointer to the new request (pkg_malloc'ed or shm_malloc'ed,
1530
+  * depending on the presence of the BUILD_IN_SHM flag, needs freeing when
1521 1531
   *   done) and sets returned_len or 0 on error.
1522 1532
   */
1523 1533
 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 1542
 	char* rport_buf;
1533 1543
 	char* new_buf;
1534 1544
 	char* buf;
1545
+	str path_buf;
1535 1546
 	unsigned int offset, s_offset, size;
1536 1547
 	struct lump* via_anchor;
1537 1548
 	struct lump* via_lump;
1538 1549
 	struct lump* via_insert_param;
1550
+	struct lump* path_anchor;
1551
+	struct lump* path_lump;
1539 1552
 	str branch;
1540 1553
 	unsigned int flags;
1541 1554
 	unsigned int udp_mtu;
... ...
@@ -1552,6 +1565,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
1552 1565
 	rport_buf=0;
1553 1566
 	line_buf=0;
1554 1567
 	via_len=0;
1568
+	path_buf.s=0;
1569
+	path_buf.len=0;
1555 1570
 
1556 1571
 	flags=msg->msg_flags|global_req_flags;
1557 1572
 	/* Calculate message body difference and adjust Content-Length */
... ...
@@ -1653,6 +1668,42 @@ after_local_via:
1653 1668
 	}
1654 1669
 
1655 1670
 after_update_via1:
1671
+	/* add route with path content */
1672
+	if(unlikely(!(mode&BUILD_NO_PATH) && msg->path_vec.s &&
1673
+					msg->path_vec.len)){
1674
+		path_buf.len=ROUTE_PREFIX_LEN+msg->path_vec.len+CRLF_LEN;
1675
+		path_buf.s=pkg_malloc(path_buf.len+1);
1676
+		if (unlikely(path_buf.s==0)){
1677
+			LOG(L_ERR, "out of memory\n");
1678
+			ser_error=E_OUT_OF_MEM;
1679
+			goto error00;
1680
+		}
1681
+		memcpy(path_buf.s, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
1682
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN, msg->path_vec.s,
1683
+					msg->path_vec.len);
1684
+		memcpy(path_buf.s+ROUTE_PREFIX_LEN+msg->path_vec.len, CRLF, CRLF_LEN);
1685
+		path_buf.s[path_buf.len]=0;
1686
+		/* insert Route header either before the other routes
1687
+		   (if present & parsed) or after the local via */
1688
+		if (msg->route){
1689
+			path_anchor=anchor_lump(msg, msg->route->name.s-buf, 0, 
1690
+									HDR_ROUTE_T);
1691
+		}else if (likely(msg->via1)){
1692
+			path_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, 
1693
+									HDR_ROUTE_T);
1694
+		}else{
1695
+			/* if no via1 (theoretically possible for non-sip messages,
1696
+			   e.g. http xmlrpc) */
1697
+			path_anchor=anchor_lump(msg, msg->headers->name.s-buf, 0, 
1698
+									HDR_ROUTE_T);
1699
+		}
1700
+		if (unlikely(path_anchor==0))
1701
+			goto error05;
1702
+		if (unlikely((path_lump=insert_new_lump_after(path_anchor, path_buf.s,
1703
+														path_buf.len,
1704
+														HDR_ROUTE_T))==0))
1705
+			goto error05;
1706
+	}
1656 1707
 	/* compute new msg len and fix overlapping zones*/
1657 1708
 	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info)+via_len;
1658 1709
 #ifdef XL_DEBUG
... ...
@@ -1767,6 +1818,8 @@ error03:
1767 1818
 	if (rport_buf) pkg_free(rport_buf);
1768 1819
 error04:
1769 1820
 	if (line_buf) pkg_free(line_buf);
1821
+error05:
1822
+	if (path_buf.s) pkg_free(path_buf.s);
1770 1823
 error00:
1771 1824
 	*returned_len=0;
1772 1825
 	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"