Browse code

- switched to new via & header parsing - lots of new members added to sip_msg - all headers are parsed - merged with cvs version => compilation errors in receive.c

Andrei Pelinescu-Onciul authored on 22/11/2001 22:32:38
Showing 8 changed files
... ...
@@ -28,7 +28,7 @@ NAME=ser
28 28
 # DEBUG compiles in some extra debugging code
29 29
 # OLD_PARSER uses the old and stable parser (from ser 8.3.2)
30 30
 # DNS_IP_HACK faster ip address resolver for ip strings (e.g "127.0.0.1")
31
-DEFS=-DNOCR -DMACROEATER -DSTATS -DOLD_PARSER -DDNS_IP_HACK #-DNO_DEBUG 
31
+DEFS=-DNOCR -DMACROEATER -DSTATS -DDNS_IP_HACK #-DNO_DEBUG 
32 32
 #-DNO_LOG
33 33
 
34 34
 PROFILE=  # -pg #set this if you want profiling
... ...
@@ -47,8 +47,8 @@ ifeq ( mode, release )
47 47
 	CFLAGS=-O2 -Wcast-align $(PROFILE) -Winline#-Wmissing-prototypes 
48 48
 	LDFLAGS=-Wl,-O2 -Wl,-E $(PROFILE)
49 49
 else
50
-	CFLAGS=-g
51
-	LDFLAGS=-g
50
+	CFLAGS=-g -Wcast-align -Winline
51
+	LDFLAGS=-g -Wl,-E
52 52
 endif
53 53
 
54 54
 LEX=flex
... ...
@@ -192,7 +192,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
192 192
 		
193 193
 	
194 194
 	/* check if received needs to be added */
195
-	if (check_address(source_ip, msg->via1.host.s, received_dns)!=0){
195
+	if (check_address(source_ip, msg->via1->host.s, received_dns)!=0){
196 196
 		received_buf=malloc(sizeof(char)*MAX_RECEIVED_SIZE);
197 197
 		if (received_buf==0){
198 198
 			LOG(L_ERR, "ERROR: forward_request: out of memory\n");
... ...
@@ -214,22 +214,23 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
214 214
 	/* add via header to the list */
215 215
 	/* try to add it before msg. 1st via */
216 216
 	/*add first via, as an anchor for second via*/
217
-	anchor=anchor_lump(&(msg->add_rm), msg->via1.hdr.s-buf, 0, HDR_VIA);
217
+	anchor=anchor_lump(&(msg->add_rm), msg->via1->hdr.s-buf, 0, HDR_VIA);
218 218
 	if (anchor==0) goto error;
219 219
 	if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA)==0)
220 220
 		goto error;
221 221
 	/* if received needs to be added, add anchor after host and add it */
222 222
 	if (received_len){
223
-		if (msg->via1.params.s){
224
-				size= msg->via1.params.s-msg->via1.hdr.s-1; /*compensate 
223
+		if (msg->via1->params.s){
224
+				size= msg->via1->params.s-msg->via1->hdr.s-1; /*compensate 
225 225
 															  for ';' */
226 226
 		}else{
227
-				size= msg->via1.host.s-msg->via1.hdr.s+msg->via1.host.len;
228
-				if (msg->via1.port!=0){
229
-					size+=strlen(msg->via1.hdr.s+size+1)+1; /* +1 for ':'*/
227
+				size= msg->via1->host.s-msg->via1->hdr.s+msg->via1->host.len;
228
+				if (msg->via1->port!=0){
229
+					size+=strlen(msg->via1->hdr.s+size+1)+1; /* +1 for ':'*/
230 230
 				}
231 231
 		}
232
-		anchor=anchor_lump(&(msg->add_rm),msg->via1.hdr.s-buf+size,0, HDR_VIA);
232
+		anchor=anchor_lump(&(msg->add_rm),msg->via1->hdr.s-buf+size,0,
233
+				HDR_VIA);
233 234
 		if (anchor==0) goto error;
234 235
 		if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA) 
235 236
 				==0 ) goto error;
... ...
@@ -492,25 +493,26 @@ int forward_reply(struct sip_msg* msg)
492 493
 	/*check if first via host = us */
493 494
 	if (check_via){
494 495
 		for (r=0; r<addresses_no; r++)
495
-			if(strcmp(msg->via1.host.s, names[r])==0) break;
496
+			if(strcmp(msg->via1->host.s, names[r])==0) break;
496 497
 		if (r==addresses_no){
497 498
 			LOG(L_NOTICE, "ERROR: forward_reply: host in first via!=me :"
498
-					" %s\n", msg->via1.host);
499
+					" %s\n", msg->via1->host);
499 500
 			/* send error msg back? */
500 501
 			goto error;
501 502
 		}
502 503
 	}
503 504
 	/* we must remove the first via */
504
-	via_len=msg->via1.size;
505
-	size=msg->via1.hdr.s-buf;
505
+	via_len=msg->via1->bsize;
506
+	size=msg->via1->hdr.s-buf;
506 507
 	DBG("via len: %d, initial size: %d\n", via_len, size);
507
-	if (msg->via1.next){
508
-		/* keep hdr =substract hdr size +1 (hdr':') and add
509
-		 */
510
-		via_len-=msg->via1.hdr.len+1;
511
-		size+=msg->via1.hdr.len+1;
508
+	if (msg->via1->next){
509
+		/* add hdr size*/
510
+		size+=msg->via1->hdr.len+1;
512 511
 	    DBG(" adjusted via len: %d, initial size: %d\n",
513 512
 				via_len, size);
513
+	}else{
514
+		/* add hdr size ("Via:")*/
515
+		via_len+=msg->via1->hdr.len+1;
514 516
 	}
515 517
 	new_len=len-via_len;
516 518
 	
... ...
@@ -530,26 +532,28 @@ int forward_reply(struct sip_msg* msg)
530 532
 			s_offset, offset, 
531 533
 			len-s_offset );
532 534
 	DBG("Sending: to %s:%d, \n%s.\n",
533
-			msg->via2.host.s, 
534
-			(unsigned short)msg->via2.port,
535
+			msg->via2->host.s, 
536
+			(unsigned short)msg->via2->port,
535 537
 			new_buf);
536 538
 
537 539
 #ifdef DNS_IP_HACK
538
-	to->sin_addr.s_addr=str2ip(msg->via2.host.s, msg->via2.host.len, &err);
540
+	to->sin_addr.s_addr=str2ip(msg->via2->host.s, msg->via2->host.len, &err);
539 541
 	if (err==0){
540 542
 		to->sin_family = AF_INET;
541
-		to->sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
543
+		to->sin_port = (msg->via2->port)?htons(msg->via2->port):
544
+						htons(SIP_PORT);
542 545
 	}else{
543 546
 #endif
544 547
 		/* fork? gethostbyname will probably block... */
545
-		he=gethostbyname(msg->via2.host.s);
548
+		he=gethostbyname(msg->via2->host.s);
546 549
 		if (he==0){
547 550
 			LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n",
548
-					msg->via2.host.s);
551
+					msg->via2->host.s);
549 552
 			goto error;
550 553
 		}
551 554
 		to->sin_family = AF_INET;
552
-		to->sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
555
+		to->sin_port = (msg->via2->port)?htons(msg->via2->port):
556
+						htons(SIP_PORT);
553 557
 		to->sin_addr.s_addr=*((long*)he->h_addr_list[0]);
554 558
 
555 559
 #ifdef DNS_IP_HACK
... ...
@@ -32,5 +32,6 @@ extern int check_via;
32 32
 extern int received_dns;
33 33
 
34 34
 extern int cfg_errors;
35
+extern unsigned int msg_no;
35 36
 
36 37
 #endif
... ...
@@ -36,7 +36,7 @@
36 36
 
37 37
 
38 38
 static char id[]="@(#) $Id$";
39
-static char version[]="ser 0.8.3.8";
39
+static char version[]="ser 0.8.3.9";
40 40
 static char flags[]="NOCR:"
41 41
 #ifdef NOCR
42 42
 "On"
... ...
@@ -203,14 +203,13 @@ int field_name(char *s, int l)
203 203
 #ifndef OLD_PARSER
204 204
 /* returns pointer to next header line, and fill hdr_f ;
205 205
  * if at end of header returns pointer to the last crlf  (always buf)*/
206
-char* get_hdr_field(char* buf, unsigned int len, struct hdr_field* hdr)
206
+char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
207 207
 {
208
-	char* end;
208
+
209 209
 	char* tmp;
210 210
 	char *match;
211 211
 	struct via_body *vb;
212 212
 
213
-	end=buf+len;
214 213
 	if ((*buf)=='\n' || (*buf)=='\r'){
215 214
 		/* double crlf or lflf or crcr */
216 215
 		DBG("found end of header\n");
... ...
@@ -222,44 +221,68 @@ char* get_hdr_field(char* buf, unsigned int len, struct hdr_field* hdr)
222 221
 	if (hdr->type==HDR_ERROR){
223 222
 		LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
224 223
 		goto error;
225
-	}else if (hdr->type==HDR_VIA){
226
-		vb=malloc(sizeof(struct via_body));
227
-		if (vb==0){
228
-			LOG(L_ERR, "get_hdr_field: out of memory\n");
229
-			goto error;
230
-		}
231
-		memset(vb,0,sizeof(struct via_body));
224
+	}
225
+	switch(hdr->type){
226
+		case HDR_VIA:
227
+			vb=malloc(sizeof(struct via_body));
228
+			if (vb==0){
229
+				LOG(L_ERR, "get_hdr_field: out of memory\n");
230
+				goto error;
231
+			}
232
+			memset(vb,0,sizeof(struct via_body));
232 233
 
233
-		hdr->body.s=tmp;
234
-		tmp=parse_via(tmp, end, vb);
235
-		if (vb->error==VIA_PARSE_ERROR){
236
-			LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
237
-			free(vb);
238
-			goto error;
239
-		}
240
-		hdr->parsed=vb;
241
-		vb->hdr.s=hdr->name.s;
242
-		vb->hdr.len=hdr->name.len;
243
-		vb->size=tmp-hdr->name.s;
244
-		hdr->body.len=tmp-hdr->body.s;
245
-	}else{
246
-		/* just skip over it*/
247
-		hdr->body.s=tmp;
248
-		/* find lf*/
249
-		match=q_memchr(tmp, '\n', end-tmp);
250
-		if (match){
251
-			/* null terminate*/
252
-			*match=0;
253
-			hdr->body.len=match-tmp;
254
-			match++; /*skip*/
234
+			hdr->body.s=tmp;
235
+			tmp=parse_via(tmp, end, vb);
236
+			if (vb->error==VIA_PARSE_ERROR){
237
+				LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
238
+				free(vb);
239
+				goto error;
240
+			}
241
+			hdr->parsed=vb;
242
+			vb->hdr.s=hdr->name.s;
243
+			vb->hdr.len=hdr->name.len;
244
+			/*vb->size=tmp-hdr->name.s;*/
245
+			hdr->body.len=tmp-hdr->body.s;
246
+			break;
247
+		case HDR_TO:
248
+		case HDR_FROM:
249
+		case HDR_CSEQ:
250
+		case HDR_CALLID:
251
+		case HDR_CONTACT:
252
+		case HDR_OTHER:
253
+			/* just skip over it */
254
+			hdr->body.s=tmp;
255
+			/* find end of header */
256
+			
257
+			/* find lf */
258
+			do{
259
+				match=q_memchr(tmp, '\n', end-tmp);
260
+				if (match){
261
+					match++;
262
+				#if 0
263
+					/* null terminate*/
264
+					*match=0;
265
+					hdr->body.len=match-tmp;
266
+					match++; /*skip*/
267
+					tmp=match;
268
+				#endif
269
+				}else {
270
+					tmp=end;
271
+					LOG(L_ERR, "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
272
+							hdr->name.s, hdr->type);
273
+					goto error;
274
+				}
275
+			}while( match<end &&( (*match==' ')||(*match=='\t') ) );
276
+			*(match-1)=0; /*null terminate*/
277
+			hdr->body.len=match-hdr->body.s;
255 278
 			tmp=match;
256
-		}else {
257
-			tmp=end;
258
-			LOG(L_ERR, "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
259
-					hdr->name.s, hdr->type);
279
+			break;
280
+		default:
281
+			LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
282
+					hdr->type);
260 283
 			goto error;
261
-		}
262 284
 	}
285
+
263 286
 	return tmp;
264 287
 error:
265 288
 	DBG("get_hdr_field: error exit\n");
... ...
@@ -296,7 +319,7 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
296 319
 		hdr_f->type=HDR_EOH;
297 320
 		return tmp;
298 321
 	}
299
-	
322
+#if 0	
300 323
 	tmp=eat_token2_end(buffer, buffer+len, ':');
301 324
 	if ((tmp==buffer) || (tmp-buffer==len) ||
302 325
 		(is_empty_end(buffer, tmp))|| (*tmp!=':')){
... ...
@@ -318,11 +341,20 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
318 341
 			goto error;
319 342
 		}
320 343
 	}
344
+#endif
321 345
 
346
+	tmp=parse_hname(buffer, buffer+len, hdr_f);
347
+	if (hdr_f->type==HDR_ERROR){
348
+		LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
349
+		goto error;
350
+	}
351
+	
352
+#if 0
322 353
 	hdr_f->type=field_name(buffer, l);
323 354
 	body= ++tmp;
324 355
 	hdr_f->name.s=buffer;
325 356
 	hdr_f->name.len=l;
357
+#endif
326 358
 	offset=tmp-buffer;
327 359
 	/* get all the lines in this field  body */
328 360
 	do{
... ...
@@ -338,7 +370,7 @@ char* get_hdr_field(char *buffer, unsigned int len, struct hdr_field*  hdr_f)
338 370
 	}
339 371
 	*(tmp-1)=0; /* should be an LF */
340 372
 	hdr_f->body.s=body;
341
-	hdr_f->body.len=tmp-1-body;;
373
+	hdr_f->body.len=tmp-1-body;
342 374
 error:
343 375
 	return tmp;
344 376
 }
... ...
@@ -526,7 +558,7 @@ error:
526 558
 }
527 559
 
528 560
 
529
-
561
+#ifdef OLD_PARSER
530 562
 /* parses a via body, returns next via (for compact vias) & fills vb,
531 563
  * the buffer should be null terminated! */
532 564
 char* parse_via_body(char* buffer,unsigned int len, struct via_body * vb)
... ...
@@ -674,6 +706,108 @@ error:
674 706
 	vb->error=VIA_PARSE_ERROR;
675 707
 	return tmp;
676 708
 }
709
+#endif
710
+
711
+
712
+/* parse the headers and adds them to msg->headers and msg->to, from etc.
713
+ * It stops when all the headers requested in flags were parsed, on error
714
+ * (bad header) or end of headers */
715
+int parse_headers(struct sip_msg* msg, int flags)
716
+{
717
+	struct hdr_field* hf;
718
+	char* tmp;
719
+	char* rest;
720
+	char* end;
721
+	
722
+	end=msg->buf+msg->len;
723
+	tmp=msg->unparsed;
724
+	
725
+	DBG("parse_headers: flags=%d\n", flags);
726
+	while( tmp<end && (flags & msg->parsed_flag) != flags){
727
+		hf=malloc(sizeof(struct hdr_field));
728
+		memset(hf,0, sizeof(struct hdr_field));
729
+		if (hf==0){
730
+			LOG(L_ERR, "ERROR:parse_headers: memory allocation error\n");
731
+			goto error;
732
+		}
733
+		hf->type=HDR_ERROR;
734
+		rest=get_hdr_field(tmp, msg->buf+msg->len, hf);
735
+		switch (hf->type){
736
+			case HDR_ERROR:
737
+				LOG(L_INFO,"ERROR: bad header  field\n");
738
+				goto  error;
739
+			case HDR_EOH:
740
+				msg->eoh=tmp; /* or rest?*/
741
+				msg->parsed_flag|=HDR_EOH;
742
+				goto skip;
743
+			case HDR_OTHER: /*do nothing*/
744
+				break;
745
+			case HDR_CALLID:
746
+				if (msg->callid==0) msg->callid=hf;
747
+				msg->parsed_flag|=HDR_CALLID;
748
+				break;
749
+			case HDR_TO:
750
+				if (msg->to==0) msg->to=hf;
751
+				msg->parsed_flag|=HDR_TO;
752
+				break;
753
+			case HDR_CSEQ:
754
+				if (msg->cseq==0) msg->cseq=hf;
755
+				msg->parsed_flag|=HDR_CSEQ;
756
+				break;
757
+			case HDR_FROM:
758
+				if (msg->from==0) msg->from=hf;
759
+				msg->parsed_flag|=HDR_FROM;
760
+				break;
761
+			case HDR_CONTACT:
762
+				if (msg->contact==0) msg->contact=hf;
763
+				msg->parsed_flag|=HDR_CONTACT;
764
+				break;
765
+			case HDR_VIA:
766
+				msg->parsed_flag|=HDR_VIA;
767
+				DBG("parse_headers: Via1 found, flags=%d\n", flags);
768
+				if (msg->h_via1==0) {
769
+					msg->h_via1=hf;
770
+					msg->via1=hf->parsed;
771
+					if (msg->via1->next){
772
+						msg->via2=msg->via1->next;
773
+						msg->parsed_flag|=HDR_VIA2;
774
+					}
775
+				}else if (msg->h_via2==0){
776
+					msg->h_via2=hf;
777
+					msg->via2=hf->parsed;
778
+					msg->parsed_flag|=HDR_VIA2;
779
+				DBG("parse_headers: Via2 found, flags=%d\n", flags);
780
+				}
781
+				break;
782
+			default:
783
+				LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
784
+							hf->type);
785
+				goto error;
786
+		}
787
+		/* add the header to the list*/
788
+		if (msg->last_header==0){
789
+			msg->headers=hf;
790
+			msg->last_header=hf;
791
+		}else{
792
+			msg->last_header->next=hf;
793
+			msg->last_header=hf;
794
+		}
795
+	#ifdef DEBUG
796
+		DBG("header field type %d, name=<%s>, body=<%s>\n",
797
+			hf->type, hf->name.s, hf->body.s);
798
+	#endif
799
+		tmp=rest;
800
+	}
801
+skip:
802
+	msg->unparsed=tmp;
803
+	return 0;
804
+	
805
+error:
806
+	if (hf) free(hf);
807
+	return -1;
808
+}
809
+
810
+
677 811
 
678 812
 
679 813
 
... ...
@@ -686,9 +820,10 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
686 820
 	char* first_via;
687 821
 	char* second_via;
688 822
 	struct msg_start *fl;
689
-	struct hdr_field hf;
823
+	struct hdr_field* hf;
690 824
 	struct via_body *vb1, *vb2;
691 825
 	int offset;
826
+	int flags;
692 827
 
693 828
 #ifdef OLD_PARSER
694 829
 	/* init vb1 & vb2 to the null string */
... ...
@@ -700,6 +835,7 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
700 835
 	vb2->error=VIA_PARSE_ERROR;
701 836
 #else
702 837
 	vb1=vb2=0;
838
+	hf=0;
703 839
 #endif
704 840
 	/* eat crlf from the beginning */
705 841
 	for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
... ...
@@ -719,121 +855,37 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
719 855
 			DBG(" method:  <%s>\n",fl->u.request.method);
720 856
 			DBG(" uri:     <%s>\n",fl->u.request.uri);
721 857
 			DBG(" version: <%s>\n",fl->u.request.version);
858
+			flags=HDR_VIA;
722 859
 			break;
723 860
 		case SIP_REPLY:
724 861
 			DBG("SIP Reply  (status):\n");
725 862
 			DBG(" version: <%s>\n",fl->u.reply.version);
726 863
 			DBG(" status:  <%s>\n",fl->u.reply.status);
727 864
 			DBG(" reason:  <%s>\n",fl->u.reply.reason);
865
+			flags=HDR_VIA|HDR_VIA2;
728 866
 			break;
729 867
 		default:
730 868
 			DBG("unknown type %d\n",fl->type);
731 869
 	}
732
-	
870
+	msg->unparsed=tmp;
733 871
 	/*find first Via: */
734
-	hf.type=HDR_ERROR;
735 872
 	first_via=0;
736 873
 	second_via=0;
737
-	do{
738
-		rest=get_hdr_field(tmp, len-offset, &hf);
739
-		offset+=rest-tmp;
740
-		switch (hf.type){
741
-			case HDR_ERROR:
742
-				LOG(L_INFO,"ERROR: bad header  field\n");
743
-				goto  error;
744
-			case HDR_EOH: 
745
-				goto skip;
746
-			case HDR_VIA:
747
-				if (first_via==0){
748
-					first_via=hf.body.s;
749
-#ifndef OLD_PARSER
750
-					vb1=(struct via_body*)hf.parsed;
751
-#else
752
-						vb1->hdr.s=hf.name.s;
753
-						vb1->hdr.len=hf.name.len;
754
-						/* replace cr/lf with space in first via */
755
-						for (bar=first_via;(first_via) && (*bar);bar++)
756
-							if ((*bar=='\r')||(*bar=='\n'))	*bar=' ';
757
-#endif
758
-				#ifdef DEBUG
759
-						DBG("first via: <%s>\n", first_via);
760
-				#endif
761
-#ifdef OLD_PARSER
762
-						bar=parse_via_body(first_via, hf.body.len, vb1);
763
-						if (vb1->error!=VIA_PARSE_OK){
764
-							LOG(L_INFO, "ERROR: parsing via body: %s\n",
765
-									first_via);
766
-							goto error;
767
-						}
768
-						
769
-						vb1->size=bar-first_via+first_via-vb1->hdr.s; 
770
-						
771
-#endif
772
-						/* compact via */
773
-						if (vb1->next) {
774
-							second_via=vb1->next;
775
-							/* not interested in the rest of the header */
776
-							goto skip;
777
-						}else{
778
-#ifdef OLD_PARSER
779
-						/*  add 1 (we don't see the trailing lf which
780
-						 *  was zeroed by get_hfr_field) */
781
-							vb1->size+=1;
782
-#endif
783
-						}
784
-						if (fl->type!=SIP_REPLY) goto skip; /* we are interested
785
-															  in the 2nd via 
786
-															 only in replies */
787
-				}else if (second_via==0){
788
-							second_via=hf.body.s;
789
-#ifndef OLD_PARSER
790
-							vb2=hf.parsed;
791
-#else
792
-							vb2->hdr.s=hf.name.s;
793
-							vb2->hdr.len=hf.name.len;
794
-#endif
795
-							goto skip;
796
-				}
797
-				break;
798
-		}
799
-	#ifdef DEBUG
800
-		DBG("header field type %d, name=<%s>, body=<%s>\n",
801
-			hf.type, hf.name.s, hf.body.s);
802
-	#endif
803
-		tmp=rest;
804
-	}while(hf.type!=HDR_EOH && rest-buf < len);
805
-
806
-skip:
807
-	/* replace cr/lf with space in the second via */
808
-#ifdef OLD_PARSER
809
-	for (tmp=second_via;(second_via) && (*tmp);tmp++)
810
-		if ((*tmp=='\r')||(*tmp=='\n'))	*tmp=' ';
811
-
812
-	if (second_via) {
813
-		tmp=parse_via_body(second_via, hf.body.len, vb2);
814
-		if (vb2->error!=VIA_PARSE_OK){
815
-			LOG(L_INFO, "ERROR: parsing via2 body: %s\n", second_via);
816
-			goto error;
817
-		}
818
-		vb2->size=tmp-second_via; 
819
-		if (vb2->next==0) vb2->size+=1; /* +1 from trailing lf */
820
-		if (vb2->hdr.s) vb2->size+=second_via-vb2->hdr.s;
821
-	}
822
-#endif
823
-	
874
+	if (parse_headers(msg, flags)==-1) goto error;
824 875
 
825 876
 #ifdef DEBUG
826 877
 	/* dump parsed data */
827
-	if (first_via){
878
+	if (msg->via1){
828 879
 		DBG(" first  via: <%s/%s/%s> <%s:%s(%d)>",
829
-				vb1->name.s, vb1->version.s, vb1->transport.s, vb1->host.s,
830
-				vb1->port_str, vb1->port);
831
-		if (vb1->params.s)  DBG(";<%s>", vb1->params.s);
832
-		if (vb1->comment.s) DBG(" <%s>", vb1->comment.s);
880
+			msg->via1->name.s, msg->via1->version.s,
881
+			msg->via1->transport.s, msg->via1->host.s,
882
+			msg->via1->port_str, msg->via1->port);
883
+		if (msg->via1->params.s)  DBG(";<%s>", msg->via1->params.s);
884
+		if (msg->via1->comment.s) DBG(" <%s>", msg->via1->comment.s);
833 885
 		DBG ("\n");
834 886
 	}
835 887
 #ifdef OLD_PARSER
836
-	if (second_via){
888
+	if (msg->via2){
837 889
 		DBG(" second via: <%s/%s/%s> <%s:%d>",
838 890
 				vb2->name.s, vb2->version.s, vb2->transport.s, vb2->host.s,
839 891
 				vb2->port);
... ...
@@ -845,12 +897,14 @@ skip:
845 897
 #endif
846 898
 	
847 899
 	/* copy data into msg */
900
+#if 0
848 901
 #ifndef OLD_PARSER
849 902
 	memcpy(&(msg->via1), vb1, sizeof(struct via_body));
850 903
 	if (second_via) memcpy(&(msg->via2), vb2, sizeof(struct via_body));
851 904
 	if (vb1) free(vb1);
852 905
 	if (vb2) free(vb1);
853 906
 #endif
907
+#endif
854 908
 
855 909
 #ifdef DEBUG
856 910
 	DBG("exiting parse_msg\n");
... ...
@@ -859,6 +913,7 @@ skip:
859 913
 	return 0;
860 914
 	
861 915
 error:
916
+	if (hf) free(hf);
862 917
 #ifndef OLD_PARSER
863 918
 	if (vb1) free(vb1);
864 919
 	if (vb2) free(vb1);
... ...
@@ -879,3 +934,48 @@ void free_uri(struct sip_uri* u)
879 934
 		if (u->headers.s) free(u->headers.s);
880 935
 	}
881 936
 }
937
+
938
+
939
+
940
+void free_via_list(struct via_body* vb)
941
+{
942
+	struct via_body* foo;
943
+	while(vb){
944
+		foo=vb;
945
+		vb=vb->next;
946
+		free(foo);
947
+	}
948
+}
949
+
950
+
951
+/* frees a hdr_field structure, 
952
+ * WARNING: it frees only parsed (and not name.s, body.s)*/
953
+void clean_hdr_field(struct hdr_field* hf)
954
+{
955
+	if (hf->parsed){
956
+		switch(hf->type){
957
+			case HDR_VIA:
958
+				free_via_list(hf->parsed);
959
+				break;
960
+			default:
961
+				LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
962
+						hf->type);
963
+		}
964
+	}
965
+}
966
+
967
+
968
+
969
+/* frees a hdr_field list,
970
+ * WARNING: frees only ->parsed and ->next*/
971
+void free_hdr_field_lst(struct hdr_field* hf)
972
+{
973
+	struct hdr_field* foo;
974
+	
975
+	while(hf){
976
+		foo=hf;
977
+		hf=hf->next;
978
+		clean_hdr_field(foo);
979
+		free(foo);
980
+	}
981
+}
... ...
@@ -13,10 +13,21 @@
13 13
 #define SIP_INVALID 0
14 14
 
15 15
 
16
-enum {	HDR_EOH=-1, HDR_ERROR=0, HDR_OTHER,
17
-		HDR_VIA, HDR_TO, HDR_FROM, HDR_CSEQ, HDR_CALLID, HDR_CONTACT,
18
-		HDR_MAXFORWARDS, HDR_ROUTE
19
-	};
16
+
17
+/*header types and flags*/
18
+#define HDR_EOH           -1
19
+#define HDR_ERROR          0
20
+#define HDR_VIA            1
21
+#define HDR_VIA1           1
22
+#define HDR_VIA2           2  /*only used as flag*/
23
+#define HDR_TO             4
24
+#define HDR_FROM           8
25
+#define HDR_CSEQ          16
26
+#define HDR_CALLID        32
27
+#define HDR_CONTACT       64
28
+#define HDR_MAXFORWARDS  128
29
+#define HDR_ROUTE        256
30
+#define HDR_OTHER       65536 /*unknown header type*/
20 31
 
21 32
 #define INVITE_LEN	6
22 33
 #define ACK_LEN		3
... ...
@@ -65,6 +76,7 @@ struct hdr_field{   /* format: name':' body */
65 76
 	str name;
66 77
 	str body;
67 78
 	void* parsed;
79
+	struct hdr_field* next;
68 80
 };
69 81
 
70 82
 struct via_body{  /* format: name/version/transport host:port;params comment */
... ...
@@ -78,14 +90,30 @@ struct via_body{  /* format: name/version/transport host:port;params comment */
78 90
 	str port_str;
79 91
 	str params;
80 92
 	str comment;
81
-	int size;    /* full size, including hdr */
82
-	char* next; /* pointer to next via body string if compact via or null */
93
+	int bsize;    /* body size, not including hdr */
94
+	struct via_body* next; /* pointer to next via body string if
95
+							  compact via or null */
83 96
 };
84 97
 
85 98
 struct sip_msg{
99
+	unsigned int id; /* message id, unique/process*/
86 100
 	struct msg_start first_line;
87
-	struct via_body via1;
88
-	struct via_body via2;
101
+	struct via_body* via1;
102
+	struct via_body* via2;
103
+	struct hdr_field* headers; /* all the parsed headers*/
104
+	struct hdr_field* last_header; /* pointer to the last parsed header*/
105
+	int parsed_flag;
106
+	/* via, to, cseq, call-id, from, end of header*/
107
+	struct hdr_field* h_via1;
108
+	struct hdr_field* h_via2;
109
+	struct hdr_field* callid;
110
+	struct hdr_field* to;
111
+	struct hdr_field* cseq;
112
+	struct hdr_field* from;
113
+	struct hdr_field* contact;
114
+	char* eoh; /* pointer to the end of header (if found) or null */
115
+
116
+	char* unparsed; /* here we stopped parsing*/
89 117
 
90 118
 	unsigned int src_ip;
91 119
 	unsigned int dst_ip;
... ...
@@ -135,5 +163,9 @@ char* parse_hname(char* buf, char* end, struct hdr_field* hdr);
135 163
 char* parse_via(char* buffer, char* end, struct via_body *vb);
136 164
 #endif
137 165
 
166
+void free_via_list(struct via_body *vb);
167
+void clean_hdr_field(struct hdr_field* hf);
168
+void free_hdr_field_lst(struct hdr_field* hf);
169
+
138 170
 
139 171
 #endif
... ...
@@ -21,11 +21,15 @@
21 21
 #include "stats.h"
22 22
 #endif
23 23
 
24
+unsigned int msg_no=0;
25
+
24 26
 int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
25 27
 {
26 28
 	struct sip_msg msg;
29
+
30
+	msg_no++;
27 31
 #ifdef STATS
28
-	int skipped = 1;
32
+	skipped = 1;
29 33
 #endif
30 34
 
31 35
 	memset(&msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
... ...
@@ -33,6 +37,7 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
33 37
 	msg.buf=buf;
34 38
 	msg.len=len;
35 39
 	msg.src_ip=src_ip;
40
+	msg.id=msg_no;
36 41
 	/* make a copy of the message */
37 42
 	msg.orig=(char*) malloc(len+1);
38 43
 	if (msg.orig==0){
... ...
@@ -45,14 +50,14 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
45 50
 	if (parse_msg(buf,len, &msg)!=0){
46 51
 		goto error;
47 52
 	}
48
-	DBG("Ater parse_msg...\n");
49
-	
53
+	DBG("After parse_msg...\n");
50 54
 	if (msg.first_line.type==SIP_REQUEST){
51 55
 		DBG("msg= request\n");
52 56
 		/* sanity checks */
53
-		if (msg.via1.error!=VIA_PARSE_OK){
57
+		if ((msg.via1==0) || (msg.via1->error!=VIA_PARSE_OK)){
54 58
 			/* no via, send back error ? */
55
-			goto skip;
59
+			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
60
+			goto error;
56 61
 		}
57 62
 		/* check if neccesarry to add receive?->moved to forward_req */
58 63
 		
... ...
@@ -70,13 +75,15 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
70 75
 	}else if (msg.first_line.type==SIP_REPLY){
71 76
 		DBG("msg= reply\n");
72 77
 		/* sanity checks */
73
-		if (msg.via1.error!=VIA_PARSE_OK){
78
+		if ((msg.via1==0) || (msg.via1->error!=VIA_PARSE_OK)){
74 79
 			/* no via, send back error ? */
75
-			goto skip;
80
+			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
81
+			goto error;
76 82
 		}
77
-		if (msg.via2.error!=VIA_PARSE_OK){
83
+		if ((msg.via2==0) || (msg.via2->error!=VIA_PARSE_OK)){
78 84
 			/* no second via => error? */
79
-			goto skip;
85
+			LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
86
+			goto error;
80 87
 		}
81 88
 		/* check if via1 == us */
82 89
 
... ...
@@ -88,15 +95,17 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
88 95
 		/* send the msg */
89 96
 		if (forward_reply(&msg)==0){
90 97
 			DBG(" reply forwarded to %s:%d\n", 
91
-						msg.via2.host.s,
92
-						(unsigned short) msg.via2.port);
98
+						msg.via2->host.s,
99
+						(unsigned short) msg.via2->port);
93 100
 		}
94 101
 	}
95 102
 #ifdef STATS
96 103
 	skipped = 0;
97 104
 #endif
98 105
 skip:
106
+	DBG("skip:...\n");
99 107
 	if (msg.new_uri.s) { free(msg.new_uri.s); msg.new_uri.len=0; }
108
+	if (msg.headers) free_hdr_field_lst(msg.headers);
100 109
 	if (msg.add_rm) free_lump_list(msg.add_rm);
101 110
 	if (msg.repl_add_rm) free_lump_list(msg.repl_add_rm);
102 111
 	free(msg.orig);
... ...
@@ -105,7 +114,9 @@ skip:
105 114
 #endif
106 115
 	return 0;
107 116
 error:
117
+	DBG("error:...\n");
108 118
 	if (msg.new_uri.s) free(msg.new_uri.s);
119
+	if (msg.headers) free_hdr_field_lst(msg.headers);
109 120
 	if (msg.add_rm) free_lump_list(msg.add_rm);
110 121
 	if (msg.repl_add_rm) free_lump_list(msg.repl_add_rm);
111 122
 	free(msg.orig);
... ...
@@ -1,5 +1,5 @@
1 1
 INVITE sip:andrei@localhost:5061;a=b?c=d SIP/2.0
2
-Via: SIP/2.0/UDP localhost
2
+Via: SIP/2.0/UDP localhost, SIP/2.0/UDP 127.0.0.1:5061
3 3
 
4 4
 
5 5