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 118
 /* forwarding  -- Via buffer dimensioning */
116 119
 #define MAX_VIA_LINE_SIZE	240
117 120
 #define MAX_RECEIVED_SIZE	57
121
+#define MAX_RPORT_SIZE		13
118 122
 
119 123
 /* maximum number of branches per transaction */
120 124
 #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 190
 		LOG(L_ERR, "ERROR: received_builder: out of memory\n");
192 191
 		return 0;
193 192
 	}
194
-	/*
195
-	received_len=snprintf(buf, MAX_RECEIVED_SIZE,
196
-							";received=%s",
197
-							inet_ntoa(*(struct in_addr *)&source_ip));
198
-	*/
199 193
 	memcpy(buf, RECEIVED, RECEIVED_LEN);
200 194
 	if ( (tmp=ip_addr2a(source_ip))==0)
201 195
 		return 0; /* error*/
202 196
 	tmp_len=strlen(tmp);
203
-	len=RECEIVED_LEN+tmp_len;
197
+	len=RECEIVED_LEN+tmp_len+1; /* space for  null termination */
204 198
 	if(source_ip->af==AF_INET6){
205 199
 		len+=2;
206 200
 		buf[RECEIVED_LEN]='[';
... ...
@@ -217,6 +211,32 @@ char* received_builder(struct sip_msg *msg, unsigned int *received_len)
217 211
 
218 212
 
219 213
 
214
+char* rport_builder(struct sip_msg *msg, unsigned int *rport_len)
215
+{
216
+	char* buf;
217
+	char* tmp;
218
+	int tmp_len;
219
+	int len;
220
+	
221
+	tmp_len=0;
222
+	tmp=int2str(ntohs(msg->rcv.src_port), &tmp_len);
223
+	len=RPORT_LEN+tmp_len+1; /* space for null term */
224
+	buf=pkg_malloc(sizeof(char)*len);
225
+	if (buf==0){
226
+		ser_error=E_OUT_OF_MEM;
227
+		LOG(L_ERR, "ERROR: rport_builder: out of memory\n");
228
+		return 0;
229
+	}
230
+	memcpy(buf, RPORT, RPORT_LEN);
231
+	memcpy(buf+RPORT_LEN, tmp, tmp_len);
232
+	buf[len]=0; /*null terminate it*/
233
+	
234
+	*rport_len=len;
235
+	return buf;
236
+}
237
+
238
+
239
+
220 240
 /* computes the "unpacked" len of a lump list,
221 241
    code moved from build_req_from_req */
222 242
 static inline int lumps_len(struct lump* l)
... ...
@@ -402,9 +422,10 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
402 422
 								unsigned int *returned_len,
403 423
 								struct socket_info* send_sock, int proto)
404 424
 {
405
-	unsigned int len, new_len, received_len, uri_len, via_len;
425
+	unsigned int len, new_len, received_len, rport_len, uri_len, via_len;
406 426
 	char* line_buf;
407 427
 	char* received_buf;
428
+	char* rport_buf;
408 429
 	char* new_buf;
409 430
 	char* orig;
410 431
 	char* buf;
... ...
@@ -418,8 +439,10 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
418 439
 	buf=msg->buf;
419 440
 	len=msg->len;
420 441
 	received_len=0;
442
+	rport_len=0;
421 443
 	new_buf=0;
422 444
 	received_buf=0;
445
+	rport_buf=0;
423 446
 
424 447
 
425 448
 	line_buf = via_builder( &via_len, send_sock, 
... ...
@@ -437,6 +460,12 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
437 460
 		if ((received_buf=received_builder(msg,&received_len))==0)
438 461
 			goto error01;  /* free also line_buf */
439 462
 	}
463
+	
464
+	/* check if rport needs to be updated */
465
+	if (msg->via1->rport && msg->via1->rport->value.s==0){
466
+		if ((rport_buf=rport_builder(msg, &rport_len))==0)
467
+			goto error01; /* free everything */
468
+	}
440 469
 
441 470
 	/* add via header to the list */
442 471
 	/* try to add it before msg. 1st via */
... ...
@@ -462,9 +491,17 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
462 491
 		}
463 492
 		anchor=anchor_lump(&(msg->add_rm),msg->via1->hdr.s-buf+size,0,
464 493
 				HDR_VIA);
465
-		if (anchor==0) goto error02; /* free also line_buf */
494
+		if (anchor==0) goto error02; /* free received_buf */
466 495
 		if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA)
467
-				==0 ) goto error02; /* free also line_buf */
496
+				==0 ) goto error02; /* free received_buf */
497
+	}
498
+	/* if rport needs to be updated, delete it and add it's value */
499
+	if (rport_len){
500
+		anchor=del_lump(&(msg->add_rm), msg->via1->rport->name.s-buf,
501
+							msg->via1->rport->name.len, HDR_VIA);
502
+		if (anchor==0) goto error03; /* free rport_buf*/
503
+		if (insert_new_lump_after(anchor, rport_buf, rport_len, HDR_VIA)==0)
504
+			goto error03; /* free rport_buf*/
468 505
 	}
469 506
 
470 507
 	/* compute new msg len and fix overlapping zones*/
... ...
@@ -514,6 +551,8 @@ error01:
514 551
 	pkg_free(line_buf);
515 552
 error02:
516 553
 	if (received_buf) pkg_free(received_buf);
554
+error03:
555
+	if (rport_buf) pkg_free(rport_buf);
517 556
 error00:
518 557
 	*returned_len=0;
519 558
 	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 132
 					case FIN_TTL:
131 133
 					case FIN_MADDR:
132 134
 					case FIN_RECEIVED:
135
+					case FIN_RPORT:
136
+					case FIN_I:
133 137
 						*tmp=0;
134 138
 						param->type=state;
135 139
 						param->name.len=tmp-param->name.s;
... ...
@@ -165,6 +169,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
165 169
 					case FIN_TTL:
166 170
 					case FIN_MADDR:
167 171
 					case FIN_RECEIVED:
172
+					case FIN_RPORT:
173
+					case FIN_I:
168 174
 						*tmp=0;
169 175
 						param->type=state;
170 176
 						param->name.len=tmp-param->name.s;
... ...
@@ -205,6 +211,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
205 211
 					case FIN_TTL:
206 212
 					case FIN_MADDR:
207 213
 					case FIN_RECEIVED:
214
+					case FIN_RPORT:
215
+					case FIN_I:
208 216
 						*tmp=0;
209 217
 						param->type=state;
210 218
 						param->name.len=tmp-param->name.s;
... ...
@@ -236,6 +244,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
236 244
 					case FIN_TTL:
237 245
 					case FIN_MADDR:
238 246
 					case FIN_RECEIVED:
247
+					case FIN_RPORT:
248
+					case FIN_I:
239 249
 						*tmp=0;
240 250
 						param->type=state;
241 251
 						param->name.len=tmp-param->name.s;
... ...
@@ -263,6 +273,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
263 273
 			case ';':
264 274
 				switch(state){
265 275
 					case FIN_HIDDEN:
276
+					case FIN_RPORT: /* rport can appear w/o a value */
266 277
 						*tmp=0;
267 278
 						param->type=state;
268 279
 						param->name.len=tmp-param->name.s;
... ...
@@ -272,6 +283,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
272 283
 					case FIN_MADDR:
273 284
 					case FIN_TTL:
274 285
 					case FIN_RECEIVED:
286
+					case FIN_I:
275 287
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
276 288
 								" state %d\n", *tmp, state);
277 289
 						goto error;
... ...
@@ -292,6 +304,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
292 304
 			case ',':
293 305
 				switch(state){
294 306
 					case FIN_HIDDEN:
307
+					case FIN_RPORT:
295 308
 						*tmp=0;
296 309
 						param->type=state;
297 310
 						param->name.len=tmp-param->name.s;
... ...
@@ -301,6 +314,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
301 314
 					case FIN_MADDR:
302 315
 					case FIN_TTL:
303 316
 					case FIN_RECEIVED:
317
+					case FIN_I:
304 318
 						LOG(L_ERR, "ERROR: parse_via_param: new via found" 
305 319
 								"(',') when '=' expected (state %d=)\n",
306 320
 								state);
... ...
@@ -346,7 +360,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
346 360
 			case 'I':
347 361
 				switch(state){
348 362
 					case F_PARAM:
349
-						state=GEN_PARAM;
363
+						state=FIN_I;
350 364
 						param->name.s=tmp;
351 365
 						break;
352 366
 					case HIDDEN1:
... ...
@@ -463,6 +477,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
463 477
 					case TTL1:
464 478
 						state=TTL2;
465 479
 						break;
480
+					case RPORT3:
481
+						state=FIN_RPORT;
482
+						break;
466 483
 					case GEN_PARAM:
467 484
 						break;
468 485
 					case F_CR:
... ...
@@ -550,6 +567,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
550 567
 					case BRANCH1:
551 568
 						state=BRANCH2;
552 569
 						break;
570
+					case RPORT2:
571
+						state=RPORT3;
572
+						break;
553 573
 					case GEN_PARAM:
554 574
 						break;
555 575
 					case F_CR:
... ...
@@ -624,14 +644,43 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
624 644
 						state=GEN_PARAM;
625 645
 				}
626 646
 				break;
627
-
647
+			case 'p':
648
+			case 'P':
649
+				switch(state){
650
+					case RECEIVED1:
651
+						state=RPORT1;
652
+						break;
653
+					case F_CR:
654
+					case F_LF:
655
+					case F_CRLF:
656
+						state=END_OF_HEADER;
657
+						goto end_via;
658
+					default:
659
+						state=GEN_PARAM;
660
+				}
661
+				break;
662
+			case 'o':
663
+			case 'O':
664
+				switch(state){
665
+					case RPORT1:
666
+						state=RPORT2;
667
+						break;
668
+					case F_CR:
669
+					case F_LF:
670
+					case F_CRLF:
671
+						state=END_OF_HEADER;
672
+						goto end_via;
673
+					default:
674
+						state=GEN_PARAM;
675
+				}
676
+				break;
628 677
 			default:
629 678
 				switch(state){
630 679
 					case F_PARAM:
631 680
 						state=GEN_PARAM;
632 681
 						param->name.s=tmp;
633 682
 						break;
634
-					case  GEN_PARAM:
683
+					case GEN_PARAM:
635 684
 						break;
636 685
 					case F_CR:
637 686
 					case F_LF:
... ...
@@ -755,6 +804,11 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
755 804
 						param->value.len=tmp-param->value.s;
756 805
 						state=F_PARAM;
757 806
 						goto endofvalue;
807
+					case F_VALUE:
808
+						*tmp=0;
809
+						param->value.len=0;
810
+						state=F_PARAM;
811
+						goto endofvalue;
758 812
 					case P_STRING:
759 813
 						break; /* what to do? */
760 814
 					case F_LF:
... ...
@@ -762,6 +816,14 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
762 816
 					case F_CRLF:
763 817
 						state=END_OF_HEADER;
764 818
 						goto end_via;
819
+					case L_VALUE:
820
+						if (param->type==FIN_RPORT){
821
+							param->value.len=0;
822
+							param->value.s=0; /* null value */
823
+							state=F_PARAM;
824
+							goto endofvalue;
825
+						};
826
+						/* no break */
765 827
 					default:
766 828
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
767 829
 								" in state %d\n", *tmp, state);
... ...
@@ -776,11 +838,19 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
776 838
 						state=F_VIA;
777 839
 						goto endofvalue;
778 840
 					case P_STRING:
779
-						case F_LF:
841
+					case F_LF:
780 842
 					case F_CR:
781 843
 					case F_CRLF:
782 844
 						state=END_OF_HEADER;
783 845
 						goto end_via;
846
+					case L_VALUE:
847
+						if (param->type==FIN_RPORT){
848
+							param->value.len=0;
849
+							param->value.s=0; /* null value */
850
+							state=F_VIA;
851
+							goto endofvalue;
852
+						};
853
+						/* no break */
784 854
 					default:
785 855
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
786 856
 								" in state %d\n", *tmp, state);
... ...
@@ -847,8 +917,10 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
847 917
 	
848 918
  end_via:
849 919
 	     /* 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){
920
+	      *  (cr/lf). This is valid only if the param type is GEN_PARAM or
921
+		  *  RPORT (the only ones which can miss the value; HIDDEN is a 
922
+		  *  special case )*/
923
+	if ((param->type==GEN_PARAM)||(param->type==PARAM_RPORT)){
852 924
 		saved_state=L_PARAM; /* change the saved_state, we have an unknown
853 925
 		                        param. w/o a value */
854 926
 		goto endofparam;
... ...
@@ -1097,6 +1169,7 @@ parse_again:
1097 1169
 				switch(state){
1098 1170
 					case F_PROTO:
1099 1171
 						state=UDP1;
1172
+						vb->transport.s=tmp;
1100 1173
 						break;
1101 1174
 					default:
1102 1175
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1121,6 +1194,7 @@ parse_again:
1121 1194
 				switch(state){
1122 1195
 					case F_PROTO:
1123 1196
 						state=TCP1;
1197
+						vb->transport.s=tmp;
1124 1198
 						break;
1125 1199
 					default:
1126 1200
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1713,6 +1787,10 @@ parse_again:
1713 1787
 							vb->branch=param;
1714 1788
 						else if (param->type==PARAM_RECEIVED)
1715 1789
 							vb->received=param;
1790
+						else if (param->type==PARAM_RPORT)
1791
+							vb->rport=param;
1792
+						else if (param->type==PARAM_I)
1793
+							vb->i=param;
1716 1794
 						break;
1717 1795
 					case P_PARAM:
1718 1796
 						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 40
 #include "../str.h"
33 41
 
34 42
 /* via param types
35
- * WARNING: keep in sync w/ FIN_*, GEN_PARAM and PARAM_ERROR from via_parse.c
43
+ * WARNING: keep in sync with parse_via.c FIN_HIDDEN... 
36 44
  */
37 45
 enum {
38 46
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
39
-	PARAM_MADDR, PARAM_RECEIVED, GEN_PARAM,
47
+	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, GEN_PARAM,
40 48
 	PARAM_ERROR
41 49
 };
42 50
 
... ...
@@ -72,6 +80,8 @@ struct via_body {
72 80
 	struct via_param* branch;
73 81
 	str tid; /* transaction id, part of branch */
74 82
 	struct via_param* received;
83
+	struct via_param* rport;
84
+	struct via_param* i;
75 85
 	
76 86
 	struct via_body* next; /* pointer to next via body string if
77 87
 				  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
 {