Browse code

dded support for appending branch parameters

Jiri Kuthan authored on 29/11/2001 12:49:49
Showing 11 changed files
... ...
@@ -85,6 +85,7 @@ STAT	statistics
85 85
 MAXBUFFER maxbuffer
86 86
 CHILDREN children
87 87
 CHECK_VIA	check_via
88
+LOOP_CHECKS	loop_checks
88 89
 
89 90
 LOADMODULE	loadmodule
90 91
 
... ...
@@ -159,6 +160,7 @@ EAT_ABLE	[\ \t\b\r]
159 160
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
160 161
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
161 162
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
163
+<INITIAL>{LOOP_CHECKS}	{ count(); yylval.strval=yytext; return LOOP_CHECKS; }
162 164
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
163 165
 
164 166
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
... ...
@@ -77,6 +77,7 @@ void* f_tmp;
77 77
 %token STAT
78 78
 %token CHILDREN
79 79
 %token CHECK_VIA
80
+%token LOOP_CHECKS
80 81
 %token LOADMODULE
81 82
 %token MAXBUFFER
82 83
 
... ...
@@ -161,6 +162,8 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
161 162
 		| CHILDREN EQUAL error { yyerror("number expected"); } 
162 163
 		| CHECK_VIA EQUAL NUMBER { check_via=$3; }
163 164
 		| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
165
+		| LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
166
+		| LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
164 167
 		| LISTEN EQUAL ipv4  {
165 168
 								if (addresses_no < MAX_LISTEN){
166 169
 									tmp=inet_ntoa(*(struct in_addr*)&$3);
... ...
@@ -33,6 +33,9 @@
33 33
 #define MY_VIA "Via: SIP/2.0/UDP "
34 34
 #define MY_VIA_LEN 17
35 35
 
36
+#define MY_BRANCH ";branch=0"
37
+#define MY_BRANCH_LEN 9
38
+
36 39
 
37 40
 #define MAX_PORT_LEN 7 /* ':' + max 5 letters + \0 */
38 41
 #define CRLF "\r\n"
... ...
@@ -2,5 +2,5 @@ file ./ser
2 2
 set args -f debug.cfg 
3 3
 break main
4 4
 #break dump_all_statistic
5
-break lock_initialize
5
+#break lock_initialize
6 6
 run
... ...
@@ -30,6 +30,7 @@ extern int dont_fork;
30 30
 extern int log_stderr;
31 31
 extern int check_via;
32 32
 extern int received_dns;
33
+extern int loop_checks;
33 34
 
34 35
 extern int cfg_errors;
35 36
 extern unsigned int msg_no;
... ...
@@ -80,6 +80,7 @@ static char flags[]="NOCR:"
80 80
 static char help_msg[]= "\
81 81
 Usage: ser -l address [-l address] [options]\n\
82 82
 Options:\n\
83
+    -c		 Perform loop checks and compute branches\n\
83 84
     -f file      Configuration file (default " CFG_FILE ")\n\
84 85
     -p port      Listen on the specified port (default: 5060)\n\
85 86
     -l address   Listen on the specified address (multiple -l mean\n\
... ...
@@ -145,6 +146,7 @@ int debug = 0;
145 146
 int dont_fork = 0;
146 147
 int log_stderr = 0;
147 148
 int check_via =  0;        /* check if reply first via host==us */
149
+int loop_checks = 0;	/* calculate branches and check for loops/spirals */
148 150
 int received_dns = 0;      /* use dns and/or rdns or to see if we need to 
149 151
                               add a ;received=x.x.x.x to via: */
150 152
 
... ...
@@ -348,7 +350,7 @@ int main(int argc, char** argv)
348 350
 #ifdef STATS
349 351
 	"s:"
350 352
 #endif
351
-	"f:p:b:l:n:rRvdDEVh";
353
+	"f:p:b:l:n:rRvcdDEVh";
352 354
 	
353 355
 	while((c=getopt(argc,argv,options))!=-1){
354 356
 		switch(c){
... ...
@@ -402,6 +404,9 @@ int main(int argc, char** argv)
402 404
 			case 'v':
403 405
 					check_via=1;
404 406
 					break;
407
+			case 'c':
408
+					loop_checks=1;
409
+					break;
405 410
 			case 'r':
406 411
 					received_dns|=DO_DNS;
407 412
 					break;
... ...
@@ -126,6 +126,10 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg )
126 126
     new_msg->add_rm  = 0;
127 127
     /* repl_add_rm ( struct lump* ) -> have to be changed!!!!!!!  */
128 128
     new_msg->repl_add_rm  = 0;
129
+
130
+    /* append branch parameter */
131
+    new_msg->add_to_branch.s = (char *) sh_malloc( org_msg->add_to_branch.len );
132
+    memcpy( new_msg->add_to_branch.s, org_msg->add_to_branch.s, org_msg->add_to_branch.len );
129 133
 }
130 134
 
131 135
 
... ...
@@ -186,6 +186,7 @@ int t_lookup_request( struct sip_msg* p_msg )
186 186
  */
187 187
 int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int dest_port_param )
188 188
 {
189
+   int	branch = 0;	/* we don't do any forking right now */
189 190
    /* it's about the same transaction or not? */
190 191
    if ( global_msg_id != p_msg->id )
191 192
    {
... ...
@@ -208,7 +209,7 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
208 209
    }
209 210
 
210 211
    /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
211
-   if ( T->outbound_request[0]==NULL )
212
+   if ( T->outbound_request[branch]==NULL )
212 213
    {
213 214
       unsigned int dest_ip     = dest_ip_param;
214 215
       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
217 218
 
218 219
       DBG("DEBUG: t_forward: first time forwarding\n");
219 220
       /* allocates a new retrans_buff for the outbound request */
220
-      T->outbound_request[0] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
221
-      memset( T->outbound_request[0] , 0 , sizeof (struct retrans_buff) );
221
+      T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
222
+      memset( T->outbound_request[branch] , 0 , sizeof (struct retrans_buff) );
222 223
       T->nr_of_outgoings = 1;
223 224
 
224 225
       /* special case : CANCEL */
... ...
@@ -234,8 +235,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
234 235
             if ( (T2->status/100)==1 )
235 236
             {
236 237
                DBG("DEBUG: t_forward: it's CANCEL and I will send to the same place where INVITE went\n");
237
-               dest_ip    = T2->outbound_request[0]->dest_ip;
238
-               dest_port = T2->outbound_request[0]->dest_port;
238
+               dest_ip    = T2->outbound_request[branch]->dest_ip;
239
+               dest_port = T2->outbound_request[branch]->dest_port;
239 240
             }
240 241
             else {
241 242
                /* 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
246 247
       }/* end special case CANCEL*/
247 248
 
248 249
       /* store */
249
-      T->outbound_request[0]->tl[0].payload = &(T->outbound_request[0]);
250
-      T->outbound_request[0]->dest_ip         = dest_ip;
251
-      T->outbound_request[0]->dest_port      = dest_port;
252
-      T->outbound_request[0]->to.sin_family = AF_INET;
253
-      T->outbound_request[0]->to.sin_port     = htonl( dest_port ) ;
254
-      T->outbound_request[0]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
255
-
256
-      buf = build_req_buf_from_sip_req ( p_msg, &len);
250
+      T->outbound_request[branch]->tl[RETRASMISSIONS_LIST].payload = &(T->outbound_request[branch]);
251
+      T->outbound_request[branch]->dest_ip         = dest_ip;
252
+      T->outbound_request[branch]->dest_port      = dest_port;
253
+      T->outbound_request[branch]->to.sin_family = AF_INET;
254
+      T->outbound_request[branch]->to.sin_port     = htonl( dest_port ) ;
255
+      T->outbound_request[branch]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
256
+
257
+      if (add_branch_label( T, p_msg , branch )==-1) return -1;
258
+      buf = build_buf_from_sip_request  ( p_msg, &len);
257 259
       if (!buf)
258 260
          return -1;
259
-      T->outbound_request[0]->bufflen = len ;
260
-      T->outbound_request[0]->buffer   = (char*)sh_malloc( len );
261
-      memcpy( T->outbound_request[0]->buffer , buf , len );
261
+      T->outbound_request[branch]->bufflen = len ;
262
+      T->outbound_request[branch]->buffer   = (char*)sh_malloc( len );
263
+      memcpy( T->outbound_request[branch]->buffer , buf , len );
262 264
       free( buf ) ;
263 265
    }/* end for the first time */
264 266
 
265 267
 
266 268
    /* sets and starts the RETRANS timer */
267
-   T->outbound_request[0]->nr_retrans    = 0;
268
-   T->outbound_request[0]->max_retrans = (T->inbound_request->first_line.u.request.method_value==METHOD_INVITE) ? MAX_INVITE_RETR : MAX_NON_INVITE_RETR;
269
-   T->outbound_request[0]->timeout         = RETR_T1;
269
+   T->outbound_request[branch]->nr_retrans    = 0;
270
+   T->outbound_request[branch]->max_retrans = 
271
+	(T->inbound_request->first_line.u.request.method_value==METHOD_INVITE) ? 
272
+	MAX_INVITE_RETR : MAX_NON_INVITE_RETR;
273
+   T->outbound_request[branch]->timeout         = RETR_T1;
270 274
    /* send the request */
271
-   udp_send( T->outbound_request[0]->buffer , T->outbound_request[0]->bufflen , (struct sockaddr*)&(T->outbound_request[0]->to) , sizeof(struct sockaddr_in) );
275
+   udp_send( T->outbound_request[branch]->buffer , T->outbound_request[branch]->bufflen , 
276
+		&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
272 277
 }
273 278
 
274 279
 
... ...
@@ -865,4 +870,12 @@ void delete_handler( void *attr)
865 870
        add_to_tail_of_timer_list( hash_table, &(p_cell->tl[DELETE_LIST]), DELETE_LIST, DEL_TIME_OUT );
866 871
 }
867 872
 
868
-
873
+/* append appropriate branch labels for fast reply-transaction matching
874
+   to outgoing requests
875
+*/
876
+int add_branch_label( struct cell *trans, struct sip_msg *p_msg, int branch )
877
+{	trans->label;
878
+	trans->hash_index;
879
+	p_msg->add_to_branch;
880
+	branch;
881
+}
... ...
@@ -93,6 +93,6 @@ void final_response_handler( void *);
93 93
 void wait_handler( void *);
94 94
 void delete_handler( void *);
95 95
 
96
-
96
+int add_branch_label( struct cell *Trans, struct sip_msg *p_msg , int branch );
97 97
 
98 98
 #endif
... ...
@@ -167,6 +167,8 @@ struct sip_msg{
167 167
 
168 168
 	struct lump* add_rm;      /* used for all the forwarded messages */
169 169
 	struct lump* repl_add_rm; /* only for localy generated replies !!!*/
170
+
171
+	str add_to_branch; /* whatever whoever want to append to branch comes here */
170 172
 	
171 173
 };
172 174
 
... ...
@@ -4,9 +4,11 @@
4 4
 #include "mem.h"
5 5
 #include "dprint.h"
6 6
 #include "config.h"
7
+#include "md5utils.h"
7 8
 #include <netdb.h>
8 9
 
9 10
 
11
+
10 12
 #define MAX_VIA_LINE_SIZE      240
11 13
 #define MAX_RECEIVED_SIZE  57
12 14
 
... ...
@@ -56,7 +58,7 @@ static inline char* q_inet_itoa(unsigned long ip)
56 58
 		q_inet_itoa_buf[offset+2]=c+'0';
57 59
 		q_inet_itoa_buf[offset+3]=0;
58 60
 	}else if (b){
59
-		q_inet_itoa_buf[offset]=b+'0';
61
+		
60 62
 		q_inet_itoa_buf[offset+1]=c+'0';
61 63
 		q_inet_itoa_buf[offset+2]=0;
62 64
 	}else{
... ...
@@ -112,7 +114,7 @@ int check_address(unsigned long ip, char *name, int resolver)
112 114
 
113 115
 char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_len)
114 116
 {
115
-	unsigned int len, new_len, via_len, received_len, uri_len;
117
+	unsigned int len, new_len, via_len, received_len, uri_len, branch_len;
116 118
 	char* line_buf;
117 119
 	char* received_buf;
118 120
 	char* tmp;
... ...
@@ -144,13 +146,52 @@ char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_le
144 146
 						names[0], port_no);
145 147
 */
146 148
 	via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/
147
-	if ((via_len+port_no_str_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
149
+
150
+	/* jku: if we compute branches using MD5 it will take 32 bytes */
151
+	branch_len= (loop_checks ? MY_BRANCH_LEN : MY_BRANCH_LEN -1 + MD5_LEN) + msg->add_to_branch.len;
152
+
153
+	if ((via_len+port_no_str_len+branch_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
148 154
 		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
149 155
 		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
150 156
 		if (port_no!=SIP_PORT){
151 157
 			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
152 158
 			via_len+=port_no_str_len;
153 159
 		}
160
+
161
+		/* jku: branch parameter */
162
+		memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN );
163
+		via_len+=MY_BRANCH_LEN;
164
+		/* loop checks ? */
165
+		if (loop_checks) {
166
+
167
+			if (	(msg->from || (parse_headers( msg, HDR_FROM)!=-1 && msg->from)) &&
168
+				(msg->to|| (parse_headers( msg, HDR_TO)!=-1 && msg->to)) &&
169
+				(msg->callid|| (parse_headers( msg, HDR_CALLID)!=-1 && msg->callid)) &&
170
+				(msg->cseq|| (parse_headers( msg, HDR_CSEQ)!=-1 && msg->cseq)) ) {
171
+
172
+				str src[5];
173
+				int r;
174
+			
175
+				src[0]= msg->from->body;
176
+				src[1]= msg->to->body; 
177
+				src[2]= msg->callid->body; 
178
+				src[3]= msg->first_line.u.request.uri; 
179
+				src[4]= ((struct cseq_body *)(msg->cseq->parsed))->number;
180
+
181
+				MDStringArray ( line_buf+via_len-1, src, 5 );
182
+				DBG("DEBUG: build_buf_from_sip_request: branch loop detection: %s, %s, %s, %s, %s -> %s32\n",
183
+					msg->from->body.s, msg->to->body.s, msg->callid->body.s, 
184
+					msg->first_line.u.request.uri.s,
185
+					((struct cseq_body *)(msg->cseq->parsed))->number.s,
186
+					line_buf+via_len-1 );
187
+				via_len+=MD5_LEN - 1;
188
+				
189
+			} else DBG("DEBUG: build_buf_from_sip_request: required HFs for loop checking missing\n");
190
+		}
191
+		/* someone wants me to add something to branch here ? */
192
+		memcpy(line_buf+via_len, msg->add_to_branch.s, msg->add_to_branch.len );
193
+		via_len+=msg->add_to_branch.len;
194
+
154 195
 		memcpy(line_buf+via_len, CRLF, CRLF_LEN);
155 196
 		via_len+=CRLF_LEN;
156 197
 		line_buf[via_len]=0; /* null terminate the string*/