From 9661aa6478fe4cb78eb73aeebcf0f0131eb73b7b Mon Sep 17 00:00:00 2001 From: Guillaume Bour Date: Sat, 11 Mar 2017 10:01:12 +0100 Subject: [PATCH] drouting: use keepalive to monitor GW/destinations (sort_order 0 only) If keepalive is enabled and sort_order is 0, unavailable destinations are excluded from do_routing() resultset. --- src/modules/drouting/README | 38 ++++++++++--- src/modules/drouting/doc/drouting_admin.xml | 24 ++++++++ src/modules/drouting/dr_load.c | 3 + src/modules/drouting/drouting.c | 61 +++++++++++++++++++-- src/modules/drouting/prefix_tree.h | 4 ++ src/modules/drouting/routing.c | 2 + 6 files changed, 119 insertions(+), 13 deletions(-) diff --git a/src/modules/drouting/README b/src/modules/drouting/README index 907e3f0b2c7..7046ed795ee 100644 --- a/src/modules/drouting/README +++ b/src/modules/drouting/README @@ -51,6 +51,7 @@ Anca-Maria Vamanu 3.12. drg_grpid_col (str) 3.13. fetch_rows (int) 3.14. force_dns (int) + 3.15. enable_keepalive (int) 4. Functions @@ -92,11 +93,12 @@ Anca-Maria Vamanu 1.12. Set drg_grpid_col parameter 1.13. Set fetch_rows parameter 1.14. Set force_dns parameter - 1.15. do_routing usage - 1.16. use_next_gw usage - 1.17. goes_to_gw usage - 1.18. is_from_gw usage + 1.15. Set enable_keepalive parameter + 1.16. do_routing usage + 1.17. use_next_gw usage + 1.18. goes_to_gw usage 1.19. is_from_gw usage + 1.20. is_from_gw usage Chapter 1. Admin Guide @@ -136,6 +138,7 @@ Chapter 1. Admin Guide 3.12. drg_grpid_col (str) 3.13. fetch_rows (int) 3.14. force_dns (int) + 3.15. enable_keepalive (int) 4. Functions @@ -500,6 +503,7 @@ Chapter 1. Admin Guide 3.12. drg_grpid_col (str) 3.13. fetch_rows (int) 3.14. force_dns (int) + 3.15. enable_keepalive (int) 3.1. db_url(str) @@ -690,6 +694,22 @@ modparam("drouting", "fetch_rows", 1500) modparam("drouting", "force_dns", 0) ... +3.15. enable_keepalive (int) + + Enable monitoring of GW/destinations using keepalive module. + Destinations found unavailable will not be used on do_routing() call. + + NOTE: this option is only compatible with sort_order 0 + currently. With sort_order value of 1 or 2, destinations status will + simply be ignored. + + Default value is “0 (disabled)”. + + Example 1.15. Set enable_keepalive parameter +... +modparam("drouting", "enable_keepalive", 1) +... + 4. Functions 4.1. do_routing("[groupID]") @@ -710,7 +730,7 @@ modparam("drouting", "force_dns", 0) specification. If none specified, the function will automatically try to query the dr_group table to get this information. - Example 1.15. do_routing usage + Example 1.16. do_routing usage ... do_routing(); ... @@ -733,7 +753,7 @@ do_routing("$avp(i:10)"); is no other alternative destinations are found or in case of internal processing error. - Example 1.16. use_next_gw usage + Example 1.17. use_next_gw usage ... if (use_next_gw()) { t_relay(); @@ -754,7 +774,7 @@ if (use_next_gw()) { The function can take one optional parameter: * type (optional) - GW/destination type to be checked - Example 1.17. goes_to_gw usage + Example 1.18. goes_to_gw usage ... if (goes_to_gw("1")) { sl_send_reply("403","Forbidden"); @@ -775,7 +795,7 @@ if (goes_to_gw("1")) { * flags - if message is a request and the GW has a STRIP defined, then apply it if GW is source. - Example 1.18. is_from_gw usage + Example 1.19. is_from_gw usage ... if (is_from_gw("1") { } @@ -793,7 +813,7 @@ if (is_from_gw("1") { * flags (optional) - if message is a request and the GW has a STRIP defined, then apply it if GW is source. - Example 1.19. is_from_gw usage + Example 1.20. is_from_gw usage ... if (is_from_gw("3","1") { } diff --git a/src/modules/drouting/doc/drouting_admin.xml b/src/modules/drouting/doc/drouting_admin.xml index f4088c37808..f2cfa5aa20a 100644 --- a/src/modules/drouting/doc/drouting_admin.xml +++ b/src/modules/drouting/doc/drouting_admin.xml @@ -1137,6 +1137,30 @@ modparam("drouting", "fetch_rows", 1500) ... modparam("drouting", "force_dns", 0) +... + + + + +
+ <varname>enable_keepalive</varname> (int) + + Enable monitoring of GW/destinations using keepalive module. + Destinations found unavailable will not be used on do_routing() call. + + + NOTE: this option is only compatible with sort_order 0 currently. + With sort_order value of 1 or 2, destinations status will simply be ignored. + + + Default value is 0 (disabled). + + + + Set <varname>enable_keepalive</varname> parameter + +... +modparam("drouting", "enable_keepalive", 1) ... diff --git a/src/modules/drouting/dr_load.c b/src/modules/drouting/dr_load.c index b425ced98b7..42bc8fc647c 100644 --- a/src/modules/drouting/dr_load.c +++ b/src/modules/drouting/dr_load.c @@ -38,6 +38,8 @@ //#include "../../core/db/db.h" #include "../../core/mem/shm_mem.h" +#include "../keepalive/api.h" + #include "dr_load.h" #include "routing.h" #include "prefix_tree.h" @@ -129,6 +131,7 @@ static struct dr_gwl_tmp* dr_gw_lists = NULL; } while(0) extern int dr_fetch_rows; +extern keepalive_api_t keepalive_api; static int add_tmp_gw_list(unsigned int id, char *list) diff --git a/src/modules/drouting/drouting.c b/src/modules/drouting/drouting.c index 260462123c0..05927c834c1 100644 --- a/src/modules/drouting/drouting.c +++ b/src/modules/drouting/drouting.c @@ -49,6 +49,8 @@ #include "../../core/rpc_lookup.h" #include "../../core/rand/kam_rand.h" +#include "../keepalive/api.h" + #include "dr_load.h" #include "prefix_tree.h" #include "routing.h" @@ -71,6 +73,9 @@ static int use_domain = 1; static int sort_order = 0; int dr_fetch_rows = 1000; int dr_force_dns = 1; +/* enable destinations keepalive (through keepalive module */ +int dr_enable_keepalive = 0; +keepalive_api_t keepalive_api; /* DRG table columns */ static str drg_user_col = str_init("username"); @@ -170,6 +175,7 @@ static param_export_t params[] = { {"sort_order", INT_PARAM, &sort_order }, {"fetch_rows", INT_PARAM, &dr_fetch_rows }, {"force_dns", INT_PARAM, &dr_force_dns }, + {"enable_keepalive",INT_PARAM, &dr_enable_keepalive}, {0, 0, 0} }; @@ -212,6 +218,25 @@ static inline int rewrite_ruri(struct sip_msg* _m, char* _s) return 0; } + +void dr_keepalive_statechanged(str uri, ka_state state, void *user_attr) { + + ((pgw_t *)user_attr)->state = state; +} + +static int dr_update_keepalive(pgw_t *addrs) +{ + pgw_t *cur; + str owner = str_init("drouting"); + + for(cur = addrs; cur != NULL; cur = cur->next) { + LM_DBG("uri: %.*s\n", cur->ip.len, cur->ip.s); + keepalive_api.add_destination(cur->ip, owner, 0, dr_keepalive_statechanged, cur); + } + + return 0; +} + static inline int dr_reload_data( void ) { rt_data_t *new_data; @@ -247,11 +272,14 @@ static inline int dr_reload_data( void ) if (old_data) free_rt_data( old_data, 1 ); + if (dr_enable_keepalive) { + dr_update_keepalive((*rdata)->pgw_l); + } + return 0; } - static int dr_init(void) { pv_spec_t avp_spec; @@ -361,6 +389,15 @@ static int dr_init(void) return -1; } + if (dr_enable_keepalive) { + LM_DBG("keepalive enabled - try loading keepalive module API\n"); + + if(keepalive_load_api(&keepalive_api) < 0) { + LM_ERR("failed to load keepalive API\n"); + goto error; + } + } + return 0; error: if (ref_lock) { @@ -663,6 +700,7 @@ static int do_routing(struct sip_msg* msg, dr_group_t *drg) static int local_gwlist[DR_MAX_GWLIST]; int gwlist_size; int ret; + pgw_t *dest; ret = -1; @@ -835,15 +873,30 @@ static int do_routing(struct sip_msg* msg, dr_group_t *drg) /* next group starts from i */ j=i; } + + // sort order 0 } else { - for(i=0; ipgwl[i].pgw; + + if (dest->state != KA_STATE_DOWN) { + local_gwlist[j++] = i; + } + } + t = j; } /* do some cleanup first */ destroy_avps( ruri_avp.type, ruri_avp.name, 1); + if (j == 0) { + LM_WARN("no destinations available\n"); + ret = -1; + goto error2; + } + /* push gwlist into avps in reverse order */ for( j=t-1 ; j>=1 ; j-- ) { /* build uri*/ diff --git a/src/modules/drouting/prefix_tree.h b/src/modules/drouting/prefix_tree.h index 34abc7ca84f..097f6ae8c9e 100644 --- a/src/modules/drouting/prefix_tree.h +++ b/src/modules/drouting/prefix_tree.h @@ -32,6 +32,7 @@ #include "../../core/str.h" #include "../../core/ip_addr.h" +#include "../keepalive/api.h" #include "dr_time.h" #define PTREE_CHILDREN 13 //decimal digits, '*', '#', '+' @@ -67,6 +68,9 @@ typedef struct pgw_ { str ip; int type; str attrs; + // gateway state (see keepalive module) + ka_state state; + struct pgw_ *next; }pgw_t; diff --git a/src/modules/drouting/routing.c b/src/modules/drouting/routing.c index a201afc7589..221113f6ec6 100644 --- a/src/modules/drouting/routing.c +++ b/src/modules/drouting/routing.c @@ -324,6 +324,8 @@ add_dst( pgw->id = id; pgw->strip = strip; pgw->type = type; + // by default, the destination is considered up + pgw->state = KA_STATE_UP; /* add address in the list */ if(pgw->ip.len<5 || (strncasecmp("sip:", ip, 4)