Browse code

- applied parts of Maxim Sobolev patches (rport parsing) - fixed them so they should work - added a new via param (i=) for tcp use - fixed a bug in the via parser (transport.s not initialized), the bug was found by bogdan & daniel. - added an int2str function in ut.h (faster than snprintf %d).

Andrei Pelinescu-Onciul authored on 23/01/2003 18:58:13
Showing 5 changed files
... ...
@@ -85,6 +85,9 @@
85 85
 #define TOTAG_TOKEN ";tag="
86 86
 #define TOTAG_TOKEN_LEN (sizeof(TOTAG_TOKEN)-1)
87 87
 
88
+#define RPORT ";rport="
89
+#define RPORT_LEN 7
90
+
88 91
 #define SRV_PREFIX "_sip._udp."
89 92
 #define SRV_PREFIX_LEN 10
90 93
 
... ...
@@ -115,6 +118,7 @@
115 115
 /* forwarding  -- Via buffer dimensioning */
116 116
 #define MAX_VIA_LINE_SIZE	240
117 117
 #define MAX_RECEIVED_SIZE	57
118
+#define MAX_RPORT_SIZE		13
118 119
 
119 120
 /* maximum number of branches per transaction */
120 121
 #define MAX_BRANCHES    4
... ...
@@ -183,7 +183,6 @@ char* received_builder(struct sip_msg *msg, unsigned int *received_len)
183 183
 
184 184
 	extra_len = 0;
185 185
 	source_ip=&msg->rcv.src_ip;
186
-	buf = 0;
187 186
 
188 187
 	buf=pkg_malloc(sizeof(char)*MAX_RECEIVED_SIZE);
189 188
 	if (buf==0){
... ...
@@ -191,16 +190,11 @@ char* received_builder(struct sip_msg *msg, unsigned int *received_len)
191 191
 		LOG(L_ERR, "ERROR: received_builder: out of memory\n");
192 192
 		return 0;
193 193
 	}
194
-	/*
195
-	received_len=snprintf(buf, MAX_RECEIVED_SIZE,
196
-							";received=%s",
197
-							inet_ntoa(*(struct in_addr *)&source_ip));
198
-	*/
199 194
 	memcpy(buf, RECEIVED, RECEIVED_LEN);
200 195
 	if ( (tmp=ip_addr2a(source_ip))==0)
201 196
 		return 0; /* error*/
202 197
 	tmp_len=strlen(tmp);
203
-	len=RECEIVED_LEN+tmp_len;
198
+	len=RECEIVED_LEN+tmp_len+1; /* space for  null termination */
204 199
 	if(source_ip->af==AF_INET6){
205 200
 		len+=2;
206 201
 		buf[RECEIVED_LEN]='[';
... ...
@@ -217,6 +211,32 @@ char* received_builder(struct sip_msg *msg, unsigned int *received_len)
217 217
 
218 218
 
219 219
 
220
+char* rport_builder(struct sip_msg *msg, unsigned int *rport_len)
221
+{
222
+	char* buf;
223
+	char* tmp;
224
+	int tmp_len;
225
+	int len;
226
+	
227
+	tmp_len=0;
228
+	tmp=int2str(ntohs(msg->rcv.src_port), &tmp_len);
229
+	len=RPORT_LEN+tmp_len+1; /* space for null term */
230
+	buf=pkg_malloc(sizeof(char)*len);
231
+	if (buf==0){
232
+		ser_error=E_OUT_OF_MEM;
233
+		LOG(L_ERR, "ERROR: rport_builder: out of memory\n");
234
+		return 0;
235
+	}
236
+	memcpy(buf, RPORT, RPORT_LEN);
237
+	memcpy(buf+RPORT_LEN, tmp, tmp_len);
238
+	buf[len]=0; /*null terminate it*/
239
+	
240
+	*rport_len=len;
241
+	return buf;
242
+}
243
+
244
+
245
+
220 246
 /* computes the "unpacked" len of a lump list,
221 247
    code moved from build_req_from_req */
222 248
 static inline int lumps_len(struct lump* l)
... ...
@@ -402,9 +422,10 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
402 402
 								unsigned int *returned_len,
403 403
 								struct socket_info* send_sock, int proto)
404 404
 {
405
-	unsigned int len, new_len, received_len, uri_len, via_len;
405
+	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
406 406
 	char* line_buf;
407 407
 	char* received_buf;
408
+	char* rport_buf;
408 409
 	char* new_buf;
409 410
 	char* orig;
410 411
 	char* buf;
... ...
@@ -418,8 +439,10 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
418 418
 	buf=msg->buf;
419 419
 	len=msg->len;
420 420
 	received_len=0;
421
+	rport_len=0;
421 422
 	new_buf=0;
422 423
 	received_buf=0;
424
+	rport_buf=0;
423 425
 
424 426
 
425 427
 	line_buf = via_builder( &via_len, send_sock, 
... ...
@@ -437,6 +460,12 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
437 437
 		if ((received_buf=received_builder(msg,&received_len))==0)
438 438
 			goto error01;  /* free also line_buf */
439 439
 	}
440
+	
441
+	/* check if rport needs to be updated */
442
+	if (msg->via1->rport && msg->via1->rport->value.s==0){
443
+		if ((rport_buf=rport_builder(msg, &rport_len))==0)
444
+			goto error01; /* free everything */
445
+	}
440 446
 
441 447
 	/* add via header to the list */
442 448
 	/* try to add it before msg. 1st via */
... ...
@@ -462,9 +491,17 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
462 462
 		}
463 463
 		anchor=anchor_lump(&(msg->add_rm),msg->via1->hdr.s-buf+size,0,
464 464
 				HDR_VIA);
465
-		if (anchor==0) goto error02; /* free also line_buf */
465
+		if (anchor==0) goto error02; /* free received_buf */
466 466
 		if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA)
467
-				==0 ) goto error02; /* free also line_buf */
467
+				==0 ) goto error02; /* free received_buf */
468
+	}
469
+	/* if rport needs to be updated, delete it and add it's value */
470
+	if (rport_len){
471
+		anchor=del_lump(&(msg->add_rm), msg->via1->rport->name.s-buf,
472
+							msg->via1->rport->name.len, HDR_VIA);
473
+		if (anchor==0) goto error03; /* free rport_buf*/
474
+		if (insert_new_lump_after(anchor, rport_buf, rport_len, HDR_VIA)==0)
475
+			goto error03; /* free rport_buf*/
468 476
 	}
469 477
 
470 478
 	/* compute new msg len and fix overlapping zones*/
... ...
@@ -514,6 +551,8 @@ error01:
514 514
 	pkg_free(line_buf);
515 515
 error02:
516 516
 	if (received_buf) pkg_free(received_buf);
517
+error03:
518
+	if (rport_buf) pkg_free(rport_buf);
517 519
 error00:
518 520
 	*returned_len=0;
519 521
 	return 0;
... ...
@@ -29,14 +29,14 @@
29 29
  */
30 30
 
31 31
 
32
-/* parsing:           compact form:
33
- */
34 32
 
35 33
 /* 
36
- * still TODO/test:
37
- *  x parse next via
38
- *  - return a list of header structs
39
- *  - return list of params
34
+ *  2003-01-21  added rport parsing code, contributed by
35
+ *               Maxim Sobolev  <sobomax@FreeBSD.org>
36
+ *  2003-01-23  added extra via param parsing code (i=...), used
37
+ *               by tcp to identify the sending socket, by andrei
38
+ *  2003-01-23  fixed rport parsing code to accept rport w/o any value,
39
+ *               by andrei
40 40
  */
41 41
 
42 42
 
... ...
@@ -80,8 +80,8 @@ enum {
80 80
 
81 81
 
82 82
 /* param related states
83
- * WARNING: keep the FIN*, GEN_PARAM & PARAM_ERROR in sync w/ PARAM_* from
84
- * msg_parser.h !*/
83
+ * WARNING: keep in sync with parse_via.h, PARAM_HIDDEN, ...
84
+ */
85 85
 enum {	
86 86
 	L_VALUE = 200, F_VALUE, P_VALUE, P_STRING,
87 87
 	HIDDEN1, HIDDEN2, HIDDEN3, HIDDEN4, HIDDEN5,
... ...
@@ -90,8 +90,10 @@ enum {
90 90
 	MADDR1, MADDR2, MADDR3, MADDR4,
91 91
 	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
92 92
 	RECEIVED7,
93
+	RPORT1, RPORT2, RPORT3,
93 94
 	     /* fin states (227-...)*/
94 95
 	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
96
+	FIN_RPORT, FIN_I
95 97
 	     /*GEN_PARAM,
96 98
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
97 99
 };
... ...
@@ -130,6 +132,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
130 130
 					case FIN_TTL:
131 131
 					case FIN_MADDR:
132 132
 					case FIN_RECEIVED:
133
+					case FIN_RPORT:
134
+					case FIN_I:
133 135
 						*tmp=0;
134 136
 						param->type=state;
135 137
 						param->name.len=tmp-param->name.s;
... ...
@@ -165,6 +169,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
165 165
 					case FIN_TTL:
166 166
 					case FIN_MADDR:
167 167
 					case FIN_RECEIVED:
168
+					case FIN_RPORT:
169
+					case FIN_I:
168 170
 						*tmp=0;
169 171
 						param->type=state;
170 172
 						param->name.len=tmp-param->name.s;
... ...
@@ -205,6 +211,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
205 205
 					case FIN_TTL:
206 206
 					case FIN_MADDR:
207 207
 					case FIN_RECEIVED:
208
+					case FIN_RPORT:
209
+					case FIN_I:
208 210
 						*tmp=0;
209 211
 						param->type=state;
210 212
 						param->name.len=tmp-param->name.s;
... ...
@@ -236,6 +244,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
236 236
 					case FIN_TTL:
237 237
 					case FIN_MADDR:
238 238
 					case FIN_RECEIVED:
239
+					case FIN_RPORT:
240
+					case FIN_I:
239 241
 						*tmp=0;
240 242
 						param->type=state;
241 243
 						param->name.len=tmp-param->name.s;
... ...
@@ -263,6 +273,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
263 263
 			case ';':
264 264
 				switch(state){
265 265
 					case FIN_HIDDEN:
266
+					case FIN_RPORT: /* rport can appear w/o a value */
266 267
 						*tmp=0;
267 268
 						param->type=state;
268 269
 						param->name.len=tmp-param->name.s;
... ...
@@ -272,6 +283,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
272 272
 					case FIN_MADDR:
273 273
 					case FIN_TTL:
274 274
 					case FIN_RECEIVED:
275
+					case FIN_I:
275 276
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
276 277
 								" state %d\n", *tmp, state);
277 278
 						goto error;
... ...
@@ -292,6 +304,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
292 292
 			case ',':
293 293
 				switch(state){
294 294
 					case FIN_HIDDEN:
295
+					case FIN_RPORT:
295 296
 						*tmp=0;
296 297
 						param->type=state;
297 298
 						param->name.len=tmp-param->name.s;
... ...
@@ -301,6 +314,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
301 301
 					case FIN_MADDR:
302 302
 					case FIN_TTL:
303 303
 					case FIN_RECEIVED:
304
+					case FIN_I:
304 305
 						LOG(L_ERR, "ERROR: parse_via_param: new via found" 
305 306
 								"(',') when '=' expected (state %d=)\n",
306 307
 								state);
... ...
@@ -346,7 +360,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
346 346
 			case 'I':
347 347
 				switch(state){
348 348
 					case F_PARAM:
349
-						state=GEN_PARAM;
349
+						state=FIN_I;
350 350
 						param->name.s=tmp;
351 351
 						break;
352 352
 					case HIDDEN1:
... ...
@@ -463,6 +477,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
463 463
 					case TTL1:
464 464
 						state=TTL2;
465 465
 						break;
466
+					case RPORT3:
467
+						state=FIN_RPORT;
468
+						break;
466 469
 					case GEN_PARAM:
467 470
 						break;
468 471
 					case F_CR:
... ...
@@ -550,6 +567,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
550 550
 					case BRANCH1:
551 551
 						state=BRANCH2;
552 552
 						break;
553
+					case RPORT2:
554
+						state=RPORT3;
555
+						break;
553 556
 					case GEN_PARAM:
554 557
 						break;
555 558
 					case F_CR:
... ...
@@ -624,14 +644,43 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
624 624
 						state=GEN_PARAM;
625 625
 				}
626 626
 				break;
627
-
627
+			case 'p':
628
+			case 'P':
629
+				switch(state){
630
+					case RECEIVED1:
631
+						state=RPORT1;
632
+						break;
633
+					case F_CR:
634
+					case F_LF:
635
+					case F_CRLF:
636
+						state=END_OF_HEADER;
637
+						goto end_via;
638
+					default:
639
+						state=GEN_PARAM;
640
+				}
641
+				break;
642
+			case 'o':
643
+			case 'O':
644
+				switch(state){
645
+					case RPORT1:
646
+						state=RPORT2;
647
+						break;
648
+					case F_CR:
649
+					case F_LF:
650
+					case F_CRLF:
651
+						state=END_OF_HEADER;
652
+						goto end_via;
653
+					default:
654
+						state=GEN_PARAM;
655
+				}
656
+				break;
628 657
 			default:
629 658
 				switch(state){
630 659
 					case F_PARAM:
631 660
 						state=GEN_PARAM;
632 661
 						param->name.s=tmp;
633 662
 						break;
634
-					case  GEN_PARAM:
663
+					case GEN_PARAM:
635 664
 						break;
636 665
 					case F_CR:
637 666
 					case F_LF:
... ...
@@ -755,6 +804,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
755 755
 						param->value.len=tmp-param->value.s;
756 756
 						state=F_PARAM;
757 757
 						goto endofvalue;
758
+					case F_VALUE:
759
+						*tmp=0;
760
+						param->value.len=0;
761
+						state=F_PARAM;
762
+						goto endofvalue;
758 763
 					case P_STRING:
759 764
 						break; /* what to do? */
760 765
 					case F_LF:
... ...
@@ -762,6 +816,14 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
762 762
 					case F_CRLF:
763 763
 						state=END_OF_HEADER;
764 764
 						goto end_via;
765
+					case L_VALUE:
766
+						if (param->type==FIN_RPORT){
767
+							param->value.len=0;
768
+							param->value.s=0; /* null value */
769
+							state=F_PARAM;
770
+							goto endofvalue;
771
+						};
772
+						/* no break */
765 773
 					default:
766 774
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
767 775
 								" in state %d\n", *tmp, state);
... ...
@@ -776,11 +838,19 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
776 776
 						state=F_VIA;
777 777
 						goto endofvalue;
778 778
 					case P_STRING:
779
-						case F_LF:
779
+					case F_LF:
780 780
 					case F_CR:
781 781
 					case F_CRLF:
782 782
 						state=END_OF_HEADER;
783 783
 						goto end_via;
784
+					case L_VALUE:
785
+						if (param->type==FIN_RPORT){
786
+							param->value.len=0;
787
+							param->value.s=0; /* null value */
788
+							state=F_VIA;
789
+							goto endofvalue;
790
+						};
791
+						/* no break */
784 792
 					default:
785 793
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
786 794
 								" in state %d\n", *tmp, state);
... ...
@@ -847,8 +917,10 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
847 847
 	
848 848
  end_via:
849 849
 	     /* if we are here we found an "unexpected" end of via
850
-	      *  (cr/lf). This is valid only if the param type is GEN_PARAM*/
851
-	if (param->type==GEN_PARAM){
850
+	      *  (cr/lf). This is valid only if the param type is GEN_PARAM or
851
+		  *  RPORT (the only ones which can miss the value; HIDDEN is a 
852
+		  *  special case )*/
853
+	if ((param->type==GEN_PARAM)||(param->type==PARAM_RPORT)){
852 854
 		saved_state=L_PARAM; /* change the saved_state, we have an unknown
853 855
 		                        param. w/o a value */
854 856
 		goto endofparam;
... ...
@@ -1097,6 +1169,7 @@ parse_again:
1097 1097
 				switch(state){
1098 1098
 					case F_PROTO:
1099 1099
 						state=UDP1;
1100
+						vb->transport.s=tmp;
1100 1101
 						break;
1101 1102
 					default:
1102 1103
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1121,6 +1194,7 @@ parse_again:
1121 1121
 				switch(state){
1122 1122
 					case F_PROTO:
1123 1123
 						state=TCP1;
1124
+						vb->transport.s=tmp;
1124 1125
 						break;
1125 1126
 					default:
1126 1127
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1713,6 +1787,10 @@ parse_again:
1713 1713
 							vb->branch=param;
1714 1714
 						else if (param->type==PARAM_RECEIVED)
1715 1715
 							vb->received=param;
1716
+						else if (param->type==PARAM_RPORT)
1717
+							vb->rport=param;
1718
+						else if (param->type==PARAM_I)
1719
+							vb->i=param;
1716 1720
 						break;
1717 1721
 					case P_PARAM:
1718 1722
 						break;
... ...
@@ -25,6 +25,14 @@
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 26
  */
27 27
 
28
+/* 
29
+ *  2003-01-21  added rport parsing code, contributed by
30
+ *               Maxim Sobolev  <sobomax@FreeBSD.org>
31
+ *  2003-01-21  added extra via param parsing code (i=...), used
32
+ *               by tcp to identify the sending socket, by andrei
33
+ */
34
+
35
+
28 36
 
29 37
 #ifndef PARSE_VIA_H
30 38
 #define PARSE_VIA_H
... ...
@@ -32,11 +40,11 @@
32 32
 #include "../str.h"
33 33
 
34 34
 /* via param types
35
- * WARNING: keep in sync w/ FIN_*, GEN_PARAM and PARAM_ERROR from via_parse.c
35
+ * WARNING: keep in sync with parse_via.c FIN_HIDDEN... 
36 36
  */
37 37
 enum {
38 38
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
39
-	PARAM_MADDR, PARAM_RECEIVED, GEN_PARAM,
39
+	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, GEN_PARAM,
40 40
 	PARAM_ERROR
41 41
 };
42 42
 
... ...
@@ -72,6 +80,8 @@ struct via_body {
72 72
 	struct via_param* branch;
73 73
 	str tid; /* transaction id, part of branch */
74 74
 	struct via_param* received;
75
+	struct via_param* rport;
76
+	struct via_param* i;
75 77
 	
76 78
 	struct via_body* next; /* pointer to next via body string if
77 79
 				  compact via or null */
... ...
@@ -143,6 +143,28 @@ static inline int btostr( char *p,  unsigned char val)
143 143
 
144 144
 
145 145
 
146
+/* returns a pointer to a static buffer containint l in asciiz & sets len */
147
+static inline char* int2str(unsigned int l, int* len)
148
+{
149
+	static char r[11]; /* 10 digits + 0 */
150
+	int i;
151
+	
152
+	i=9;
153
+	r[10]=0; /* null terminate */
154
+	do{
155
+		r[i]=l%10+'0';
156
+		i--;
157
+		l/=10;
158
+	}while(l && (i>=0));
159
+	if (l && (i<0)){
160
+		LOG(L_CRIT, "BUG: int2str: overflow\n");
161
+	}
162
+	if (len) *len=9-i;
163
+	return &r[i+1];
164
+}
165
+
166
+
167
+
146 168
 /* faster memchr version */
147 169
 static inline char* q_memchr(char* p, int c, unsigned int size)
148 170
 {