Module: sip-router Branch: andrei/path Commit: d64d6bb9dd10499b83aa811557beb77714b74c5f URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d64d6bb9...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@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"