69756bc221ff3a450dd0fa31454033515c8a00b4
[sip-router] / parser / parse_via.c
1 /*
2  * $Id$ 
3  *
4  * via parsing automaton
5  * 
6  *
7  * Copyright (C) 2001-2003 FhG Fokus
8  *
9  * This file is part of ser, a free SIP server.
10  *
11  * ser is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * For a license to use the ser software under conditions
17  * other than those described here, or to purchase support for this
18  * software, please contact iptel.org by e-mail at the following addresses:
19  *    info@iptel.org
20  *
21  * ser is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License 
27  * along with this program; if not, write to the Free Software 
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  */
30
31 /** @file
32  * @brief Parser :: Via parsing automation
33  *
34  * @ingroup parser
35  */
36
37 /* 
38  *  2003-01-21  added rport parsing code, contributed by
39  *               Maxim Sobolev  <sobomax@FreeBSD.org>
40  *  2003-01-23  added extra via param parsing code (i=...), used
41  *               by tcp to identify the sending socket, by andrei
42  *  2003-01-23  fixed rport parsing code to accept rport w/o any value,
43  *               by andrei
44  *  2003-01-27  modified parse_via to set new via_param->start member and
45  *               via->params.s (andrei)
46  *  2003-01-28  zero-terminations replaced with VIA_ZT (jiri)
47  *  2003-02-28  scratchpad compatibility abandoned (jiri)
48  *  2003-04-26  ZSW (jiri)
49  *  2003-06-23  fixed  parse_via_param [op].* param. parsing bug (andrei)
50  *  2003-07-02  added support for TLS parsing in via (andrei)
51  *  2003-10-27  added support for alias via param parsing [see
52  *               draft-ietf-sip-connect-reuse-00.txt.]  (andrei)
53  *  2004-03-31  fixed rport set instead of i bug (andrei)
54  *  2005-03-02  if via has multiple bodies, and one of them is bad set
55  *               also the first one as bad (andrei)
56  *  2006-02-24  added support for comp parameter parsing, see rfc3486 (andrei)
57  *  2008-08-08  SCTP support (andrei)
58  */
59
60
61
62 #include "../comp_defs.h"
63 #include <stdlib.h>
64 #include <string.h>
65 #include "../dprint.h"
66 #include "../ut.h"
67 #include "../mem/mem.h"
68 #include "../ip_addr.h"
69 #include "parse_via.h"
70 #include "parse_def.h"
71 #include "msg_parser.h"
72
73
74
75 /** \brief main via states (uri:port ...) */
76 enum {           
77         F_HOST, P_HOST,
78         L_PORT, F_PORT, P_PORT,
79         L_PARAM, F_PARAM, P_PARAM,
80         L_VIA, F_VIA,
81         F_COMMENT, P_COMMENT,
82         F_IP6HOST, P_IP6HOST, 
83         F_CRLF,
84         F_LF,
85         F_CR,
86         END_OF_HEADER
87 };
88
89
90 /** \brief first via part state */
91 enum {
92         F_SIP = 100,
93         SIP1, SIP2, FIN_SIP,
94         L_VER, F_VER,
95         VER1, VER2, FIN_VER,
96         UDP1, UDP2, FIN_UDP,
97         TCP_TLS1, TCP2, FIN_TCP,
98                   TLS2, FIN_TLS,
99         SCTP1, SCTP2, SCTP3, FIN_SCTP,
100         WS_WSS1, WS_WSS2, FIN_WSS,
101         OTHER_PROTO,
102         L_PROTO, F_PROTO
103 };
104
105
106 /** \brief param related states
107  * WARNING: keep in sync with parse_via.h, PARAM_HIDDEN, ...
108  */
109 enum {  
110         L_VALUE = 200, F_VALUE, P_VALUE, P_STRING,
111         HIDDEN1, HIDDEN2, HIDDEN3, HIDDEN4, HIDDEN5,
112         TTL1, TTL2,
113         BRANCH1, BRANCH2, BRANCH3, BRANCH4, BRANCH5,
114         MADDR1, MADDR2, MADDR3, MADDR4,
115         RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
116         RECEIVED7,
117         RPORT1, RPORT2, RPORT3,
118         ALIAS1, ALIAS2, ALIAS3, ALIAS4,
119 #ifdef USE_COMP
120         COMP1, COMP2, COMP3, 
121         /* values */
122         L_COMP_VALUE, F_COMP_VALUE,
123         V_COMP_S, V_SIGCOMP_I, V_SIGCOMP_G, V_SIGCOMP_C, V_SIGCOMP_O, V_SIGCOMP_M,
124         FIN_V_SIGCOMP_P,
125         V_SERGZ_E, V_SERGZ_R, V_SERGZ_G, FIN_V_SERGZ_Z,
126 #endif
127              /* fin states (227-...)*/
128         FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
129         FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
130 #ifdef USE_COMP
131         , FIN_COMP
132 #endif
133              /*GEN_PARAM,
134                PARAM_ERROR*/ /* declared in msg_parser.h*/
135 };
136
137
138 /* entry state must be F_PARAM, or saved_state=F_PARAM and
139  * state=F_{LF,CR,CRLF}!
140  * output state = L_PARAM or F_PARAM or END_OF_HEADER
141  * (and saved_state= last state); everything else => error 
142  * WARNING: param->start must be filled before, it's used in param->size 
143  * computation.
144  */
145 static /*inline*/ char* parse_via_param(char* p, char* end,
146                                                                                 unsigned char* pstate, 
147                                                                         unsigned char* psaved_state,
148                                                                                 struct via_param* param,
149                                                                                 struct via_body* vb)
150 {
151         char* tmp;
152         register unsigned char state;
153         unsigned char saved_state;
154
155 #define value_case(c, C, oldstate, newstate, start_of_value) \
156                         case (c): \
157                         case (C): \
158                                 switch(state){ \
159                                         case (oldstate): \
160                                                 state=(newstate); \
161                                                 if ((start_of_value))  param->value.s=tmp; \
162                                                 break; \
163                                         default_value_cases \
164                                 } \
165                                 break
166
167 #define value_case_double(c, C, oldstate1, newstate1, oldstate2, newstate2) \
168                         case (c): \
169                         case (C): \
170                                 switch(state){ \
171                                         case (oldstate1): \
172                                                 state=(newstate1); \
173                                                 break; \
174                                         case (oldstate2): \
175                                                 state=(newstate2); \
176                                                 break; \
177                                         default_value_cases \
178                                 } \
179                                 break
180
181 #define default_value_cases \
182                                         case F_VALUE: \
183                                                 state=P_VALUE; \
184                                                 param->value.s=tmp; \
185                                                 break; \
186                                         case P_VALUE: \
187                                         case P_STRING: \
188                                                 break; \
189                                         case F_LF: \
190                                         case F_CR:  \
191                                         case F_CRLF: \
192                                                 state=END_OF_HEADER; \
193                                                 goto end_via; \
194                                         default: \
195                                                 switch(state){ \
196                                                         case F_COMP_VALUE: \
197                                                                 comp_unexpected_char; \
198                                                                 state=P_VALUE; \
199                                                                 param->value.s=tmp; \
200                                                                 break; \
201                                                         comp_states_cases \
202                                                         comp_fin_states_cases \
203                                                                 comp_unexpected_char; \
204                                                                 state=P_VALUE; \
205                                                                 break; \
206                                                         default: \
207                                                                 LOG(L_ERR, "ERROR: parse_via_param: invalid " \
208                                                                         "char <%c> in state %d\n", *tmp, state); \
209                                                                 goto error; \
210                                                 }
211
212 #define comp_states_cases \
213                                         case V_COMP_S: \
214                                         case V_SIGCOMP_I: \
215                                         case V_SIGCOMP_G: \
216                                         case V_SIGCOMP_C: \
217                                         case V_SIGCOMP_O: \
218                                         case V_SIGCOMP_M: \
219                                         case V_SERGZ_E: \
220                                         case V_SERGZ_R: \
221                                         case V_SERGZ_G: 
222
223 #define comp_fin_states_cases \
224                                         case FIN_V_SIGCOMP_P: \
225                                         case FIN_V_SERGZ_Z:
226
227
228 /* if unrecognized/bad comp, don't return error, just ignore comp */
229 #define comp_unexpected_char \
230                                                         LOG(L_ERR, "parse_via_param: bad/unrecognized" \
231                                                                         " comp method\n"); \
232                                                         vb->comp_no=0
233                                                                 
234
235
236         state=*pstate;
237         saved_state=*psaved_state;
238         param->type=PARAM_ERROR;
239
240         for (tmp=p;tmp<end;tmp++){
241                 switch(*tmp){
242                         case ' ':
243                         case '\t':
244                                 switch(state){
245                                         case FIN_HIDDEN:
246                                         case FIN_ALIAS:
247                                                 param->type=state;
248                                                 param->name.len=tmp-param->name.s;
249                                                 state=L_PARAM;
250                                                 goto endofparam;
251                                         case FIN_BRANCH:
252                                         case FIN_TTL:
253                                         case FIN_MADDR:
254                                         case FIN_RECEIVED:
255                                         case FIN_RPORT:
256                                         case FIN_I:
257                                                 param->type=state;
258                                                 param->name.len=tmp-param->name.s;
259                                                 state=L_VALUE;
260                                                 goto find_value;
261 #ifdef USE_COMP
262                                         case FIN_COMP:
263                                                 param->type=state;
264                                                 param->name.len=tmp-param->name.s;
265                                                 state=L_COMP_VALUE;
266                                                 goto find_value;
267 #endif
268                                         case F_PARAM:
269                                                 break;
270                                         case F_LF:
271                                         case F_CR:
272                                         case F_CRLF:
273                                                 state=saved_state;
274                                                 break;
275                                         case GEN_PARAM:
276                                         default:
277                                                 param->type=GEN_PARAM;
278                                                 param->name.len=tmp-param->name.s;
279                                                 state=L_VALUE;
280                                                 goto find_value;
281                                 }
282                                 break;
283                         /* \n and \r*/
284                         case '\n':
285                                 switch(state){
286                                         case FIN_HIDDEN:
287                                         case FIN_ALIAS:
288                                                 param->type=state;
289                                                 param->name.len=tmp-param->name.s;
290                                                 param->size=tmp-param->start; 
291                                                 saved_state=L_PARAM;
292                                                 state=F_LF;
293                                                 goto endofparam;
294                                         case FIN_BRANCH:
295                                         case FIN_TTL:
296                                         case FIN_MADDR:
297                                         case FIN_RECEIVED:
298                                         case FIN_I:
299                                         case FIN_RPORT:
300                                                 param->type=state;
301                                                 param->name.len=tmp-param->name.s;
302                                                 param->size=tmp-param->start; 
303                                                 saved_state=L_VALUE;
304                                                 state=F_LF;
305                                                 goto find_value;
306 #ifdef USE_COMP
307                                         case FIN_COMP:
308                                                 param->type=state;
309                                                 param->name.len=tmp-param->name.s;
310                                                 param->size=tmp-param->start; 
311                                                 saved_state=L_COMP_VALUE;
312                                                 state=F_LF;
313                                                 goto find_value;
314 #endif
315                                         case F_PARAM:
316                                                 saved_state=state;
317                                                 state=F_LF;
318                                                 break;
319                                         case F_LF:
320                                         case F_CRLF:
321                                                 state=END_OF_HEADER;
322                                                 goto end_via;
323                                         case F_CR:
324                                                 state=F_CRLF;
325                                                 break;
326                                         case GEN_PARAM:
327                                         default:
328                                                 param->type=GEN_PARAM;
329                                                 saved_state=L_VALUE;
330                                                 param->name.len=tmp-param->name.s;
331                                                 param->size=tmp-param->start; 
332                                                 state=F_LF;
333                                                 goto find_value;
334                                 }
335                                 break;
336                         case '\r':
337                                 switch(state){
338                                         case FIN_HIDDEN:
339                                         case FIN_ALIAS:
340                                                 param->type=state;
341                                                 param->name.len=tmp-param->name.s;
342                                                 param->size=tmp-param->start; 
343                                                 saved_state=L_PARAM;
344                                                 state=F_CR;
345                                                 goto endofparam;
346                                         case FIN_BRANCH:
347                                         case FIN_TTL:
348                                         case FIN_MADDR:
349                                         case FIN_RECEIVED:
350                                         case FIN_I:
351                                         case FIN_RPORT:
352                                                 param->type=state;
353                                                 param->name.len=tmp-param->name.s;
354                                                 param->size=tmp-param->start; 
355                                                 saved_state=L_VALUE;
356                                                 state=F_CR;
357                                                 goto find_value;
358 #ifdef USE_COMP
359                                         case FIN_COMP:
360                                                 param->type=state;
361                                                 param->name.len=tmp-param->name.s;
362                                                 param->size=tmp-param->start; 
363                                                 saved_state=L_COMP_VALUE;
364                                                 state=F_LF;
365                                                 goto find_value;
366 #endif
367                                         case F_PARAM:
368                                                 saved_state=state;
369                                                 state=F_CR;
370                                                 break;
371                                         case F_CR:
372                                         case F_CRLF:
373                                                 state=END_OF_HEADER;
374                                                 goto end_via;
375                                         case GEN_PARAM:
376                                         default:
377                                                 param->type=GEN_PARAM;
378                                                 param->name.len=tmp-param->name.s;
379                                                 param->size=tmp-param->start; 
380                                                 saved_state=L_VALUE;
381                                                 state=F_CR;
382                                                 goto find_value;
383                                 }
384                                 break;
385
386                         case '=':
387                                 switch(state){
388                                         case FIN_BRANCH:
389                                         case FIN_TTL:
390                                         case FIN_MADDR:
391                                         case FIN_RECEIVED:
392                                         case FIN_RPORT:
393                                         case FIN_I:
394                                                 param->type=state;
395                                                 param->name.len=tmp-param->name.s;
396                                                 state=F_VALUE;
397                                                 goto find_value;
398 #ifdef USE_COMP
399                                         case FIN_COMP:
400                                                 param->type=state;
401                                                 param->name.len=tmp-param->name.s;
402                                                 state=F_COMP_VALUE;
403                                                 goto find_value;
404 #endif
405                                         case F_PARAM:
406                                         case FIN_HIDDEN:
407                                         case FIN_ALIAS:
408                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
409                                                                 " state %d\n", *tmp, state);
410                                                 goto error;
411                                         case F_CR:
412                                         case F_LF:
413                                         case F_CRLF:
414                                                 state=END_OF_HEADER;
415                                                 goto end_via;
416                                         case GEN_PARAM:
417                                         default:
418                                                 param->type=GEN_PARAM;
419                                                 param->name.len=tmp-param->name.s;
420                                                 state=F_VALUE;
421                                                 goto find_value;
422                                 }
423                                 break;
424                         case ';':
425                                 switch(state){
426                                         case FIN_HIDDEN:
427                                         case FIN_RPORT: /* rport can appear w/o a value */
428                                         case FIN_ALIAS:
429                                                 param->type=state;
430                                                 param->name.len=tmp-param->name.s;
431                                                 state=F_PARAM;
432                                                 goto endofparam;
433                                         case FIN_BRANCH:
434                                         case FIN_MADDR:
435                                         case FIN_TTL:
436                                         case FIN_RECEIVED:
437                                         case FIN_I:
438 #ifdef USE_COMP
439                                         case FIN_COMP:
440 #endif
441                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
442                                                                 " state %d\n", *tmp, state);
443                                                 goto error;
444                                         case F_CR:
445                                         case F_LF:
446                                         case F_CRLF:
447                                                 state=END_OF_HEADER;
448                                                 goto end_via;
449                                         case GEN_PARAM:
450                                         default:
451                                                 param->type=GEN_PARAM;
452                                                 param->name.len=tmp-param->name.s;
453                                                 state=F_PARAM;
454                                                 goto endofparam;
455                                 }
456                                 break;
457                         case ',':
458                                 switch(state){
459                                         case FIN_HIDDEN:
460                                         case FIN_RPORT:
461                                         case FIN_ALIAS:
462                                                 param->type=state;
463                                                 param->name.len=tmp-param->name.s;
464                                                 state=F_VIA;
465                                                 goto endofvalue;
466                                         case FIN_BRANCH:
467                                         case FIN_MADDR:
468                                         case FIN_TTL:
469                                         case FIN_RECEIVED:
470                                         case FIN_I:
471 #ifdef USE_COMP
472                                         case FIN_COMP:
473 #endif
474                                                 LOG(L_ERR, "ERROR: parse_via_param: new via found" 
475                                                                 "(',') when '=' expected (state %d=)\n",
476                                                                 state);
477                                                 goto error; /* or we could ignore this bad param*/
478                                         case F_CR:
479                                         case F_LF:
480                                         case F_CRLF:
481                                                 state=END_OF_HEADER;
482                                                 goto end_via;
483                                         case GEN_PARAM:
484                                         default:
485                                                 param->type=GEN_PARAM;
486                                                 param->name.len=tmp-param->name.s;
487                                                 state=F_VIA;
488                                                 goto endofvalue;
489                                 }
490                                 break; 
491
492                                 /* param names */
493                         case 'h':
494                         case 'H':
495                                 switch(state){
496                                         case F_PARAM:
497                                                 state=HIDDEN1;
498                                                 param->name.s=tmp;
499                                                 break;
500                                         case BRANCH5:
501                                                 state=FIN_BRANCH;
502                                                 break;
503                                         case GEN_PARAM:
504                                                 break;
505                                         case F_CR:
506                                         case F_LF:
507                                         case F_CRLF:
508                                                 state=END_OF_HEADER;
509                                                 goto end_via;
510                                         default:
511                                                 state=GEN_PARAM;
512                                 }
513                                 break;
514                         case 'i':
515                         case 'I':
516                                 switch(state){
517                                         case F_PARAM:
518                                                 state=FIN_I;
519                                                 param->name.s=tmp;
520                                                 break;
521                                         case HIDDEN1:
522                                                 state=HIDDEN2;
523                                                 break;
524                                         case RECEIVED4:
525                                                 state=RECEIVED5;
526                                                 break;
527                                         case ALIAS2:
528                                                 state=ALIAS3;
529                                                 break;
530                                         case GEN_PARAM:
531                                                 break;
532                                         case F_CR:
533                                         case F_LF:
534                                         case F_CRLF:
535                                                 state=END_OF_HEADER;
536                                                 goto end_via;
537                                         default:
538                                                 state=GEN_PARAM;
539                                 }
540                                 break;
541                         case 'd':
542                         case 'D':
543                                 switch(state){
544                                         case F_PARAM:
545                                                 state=GEN_PARAM;
546                                                 param->name.s=tmp;
547                                                 break;
548                                         case HIDDEN2:
549                                                 state=HIDDEN3;
550                                                 break;
551                                         case HIDDEN3:
552                                                 state=HIDDEN4;
553                                                 break;
554                                         case MADDR2:
555                                                 state=MADDR3;
556                                                 break;
557                                         case MADDR3:
558                                                 state=MADDR4;
559                                                 break;
560                                         case RECEIVED7:
561                                                 state=FIN_RECEIVED;
562                                                 break;
563                                         case GEN_PARAM:
564                                                 break;
565                                         case F_CR:
566                                         case F_LF:
567                                         case F_CRLF:
568                                                 state=END_OF_HEADER;
569                                                 goto end_via;
570                                         default:
571                                                 state=GEN_PARAM;
572                                 }
573                                 break;
574                         case 'e':
575                         case 'E':
576                                 switch(state){
577                                         case F_PARAM:
578                                                 state=GEN_PARAM;
579                                                 param->name.s=tmp;
580                                                 break;
581                                         case HIDDEN4:
582                                                 state=HIDDEN5;
583                                                 break;
584                                         case RECEIVED1:
585                                                 state=RECEIVED2;
586                                                 break;
587                                         case RECEIVED3:
588                                                 state=RECEIVED4;
589                                                 break;
590                                         case RECEIVED6:
591                                                 state=RECEIVED7;
592                                                 break;
593                                         case GEN_PARAM:
594                                                 break;
595                                         case F_CR:
596                                         case F_LF:
597                                         case F_CRLF:
598                                                 state=END_OF_HEADER;
599                                                 goto end_via;
600                                         default:
601                                                 state=GEN_PARAM;
602                                 }
603                                 break;
604                         case 'n':
605                         case 'N':
606                                 switch(state){
607                                         case F_PARAM:
608                                                 state=GEN_PARAM;
609                                                 param->name.s=tmp;
610                                                 break;
611                                         case HIDDEN5:
612                                                 state=FIN_HIDDEN;
613                                                 break;
614                                         case BRANCH3:
615                                                 state=BRANCH4;
616                                                 break;
617                                         case GEN_PARAM:
618                                                 break;
619                                         case F_CR:
620                                         case F_LF:
621                                         case F_CRLF:
622                                                 state=END_OF_HEADER;
623                                                 goto end_via;
624                                         default:
625                                                 state=GEN_PARAM;
626                                 }
627                                 break;
628                         case 't':
629                         case 'T':
630                                 switch(state){
631                                         case F_PARAM:
632                                                 state=TTL1;
633                                                 param->name.s=tmp;
634                                                 break;
635                                         case TTL1:
636                                                 state=TTL2;
637                                                 break;
638                                         case RPORT3:
639                                                 state=FIN_RPORT;
640                                                 break;
641                                         case GEN_PARAM:
642                                                 break;
643                                         case F_CR:
644                                         case F_LF:
645                                         case F_CRLF:
646                                                 state=END_OF_HEADER;
647                                                 goto end_via;
648                                         default:
649                                                 state=GEN_PARAM;
650                                 }
651                                 break;
652                         case 'l':
653                         case 'L':
654                                 switch(state){
655                                         case F_PARAM:
656                                                 state=GEN_PARAM;
657                                                 param->name.s=tmp;
658                                                 break;
659                                         case TTL2:
660                                                 state=FIN_TTL;
661                                                 break;
662                                         case ALIAS1:
663                                                 state=ALIAS2;
664                                                 break;
665                                         case GEN_PARAM:
666                                                 break;
667                                         case F_CR:
668                                         case F_LF:
669                                         case F_CRLF:
670                                                 state=END_OF_HEADER;
671                                                 goto end_via;
672                                         default:
673                                                 state=GEN_PARAM;
674                                 }
675                                 break;
676                         case 'm':
677                         case 'M':
678                                 switch(state){
679                                         case F_PARAM:
680                                                 state=MADDR1;
681                                                 param->name.s=tmp;
682                                                 break;
683 #ifdef USE_COMP
684                                         case COMP2:
685                                                 state=COMP3;
686                                                 break;
687 #endif
688                                         case GEN_PARAM:
689                                                 break;
690                                         case F_CR:
691                                         case F_LF:
692                                         case F_CRLF:
693                                                 state=END_OF_HEADER;
694                                                 goto end_via;
695                                         default:
696                                                 state=GEN_PARAM;
697                                 }
698                                 break;
699                         case 'a':
700                         case 'A':
701                                 switch(state){
702                                         case F_PARAM:
703                                                 state=ALIAS1;
704                                                 param->name.s=tmp;
705                                                 break;
706                                         case MADDR1:
707                                                 state=MADDR2;
708                                                 break;
709                                         case BRANCH2:
710                                                 state=BRANCH3;
711                                                 break;
712                                         case ALIAS3:
713                                                 state=ALIAS4;
714                                                 break;
715                                         case GEN_PARAM:
716                                                 break;
717                                         case F_CR:
718                                         case F_LF:
719                                         case F_CRLF:
720                                                 state=END_OF_HEADER;
721                                                 goto end_via;
722                                         default:
723                                                 state=GEN_PARAM;
724                                 }
725                                 break;
726                         case 'r':
727                         case 'R':
728                                 switch(state){
729                                         case MADDR4:
730                                                 state=FIN_MADDR;
731                                                 break;
732                                         case F_PARAM:
733                                                 state=RECEIVED1;
734                                                 param->name.s=tmp;
735                                                 break;
736                                         case BRANCH1:
737                                                 state=BRANCH2;
738                                                 break;
739                                         case RPORT2:
740                                                 state=RPORT3;
741                                                 break;
742                                         case GEN_PARAM:
743                                                 break;
744                                         case F_CR:
745                                         case F_LF:
746                                         case F_CRLF:
747                                                 state=END_OF_HEADER;
748                                                 goto end_via;
749                                         default:
750                                                 state=GEN_PARAM;
751                                 }
752                                 break;
753                         case 'c':
754                         case 'C':
755                                 switch(state){
756                                         case F_PARAM:
757 #ifdef USE_COMP
758                                                 state=COMP1;
759 #else
760                                                 state=GEN_PARAM;
761 #endif
762                                                 param->name.s=tmp;
763                                                 break;
764                                         case RECEIVED2:
765                                                 state=RECEIVED3;
766                                                 break;
767                                         case BRANCH4:
768                                                 state=BRANCH5;
769                                                 break;
770                                         case GEN_PARAM:
771                                                 break;
772                                         case F_CR:
773                                         case F_LF:
774                                         case F_CRLF:
775                                                 state=END_OF_HEADER;
776                                                 goto end_via;
777                                         default:
778                                                 state=GEN_PARAM;
779                                 }
780                                 break;
781                         case 'v':
782                         case 'V':
783                                 switch(state){
784                                         case F_PARAM:
785                                                 state=GEN_PARAM;
786                                                 param->name.s=tmp;
787                                                 break;
788                                         case RECEIVED5:
789                                                 state=RECEIVED6;
790                                                 break;
791                                         case GEN_PARAM:
792                                                 break;
793                                         case F_CR:
794                                         case F_LF:
795                                         case F_CRLF:
796                                                 state=END_OF_HEADER;
797                                                 goto end_via;
798                                         default:
799                                                 state=GEN_PARAM;
800                                 }
801                                 break;
802                         case 'b':
803                         case 'B':
804                                 switch(state){
805                                         case F_PARAM:
806                                                 state=BRANCH1;
807                                                 param->name.s=tmp;
808                                                 break;
809                                         case GEN_PARAM:
810                                                 break;
811                                         case F_CR:
812                                         case F_LF:
813                                         case F_CRLF:
814                                                 state=END_OF_HEADER;
815                                                 goto end_via;
816                                         default:
817                                                 state=GEN_PARAM;
818                                 }
819                                 break;
820                         case 'p':
821                         case 'P':
822                                 switch(state){
823                                         case F_PARAM:
824                                                 state=GEN_PARAM;
825                                                 param->name.s=tmp;
826                                                 break;
827                                         case RECEIVED1:
828                                                 state=RPORT1;
829                                                 break;
830 #ifdef USE_COMP
831                                         case COMP3:
832                                                 state=FIN_COMP;
833                                                 break;
834 #endif
835                                         case F_CR:
836                                         case F_LF:
837                                         case F_CRLF:
838                                                 state=END_OF_HEADER;
839                                                 goto end_via;
840                                         default:
841                                                 state=GEN_PARAM;
842                                 }
843                                 break;
844                         case 'o':
845                         case 'O':
846                                 switch(state){
847                                         case F_PARAM:
848                                                 state=GEN_PARAM;
849                                                 param->name.s=tmp;
850                                                 break;
851                                         case RPORT1:
852                                                 state=RPORT2;
853                                                 break;
854 #ifdef USE_COMP
855                                         case COMP1:
856                                                 state=COMP2;
857                                                 break;
858 #endif
859                                         case F_CR:
860                                         case F_LF:
861                                         case F_CRLF:
862                                                 state=END_OF_HEADER;
863                                                 goto end_via;
864                                         default:
865                                                 state=GEN_PARAM;
866                                 }
867                                 break;
868                         case 's':
869                         case 'S':
870                                 switch(state){
871                                         case F_PARAM:
872                                                 state=GEN_PARAM;
873                                                 param->name.s=tmp;
874                                                 break;
875                                         case ALIAS4:
876                                                 state=FIN_ALIAS;
877                                                 break;
878                                         case F_CR:
879                                         case F_LF:
880                                         case F_CRLF:
881                                                 state=END_OF_HEADER;
882                                                 goto end_via;
883                                         default:
884                                                 state=GEN_PARAM;
885                                 }
886                                 break;
887                         default:
888                                 switch(state){
889                                         case F_PARAM:
890                                                 state=GEN_PARAM;
891                                                 param->name.s=tmp;
892                                                 break;
893                                         case GEN_PARAM:
894                                                 break;
895                                         case F_CR:
896                                         case F_LF:
897                                         case F_CRLF:
898                                                 state=END_OF_HEADER;
899                                                 goto end_via;
900                                         default:
901                                                 state=GEN_PARAM;
902                                 }
903                 }
904         }/* for tmp*/
905
906         /* end of packet? => error, no cr/lf,',' found!!!*/
907         saved_state=state;
908         state=END_OF_HEADER;
909         goto error;
910         
911  find_value:
912         tmp++;
913         for(;*tmp;tmp++){
914                 switch(*tmp){
915                         case ' ':
916                         case '\t':
917                                 switch(state){
918                                         case L_VALUE:
919                                         case F_VALUE: /*eat space*/
920                                                 break; 
921                                         case P_VALUE:
922                                                 state=L_PARAM;
923                                                 param->value.len=tmp-param->value.s;
924                                                 goto endofvalue;
925 #ifdef USE_COMP
926                                         case L_COMP_VALUE:
927                                         case F_COMP_VALUE:
928                                                 break; /* eat space */
929                                         case FIN_V_SIGCOMP_P:
930                                                 state=L_PARAM;
931                                                 param->value.len=tmp-param->value.s;
932                                                 vb->comp_no=COMP_SIGCOMP;
933                                                 goto endofvalue;
934                                         case FIN_V_SERGZ_Z:
935                                                 state=L_PARAM;
936                                                 param->value.len=tmp-param->value.s;
937                                                 vb->comp_no=COMP_SIGCOMP;
938                                                 goto endofvalue;
939                                         comp_states_cases
940                                                 state=L_PARAM;
941                                                 param->value.len=tmp-param->value.s;
942                                                 comp_unexpected_char;
943                                                 goto endofvalue;
944 #endif
945                                         case P_STRING:
946                                                 break;
947                                         case F_CR:
948                                         case F_LF:
949                                         case F_CRLF:
950                                                 state=saved_state;
951                                                 break;
952                                         default:
953                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
954                                                                 " in state %d\n", *tmp, state);
955                                                 goto error;
956                                 }
957                                 break;
958                         case '\n':
959                                 switch(state){
960                                         case L_VALUE:
961                                         case F_VALUE: /*eat space*/
962 #ifdef USE_COMP
963                                         case L_COMP_VALUE:
964                                         case F_COMP_VALUE:
965 #endif
966                                         case P_STRING:
967                                                 saved_state=state;
968                                                 param->size=tmp-param->start;
969                                                 state=F_LF;
970                                                 break;
971                                         case P_VALUE:
972                                                 saved_state=L_PARAM;
973                                                 state=F_LF;
974                                                 param->value.len=tmp-param->value.s;
975                                                 goto endofvalue;
976 #ifdef USE_COMP
977                                         case FIN_V_SIGCOMP_P:
978                                                 saved_state=L_PARAM;
979                                                 state=F_LF;
980                                                 param->value.len=tmp-param->value.s;
981                                                 vb->comp_no=COMP_SIGCOMP;
982                                                 goto endofvalue;
983                                         case FIN_V_SERGZ_Z:
984                                                 saved_state=L_PARAM;
985                                                 state=F_LF;
986                                                 param->value.len=tmp-param->value.s;
987                                                 vb->comp_no=COMP_SIGCOMP;
988                                                 goto endofvalue;
989                                         comp_states_cases
990                                                 saved_state=L_PARAM;
991                                                 state=F_LF;
992                                                 param->value.len=tmp-param->value.s;
993                                                 comp_unexpected_char;
994                                                 goto endofvalue;
995 #endif
996                                         case F_LF:
997                                         case F_CRLF:
998                                                 state=END_OF_HEADER;
999                                                 goto end_via;
1000                                         case F_CR:
1001                                                 state=F_CRLF;
1002                                                 break;
1003                                         default:
1004                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1005                                                                 " in state %d\n", *tmp, state);
1006                                                 goto error;
1007                                 }
1008                                 break;
1009                         case '\r':
1010                                 switch(state){
1011                                         case L_VALUE:
1012                                         case F_VALUE: /*eat space*/
1013 #ifdef USE_COMP
1014                                         case L_COMP_VALUE:
1015                                         case F_COMP_VALUE:
1016 #endif
1017                                         case P_STRING:
1018                                                 saved_state=state;
1019                                                 param->size=tmp-param->start;
1020                                                 state=F_CR;
1021                                                 break;
1022                                         case P_VALUE:
1023                                                 param->value.len=tmp-param->value.s;
1024                                                 saved_state=L_PARAM;
1025                                                 state=F_CR;
1026                                                 goto endofvalue;
1027 #ifdef USE_COMP
1028                                         case FIN_V_SIGCOMP_P:
1029                                                 saved_state=L_PARAM;
1030                                                 state=F_CR;
1031                                                 param->value.len=tmp-param->value.s;
1032                                                 vb->comp_no=COMP_SIGCOMP;
1033                                                 goto endofvalue;
1034                                         case FIN_V_SERGZ_Z:
1035                                                 saved_state=L_PARAM;
1036                                                 state=F_CR;
1037                                                 param->value.len=tmp-param->value.s;
1038                                                 vb->comp_no=COMP_SIGCOMP;
1039                                                 goto endofvalue;
1040                                         comp_states_cases
1041                                                 saved_state=L_PARAM;
1042                                                 state=F_CR;
1043                                                 param->value.len=tmp-param->value.s;
1044                                                 comp_unexpected_char;
1045                                                 goto endofvalue;
1046 #endif
1047                                         case F_LF:
1048                                         case F_CR:
1049                                         case F_CRLF:
1050                                                 state=END_OF_HEADER;
1051                                                 goto end_via;
1052                                         default:
1053                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1054                                                                 " in state %d\n", *tmp, state);
1055                                                 goto error;
1056                                 }
1057                                 break;
1058
1059                         case '=':
1060                                 switch(state){
1061                                         case L_VALUE:
1062                                                 state=F_VALUE;
1063                                                 break;
1064 #ifdef USE_COMP
1065                                         case L_COMP_VALUE:
1066                                                 state=F_COMP_VALUE;
1067                                                 break;
1068                                         /* '=' in any other COMP value state is an error,
1069                                          * and it will be catched by the default branch */
1070 #endif
1071                                         case P_STRING:
1072                                                 break;
1073                                         case F_LF:
1074                                         case F_CR:
1075                                         case F_CRLF:
1076                                                 state=END_OF_HEADER;
1077                                                 goto end_via;
1078                                         default:
1079                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1080                                                                 " in state %d\n", *tmp, state);
1081                                                 goto error;
1082                                 }
1083                                 break;
1084                         case ';':
1085                                 switch(state){
1086                                         case P_VALUE:
1087                                                 param->value.len=tmp-param->value.s;
1088                                                 state=F_PARAM;
1089                                                 goto endofvalue;
1090                                         case F_VALUE:
1091                                                 param->value.len=0;
1092                                                 state=F_PARAM;
1093                                                 goto endofvalue;
1094                                         case P_STRING:
1095                                                 break; /* what to do? */
1096                                         case F_LF:
1097                                         case F_CR:
1098                                         case F_CRLF:
1099                                                 state=END_OF_HEADER;
1100                                                 goto end_via;
1101 #ifdef USE_COMP
1102                                         case L_COMP_VALUE:
1103                                                 comp_unexpected_char;
1104                                                 /* we want to contine with no comp */
1105                                                 state=F_PARAM;
1106                                                 param->value.len=0;
1107                                                 param->value.s=0;
1108                                                 goto endofvalue;
1109                                         case F_COMP_VALUE:
1110                                                 comp_unexpected_char;
1111                                                 param->value.len=0;
1112                                                 state=F_PARAM;
1113                                                 goto endofvalue;
1114                                         comp_states_cases
1115                                                 comp_unexpected_char;
1116                                                 param->value.len=tmp-param->value.s;
1117                                                 state=F_PARAM;
1118                                                 goto endofvalue;
1119                                         case FIN_V_SIGCOMP_P:
1120                                                 vb->comp_no=COMP_SIGCOMP;
1121                                                 param->value.len=tmp-param->value.s;
1122                                                 state=F_PARAM;
1123                                                 goto endofvalue;
1124                                         case FIN_V_SERGZ_Z:
1125                                                 vb->comp_no=COMP_SIGCOMP;
1126                                                 param->value.len=tmp-param->value.s;
1127                                                 state=F_PARAM;
1128                                                 goto endofvalue;
1129 #endif
1130                                         case L_VALUE:
1131                                                 param->value.len=0;
1132                                                 param->value.s=0; /* null value */
1133                                                 state=F_PARAM;
1134                                                 goto endofvalue;
1135                                         default:
1136                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1137                                                                 " in state %d\n", *tmp, state);
1138                                                 goto error;
1139                                 }
1140                                 break;
1141                         case ',':
1142                                 switch(state){
1143                                         case P_VALUE:
1144                                                 param->value.len=tmp-param->value.s;
1145                                                 state=F_VIA;
1146                                                 goto endofvalue;
1147                                         case P_STRING:
1148                                         case F_LF:
1149                                         case F_CR:
1150                                         case F_CRLF:
1151                                                 state=END_OF_HEADER;
1152                                                 goto end_via;
1153 #ifdef USE_COMP
1154                                         case L_COMP_VALUE:
1155                                                 comp_unexpected_char;
1156                                                 /* we want to contine with no comp */
1157                                                 state=F_VIA;
1158                                                 param->value.len=0;
1159                                                 param->value.s=0;
1160                                                 goto endofvalue;
1161                                         case F_COMP_VALUE:
1162                                                 comp_unexpected_char;
1163                                                 param->value.len=0;
1164                                                 state=F_VIA;
1165                                                 goto endofvalue;
1166                                         comp_states_cases
1167                                                 comp_unexpected_char;
1168                                                 param->value.len=tmp-param->value.s;
1169                                                 state=F_VIA;
1170                                                 goto endofvalue;
1171                                         case FIN_V_SIGCOMP_P:
1172                                                 vb->comp_no=COMP_SIGCOMP;
1173                                                 param->value.len=tmp-param->value.s;
1174                                                 state=F_VIA;
1175                                                 goto endofvalue;
1176                                         case FIN_V_SERGZ_Z:
1177                                                 vb->comp_no=COMP_SIGCOMP;
1178                                                 param->value.len=tmp-param->value.s;
1179                                                 state=F_VIA;
1180                                                 goto endofvalue;
1181 #endif
1182                                         case L_VALUE:
1183                                                 if (param->type==FIN_RPORT){
1184                                                         param->value.len=0;
1185                                                         param->value.s=0; /* null value */
1186                                                         state=F_VIA;
1187                                                         goto endofvalue;
1188                                                 };
1189                                                 /* no break */
1190                                         default:
1191                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1192                                                                 " in state %d\n", *tmp, state);
1193                                                 goto error;
1194                                 }
1195                                 break; /* what to do? */
1196                         case '"':
1197                                 switch(state){
1198                                         case F_VALUE:
1199                                                 state=P_STRING;
1200                                                 param->value.s=tmp+1;
1201                                                 break;
1202                                         case P_STRING:
1203                                                 state=L_PARAM;
1204                                                 param->value.len=tmp-param->value.s;
1205                                                 goto endofvalue;
1206                                         case F_LF:
1207                                         case F_CR:
1208                                         case F_CRLF:
1209                                                 state=END_OF_HEADER;
1210                                                 goto end_via;
1211                                         default:
1212                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1213                                                                 " in state %d\n", *tmp, state);
1214                                                 goto error;
1215                                 }
1216                                 break;
1217 #ifdef USE_COMP
1218                         value_case('s', 'S', F_COMP_VALUE, V_COMP_S, 1);
1219                         value_case('i', 'I', V_COMP_S, V_SIGCOMP_I, 0);
1220                         value_case_double('g', 'G', V_SIGCOMP_I, V_SIGCOMP_G,
1221                                                             V_SERGZ_R,   V_SERGZ_G);
1222                         value_case('c', 'C', V_SIGCOMP_G, V_SIGCOMP_C, 0);
1223                         value_case('o', 'O', V_SIGCOMP_C, V_SIGCOMP_O, 0);
1224                         value_case('m', 'M', V_SIGCOMP_O, V_SIGCOMP_M, 0);
1225                         value_case('p', 'P', V_SIGCOMP_M, FIN_V_SIGCOMP_P, 0);
1226                         
1227                         value_case('e', 'E', V_COMP_S, V_SERGZ_E, 0);
1228                         value_case('r', 'R', V_SERGZ_E, V_SERGZ_R, 0);
1229                         value_case('z', 'Z', V_SERGZ_G, FIN_V_SERGZ_Z, 0);
1230 #endif /* USE_COMP */
1231                                 
1232                         default:
1233                                 switch(state){
1234                                         case F_VALUE:
1235                                                 state=P_VALUE;
1236                                                 param->value.s=tmp;
1237                                                 break;
1238                                         case P_VALUE:
1239                                         case P_STRING:
1240                                                 break;
1241                                         case F_LF:
1242                                         case F_CR:
1243                                         case F_CRLF:
1244                                                 state=END_OF_HEADER;
1245                                                 goto end_via;
1246                                         default:
1247 #ifdef USE_COMP
1248                                                 switch(state){
1249                                                         case F_COMP_VALUE:
1250                                                                 comp_unexpected_char;
1251                                                                 state=P_VALUE;
1252                                                                 param->value.s=tmp;
1253                                                                 break;
1254                                                         comp_states_cases
1255                                                         comp_fin_states_cases
1256                                                                 comp_unexpected_char;
1257                                                                 state=P_VALUE;
1258                                                                 break;
1259                                                         default:
1260                                                                 LOG(L_ERR, "ERROR: parse_via_param: invalid "
1261                                                                         "char <%c> in state %d\n", *tmp, state);
1262                                                                 goto error;
1263                                                 }
1264 #else
1265                                                 LOG(L_ERR, "ERROR: parse_via: invalid char <%c>"
1266                                                                 " in state %d\n", *tmp, state);
1267                                                 goto error;
1268 #endif /* USE_COMP */
1269                                 }
1270                 }
1271         } /* for2 tmp*/
1272
1273         /* end of buff and no CR/LF =>error*/
1274         saved_state=state;
1275         state=END_OF_HEADER;
1276         goto error;
1277         
1278  endofparam:
1279  endofvalue:
1280         param->size=tmp-param->start;
1281 normal_exit:
1282         *pstate=state;
1283         *psaved_state=saved_state;
1284         DBG("Found param type %d, <%.*s> = <%.*s>; state=%d\n", param->type,
1285                         param->name.len, ZSW(param->name.s), 
1286                         (param->value.len?param->value.len:3),
1287                         (param->value.len?param->value.s:"n/a"), state);
1288         return tmp;
1289         
1290  end_via:
1291              /* if we are here we found an "unexpected" end of via
1292               *  (cr/lf). This is valid only if the param type is GEN_PARAM or
1293                   *  RPORT (the only ones which can miss the value; HIDDEN is a 
1294                   *  special case )*/
1295         if ((param->type==GEN_PARAM)||(param->type==PARAM_RPORT)){
1296                 saved_state=L_PARAM; /* change the saved_state, we have an unknown
1297                                         param. w/o a value */
1298                 /* param->size should be computed before */
1299                 goto normal_exit;
1300         }
1301         *pstate=state;
1302         *psaved_state=saved_state;
1303         DBG("Error on  param type %d, <%.*s>, state=%d, saved_state=%d\n",
1304                 param->type, param->name.len, ZSW(param->name.s), state, saved_state);
1305
1306  error:
1307         LOG(L_ERR, "error: parse_via_param\n");
1308         param->type=PARAM_ERROR;
1309         *pstate=PARAM_ERROR;
1310         *psaved_state=state;
1311         return tmp;
1312 }
1313
1314
1315
1316 /*
1317  * call it with a vb initialized to 0
1318  * returns: pointer after the parsed parts and sets vb->error
1319  * WARNING: don't forget to cleanup on error with free_via_list(vb)!
1320  */
1321 char* parse_via(char* buffer, char* end, struct via_body *vbody)
1322 {
1323         char* tmp;
1324         char* param_start;
1325         unsigned char state;
1326         unsigned char saved_state;
1327         int c_nest;
1328         int err;
1329         struct via_body* vb;
1330         struct via_param* param;
1331
1332         vb=vbody; /* keep orignal vbody value, needed to set the error member
1333                                  in case of multiple via bodies in the same header */
1334 parse_again:
1335         vb->error=PARSE_ERROR;
1336         /* parse start of via ( SIP/2.0/UDP    )*/
1337         state=F_SIP;
1338         saved_state=F_SIP; /* fixes gcc 4.0 warning */
1339         param_start=0;
1340         for(tmp=buffer;tmp<end;tmp++){
1341                 switch(*tmp){
1342                         case ' ':
1343                         case'\t':
1344                                 switch(state){
1345                                         case L_VER: /* eat space */
1346                                         case L_PROTO:
1347                                         case F_SIP:
1348                                         case F_VER:
1349                                         case F_PROTO:
1350                                                 break;
1351                                         case FIN_UDP:
1352                                                 vb->transport.len=tmp-vb->transport.s;
1353                                                 vb->proto=PROTO_UDP;
1354                                                 state=F_HOST; /* start looking for host*/
1355                                                 goto main_via;
1356                                         case FIN_TCP:
1357                                                 /* finished proto parsing */
1358                                                 vb->transport.len=tmp-vb->transport.s;
1359                                                 vb->proto=PROTO_TCP;
1360                                                 state=F_HOST; /* start looking for host*/
1361                                                 goto main_via;
1362                                         case FIN_TLS:
1363                                                 /* finished proto parsing */
1364                                                 vb->transport.len=tmp-vb->transport.s;
1365                                                 vb->proto=PROTO_TLS;
1366                                                 state=F_HOST; /* start looking for host*/
1367                                                 goto main_via;
1368                                         case FIN_SCTP:
1369                                                 /* finished proto parsing */
1370                                                 vb->transport.len=tmp-vb->transport.s;
1371                                                 vb->proto=PROTO_SCTP;
1372                                                 state=F_HOST; /* start looking for host*/
1373                                                 goto main_via;
1374                                         case WS_WSS2:
1375                                                 /* finished proto parsing */
1376                                                 vb->transport.len=tmp-vb->transport.s;
1377                                                 vb->proto=PROTO_TCP;
1378                                                 state=F_HOST; /* start looking for host*/
1379                                                 goto main_via;
1380                                         case FIN_WSS:
1381                                                 /* finished proto parsing */
1382                                                 vb->transport.len=tmp-vb->transport.s;
1383                                                 vb->proto=PROTO_TLS;
1384                                                 state=F_HOST; /* start looking for host*/
1385                                                 goto main_via;
1386                                         case OTHER_PROTO:
1387                                                 /* finished proto parsing */
1388                                                 vb->transport.len=tmp-vb->transport.s;
1389                                                 vb->proto=PROTO_OTHER;
1390                                                 state=F_HOST; /* start looking for host*/
1391                                                 goto main_via;
1392                                         case UDP1:
1393                                         case UDP2:
1394                                         case TCP_TLS1:
1395                                         case TCP2:
1396                                         case TLS2:
1397                                         case SCTP1:
1398                                         case SCTP2:
1399                                         case SCTP3:
1400                                         case WS_WSS1:
1401                                                 /* finished proto parsing */
1402                                                 vb->transport.len=tmp-vb->transport.s;
1403                                                 vb->proto=PROTO_OTHER;
1404                                                 state=F_HOST; /* start looking for host*/
1405                                                 goto main_via;
1406                                         case FIN_SIP:
1407                                                 vb->name.len=tmp-vb->name.s;
1408                                                 state=L_VER;
1409                                                 break;
1410                                         case FIN_VER:
1411                                                 vb->version.len=tmp-vb->version.s;
1412                                                 state=L_PROTO;
1413                                                 break;
1414                                         case F_LF:
1415                                         case F_CRLF:
1416                                         case F_CR: /* header continues on this line */
1417                                                 state=saved_state;
1418                                                 break;
1419                                         default:
1420                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1421                                                                 " state %d\n", *tmp, state);
1422                                                 goto error;
1423                                 }
1424                                 break;
1425                         case '\n':
1426                                 switch(state){
1427                                         case L_VER:
1428                                         case F_SIP:
1429                                         case F_VER:
1430                                         case F_PROTO:
1431                                         case L_PROTO:
1432                                                 saved_state=state;
1433                                                 state=F_LF;
1434                                                 break;
1435                                         case FIN_UDP:
1436                                                 vb->transport.len=tmp-vb->transport.s;
1437                                                 vb->proto=PROTO_UDP;
1438                                                 state=F_LF;
1439                                                 saved_state=F_HOST; /* start looking for host*/
1440                                                 goto main_via;
1441                                         case FIN_TCP:
1442                                                 vb->transport.len=tmp-vb->transport.s;
1443                                                 vb->proto=PROTO_TCP;
1444                                                 state=F_LF;
1445                                                 saved_state=F_HOST; /* start looking for host*/
1446                                                 goto main_via;
1447                                         case FIN_TLS:
1448                                                 vb->transport.len=tmp-vb->transport.s;
1449                                                 vb->proto=PROTO_TLS;
1450                                                 state=F_LF;
1451                                                 saved_state=F_HOST; /* start looking for host*/
1452                                                 goto main_via;
1453                                         case FIN_SCTP:
1454                                                 /* finished proto parsing */
1455                                                 vb->transport.len=tmp-vb->transport.s;
1456                                                 vb->proto=PROTO_SCTP;
1457                                                 state=F_LF;
1458                                                 saved_state=F_HOST; /* start looking for host*/
1459                                                 goto main_via;
1460                                         case WS_WSS2:
1461                                                 /* finished proto parsing */
1462                                                 vb->transport.len=tmp-vb->transport.s;
1463                                                 vb->proto=PROTO_TCP;
1464                                                 state=F_LF;
1465                                                 saved_state=F_HOST; /* start looking for host*/
1466                                                 goto main_via;
1467                                         case FIN_WSS:
1468                                                 /* finished proto parsing */
1469                                                 vb->transport.len=tmp-vb->transport.s;
1470                                                 vb->proto=PROTO_TLS;
1471                                                 state=F_LF;
1472                                                 saved_state=F_HOST; /* start looking for host*/
1473                                                 goto main_via;
1474                                         case OTHER_PROTO:
1475                                                 /* finished proto parsing */
1476                                                 vb->transport.len=tmp-vb->transport.s;
1477                                                 vb->proto=PROTO_OTHER;
1478                                                 state=F_LF;
1479                                                 saved_state=F_HOST; /* start looking for host*/
1480                                                 goto main_via;
1481                                         case UDP1:
1482                                         case UDP2:
1483                                         case TCP_TLS1:
1484                                         case TCP2:
1485                                         case TLS2:
1486                                         case SCTP1:
1487                                         case SCTP2:
1488                                         case SCTP3:
1489                                         case WS_WSS1:
1490                                                 /* finished proto parsing */
1491                                                 vb->transport.len=tmp-vb->transport.s;
1492                                                 vb->proto=PROTO_OTHER;
1493                                                 state=F_LF;
1494                                                 saved_state=F_HOST; /* start looking for host*/
1495                                                 goto main_via;
1496                                         case FIN_SIP:
1497                                                 vb->name.len=tmp-vb->name.s;
1498                                                 state=F_LF;
1499                                                 saved_state=L_VER;
1500                                                 break;
1501                                         case FIN_VER:
1502                                                 vb->version.len=tmp-vb->version.s;
1503                                                 state=F_LF;
1504                                                 saved_state=L_PROTO;
1505                                                 break;
1506                                         case F_CR:
1507                                                 state=F_CRLF;
1508                                                 break;
1509                                         case F_LF:
1510                                         case F_CRLF:
1511                                                 state=saved_state;
1512                                                 goto endofheader;
1513                                         default:
1514                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1515                                                                 " state %d\n", *tmp, state);
1516                                                 goto error;
1517                                 }
1518                                 break;
1519                         case '\r':
1520                                 switch(state){
1521                                         case L_VER:
1522                                         case F_SIP:
1523                                         case F_VER:
1524                                         case F_PROTO:
1525                                         case L_PROTO:
1526                                                 saved_state=state;
1527                                                 state=F_CR;
1528                                                 break;
1529                                         case FIN_UDP:
1530                                                 vb->transport.len=tmp-vb->transport.s;
1531                                                 vb->proto=PROTO_UDP;
1532                                                 state=F_CR;
1533                                                 saved_state=F_HOST;
1534                                                 goto main_via;
1535                                         case FIN_TCP:
1536                                                 vb->transport.len=tmp-vb->transport.s;
1537                                                 vb->proto=PROTO_TCP;
1538                                                 state=F_CR;
1539                                                 saved_state=F_HOST;
1540                                                 goto main_via;
1541                                         case FIN_TLS:
1542                                                 vb->transport.len=tmp-vb->transport.s;
1543                                                 vb->proto=PROTO_TLS;
1544                                                 state=F_CR;
1545                                                 saved_state=F_HOST;
1546                                                 goto main_via;
1547                                         case FIN_SCTP:
1548                                                 vb->transport.len=tmp-vb->transport.s;
1549                                                 vb->proto=PROTO_SCTP;
1550                                                 state=F_CR;
1551                                                 saved_state=F_HOST;
1552                                                 goto main_via;
1553                                         case WS_WSS2:
1554                                                 vb->transport.len=tmp-vb->transport.s;
1555                                                 vb->proto=PROTO_TCP;
1556                                                 state=F_CR;
1557                                                 saved_state=F_HOST;
1558                                                 goto main_via;
1559                                         case FIN_WSS:
1560                                                 vb->transport.len=tmp-vb->transport.s;
1561                                                 vb->proto=PROTO_TLS;
1562                                                 state=F_CR;
1563                                                 saved_state=F_HOST;
1564                                                 goto main_via;
1565                                         case OTHER_PROTO:
1566                                                 vb->transport.len=tmp-vb->transport.s;
1567                                                 vb->proto=PROTO_OTHER;
1568                                                 state=F_CR;
1569                                                 saved_state=F_HOST;
1570                                                 goto main_via;
1571                                         case UDP1:
1572                                         case UDP2:
1573                                         case TCP_TLS1:
1574                                         case TCP2:
1575                                         case TLS2:
1576                                         case SCTP1:
1577                                         case SCTP2:
1578                                         case SCTP3:
1579                                         case WS_WSS1:
1580                                                 /* finished proto parsing */
1581                                                 vb->transport.len=tmp-vb->transport.s;
1582                                                 vb->proto=PROTO_OTHER;
1583                                                 state=F_CR;
1584                                                 saved_state=F_HOST;
1585                                                 goto main_via;
1586                                         case FIN_SIP:
1587                                                 vb->name.len=tmp-vb->name.s;
1588                                                 state=F_CR;
1589                                                 saved_state=L_VER;
1590                                                 break;
1591                                         case FIN_VER:
1592                                                 vb->version.len=tmp-vb->version.s;
1593                                                 state=F_CR;
1594                                                 saved_state=L_PROTO;
1595                                                 break;
1596                                         case F_LF: /*end of line ?next header?*/
1597                                         case F_CR:
1598                                         case F_CRLF:
1599                                                 state=saved_state;
1600                                                 goto endofheader;
1601                                         default:
1602                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1603                                                                 " state %d\n", *tmp, state);
1604                                                 goto error;
1605                                 }
1606                                 break;
1607                         
1608                         case '/':
1609                                 switch(state){
1610                                         case FIN_SIP:
1611                                                 vb->name.len=tmp-vb->name.s;
1612                                                 state=F_VER;
1613                                                 break;
1614                                         case FIN_VER:
1615                                                 vb->version.len=tmp-vb->version.s;
1616                                                 state=F_PROTO;
1617                                                 break;
1618                                         case L_VER:
1619                                                 state=F_VER;
1620                                                 break;
1621                                         case L_PROTO:
1622                                                 state=F_PROTO;
1623                                                 break;
1624                                         default:
1625                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1626                                                                 " state %d\n", *tmp, state);
1627                                                 goto error;
1628                                 }
1629                                 break;
1630                                 /* match SIP*/
1631                         case 'S':
1632                         case 's':
1633                                 switch(state){
1634                                         case F_SIP:
1635                                                 state=SIP1;
1636                                                 vb->name.s=tmp;
1637                                                 break;
1638                                         case TLS2:
1639                                                 state=FIN_TLS;
1640                                                 break;
1641                                         case WS_WSS1:
1642                                                 state=WS_WSS2;
1643                                                 break;
1644                                         case WS_WSS2:
1645                                                 state=FIN_WSS;
1646                                                 break;
1647                                         case F_PROTO:
1648                                                 state=SCTP1;
1649                                                 vb->transport.s=tmp;
1650                                                 break;
1651                                         case OTHER_PROTO:
1652                                                 break;
1653                                         case UDP1:
1654                                         case UDP2:
1655                                         case FIN_UDP:
1656                                         case TCP_TLS1:
1657                                         case TCP2:
1658                                         case FIN_TCP:
1659                                         case FIN_TLS:
1660                                         case SCTP1:
1661                                         case SCTP2:
1662                                         case SCTP3:
1663                                         case FIN_WSS:
1664                                         case FIN_SCTP:
1665                                                 state=OTHER_PROTO;
1666                                                 break;
1667                                         default:
1668                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1669                                                                 " state %d\n", *tmp, state);
1670                                                 goto error;
1671                                 }
1672                                 break;
1673                         case 'I':
1674                         case 'i':
1675                                 switch(state){
1676                                         case SIP1:
1677                                                 state=SIP2;
1678                                                 break;
1679                                         case OTHER_PROTO:
1680                                                 break;
1681                                         case UDP1:
1682                                         case UDP2:
1683                                         case FIN_UDP:
1684                                         case TCP_TLS1:
1685                                         case TCP2:
1686                                         case FIN_TCP:
1687                                         case TLS2:
1688                                         case FIN_TLS:
1689                                         case SCTP1:
1690                                         case SCTP2:
1691                                         case SCTP3:
1692                                         case FIN_SCTP:
1693                                         case WS_WSS1:
1694                                         case WS_WSS2:
1695                                         case FIN_WSS:
1696                                                 state=OTHER_PROTO;
1697                                                 break;
1698                                         default:
1699                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1700                                                                 " state %d\n", *tmp, state);
1701                                                 goto error;
1702                                 }
1703                                 break;
1704                         case 'p':
1705                         case 'P':
1706                                 switch(state){
1707                                         case SIP2:
1708                                                 state=FIN_SIP;
1709                                                 break;
1710                                         /* allow p in PROTO */
1711                                         case UDP2:
1712                                                 state=FIN_UDP;
1713                                                 break;
1714                                         case TCP2:
1715                                                 state=FIN_TCP;
1716                                                 break;
1717                                         case SCTP3:
1718                                                 state=FIN_SCTP;
1719                                                 break;
1720                                         case OTHER_PROTO:
1721                                                 break;
1722                                         case UDP1:
1723                                         case FIN_UDP:
1724                                         case TCP_TLS1:
1725                                         case FIN_TCP:
1726                                         case TLS2:
1727                                         case FIN_TLS:
1728                                         case SCTP1:
1729                                         case SCTP2:
1730                                         case FIN_SCTP:
1731                                         case WS_WSS1:
1732                                         case WS_WSS2:
1733                                         case FIN_WSS:
1734                                                 state=OTHER_PROTO;
1735                                                 break;
1736                                         default:
1737                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1738                                                                 " state %d\n", *tmp, state);
1739                                                 goto error;
1740                                 }
1741                                 break;
1742                         case 'U':
1743                         case 'u':
1744                                 switch(state){
1745                                         case F_PROTO:
1746                                                 state=UDP1;
1747                                                 vb->transport.s=tmp;
1748                                                 break;
1749                                         case OTHER_PROTO:
1750                                                 break;
1751                                         case UDP1:
1752                                         case UDP2:
1753                                         case FIN_UDP:
1754                                         case TCP_TLS1:
1755                                         case TCP2:
1756                                         case FIN_TCP:
1757                                         case TLS2:
1758                                         case FIN_TLS:
1759                                         case SCTP1:
1760                                         case SCTP2:
1761                                         case SCTP3:
1762                                         case FIN_SCTP:
1763                                         case WS_WSS1:
1764                                         case WS_WSS2:
1765                                         case FIN_WSS:
1766                                                 state=OTHER_PROTO;
1767                                                 break;
1768                                         default:
1769                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1770                                                                 " state %d\n", *tmp, state);
1771                                                 goto error;
1772                                 }
1773                                 break;
1774                         case 'D':
1775                         case 'd':
1776                                 switch(state){
1777                                         case UDP1:
1778                                                 state=UDP2;
1779                                                 break;
1780                                         case OTHER_PROTO:
1781                                                 break;
1782                                         case UDP2:
1783                                         case FIN_UDP:
1784                                         case TCP_TLS1:
1785                                         case TCP2:
1786                                         case FIN_TCP:
1787                                         case TLS2:
1788                                         case FIN_TLS:
1789                                         case SCTP1:
1790                                         case SCTP2:
1791                                         case SCTP3:
1792                                         case FIN_SCTP:
1793                                         case WS_WSS1:
1794                                         case WS_WSS2:
1795                                         case FIN_WSS:
1796                                                 state=OTHER_PROTO;
1797                                                 break;
1798                                         default:
1799                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1800                                                                 " state %d\n", *tmp, state);
1801                                                 goto error;
1802                                 }
1803                                 break;
1804                         case 'T':
1805                         case 't':
1806                                 switch(state){
1807                                         case F_PROTO:
1808                                                 state=TCP_TLS1;
1809                                                 vb->transport.s=tmp;
1810                                                 break;
1811                                         case SCTP2:
1812                                                 state=SCTP3;
1813                                                 break;
1814                                         case OTHER_PROTO:
1815                                                 break;
1816                                         case UDP1:
1817                                         case UDP2:
1818                                         case FIN_UDP:
1819                                         case TCP_TLS1:
1820                                         case TCP2:
1821                                         case FIN_TCP:
1822                                         case TLS2:
1823                                         case FIN_TLS:
1824                                         case SCTP1:
1825                                         case SCTP3:
1826                                         case FIN_SCTP:
1827                                         case WS_WSS1:
1828                                         case WS_WSS2:
1829                                         case FIN_WSS:
1830                                                 state=OTHER_PROTO;
1831                                                 break;
1832                                         default:
1833                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1834                                                                 " state %d\n", *tmp, state);
1835                                                 goto error;
1836                                 }
1837                                 break;
1838                         case 'C':
1839                         case 'c':
1840                                 switch(state){
1841                                         case TCP_TLS1:
1842                                                 state=TCP2;
1843                                                 break;
1844                                         case SCTP1:
1845                                                 state=SCTP2;
1846                                                 break;
1847                                         case OTHER_PROTO:
1848                                                 break;
1849                                         case UDP1:
1850                                         case UDP2:
1851                                         case FIN_UDP:
1852                                         case TCP2:
1853                                         case FIN_TCP:
1854                                         case TLS2:
1855                                         case FIN_TLS:
1856                                         case SCTP2:
1857                                         case SCTP3:
1858                                         case FIN_SCTP:
1859                                         case WS_WSS1:
1860                                         case WS_WSS2:
1861                                         case FIN_WSS:
1862                                                 state=OTHER_PROTO;
1863                                                 break;
1864                                         default:
1865                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1866                                                                 " state %d\n", *tmp, state);
1867                                                 goto error;
1868                                 }
1869                                 break;
1870                         case 'L':
1871                         case 'l':
1872                                 switch(state){
1873                                         case TCP_TLS1:
1874                                                 state=TLS2;
1875                                                 break;
1876                                         case OTHER_PROTO:
1877                                                 break;
1878                                         case UDP1:
1879                                         case UDP2:
1880                                         case FIN_UDP:
1881                                         case TCP2:
1882                                         case FIN_TCP:
1883                                         case TLS2:
1884                                         case FIN_TLS:
1885                                         case SCTP1:
1886                                         case SCTP2:
1887                                         case SCTP3:
1888                                         case FIN_SCTP:
1889                                         case WS_WSS1:
1890                                         case WS_WSS2:
1891                                         case FIN_WSS:
1892                                                 state=OTHER_PROTO;
1893                                                 break;
1894                                         default:
1895                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1896                                                                 " state %d\n", *tmp, state);
1897                                                 goto error;
1898                                 }
1899                                 break;
1900                         case 'W':
1901                         case 'w':
1902                                 switch(state){
1903                                         case F_PROTO:
1904                                                 state=WS_WSS1;
1905                                                 vb->transport.s=tmp;
1906                                                 break;
1907                                         case OTHER_PROTO:
1908                                                 break;
1909                                         case UDP1:
1910                                         case UDP2:
1911                                         case FIN_UDP:
1912                                         case TCP_TLS1:
1913                                         case TCP2:
1914                                         case FIN_TCP:
1915                                         case TLS2:
1916                                         case FIN_TLS:
1917                                         case SCTP1:
1918                                         case SCTP2:
1919                                         case SCTP3:
1920                                         case FIN_SCTP:
1921                                         case WS_WSS1:
1922                                         case WS_WSS2:
1923                                         case FIN_WSS:
1924                                                 state=OTHER_PROTO;
1925                                                 break;
1926                                         default:
1927                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1928                                                                 " state %d\n", *tmp, state);
1929                                                 goto error;
1930                                 }
1931                                 break;
1932                         /*match 2.0*/
1933                         case '2':
1934                                 switch(state){
1935                                         case F_VER:
1936                                                 state=VER1;
1937                                                 vb->version.s=tmp;
1938                                                 break;
1939                                         case OTHER_PROTO:
1940                                                 break;
1941                                         case UDP1:
1942                                         case UDP2:
1943                                         case FIN_UDP:
1944                                         case TCP_TLS1:
1945                                         case TCP2:
1946                                         case FIN_TCP:
1947                                         case TLS2:
1948                                         case FIN_TLS:
1949                                         case SCTP1:
1950                                         case SCTP2:
1951                                         case SCTP3:
1952                                         case FIN_SCTP:
1953                                         case WS_WSS1:
1954                                         case WS_WSS2:
1955                                         case FIN_WSS:
1956                                                 state=OTHER_PROTO;
1957                                                 break;
1958                                         default:
1959                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1960                                                                 " state %d\n", *tmp, state);
1961                                                 goto error;
1962                                 }
1963                                 break;
1964                         case '.':
1965                                 switch(state){
1966                                         case VER1:
1967                                                 state=VER2;
1968                                                 break;
1969                                         case OTHER_PROTO:
1970                                                 break;
1971                                         case UDP1:
1972                                         case UDP2:
1973                                         case FIN_UDP:
1974                                         case TCP_TLS1:
1975                                         case TCP2:
1976                                         case FIN_TCP:
1977                                         case TLS2:
1978                                         case FIN_TLS:
1979                                         case SCTP1:
1980                                         case SCTP2:
1981                                         case SCTP3:
1982                                         case FIN_SCTP:
1983                                         case WS_WSS1:
1984                                         case WS_WSS2:
1985                                         case FIN_WSS:
1986                                                 state=OTHER_PROTO;
1987                                                 break;
1988                                         default:
1989                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1990                                                                 " state %d\n", *tmp, state);
1991                                                 goto error;
1992                                 }
1993                                  break;
1994                         case '0':
1995                                 switch(state){
1996                                         case VER2:
1997                                                 state=FIN_VER;
1998                                                 break;
1999                                         case OTHER_PROTO:
2000                                                 break;
2001                                         case UDP1:
2002                                         case UDP2:
2003                                         case FIN_UDP:
2004                                         case TCP_TLS1:
2005                                         case TCP2:
2006                                         case FIN_TCP:
2007                                         case TLS2:
2008                                         case FIN_TLS:
2009                                         case SCTP1:
2010                                         case SCTP2:
2011                                         case SCTP3:
2012                                         case FIN_SCTP:
2013                                         case WS_WSS1:
2014                                         case WS_WSS2:
2015                                         case FIN_WSS:
2016                                                 state=OTHER_PROTO;
2017                                                 break;
2018                                         default:
2019                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
2020                                                                 " state %d\n", *tmp, state);
2021                                                 goto error;
2022                                 }
2023                                 break;
2024                         default:
2025                                 switch(state){
2026                                         case F_PROTO:
2027                                                 state=OTHER_PROTO;
2028                                                 vb->transport.s=tmp;
2029                                                 break;
2030                                         case OTHER_PROTO:
2031                                                 break;
2032                                         case UDP1:
2033                                         case UDP2:
2034                                         case FIN_UDP:
2035                                         case TCP_TLS1:
2036                                         case TCP2:
2037                                         case FIN_TCP:
2038                                         case TLS2:
2039                                         case FIN_TLS:
2040                                         case SCTP1:
2041                                         case SCTP2:
2042                                         case SCTP3:
2043                                         case FIN_SCTP:
2044                                         case WS_WSS1:
2045                                         case WS_WSS2:
2046                                         case FIN_WSS:
2047                                                 state=OTHER_PROTO;
2048                                                 break;
2049                                         default:
2050                                                 LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
2051                                                 " state %d\n", *tmp, state);
2052                                                 goto error;
2053                                 }
2054                                 break;
2055                 }
2056         } /* for tmp*/
2057
2058         /* we should not be here! if everything is ok > main_via*/
2059         LOG(L_ERR, "ERROR: parse_via: bad via: end of packet on state=%d\n",
2060                         state);
2061         goto error;
2062
2063  main_via:
2064         /* inc tmp to point to the next char*/
2065         tmp++;
2066         c_nest=0;
2067         /*state should always be F_HOST here*/;
2068         for(;*tmp;tmp++){
2069                 switch(*tmp){
2070                 case ' ':
2071                 case '\t':
2072                         switch(state){
2073                                         case F_HOST:/*eat the spaces*/
2074                                                 break;
2075                                         case P_HOST:
2076                                                  /*mark end of host*/
2077                                                  vb->host.len=tmp-vb->host.s;
2078                                                  state=L_PORT;
2079                                                  break;
2080                                         case L_PORT: /*eat the spaces*/
2081                                         case F_PORT:
2082                                                 break;
2083                                         case P_PORT:
2084                                                 /*end of port */
2085                                                 vb->port_str.len=tmp-vb->port_str.s;
2086                                                 state=L_PARAM;
2087                                                 break;
2088                                         case L_PARAM: /* eat the space */
2089                                         case F_PARAM:
2090                                                 break;
2091                                         case P_PARAM:
2092                                         /*      *tmp=0;*/ /*!?end of param*/
2093                                                 state=L_PARAM;
2094                                                 break;
2095                                         case L_VIA:
2096                                         case F_VIA: /* eat the space */
2097                                                 break;
2098                                         case F_COMMENT:
2099                                         case P_COMMENT:
2100                                                 break;
2101                                         case F_IP6HOST: /*no spaces allowed*/
2102                                         case P_IP6HOST:
2103                                                 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
2104                                                 goto error;
2105                                         case F_CRLF:
2106                                         case F_LF:
2107                                         case F_CR:
2108                                                 /*previous=crlf and now =' '*/
2109                                                 state=saved_state;
2110                                                 break;
2111                                         default:
2112                                                 LOG(L_CRIT,"BUG: parse_via"
2113                                                         " on <%c>, state=%d\n",*tmp, state);
2114                                                 goto  error;
2115                                 }
2116                         break;
2117                         case '\n':
2118                                 switch(state){
2119                                         case F_HOST:/*eat the spaces*/
2120                                         case L_PORT: /*eat the spaces*/
2121                                         case F_PORT:
2122                                         case L_PARAM: /* eat the space */
2123                                         case F_PARAM:
2124                                         case F_VIA: /* eat the space */
2125                                         case L_VIA:
2126                                         case F_COMMENT:
2127                                         case P_COMMENT:
2128                                         case F_IP6HOST:
2129                                         case P_IP6HOST:
2130                                                 saved_state=state;
2131                                                 state=F_LF;
2132                                                 break;
2133                                         case P_HOST:
2134                                                  /*mark end of host*/
2135                                                  vb->host.len=tmp-vb->host.s;
2136                                                  saved_state=L_PORT;
2137                                                  state=F_LF;
2138                                                  break;
2139                                         case P_PORT:
2140                                                 /*end of port */
2141                                                 vb->port_str.len=tmp-vb->port_str.s;
2142                                                 saved_state=L_PARAM;
2143                                                 state=F_LF;
2144                                                 break;
2145                                         case P_PARAM:
2146                                         /*      *tmp=0;*/ /*!?end of param*/
2147                                                 saved_state=L_PARAM;
2148                                                 state=F_LF;
2149                                                 break;
2150                                         case F_CR:
2151                                                 state=F_CRLF;
2152                                                 break;
2153                                         case F_CRLF:
2154                                         case F_LF:
2155                                                 state=saved_state;
2156                                                 goto endofheader;
2157                                         default:
2158                                                 LOG(L_CRIT,"BUG: parse_via"
2159                                                         " on <%c>\n",*tmp);
2160                                                 goto  error;
2161                                 }
2162                         break;
2163                 case '\r':
2164                                 switch(state){
2165                                         case F_HOST:/*eat the spaces*/
2166                                         case L_PORT: /*eat the spaces*/
2167                                         case F_PORT:
2168                                         case L_PARAM: /* eat the space */
2169                                         case F_PARAM:
2170                                         case F_VIA: /* eat the space */
2171                                         case L_VIA:
2172                                         case F_COMMENT:
2173                                         case P_COMMENT:
2174                                         case F_IP6HOST:
2175                                         case P_IP6HOST:
2176                                                 saved_state=state;
2177                                                 state=F_CR;
2178                                                 break;
2179                                         case P_HOST:
2180                                                  /*mark end of host*/
2181                                                  vb->host.len=tmp-vb->host.s;
2182                                                  saved_state=L_PORT;
2183                                                  state=F_CR;
2184                                                  break;
2185                                         case P_PORT:
2186                                                 /*end of port */
2187                                                 vb->port_str.len=tmp-vb->port_str.s;
2188                                                 saved_state=L_PARAM;
2189                                                 state=F_CR;
2190                                                 break;
2191                                         case P_PARAM:
2192                                         /*      *tmp=0;*/ /*!?end of param*/
2193                                                 saved_state=L_PARAM;
2194                                                 state=F_CR;
2195                                                 break;
2196                                         case F_CRLF:
2197                                         case F_CR:
2198                                         case F_LF:
2199                                                 state=saved_state;
2200                                                 goto endofheader;
2201                                         default:
2202                                                 LOG(L_CRIT,"BUG: parse_via"
2203                                                         " on <%c>\n",*tmp);
2204                                                 goto  error;
2205                                 }
2206                         break;
2207                         
2208                         case ':':
2209                                 switch(state){
2210                                         case F_HOST:
2211                                         case F_IP6HOST:
2212                                                 state=P_IP6HOST;
2213                                                 break;
2214                                         case P_IP6HOST:
2215                                                 break;
2216                                         case P_HOST:
2217                                                 /*mark  end of host*/
2218                                                 vb->host.len=tmp-vb->host.s;
2219                                                 state=F_PORT;
2220                                                 break;
2221                                         case L_PORT:
2222                                                 state=F_PORT;
2223                                                 break;
2224                                         case P_PORT:
2225                                                 LOG(L_ERR, "ERROR:parse_via:"
2226                                                         " bad port\n");
2227                                                 goto error;
2228                                         case L_PARAM:
2229                                         case F_PARAM:
2230                                         case F_PORT:
2231                                         case P_PARAM:
2232                                                 LOG(L_ERR, "ERROR:parse_via:"
2233                                                 " bad char <%c> in state %d\n",
2234                                                         *tmp,state);
2235                                                 goto error;
2236                                         case L_VIA:
2237                                         case F_VIA:
2238                                                 LOG(L_ERR, "ERROR:parse_via:"
2239                                                 " bad char in compact via\n");
2240                                                 goto error;
2241                                         case F_CRLF:
2242                                         case F_LF:
2243                                         case F_CR:
2244                                                 /*previous=crlf and now !=' '*/
2245                                                 goto endofheader;
2246                                         case F_COMMENT:/*everything is allowed in a comment*/
2247                                                 vb->comment.s=tmp;
2248                                                 state=P_COMMENT;
2249                                                 break;
2250                                         case P_COMMENT: /*everything is allowed in a comment*/
2251                                                 break;
2252                                         default:
2253                                                 LOG(L_CRIT,"BUG: parse_via"
2254                                                         " on <%c> state %d\n",
2255                                                         *tmp, state);
2256                                                 goto error;
2257                                 }
2258                                 break;
2259                         case ';':
2260                                 switch(state){
2261                                         case F_HOST:
2262                                         case F_IP6HOST:
2263                                                 LOG(L_ERR,"ERROR:parse_via:"
2264                                                         " no host found\n");
2265                                                 goto error;
2266                                         case P_IP6HOST:
2267                                                 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
2268                                                 goto error;
2269                                         case P_HOST:
2270                                                 vb->host.len=tmp-vb->host.s;
2271                                                 state=F_PARAM;
2272                                                 param_start=tmp+1;
2273                                                 break;
2274                                         case P_PORT:
2275                                                 /*mark the end*/
2276                                                 vb->port_str.len=tmp-vb->port_str.s;
2277                                         case L_PORT:
2278                                         case L_PARAM:
2279                                                 state=F_PARAM;
2280                                                 param_start=tmp+1;
2281                                                 break;
2282                                         case F_PORT:
2283                                                 LOG(L_ERR, "ERROR:parse_via:"
2284                                                 " bad char <%c> in state %d\n",
2285                                                         *tmp,state);
2286                                                 goto error;
2287                                         case F_PARAM:
2288                                                 LOG(L_ERR,  "ERROR:parse_via:"
2289                                                         " null param?\n");
2290                                                 goto error;
2291                                         case P_PARAM:
2292                                                 /*hmm next, param?*/
2293                                                 state=F_PARAM;
2294                                                 param_start=tmp+1;
2295                                                 break;
2296                                         case L_VIA:
2297                                         case F_VIA:
2298                                                 LOG(L_ERR, "ERROR:parse_via:"
2299                                                 " bad char <%c> in next via\n",
2300                                                         *tmp);
2301                                                 goto error;
2302                                         case F_CRLF:
2303                                         case F_LF:
2304                                         case F_CR:
2305                                                 /*previous=crlf and now !=' '*/
2306                                                 goto endofheader;
2307                                         case F_COMMENT:/*everything is allowed in a comment*/
2308                                                 vb->comment.s=tmp;
2309                                                 state=P_COMMENT;
2310                                                 break;
2311                                         case P_COMMENT: /*everything is allowed in a comment*/
2312                                                 break;
2313                                         
2314                                         default:
2315                                                 LOG(L_CRIT,"BUG: parse_via"
2316                                                         " on <%c> state %d\n",
2317                                                         *tmp, state);
2318                                                 goto  error;
2319                                 }
2320                         break;
2321                         case ',':
2322                                 switch(state){
2323                                         case F_HOST:
2324                                         case F_IP6HOST:
2325                                                 LOG(L_ERR,"ERROR:parse_via:"
2326                                                         " no host found\n");
2327                                                 goto error;
2328                                         case P_IP6HOST:
2329                                                 LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
2330                                                 goto error;
2331                                         case P_HOST:
2332                                                 /*mark the end*/
2333                                                 vb->host.len=tmp-vb->host.s;
2334                                                 state=F_VIA;
2335                                                 break;
2336                                         case P_PORT:
2337                                                 /*mark the end*/
2338                                                 vb->port_str.len=tmp-vb->port_str.s;
2339                                                 state=F_VIA;
2340                                                 break;
2341                                         case L_PORT:
2342                                         case L_PARAM:
2343                                         case P_PARAM:
2344                                         case L_VIA:
2345                                                 state=F_VIA;
2346                                                 break;
2347                                         case F_PORT:
2348                                         case F_PARAM:
2349                                                 LOG(L_ERR, "ERROR:parse_via:"
2350                                                 " invalid char <%c> in state"
2351                                                 " %d\n", *tmp,state);
2352                                                 goto error;
2353                                         case F_VIA:
2354                                                 /* do  nothing,  eat ","*/
2355                                                 break;  
2356                                         case F_CRLF:
2357                                         case F_LF:
2358                                         case F_CR:
2359                                                 /*previous=crlf and now !=' '*/
2360                                                 goto endofheader;
2361                                         case F_COMMENT:/*everything is allowed in a comment*/
2362                                                 vb->comment.s=tmp;
2363                                                 state=P_COMMENT;
2364                                                 break;
2365                                         case P_COMMENT: /*everything is allowed in a comment*/
2366                                                 break;
2367                                         default:
2368                                                 LOG(L_CRIT,"BUG: parse_via"
2369                                                         " on <%c> state %d\n",
2370                                                         *tmp, state);
2371                                                 goto  error;
2372                                 }
2373                         break;
2374                         case '(':
2375                                 switch(state){
2376                                         case F_HOST:
2377                                         case F_PORT:
2378                                         case F_PARAM:
2379                                         case F_VIA:
2380                                         case F_IP6HOST:
2381                                         case P_IP6HOST: /*must be terminated in ']'*/
2382                                                 LOG(L_ERR,"ERROR:parse_via"
2383                                                         " on <%c> state %d\n",
2384                                                         *tmp, state);
2385                                                 goto  error;
2386                                         case P_HOST:
2387                                                 /*mark the end*/
2388                                                 vb->host.len=tmp-vb->host.s;
2389                                                 state=F_COMMENT;
2390                                                 c_nest++;
2391                                                 break;
2392                                         case P_PORT:
2393                                                 /*mark the end*/
2394                                                 vb->port_str.len=tmp-vb->port_str.s;
2395                                                 state=F_COMMENT;
2396                                                 c_nest++;
2397                                                 break;
2398                                         case P_PARAM:
2399                                                 /*mark the end*/
2400                                                 vb->params.len=tmp-vb->params.s;
2401                                                 state=F_COMMENT;
2402                                                 c_nest++;
2403                                                 break;
2404                                         case L_PORT:
2405                                         case L_PARAM:
2406                                         case L_VIA:
2407                                                 state=F_COMMENT;
2408                                                 vb->params.len=tmp-vb->params.s;
2409                                                 c_nest++;
2410                                                 break;
2411                                         case P_COMMENT:
2412                                         case F_COMMENT:
2413                                                 c_nest++;
2414                                                 break;
2415                                         case F_CRLF:
2416                                         case F_LF:
2417                                         case F_CR:
2418                                                 /*previous=crlf and now !=' '*/
2419                                                 goto endofheader;
2420                                         default:
2421                                                 LOG(L_CRIT,"BUG: parse_via"
2422                                                         " on <%c> state %d\n",
2423                                                         *tmp, state);
2424                                                 goto  error;
2425                                 }
2426                         break;
2427                         case ')':
2428                                 switch(state){
2429                                         case F_COMMENT:
2430                                         case P_COMMENT:
2431                                                 if (c_nest){