|
@@ -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);
|