Browse Source

dded support for appending branch parameters

Jiri Kuthan 24 năm trước cách đây
mục cha
commit
676eb608d1
11 tập tin đã thay đổi với 101 bổ sung27 xóa
  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*/