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 159
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
160 160
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
161 161
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
162
+<INITIAL>{LOOP_CHECKS}	{ count(); yylval.strval=yytext; return LOOP_CHECKS; }
162 163
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
163 164
 
164 165
 <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 161
 		| CHILDREN EQUAL error { yyerror("number expected"); } 
162 162
 		| CHECK_VIA EQUAL NUMBER { check_via=$3; }
163 163
 		| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
164
+		| LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
165
+		| LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
164 166
 		| LISTEN EQUAL ipv4  {
165 167
 								if (addresses_no < MAX_LISTEN){
166 168
 									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 145
 int dont_fork = 0;
146 146
 int log_stderr = 0;
147 147
 int check_via =  0;        /* check if reply first via host==us */
148
+int loop_checks = 0;	/* calculate branches and check for loops/spirals */
148 149
 int received_dns = 0;      /* use dns and/or rdns or to see if we need to 
149 150
                               add a ;received=x.x.x.x to via: */
150 151
 
... ...
@@ -348,7 +350,7 @@ int main(int argc, char** argv)
348 348
 #ifdef STATS
349 349
 	"s:"
350 350
 #endif
351
-	"f:p:b:l:n:rRvdDEVh";
351
+	"f:p:b:l:n:rRvcdDEVh";
352 352
 	
353 353
 	while((c=getopt(argc,argv,options))!=-1){
354 354
 		switch(c){
... ...
@@ -402,6 +404,9 @@ int main(int argc, char** argv)
402 402
 			case 'v':
403 403
 					check_via=1;
404 404
 					break;
405
+			case 'c':
406
+					loop_checks=1;
407
+					break;
405 408
 			case 'r':
406 409
 					received_dns|=DO_DNS;
407 410
 					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 208
    }
209 209
 
210 210
    /* if it's forwarded for the first time ; else the request is retransmited from the transaction buffer */
211
-   if ( T->outbound_request[0]==NULL )
211
+   if ( T->outbound_request[branch]==NULL )
212 212
    {
213 213
       unsigned int dest_ip     = dest_ip_param;
214 214
       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 217
 
218 218
       DBG("DEBUG: t_forward: first time forwarding\n");
219 219
       /* 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) );
220
+      T->outbound_request[branch] = (struct retrans_buff*)sh_malloc( sizeof(struct retrans_buff) );
221
+      memset( T->outbound_request[branch] , 0 , sizeof (struct retrans_buff) );
222 222
       T->nr_of_outgoings = 1;
223 223
 
224 224
       /* special case : CANCEL */
... ...
@@ -234,8 +235,8 @@ int t_forward( struct sip_msg* p_msg , unsigned int dest_ip_param , unsigned int
234 234
             if ( (T2->status/100)==1 )
235 235
             {
236 236
                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;
237
+               dest_ip    = T2->outbound_request[branch]->dest_ip;
238
+               dest_port = T2->outbound_request[branch]->dest_port;
239 239
             }
240 240
             else {
241 241
                /* 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 246
       }/* end special case CANCEL*/
247 247
 
248 248
       /* 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);
249
+      T->outbound_request[branch]->tl[RETRASMISSIONS_LIST].payload = &(T->outbound_request[branch]);
250
+      T->outbound_request[branch]->dest_ip         = dest_ip;
251
+      T->outbound_request[branch]->dest_port      = dest_port;
252
+      T->outbound_request[branch]->to.sin_family = AF_INET;
253
+      T->outbound_request[branch]->to.sin_port     = htonl( dest_port ) ;
254
+      T->outbound_request[branch]->to.sin_addr.s_addr = ntohl( dest_ip ) ;
255
+
256
+      if (add_branch_label( T, p_msg , branch )==-1) return -1;
257
+      buf = build_buf_from_sip_request  ( p_msg, &len);
257 258
       if (!buf)
258 259
          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 );
260
+      T->outbound_request[branch]->bufflen = len ;
261
+      T->outbound_request[branch]->buffer   = (char*)sh_malloc( len );
262
+      memcpy( T->outbound_request[branch]->buffer , buf , len );
262 263
       free( buf ) ;
263 264
    }/* end for the first time */
264 265
 
265 266
 
266 267
    /* 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;
268
+   T->outbound_request[branch]->nr_retrans    = 0;
269
+   T->outbound_request[branch]->max_retrans = 
270
+	(T->inbound_request->first_line.u.request.method_value==METHOD_INVITE) ? 
271
+	MAX_INVITE_RETR : MAX_NON_INVITE_RETR;
272
+   T->outbound_request[branch]->timeout         = RETR_T1;
270 273
    /* 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) );
274
+   udp_send( T->outbound_request[branch]->buffer , T->outbound_request[branch]->bufflen , 
275
+		&(T->outbound_request[branch]->to) , sizeof(struct sockaddr_in) );
272 276
 }
273 277
 
274 278
 
... ...
@@ -865,4 +870,12 @@ void delete_handler( void *attr)
865 865
        add_to_tail_of_timer_list( hash_table, &(p_cell->tl[DELETE_LIST]), DELETE_LIST, DEL_TIME_OUT );
866 866
 }
867 867
 
868
-
868
+/* append appropriate branch labels for fast reply-transaction matching
869
+   to outgoing requests
870
+*/
871
+int add_branch_label( struct cell *trans, struct sip_msg *p_msg, int branch )
872
+{	trans->label;
873
+	trans->hash_index;
874
+	p_msg->add_to_branch;
875
+	branch;
876
+}
... ...
@@ -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 56
 		q_inet_itoa_buf[offset+2]=c+'0';
57 57
 		q_inet_itoa_buf[offset+3]=0;
58 58
 	}else if (b){
59
-		q_inet_itoa_buf[offset]=b+'0';
59
+		
60 60
 		q_inet_itoa_buf[offset+1]=c+'0';
61 61
 		q_inet_itoa_buf[offset+2]=0;
62 62
 	}else{
... ...
@@ -112,7 +114,7 @@ int check_address(unsigned long ip, char *name, int resolver)
112 112
 
113 113
 char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_len)
114 114
 {
115
-	unsigned int len, new_len, via_len, received_len, uri_len;
115
+	unsigned int len, new_len, via_len, received_len, uri_len, branch_len;
116 116
 	char* line_buf;
117 117
 	char* received_buf;
118 118
 	char* tmp;
... ...
@@ -144,13 +146,52 @@ char * build_req_buf_from_sip_req(struct sip_msg* msg, unsigned int *returned_le
144 144
 						names[0], port_no);
145 145
 */
146 146
 	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){
147
+
148
+	/* jku: if we compute branches using MD5 it will take 32 bytes */
149
+	branch_len= (loop_checks ? MY_BRANCH_LEN : MY_BRANCH_LEN -1 + MD5_LEN) + msg->add_to_branch.len;
150
+
151
+	if ((via_len+port_no_str_len+branch_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
148 152
 		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
149 153
 		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
150 154
 		if (port_no!=SIP_PORT){
151 155
 			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
152 156
 			via_len+=port_no_str_len;
153 157
 		}
158
+
159
+		/* jku: branch parameter */
160
+		memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN );
161
+		via_len+=MY_BRANCH_LEN;
162
+		/* loop checks ? */
163
+		if (loop_checks) {
164
+
165
+			if (	(msg->from || (parse_headers( msg, HDR_FROM)!=-1 && msg->from)) &&
166
+				(msg->to|| (parse_headers( msg, HDR_TO)!=-1 && msg->to)) &&
167
+				(msg->callid|| (parse_headers( msg, HDR_CALLID)!=-1 && msg->callid)) &&
168
+				(msg->cseq|| (parse_headers( msg, HDR_CSEQ)!=-1 && msg->cseq)) ) {
169
+
170
+				str src[5];
171
+				int r;
172
+			
173
+				src[0]= msg->from->body;
174
+				src[1]= msg->to->body; 
175
+				src[2]= msg->callid->body; 
176
+				src[3]= msg->first_line.u.request.uri; 
177
+				src[4]= ((struct cseq_body *)(msg->cseq->parsed))->number;
178
+
179
+				MDStringArray ( line_buf+via_len-1, src, 5 );
180
+				DBG("DEBUG: build_buf_from_sip_request: branch loop detection: %s, %s, %s, %s, %s -> %s32\n",
181
+					msg->from->body.s, msg->to->body.s, msg->callid->body.s, 
182
+					msg->first_line.u.request.uri.s,
183
+					((struct cseq_body *)(msg->cseq->parsed))->number.s,
184
+					line_buf+via_len-1 );
185
+				via_len+=MD5_LEN - 1;
186
+				
187
+			} else DBG("DEBUG: build_buf_from_sip_request: required HFs for loop checking missing\n");
188
+		}
189
+		/* someone wants me to add something to branch here ? */
190
+		memcpy(line_buf+via_len, msg->add_to_branch.s, msg->add_to_branch.len );
191
+		via_len+=msg->add_to_branch.len;
192
+
154 193
 		memcpy(line_buf+via_len, CRLF, CRLF_LEN);
155 194
 		via_len+=CRLF_LEN;
156 195
 		line_buf[via_len]=0; /* null terminate the string*/