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)
+...
+
+
+
+
+
+ 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)
.
+
+
+
+ Set enable_keepalive 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)