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