[sr-dev] git:master: modules/ims_isc: send path header in 3rd-party registration

Jason Penton jason.penton at gmail.com
Wed Nov 19 11:57:20 CET 2014


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

Author: Jason Penton <jason.penton at gmail.com>
Committer: Jason Penton <jason.penton at gmail.com>
Date:   Wed Nov 19 12:56:34 2014 +0200

modules/ims_isc: send path header in 3rd-party registration

---

 modules/ims_isc/checker.c         |    2 +-
 modules/ims_isc/mod.c             |   12 ++++-
 modules/ims_isc/third_party_reg.c |   92 ++++++++++++++++++++++++++++++++++++-
 modules/ims_isc/third_party_reg.h |    5 +-
 4 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/modules/ims_isc/checker.c b/modules/ims_isc/checker.c
index 10e27ff..bbf1b1b 100644
--- a/modules/ims_isc/checker.c
+++ b/modules/ims_isc/checker.c
@@ -397,7 +397,7 @@ isc_match* isc_checker_find(str uri, char direction, int skip,
 	//need to get the urecord
 	if ((ret = isc_ulb.get_impurecord(d, &uri, &p)) != 0) {
 		isc_ulb.unlock_udomain(d, &uri);
-		LM_ERR("Failure getting record");
+		LM_ERR("Failure getting IMPU record for [%.*s] - ISC checker find METHOD: [%.*s]\n", uri.len, uri.s, msg->first_line.u.request.method.len, msg->first_line.u.request.method.s);
 		return 0;
 	};
 
diff --git a/modules/ims_isc/mod.c b/modules/ims_isc/mod.c
index 888af13..a21e8ed 100644
--- a/modules/ims_isc/mod.c
+++ b/modules/ims_isc/mod.c
@@ -401,6 +401,13 @@ done:
     return ret;
 }
 
+void clean_impu_str(str* impu_s) {
+    char *p;
+    
+    if ((p = memchr(impu_s->s, ';', impu_s->len))) {
+	impu_s->len = p - impu_s->s;
+    }
+}
 /**
  * Checks if there is a match on REGISTER.
  * Inserts route headers and set the dst_uri
@@ -436,7 +443,10 @@ int isc_match_filter_reg(struct sip_msg *msg, char *str1, udomain_t* d) {
             else
                 k = 1;
 
-            LM_DBG("Orig User <%.*s> [%d]\n", s.len, s.s, k);
+	    LM_DBG("Orig User before clean: <%.*s> [%d]\n", s.len, s.s, k);
+	    clean_impu_str(&s);
+            LM_DBG("Orig User after clean: <%.*s> [%d]\n", s.len, s.s, k);
+	    
             m = isc_checker_find(s, old_mark.direction, old_mark.skip, msg, k, d);
             while (m) {
                 LM_DBG("REGISTER match found in filter criteria\n");
diff --git a/modules/ims_isc/third_party_reg.c b/modules/ims_isc/third_party_reg.c
index 4b30639..6d4d599 100644
--- a/modules/ims_isc/third_party_reg.c
+++ b/modules/ims_isc/third_party_reg.c
@@ -45,6 +45,66 @@
 
 #include "third_party_reg.h"
 
+/*! \brief
+ * Combines all Path HF bodies into one string.
+ */
+int build_path_vector(struct sip_msg *_m, str *path, str *received)
+{
+	static char buf[MAX_PATH_SIZE];
+	char *p;
+	struct hdr_field *hdr;
+	struct sip_uri puri;
+
+	rr_t *route = 0;
+
+	path->len = 0;
+	path->s = 0;
+	received->s = 0;
+	received->len = 0;
+
+	if(parse_headers(_m, HDR_EOH_F, 0) < 0) {
+		LM_ERR("failed to parse the message\n");
+		goto error;
+	}
+
+	for( hdr=_m->path,p=buf ; hdr ; hdr = next_sibling_hdr(hdr)) {
+		/* check for max. Path length */
+		if( p-buf+hdr->body.len+1 >= MAX_PATH_SIZE) {
+			LM_ERR("Overall Path body exceeds max. length of %d\n",
+					MAX_PATH_SIZE);
+			goto error;
+		}
+		if(p!=buf)
+			*(p++) = ',';
+		memcpy( p, hdr->body.s, hdr->body.len);
+		p +=  hdr->body.len;
+	}
+
+	if (p!=buf) {
+		/* check if next hop is a loose router */
+		if (parse_rr_body( buf, p-buf, &route) < 0) {
+			LM_ERR("failed to parse Path body, no head found\n");
+			goto error;
+		}
+		if (parse_uri(route->nameaddr.uri.s,route->nameaddr.uri.len,&puri)<0){
+			LM_ERR("failed to parse the first Path URI\n");
+			goto error;
+		}
+		if (!puri.lr.s) {
+			LM_ERR("first Path URI is not a loose-router, not supported\n");
+			goto error;
+		}
+		free_rr(&route);
+	}
+
+	path->s = buf;
+	path->len = p-buf;
+	return 0;
+error:
+	if(route) free_rr(&route);
+	return -1;
+}
+
 /**
  * Handle third party registration
  * @param msg - the SIP REGISTER message
@@ -54,6 +114,7 @@
  */
 int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark) {
 	r_third_party_registration r;
+	str path, path_received;
 	int expires = 0;
 	str req_uri = { 0, 0 };
 	str to = { 0, 0 };
@@ -82,6 +143,12 @@ int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark) {
 	pvni = cscf_get_visited_network_id(msg, &hdr);
 	/* Get P-Access-Network-Info header */
 	pani = cscf_get_access_network_info(msg, &hdr);
+	
+	if (build_path_vector(msg, &path, &path_received) < 0) {
+	    LM_ERR("Failed to parse PATH header for third-party reg\n");
+	    return ISC_RETURN_FALSE;
+	}
+	LM_DBG("PATH header in REGISTER is [%.*s]\n", path.len, path.s);
 
 	/* Get P-Charging-Vector header */
 	/* Just forward the charging header received from P-CSCF */
@@ -99,6 +166,7 @@ int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark) {
 		r.pani = pani;
 		r.cv = cv;
 		r.service_info = m->service_info;
+		r.path = path;
 
 		if (expires <= 0)
 			r_send_third_party_reg(&r, 0);
@@ -126,6 +194,15 @@ static str p_access_network_info_e = { "\r\n", 2 };
 
 static str p_charging_vector_s = { "P-Charging-Vector: ", 19 };
 static str p_charging_vector_e = { "\r\n", 2 };
+
+static str path_s = { "Path: ", 6 };
+static str path_e = { "\r\n", 2 };
+
+static str comma = { ",", 1};
+
+static str path_mine_s = { "<", 1};
+static str path_mine_e = { ";lr>", 4};
+
 static str body_s = { "<ims-3gpp version=\"1\"><service-info>", 36 };
 static str body_e = { "</service-info></ims-3gpp>", 26 };
 
@@ -159,6 +236,9 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
 
 	if (r->cv.len)
 		h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len;
+	
+	if (r->path.len) 
+	    h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/;
 
 	h.s = pkg_malloc(h.len);
 	if (!h.s) {
@@ -176,6 +256,16 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
 	sprintf(h.s + h.len, "%d", expires);
 	h.len += strlen(h.s + h.len);
 	STR_APPEND(h, expires_e);
+	
+	if (r->path.len) {
+	    STR_APPEND(h, path_s);
+	    STR_APPEND(h, r->path);
+	    STR_APPEND(h, comma);
+	    STR_APPEND(h, path_mine_s);
+	    STR_APPEND(h, r->from);
+	    STR_APPEND(h, path_mine_e);
+	    STR_APPEND(h, path_e);
+	}
 
 	STR_APPEND(h, contact_s);
 	STR_APPEND(h, isc_my_uri_sip);
@@ -198,7 +288,7 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
 		STR_APPEND(h, r->cv);
 		STR_APPEND(h, p_charging_vector_e);
 	}
-	LM_CRIT("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
+	LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
 	if (r->service_info.len) {
 		b.len = body_s.len + r->service_info.len + body_e.len;
 		b.s = pkg_malloc(b.len);
diff --git a/modules/ims_isc/third_party_reg.h b/modules/ims_isc/third_party_reg.h
index 2b687b0..a23cbce 100644
--- a/modules/ims_isc/third_party_reg.h
+++ b/modules/ims_isc/third_party_reg.h
@@ -65,13 +65,14 @@ extern struct tm_binds isc_tmb; 	/**< Structure with pointers to tm funcs 		*/
 
 /** reg event notification structure */
 typedef struct _r_third_party_reg {
-	str req_uri; 		/* AS sip uri:  	*/
+	str req_uri;                    /* AS sip uri:  	*/
 	str from; 			/* SCSCF uri            */
 	str to; 			/* Public user id       */
 	str pvni; 			/* Visited network id 	*/
 	str pani; 			/* Access Network info 	*/
 	str cv; 			/* Charging vector 	*/
-	str service_info; 	/* Service info body */
+	str service_info;               /* Service info body */
+    str path;                       /* Path header  */
 } r_third_party_registration;
 
 int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark);




More information about the sr-dev mailing list