From ac8152d4543d8b4346f567db304c5791bae9964c Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:27 +0100 Subject: [PATCH 1/9] core/dset: Cleanup printing the dset Eliminate duplicate code --- src/core/dset.c | 138 ++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 68 deletions(-) diff --git a/src/core/dset.c b/src/core/dset.c index a534366bf6e..5af62525945 100644 --- a/src/core/dset.c +++ b/src/core/dset.c @@ -46,7 +46,7 @@ #define CONTACT_DELIM ", " #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1) -#define Q_PARAM ">;q=" +#define Q_PARAM ";q=" #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1) @@ -465,109 +465,111 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path, return 1; } +/*! \brief + * Combines the given elements into a Contact header field + * dest = target buffer, will be updated to new position after the printed contact + * uri, q = contact elements + * end = end of target buffer + * Returns 0 on success or -1 on error (buffer is too short) + */ +static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end) +{ + char *p = *dest; + str buf; + + /* uri */ + if (p + uri->len + 2 > end) { + return -1; + } + *p++ = '<'; + memcpy(p, uri->s, uri->len); + p += uri->len; + *p++ = '>'; + + /* header parameters */ + /* q value */ + if (q != Q_UNSPECIFIED) { + buf.s = q2str(q, (unsigned int*)&buf.len); + if (p + Q_PARAM_LEN + buf.len > end) { + return -1; + } + memcpy(p, Q_PARAM, Q_PARAM_LEN); + p += Q_PARAM_LEN; + memcpy(p, buf.s, buf.len); + p += buf.len; + } + *dest = p; + return 0; +} + /* * Create a Contact header field from the dset * array */ -char* print_dset(struct sip_msg* msg, int* len) +char* print_dset(struct sip_msg* msg, int* len) { - int cnt, i; - unsigned int qlen; + int cnt = 0; qvalue_t q; str uri; - char* p, *qbuf; + char *p; int crt_branch; static char dset[MAX_REDIRECTION_LEN]; - - if (msg->new_uri.s) { - cnt = 1; - *len = msg->new_uri.len + 1 /*'<'*/; - if (ruri_q != Q_UNSPECIFIED) { - *len += Q_PARAM_LEN + len_q(ruri_q); - } else { - *len += 1 /*'>'*/; - } - } else { - cnt = 0; - *len = 0; - } + char *end = dset + MAX_REDIRECTION_LEN; /* backup current branch index to restore it later */ crt_branch = get_branch_iterator(); - init_branch_iterator(); - while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) { - cnt++; - *len += uri.len + 1 /*'<'*/; - if (q != Q_UNSPECIFIED) { - *len += Q_PARAM_LEN + len_q(q); - } else { - *len += 1 /*'>'*/; - } - } - - if (cnt == 0) return 0; - - *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN; - - if (*len + 1 > MAX_REDIRECTION_LEN) { - LM_ERR("redirection buffer length exceed\n"); - goto error; + /* contact header name */ + if (CONTACT_LEN + CRLF_LEN + 1 > MAX_REDIRECTION_LEN) { + goto memfail; } - memcpy(dset, CONTACT, CONTACT_LEN); p = dset + CONTACT_LEN; - if (msg->new_uri.s) { - *p++ = '<'; - - memcpy(p, msg->new_uri.s, msg->new_uri.len); - p += msg->new_uri.len; - if (ruri_q != Q_UNSPECIFIED) { - memcpy(p, Q_PARAM, Q_PARAM_LEN); - p += Q_PARAM_LEN; - - qbuf = q2str(ruri_q, &qlen); - memcpy(p, qbuf, qlen); - p += qlen; - } else { - *p++ = '>'; + /* current uri */ + if (msg->new_uri.s) { + if (print_contact_str(&p, &msg->new_uri, ruri_q, end) < 0) { + goto memfail; } - i = 1; - } else { - i = 0; + cnt++; } + /* branches */ init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) { - if (i) { + if (cnt > 0) { + if (p + CONTACT_DELIM_LEN > end) { + goto memfail; + } memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN); p += CONTACT_DELIM_LEN; } - *p++ = '<'; + if (print_contact_str(&p, &uri, q, end) < 0) { + goto memfail; + } - memcpy(p, uri.s, uri.len); - p += uri.len; - if (q != Q_UNSPECIFIED) { - memcpy(p, Q_PARAM, Q_PARAM_LEN); - p += Q_PARAM_LEN; + cnt++; + } - qbuf = q2str(q, &qlen); - memcpy(p, qbuf, qlen); - p += qlen; - } else { - *p++ = '>'; - } - i++; + if (cnt == 0) { + LM_WARN("no r-uri or branches\n"); + goto error; } + if (p + CRLF_LEN + 1 > end) { + goto memfail; + } memcpy(p, CRLF " ", CRLF_LEN + 1); + *len = p - dset + CRLF_LEN; set_branch_iterator(crt_branch); return dset; +memfail: + LM_ERR("redirection buffer length exceed\n"); error: + *len = 0; set_branch_iterator(crt_branch); return 0; } From 4dc75f83c21554a58ae253a8b958eba80b3503ed Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:28 +0100 Subject: [PATCH 2/9] core/dset: Add options field to print_dset() Will be used later on to optionally enhance the contacts. --- src/core/dset.c | 8 ++++---- src/core/dset.h | 2 +- src/modules/pv/pv_core.c | 2 +- src/modules/sl/sl_funcs.c | 2 +- src/modules/tm/t_reply.c | 2 +- src/modules/xprint/xp_lib.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/dset.c b/src/core/dset.c index 5af62525945..239a4f2ebce 100644 --- a/src/core/dset.c +++ b/src/core/dset.c @@ -472,7 +472,7 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path, * end = end of target buffer * Returns 0 on success or -1 on error (buffer is too short) */ -static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end) +static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end, int options) { char *p = *dest; str buf; @@ -507,7 +507,7 @@ static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end) * Create a Contact header field from the dset * array */ -char* print_dset(struct sip_msg* msg, int* len) +char* print_dset(struct sip_msg* msg, int* len, int options) { int cnt = 0; qvalue_t q; @@ -529,7 +529,7 @@ char* print_dset(struct sip_msg* msg, int* len) /* current uri */ if (msg->new_uri.s) { - if (print_contact_str(&p, &msg->new_uri, ruri_q, end) < 0) { + if (print_contact_str(&p, &msg->new_uri, ruri_q, end, options) < 0) { goto memfail; } cnt++; @@ -546,7 +546,7 @@ char* print_dset(struct sip_msg* msg, int* len) p += CONTACT_DELIM_LEN; } - if (print_contact_str(&p, &uri, q, end) < 0) { + if (print_contact_str(&p, &uri, q, end, options) < 0) { goto memfail; } diff --git a/src/core/dset.h b/src/core/dset.h index 603b2023d19..b786cee0530 100644 --- a/src/core/dset.h +++ b/src/core/dset.h @@ -158,7 +158,7 @@ void clear_branches(void); * Create a Contact header field from the * list of current branches */ -char* print_dset(struct sip_msg* msg, int* len); +char* print_dset(struct sip_msg* msg, int* len, int options); /*! \brief diff --git a/src/modules/pv/pv_core.c b/src/modules/pv/pv_core.c index 0419641efdc..ac119ef3d34 100644 --- a/src/modules/pv/pv_core.c +++ b/src/modules/pv/pv_core.c @@ -1335,7 +1335,7 @@ int pv_get_dset(struct sip_msg *msg, pv_param_t *param, if(msg==NULL) return -1; - s.s = print_dset(msg, &s.len); + s.s = print_dset(msg, &s.len, 0); if (s.s == NULL) return pv_get_null(msg, param, res); s.len -= CRLF_LEN; diff --git a/src/modules/sl/sl_funcs.c b/src/modules/sl/sl_funcs.c index 1e408e653f1..c9730d71952 100644 --- a/src/modules/sl/sl_funcs.c +++ b/src/modules/sl/sl_funcs.c @@ -150,7 +150,7 @@ int sl_reply_helper(struct sip_msg *msg, int code, char *reason, str *tag) /* if that is a redirection message, dump current message set to it */ if (code>=300 && code<400) { - dset.s=print_dset(msg, &dset.len); + dset.s=print_dset(msg, &dset.len, 0); if (dset.s) { add_lump_rpl(msg, dset.s, dset.len, LUMP_RPL_HDR); } diff --git a/src/modules/tm/t_reply.c b/src/modules/tm/t_reply.c index 81f041fc60e..e2058cae786 100644 --- a/src/modules/tm/t_reply.c +++ b/src/modules/tm/t_reply.c @@ -640,7 +640,7 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg, /* if that is a redirection message, dump current message set to it */ if (code>=300 && code<400) { - dset=print_dset(p_msg, &dset_len); + dset=print_dset(p_msg, &dset_len, 0); if (dset) { add_lump_rpl(p_msg, dset, dset_len, LUMP_RPL_HDR); } diff --git a/src/modules/xprint/xp_lib.c b/src/modules/xprint/xp_lib.c index 068608a3049..bbe2ceaafed 100644 --- a/src/modules/xprint/xp_lib.c +++ b/src/modules/xprint/xp_lib.c @@ -559,7 +559,7 @@ static int xl_get_dset(struct sip_msg *msg, str *res, str *hp, int hi, int hf) if(msg==NULL || res==NULL) return -1; - res->s = print_dset(msg, &res->len); + res->s = print_dset(msg, &res->len, 0); if ((res->s) == NULL) return xl_get_null(msg, res, hp, hi, hf); From ffb7e0edd521e1d6d4a46cb3796f92ea9765c426 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:29 +0100 Subject: [PATCH 3/9] core/dset: Create Contacts header with path vector as Route header When Kamailio is functioning as a registrar sends a 302 redirect, the registered contacts are sent inside the Contact header. If a contact as a path vector, that path should become a Route header in the INVITE (rfc 3327). This patch adds the path vector as a Route header parameter to the Contacts in the redirect so the receiving entity of the 302 can add the proper Route headers. This is a standard way to specify headers to be added to a request, see rfc3261 section 19.1.1. --- src/core/dset.c | 33 ++++++++++++++++++++++++++++----- src/core/dset.h | 2 ++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/core/dset.c b/src/core/dset.c index 239a4f2ebce..d911515e0b2 100644 --- a/src/core/dset.c +++ b/src/core/dset.c @@ -39,6 +39,7 @@ #include "dset.h" #include "mem/mem.h" #include "ip_addr.h" +#include "strutils.h" #define CONTACT "Contact: " #define CONTACT_LEN (sizeof(CONTACT) - 1) @@ -49,6 +50,8 @@ #define Q_PARAM ";q=" #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1) +#define ROUTE_PARAM "?Route=" +#define ROUTE_PARAM_LEN (sizeof(ROUTE_PARAM) - 1) /* * Where we store URIs of additional transaction branches @@ -465,6 +468,7 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path, return 1; } + /*! \brief * Combines the given elements into a Contact header field * dest = target buffer, will be updated to new position after the printed contact @@ -472,7 +476,7 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path, * end = end of target buffer * Returns 0 on success or -1 on error (buffer is too short) */ -static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end, int options) +static int print_contact_str(char **dest, str *uri, qvalue_t q, str *path, char *end, int options) { char *p = *dest; str buf; @@ -484,6 +488,25 @@ static int print_contact_str(char **dest, str *uri, qvalue_t q, char *end, int o *p++ = '<'; memcpy(p, uri->s, uri->len); p += uri->len; + + /* uri parameters */ + /* path vector as route header parameter */ + if ((options & DS_PATH) && path->len > 0) { + if (p + ROUTE_PARAM_LEN + path->len > end) { + return -1; + } + memcpy(p, ROUTE_PARAM, ROUTE_PARAM_LEN); + p += ROUTE_PARAM_LEN; + /* copy escaped path into dest */ + buf.s = p; + buf.len = end - p; + if (escape_param(path, &buf) < 0) { + return -1; + } + p += buf.len; + } + + /* end of uri parameters */ *p++ = '>'; /* header parameters */ @@ -511,7 +534,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) { int cnt = 0; qvalue_t q; - str uri; + str uri, path; char *p; int crt_branch; static char dset[MAX_REDIRECTION_LEN]; @@ -529,7 +552,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) /* current uri */ if (msg->new_uri.s) { - if (print_contact_str(&p, &msg->new_uri, ruri_q, end, options) < 0) { + if (print_contact_str(&p, &msg->new_uri, ruri_q, &msg->path_vec, end, options) < 0) { goto memfail; } cnt++; @@ -537,7 +560,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) /* branches */ init_branch_iterator(); - while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0, 0, 0, 0))) { + while ((uri.s = next_branch(&uri.len, &q, 0, &path, 0, 0, 0, 0, 0))) { if (cnt > 0) { if (p + CONTACT_DELIM_LEN > end) { goto memfail; @@ -546,7 +569,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) p += CONTACT_DELIM_LEN; } - if (print_contact_str(&p, &uri, q, end, options) < 0) { + if (print_contact_str(&p, &uri, q, &path, end, options) < 0) { goto memfail; } diff --git a/src/core/dset.h b/src/core/dset.h index b786cee0530..e09262c8345 100644 --- a/src/core/dset.h +++ b/src/core/dset.h @@ -37,6 +37,8 @@ extern unsigned int nr_branches; extern int ruri_is_new; +#define DS_PATH 2 + /*! \brief * Structure for storing branch attributes */ From 32fa8d63a5819714ad2ee2222f55b83c185ccac8 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:30 +0100 Subject: [PATCH 4/9] core/dset: Create contacts with flags as header parameter Add the branch flags to the Contact uri in a redirect (302). --- src/core/dset.c | 25 +++++++++++++++++++++---- src/core/dset.h | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/core/dset.c b/src/core/dset.c index d911515e0b2..1803155206c 100644 --- a/src/core/dset.c +++ b/src/core/dset.c @@ -53,6 +53,9 @@ #define ROUTE_PARAM "?Route=" #define ROUTE_PARAM_LEN (sizeof(ROUTE_PARAM) - 1) +#define FLAGS_PARAM ";flags=" +#define FLAGS_PARAM_LEN (sizeof(FLAGS_PARAM) - 1) + /* * Where we store URIs of additional transaction branches * (sr_dst_max_branches - 1 : because of the default branch for r-uri, #0 in tm) @@ -476,7 +479,7 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path, * end = end of target buffer * Returns 0 on success or -1 on error (buffer is too short) */ -static int print_contact_str(char **dest, str *uri, qvalue_t q, str *path, char *end, int options) +static int print_contact_str(char **dest, str *uri, qvalue_t q, str *path, unsigned int flags, char *end, int options) { char *p = *dest; str buf; @@ -521,6 +524,19 @@ static int print_contact_str(char **dest, str *uri, qvalue_t q, str *path, char memcpy(p, buf.s, buf.len); p += buf.len; } + + /* branch flags (not SIP standard conformant) */ + if (options & DS_FLAGS) { + buf.s = int2str(flags, &buf.len); + if (p + FLAGS_PARAM_LEN + buf.len > end) { + return -1; + } + memcpy(p, FLAGS_PARAM, FLAGS_PARAM_LEN); + p += FLAGS_PARAM_LEN; + memcpy(p, buf.s, buf.len); + p += buf.len; + } + *dest = p; return 0; } @@ -535,6 +551,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) int cnt = 0; qvalue_t q; str uri, path; + unsigned int flags; char *p; int crt_branch; static char dset[MAX_REDIRECTION_LEN]; @@ -552,7 +569,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) /* current uri */ if (msg->new_uri.s) { - if (print_contact_str(&p, &msg->new_uri, ruri_q, &msg->path_vec, end, options) < 0) { + if (print_contact_str(&p, &msg->new_uri, ruri_q, &msg->path_vec, ruri_bflags, end, options) < 0) { goto memfail; } cnt++; @@ -560,7 +577,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) /* branches */ init_branch_iterator(); - while ((uri.s = next_branch(&uri.len, &q, 0, &path, 0, 0, 0, 0, 0))) { + while ((uri.s = next_branch(&uri.len, &q, 0, &path, &flags, 0, 0, 0, 0))) { if (cnt > 0) { if (p + CONTACT_DELIM_LEN > end) { goto memfail; @@ -569,7 +586,7 @@ char* print_dset(struct sip_msg* msg, int* len, int options) p += CONTACT_DELIM_LEN; } - if (print_contact_str(&p, &uri, q, &path, end, options) < 0) { + if (print_contact_str(&p, &uri, q, &path, flags, end, options) < 0) { goto memfail; } diff --git a/src/core/dset.h b/src/core/dset.h index e09262c8345..65b54c31049 100644 --- a/src/core/dset.h +++ b/src/core/dset.h @@ -37,6 +37,7 @@ extern unsigned int nr_branches; extern int ruri_is_new; +#define DS_FLAGS 1 #define DS_PATH 2 /*! \brief From 0d00c395762106e8e2ddb15d3b31dded40559509 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:31 +0100 Subject: [PATCH 5/9] sl: Add option to add path and flags to redirected contacts --- src/modules/sl/doc/sl_params.xml | 30 ++++++++++++++++++++++++++++++ src/modules/sl/sl.c | 1 + src/modules/sl/sl_funcs.c | 5 ++++- src/modules/sl/sl_funcs.h | 2 ++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/modules/sl/doc/sl_params.xml b/src/modules/sl/doc/sl_params.xml index f6ee54ba3de..79db29ab88c 100644 --- a/src/modules/sl/doc/sl_params.xml +++ b/src/modules/sl/doc/sl_params.xml @@ -61,4 +61,34 @@ modparam("sl", "bind_tm", 0) # feature disabled +
+ <varname>rich_redirect</varname> (int) + + When sending a 3xx class reply, include additional branch info + to the contacts such as path vector and branch flags. + + + + 0 - no extra info is added (default) + + + 1 - include branch flags as contact header parameter + + + 2 - include path as contact uri Route header + + + + Values may be combined (added). + + + rich_redirect example + +... +modparam("sl", "rich_redirect", 3) +... + + +
+ diff --git a/src/modules/sl/sl.c b/src/modules/sl/sl.c index 36c8a8eec7d..10361b12e1c 100644 --- a/src/modules/sl/sl.c +++ b/src/modules/sl/sl.c @@ -116,6 +116,7 @@ static param_export_t params[] = { {"default_code", PARAM_INT, &default_code}, {"default_reason", PARAM_STR, &default_reason}, {"bind_tm", PARAM_INT, &sl_bind_tm}, + {"rich_redirect", PARAM_INT, &sl_rich_redirect}, {0, 0, 0} }; diff --git a/src/modules/sl/sl_funcs.c b/src/modules/sl/sl_funcs.c index c9730d71952..7cdce0cda29 100644 --- a/src/modules/sl/sl_funcs.c +++ b/src/modules/sl/sl_funcs.c @@ -55,6 +55,9 @@ static int _sl_filtered_ack_route = -1; /* default disabled */ static int _sl_evrt_local_response = -1; /* default disabled */ +/* send path and flags in 3xx class reply */ +int sl_rich_redirect = 0; + /*! * lookup sl event routes */ @@ -150,7 +153,7 @@ int sl_reply_helper(struct sip_msg *msg, int code, char *reason, str *tag) /* if that is a redirection message, dump current message set to it */ if (code>=300 && code<400) { - dset.s=print_dset(msg, &dset.len, 0); + dset.s=print_dset(msg, &dset.len, sl_rich_redirect); if (dset.s) { add_lump_rpl(msg, dset.s, dset.len, LUMP_RPL_HDR); } diff --git a/src/modules/sl/sl_funcs.h b/src/modules/sl/sl_funcs.h index 659061f366f..53711efd374 100644 --- a/src/modules/sl/sl_funcs.h +++ b/src/modules/sl/sl_funcs.h @@ -30,6 +30,8 @@ #define SL_TOTAG_SEPARATOR '.' +extern int sl_rich_redirect; + int sl_startup(); int sl_shutdown(); From 54fdf1036d2d4937dd1964ea4c546c565d538866 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:32 +0100 Subject: [PATCH 6/9] tm: Add option to add path and flags to redirected contacts --- src/modules/tm/doc/params.xml | 30 ++++++++++++++++++++++++++++++ src/modules/tm/t_reply.c | 4 +++- src/modules/tm/tm.c | 1 + 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/modules/tm/doc/params.xml b/src/modules/tm/doc/params.xml index 3692dab0d48..75b60d9b0a7 100644 --- a/src/modules/tm/doc/params.xml +++ b/src/modules/tm/doc/params.xml @@ -1485,4 +1485,34 @@ modparam("tm", "relay_100", 1) +
+ <varname>rich_redirect</varname> (int) + + When sending a 3xx class reply, include additional branch info + to the contacts such as path vector and branch flags. + + + + 0 - no extra info is added (default) + + + 1 - include branch flags as contact header parameter + + + 2 - include path as contact uri Route header + + + + Values may be combined (added). + + + rich_redirect example + +... +modparam("tm", "rich_redirect", 3) +.... + + +
+ diff --git a/src/modules/tm/t_reply.c b/src/modules/tm/t_reply.c index e2058cae786..e1e8051cf14 100644 --- a/src/modules/tm/t_reply.c +++ b/src/modules/tm/t_reply.c @@ -102,6 +102,8 @@ int goto_on_sl_reply=0; /* remap 503 response code to 500 */ extern int tm_remap_503_500; +/* send path and flags in 3xx class reply */ +int tm_rich_redirect = 0; /* how to deal with winning branch reply selection in failure_route * can be overwritten per transaction with t_drop_replies(...) @@ -640,7 +642,7 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg, /* if that is a redirection message, dump current message set to it */ if (code>=300 && code<400) { - dset=print_dset(p_msg, &dset_len, 0); + dset=print_dset(p_msg, &dset_len, tm_rich_redirect); if (dset) { add_lump_rpl(p_msg, dset, dset_len, LUMP_RPL_HDR); } diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index c8afee9c4cd..c4a277d8241 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -475,6 +475,7 @@ static param_export_t params[]={ {"xavp_contact", PARAM_STR, &ulattrs_xavp_name }, {"event_callback", PARAM_STR, &tm_event_callback }, {"relay_100", PARAM_INT, &default_tm_cfg.relay_100 }, + {"rich_redirect" , PARAM_INT, &tm_rich_redirect }, {0,0,0} }; From 779cb39af6b25135884f659b8a9f2163d92aafc7 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:33 +0100 Subject: [PATCH 7/9] core/parser: Add parser for 'flags' param in Contact header --- src/core/parser/contact/contact.c | 2 ++ src/core/parser/contact/contact.h | 1 + src/core/parser/parse_param.c | 11 +++++++++++ src/core/parser/parse_param.h | 2 ++ 4 files changed, 16 insertions(+) diff --git a/src/core/parser/contact/contact.c b/src/core/parser/contact/contact.c index 06b85dd5dde..61a40e3bd80 100644 --- a/src/core/parser/contact/contact.c +++ b/src/core/parser/contact/contact.c @@ -244,6 +244,7 @@ int parse_contacts(str* _s, contact_t** _c) c->methods = hooks.contact.methods; c->instance = hooks.contact.instance; c->reg_id = hooks.contact.reg_id; + c->flags = hooks.contact.flags; if (_s->len == 0) goto ok; } @@ -314,6 +315,7 @@ void print_contacts(FILE* _o, contact_t* _c) fprintf(_o, "methods : %p\n", ptr->methods); fprintf(_o, "instance: %p\n", ptr->instance); fprintf(_o, "reg-id : %p\n", ptr->reg_id); + fprintf(_o, "flags : %p\n", ptr->flags); fprintf(_o, "len : %d\n", ptr->len); if (ptr->params) { print_params(_o, ptr->params); diff --git a/src/core/parser/contact/contact.h b/src/core/parser/contact/contact.h index c2d63aef71b..b72f9e59d9c 100644 --- a/src/core/parser/contact/contact.h +++ b/src/core/parser/contact/contact.h @@ -50,6 +50,7 @@ typedef struct contact { param_t* received; /* received parameter hook */ param_t* instance; /* sip.instance parameter hook */ param_t* reg_id; /* reg-id parameter hook */ + param_t* flags; /* flags parameter hook */ param_t* params; /* List of all parameters */ int len; /* Total length of the element */ struct contact* next; /* Next contact in the list */ diff --git a/src/core/parser/parse_param.c b/src/core/parser/parse_param.c index 5af3993cb94..b80ffbdcc02 100644 --- a/src/core/parser/parse_param.c +++ b/src/core/parser/parse_param.c @@ -173,6 +173,14 @@ static inline void parse_contact_class(param_hooks_t *_h, param_t *_p) _h->contact.ob = _p; } break; + case 'f': + case 'F': + if ((_p->name.len == 5) && + (!strncasecmp(_p->name.s + 1, "lags", 4))) { + _p->type = P_FLAGS; + _h->contact.flags = _p; + } + break; } } @@ -673,6 +681,9 @@ static inline void print_param(FILE *_o, param_t *_p) case P_METHODS: type = "P_METHODS"; break; + case P_FLAGS: + type = "P_FLAGS"; + break; case P_TRANSPORT: type = "P_TRANSPORT"; break; diff --git a/src/core/parser/parse_param.h b/src/core/parser/parse_param.h index 1007358125a..ebb3ac56d6e 100644 --- a/src/core/parser/parse_param.h +++ b/src/core/parser/parse_param.h @@ -44,6 +44,7 @@ typedef enum ptype { P_EXPIRES, /*!< Contact: expires parameter */ P_METHODS, /*!< Contact: methods parameter */ P_RECEIVED, /*!< Contact: received parameter */ + P_FLAGS, /*!< Contact: flags parameter */ P_TRANSPORT, /*!< URI: transport parameter */ P_LR, /*!< URI: lr parameter */ P_R2, /*!< URI: r2 parameter (ser specific) */ @@ -98,6 +99,7 @@ struct contact_hooks { struct param* instance; /*!< sip.instance parameter */ struct param* reg_id; /*!< reg-id parameter */ struct param* ob; /*!< ob parameter */ + struct param* flags; /*!< flags parameter */ }; From 6d868291e6687232fd752c8c19092a1ecf333ffa Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:34 +0100 Subject: [PATCH 8/9] uac_redirect: Use Contact's "flags" header parameter into branch flags. --- .../uac_redirect/doc/uac_redirect_admin.xml | 40 ++++++++++++++++++- src/modules/uac_redirect/rd_funcs.c | 9 ++++- src/modules/uac_redirect/rd_funcs.h | 2 + src/modules/uac_redirect/uac_redirect.c | 2 + 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/modules/uac_redirect/doc/uac_redirect_admin.xml b/src/modules/uac_redirect/doc/uac_redirect_admin.xml index 2c7fc0e883f..b044d38c250 100644 --- a/src/modules/uac_redirect/doc/uac_redirect_admin.xml +++ b/src/modules/uac_redirect/doc/uac_redirect_admin.xml @@ -302,8 +302,46 @@ branch_route[1] { +
+ <varname>flags_hdr_mode</varname> (int) + + Specifies if and how a Contact's flags header parameter + must be used. If set, and a flags header parameter is set, + its value will be set as branch flags for that contact. + + + Its values may be: + + + + 0 - ignore flags header parameter, + just use bflags module parameter + + + 1 - use flags header parameter if + present, ignore bflags module parameter + + + 2 - use flags header parameter if + present and merge (binary or) it with the bflags module + parameter + + + + + The default value is 0. + + + + Set <varname>flags_hdr_mode</varname> parameter + +... +modparam("uac_redirect","flags_hdr_mode",2) +... + + +
-
Functions
diff --git a/src/modules/uac_redirect/rd_funcs.c b/src/modules/uac_redirect/rd_funcs.c index fdd885b1791..3dcf8077b69 100644 --- a/src/modules/uac_redirect/rd_funcs.c +++ b/src/modules/uac_redirect/rd_funcs.c @@ -199,6 +199,7 @@ static int shmcontact2dset(struct sip_msg *req, struct sip_msg *sh_rpl, int added; int dup; int ret; + unsigned int flags; /* dup can be: * 0 - sh reply but nothing duplicated @@ -294,8 +295,14 @@ static int shmcontact2dset(struct sip_msg *req, struct sip_msg *sh_rpl, LM_DBG("adding contact <%.*s>\n", scontacts[i]->uri.len, scontacts[i]->uri.s); if(sruid_next(&_redirect_sruid)==0) { + if (flags_hdr_mode && scontacts[i]->flags && str2int(&(scontacts[i]->flags->body), &flags) == 0) { + if (flags_hdr_mode == 2) + flags |= bflags; + } else { + flags = bflags; + } if(append_branch( 0, &scontacts[i]->uri, 0, 0, sqvalues[i], - bflags, 0, &_redirect_sruid.uid, 0, + flags, 0, &_redirect_sruid.uid, 0, &_redirect_sruid.uid, &_redirect_sruid.uid)<0) { LM_ERR("failed to add contact to dset\n"); } else { diff --git a/src/modules/uac_redirect/rd_funcs.h b/src/modules/uac_redirect/rd_funcs.h index a5304c19dc0..f686615969e 100644 --- a/src/modules/uac_redirect/rd_funcs.h +++ b/src/modules/uac_redirect/rd_funcs.h @@ -36,6 +36,8 @@ extern cmd_function rd_acc_fct; extern char *acc_db_table; +extern int flags_hdr_mode; + int get_redirect( struct sip_msg *msg , int maxt, int maxb, struct acc_param *reason, unsigned int bflags); diff --git a/src/modules/uac_redirect/uac_redirect.c b/src/modules/uac_redirect/uac_redirect.c index e1f7d640db7..6ade1719c6b 100644 --- a/src/modules/uac_redirect/uac_redirect.c +++ b/src/modules/uac_redirect/uac_redirect.c @@ -48,6 +48,7 @@ char *accept_filter_s = 0; char *def_filter_s = 0; unsigned int bflags = 0; +int flags_hdr_mode = 0; #define ACCEPT_RULE_STR "accept" #define DENY_RULE_STR "deny" @@ -86,6 +87,7 @@ static param_export_t params[] = { {"acc_function", PARAM_STRING, &acc_fct_s }, {"acc_db_table", PARAM_STRING, &acc_db_table }, {"bflags", INT_PARAM, &bflags }, + {"flags_hdr_mode", INT_PARAM, &flags_hdr_mode }, {0, 0, 0} }; From 386d6379b874e3ed170716c58319e74acf86c019 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Thu, 31 Jan 2019 17:28:35 +0100 Subject: [PATCH 9/9] core/config: Increase MAX_REDIRECTION_LEN from 512 to 4096 Contacts can be long and there may be many of them. --- src/core/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/config.h b/src/core/config.h index bdc76573653..a891328eb37 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -166,7 +166,7 @@ #define MAX_PRINT_TEXT 256 /*!< max length of the text of fifo 'print' command */ -#define MAX_REDIRECTION_LEN 512 /*!< maximum length of Contact header field in redirection replies */ +#define MAX_REDIRECTION_LEN 4096 /*!< maximum length of Contact header field in redirection replies */ /*! \brief used by FIFO statistics in module to terminate line; extra whitespaces are used to overwrite remainders of