... | ... |
@@ -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 |
... | ... |
@@ -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); |