Browse code

- tm better final reply selection: 6xx is preferred over other negative replies; from several 4xx prefer 401, 407, 415, 420, 484 (in this order). For all the other cases, return the lowest code (as before).

Andrei Pelinescu-Onciul authored on 06/10/2006 11:32:41
Showing 4 changed files
... ...
@@ -67,7 +67,7 @@ MAIN_NAME=ser
67 67
 VERSION = 0
68 68
 PATCHLEVEL = 10
69 69
 SUBLEVEL =   99
70
-EXTRAVERSION = -dev47-dns_cache
70
+EXTRAVERSION = -dev49-dns_cache
71 71
 
72 72
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
73 73
 			$(SUBLEVEL) )
... ...
@@ -24,7 +24,11 @@ modules:
24 24
                 hashing after an uri (to, from or request uri)
25 25
               - improved uri hashing (password is ignored, port is used only
26 26
                 if != 5060 or 5061)
27
- - tm        - special functions for checking for timeout, if a reply was
27
+ - tm        - better final reply selection: 6xx is preferred over other 
28
+               negative replies; from several 4xx prefer 401, 407, 415, 420,
29
+               484 (in this order). For all the other cases, return the lowest
30
+               code (as before)
31
+             - special functions for checking for timeout, if a reply was
28 32
                received or if the current transaction was canceled
29 33
              - dns failover and dst blacklist support
30 34
              - migrated to the new timers (tm timers completely rewritten)
... ...
@@ -71,6 +71,10 @@
71 71
  *  2006-09-13  t_pick_branch will skip also over branches with empty reply 
72 72
  *              t_should_relay_response will re-pick the branch if failure 
73 73
  *               route /handlers added new branches (andrei)
74
+ * 2006-10-05  better final reply selection: t_pick_branch will prefer 6xx,
75
+ *              if no 6xx reply => lowest class/code; if class==4xx =>
76
+ *              prefer 401, 407, 415, 420 and 484   (andrei)
77
+ *
74 78
  */
75 79
 
76 80
 
... ...
@@ -124,6 +128,22 @@ static int goto_on_negative=0;
124 128
 static int goto_on_reply=0;
125 129
 
126 130
 
131
+/* responses priority (used by t_pick_branch)
132
+ *  0xx is used only for the initial value (=> should have no chance to be
133
+ *  selected => the highest value); 1xx is not used */
134
+static unsigned short resp_class_prio[]={
135
+			32000, /* 0-99, special */
136
+			11000, /* 1xx, special, should never be used */
137
+				0,  /* 2xx, high priority (not used, 2xx are immediately 
138
+				       forwarded and t_pick_branch will never be called if
139
+					   a 2xx was received) */
140
+			3000,  /* 3xx */
141
+			4000,  /* 4xx */
142
+			5000,  /* 5xx */
143
+			1000   /* 6xx, highest priority */
144
+};
145
+
146
+
127 147
 
128 148
 /* we store the reply_route # in private memory which is
129 149
    then processed during t_relay; we cannot set this value
... ...
@@ -703,6 +723,52 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
703 723
 }
704 724
 
705 725
 
726
+
727
+/* 401, 407, 415, 420, and 484 have priority over the other 4xx*/
728
+inline static short int get_4xx_prio(unsigned char xx)
729
+{
730
+	switch(xx){
731
+		case  1:
732
+		case  7:
733
+		case 15:
734
+		case 20:
735
+		case 84:
736
+			return xx;
737
+			break;
738
+	}
739
+	return 100+xx;
740
+}
741
+
742
+
743
+
744
+/* returns response priority, lower number => highest prio
745
+ *
746
+ * responses                    priority val
747
+ *  0-99                        32000+reponse         (special)
748
+ *  1xx                         11000+reponse         (special)
749
+ *  700-999                     10000+response        (very low)
750
+ *  5xx                          5000+xx              (low)
751
+ *  4xx                          4000+xx
752
+ *  3xx                          3000+xx
753
+ *  6xx                          1000+xx              (high)
754
+ *  2xx                          0000+xx              (highest) 
755
+ */
756
+inline static short int get_prio(unsigned int resp)
757
+{
758
+	int class;
759
+	int xx;
760
+	
761
+	class=resp/100;
762
+
763
+	if (class<7){
764
+		xx=resp%100;
765
+		return resp_class_prio[class]+((class==4)?get_4xx_prio(xx):xx);
766
+	}
767
+	return 10000+resp; /* unknown response class => return very low prio */
768
+}
769
+
770
+
771
+
706 772
 /* select a branch for forwarding; returns:
707 773
  * 0..X ... branch number
708 774
  * -1   ... error
... ...
@@ -710,15 +776,15 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
710 776
  */
711 777
 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
712 778
 {
713
-	int lowest_b, lowest_s, b;
779
+	int best_b, best_s, b;
714 780
 
715
-	lowest_b=-1; lowest_s=999;
781
+	best_b=-1; best_s=0;
716 782
 	for ( b=0; b<t->nr_of_outgoings ; b++ ) {
717 783
 		/* "fake" for the currently processed branch */
718 784
 		if (b==inc_branch) {
719
-			if (inc_code<lowest_s) {
720
-				lowest_b=b;
721
-				lowest_s=inc_code;
785
+			if (get_prio(inc_code)<get_prio(best_s)) {
786
+				best_b=b;
787
+				best_s=inc_code;
722 788
 			}
723 789
 			continue;
724 790
 		}
... ...
@@ -728,16 +794,19 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
728 794
 		if ( t->uac[b].last_received<200 )
729 795
 			return -2;
730 796
 		/* if reply is null => t_send_branch "faked" reply, skip over it */
731
-		if ( t->uac[b].last_received<lowest_s && t->uac[b].reply ) {
732
-			lowest_b =b;
733
-			lowest_s = t->uac[b].last_received;
797
+		if ( t->uac[b].reply && 
798
+				get_prio(t->uac[b].last_received)<get_prio(best_s) ) {
799
+			best_b =b;
800
+			best_s = t->uac[b].last_received;
734 801
 		}
735 802
 	} /* find lowest branch */
736
-
737
-	*res_code=lowest_s;
738
-	return lowest_b;
803
+	
804
+	*res_code=best_s;
805
+	return best_b;
739 806
 }
740 807
 
808
+
809
+
741 810
 /* This is the neurological point of reply processing -- called
742 811
  * from within a REPLY_LOCK, t_should_relay_response decides
743 812
  * how a reply shall be processed and how transaction state is
... ...
@@ -543,7 +543,7 @@ static int mod_init(void)
543 543
 		LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
544 544
 		return -1;
545 545
 	}
546
-
546
+	
547 547
 	tm_init_tags();
548 548
 	init_twrite_lines();
549 549
 	if (init_twrite_sock() < 0) {