ソースを参照

drouting: pull out unavailable destinations for sort_order 1 and 2

- destinations are monitored with keepalive module (when 'enable_keepalive' option is set)
- it was already supported for sort_order 0 in a previous commit
Guillaume Bour 8 年 前
コミット
9875e64a95
2 ファイル変更42 行追加29 行削除
  1. 3 6
      src/modules/drouting/doc/drouting_admin.xml
  2. 39 23
      src/modules/drouting/drouting.c

+ 3 - 6
src/modules/drouting/doc/drouting_admin.xml

@@ -935,7 +935,7 @@ modparam("drouting", "drl_table", "my_gw_lists")
 		</listitem>
 		</listitem>
 		<listitem>
 		<listitem>
 			<emphasis>1</emphasis> - the destinations from each group are
 			<emphasis>1</emphasis> - the destinations from each group are
-			randomly arranged (only the two elements are randomly selected);
+			randomly arranged (only the two first elements are randomly selected);
 			groups do maintain their order (as given); the resulting list is 
 			groups do maintain their order (as given); the resulting list is 
 			used (with all the defined destinations).
 			used (with all the defined destinations).
 			Ex: 1,2;3,4,5;6 -> randomizer -> 
 			Ex: 1,2;3,4,5;6 -> randomizer -> 
@@ -1147,11 +1147,8 @@ modparam("drouting", "force_dns", 0)
 		<para>
 		<para>
 		Enable monitoring of GW/destinations using keepalive module.
 		Enable monitoring of GW/destinations using keepalive module.
 		Destinations found unavailable will not be used on do_routing() call.
 		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>
+
 		<para>
 		<para>
 		<emphasis>Default value is <quote>0 (disabled)</quote>.
 		<emphasis>Default value is <quote>0 (disabled)</quote>.
 		</emphasis>
 		</emphasis>

+ 39 - 23
src/modules/drouting/drouting.c

@@ -671,12 +671,12 @@ static int use_next_gw(struct sip_msg* msg)
 	return 1;
 	return 1;
 }
 }
 
 
-int dr_already_choosen(rt_info_t* rt_info, int* local_gwlist, int lgw_size, int check)
+int dr_already_choosen(rt_info_t* rt_info, int *active_gwlist, int* local_gwlist, int lgw_size, int check)
 {
 {
 	int l;
 	int l;
 
 
 	for ( l = 0; l<lgw_size; l++ ) {
 	for ( l = 0; l<lgw_size; l++ ) {
-		if ( rt_info->pgwl[local_gwlist[l]].pgw == rt_info->pgwl[check].pgw ) {
+		if ( rt_info->pgwl[active_gwlist[local_gwlist[l]]].pgw == rt_info->pgwl[check].pgw ) {
 			LM_INFO("Gateway already chosen %.*s, local_gwlist[%d]=%d, %d\n",
 			LM_INFO("Gateway already chosen %.*s, local_gwlist[%d]=%d, %d\n",
 					rt_info->pgwl[check].pgw->ip.len, rt_info->pgwl[check].pgw->ip.s, l, local_gwlist[l], check);
 					rt_info->pgwl[check].pgw->ip.len, rt_info->pgwl[check].pgw->ip.s, l, local_gwlist[l], check);
 			return 1;
 			return 1;
@@ -697,6 +697,7 @@ static int do_routing(struct sip_msg* msg, dr_group_t *drg)
 	int_str val;
 	int_str val;
 	struct usr_avp *avp;
 	struct usr_avp *avp;
 #define DR_MAX_GWLIST	32
 #define DR_MAX_GWLIST	32
+	static int active_gwlist[DR_MAX_GWLIST];
 	static int local_gwlist[DR_MAX_GWLIST];
 	static int local_gwlist[DR_MAX_GWLIST];
 	int gwlist_size;
 	int gwlist_size;
 	int ret;
 	int ret;
@@ -794,6 +795,24 @@ again:
 	gwlist_size
 	gwlist_size
 		= (rt_info->pgwa_len>DR_MAX_GWLIST)?DR_MAX_GWLIST:rt_info->pgwa_len;
 		= (rt_info->pgwa_len>DR_MAX_GWLIST)?DR_MAX_GWLIST:rt_info->pgwa_len;
 	
 	
+	// we filter out inactive gateways
+	for(i=0,j=0; i < gwlist_size; i++) {
+		dest = rt_info->pgwl[i].pgw;
+
+		if (dest->state != KA_STATE_DOWN) {
+			active_gwlist[j++] = i;
+		}
+	}
+	// updating gwlist_size value
+	gwlist_size = j;
+
+	if (gwlist_size == 0) {
+		LM_WARN("no gateways available (all in state down)\n");
+		ret = -1;
+		goto error2;
+	}
+
+
 	/* set gw order */
 	/* set gw order */
 	if(sort_order>=1&&gwlist_size>1)
 	if(sort_order>=1&&gwlist_size>1)
 	{
 	{
@@ -803,7 +822,7 @@ again:
 		{
 		{
 			/* identify the group: [j..i) */
 			/* identify the group: [j..i) */
 			for(i=j+1; i<gwlist_size; i++)
 			for(i=j+1; i<gwlist_size; i++)
-				if(rt_info->pgwl[j].grpid!=rt_info->pgwl[i].grpid)
+				if(rt_info->pgwl[active_gwlist[j]].grpid!=rt_info->pgwl[active_gwlist[i]].grpid)
 					break;
 					break;
 			if(i-j==1)
 			if(i-j==1)
 			{
 			{
@@ -853,7 +872,7 @@ again:
 					/* check if all in the current set were already chosen */
 					/* check if all in the current set were already chosen */
 					if (i-j <= t-1) {
 					if (i-j <= t-1) {
 						for( l = j; l< i; l++) {
 						for( l = j; l< i; l++) {
-							if ( ! dr_already_choosen(rt_info, local_gwlist, t-1, l) )
+							if ( ! dr_already_choosen(rt_info, active_gwlist, local_gwlist, t-1, active_gwlist[l]) )
 								break;
 								break;
 						}
 						}
 						if ( l == i ) {
 						if ( l == i ) {
@@ -862,12 +881,12 @@ again:
 							j=i; continue;
 							j=i; continue;
 						}
 						}
 					}
 					}
-					while ( dr_already_choosen(rt_info, local_gwlist, t-1, local_gwlist[t-1]) ) {
+					while ( dr_already_choosen(rt_info, active_gwlist, local_gwlist, t-1, active_gwlist[local_gwlist[t-1]]) ) {
 						local_gwlist[t-1]   = j + kam_rand()%(i-j);
 						local_gwlist[t-1]   = j + kam_rand()%(i-j);
 					}
 					}
 				}
 				}
-				LM_DBG("The %d gateway is %.*s [%d]\n", t, rt_info->pgwl[local_gwlist[t-1]].pgw->ip.len,
-						rt_info->pgwl[local_gwlist[t-1]].pgw->ip.s, local_gwlist[t-1]);
+				LM_DBG("The %d gateway is %.*s [%d]\n", t, rt_info->pgwl[active_gwlist[local_gwlist[t-1]]].pgw->ip.len,
+						rt_info->pgwl[active_gwlist[local_gwlist[t-1]]].pgw->ip.s, local_gwlist[t-1]);
 			}
 			}
 
 
 			/* next group starts from i */
 			/* next group starts from i */
@@ -878,13 +897,10 @@ again:
 	} else {
 	} else {
 		LM_DBG("sort order 0\n");
 		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;
-			}
+		for(i=0; i<gwlist_size; i++) {
+			local_gwlist[i] = i;
 		}
 		}
+
 		t = j;
 		t = j;
 	}
 	}
 
 
@@ -899,10 +915,10 @@ again:
 
 
 	/* push gwlist into avps in reverse order */
 	/* push gwlist into avps in reverse order */
 	for( j=t-1 ; j>=1 ; j-- ) {
 	for( j=t-1 ; j>=1 ; j-- ) {
-		/* build uri*/
-		ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[j]].pgw->strip,
-				&rt_info->pgwl[local_gwlist[j]].pgw->pri,
-				&rt_info->pgwl[local_gwlist[j]].pgw->ip);
+		/* build uri */
+		ruri = build_ruri(&uri, rt_info->pgwl[active_gwlist[local_gwlist[j]]].pgw->strip,
+				&rt_info->pgwl[active_gwlist[local_gwlist[j]]].pgw->pri,
+				&rt_info->pgwl[active_gwlist[local_gwlist[j]]].pgw->ip);
 		if (ruri==0) {
 		if (ruri==0) {
 			LM_ERR("failed to build avp ruri\n");
 			LM_ERR("failed to build avp ruri\n");
 			goto error2;
 			goto error2;
@@ -918,7 +934,7 @@ again:
 		}
 		}
 		pkg_free(ruri->s);
 		pkg_free(ruri->s);
 		/* add attrs avp */
 		/* add attrs avp */
-		val.s = rt_info->pgwl[local_gwlist[j]].pgw->attrs;
+		val.s = rt_info->pgwl[active_gwlist[local_gwlist[j]]].pgw->attrs;
 		LM_DBG("setting attr [%.*s] as avp\n",val.s.len,val.s.s);
 		LM_DBG("setting attr [%.*s] as avp\n",val.s.len,val.s.s);
 		if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
 		if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
 			LM_ERR("failed to insert attrs avp\n");
 			LM_ERR("failed to insert attrs avp\n");
@@ -927,12 +943,12 @@ again:
 	}
 	}
 
 
 	/* use first GW in RURI */
 	/* use first GW in RURI */
-	ruri = build_ruri(&uri, rt_info->pgwl[local_gwlist[0]].pgw->strip,
-			&rt_info->pgwl[local_gwlist[0]].pgw->pri,
-			&rt_info->pgwl[local_gwlist[0]].pgw->ip);
+	ruri = build_ruri(&uri, rt_info->pgwl[active_gwlist[local_gwlist[0]]].pgw->strip,
+			&rt_info->pgwl[active_gwlist[local_gwlist[0]]].pgw->pri,
+			&rt_info->pgwl[active_gwlist[local_gwlist[0]]].pgw->ip);
 
 
 	/* add attrs avp */
 	/* add attrs avp */
-	val.s = rt_info->pgwl[local_gwlist[0]].pgw->attrs;
+	val.s = rt_info->pgwl[active_gwlist[local_gwlist[0]]].pgw->attrs;
 	LM_DBG("setting attr [%.*s] as for ruri\n",val.s.len,val.s.s);
 	LM_DBG("setting attr [%.*s] as for ruri\n",val.s.len,val.s.s);
 	if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
 	if (add_avp( AVP_VAL_STR|(attrs_avp.type),attrs_avp.name, val)!=0 ) {
 		LM_ERR("failed to insert attrs avp\n");
 		LM_ERR("failed to insert attrs avp\n");
@@ -950,7 +966,7 @@ again:
 		goto error1;
 		goto error1;
 	}
 	}
 	LM_DBG("setting the gw [%d] as ruri \"%.*s\"\n",
 	LM_DBG("setting the gw [%d] as ruri \"%.*s\"\n",
-			local_gwlist[0], ruri->len, ruri->s);
+			active_gwlist[local_gwlist[0]], ruri->len, ruri->s);
 	if (msg->new_uri.s)
 	if (msg->new_uri.s)
 		pkg_free(msg->new_uri.s);
 		pkg_free(msg->new_uri.s);
 	msg->new_uri = *ruri;
 	msg->new_uri = *ruri;