Browse code

dispatcher(k): new state trying for destination addresses

- the state trying (t) is a transition between active to inactive, when
inactive state is wanted after a certain number of failures specified
in probing threshold
- when in trying state, the destination is still selected, but
additional settings of trying state will increment an internal failure
counter which results in setting inactive state when probing threshold
is matched
- the functionality was before based on probing mode, but since 3.2
probing is not longer related to destination selection. This will
provide back the lost functionality
- ds_mark_dst(x) can have as parameter a combination between state and
probing mode, such as 'ip' - inactive and probing, or ap - active and
probing, or 'tp' - trying and probing

Daniel-Constantin Mierla authored on 27/10/2011 14:00:55
Showing 3 changed files
... ...
@@ -142,7 +142,7 @@ int ds_print_sets(void)
142 142
 
143 143
 	if(_ds_list==NULL)
144 144
 		return -1;
145
-	
145
+
146 146
 	/* get the index of the set */
147 147
 	si = _ds_list;
148 148
 	while(si)
... ...
@@ -177,7 +177,7 @@ int init_data(void)
177 177
 	}
178 178
 	ds_lists[0] = ds_lists[1] = 0;
179 179
 
180
-	
180
+
181 181
 	p = (int*)shm_malloc(3*sizeof(int));
182 182
 	if(!p)
183 183
 	{
... ...
@@ -247,7 +247,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
247 247
 	ds_set_t  *sp = NULL;
248 248
 	ds_dest_t *dp0 = NULL;
249 249
 	ds_dest_t *dp1 = NULL;
250
-	
250
+
251 251
 	/* For DNS-Lookups */
252 252
 	static char hn[256];
253 253
 	struct hostent* he;
... ...
@@ -261,7 +261,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
261 261
 		LM_ERR("bad uri [%.*s]\n", uri.len, uri.s);
262 262
 		goto err;
263 263
 	}
264
-	
264
+
265 265
 	/* get dest set */
266 266
 	sp = ds_lists[list_idx];
267 267
 	while(sp)
... ...
@@ -279,7 +279,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
279 279
 			LM_ERR("no more memory.\n");
280 280
 			goto err;
281 281
 		}
282
-		
282
+
283 283
 		memset(sp, 0, sizeof(ds_set_t));
284 284
 		sp->next = ds_lists[list_idx];
285 285
 		ds_lists[list_idx] = sp;
... ...
@@ -321,7 +321,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
321 321
 	 * make a copy here. */
322 322
 	strncpy(hn, puri.host.s, puri.host.len);
323 323
 	hn[puri.host.len]='\0';
324
-		
324
+
325 325
 	/* Do a DNS-Lookup for the Host-Name: */
326 326
 	he=resolvehost(hn);
327 327
 	if (he==0)
... ...
@@ -331,7 +331,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
331 331
 	}
332 332
 	/* Free the hostname */
333 333
 	hostent2ip_addr(&dp->ip_address, he, 0);
334
-		
334
+
335 335
 	/* Copy the Port out of the URI: */
336 336
 	dp->port = puri.port_no;		
337 337
 
... ...
@@ -359,7 +359,7 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
359 359
 	}
360 360
 
361 361
 	LM_DBG("dest [%d/%d] <%.*s>\n", sp->id, sp->nr, dp->uri.len, dp->uri.s);
362
-	
362
+
363 363
 	return 0;
364 364
 err:
365 365
 	/* free allocated memory */
... ...
@@ -456,7 +456,7 @@ int reindex_dests(int list_idx, int setn)
456 456
 
457 457
 			dp = sp->dlist;
458 458
 			sp->dlist = dp->next;
459
-			
459
+
460 460
 			shm_free(dp);
461 461
 			dp=NULL;
462 462
 		}
... ...
@@ -496,7 +496,7 @@ int ds_load_list(char *lfile)
496 496
 	{
497 497
 		LM_ERR("can't open list file [%s]\n", lfile);
498 498
 		return -1;
499
-		
499
+
500 500
 	}
501 501
 
502 502
 	id = setn = flags = priority = 0;
... ...
@@ -587,7 +587,7 @@ add_destination:
587 587
 next_line:
588 588
 		p = fgets(line, 256, f);
589 589
 	}
590
-		
590
+
591 591
 	if(reindex_dests(*next_idx, setn)!=0){
592 592
 		LM_ERR("error on reindex\n");
593 593
 		goto error;
... ...
@@ -646,20 +646,20 @@ int init_ds_db(void)
646 646
 		LM_ERR("invalid database name\n");
647 647
 		return -1;
648 648
 	}
649
-	
649
+
650 650
 	/* Find a database module */
651 651
 	if (db_bind_mod(&ds_db_url, &ds_dbf) < 0)
652 652
 	{
653 653
 		LM_ERR("Unable to bind to a database driver\n");
654 654
 		return -1;
655 655
 	}
656
-	
656
+
657 657
 	if(ds_connect_db()!=0){
658
-		
658
+
659 659
 		LM_ERR("unable to connect to the database\n");
660 660
 		return -1;
661 661
 	}
662
-	
662
+
663 663
 	_ds_table_version = db_table_version(&ds_dbf, ds_db_handle, &ds_table_name);
664 664
 	if (_ds_table_version < 0)
665 665
 	{
... ...
@@ -670,9 +670,9 @@ int init_ds_db(void)
670 670
 			&& _ds_table_version != DS_TABLE_VERSION3
671 671
 			&& _ds_table_version != DS_TABLE_VERSION4) {
672 672
 		LM_ERR("invalid table version (found %d , required %d, %d, %d or %d)\n"
673
-			"(use kamdbctl reinit)\n",
674
-			_ds_table_version, DS_TABLE_VERSION, DS_TABLE_VERSION2,
675
-			DS_TABLE_VERSION3, DS_TABLE_VERSION4);
673
+				"(use kamdbctl reinit)\n",
674
+				_ds_table_version, DS_TABLE_VERSION, DS_TABLE_VERSION2,
675
+				DS_TABLE_VERSION3, DS_TABLE_VERSION4);
676 676
 		return -1;
677 677
 	}
678 678
 
... ...
@@ -695,11 +695,11 @@ int ds_load_db(void)
695 695
 	db1_res_t * res;
696 696
 	db_val_t * values;
697 697
 	db_row_t * rows;
698
-	
698
+
699 699
 	db_key_t query_cols[5] = {&ds_set_id_col, &ds_dest_uri_col,
700
-				&ds_dest_flags_col, &ds_dest_priority_col,
701
-				&ds_dest_attrs_col};
702
-	
700
+		&ds_dest_flags_col, &ds_dest_priority_col,
701
+		&ds_dest_attrs_col};
702
+
703 703
 	nrcols = 2;
704 704
 	if(_ds_table_version == DS_TABLE_VERSION2)
705 705
 		nrcols = 3;
... ...
@@ -715,8 +715,8 @@ int ds_load_db(void)
715 715
 	}
716 716
 
717 717
 	if(ds_db_handle == NULL){
718
-			LM_ERR("invalid DB handler\n");
719
-			return -1;
718
+		LM_ERR("invalid DB handler\n");
719
+		return -1;
720 720
 	}
721 721
 
722 722
 	if (ds_dbf.use_table(ds_db_handle, &ds_table_name) < 0)
... ...
@@ -740,7 +740,7 @@ int ds_load_db(void)
740 740
 	setn = 0;
741 741
 	*next_idx = (*crt_idx + 1)%2;
742 742
 	destroy_list(*next_idx);
743
-	
743
+
744 744
 	for(i=0; i<nr_rows; i++)
745 745
 	{
746 746
 		values = ROW_VALUES(rows+i);
... ...
@@ -820,16 +820,16 @@ void destroy_list(int list_id)
820 820
 		for(dest = sp->dlist; dest!= NULL; dest=dest->next)
821 821
 		{
822 822
 			if(dest->uri.s!=NULL)
823
-   			{
824
-   				shm_free(dest->uri.s);
825
-   				dest->uri.s = NULL;
826
-	   		}
823
+			{
824
+				shm_free(dest->uri.s);
825
+				dest->uri.s = NULL;
826
+			}
827 827
 		}
828 828
 		if (sp->dlist != NULL)
829 829
 			shm_free(sp->dlist);
830 830
 		sp = sp->next;
831 831
 	}
832
-	
832
+
833 833
 	ds_lists[list_id]  = NULL;
834 834
 }
835 835
 
... ...
@@ -875,7 +875,7 @@ unsigned int ds_get_hash(str *x, str *y)
875 875
 				h+=v^(v>>3);
876 876
 			}
877 877
 		}
878
-	
878
+
879 879
 		v=0;
880 880
 		for (;p<(y->s+y->len); p++)
881 881
 		{
... ...
@@ -905,10 +905,10 @@ unsigned int ds_get_hash(str *x, str *y)
905 905
  * \return: -1 on error, 0 on success
906 906
  */
907 907
 static inline int get_uri_hash_keys(str* key1, str* key2,
908
-							str* uri, struct sip_uri* parsed_uri, int flags)
908
+		str* uri, struct sip_uri* parsed_uri, int flags)
909 909
 {
910 910
 	struct sip_uri tmp_p_uri; /* used only if parsed_uri==0 */
911
-	
911
+
912 912
 	if (parsed_uri==0)
913 913
 	{
914 914
 		if (parse_uri(uri->s, uri->len, &tmp_p_uri)<0)
... ...
@@ -921,11 +921,11 @@ static inline int get_uri_hash_keys(str* key1, str* key2,
921 921
 	/* uri sanity checks */
922 922
 	if (parsed_uri->host.s==0)
923 923
 	{
924
-			LM_ERR("invalid uri, no host present: %.*s\n",
925
-					uri->len, uri->len?uri->s:"");
926
-			goto error;
924
+		LM_ERR("invalid uri, no host present: %.*s\n",
925
+				uri->len, uri->len?uri->s:"");
926
+		goto error;
927 927
 	}
928
-	
928
+
929 929
 	/* we want: user@host:port if port !=5060
930 930
 	 *          user@host if port==5060
931 931
 	 *          user if the user flag is set*/
... ...
@@ -962,31 +962,31 @@ int ds_hash_fromuri(struct sip_msg *msg, unsigned int *hash)
962 962
 	str from;
963 963
 	str key1;
964 964
 	str key2;
965
-	
965
+
966 966
 	if(msg==NULL || hash == NULL)
967 967
 	{
968 968
 		LM_ERR("bad parameters\n");
969 969
 		return -1;
970 970
 	}
971
-	
971
+
972 972
 	if(parse_from_header(msg)<0)
973 973
 	{
974 974
 		LM_ERR("cannot parse From hdr\n");
975 975
 		return -1;
976 976
 	}
977
-	
977
+
978 978
 	if(msg->from==NULL || get_from(msg)==NULL)
979 979
 	{
980 980
 		LM_ERR("cannot get From uri\n");
981 981
 		return -1;
982 982
 	}
983
-	
983
+
984 984
 	from   = get_from(msg)->uri;
985 985
 	trim(&from);
986 986
 	if (get_uri_hash_keys(&key1, &key2, &from, 0, ds_flags)<0)
987 987
 		return -1;
988 988
 	*hash = ds_get_hash(&key1, &key2);
989
-	
989
+
990 990
 	return 0;
991 991
 }
992 992
 
... ...
@@ -999,7 +999,7 @@ int ds_hash_touri(struct sip_msg *msg, unsigned int *hash)
999 999
 	str to;
1000 1000
 	str key1;
1001 1001
 	str key2;
1002
-	
1002
+
1003 1003
 	if(msg==NULL || hash == NULL)
1004 1004
 	{
1005 1005
 		LM_ERR("bad parameters\n");
... ...
@@ -1011,15 +1011,15 @@ int ds_hash_touri(struct sip_msg *msg, unsigned int *hash)
1011 1011
 		LM_ERR("cannot parse To hdr\n");
1012 1012
 		return -1;
1013 1013
 	}
1014
-	
1015
-	
1014
+
1015
+
1016 1016
 	to   = get_to(msg)->uri;
1017 1017
 	trim(&to);
1018
-	
1018
+
1019 1019
 	if (get_uri_hash_keys(&key1, &key2, &to, 0, ds_flags)<0)
1020 1020
 		return -1;
1021 1021
 	*hash = ds_get_hash(&key1, &key2);
1022
-	
1022
+
1023 1023
 	return 0;
1024 1024
 }
1025 1025
 
... ...
@@ -1035,20 +1035,20 @@ int ds_hash_callid(struct sip_msg *msg, unsigned int *hash)
1035 1035
 		LM_ERR("bad parameters\n");
1036 1036
 		return -1;
1037 1037
 	}
1038
-	
1038
+
1039 1039
 	if(msg->callid==NULL && ((parse_headers(msg, HDR_CALLID_F, 0)==-1) ||
1040 1040
 				(msg->callid==NULL)) )
1041 1041
 	{
1042 1042
 		LM_ERR("cannot parse Call-Id\n");
1043 1043
 		return -1;
1044 1044
 	}
1045
-	
1045
+
1046 1046
 	cid.s   = msg->callid->body.s;
1047 1047
 	cid.len = msg->callid->body.len;
1048 1048
 	trim(&cid);
1049
-	
1049
+
1050 1050
 	*hash = ds_get_hash(&cid, NULL);
1051
-	
1051
+
1052 1052
 	return 0;
1053 1053
 }
1054 1054
 
... ...
@@ -1061,8 +1061,8 @@ int ds_hash_ruri(struct sip_msg *msg, unsigned int *hash)
1061 1061
 	str* uri;
1062 1062
 	str key1;
1063 1063
 	str key2;
1064
-	
1065
-	
1064
+
1065
+
1066 1066
 	if(msg==NULL || hash == NULL)
1067 1067
 	{
1068 1068
 		LM_ERR("bad parameters\n");
... ...
@@ -1072,11 +1072,11 @@ int ds_hash_ruri(struct sip_msg *msg, unsigned int *hash)
1072 1072
 		LM_ERR("bad request uri\n");
1073 1073
 		return -1;
1074 1074
 	}
1075
-	
1075
+
1076 1076
 	uri=GET_RURI(msg);
1077 1077
 	if (get_uri_hash_keys(&key1, &key2, uri, &msg->parsed_uri, ds_flags)<0)
1078 1078
 		return -1;
1079
-	
1079
+
1080 1080
 	*hash = ds_get_hash(&key1, &key2);
1081 1081
 	return 0;
1082 1082
 }
... ...
@@ -1092,7 +1092,7 @@ int ds_hash_authusername(struct sip_msg *msg, unsigned int *hash)
1092 1092
 	str username = {0, 0};
1093 1093
 	/* The Credentials from this request */
1094 1094
 	auth_body_t* cred;
1095
-	
1095
+
1096 1096
 	if(msg==NULL || hash == NULL)
1097 1097
 	{
1098 1098
 		LM_ERR("bad parameters\n");
... ...
@@ -1133,14 +1133,14 @@ int ds_hash_authusername(struct sip_msg *msg, unsigned int *hash)
1133 1133
 		LM_ERR("No Authorization-Username or Credentials!\n");
1134 1134
 		return 1;
1135 1135
 	}
1136
-	
1136
+
1137 1137
 	username.s = cred->digest.username.user.s;
1138 1138
 	username.len = cred->digest.username.user.len;
1139 1139
 
1140 1140
 	trim(&username);
1141
-	
1141
+
1142 1142
 	*hash = ds_get_hash(&username, NULL);
1143
-	
1143
+
1144 1144
 	return 0;
1145 1145
 }
1146 1146
 
... ...
@@ -1152,7 +1152,7 @@ int ds_hash_pvar(struct sip_msg *msg, unsigned int *hash)
1152 1152
 {
1153 1153
 	/* The String to create the hash */
1154 1154
 	str hash_str = {0, 0};
1155
-	
1155
+
1156 1156
 	if(msg==NULL || hash == NULL || hash_param_model == NULL)
1157 1157
 	{
1158 1158
 		LM_ERR("bad parameters\n");
... ...
@@ -1172,7 +1172,7 @@ int ds_hash_pvar(struct sip_msg *msg, unsigned int *hash)
1172 1172
 	LM_DBG("Hashing %.*s!\n", hash_str.len, hash_str.s);
1173 1173
 
1174 1174
 	*hash = ds_get_hash(&hash_str, NULL);
1175
-	
1175
+
1176 1176
 	return 0;
1177 1177
 }
1178 1178
 
... ...
@@ -1182,10 +1182,10 @@ int ds_hash_pvar(struct sip_msg *msg, unsigned int *hash)
1182 1182
 static inline int ds_get_index(int group, ds_set_t **index)
1183 1183
 {
1184 1184
 	ds_set_t *si = NULL;
1185
-	
1185
+
1186 1186
 	if(index==NULL || group<0 || _ds_list==NULL)
1187 1187
 		return -1;
1188
-	
1188
+
1189 1189
 	/* get the index of the set */
1190 1190
 	si = _ds_list;
1191 1191
 	while(si)
... ...
@@ -1246,7 +1246,7 @@ int ds_load_add(struct sip_msg *msg, ds_set_t *dset, int setid, int dst)
1246 1246
 	}
1247 1247
 
1248 1248
 	if(ds_add_cell(_dsht_load, &msg->callid->body,
1249
-			&dset->dlist[dst].attrs.duid, setid)<0)
1249
+				&dset->dlist[dst].attrs.duid, setid)<0)
1250 1250
 	{
1251 1251
 		LM_ERR("cannot add load to %d (%.*s)\n", setid,
1252 1252
 				msg->callid->body.len, msg->callid->body.s);
... ...
@@ -1332,7 +1332,7 @@ int ds_load_replace(struct sip_msg *msg, str *duid)
1332 1332
 	if(ds_load_add(msg, idx, set, newdst)<0)
1333 1333
 	{
1334 1334
 		LM_ERR("unable to replace destination load [%.*s / %.*s]\n",
1335
-			duid->len, duid->s, msg->callid->body.len, msg->callid->body.s);
1335
+				duid->len, duid->s, msg->callid->body.len, msg->callid->body.s);
1336 1336
 		return -1;
1337 1337
 	}
1338 1338
 	return 0;
... ...
@@ -1454,14 +1454,14 @@ int ds_load_state(struct sip_msg *msg, int state)
1454 1454
  */
1455 1455
 int ds_load_update(struct sip_msg *msg)
1456 1456
 {
1457
-    if(parse_headers(msg, HDR_CSEQ_F|HDR_CALLID_F, 0)!=0
1457
+	if(parse_headers(msg, HDR_CSEQ_F|HDR_CALLID_F, 0)!=0
1458 1458
 			|| msg->cseq==NULL || msg->callid==NULL)
1459
-    {
1460
-        LM_ERR("cannot parse cseq and callid headers\n");
1461
-        return -1;
1462
-    }
1459
+	{
1460
+		LM_ERR("cannot parse cseq and callid headers\n");
1461
+		return -1;
1462
+	}
1463 1463
 	if(msg->first_line.type==SIP_REQUEST)
1464
-    {
1464
+	{
1465 1465
 		if(msg->first_line.u.request.method_value==METHOD_BYE
1466 1466
 				|| msg->first_line.u.request.method_value==METHOD_CANCEL)
1467 1467
 		{
... ...
@@ -1488,14 +1488,14 @@ int ds_load_unset(struct sip_msg *msg)
1488 1488
 	struct search_state st;
1489 1489
 	struct usr_avp *prev_avp;
1490 1490
 	int_str avp_value;
1491
-	
1491
+
1492 1492
 	if(dstid_avp_name.n==0)
1493 1493
 		return 0;
1494 1494
 
1495 1495
 	/* for INVITE requests should be called after dst list is built */
1496 1496
 	if(msg->first_line.type==SIP_REQUEST
1497 1497
 			&&  msg->first_line.u.request.method_value==METHOD_INVITE)
1498
-    {
1498
+	{
1499 1499
 		prev_avp = search_first_avp(dstid_avp_type, dstid_avp_name,
1500 1500
 				&avp_value, &st);
1501 1501
 		if(prev_avp==NULL)
... ...
@@ -1528,7 +1528,7 @@ static inline int ds_update_dst(struct sip_msg *msg, str *uri, int mode)
1528 1528
 				LM_ERR("error while setting host\n");
1529 1529
 				return -1;
1530 1530
 			}
1531
-		break;
1531
+			break;
1532 1532
 		default:
1533 1533
 			duri = uri;
1534 1534
 			if (set_dst_uri(msg, uri) < 0) {
... ...
@@ -1536,9 +1536,9 @@ static inline int ds_update_dst(struct sip_msg *msg, str *uri, int mode)
1536 1536
 				return -1;
1537 1537
 			}
1538 1538
 			/* dst_uri changes, so it makes sense to re-use the current uri for
1539
-				forking */
1539
+			   forking */
1540 1540
 			ruri_mark_new(); /* re-use uri for serial forking */
1541
-		break;
1541
+			break;
1542 1542
 	}
1543 1543
 	return 0;
1544 1544
 }
... ...
@@ -1558,7 +1558,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1558 1558
 		LM_ERR("bad parameters\n");
1559 1559
 		return -1;
1560 1560
 	}
1561
-	
1561
+
1562 1562
 	if(_ds_list==NULL || _ds_list_nr<=0)
1563 1563
 	{
1564 1564
 		LM_ERR("no destination sets\n");
... ...
@@ -1572,7 +1572,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1572 1572
 				msg->dst_uri.s);
1573 1573
 		return -1;
1574 1574
 	}
1575
-	
1575
+
1576 1576
 
1577 1577
 	/* get the index of the set */
1578 1578
 	if(ds_get_index(set, &idx)!=0)
... ...
@@ -1580,7 +1580,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1580 1580
 		LM_ERR("destination set [%d] not found\n", set);
1581 1581
 		return -1;
1582 1582
 	}
1583
-	
1583
+
1584 1584
 	LM_DBG("set [%d]\n", set);
1585 1585
 
1586 1586
 	hash = 0;
... ...
@@ -1592,67 +1592,67 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1592 1592
 				LM_ERR("can't get callid hash\n");
1593 1593
 				return -1;
1594 1594
 			}
1595
-		break;
1595
+			break;
1596 1596
 		case 1: /* hash from-uri */
1597 1597
 			if(ds_hash_fromuri(msg, &hash)!=0)
1598 1598
 			{
1599 1599
 				LM_ERR("can't get From uri hash\n");
1600 1600
 				return -1;
1601 1601
 			}
1602
-		break;
1602
+			break;
1603 1603
 		case 2: /* hash to-uri */
1604 1604
 			if(ds_hash_touri(msg, &hash)!=0)
1605 1605
 			{
1606 1606
 				LM_ERR("can't get To uri hash\n");
1607 1607
 				return -1;
1608 1608
 			}
1609
-		break;
1609
+			break;
1610 1610
 		case 3: /* hash r-uri */
1611 1611
 			if (ds_hash_ruri(msg, &hash)!=0)
1612 1612
 			{
1613 1613
 				LM_ERR("can't get ruri hash\n");
1614 1614
 				return -1;
1615 1615
 			}
1616
-		break;
1616
+			break;
1617 1617
 		case DS_ALG_RROBIN: /* round robin */
1618 1618
 			hash = idx->last;
1619 1619
 			idx->last = (idx->last+1) % idx->nr;
1620
-		break;
1620
+			break;
1621 1621
 		case 5: /* hash auth username */
1622 1622
 			i = ds_hash_authusername(msg, &hash);
1623 1623
 			switch (i)
1624 1624
 			{
1625 1625
 				case 0:
1626 1626
 					/* Authorization-Header found: Nothing to be done here */
1627
-				break;
1627
+					break;
1628 1628
 				case 1:
1629 1629
 					/* No Authorization found: Use round robin */
1630 1630
 					hash = idx->last;
1631 1631
 					idx->last = (idx->last+1) % idx->nr;
1632
-				break;
1632
+					break;
1633 1633
 				default:
1634 1634
 					LM_ERR("can't get authorization hash\n");
1635 1635
 					return -1;
1636
-				break;
1636
+					break;
1637 1637
 			}
1638
-		break;
1638
+			break;
1639 1639
 		case 6: /* random selection */
1640 1640
 			hash = rand() % idx->nr;
1641
-		break;
1641
+			break;
1642 1642
 		case 7: /* hash on PV value */
1643 1643
 			if (ds_hash_pvar(msg, &hash)!=0)
1644 1644
 			{
1645 1645
 				LM_ERR("can't get PV hash\n");
1646 1646
 				return -1;
1647 1647
 			}
1648
-		break;		
1648
+			break;
1649 1649
 		case 8: /* use always first entry */
1650 1650
 			hash = 0;
1651
-		break;
1651
+			break;
1652 1652
 		case 9: /* weight based distribution */
1653 1653
 			hash = idx->wlist[idx->wlast];
1654 1654
 			idx->wlast = (idx->wlast+1) % 100;
1655
-		break;
1655
+			break;
1656 1656
 		case DS_ALG_LOAD: /* call load based distribution */
1657 1657
 			/* only INVITE can start a call */
1658 1658
 			if(msg->first_line.u.request.method_value!=METHOD_INVITE)
... ...
@@ -1677,7 +1677,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1677 1677
 					alg = 0;
1678 1678
 				}
1679 1679
 			}
1680
-		break;
1680
+			break;
1681 1681
 		default:
1682 1682
 			LM_WARN("algo %d not implemented - using first entry...\n", alg);
1683 1683
 			hash = 0;
... ...
@@ -1722,7 +1722,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1722 1722
 	/* if alg is round-robin then update the shortcut to next to be used */
1723 1723
 	if(alg==DS_ALG_RROBIN)
1724 1724
 		idx->last = (hash+1) % idx->nr;
1725
-	
1725
+
1726 1726
 	LM_DBG("selected [%d-%d/%d] <%.*s>\n", alg, set, hash,
1727 1727
 			idx->dlist[hash].uri.len, idx->dlist[hash].uri.s);
1728 1728
 
... ...
@@ -1761,7 +1761,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1761 1761
 			}
1762 1762
 			cnt++;
1763 1763
 		}
1764
-	
1764
+
1765 1765
 		/* add to avp */
1766 1766
 
1767 1767
 		for(i=hash-1; i>=0; i--)
... ...
@@ -1831,7 +1831,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1831 1831
 			}
1832 1832
 			cnt++;
1833 1833
 		}
1834
-	
1834
+
1835 1835
 		/* add to avp the first used dst */
1836 1836
 		avp_val.s = idx->dlist[hash].uri;
1837 1837
 		if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0)
... ...
@@ -1849,8 +1849,8 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1849 1849
 			if(idx->dlist[hash].attrs.duid.len<=0)
1850 1850
 			{
1851 1851
 				LM_ERR("no uid for destination: %d %.*s\n", set,
1852
-							idx->dlist[hash].uri.len,
1853
-							idx->dlist[hash].uri.s);
1852
+						idx->dlist[hash].uri.len,
1853
+						idx->dlist[hash].uri.s);
1854 1854
 				return -1;
1855 1855
 			}
1856 1856
 			avp_val.s = idx->dlist[hash].attrs.duid;
... ...
@@ -1876,7 +1876,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1876 1876
 		if(add_avp(cnt_avp_type, cnt_avp_name, avp_val)!=0)
1877 1877
 			return -1;
1878 1878
 	}
1879
-	
1879
+
1880 1880
 	return 1;
1881 1881
 }
1882 1882
 
... ...
@@ -1887,7 +1887,7 @@ int ds_next_dst(struct sip_msg *msg, int mode)
1887 1887
 	struct usr_avp *prev_avp;
1888 1888
 	int_str avp_value;
1889 1889
 	int alg = 0;
1890
-	
1890
+
1891 1891
 	if(!(ds_flags&DS_FAILOVER_ON) || dst_avp_name.n==0)
1892 1892
 	{
1893 1893
 		LM_WARN("failover support disabled\n");
... ...
@@ -1910,7 +1910,7 @@ int ds_next_dst(struct sip_msg *msg, int mode)
1910 1910
 	if(attrs_avp_name.n!=0)
1911 1911
 	{
1912 1912
 		prev_avp = search_first_avp(attrs_avp_type,
1913
-					attrs_avp_name, &avp_value, &st);
1913
+				attrs_avp_name, &avp_value, &st);
1914 1914
 		if(prev_avp!=NULL)
1915 1915
 		{
1916 1916
 			destroy_avp(prev_avp);
... ...
@@ -1925,7 +1925,7 @@ int ds_next_dst(struct sip_msg *msg, int mode)
1925 1925
 	destroy_avp(prev_avp);
1926 1926
 	if(avp==NULL || !(avp->flags&AVP_VAL_STR))
1927 1927
 		return -1; /* no more avps or value is int */
1928
-	
1928
+
1929 1929
 	if(ds_update_dst(msg, &avp_value.s, mode)!=0)
1930 1930
 	{
1931 1931
 		LM_ERR("cannot set dst addr\n");
... ...
@@ -1947,16 +1947,16 @@ int ds_next_dst(struct sip_msg *msg, int mode)
1947 1947
 			return -1;
1948 1948
 		}
1949 1949
 	}
1950
-	
1950
+
1951 1951
 	return 1;
1952 1952
 }
1953 1953
 
1954
-int ds_mark_dst(struct sip_msg *msg, int mode)
1954
+int ds_mark_dst(struct sip_msg *msg, int state)
1955 1955
 {
1956 1956
 	int group, ret;
1957 1957
 	struct usr_avp *prev_avp;
1958 1958
 	int_str avp_value;
1959
-	
1959
+
1960 1960
 	if(!(ds_flags&DS_FAILOVER_ON))
1961 1961
 	{
1962 1962
 		LM_WARN("failover support disabled\n");
... ...
@@ -1964,41 +1964,31 @@ int ds_mark_dst(struct sip_msg *msg, int mode)
1964 1964
 	}
1965 1965
 
1966 1966
 	prev_avp = search_first_avp(grp_avp_type, grp_avp_name, &avp_value, 0);
1967
-	
1967
+
1968 1968
 	if(prev_avp==NULL || prev_avp->flags&AVP_VAL_STR)
1969 1969
 		return -1; /* grp avp deleted -- strange */
1970 1970
 	group = avp_value.n;
1971
-	
1971
+
1972 1972
 	prev_avp = search_first_avp(dst_avp_type, dst_avp_name, &avp_value, 0);
1973
-	
1973
+
1974 1974
 	if(prev_avp==NULL || !(prev_avp->flags&AVP_VAL_STR))
1975 1975
 		return -1; /* dst avp deleted -- strange */
1976
-	
1977
-	if(mode==1) {
1978
-		ret = ds_set_state(group, &avp_value.s,
1979
-				DS_INACTIVE_DST|DS_PROBING_DST|DS_RESET_FAIL_DST, 0, msg);
1980
-	} else if(mode==2) {
1981
-		ret = ds_set_state(group, &avp_value.s, DS_PROBING_DST, 1, msg);
1982
-		if (ret == 0) ret = ds_set_state(group, &avp_value.s,
1983
-				DS_INACTIVE_DST, 0, msg);
1984
-	} else {
1985
-		ret = ds_set_state(group, &avp_value.s, DS_INACTIVE_DST, 1, msg);
1986
-		if (ret == 0) ret = ds_set_state(group, &avp_value.s,
1987
-				DS_PROBING_DST, 0, msg);
1988
-	}
1989
-	
1990
-	LM_DBG("mode [%d] grp [%d] dst [%.*s]\n", mode, group, avp_value.s.len,
1976
+
1977
+	ret = ds_update_state(msg, group, &avp_value.s, state);
1978
+
1979
+	LM_DBG("state [%d] grp [%d] dst [%.*s]\n", state, group, avp_value.s.len,
1991 1980
 			avp_value.s.s);
1992
-	
1981
+
1993 1982
 	return (ret==0)?1:-1;
1994 1983
 }
1995 1984
 
1996 1985
 /**
1997 1986
  *
1998 1987
  */
1999
-int ds_set_state(int group, str *address, int state, int type, struct sip_msg *msg)
1988
+int ds_update_state(sip_msg_t *msg, int group, str *address, int state)
2000 1989
 {
2001 1990
 	int i=0;
1991
+	int old_state = 0;
2002 1992
 	ds_set_t *idx = NULL;
2003 1993
 
2004 1994
 	if(_ds_list==NULL || _ds_list_nr<=0)
... ...
@@ -2006,7 +1996,7 @@ int ds_set_state(int group, str *address, int state, int type, struct sip_msg *m
2006 1996
 		LM_ERR("the list is null\n");
2007 1997
 		return -1;
2008 1998
 	}
2009
-	
1999
+
2010 2000
 	/* get the index of the set */
2011 2001
 	if(ds_get_index(group, &idx)!=0)
2012 2002
 	{
... ...
@@ -2020,57 +2010,40 @@ int ds_set_state(int group, str *address, int state, int type, struct sip_msg *m
2020 2010
 				&& strncasecmp(idx->dlist[i].uri.s, address->s,
2021 2011
 					address->len)==0)
2022 2012
 		{
2023
-			/* remove the Probing/Inactive-State? Set the fail-count to 0. */
2024
-			if (state == DS_PROBING_DST) {
2025
-				if (type) {
2026
-					if (idx->dlist[i].flags & DS_DISABLED_DST) {
2027
-						LM_INFO("Ignoring the request to set this destination"
2028
-								" to probing: It is disabled by admin!\n");
2029
-						return 0;
2030
-					}
2031
-					
2032
-					idx->dlist[i].failure_count++;
2033
-					/* Fire only, if the Threshold is reached. */
2034
-					if (idx->dlist[i].failure_count
2035
-							< probing_threshhold) return 0;
2036
-					if (idx->dlist[i].failure_count
2037
-							> probing_threshhold)
2038
-						idx->dlist[i].failure_count
2039
-							= probing_threshhold;				
2013
+			/* destination address found */
2014
+			old_state = idx->dlist[i].flags;
2015
+
2016
+			/* reset the bits used for states */
2017
+			idx->dlist[i].flags &= ~(DS_STATES_ALL);
2018
+
2019
+			/* set the new states */
2020
+			if(state & DS_DISABLED_DST)
2021
+				idx->dlist[i].flags |= DS_DISABLED_DST;
2022
+			else
2023
+				idx->dlist[i].flags |= state;
2024
+
2025
+			if(state & DS_TRYING_DST)
2026
+			{
2027
+				idx->dlist[i].failure_count++;
2028
+				if (idx->dlist[i].failure_count >= probing_threshhold)
2029
+				{
2030
+					idx->dlist[i].flags &= ~DS_TRYING_DST;
2031
+					idx->dlist[i].flags |= DS_INACTIVE_DST;
2032
+					idx->dlist[i].failure_count = 0;
2040 2033
 				}
2041
-			}
2042
-			/* Reset the Failure-Counter */
2043
-			if ((state & DS_RESET_FAIL_DST) > 0) {
2034
+			} else {
2044 2035
 				idx->dlist[i].failure_count = 0;
2045
-				state &= ~DS_RESET_FAIL_DST;
2046 2036
 			}
2047
-	
2048
-			/*  Type 2 means reply from OPTIONS-Ping */
2049
-			if (type == 2) {
2050
-				if (idx->dlist[i].flags & DS_DISABLED_DST) {
2051
-					LM_INFO("Ignoring the request to set this destination"
2052
-							" to active: It is already administratively deactivated!\n");
2053
-					return 0;
2054
-				}
2055
-				type = 0;
2056
-			}
2057
-			
2058
-			if(type)
2059
-			{
2060
-				if (state & DS_PROBING_DST && !(idx->dlist[i].flags & state))
2061
-					ds_run_route(msg, "dispatcher:dst-down");
2062 2037
 
2063
-				idx->dlist[i].flags |= state;
2064
-			}
2065
-			else
2038
+			if (!ds_skip_dst(old_state) && ds_skip_dst(idx->dlist[i].flags))
2066 2039
 			{
2067
-				if (state & DS_PROBING_DST && idx->dlist[i].flags & state)
2068
-					ds_run_route(msg, "dispatcher:dst-up");
2069
-
2070
-				idx->dlist[i].flags &= ~state;
2040
+				ds_run_route(msg, "dispatcher:dst-down");
2071 2041
 
2042
+			} else {
2043
+				if(ds_skip_dst(old_state) && !ds_skip_dst(idx->dlist[i].flags))
2044
+					ds_run_route(msg, "dispatcher:dst-up");
2072 2045
 			}
2073
-				
2046
+
2074 2047
 			return 0;
2075 2048
 		}
2076 2049
 		i++;
... ...
@@ -2150,43 +2123,46 @@ int ds_print_list(FILE *fout)
2150 2123
 {
2151 2124
 	int j;
2152 2125
 	ds_set_t *list;
2153
-		
2126
+
2154 2127
 	if(_ds_list==NULL || _ds_list_nr<=0)
2155 2128
 	{
2156 2129
 		LM_ERR("no destination sets\n");
2157 2130
 		return -1;
2158 2131
 	}
2159
-	
2132
+
2160 2133
 	fprintf(fout, "\nnumber of destination sets: %d\n", _ds_list_nr);
2161
-	
2134
+
2162 2135
 	for(list = _ds_list; list!= NULL; list= list->next)
2163 2136
 	{
2164 2137
 		for(j=0; j<list->nr; j++)
2165 2138
 		{
2166 2139
 			fprintf(fout, "\n set #%d\n", list->id);
2167
-		
2140
+
2168 2141
 			if (list->dlist[j].flags&DS_DISABLED_DST)
2169
-  				fprintf(fout, "    Disabled         ");
2142
+				fprintf(fout, "    Disabled         ");
2170 2143
 			else if (list->dlist[j].flags&DS_INACTIVE_DST)
2171 2144
 				fprintf(fout, "    Inactive         ");
2172
-  			else {
2173
-  				fprintf(fout, "    Active");
2174
-  				/* Optional: Print the tries for this host. */
2175
-  				if (list->dlist[j].failure_count > 0) {
2176
-  					fprintf(fout, " (Fail %d/%d)",
2177
-  							list->dlist[j].failure_count,
2178
- 							probing_threshhold);
2179
-  				} else {
2180
-  					fprintf(fout, "           ");
2181
-  				}
2182
-  			}
2145
+			else if (list->dlist[j].flags&DS_TRYING_DST) {
2146
+				fprintf(fout, "    Trying");
2147
+				/* print the tries for this host. */
2148
+				if (list->dlist[j].failure_count > 0) {
2149
+					fprintf(fout, " (Fail %d/%d)",
2150
+							list->dlist[j].failure_count,
2151
+							probing_threshhold);
2152
+				} else {
2153
+					fprintf(fout, "           ");
2154
+				}
2155
+
2156
+			} else {
2157
+				fprintf(fout, "    Active           ");
2158
+			}
2183 2159
 			if (list->dlist[j].flags&DS_PROBING_DST)
2184 2160
 				fprintf(fout, "(P)");
2185 2161
 			else
2186 2162
 				fprintf(fout, "(*)");
2187 2163
 
2188
-  			fprintf(fout, "   %.*s\n",
2189
-  				list->dlist[j].uri.len, list->dlist[j].uri.s);		
2164
+			fprintf(fout, "   %.*s\n",
2165
+					list->dlist[j].uri.len, list->dlist[j].uri.s);
2190 2166
 		}
2191 2167
 	}
2192 2168
 	return 0;
... ...
@@ -2215,13 +2191,13 @@ int ds_is_from_list(struct sip_msg *_m, int group)
2215 2191
 				// LM_ERR("port no: %d (%d)\n", list->dlist[j].port, j);
2216 2192
 				if (ip_addr_cmp(&_m->rcv.src_ip, &list->dlist[j].ip_address)
2217 2193
 						&& (list->dlist[j].port==0
2218
-						|| _m->rcv.src_port == list->dlist[j].port))
2194
+							|| _m->rcv.src_port == list->dlist[j].port))
2219 2195
 				{
2220 2196
 					if(group==-1 && ds_setid_pvname.s!=0)
2221 2197
 					{
2222 2198
 						val.ri = list->id;
2223 2199
 						if(ds_setid_pv.setf(_m, &ds_setid_pv.pvp,
2224
-								(int)EQ_T, &val)<0)
2200
+									(int)EQ_T, &val)<0)
2225 2201
 						{
2226 2202
 							LM_ERR("setting PV failed\n");
2227 2203
 							return -2;
... ...
@@ -2246,7 +2222,7 @@ int ds_print_mi_list(struct mi_node* rpl)
2246 2222
 	struct mi_node* node = NULL;
2247 2223
 	struct mi_node* set_node = NULL;
2248 2224
 	struct mi_attr* attr = NULL;
2249
-	
2225
+
2250 2226
 	if(_ds_list==NULL || _ds_list_nr<=0)
2251 2227
 	{
2252 2228
 		LM_ERR("no destination sets\n");
... ...
@@ -2266,17 +2242,19 @@ int ds_print_mi_list(struct mi_node* rpl)
2266 2242
 			return -1;
2267 2243
 
2268 2244
 		for(j=0; j<list->nr; j++)
2269
-  		{
2270
-  			node= add_mi_node_child(set_node, 0, "URI", 3,
2271
-  					list->dlist[j].uri.s, list->dlist[j].uri.len);
2272
-  			if(node == NULL)
2273
-  				return -1;
2245
+		{
2246
+			node= add_mi_node_child(set_node, 0, "URI", 3,
2247
+					list->dlist[j].uri.s, list->dlist[j].uri.len);
2248
+			if(node == NULL)
2249
+				return -1;
2274 2250
 
2275 2251
 			memset(&c, 0, sizeof(c));
2276 2252
 			if (list->dlist[j].flags & DS_INACTIVE_DST)
2277 2253
 				c[0] = 'I';
2278 2254
 			else if (list->dlist[j].flags & DS_DISABLED_DST)
2279 2255
 				c[0] = 'D';
2256
+			else if (list->dlist[j].flags & DS_TRYING_DST)
2257
+				c[0] = 'T';
2280 2258
 			else
2281 2259
 				c[0] = 'A';
2282 2260
 
... ...
@@ -2287,18 +2265,18 @@ int ds_print_mi_list(struct mi_node* rpl)
2287 2265
 
2288 2266
 			attr = add_mi_attr (node, MI_DUP_VALUE, "flags", 5, c, 2);
2289 2267
 			if(attr == 0)
2290
-  				return -1;
2268
+				return -1;
2291 2269
 
2292 2270
 			data.s = int2str(list->dlist[j].priority, &data.len);
2293 2271
 			attr = add_mi_attr (node, MI_DUP_VALUE, "priority", 8,
2294 2272
 					data.s, data.len);
2295
-  			if(attr == 0)
2296
-  				return -1;
2297
-   			attr = add_mi_attr (node, MI_DUP_VALUE, "attrs", 5,
2298
-				(list->dlist[j].attrs.body.s)?list->dlist[j].attrs.body.s:"",
2299
-				list->dlist[j].attrs.body.len);
2300
-  			if(attr == 0)
2301
-  				return -1;
2273
+			if(attr == 0)
2274
+				return -1;
2275
+			attr = add_mi_attr (node, MI_DUP_VALUE, "attrs", 5,
2276
+					(list->dlist[j].attrs.body.s)?list->dlist[j].attrs.body.s:"",
2277
+					list->dlist[j].attrs.body.len);
2278
+			if(attr == 0)
2279
+				return -1;
2302 2280
 		}
2303 2281
 	}
2304 2282
 
... ...
@@ -2316,6 +2294,7 @@ static void ds_options_callback( struct cell *t, int type,
2316 2294
 	int group = 0;
2317 2295
 	str uri = {0, 0};
2318 2296
 	struct sip_msg *fmsg;
2297
+	int state;
2319 2298
 
2320 2299
 	/* The Param does contain the group, in which the failed host
2321 2300
 	 * can be found.*/
... ...
@@ -2338,7 +2317,7 @@ static void ds_options_callback( struct cell *t, int type,
2338 2317
 	/* ps->code contains the result-code of the request.
2339 2318
 	 *
2340 2319
 	 * We accept both a "200 OK" or the configured reply as a valid response */
2341
-	if ((ps->code == 200) || ds_ping_check_rplcode(ps->code))
2320
+	if((ps->code>=200 && ps->code<=299) || ds_ping_check_rplcode(ps->code))
2342 2321
 	{
2343 2322
 		if (faked_msg_init() < 0)
2344 2323
 		{
... ...
@@ -2349,15 +2328,19 @@ static void ds_options_callback( struct cell *t, int type,
2349 2328
 		fmsg->parsed_orig_ruri_ok = 0;
2350 2329
 		fmsg->new_uri = uri;
2351 2330
 
2352
-		/* Set the according entry back to "Active":
2353
-		 *  remove the Probing/Inactive Flag and reset the failure counter. */
2354
-		if (ds_set_state(group, &uri,
2355
-					DS_INACTIVE_DST|DS_PROBING_DST|DS_RESET_FAIL_DST, 2, fmsg) != 0)
2331
+		/* Set the according entry back to "Active" */
2332
+		state = 0;
2333
+		if (ds_probing_mode==1)
2334
+			state |= DS_PROBING_DST;
2335
+		if (ds_update_state(fmsg, group, &uri, state) != 0)
2356 2336
 		{
2357 2337
 			LM_ERR("Setting the state failed (%.*s, group %d)\n", uri.len,
2358 2338
 					uri.s, group);
2359 2339
 		}
2360
-	} else if (ds_probing_mode==1) {
2340
+	} else {
2341
+		state = DS_TRYING_DST;
2342
+		if (ds_probing_mode==1)
2343
+			state |= DS_PROBING_DST;
2361 2344
 
2362 2345
 		if (faked_msg_init() < 0)
2363 2346
 		{
... ...
@@ -2368,7 +2351,7 @@ static void ds_options_callback( struct cell *t, int type,
2368 2351
 		fmsg->parsed_orig_ruri_ok = 0;
2369 2352
 		fmsg->new_uri = uri;
2370 2353
 
2371
-		if (ds_set_state(group, &uri, DS_PROBING_DST, 1, fmsg) != 0)
2354
+		if (ds_update_state(fmsg, group, &uri, state) != 0)
2372 2355
 		{
2373 2356
 			LM_ERR("Setting the probing state failed (%.*s, group %d)\n",
2374 2357
 					uri.len, uri.s, group);
... ...
@@ -2379,7 +2362,7 @@ static void ds_options_callback( struct cell *t, int type,
2379 2362
 }
2380 2363
 
2381 2364
 /*! \brief
2382
- * Timer for checking inactive destinations
2365
+ * Timer for checking probing destinations
2383 2366
  *
2384 2367
  * This timer is regularly fired.
2385 2368
  */
... ...
@@ -2388,7 +2371,7 @@ void ds_check_timer(unsigned int ticks, void* param)
2388 2371
 	int j;
2389 2372
 	ds_set_t *list;
2390 2373
 	uac_req_t uac_r;
2391
-	
2374
+
2392 2375
 	/* Check for the list. */
2393 2376
 	if(_ds_list==NULL || _ds_list_nr<=0)
2394 2377
 	{
... ...
@@ -2410,14 +2393,14 @@ void ds_check_timer(unsigned int ticks, void* param)
2410 2393
 			{
2411 2394
 				LM_DBG("probing set #%d, URI %.*s\n", list->id,
2412 2395
 						list->dlist[j].uri.len, list->dlist[j].uri.s);
2413
-				
2396
+
2414 2397
 				/* Send ping using TM-Module.
2415 2398
 				 * int request(str* m, str* ruri, str* to, str* from, str* h,
2416 2399
 				 *		str* b, str *oburi,
2417 2400
 				 *		transaction_cb cb, void* cbp); */
2418 2401
 				set_uac_req(&uac_r, &ds_ping_method, 0, 0, 0,
2419 2402
 						TMCB_LOCAL_COMPLETED, ds_options_callback,
2420
-							(void*)(long)list->id);
2403
+						(void*)(long)list->id);
2421 2404
 				if (tmb.t_request(&uac_r,
2422 2405
 							&list->dlist[j].uri,
2423 2406
 							&list->dlist[j].uri,
... ...
@@ -2447,7 +2430,7 @@ void ds_ht_timer(unsigned int ticks, void *param)
2447 2430
 		return;
2448 2431
 
2449 2432
 	now = time(NULL);
2450
-	
2433
+
2451 2434
 	for(i=0; i<_dsht_load->htsize; i++)
2452 2435
 	{
2453 2436
 		/* free entries */
... ...
@@ -2457,7 +2440,7 @@ void ds_ht_timer(unsigned int ticks, void *param)
2457 2440
 		{
2458 2441
 			it0 = it->next;
2459 2442
 			if((it->expire!=0 && it->expire<now)
2460
-				|| (it->state==DS_LOAD_INIT
2443
+					|| (it->state==DS_LOAD_INIT
2461 2444
 						&& it->initexpire!=0 && it->initexpire<now))
2462 2445
 			{
2463 2446
 				/* expired */
... ...
@@ -50,10 +50,10 @@
50 50
 #define DS_FAILOVER_ON		2  /*!< store the other dest in avps */
51 51
 
52 52
 #define DS_INACTIVE_DST		1  /*!< inactive destination */
53
-#define DS_PROBING_DST		2  /*!< checking destination */
53
+#define DS_TRYING_DST		2  /*!< temporary trying destination */
54 54
 #define DS_DISABLED_DST		4  /*!< admin disabled destination */
55
-#define DS_STATES_ALL		7  /*!< all bits for the states of destination */
56
-#define DS_RESET_FAIL_DST	8  /*!< Reset-Failure-Counter */
55
+#define DS_PROBING_DST		8  /*!< checking destination */
56
+#define DS_STATES_ALL		15  /*!< all bits for the states of destination */
57 57
 
58 58
 #define ds_skip_dst(flags)	((flags) & (DS_INACTIVE_DST|DS_DISABLED_DST))
59 59
 
... ...
@@ -89,7 +89,7 @@ extern struct tm_binds tmb;
89 89
 extern str ds_ping_method;
90 90
 extern str ds_ping_from;
91 91
 extern int probing_threshhold; /*!< number of failed requests,
92
-						before a destination is taken into probing */ 
92
+								 before a destination is taken into probing */ 
93 93
 extern int ds_probing_mode;
94 94
 
95 95
 int init_data(void);
... ...
@@ -101,7 +101,7 @@ int ds_load_db(void);
101 101
 int ds_destroy_list(void);
102 102
 int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode);
103 103
 int ds_next_dst(struct sip_msg *msg, int mode);
104
-int ds_set_state(int group, str *address, int state, int type, struct sip_msg *msg);
104
+int ds_update_state(sip_msg_t *msg, int group, str *address, int state);
105 105
 int ds_reinit_state(int group, str *address, int state);
106 106
 int ds_mark_dst(struct sip_msg *msg, int mode);
107 107
 int ds_print_list(FILE *fout);
... ...
@@ -448,7 +448,7 @@ static int mod_init(void)
448 448
 	} else {
449 449
 		hash_param_model = NULL;
450 450
 	}
451
-	
451
+
452 452
 	if(ds_setid_pvname.s!=0)
453 453
 	{
454 454
 		if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL
... ...
@@ -477,7 +477,7 @@ static int mod_init(void)
477 477
 	{
478 478
 		/*****************************************************
479 479
 		 * TM-Bindings
480
-	  	 *****************************************************/
480
+		 *****************************************************/
481 481
 		if (load_tm_api( &tmb ) == -1)
482 482
 		{
483 483
 			LM_ERR("could not load the TM-functions - disable DS ping\n");
... ...
@@ -504,7 +504,7 @@ static int child_init(int rank)
504 504
 
505 505
 static int mi_child_init(void)
506 506
 {
507
-	
507
+
508 508
 	if(ds_db_url.s)
509 509
 		return ds_connect_db();
510 510
 	return 0;
... ...
@@ -531,7 +531,7 @@ static void destroy(void)
531 531
 static int w_ds_select_dst(struct sip_msg* msg, char* set, char* alg)
532 532
 {
533 533
 	int a, s;
534
-	
534
+
535 535
 	if(msg==NULL)
536 536
 		return -1;
537 537
 	if(fixup_get_ivalue(msg, (gparam_p)set, &s)!=0)
... ...
@@ -592,7 +592,13 @@ static int w_ds_next_domain(struct sip_msg *msg, char *str1, char *str2)
592 592
  */
593 593
 static int w_ds_mark_dst0(struct sip_msg *msg, char *str1, char *str2)
594 594
 {
595
-	return ds_mark_dst(msg, 0);
595
+	int state;
596
+
597
+	state = DS_INACTIVE_DST;
598
+	if (ds_probing_mode==1)
599
+		state |= DS_PROBING_DST;
600
+
601
+	return ds_mark_dst(msg, state);
596 602
 }
597 603
 
598 604
 /**
... ...
@@ -600,12 +606,26 @@ static int w_ds_mark_dst0(struct sip_msg *msg, char *str1, char *str2)
600 606
  */
601 607
 static int w_ds_mark_dst1(struct sip_msg *msg, char *str1, char *str2)
602 608
 {
603
-	if(str1 && (str1[0]=='i' || str1[0]=='I' || str1[0]=='0'))
604
-		return ds_mark_dst(msg, 0);
605
-	else if(str1 && (str1[0]=='p' || str1[0]=='P' || str1[0]=='2'))
606
-		return ds_mark_dst(msg, 2);
607
-	else
608
-		return ds_mark_dst(msg, 1);
609
+	int state;
610
+	int len;
611
+
612
+	if(str1==NULL)
613
+		return w_ds_mark_dst0(msg, NULL, NULL);
614
+
615
+	len = strlen(str1);
616
+	state = 0;
617
+	if (len>1 && (str1[1]=='p' || str1[1]=='P'))
618
+		state |= DS_PROBING_DST;
619
+
620
+	if(str1[0]=='i' || str1[0]=='I')
621
+		state |= DS_INACTIVE_DST;
622
+	else if(str1[0]=='t' || str1[0]=='T')
623
+		state |= DS_TRYING_DST;
624
+	else if(str1[0]=='d' || str1[0]=='D')
625
+		state = DS_DISABLED_DST;
626
+	else if(str1[0]=='p' || str1[0]=='P')
627
+		state =  DS_INACTIVE_DST|DS_PROBING_DST;
628
+	return ds_mark_dst(msg, state);
609 629
 }
610 630
 
611 631
 
... ...
@@ -674,6 +694,11 @@ static struct mi_root* ds_mi_set(struct mi_root* cmd_tree, void* param)
674 694
 	} else if(sp.s[0]=='2' || sp.s[0]=='D' || sp.s[0]=='d') {
675 695
 		/* set disabled */
676 696
 		state |= DS_DISABLED_DST;
697
+	} else if(sp.s[0]=='3' || sp.s[0]=='T' || sp.s[0]=='t') {
698
+		/* set trying */
699
+		state |= DS_TRYING_DST;
700
+		if((sp.len>1) && (sp.s[1]=='P' || sp.s[1]=='p'))
701
+			state |= DS_PROBING_DST;
677 702
 	} else {
678 703
 		LM_ERR("unknow state value\n");
679 704
 		return init_mi_tree(500, "unknown state value", 19);
... ...
@@ -784,13 +809,13 @@ static int ds_parse_reply_codes() {
784 809
 
785 810
 	/* Validate String: */
786 811
 	if (cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).s == 0 
787
-		|| cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).len<=0)
812
+			|| cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).len<=0)
788 813
 		return 0;
789 814
 
790 815
 	/* parse_params will modify the string pointer of .s, so we need to make a copy. */
791 816
 	input.s = cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).s;
792 817
 	input.len = cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str).len;
793
-	
818
+
794 819
 	/* Parse the parameters: */
795 820
 	if (parse_params(&input, CLASS_ANY, 0, &params_list)<0)
796 821
 		return -1;
... ...
@@ -821,7 +846,7 @@ static int ds_parse_reply_codes() {
821 846
 			LM_ERR("no more memory\n");
822 847
 			return -1;
823 848
 		}
824
-	 
849
+
825 850
 		/* Now create the list of valid reply-codes: */
826 851
 		for (pit = params_list; pit; pit=pit->next)
827 852
 		{
... ...
@@ -855,7 +880,7 @@ static int ds_parse_reply_codes() {
855 880
 		// Free the old memory area:
856 881
 		if(ds_ping_reply_codes_old)
857 882
 			shm_free(ds_ping_reply_codes_old);	
858
-	/* Less or equal? Set the number of codes first. */
883
+		/* Less or equal? Set the number of codes first. */
859 884
 	} else {
860 885
 		// Done:
861 886
 		*ds_ping_reply_codes_cnt = list_size;
... ...
@@ -870,7 +895,7 @@ static int ds_parse_reply_codes() {
870 895
 	for (i =0; i< *ds_ping_reply_codes_cnt; i++)
871 896
 	{
872 897
 		LM_DBG("Dispatcher: Now accepting Reply-Code %d (%d/%d) as valid\n",
873
-			(*ds_ping_reply_codes)[i], (i+1), *ds_ping_reply_codes_cnt);
898
+				(*ds_ping_reply_codes)[i], (i+1), *ds_ping_reply_codes_cnt);
874 899
 	}
875 900
 	return 0;
876 901
 }
... ...
@@ -878,7 +903,7 @@ static int ds_parse_reply_codes() {
878 903
 int ds_ping_check_rplcode(int code)
879 904
 {
880 905
 	int i;
881
-	
906
+
882 907
 	for (i =0; i< *ds_ping_reply_codes_cnt; i++)
883 908
 	{
884 909
 		if((*ds_ping_reply_codes)[i] == code)
... ...
@@ -977,7 +1002,7 @@ static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
977 1002
 	for(list = ds_list; list!= NULL; list= list->next)
978 1003
 	{
979 1004
 		if(rpc->struct_add(ih, "d",
980
-				"SET_ID", list->id)<0)
1005
+					"SET_ID", list->id)<0)
981 1006
 		{
982 1007
 			rpc->fault(c, 500, "Internal error creating set id");
983 1008
 			return;
... ...
@@ -986,7 +1011,7 @@ static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
986 1011
 		for(j=0; j<list->nr; j++)
987 1012
 		{
988 1013
 			if(rpc->struct_add(ih, "{",
989
-				"DEST", &vh)<0)
1014
+						"DEST", &vh)<0)
990 1015
 			{
991 1016
 				rpc->fault(c, 500, "Internal error creating dest");
992 1017
 				return;
... ...
@@ -997,6 +1022,8 @@ static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
997 1022
 				c[0] = 'I';
998 1023
 			else if (list->dlist[j].flags & DS_DISABLED_DST)
999 1024
 				c[0] = 'D';
1025
+			else if (list->dlist[j].flags & DS_TRYING_DST)
1026
+				c[0] = 'T';
1000 1027
 			else
1001 1028
 				c[0] = 'A';
1002 1029
 
... ...
@@ -1006,11 +1033,11 @@ static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
1006 1033
 				c[1] = 'X';
1007 1034
 
1008 1035
 			if(rpc->struct_add(vh, "SsdS",
1009
-				"URI", &list->dlist[j].uri,
1010
-				"FLAGS", c,
1011
-				"PRIORITY", list->dlist[j].priority,
1012
-				"ATTRS", (list->dlist[j].attrs.body.s)?
1013
-							&(list->dlist[j].attrs.body):&data)<0)
1036
+						"URI", &list->dlist[j].uri,
1037
+						"FLAGS", c,
1038
+						"PRIORITY", list->dlist[j].priority,
1039
+						"ATTRS", (list->dlist[j].attrs.body.s)?
1040
+						&(list->dlist[j].attrs.body):&data)<0)
1014 1041
 			{
1015 1042
 				rpc->fault(c, 500, "Internal error creating dest struct");
1016 1043
 				return;
... ...
@@ -1063,6 +1090,11 @@ static void dispatcher_rpc_set_state(rpc_t* rpc, void* ctx)
1063 1090
 	} else if(state.s[0]=='2' || state.s[0]=='D' || state.s[0]=='d') {
1064 1091
 		/* set disabled */
1065 1092
 		stval |= DS_DISABLED_DST;
1093
+	} else if(state.s[0]=='3' || state.s[0]=='T' || state.s[0]=='t') {
1094
+		/* set trying */
1095
+		stval |= DS_TRYING_DST;
1096
+		if((state.len>1) && (state.s[1]=='P' || state.s[1]=='p'))
1097
+			stval |= DS_PROBING_DST;
1066 1098
 	} else {
1067 1099
 		LM_ERR("unknow state value\n");
1068 1100
 		rpc->fault(ctx, 500, "Unknown State Value");