Browse Source

dispatcher: Adding new feature for counting successful requests before placing destination from inactive to active state (code)

alezzandro 10 năm trước cách đây
mục cha
commit
2e567ce1ba

+ 3 - 0
modules/dispatcher/config.c

@@ -32,6 +32,7 @@
 
 struct cfg_group_dispatcher	default_dispatcher_cfg = {
 		3,	/* Probing threshold */	
+		3,      /* Inactive threshold */
 		{0,0}	/* reply codes */
 	    };
 
@@ -40,6 +41,8 @@ void	*dispatcher_cfg = &default_dispatcher_cfg;
 cfg_def_t	dispatcher_cfg_def[] = {
 	{"probing_threshold",		CFG_VAR_INT | CFG_ATOMIC, 	0, 0, 0, 0,
 		"Number of failed requests, before a destination is set to probing."},
+	{"inactive_threshold",           CFG_VAR_INT | CFG_ATOMIC,       0, 0, 0, 0,
+                "Number of successful requests, before a destination is set to active."},
 	{"ping_reply_codes",		CFG_VAR_STR | CFG_CB_ONLY_ONCE ,			0, 0, 0, ds_ping_reply_codes_update,
 		"Additional, valid reply codes for the OPTIONS Pinger. Default is \"\""},
 	{0, 0, 0, 0, 0, 0}

+ 1 - 0
modules/dispatcher/config.h

@@ -28,6 +28,7 @@
 
 struct cfg_group_dispatcher {
 	int probing_threshold;
+	int inactive_threshold;
 	str ds_ping_reply_codes_str;
 };
 

+ 68 - 12
modules/dispatcher/dispatch.c

@@ -39,6 +39,7 @@
  * 			   added DB support to load/reload data(ancuta)
  * 2007-09-17  added list-file support for reload data (carstenbock)
  * 2014-12-23  Corrected misspelled words in some variables' name (alezzandro)
+ * 2014-12-23  Added support for custom number of successful probing requests before moving a destination from 'inactive' to 'active' state (alezzandro)
  */
 
 /*! \file
@@ -2188,7 +2189,43 @@ int ds_mark_dst(struct sip_msg *msg, int state)
 }
 
 /**
- *
+ * Get state for given destination
+ */
+int ds_get_state(int group, str *address)
+{
+	int i=0;
+	int state = 0;
+	ds_set_t *idx = NULL;
+
+	if(_ds_list==NULL || _ds_list_nr<=0)
+	{
+		LM_ERR("the list is null\n");
+		return -1;
+	}
+
+	/* get the index of the set */
+	if(ds_get_index(group, &idx)!=0)
+	{
+		LM_ERR("destination set [%d] not found\n", group);
+		return -1;
+	}
+
+	while(i<idx->nr)
+	{
+		if(idx->dlist[i].uri.len==address->len
+				&& strncasecmp(idx->dlist[i].uri.s, address->s,
+					address->len)==0)
+		{
+			/* destination address found */
+			state = idx->dlist[i].flags;
+		}
+		i++;
+	}
+	return state;
+}
+
+/**
+ * Update destionation's state
  */
 int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
 {
@@ -2220,7 +2257,10 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
 
 			/* reset the bits used for states */
 			idx->dlist[i].flags &= ~(DS_STATES_ALL);
-
+			
+			/* we need the initial state for inactive counter */
+			int init_state = state;
+			
 			if((state & DS_TRYING_DST) && (old_state & DS_INACTIVE_DST))
 			{
 				/* old state is inactive, new state is trying => keep it inactive
@@ -2236,18 +2276,33 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
 			} else {
 				idx->dlist[i].flags |= state;
 			}
-
+			
 			if(state & DS_TRYING_DST)
 			{
-				idx->dlist[i].failure_count++;
-				if (idx->dlist[i].failure_count >= probing_threshold)
+				idx->dlist[i].message_count++;
+				/* Destination is not replying.. Increasing failure counter */
+				if (idx->dlist[i].message_count >= probing_threshold)
 				{
+					/* Destionation has too much lost messages.. Bringing it to inactive state */
 					idx->dlist[i].flags &= ~DS_TRYING_DST;
 					idx->dlist[i].flags |= DS_INACTIVE_DST;
-					idx->dlist[i].failure_count = 0;
+					idx->dlist[i].message_count = 0;
 				}
 			} else {
-				idx->dlist[i].failure_count = 0;
+				if(!(init_state & DS_TRYING_DST) && (old_state & DS_INACTIVE_DST)){
+					idx->dlist[i].message_count++;
+					/* Destination was inactive but it is just replying.. Increasing successful counter */
+					if (idx->dlist[i].message_count < inactive_threshold)
+					{
+						/* Destination has not enough successful replies.. Leaving it into inactive state */
+						idx->dlist[i].flags |= DS_INACTIVE_DST;
+					}else{
+						/* Destination has enough replied messages.. Bringing it to active state */
+						idx->dlist[i].message_count = 0;
+					}
+				}else{ 
+					idx->dlist[i].message_count = 0;
+				}
 			}
 
 			if (!ds_skip_dst(old_state) && ds_skip_dst(idx->dlist[i].flags))
@@ -2376,9 +2431,9 @@ int ds_print_list(FILE *fout)
 			else if (list->dlist[j].flags&DS_TRYING_DST) {
 				fprintf(fout, "    Trying");
 				/* print the tries for this host. */
-				if (list->dlist[j].failure_count > 0) {
+				if (list->dlist[j].message_count > 0) {
 					fprintf(fout, " (Fail %d/%d)",
-							list->dlist[j].failure_count,
+							list->dlist[j].message_count,
 							probing_threshold);
 				} else {
 					fprintf(fout, "           ");
@@ -2608,7 +2663,8 @@ static void ds_options_callback( struct cell *t, int type,
 		state = 0;
 		if (ds_probing_mode==DS_PROBE_ALL)
 			state |= DS_PROBING_DST;
-		if (ds_update_state(fmsg, group, &uri, state) != 0)
+		/* Check if in the meantime someone disabled the target through RPC or MI */
+		if (!(ds_get_state(group, &uri) & DS_DISABLED_DST) && ds_update_state(fmsg, group, &uri, state) != 0)
 		{
 			LM_ERR("Setting the state failed (%.*s, group %d)\n", uri.len,
 					uri.s, group);
@@ -2617,8 +2673,8 @@ static void ds_options_callback( struct cell *t, int type,
 		state = DS_TRYING_DST;
 		if (ds_probing_mode!=DS_PROBE_NONE)
 			state |= DS_PROBING_DST;
-
-		if (ds_update_state(fmsg, group, &uri, state) != 0)
+		/* Check if in the meantime someone disabled the target through RPC or MI */
+		if (!(ds_get_state(group, &uri) & DS_DISABLED_DST) && ds_update_state(fmsg, group, &uri, state) != 0)
 		{
 			LM_ERR("Setting the probing state failed (%.*s, group %d)\n",
 					uri.len, uri.s, group);

+ 4 - 3
modules/dispatcher/dispatch.h

@@ -31,6 +31,7 @@
  * 2007-05-08  Ported the changes to SVN-Trunk and renamed ds_is_domain
  *		to ds_is_from_list.
  * 2014-12-23  Corrected misspelled words in some variables' name (alezzandro) 
+ * 2014-12-23  Added support for custom number of successful probing requests before moving a destination from 'inactive' to 'active' state (alezzandro)
  */
 
 /*! \file
@@ -101,8 +102,8 @@ extern pv_spec_t ds_attrs_pv;
 extern struct tm_binds tmb;
 extern str ds_ping_method;
 extern str ds_ping_from;
-extern int probing_threshold; /*!< number of failed requests,
-								 before a destination is taken into probing */ 
+extern int probing_threshold; /*!< number of failed requests, before a destination is taken into probing */
+extern int inactive_threshold; /*!< number of successful requests, before a destination is taken into active */
 extern int ds_probing_mode;
 extern str ds_outbound_proxy;
 extern str ds_default_socket;
@@ -173,7 +174,7 @@ typedef struct _ds_dest
 	struct ip_addr ip_address; 	/*!< IP-Address of the entry */
 	unsigned short int port; 	/*!< Port of the URI */
 	unsigned short int proto; 	/*!< Protocol of the URI */
-	int failure_count;
+	int message_count;
 	struct _ds_dest *next;
 } ds_dest_t;
 

+ 1 - 0
modules/dispatcher/dispatcher.c

@@ -35,6 +35,7 @@
  * 			   reload triggered from ds_reload MI_Command (ancuta)
  * 2014-12-12  Added "ds_list_exist" function
  * 2014-12-23  Corrected misspelled words in some variables' name (alezzandro)
+ * 2014-12-23  Added support for custom number of successful probing requests before moving a destination from 'inactive' to 'active' state (alezzandro)
  */
 
 /*! \file