Module: sip-router Branch: master Commit: ea6a8ec6a9c5dd0888f9260f5189c186430bc484 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ea6a8ec6...
Author: Jason Penton jason.penton@gmail.com Committer: Jason Penton jason.penton@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);