浏览代码

drouting: use keepalive to monitor GW/destinations

- it works for sort_order 0 only
Guillaume Bour 8 年之前
父节点
当前提交
4e1437aacd

+ 24 - 0
src/modules/drouting/doc/drouting_admin.xml

@@ -1137,6 +1137,30 @@ modparam("drouting", "fetch_rows", 1500)
 		<programlisting format="linespecific">
 ...
 modparam("drouting", "force_dns", 0)
+...
+	</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>enable_keepalive</varname> (int)</title>
+		<para>
+		Enable monitoring of GW/destinations using keepalive module.
+		Destinations found unavailable will not be used on do_routing() call.
+		</para>
+		<para>
+		NOTE: this option is only compatible with <em>sort_order</em> 0 currently.
+		With sort_order value of 1 or 2, destinations status will simply be ignored.
+		</para>
+		<para>
+		<emphasis>Default value is <quote>0 (disabled)</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>enable_keepalive</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("drouting", "enable_keepalive", 1)
 ...
 	</programlisting>
 		</example>

+ 3 - 0
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)

+ 57 - 4
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 @@ again:
 			/* next group starts from i */
 			j=i;
 		}
+
+	// sort order 0
 	} else {
-		for(i=0; i<gwlist_size; i++)
-			local_gwlist[i] = i;
-		t = i;
+		LM_DBG("sort order 0\n");
+
+		for(i=0,j=0; i<gwlist_size; i++) {
+			dest = rt_info->pgwl[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*/

+ 4 - 0
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;
 

+ 2 - 0
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)