Browse code

t_check_status() checks also the blind UACs if t_pick_branch() fails to determine the picked branch in failure_route. Closes SER-434.

Miklos Tirpak authored on 28/01/2009 14:49:55
Showing 3 changed files
... ...
@@ -937,6 +937,36 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
937 937
 	return best_b;
938 938
 }
939 939
 
940
+/* The same as t_pick_branch(), but allows also
941
+ * blind branches to be picked up.
942
+ * This function should be used only in failure_route
943
+ * to check which response has been 
944
+ * picked up by t_pick_branch().
945
+ * returns:
946
+ * 0..X ... branch number
947
+ * -1   ... error
948
+ * -2   ... can't decide yet -- incomplete branches present
949
+ */
950
+int t_pick_branch_blind(struct cell *t, int *res_code)
951
+{
952
+	int best_b, best_s, b;
953
+
954
+	best_b=-1; best_s=0;
955
+	for ( b=0; b<t->nr_of_outgoings ; b++ ) {
956
+		/* there is still an unfinished UAC transaction; wait now! */
957
+		if ( t->uac[b].last_received<200 )
958
+			return -2;
959
+		/* if reply is null => t_send_branch "faked" reply, skip over it */
960
+		if ( t->uac[b].reply && 
961
+				get_prio(t->uac[b].last_received)<get_prio(best_s) ) {
962
+			best_b = b;
963
+			best_s = t->uac[b].last_received;
964
+		}
965
+	} /* find lowest branch */
966
+	
967
+	*res_code=best_s;
968
+	return best_b;
969
+}
940 970
 
941 971
 /* flag indicating whether it is requested
942 972
  * to drop the already saved replies or not */
... ...
@@ -147,6 +147,8 @@ void tm_init_tags();
147 147
 
148 148
 /* selects the branch for fwd-ing the reply */
149 149
 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code);
150
+/* checks the selected branch from failure_route */
151
+int t_pick_branch_blind(struct cell *t, int *res_code);
150 152
 
151 153
 /* drops all the replies to make sure
152 154
  * that none of them is picked up again
... ...
@@ -791,7 +791,7 @@ static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
791 791
 	struct cell *t;
792 792
 	char *status, *s = NULL;
793 793
 	char backup;
794
-	int lowest_status, n;
794
+	int lowest_status, n, ret;
795 795
 	fparam_t* fp;
796 796
 	regex_t* re = NULL;
797 797
 	str tmp;
... ...
@@ -850,7 +850,16 @@ static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
850 850
 
851 851
 	case MODE_ONFAILURE:
852 852
 		/* use the status of the winning reply */
853
-		if (t_pick_branch( -1, 0, t, &lowest_status)<0 ) {
853
+		ret = t_pick_branch( -1, 0, t, &lowest_status);
854
+		if (ret == -1) {
855
+			/* t_pick_branch() retuns error also when there are only
856
+			 * blind UACs. Let us give it another chance including the
857
+			 * blind branches. */
858
+			LOG(L_DBG, "DEBUG: t_check_status: t_pick_branch returned error, "
859
+				"trying t_pick_branch_blind\n");
860
+			ret = t_pick_branch_blind(t, &lowest_status);
861
+		}
862
+		if (ret < 0) {
854 863
 			LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get "
855 864
 				" a final response in MODE_ONFAILURE\n");
856 865
 			goto error;