瀏覽代碼

dded support for appending branch parameters

Jiri Kuthan 24 年之前
父節點
當前提交
676eb608d1
共有 11 個文件被更改,包括 101 次插入27 次删除
  1. 2 0
      cfg.lex
  2. 3 0
      cfg.y
  3. 3 0
      config.h
  4. 1 1
      debug.gdb
  5. 1 0
      globals.h
  6. 6 1
      main.c
  7. 4 0
      modules/tm/sip_msg.c
  8. 34 21
      modules/tm/t_funcs.c
  9. 1 1
      modules/tm/t_funcs.h
  10. 2 0
      msg_parser.h
  11. 44 3
      msg_translator.c

+ 2 - 0
cfg.lex

@@ -85,6 +85,7 @@ STAT	statistics
 MAXBUFFER maxbuffer
 CHILDREN children
 CHECK_VIA	check_via
+LOOP_CHECKS	loop_checks
 
 LOADMODULE	loadmodule
 
@@ -159,6 +160,7 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
+<INITIAL>{LOOP_CHECKS}	{ count(); yylval.strval=yytext; return LOOP_CHECKS; }
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
 
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }

+ 3 - 0
cfg.y

@@ -77,6 +77,7 @@ void* f_tmp;
 %token STAT
 %token CHILDREN
 %token CHECK_VIA
+%token LOOP_CHECKS
 %token LOADMODULE
 %token MAXBUFFER
 
@@ -161,6 +162,8 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 		| CHILDREN EQUAL error { yyerror("number expected"); } 
 		| CHECK_VIA EQUAL NUMBER { check_via=$3; }
 		| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
+		| LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
+		| LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
 		| LISTEN EQUAL ipv4  {
 								if (addresses_no < MAX_LISTEN){
 									tmp=inet_ntoa(*(struct in_addr*)&$3);

+ 3 - 0
config.h

@@ -33,6 +33,9 @@
 #define MY_VIA "Via: SIP/2.0/UDP "
 #define MY_VIA_LEN 17
 
+#define MY_BRANCH ";branch=0"
+#define MY_BRANCH_LEN 9
+
 
 #define MAX_PORT_LEN 7 /* ':' + max 5 letters + \0 */
 #define CRLF "\r\n"

+ 1 - 1
debug.gdb

@@ -2,5 +2,5 @@ file ./ser
 set args -f debug.cfg 
 break main
 #break dump_all_statistic
-break lock_initialize
+#break lock_initialize
 run

+ 1 - 0
globals.h

@@ -30,6 +30,7 @@ extern int dont_fork;
 extern int log_stderr;
 extern int check_via;
 extern int received_dns;
+extern int loop_checks;
 
 extern int cfg_errors;
 extern unsigned int msg_no;

+ 6 - 1
main.c

@@ -80,6 +80,7 @@ static char flags[]="NOCR:"
 static char help_msg[]= "\
 Usage: ser -l address [-l address] [options]\n\
 Options:\n\
+    -c		 Perform loop checks and compute branches\n\
     -f file      Configuration file (default " CFG_FILE ")\n\
     -p port      Listen on the specified port (default: 5060)\n\
     -l address   Listen on the specified address (multiple -l mean\n\
@@ -145,6 +146,7 @@ int debug = 0;
 int dont_fork = 0;
 int log_stderr = 0;
 int check_via =  0;        /* check if reply first via host==us */
+int loop_checks = 0;	/* calculate branches and check for loops/spirals */
 int received_dns = 0;      /* use dns and/or rdns or to see if we need to 
                               add a ;received=x.x.x.x to via: */
 
@@ -348,7 +350,7 @@ int main(int argc, char** argv)
 #ifdef STATS
 	"s:"
 #endif
-	"f:p:b:l:n:rRvdDEVh";
+	"f:p:b:l:n:rRvcdDEVh";
 	
 	while((c=getopt(argc,argv,options))!=-1){
 		switch(c){
@@ -402,6 +404,9 @@ int main(int argc, char** argv)
 			case 'v':
 					check_via=1;
 					break;
+			case 'c':
+					loop_checks=1;
+					break;
 			case 'r':
 					received_dns|=DO_DNS;
 					break;

+ 4 - 0
modules/tm/sip_msg.c

@@ -126,6 +126,10 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg )
     new_msg->add_rm  = 0;
     /* repl_add_rm ( struct lump* ) -> have to be changed!!!!!!!  */
     new_msg->repl_add_rm  = 0;
+
+    /* append branch parameter */
+    new_msg->add_to_branch.s = (char *) sh_malloc( org_msg->add_to_branch.len );
+    memcpy( new_msg->add_to_branch.s, org_msg->add_to_branch.s, org_msg->add_to_branch.len );
 }
 
 

+ 34 - 21
modules/tm/t_funcs.c

@@ -186,6 +186,7 @@ int t_lookup_request( struct sip_msg* p_msg )
  */
 int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int dest_port_param )
 {
+   int	branch = 0;	/* we don't do any forking right now */
    /* it's about the same transaction or not? */
    if ( global_msg_id != p_msg->id )
    {
@@ -208,7 +209,7 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
    }
 
    /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
-   if ( T->outbound_request[0]==NULL )
+   if ( T->outbound_request[branch]==NULL )
    {
       unsigned int dest_ip     = dest_ip_param;
       unsigned int dest_port  = dest_port_param;
@@ -217,8 +218,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
 
       DBG("DEBUG: t_forward: first time forwarding\n");
       /* allocates a new retrans_buff for the outbound request */
-      T->outbound_request[0] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
-      memset( T->outbound_request[0] , 0 , sizeof (struct retrans_buff) );
+      T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
+      memset( T->outbound_request[branch] , 0 , sizeof (struct retrans_buff) );
       T->nr_of_outgoings = 1;
 
       /* special case : CANCEL */
@@ -234,8 +235,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
             if ( (T2->status/100)==1 )
             {
                DBG("DEBUG: t_forward: it's CANCEL and I will send to the same place where INVITE went\n");
-               dest_ip    = T2->outbound_request[0]->dest_ip;
-               dest_port = T2->outbound_request[0]->dest_port;
+               dest_ip    = T2->outbound_request[branch]->dest_ip;
+               dest_port = T2->outbound_request[branch]->dest_port;
             }
             else {
                /* transaction exists, but nothing to cancel */
@@ -246,29 +247,33 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
       }/* end special case CANCEL*/
 
       /* store */
-      T->outbound_request[0]->tl[0].payload = &(T->outbound_request[0]);
-      T->outbound_request[0]->dest_ip         = dest_ip;
-      T->outbound_request[0]->dest_port      = dest_port;
-      T->outbound_request[0]->to.sin_family = AF_INET;
-      T->outbound_request[0]->to.sin_port     = htonl( dest_port ) ;
-      T->outbound_request[0]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
-
-      buf = build_req_buf_from_sip_req ( p_msg, &len);
+      T->outbound_request[branch]->tl[RETRASMISSIONS_LIST].payload = &(T->outbound_request[branch]);
+      T->outbound_request[branch]->dest_ip         = dest_ip;
+      T->outbound_request[branch]->dest_port      = dest_port;
+      T->outbound_request[branch]->to.sin_family = AF_INET;
+      T->outbound_request[branch]->to.sin_port     = htonl( dest_port ) ;
+      T->outbound_request[branch]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
+
+      if (add_branch_label( T, p_msg , branch )==-1) return -1;
+      buf = build_buf_from_sip_request  ( p_msg, &len);
       if (!buf)
          return -1;
-      T->outbound_request[0]->bufflen = len ;
-      T->outbound_request[0]->buffer   = (char*)sh_malloc( len );
-      memcpy( T->outbound_request[0]->buffer , buf , len );
+      T->outbound_request[branch]->bufflen = len ;
+      T->outbound_request[branch]->buffer   = (char*)sh_malloc( len );
+      memcpy( T->outbound_request[branch]->buffer , buf , len );
       free( buf ) ;
    }/* end for the first time */
 
 
    /* sets and starts the RETRANS timer */
-   T->outbound_request[0]->nr_retrans    = 0;
-   T->outbound_request[0]->max_retrans = (T->inbound_request->first_line.u.request.method_value==METHOD_INVITE) ? MAX_INVITE_RETR : MAX_NON_INVITE_RETR;
-   T->outbound_request[0]->timeout         = RETR_T1;
+   T->outbound_request[branch]->nr_retrans    = 0;
+   T->outbound_request[branch]->max_retrans = 
+	(T->inbound_request->first_line.u.request.method_value==METHOD_INVITE) ? 
+	MAX_INVITE_RETR : MAX_NON_INVITE_RETR;
+   T->outbound_request[branch]->timeout         = RETR_T1;
    /* send the request */
-   udp_send( T->outbound_request[0]->buffer , T->outbound_request[0]->bufflen , (struct sockaddr*)&(T->outbound_request[0]->to) , sizeof(struct sockaddr_in) );
+   udp_send( T->outbound_request[branch]->buffer , T->outbound_request[branch]->bufflen , 
+		&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
 }
 
 
@@ -865,4 +870,12 @@ void delete_handler( void *attr)
        add_to_tail_of_timer_list( hash_table, &(p_cell->tl[DELETE_LIST]), DELETE_LIST, DEL_TIME_OUT );
 }
 
-
+/* append appropriate branch labels for fast reply-transaction matching
+   to outgoing requests
+*/
+int add_branch_label( struct cell *trans, struct sip_msg *p_msg, int branch )
+{	trans->label;
+	trans->hash_index;
+	p_msg->add_to_branch;
+	branch;
+}

+ 1 - 1
modules/tm/t_funcs.h

@@ -93,6 +93,6 @@ void final_response_handler( void *);
 void wait_handler( void *);
 void delete_handler( void *);
 
-
+int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
 
 #endif

+ 2 - 0
msg_parser.h

@@ -167,6 +167,8 @@ struct sip_msg{
 
 	struct lump* add_rm;      /* used for all the forwarded messages */
 	struct lump* repl_add_rm; /* only for localy generated replies !!!*/
+
+	str add_to_branch; /* whatever whoever want to append to branch comes here */
 	
 };
 

+ 44 - 3
msg_translator.c

@@ -4,9 +4,11 @@
 #include "mem.h"
 #include "dprint.h"
 #include "config.h"
+#include "md5utils.h"
 #include <netdb.h>
 
 
+
 #define MAX_VIA_LINE_SIZE      240
 #define MAX_RECEIVED_SIZE  57
 
@@ -56,7 +58,7 @@ static inline char* q_inet_itoa(unsigned long ip)
 		q_inet_itoa_buf[offset+2]=c+'0';
 		q_inet_itoa_buf[offset+3]=0;
 	}else if (b){
-		q_inet_itoa_buf[offset]=b+'0';
+		
 		q_inet_itoa_buf[offset+1]=c+'0';
 		q_inet_itoa_buf[offset+2]=0;
 	}else{
@@ -112,7 +114,7 @@ int check_address(unsigned long ip, char *name, int resolver)
 
 char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_len)
 {
-	unsigned int len, new_len, via_len, received_len, uri_len;
+	unsigned int len, new_len, via_len, received_len, uri_len, branch_len;
 	char* line_buf;
 	char* received_buf;
 	char* tmp;
@@ -144,13 +146,52 @@ char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_le
 						names[0], port_no);
 */
 	via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/
-	if ((via_len+port_no_str_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
+
+	/* jku: if we compute branches using MD5 it will take 32 bytes */
+	branch_len= (loop_checks ? MY_BRANCH_LEN : MY_BRANCH_LEN -1 + MD5_LEN) + msg->add_to_branch.len;
+
+	if ((via_len+port_no_str_len+branch_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
 		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
 		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
 		if (port_no!=SIP_PORT){
 			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
 			via_len+=port_no_str_len;
 		}
+
+		/* jku: branch parameter */
+		memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN );
+		via_len+=MY_BRANCH_LEN;
+		/* loop checks ? */
+		if (loop_checks) {
+
+			if (	(msg->from || (parse_headers( msg, HDR_FROM)!=-1 && msg->from)) &&
+				(msg->to|| (parse_headers( msg, HDR_TO)!=-1 && msg->to)) &&
+				(msg->callid|| (parse_headers( msg, HDR_CALLID)!=-1 && msg->callid)) &&
+				(msg->cseq|| (parse_headers( msg, HDR_CSEQ)!=-1 && msg->cseq)) ) {
+
+				str src[5];
+				int r;
+			
+				src[0]= msg->from->body;
+				src[1]= msg->to->body; 
+				src[2]= msg->callid->body; 
+				src[3]= msg->first_line.u.request.uri; 
+				src[4]= ((struct cseq_body *)(msg->cseq->parsed))->number;
+
+				MDStringArray ( line_buf+via_len-1, src, 5 );
+				DBG("DEBUG: build_buf_from_sip_request: branch loop detection: %s, %s, %s, %s, %s -> %s32\n",
+					msg->from->body.s, msg->to->body.s, msg->callid->body.s, 
+					msg->first_line.u.request.uri.s,
+					((struct cseq_body *)(msg->cseq->parsed))->number.s,
+					line_buf+via_len-1 );
+				via_len+=MD5_LEN - 1;
+				
+			} else DBG("DEBUG: build_buf_from_sip_request: required HFs for loop checking missing\n");
+		}
+		/* someone wants me to add something to branch here ? */
+		memcpy(line_buf+via_len, msg->add_to_branch.s, msg->add_to_branch.len );
+		via_len+=msg->add_to_branch.len;
+
 		memcpy(line_buf+via_len, CRLF, CRLF_LEN);
 		via_len+=CRLF_LEN;
 		line_buf[via_len]=0; /* null terminate the string*/