Coverage Report

Created: 2026-10-17 06:23

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