Skip to content

Commit

Permalink
ims_isc: add-on for third-party registration
Browse files Browse the repository at this point in the history
- The feature is a add-on to third party registration in S-CSCF
- The feature assumes two new flags in HSS database, where additional to the
  "Service Info XML" an "insertRegisterRequest" flag or an "insertRegisterRepsonse"
  flag can be set. These flags are sent with the SAR/SAA exchange to the S-CSCF,
  where the new feature does a prioritization:
  If Service Info present -> add service info to body of 3rd Party REGISTER Request
  else if insertRegisterRequest -> add original REGISTER request to body of
    3rd Party REGISTER request
  else if insertRegisterResponse -> add original REGISTER response to body of
    3rd Party REGISTER request
  else -> add no body to 3rd Party REGISTER request.
- Multipart Body is not supported.
- More info about the insertRegisterRequest and insertRegisterResponse flags
  can be found in applicable 3GPP standards.
  • Loading branch information
Christoph Valentin authored and henningw committed Apr 9, 2019
1 parent 7a97761 commit 99b2cfa
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/modules/ims_isc/checker.c
Expand Up @@ -393,6 +393,8 @@ static inline isc_match* isc_new_match(ims_filter_criteria *fc, int index) {
fc->application_server.service_info.len);
}
r->index = index;
r->include_register_request = fc->application_server.include_register_request;
r->include_register_response = fc->application_server.include_register_response;
return r;
}

Expand Down
2 changes: 2 additions & 0 deletions src/modules/ims_isc/checker.h
Expand Up @@ -68,6 +68,8 @@ typedef struct {
char default_handling; /**< handling to apply on failure to contact the AS */
str service_info; /**< additional service information */
int index; /**< index of the matching IFC */
int include_register_request; /**< additional flag from the HSS */
int include_register_response; /**< additional flag from the HSS */
} isc_match;


Expand Down
8 changes: 8 additions & 0 deletions src/modules/ims_isc/doc/ims_isc_admin.xml
Expand Up @@ -163,6 +163,14 @@ modparam("ims_isc", "add_p_served_user", 1)
<para>A positive return code (1) means that the REGISTER message has
matched to Initial Filter Criteria and is armed for routing.</para>

<para>This function handles also the Service Info (if sent by the
HSS), the InsertRegisterRequest flag (if sent by the HSS) or the
InsertRegisterResponse flag (if sent by the HSS). Either the Service
Info OR the original REGISTER request OR the original REGISTER
response is added to the body of the REGISTER message, before it is
forwarded to the relevant Application Server. Multipart body is not
supported in this case.</para>

<para>Meaning of the parameters is as follows:</para>

<itemizedlist>
Expand Down
106 changes: 91 additions & 15 deletions src/modules/ims_isc/third_party_reg.c
Expand Up @@ -44,6 +44,7 @@
*/

#include "third_party_reg.h"
#include "../../core/msg_translator.h"

usrloc_api_t isc_ulb;/*!< Structure containing pointers to usrloc functions*/

Expand Down Expand Up @@ -204,7 +205,7 @@ int build_p_associated_uri(ims_subscription* s) {
return 0;
}


static str reg_resp_200OK = {"OK", 2};

/**
* Handle third party registration
Expand Down Expand Up @@ -286,7 +287,24 @@ int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udoma
r.pvni = pvni;
r.pani = pani;
r.cv = cv;
r.service_info = m->service_info;
if (m->service_info.s && m->service_info.len) {
r.body.content_type = CT_SERVICE_INFO;
r.body.content = m->service_info;
} else if (m->include_register_request) {
r.body.content_type = CT_REGISTER_REQ;
r.body.content.s = msg->first_line.u.request.method.s;
r.body.content.len = msg->len;
} else if (m->include_register_response) {
struct bookmark dummy_bm;
r.body.content_type = CT_REGISTER_RESP;
r.body.content.s = build_res_buf_from_sip_req(200, &reg_resp_200OK, 0, msg, (unsigned int*)&r.body.content.len, &dummy_bm);
if (!r.body.content.s) {
LM_DBG("response building failed for body of third party register request");
r.body.content_type = CT_NONE;
}
} else {
r.body.content_type = CT_NONE;
}
r.path = path;

if (expires <= 0)
Expand Down Expand Up @@ -324,6 +342,13 @@ static str comma = {",", 1};
static str path_mine_s = {"<", 1};
static str path_mine_e = {";lr>", 4};

static str content_type_s = {"Content-Type: ", 14};
static str content_type_e = {"\r\n", 2};

static str ct_service_info = {"application/3gpp-ims+xml", 24};
static str ct_register_req = {"message/sip", 11};
static str ct_register_resp = {"message/sip", 11};

static str body_s = {"<ims-3gpp version=\"1\"><service-info>", 36};
static str body_e = {"</service-info></ims-3gpp>", 26};

Expand Down Expand Up @@ -371,6 +396,20 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
h.len += pauri.len;
}

if (r->body.content_type == CT_SERVICE_INFO) {
h.len += content_type_s.len;
h.len += ct_service_info.len;
h.len += content_type_e.len;
} else if (r->body.content_type == CT_REGISTER_REQ) {
h.len += content_type_s.len;
h.len += ct_register_req.len;
h.len += content_type_e.len;
} else if (r->body.content_type == CT_REGISTER_RESP) {
h.len += content_type_s.len;
h.len += ct_register_resp.len;
h.len += content_type_e.len;
}

h.s = pkg_malloc(h.len);
if (!h.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
Expand Down Expand Up @@ -423,20 +462,53 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
if (p_associated_uri.data_len > 0) {
STR_APPEND(h, pauri);
}
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);
if (!b.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
b.len = 0;
return 0;
LM_DBG("BODY TYPE(3rd PARTY REGISTER):<%d>\n", r->body.content_type);
if (r->body.content_type != CT_NONE) {
if (r->body.content_type == CT_SERVICE_INFO) {
LM_ERR("BODY (3rd PARTY REGISTER) \"SI\": <%.*s>\n", r->body.content.len, r->body.content.s);
b.len = body_s.len + r->body.content.len + body_e.len;
b.s = pkg_malloc(b.len);
if (!b.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
b.len = 0;
goto error;
}
b.len = 0;
STR_APPEND(b, body_s);
STR_APPEND(b, r->body.content);
STR_APPEND(b, body_e);
STR_APPEND(h, content_type_s);
STR_APPEND(h, ct_service_info);
STR_APPEND(h, content_type_e);
} else if (r->body.content_type == CT_REGISTER_REQ) {
LM_ERR("BODY (3rd PARTY REGISTER) \"REQ\": <%.*s>\n", r->body.content.len, r->body.content.s);
b.len = r->body.content.len;
b.s = pkg_malloc(b.len);
if (!b.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
b.len = 0;
goto error;
}
b.len = 0;
STR_APPEND(b, r->body.content);
STR_APPEND(h, content_type_s);
STR_APPEND(h, ct_register_req);
STR_APPEND(h, content_type_e);
} else if (r->body.content_type == CT_REGISTER_RESP) {
LM_ERR("BODY (3rd PARTY REGISTER) \"RESP\": <%.*s>\n", r->body.content.len, r->body.content.s);
b.len = r->body.content.len;
b.s = pkg_malloc(b.len);
if (!b.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
b.len = 0;
goto error;
}
b.len = 0;
STR_APPEND(b, r->body.content);
STR_APPEND(h, content_type_s);
STR_APPEND(h, ct_register_resp);
STR_APPEND(h, content_type_e);
}

b.len = 0;
STR_APPEND(b, body_s);
STR_APPEND(b, r->service_info);
STR_APPEND(b, body_e);
}

set_uac_req(&req, &method, &h, &b, 0,
Expand All @@ -450,13 +522,17 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
pkg_free(h.s);
if (b.s)
pkg_free(b.s);
if (r->body.content_type == CT_REGISTER_RESP)
pkg_free(r->body.content.s);
return 1;

error:
if (h.s)
pkg_free(h.s);
if (b.s)
pkg_free(b.s);
if (r->body.content_type == CT_REGISTER_RESP)
pkg_free(r->body.content.s);
return 0;
}

Expand Down
18 changes: 16 additions & 2 deletions src/modules/ims_isc/third_party_reg.h
Expand Up @@ -63,6 +63,20 @@ extern int isc_expires_grace; /**< expires value to add to the expires in the
to prevent expiration in AS */
extern struct tm_binds isc_tmb; /**< Structure with pointers to tm funcs */


#define CT_NONE 0
#define CT_SERVICE_INFO 1
#define CT_REGISTER_REQ 2
#define CT_REGISTER_RESP 3

/** one (part of a) body for the reg event notification structure */
/** Currently we restrict the usage of multipart bodies */
typedef struct body {
char content_type; /* Content-Type header for (one part of the) body*/
str content; /* Content of (one part of the) body */
} body_t;


/** reg event notification structure */
typedef struct _r_third_party_reg {
str req_uri; /* AS sip uri: */
Expand All @@ -71,8 +85,8 @@ typedef struct _r_third_party_reg {
str pvni; /* Visited network id */
str pani; /* Access Network info */
str cv; /* Charging vector */
str service_info; /* Service info body */
str path; /* Path header */
body_t body; /* The body */
str path; /* Path header */
} r_third_party_registration;

int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udomain_t* d);
Expand Down

0 comments on commit 99b2cfa

Please sign in to comment.