소스 검색

- 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 19 년 전
부모
커밋
b0cfdf5fa6
4개의 변경된 파일87개의 추가작업 그리고 14개의 파일을 삭제
  1. 1 1
      Makefile.defs
  2. 5 1
      NEWS
  3. 80 11
      modules/tm/t_reply.c
  4. 1 1
      modules/tm/tm.c

+ 1 - 1
Makefile.defs

@@ -67,7 +67,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev47-dns_cache
+EXTRAVERSION = -dev49-dns_cache
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
 			$(SUBLEVEL) )

+ 5 - 1
NEWS

@@ -24,7 +24,11 @@ modules:
                 hashing after an uri (to, from or request uri)
               - improved uri hashing (password is ignored, port is used only
                 if != 5060 or 5061)
- - tm        - special functions for checking for timeout, if a reply was
+ - 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)
+             - special functions for checking for timeout, if a reply was
                received or if the current transaction was canceled
              - dns failover and dst blacklist support
              - migrated to the new timers (tm timers completely rewritten)

+ 80 - 11
modules/tm/t_reply.c

@@ -71,6 +71,10 @@
  *  2006-09-13  t_pick_branch will skip also over branches with empty reply 
  *              t_should_relay_response will re-pick the branch if failure 
  *               route /handlers added new branches (andrei)
+ * 2006-10-05  better final reply selection: t_pick_branch will prefer 6xx,
+ *              if no 6xx reply => lowest class/code; if class==4xx =>
+ *              prefer 401, 407, 415, 420 and 484   (andrei)
+ *
  */
 
 
@@ -124,6 +128,22 @@ static int goto_on_negative=0;
 static int goto_on_reply=0;
 
 
+/* responses priority (used by t_pick_branch)
+ *  0xx is used only for the initial value (=> should have no chance to be
+ *  selected => the highest value); 1xx is not used */
+static unsigned short resp_class_prio[]={
+			32000, /* 0-99, special */
+			11000, /* 1xx, special, should never be used */
+				0,  /* 2xx, high priority (not used, 2xx are immediately 
+				       forwarded and t_pick_branch will never be called if
+					   a 2xx was received) */
+			3000,  /* 3xx */
+			4000,  /* 4xx */
+			5000,  /* 5xx */
+			1000   /* 6xx, highest priority */
+};
+
+
 
 /* we store the reply_route # in private memory which is
    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,
 }
 
 
+
+/* 401, 407, 415, 420, and 484 have priority over the other 4xx*/
+inline static short int get_4xx_prio(unsigned char xx)
+{
+	switch(xx){
+		case  1:
+		case  7:
+		case 15:
+		case 20:
+		case 84:
+			return xx;
+			break;
+	}
+	return 100+xx;
+}
+
+
+
+/* returns response priority, lower number => highest prio
+ *
+ * responses                    priority val
+ *  0-99                        32000+reponse         (special)
+ *  1xx                         11000+reponse         (special)
+ *  700-999                     10000+response        (very low)
+ *  5xx                          5000+xx              (low)
+ *  4xx                          4000+xx
+ *  3xx                          3000+xx
+ *  6xx                          1000+xx              (high)
+ *  2xx                          0000+xx              (highest) 
+ */
+inline static short int get_prio(unsigned int resp)
+{
+	int class;
+	int xx;
+	
+	class=resp/100;
+
+	if (class<7){
+		xx=resp%100;
+		return resp_class_prio[class]+((class==4)?get_4xx_prio(xx):xx);
+	}
+	return 10000+resp; /* unknown response class => return very low prio */
+}
+
+
+
 /* select a branch for forwarding; returns:
  * 0..X ... branch number
  * -1   ... error
@@ -710,15 +776,15 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
  */
 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
 {
-	int lowest_b, lowest_s, b;
+	int best_b, best_s, b;
 
-	lowest_b=-1; lowest_s=999;
+	best_b=-1; best_s=0;
 	for ( b=0; b<t->nr_of_outgoings ; b++ ) {
 		/* "fake" for the currently processed branch */
 		if (b==inc_branch) {
-			if (inc_code<lowest_s) {
-				lowest_b=b;
-				lowest_s=inc_code;
+			if (get_prio(inc_code)<get_prio(best_s)) {
+				best_b=b;
+				best_s=inc_code;
 			}
 			continue;
 		}
@@ -728,16 +794,19 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
 		if ( t->uac[b].last_received<200 )
 			return -2;
 		/* if reply is null => t_send_branch "faked" reply, skip over it */
-		if ( t->uac[b].last_received<lowest_s && t->uac[b].reply ) {
-			lowest_b =b;
-			lowest_s = t->uac[b].last_received;
+		if ( t->uac[b].reply && 
+				get_prio(t->uac[b].last_received)<get_prio(best_s) ) {
+			best_b =b;
+			best_s = t->uac[b].last_received;
 		}
 	} /* find lowest branch */
-
-	*res_code=lowest_s;
-	return lowest_b;
+	
+	*res_code=best_s;
+	return best_b;
 }
 
+
+
 /* This is the neurological point of reply processing -- called
  * from within a REPLY_LOCK, t_should_relay_response decides
  * how a reply shall be processed and how transaction state is

+ 1 - 1
modules/tm/tm.c

@@ -543,7 +543,7 @@ static int mod_init(void)
 		LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
 		return -1;
 	}
-
+	
 	tm_init_tags();
 	init_twrite_lines();
 	if (init_twrite_sock() < 0) {