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)