From 275095a26c580531062c7a2b78673d60859d379e Mon Sep 17 00:00:00 2001 From: emvondo Date: Tue, 31 May 2022 16:19:28 +0100 Subject: [PATCH 1/2] Enable tm dns failover to try next ip on receiving code other than 503 --- src/modules/tm/doc/params.xml | 25 ++++++ src/modules/tm/t_funcs.c | 11 +++ src/modules/tm/t_reply.c | 12 ++- src/modules/tm/t_reply.h | 4 + src/modules/tm/tm.c | 139 ++++++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 1 deletion(-) diff --git a/src/modules/tm/doc/params.xml b/src/modules/tm/doc/params.xml index 3f67ae3f4d9..518d0dfc505 100644 --- a/src/modules/tm/doc/params.xml +++ b/src/modules/tm/doc/params.xml @@ -1623,4 +1623,29 @@ modparam("tm", "enable_uac_fr", 1) +
+ <varname>failover_reply_codes</varname> (string) + + This parameter defines the response codes (only codes >= 300 and class >= 3), which enable + dns failover to continue to try next ips when previous one fail. It is a list separated by + colons, where you may define either a single code (e.g. "code=408" would accept 408 as an + additional response code) or a class of responses, you want to accept (e.g. "class=3" would accept + everything from 300 to 999 as valid response). + (with default behaviour only 503 code or no response from previous one will try next ip). + + + + Default value is + + + + Set the <quote>failover_reply_codes</quote> parameter + +... +modparam("tm", "failover_reply_codes", "code=403;code=488;class=5") +... + + +
+ diff --git a/src/modules/tm/t_funcs.c b/src/modules/tm/t_funcs.c index 97c0d2568b1..2862937627b 100644 --- a/src/modules/tm/t_funcs.c +++ b/src/modules/tm/t_funcs.c @@ -43,6 +43,11 @@ * end (this allows the script writter to send its own error reply) */ #define TM_DELAYED_REPLY +#ifdef USE_DNS_FAILOVER +extern int** failover_reply_codes; +extern int* failover_reply_codes_cnt; +#endif + /* fr_timer AVP specs */ static int fr_timer_avp_type = 0; static int_str fr_timer_avp = {0}; @@ -83,6 +88,12 @@ void tm_shutdown() LM_DBG("start\n"); +#ifdef USE_DNS_FAILOVER + if(failover_reply_codes) + shm_free(failover_reply_codes); + if(failover_reply_codes_cnt) + shm_free(failover_reply_codes_cnt); +#endif /* destroy the hash table */ LM_DBG("emptying hash table\n"); free_hash_table( ); diff --git a/src/modules/tm/t_reply.c b/src/modules/tm/t_reply.c index 509cbcb9503..f478da054b0 100644 --- a/src/modules/tm/t_reply.c +++ b/src/modules/tm/t_reply.c @@ -104,6 +104,10 @@ extern str _tm_event_callback_lres_sent; extern unsigned long tm_exec_time_check; +#ifdef USE_DNS_FAILOVER +extern str failover_reply_codes_str; +#endif + /* remap 503 response code to 500 */ extern int tm_remap_503_500; /* send path and flags in 3xx class reply */ @@ -2328,6 +2332,7 @@ int reply_received( struct sip_msg *p_msg ) #ifdef USE_DNS_FAILOVER int branch_ret; int prev_branch; + int failover_continue = 0; #endif #ifdef USE_DST_BLOCKLIST int blst_503_timeout; @@ -2642,7 +2647,12 @@ int reply_received( struct sip_msg *p_msg ) * This code is out of LOCK_REPLIES() to minimize the time the * reply lock is held (the lock won't be held while sending the * message)*/ - if (cfg_get(core, core_cfg, use_dns_failover) && (msg_status==503)) { + + + failover_continue = (failover_reply_codes_str.s!=NULL && failover_reply_codes_str.len>0 && + t_failover_check_reply_code(msg_status)); + + if (cfg_get(core, core_cfg, use_dns_failover) && (msg_status==503 || failover_continue)) { branch_ret=add_uac_dns_fallback(t, t->uas.request, uac, !replies_locked); prev_branch=-1; diff --git a/src/modules/tm/t_reply.h b/src/modules/tm/t_reply.h index cdc5e9e9ace..ea287411dfb 100644 --- a/src/modules/tm/t_reply.h +++ b/src/modules/tm/t_reply.h @@ -228,4 +228,8 @@ int t_get_picked_branch(void); int t_get_this_branch_instance(struct sip_msg *msg, str *instance); int t_get_this_branch_ruid(struct sip_msg *msg, str *ruid); +#ifdef USE_DNS_FAILOVER +int t_failover_check_reply_code(int code); +#endif + #endif diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index b6fcc96681d..c0b2534ce3b 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -104,6 +104,9 @@ static int fixup_t_is_set(void** param, int param_no); static int mod_init(void); static int child_init(int rank); +#ifdef USE_DNS_FAILOVER +static int t_failover_parse_reply_codes(); +#endif /* exported functions */ static int w_t_check(struct sip_msg* msg, char* str, char* str2); @@ -222,6 +225,12 @@ str on_sl_reply_name = {NULL, 0}; int tm_remap_503_500 = 1; str _tm_event_callback_lres_sent = {NULL, 0}; +#ifdef USE_DNS_FAILOVER +str failover_reply_codes_str = {NULL, 0}; +int** failover_reply_codes = NULL; +int* failover_reply_codes_cnt; +#endif + /* control if reply should be relayed * when transaction reply status is RPS_PUSHED_AFTER_COMPLETION */ int tm_reply_relay_mode = 1; @@ -487,6 +496,9 @@ static param_export_t params[]={ {"exec_time_check" , PARAM_INT, &tm_exec_time_check_param }, {"reply_relay_mode", PARAM_INT, &tm_reply_relay_mode }, {"enable_uac_fr", PARAM_INT, &default_tm_cfg.enable_uac_fr }, +#ifdef USE_DNS_FAILOVER + {"failover_reply_codes",PARAM_STR, &failover_reply_codes_str }, +#endif {0,0,0} }; @@ -780,6 +792,18 @@ static int mod_init(void) } #ifdef USE_DNS_FAILOVER + /* Initialize code and counter for other failover reply codes*/ + failover_reply_codes = (int **)shm_malloc(sizeof(unsigned int *)); + *failover_reply_codes = 0; + failover_reply_codes_cnt = (int *)shm_malloc(sizeof(int)); + *failover_reply_codes_cnt = 0; + if(failover_reply_codes_str.s && failover_reply_codes_str.len > 0) { + if(t_failover_parse_reply_codes() < 0) { + LM_ERR("failed to parse failover_reply_codes\n"); + return -1; + } + } + if (default_tm_cfg.reparse_on_dns_failover && mhomed) { LM_WARN("reparse_on_dns_failover is enabled on a" " multihomed host -- check the readme of tm module!\n"); @@ -3053,6 +3077,121 @@ static int ki_t_clean(sip_msg_t* msg) return 1; } +#ifdef USE_DNS_FAILOVER +/* parse reply codes for failover given in module paraleter */ +static int t_failover_parse_reply_codes() +{ + param_t *params_list = NULL; + param_t *pit = NULL; + int list_size = 0; + int i = 0; + int pos = 0; + int code = 0; + str input = {0, 0}; + int *new_failover_reply_codes = NULL; + int *old_failover_reply_codes = NULL; + + /* validate input string */ + if(failover_reply_codes_str.s == 0 || failover_reply_codes_str.len <= 0) + return 0; + + /* parse_params() updates the string pointer of .s -- make a copy */ + input.s = failover_reply_codes_str.s; + input.len = failover_reply_codes_str.len; + + if(parse_params(&input, CLASS_ANY, 0, ¶ms_list) < 0) + return -1; + + /* get the number of entries in the list */ + for(pit = params_list; pit; pit = pit->next) { + if(pit->name.len == 4 && strncasecmp(pit->name.s, "code", 4) == 0) { + str2sint(&pit->body, &code); + if((code >= 300) && (code < 700)) + list_size += 1; + } else if(pit->name.len == 5 + && strncasecmp(pit->name.s, "class", 5) == 0) { + str2sint(&pit->body, &code); + if((code >= 3) && (code < 7)) + list_size += 1; + } + } + LM_DBG("expecting %d reply codes and classes\n", list_size); + + if(list_size > 0) { + /* Allocate Memory for the new list: */ + new_failover_reply_codes = (int *)shm_malloc(list_size * sizeof(int)); + if(new_failover_reply_codes == NULL) { + free_params(params_list); + LM_ERR("no more memory\n"); + return -1; + } + + /* Now create the list of valid reply-codes: */ + for(pit = params_list; pit; pit = pit->next) { + if(pit->name.len == 4 && strncasecmp(pit->name.s, "code", 4) == 0) { + str2sint(&pit->body, &code); + if((code >= 300) && (code < 700)) { + new_failover_reply_codes[pos++] = code; + } + } else if(pit->name.len == 5 + && strncasecmp(pit->name.s, "class", 5) == 0) { + str2sint(&pit->body, &code); + if((code >= 3) && (code < 7)) { + new_failover_reply_codes[pos++] = code; + } + } + } + } else { + new_failover_reply_codes = 0; + } + free_params(params_list); + + if(list_size > *failover_reply_codes_cnt) { + /* if more reply-codes -- change pointer and then set number of codes */ + old_failover_reply_codes = *failover_reply_codes; + *failover_reply_codes = new_failover_reply_codes; + *failover_reply_codes_cnt = list_size; + if(old_failover_reply_codes) + shm_free(old_failover_reply_codes); + } else { + /* less or equal reply codea -- set the number of codes first */ + *failover_reply_codes_cnt = list_size; + old_failover_reply_codes = *failover_reply_codes; + *failover_reply_codes = new_failover_reply_codes; + if(old_failover_reply_codes) + shm_free(old_failover_reply_codes); + } + /* Print the list as INFO: */ + for(i = 0; i < *failover_reply_codes_cnt; i++) { + LM_DBG("accepting reply %s %d (%d/%d) as valid\n", + ((*failover_reply_codes)[i]/10)?"code":"class", + (*failover_reply_codes)[i], (i + 1), *failover_reply_codes_cnt); + } + return 0; +} + +int t_failover_check_reply_code(int code) +{ + int i; + + for(i = 0; i < *failover_reply_codes_cnt; i++) { + if((*failover_reply_codes)[i] / 10) { + /* reply code */ + if((*failover_reply_codes)[i] == code) { + return 1; + } + } else { + /* reply class */ + if(((*failover_reply_codes)[i] / 100) == code) { + return 1; + } + } + } + + return 0; +} +#endif + /** * */ From 35c94ef0afcb21fac299a1d9a7297a059ae0510d Mon Sep 17 00:00:00 2001 From: emvondo Date: Sat, 18 Jun 2022 11:15:15 +0100 Subject: [PATCH 2/2] topos: remove contact header for CANCEL,BYE,PRACK REQUESTS --- src/modules/topos/tps_msg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/topos/tps_msg.c b/src/modules/topos/tps_msg.c index 83d5f5fddff..22842eaba04 100644 --- a/src/modules/topos/tps_msg.c +++ b/src/modules/topos/tps_msg.c @@ -581,9 +581,12 @@ int tps_reinsert_via(sip_msg_t *msg, tps_data_t *ptsd, str *hbody) int tps_reinsert_contact(sip_msg_t *msg, tps_data_t *ptsd, str *hbody) { str hname = str_init("Contact"); + int method = get_cseq(msg)->method_id; - if(tps_add_headers(msg, &hname, hbody, 0)<0) { - return -1; + if (!(method & (METHOD_CANCEL|METHOD_BYE|METHOD_PRACK))) { + if(tps_add_headers(msg, &hname, hbody, 0)<0) { + return -1; + } } return 0;