From 9ccd25fc282db8b2452254790c5492fc5829e382 Mon Sep 17 00:00:00 2001 From: John Burke Date: Wed, 11 Aug 2021 00:19:18 -0500 Subject: [PATCH 1/3] rtpengine: refactor of node probing Probing of disabled rtpengine nodes is now done in timer routine instead of SIP context. --- modules/rtpengine/doc/rtpengine_admin.xml | 20 ++++++++ modules/rtpengine/rtpengine.c | 61 ++++++++++++----------- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/modules/rtpengine/doc/rtpengine_admin.xml b/modules/rtpengine/doc/rtpengine_admin.xml index 0ec3972bec4..0629890e1ee 100644 --- a/modules/rtpengine/doc/rtpengine_admin.xml +++ b/modules/rtpengine/doc/rtpengine_admin.xml @@ -185,6 +185,26 @@ modparam("rtpengine", "rtpengine_tout", 2) ... modparam("rtpengine", "rtpengine_retr", 2) ... + + + +
+ <varname>rtpengine_timer_interval</varname> (integer) + + Frequency to scan rtpengine sets for disabled node probing. Probing is done + outside the SIP processing context and in a separate timer routine. Disabled nodes + are probed for re-enablement after rtpengine_disable_tout seconds. Setting this value + too high can lead to unexpectedly large disabled interval as the max interval + before probing is (rtpengine_timer_interval + rtpengine_disable_tout) seconds. + + Default value is 5. + + + Set <varname>rtpengine_timer_interval</varname> parameter + +... +modparam("rtpengine", "rtpengine_timer_interval", 1) +...
diff --git a/modules/rtpengine/rtpengine.c b/modules/rtpengine/rtpengine.c index 801d41c938a..7bea880778d 100644 --- a/modules/rtpengine/rtpengine.c +++ b/modules/rtpengine/rtpengine.c @@ -296,7 +296,7 @@ static int fixup_set_id(void ** param); static int fixup_free_set_id(void ** param); static int set_rtpengine_set_f(struct sip_msg * msg, rtpe_set_link_t *set_param); static struct rtpe_set * select_rtpe_set(int id_set); -static struct rtpe_node *select_rtpe_node(str, int, struct rtpe_set *); +static struct rtpe_node *select_rtpe_node(str, struct rtpe_set *); static char *send_rtpe_command(struct rtpe_node *, bencode_item_t *, int *); static int get_extra_id(struct sip_msg* msg, str *id_str); @@ -330,6 +330,7 @@ static int rtpengine_stats_used = 0; static int rtpengine_disable_tout = 60; static int rtpengine_retr = 5; static int rtpengine_tout = 1; +static int rtpengine_timer_interval = 5; static pid_t mypid; static int myrand = 0; static unsigned int myseqn = 0; @@ -637,6 +638,7 @@ static param_export_t params[] = { {"rtpengine_disable_tout", INT_PARAM, &rtpengine_disable_tout }, {"rtpengine_retr", INT_PARAM, &rtpengine_retr }, {"rtpengine_tout", INT_PARAM, &rtpengine_tout }, + {"rtpengine_timer_interval", INT_PARAM, &rtpengine_timer_interval}, {"notification_sock", STR_PARAM, &rtpengine_notify_sock.s}, {"extra_id_pv", STR_PARAM, &extra_id_pv_param.s }, {"setid_avp", STR_PARAM, &setid_avp_param }, @@ -1201,6 +1203,26 @@ static mi_response_t *mi_teardown_call(const mi_params_t *params, return init_mi_result_ok(); } +/* + * Timer housekeeping, invoked each timer interval to check for proxy re-enablement + */ +void rtpengine_timer(unsigned int ticks, void *param) +{ + struct rtpe_set *rtpe_list; + struct rtpe_node *crt_rtpe; + + RTPE_START_READ(); + for(rtpe_list = (*rtpe_set_list)->rset_first; rtpe_list != NULL; + rtpe_list = rtpe_list->rset_next){ + for(crt_rtpe = rtpe_list->rn_first; crt_rtpe != NULL; + crt_rtpe = crt_rtpe->rn_next){ + if (crt_rtpe->rn_disabled && crt_rtpe->rn_recheck_ticks <= get_ticks()) + crt_rtpe->rn_disabled = rtpe_test(crt_rtpe, 0, 1); + } + } + RTPE_STOP_READ(); +} + /* hack to get the rtpengine node used for the offer */ static pv_spec_t media_pvar; @@ -1375,6 +1397,11 @@ mod_init(void) memset(&dlgb, 0, sizeof(struct dlg_binds)); } + if (register_timer("rtpengine-timer", rtpengine_timer, NULL, rtpengine_timer_interval, TIMER_FLAG_SKIP_ON_DELAY) <0 ) { + LM_ERR("could not register timer function\n"); + return -1; + } + return 0; } @@ -2104,10 +2131,10 @@ static bencode_item_t *rtpe_function_call(bencode_buffer_t *bencbuf, struct sip_ do { if (snode && snode->s) { if ((node = get_rtpe_node(snode, set)) == NULL) - node = select_rtpe_node(ng_flags.call_id, 1, set); + node = select_rtpe_node(ng_flags.call_id, set); snode = NULL; } else { - node = select_rtpe_node(ng_flags.call_id, 1, set); + node = select_rtpe_node(ng_flags.call_id, set); } if (!node) { LM_ERR("no available proxies\n"); @@ -2486,7 +2513,7 @@ static struct rtpe_set * select_rtpe_set(int id_set ) * too expensive here. */ static struct rtpe_node * -select_rtpe_node(str callid, int do_test, struct rtpe_set *set) +select_rtpe_node(str callid, struct rtpe_set *set) { unsigned sum, weight_sum; struct rtpe_node* node; @@ -2506,11 +2533,8 @@ select_rtpe_node(str callid, int do_test, struct rtpe_set *set) /* Most popular case: 1 proxy, nothing to calculate */ if (set->rtpe_node_count == 1) { node = set->rn_first; - if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks()) - node->rn_disabled = rtpe_test(node, 1, 0); if (node->rn_disabled) return NULL; - return node; } @@ -2520,16 +2544,10 @@ select_rtpe_node(str callid, int do_test, struct rtpe_set *set) sum &= 0xff; was_forced = 0; -retry: weight_sum = 0; constant_weight_sum = 0; found = 0; for (node=set->rn_first; node!=NULL; node=node->rn_next) { - - if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks()){ - /* Try to enable if it's time to try. */ - node->rn_disabled = rtpe_test(node, 1, 0); - } constant_weight_sum += node->rn_weight; if (!node->rn_disabled) { weight_sum += node->rn_weight; @@ -2537,14 +2555,7 @@ select_rtpe_node(str callid, int do_test, struct rtpe_set *set) } } if (found == 0) { - /* No proxies? Force all to be re-detected, if not yet */ - if (was_forced) return NULL; - was_forced = 1; - for(node=set->rn_first; node!=NULL; node=node->rn_next) { - node->rn_disabled = rtpe_test(node, 1, 1); - } - goto retry; } sumcut = weight_sum ? sum % constant_weight_sum : -1; /* @@ -2555,7 +2566,7 @@ select_rtpe_node(str callid, int do_test, struct rtpe_set *set) for (node=set->rn_first; node!=NULL;) { if (sumcut < (int)node->rn_weight) { if (!node->rn_disabled) - goto found; + return node; if (was_forced == 0) { /* appropriate proxy is disabled : redistribute on enabled ones */ sumcut = weight_sum ? sum % weight_sum : -1; @@ -2569,14 +2580,6 @@ select_rtpe_node(str callid, int do_test, struct rtpe_set *set) } /* No node list */ return NULL; -found: - if (do_test) { - node->rn_disabled = rtpe_test(node, node->rn_disabled, 0); - if (node->rn_disabled) - goto retry; - } - - return node; } static int From b3dd7c51ddcd5e96f24212341c325d823c5b87bd Mon Sep 17 00:00:00 2001 From: John Burke Date: Thu, 12 Aug 2021 10:54:13 -0500 Subject: [PATCH 2/3] rtpengine: use `DELAY_ON_DELAY` instead of `SKIP_ON_DELAY` timer flag --- modules/rtpengine/rtpengine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rtpengine/rtpengine.c b/modules/rtpengine/rtpengine.c index 7bea880778d..ca4f931af31 100644 --- a/modules/rtpengine/rtpengine.c +++ b/modules/rtpengine/rtpengine.c @@ -1397,7 +1397,7 @@ mod_init(void) memset(&dlgb, 0, sizeof(struct dlg_binds)); } - if (register_timer("rtpengine-timer", rtpengine_timer, NULL, rtpengine_timer_interval, TIMER_FLAG_SKIP_ON_DELAY) <0 ) { + if (register_timer("rtpengine-timer", rtpengine_timer, NULL, rtpengine_timer_interval, TIMER_FLAG_DELAY_ON_DELAY) <0 ) { LM_ERR("could not register timer function\n"); return -1; } From dc4a2b924434020462b8522fad455a36852e50f5 Mon Sep 17 00:00:00 2001 From: John Burke Date: Thu, 12 Aug 2021 11:47:19 -0500 Subject: [PATCH 3/3] rtpengine: check for empty list before processing timer job --- modules/rtpengine/rtpengine.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/rtpengine/rtpengine.c b/modules/rtpengine/rtpengine.c index ca4f931af31..51b4f090382 100644 --- a/modules/rtpengine/rtpengine.c +++ b/modules/rtpengine/rtpengine.c @@ -1211,6 +1211,9 @@ void rtpengine_timer(unsigned int ticks, void *param) struct rtpe_set *rtpe_list; struct rtpe_node *crt_rtpe; + if (*rtpe_set_list == NULL) + return; + RTPE_START_READ(); for(rtpe_list = (*rtpe_set_list)->rset_first; rtpe_list != NULL; rtpe_list = rtpe_list->rset_next){