Module: sip-router Branch: master Commit: 2e466866468a71d4a6e7589cae69ae606b194716 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2e466866...
Author: Jason Penton jason.penton@smilecoms.com Committer: Jason Penton jason.penton@smilecoms.com Date: Wed Jun 5 08:46:13 2013 +0200
modules/ims_isc: Add support for P-Serverd-User header - This header allows a triggered Application Server to know the IMS user for who it was triggered, and in what state (originating/terminating, registered/unregistered) - Thanks to Camille Oudot for patch!
---
modules/ims_isc/doc/ims_isc_admin.xml | 20 +++++++++ modules/ims_isc/mark.c | 70 +++++++++++++++++++++++++++++++++ modules/ims_isc/mark.h | 1 + modules/ims_isc/mod.c | 2 + 4 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/modules/ims_isc/doc/ims_isc_admin.xml b/modules/ims_isc/doc/ims_isc_admin.xml index adc6f5e..33dac0a 100644 --- a/modules/ims_isc/doc/ims_isc_admin.xml +++ b/modules/ims_isc/doc/ims_isc_admin.xml @@ -126,6 +126,26 @@ modparam("ims_isc", "isc_fr_inv_timeout", 20000) </programlisting> </example> </section> + + <section> + <title><varname>add_p_served_user</varname> (integer)</title> + + <para>This boolean indicates if a P-Served-User should be added on the ISC + interface, according to RFC 5502.</para> + + <para><emphasis> Default value is 0 (false)</emphasis></para> + + <example> + <title><varname>add_p_served_user</varname> parameter usage</title> + + <programlisting format="linespecific"> +... +modparam("ims_isc", "add_p_served_user", 1) +# p-served user header will be enabled +... + </programlisting> + </example> + </section> </section>
<section> diff --git a/modules/ims_isc/mark.c b/modules/ims_isc/mark.c index a1a73e4..c879604 100644 --- a/modules/ims_isc/mark.c +++ b/modules/ims_isc/mark.c @@ -44,6 +44,16 @@ */
#include "mark.h" +#include "../../str.h" +#include "../../data_lump.h" + +const str psu_hdr_s = str_init("P-Served-User: <%.*s>;sescase=%.*s;regstate=%.*s\r\n"); +const str sescase_orig = str_init("orig"); +const str sescase_term = str_init("term"); +const str regstate_reg = str_init("reg"); +const str regstate_unreg = str_init("unreg"); + +extern int add_p_served_user;
/** base16 char constants */ char *hexchars = "0123456789abcdef"; @@ -243,6 +253,9 @@ int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark) { if (match) as = match->server_name; isc_mark_write_route(msg, &as, &route); + if (add_p_served_user) { + isc_mark_write_psu(msg, mark); + } LM_DBG("isc_mark_set: NEW mark <%s>\n", chr_mark);
return 1; @@ -291,3 +304,60 @@ inline int isc_mark_write_route(struct sip_msg *msg, str *as, str *iscmark) { return 1; }
+/** + * Inserts the P-Served-User header on a SIP message + * as specified in RFC 5502 + * @param msg - SIP message + * @param mark - the mark containing all required information + * @returns 1 on success, else 0 + */ +int isc_mark_write_psu(struct sip_msg *msg, isc_mark *mark) { + struct lump *l = msg->add_rm; + int hlen; + char * hstr = NULL; + const str *regstate, *sescase; + + switch(mark->direction) { + case IFC_ORIGINATING_SESSION: + regstate = ®state_reg; + sescase = &sescase_orig; + break; + case IFC_TERMINATING_SESSION: + regstate = ®state_reg; + sescase = &sescase_term; + break; + case IFC_TERMINATING_UNREGISTERED: + regstate = ®state_unreg; + sescase = &sescase_term; + break; + default: + LM_ERR("isc_mark_write_psu: unknown direction: %d\n", mark->direction); + return 0; + } + + hlen = psu_hdr_s.len - /* 3 "%.*s" */ 12 + mark->aor.len + regstate->len + sescase->len + 1; + hstr = pkg_malloc(hlen); + if (hstr == NULL) { + LM_ERR("isc_mark_write_psu: could not allocate %d bytes\n", hlen); + return 0; + } + + int ret = snprintf(hstr, hlen, psu_hdr_s.s, + mark->aor.len, mark->aor.s, + sescase->len, sescase->s, + regstate->len, regstate->s); + if (ret >= hlen) { + LM_ERR("isc_mark_write_psu: invalid string buffer size: %d, required: %d\n", hlen, ret); + pkg_free(hstr); + return 0; + } + + LM_DBG("isc_mark_write_psu: %.*s\n", hlen - 3 /* don't print \r\n\0 */, hstr); + if (append_new_lump(&l, hstr, hlen - 1, HDR_OTHER_T) == 0) { + LM_ERR("isc_mark_write_psu: append_new_lump(%p, "%.*s\\r\n", %d, 0) failed\n", &l, hlen - 3 /* don't print \r\n\0 */, hstr, hlen - 1); + pkg_free(hstr); + return 0; + } + /* hstr will be deallocated when msg will be destroyed */ + return 1; +} diff --git a/modules/ims_isc/mark.h b/modules/ims_isc/mark.h index e6912f3..9121eaa 100644 --- a/modules/ims_isc/mark.h +++ b/modules/ims_isc/mark.h @@ -76,6 +76,7 @@ int base16_to_bin(char *from,int len, char *to); inline int isc_mark_drop_route(struct sip_msg *msg); int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark); inline int isc_mark_write_route(struct sip_msg *msg,str *as,str *iscmark); +int isc_mark_write_psu(struct sip_msg *msg, isc_mark *mark); int bin_to_base16(char *from,int len, char *to);
#endif diff --git a/modules/ims_isc/mod.c b/modules/ims_isc/mod.c index 3b69bbd..5c54453 100644 --- a/modules/ims_isc/mod.c +++ b/modules/ims_isc/mod.c @@ -62,6 +62,7 @@ str isc_my_uri_sip = {0, 0}; /**< Uri of myself to loop the message in str with int isc_expires_grace = 120; /**< expires value to add to the expires in the 3rd party register*/ int isc_fr_timeout = 5000; /**< default ISC response timeout in ms */ int isc_fr_inv_timeout = 20000; /**< default ISC invite response timeout in ms */ +int add_p_served_user = 0; /**< should the P-Served-User header be inserted? */
/** module functions */ static int mod_init(void); @@ -92,6 +93,7 @@ static param_export_t params[] = { consider it dead. Has to be lower than SIP transaction timeout to prevent downstream timeouts. Not too small though because AS are usually slow as hell... */ + { "add_p_served_user", INT_PARAM, &add_p_served_user}, /**< boolean indicating if the P-Served-User (RFC5502) should be added on the ISC interface or not */ { 0, 0, 0} };