Coverage Report

Created: 2026-08-31 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/parser/parse_uri.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2003 FhG Fokus
3
 *
4
 * This file is part of opensips, a free SIP server.
5
 *
6
 * opensips is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version
10
 *
11
 * opensips is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19
 *
20
 * History:
21
 * --------
22
 * 2003-04-04  convenience inbound-uri parser parse_orig_ruri
23
 *             introduced (jiri)
24
 * 2003-04-11  new parse_uri introduced (better, parses also some parameters,
25
 *              works in one pass) (andrei)
26
 * 2003-04-11  ser_error is now set in parse_uri (andrei)
27
 * 2003-04-26  ZSW (jiri)
28
 * 2003-07-03  sips:, r2, lr=on support added (andrei)
29
 * 2005-02-25  preliminary tel uri support (andrei)
30
 * 2005-03-03  more tel uri fixes (andrei)
31
 * 2006-11-28  Added statistic support for the number of bad URI's
32
 *             (Jeffrey Magder - SOMA Networks)
33
 *  2011-04-20  added support for URI unknown parameters (osas)
34
 */
35
36
37
#include "parse_uri.h"
38
#include <string.h>
39
#include "../dprint.h"
40
#include "../ut.h"   /* q_memchr */
41
#include "../error.h"
42
#include "../errinfo.h"
43
#include "../core_stats.h"
44
#include "../strcommon.h"
45
46
static const str uri_type_names[7] = {
47
  {NULL, 0}, /*This is the error type*/
48
  str_init("sip"),
49
  str_init("sips"),
50
  str_init("tel"),
51
  str_init("tels"),
52
  str_init("urn:service"),
53
  str_init("urn:nena:service")
54
};
55
56
char* uri_type2str(const uri_type type, char *result)
57
0
{
58
0
  if (type == ERROR_URI_T)
59
0
    return NULL;
60
61
0
  memcpy(result, uri_type_names[type].s, uri_type_names[type].len);
62
0
  return result + uri_type_names[type].len;
63
0
}
64
65
int uri_typestrlen(const uri_type type)
66
0
{
67
0
  return uri_type_names[type].len;
68
0
}
69
70
uri_type str2uri_type(char * buf)
71
0
{
72
0
  int scheme = 0;
73
0
  uri_type type = ERROR_URI_T;
74
0
  scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
75
0
  scheme|=0x20202020;
76
0
  if (scheme==SIP_SCH){
77
0
    type=SIP_URI_T;
78
0
  }else if(scheme==SIPS_SCH){
79
0
    if(buf[4]==':')
80
0
      type=SIPS_URI_T;
81
0
    else type = ERROR_URI_T;
82
0
  }else if (scheme==TEL_SCH){
83
0
    type=TEL_URI_T;
84
0
  }else if (scheme==URN_SERVICE_SCH){
85
0
    if (memcmp(buf+3,URN_SERVICE_STR,URN_SERVICE_STR_LEN) == 0) {
86
0
      type=URN_SERVICE_URI_T;
87
0
    }
88
0
    else if (memcmp(buf+3,URN_NENA_SERVICE_STR,URN_NENA_SERVICE_STR_LEN) == 0) {
89
0
      type=URN_NENA_SERVICE_URI_T;
90
0
    }
91
0
  }
92
0
  return type;
93
0
}
94
95
int parse_uri_headers(str headers, str h_name[], str h_val[], int h_size)
96
0
{
97
0
  enum states {URI_H_HEADER, URI_H_VALUE};
98
0
  register enum states state;
99
0
  char* h; /* header start */
100
0
  char* v; /* header value start */
101
0
  str* header;    /* current header */
102
0
  str* header_val;  /* current header val */
103
0
  register char* p;
104
0
  char* end;
105
0
  unsigned int i = 0;
106
107
  /* init */
108
0
  end = headers.s + headers.len;
109
0
  p = h = headers.s;
110
0
  v = NULL;
111
0
  header = &h_name[0];
112
0
  header_val = &h_val[0];
113
0
  state = URI_H_HEADER;
114
0
  memset(h_name, 0, h_size * sizeof(str));
115
0
  memset(h_val, 0, h_size * sizeof(str));
116
117
0
  for(;p<end; p++){
118
0
    switch((unsigned char)state){
119
0
    case URI_H_HEADER:
120
0
      switch(*p){
121
0
      case '=':
122
0
        v = p+1;
123
0
        header->s = h;
124
0
        header->len = p-h;
125
0
        state = URI_H_VALUE;
126
0
        break;
127
0
      case '?':
128
0
        LM_ERR("Header without value\n");
129
0
        h = p+1;
130
0
        header->s = h;
131
0
        header->len = p-h;
132
0
        header_val->s = NULL;
133
0
        header_val->len = 0;
134
135
        /* advance header and header_val */
136
0
        i++;
137
0
        if(i<h_size){
138
0
          header = &h_name[i];
139
0
          header_val = &h_val[i];
140
0
        } else {
141
0
          LM_ERR("To many URI headers\n");
142
0
          return -1;
143
0
        }
144
0
        break;
145
0
      }
146
0
      break;
147
0
    case URI_H_VALUE:
148
0
      switch(*p){
149
0
      case '=':
150
0
        LM_ERR("Ignoring unexpected '=' inside URI header value\n");
151
0
        break;
152
0
      case '?':
153
0
        h = p+1;
154
0
        header_val->s = v;
155
0
        header_val->len = p-v;
156
0
        state = URI_H_HEADER;
157
158
        /* advance header and header_val */
159
0
        i++;
160
0
        if(i<h_size){
161
0
          header = &h_name[i];
162
0
          header_val = &h_val[i];
163
0
        } else {
164
0
          LM_ERR("To many URI headers\n");
165
0
          return -1;
166
0
        }
167
0
        break;
168
0
      }
169
0
      break;
170
0
    default:
171
0
      LM_ERR("Unexpected state [%d]\n", state);
172
0
      return -1;
173
0
    }
174
0
  }
175
176
0
  switch(state){
177
0
  case URI_H_HEADER:
178
0
    LM_ERR("Header without value\n");
179
0
    header->s = h;
180
0
    header->len = p-h;
181
0
    header_val->s = NULL;
182
0
    header_val->len = 0;
183
0
    break;
184
0
  case URI_H_VALUE:
185
0
    header_val->s = v;
186
0
    header_val->len = p-v;
187
0
    break;
188
0
  }
189
190
#ifdef EXTRA_DEBUG
191
  for(i=0; i<h_size && h_name[i].s; i++)
192
    LM_DBG("header=[%p]-><%.*s> val=[%p]-><%.*s>\n",
193
      h_name[i].s, h_name[i].len, h_name[i].s,
194
      h_val[i].s, h_val[i].len, h_val[i].s);
195
#endif
196
197
0
  return 0;
198
0
}
199
200
int print_uri(struct sip_uri *uri, str *out_buf)
201
0
{
202
0
#define append_str_chunk(field) \
203
0
  do { \
204
0
    if (bytes + uri->field.len > out_buf->len) { \
205
0
      LM_ERR("no more space left! printed so far: '%.*s'\n", \
206
0
               bytes, out_buf->s); \
207
0
      return -1; \
208
0
    } \
209
0
    memcpy(out_buf->s + bytes, uri->field.s, uri->field.len); \
210
0
    bytes += uri->field.len; \
211
0
  } while (0)
212
213
0
#define append_char(ch) \
214
0
  do { \
215
0
    if (bytes + 1 > out_buf->len) { \
216
0
      LM_ERR("no more space left! printed so far: '%.*s'\n", \
217
0
               bytes, out_buf->s); \
218
0
      return -1; \
219
0
    } \
220
0
    out_buf->s[bytes++] = ch; \
221
0
  } while (0)
222
223
0
#define VAL(p) p##_val
224
225
0
#define append_param(p) \
226
0
  do { \
227
0
    if (uri->p.s) { \
228
0
      append_char(';'); \
229
0
      append_str_chunk(p); \
230
0
    } \
231
0
  } while (0)
232
233
0
#define append_uk_param(idx) \
234
0
  do { \
235
0
    if (uri->u_name[idx].s) { \
236
0
      append_char(';'); \
237
0
      if (bytes + uri->u_name[idx].len > out_buf->len) { \
238
0
        LM_ERR("no more space left! printed so far: '%.*s'\n", \
239
0
                 bytes, out_buf->s); \
240
0
        return -1; \
241
0
      } \
242
0
      memcpy(out_buf->s + bytes, uri->u_name[idx].s, uri->u_name[idx].len); \
243
0
      bytes += uri->u_name[idx].len; \
244
0
      if (uri->u_val[idx].s) { \
245
0
        append_char('='); \
246
0
        if (bytes + uri->u_val[idx].len > out_buf->len) { \
247
0
          LM_ERR("no more space left! printed so far: '%.*s'\n", \
248
0
                   bytes, out_buf->s); \
249
0
          return -1; \
250
0
        } \
251
0
        memcpy(out_buf->s + bytes, uri->u_val[idx].s, uri->u_val[idx].len); \
252
0
        bytes += uri->u_val[idx].len; \
253
0
      } \
254
0
    } \
255
0
  } while (0)
256
257
0
  int bytes = 0;
258
0
  int i;
259
260
0
  memcpy(out_buf->s, uri_type_names[uri->type].s, uri_type_names[uri->type].len);
261
0
  bytes += uri_type_names[uri->type].len;
262
0
  append_char(':');
263
0
  append_str_chunk(user);
264
0
  if (uri->passwd.s) {
265
0
    append_char(':');
266
0
    append_str_chunk(passwd);
267
0
  }
268
0
  if (uri->host.s) {
269
0
    append_char('@');
270
0
    append_str_chunk(host);
271
0
  }
272
0
  if (uri->port.s) {
273
0
    append_char(':');
274
0
    append_str_chunk(port);
275
0
  }
276
277
0
  append_param(transport);
278
0
  append_param(ttl);
279
0
  append_param(user_param);
280
0
  append_param(maddr);
281
0
  append_param(method);
282
0
  append_param(lr);
283
0
  append_param(r2);
284
0
  append_param(gr);
285
0
  append_param(pn_provider);
286
0
  append_param(pn_prid);
287
0
  append_param(pn_param);
288
0
  append_param(pn_purr);
289
290
0
  for (i = 0; i < uri->u_params_no; i++)
291
0
    append_uk_param(i);
292
293
0
  out_buf->len = bytes;
294
295
0
  return 0;
296
0
#undef append_str_chunk
297
0
#undef append_char
298
0
#undef VAL
299
0
#undef append_param
300
0
#undef append_uk_param
301
0
}
302
303
/* buf= pointer to beginning of uri (sip:x@foo.bar:5060;a=b?h=i)
304
 * len= len of uri
305
 * returns: fills uri & returns <0 on error or 0 if ok
306
 */
307
int parse_uri(char* buf, int len, struct sip_uri* uri)
308
142k
{
309
142k
  enum states  {  URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
310
142k
          URI_HOST, URI_HOST_P,
311
142k
          URI_HOST6_P, URI_HOST6_END, URI_PORT,
312
142k
          URI_PARAM, URI_PARAM_P, URI_PARAM_VAL_P,
313
142k
          URI_VAL_P, URI_HEADERS,
314
          /* param states */
315
          /* transport */
316
142k
          PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
317
142k
          PT_eq,
318
          /* ttl */
319
142k
          PTTL_T2, PTTL_L, PTTL_eq,
320
          /* user */
321
142k
          PU_U, PU_S, PU_E, PU_R, PU_eq,
322
          /* method */
323
142k
          PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
324
          /* maddr */
325
142k
          PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
326
          /* lr */
327
142k
          PLR_L, PLR_R_FIN, PLR_eq,
328
          /* gr */
329
142k
          PG_G, PG_G_FIN, PG_eq,
330
          /* r2 */
331
142k
          PR2_R, PR2_2_FIN, PR2_eq,
332
          /* transport values */
333
          /* udp */
334
142k
          VU_U, VU_D, VU_P_FIN,
335
          /* tcp */
336
142k
          VT_T, VT_C, VT_P_FIN,
337
          /* tls */
338
142k
          VTLS_L, VTLS_S_FIN,
339
          /* sctp */
340
142k
          VS_S, VS_C, VS_T, VS_P_FIN,
341
          /* ws */
342
142k
          VW_W, VW_S, VW_S_FIN, VWS_S_FIN,
343
344
          /* pn-{provider, prid, param, purr} (RFC 8599 - SIP PN) */
345
142k
          PN_P, PN_N, PN_dash, PN_P2, PN_PR,
346
142k
          PN1_O, PN1_V, PN1_I, PN1_D, PN1_E, PN1_FIN, PN1_eq,
347
142k
          PN2_I, PN2_D, PN2_eq,
348
142k
          PN3_A, PN3_R, PN3_A2, PN3_M, PN3_eq,
349
142k
          PN4_U, PN4_R, PN4_R2, PN4_eq,
350
351
142k
  };
352
142k
  register enum states state;
353
142k
  char* s;
354
142k
  char* b; /* param start */
355
142k
  char *v; /* value start */
356
142k
  str* param; /* current param */
357
142k
  str* param_val; /* current param val */
358
142k
  str user;
359
142k
  str password;
360
142k
  unsigned int port_no;
361
142k
  register char* p;
362
142k
  char* end;
363
142k
  char* pass;
364
142k
  int found_user;
365
142k
  int error_headers;
366
142k
  unsigned int scheme;
367
142k
  uri_type backup;
368
#ifdef EXTRA_DEBUG
369
  int i;
370
#endif
371
372
142k
#define case_port( ch, var, ovf_check1, ovf_check2) \
373
142k
  case ch: \
374
68.5k
      if (ovf_check1) \
375
68.5k
        (var)=(var)*10+(ch-'0'); \
376
68.5k
      if (ovf_check2 && (var) > USHRT_MAX) \
377
68.5k
        goto error_bad_port; \
378
68.5k
      break
379
380
142k
#define still_at_user  \
381
142k
            if (found_user==0){ \
382
24.9k
              user.s=uri->host.s; \
383
24.9k
              if (pass){\
384
10.0k
                user.len=pass-user.s; \
385
10.0k
                password.s=pass+1; \
386
10.0k
                password.len=p-password.s; \
387
14.8k
              }else{ \
388
14.8k
                user.len=p-user.s; \
389
14.8k
              }\
390
              /* save the uri type/scheme */ \
391
24.9k
              backup=uri->type; \
392
              /* everything else is 0 */ \
393
24.9k
              memset(uri, 0, sizeof(struct sip_uri)); \
394
              /* restore the scheme, copy user & pass */ \
395
24.9k
              uri->type=backup; \
396
24.9k
              uri->user=user; \
397
24.9k
              if (pass) uri->passwd=password;  \
398
24.9k
              s=p+1; \
399
24.9k
              found_user=1;\
400
24.9k
              error_headers=0; \
401
24.9k
              state=URI_HOST; \
402
24.9k
            }else goto error_bad_char
403
404
142k
#define check_host_end \
405
142k
          case ':': \
406
            /* found the host */ \
407
3.53k
            uri->host.s=s; \
408
3.53k
            uri->host.len=p-s; \
409
3.53k
            state=URI_PORT; \
410
3.53k
            s=p+1; \
411
3.53k
            break; \
412
13.1k
          case ';': \
413
13.1k
            uri->host.s=s; \
414
13.1k
            uri->host.len=p-s; \
415
13.1k
            state=URI_PARAM; \
416
13.1k
            s=p+1; \
417
13.1k
            break; \
418
13.1k
          case '?': \
419
126
            uri->host.s=s; \
420
126
            uri->host.len=p-s; \
421
126
            state=URI_HEADERS; \
422
126
            s=p+1; \
423
126
            break; \
424
134
          case '&': \
425
357
          case '@': \
426
357
            goto error_bad_char
427
428
429
142k
#define param_set(t_start, v_start) \
430
142k
          param->s=(t_start);\
431
97.0k
          param->len=(p-(t_start));\
432
97.0k
          param_val->s=(v_start); \
433
97.0k
          param_val->len=(p-(v_start))
434
435
142k
#define u_param_set(t_start, v_start) \
436
463k
      if (uri->u_params_no < URI_MAX_U_PARAMS){ \
437
144k
        if((v_start)>(t_start)){ \
438
8.87k
          uri->u_name[uri->u_params_no].s=(t_start); \
439
8.87k
          uri->u_name[uri->u_params_no].len=((v_start)-(t_start)-1); \
440
8.87k
          if(p>(v_start)) { \
441
6.61k
            uri->u_val[uri->u_params_no].s=(v_start); \
442
6.61k
            uri->u_val[uri->u_params_no].len=(p-(v_start)); \
443
6.61k
          } \
444
135k
        } else { \
445
135k
          uri->u_name[uri->u_params_no].s=(t_start); \
446
135k
          uri->u_name[uri->u_params_no].len=(p-(t_start)); \
447
135k
        } \
448
144k
        uri->u_params_no++; \
449
319k
      } else { \
450
319k
        LM_ERR("unknown URI param list excedeed\n"); \
451
319k
      }
452
453
142k
#define semicolon_case \
454
634k
          case';': \
455
634k
            if (pass){ \
456
10.2k
              found_user=1;/* no user, pass cannot contain ';'*/ \
457
10.2k
              pass=0; \
458
10.2k
            } \
459
634k
            state=URI_PARAM   /* new param */
460
461
142k
#define question_case \
462
142k
          case '?': \
463
17.9k
            uri->params.s=s; \
464
17.9k
            uri->params.len=p-s; \
465
17.9k
            state=URI_HEADERS; \
466
17.9k
            s=p+1; \
467
17.9k
            if (pass){ \
468
3.93k
              found_user=1;/* no user, pass cannot contain '?'*/ \
469
3.93k
              pass=0; \
470
3.93k
            }
471
472
142k
#define colon_case \
473
219k
          case ':': \
474
219k
            if (found_user==0){ \
475
              /*might be pass but only if user not found yet*/ \
476
17.9k
              if (pass){ \
477
1.07k
                found_user=1; /* no user */ \
478
1.07k
                pass=0; \
479
16.8k
              }else{ \
480
16.8k
                pass=p; \
481
16.8k
              } \
482
17.9k
            } \
483
219k
            state=URI_PARAM_P /* generic param */
484
485
142k
#define param_common_cases \
486
142k
          case '@': \
487
            /* ughhh, this is still the user */ \
488
6.48k
            still_at_user; \
489
3.44k
            break; \
490
88.9k
          semicolon_case; \
491
88.9k
            break; \
492
88.9k
          question_case; \
493
3.44k
            break; \
494
51.2k
          colon_case; \
495
51.2k
            break
496
497
142k
#define u_param_common_cases \
498
142k
          case '@': \
499
            /* ughhh, this is still the user */ \
500
22.9k
            still_at_user; \
501
13.7k
            break; \
502
447k
          semicolon_case; \
503
447k
            u_param_set(b, v); \
504
447k
            break; \
505
447k
          question_case; \
506
11.6k
            u_param_set(b, v); \
507
11.6k
            break; \
508
134k
          colon_case; \
509
134k
            break
510
511
142k
#define value_common_cases \
512
142k
          case '@': \
513
            /* ughhh, this is still the user */ \
514
3.58k
            still_at_user; \
515
1.73k
            break; \
516
87.2k
          semicolon_case; \
517
87.2k
            param_set(b, v); \
518
87.2k
            break; \
519
87.2k
          question_case; \
520
1.65k
            param_set(b, v); \
521
1.65k
            break; \
522
21.1k
          colon_case; \
523
21.1k
            state=URI_VAL_P; \
524
21.1k
            break
525
526
142k
#define param_switch(old_state, c1, c2, new_state) \
527
1.64M
      case old_state: \
528
1.64M
        switch(*p){ \
529
824k
          case c1: \
530
1.41M
          case c2: \
531
1.41M
            state=(new_state); \
532
1.41M
            break; \
533
824k
          u_param_common_cases; \
534
110k
          default: \
535
110k
            state=URI_PARAM_P; \
536
1.64M
        } \
537
1.64M
        break
538
142k
#define param_switch1(old_state, c1, new_state) \
539
292k
      case old_state: \
540
292k
        switch(*p){ \
541
234k
          case c1: \
542
234k
            state=(new_state); \
543
234k
            break; \
544
904
          param_common_cases; \
545
24.2k
          default: \
546
24.2k
            state=URI_PARAM_P; \
547
292k
        } \
548
292k
        break
549
142k
#define param_xswitch1(old_state, c1, new_state) \
550
142k
      case old_state: \
551
12.0k
        switch(*p){ \
552
11.8k
          case c1: \
553
11.8k
            state=(new_state); \
554
11.8k
            break; \
555
187
          default: \
556
187
            goto error_bad_char; \
557
12.0k
        } \
558
12.0k
        break
559
142k
#define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
560
365k
      case old_state : \
561
365k
        switch(*p){ \
562
171k
          case c1: \
563
204k
          case c2: \
564
204k
            state=(new_state_c); \
565
204k
            break; \
566
171k
          case d1: \
567
98.2k
          case d2: \
568
98.2k
            state=(new_state_d); \
569
98.2k
            break; \
570
85.3k
          u_param_common_cases; \
571
38.8k
          default: \
572
38.8k
            state=URI_PARAM_P; \
573
365k
        } \
574
365k
        break
575
142k
#define param_switch_bigger(old_state, c1, c2, d1, d2, e1, e2, new_state_c, new_state_d, new_state_e) \
576
142k
      case old_state : \
577
101k
        switch(*p){ \
578
31.9k
          case c1: \
579
53.2k
          case c2: \
580
53.2k
            state=(new_state_c); \
581
53.2k
            break; \
582
31.9k
          case d1: \
583
19.8k
          case d2: \
584
19.8k
            state=(new_state_d); \
585
19.8k
            break; \
586
5.59k
          case e1: \
587
18.8k
          case e2: \
588
18.8k
            state=(new_state_e); \
589
18.8k
            break; \
590
5.59k
          u_param_common_cases; \
591
5.42k
          default: \
592
5.42k
            state=URI_PARAM_P; \
593
101k
        } \
594
101k
        break
595
142k
#define value_switch(old_state, c1, c2, new_state) \
596
142k
      case old_state: \
597
94.3k
        switch(*p){ \
598
27.0k
          case c1: \
599
47.7k
          case c2: \
600
47.7k
            state=(new_state); \
601
47.7k
            break; \
602
27.0k
          value_common_cases; \
603
9.95k
          default: \
604
9.95k
            state=URI_VAL_P; \
605
94.3k
        } \
606
94.3k
        break
607
142k
#define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
608
142k
      case old_state: \
609
34.9k
        switch(*p){ \
610
12.1k
          case c1: \
611
15.3k
          case c2: \
612
15.3k
            state=(new_state_c); \
613
15.3k
            break; \
614
12.1k
          case d1: \
615
16.8k
          case d2: \
616
16.8k
            state=(new_state_d); \
617
16.8k
            break; \
618
8.31k
          value_common_cases; \
619
1.39k
          default: \
620
1.39k
            state=URI_VAL_P; \
621
34.9k
        } \
622
34.9k
        break
623
624
142k
#define transport_fin(c_state, proto_no) \
625
142k
      case c_state: \
626
26.0k
        switch(*p){ \
627
505
          case '@': \
628
505
            still_at_user; \
629
505
            break; \
630
6.42k
          semicolon_case; \
631
6.42k
            param_set(b, v); \
632
6.42k
            uri->proto=(proto_no); \
633
6.42k
            break; \
634
668
          question_case; \
635
668
            param_set(b, v); \
636
668
            uri->proto=(proto_no); \
637
668
            break; \
638
9.66k
          colon_case;  \
639
18.4k
          default: \
640
18.4k
            state=URI_VAL_P; \
641
18.4k
            break; \
642
26.0k
        } \
643
26.0k
        break
644
645
646
647
  /* init */
648
142k
  end=buf+len;
649
142k
  p=buf+4;
650
142k
  found_user=0;
651
142k
  error_headers=0;
652
142k
  b=v=0;
653
142k
  param=param_val=0;
654
142k
  pass=0;
655
142k
  password.s = 0;
656
142k
  password.len = 0;
657
142k
  port_no=0;
658
142k
  state=URI_INIT;
659
142k
  memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
660
  /*look for sip:, sips: or tel:*/
661
142k
  if (len<5) goto error_too_short;
662
64.6k
  scheme=(unsigned)(unsigned char)buf[0]
663
64.6k
      + (((unsigned)(unsigned char)buf[1])<<8)
664
64.6k
      + (((unsigned)(unsigned char)buf[2])<<16)
665
64.6k
      + (((unsigned)(unsigned char)buf[3])<<24);
666
64.6k
  scheme|=0x20202020;
667
64.6k
  if (scheme==SIP_SCH){
668
53.5k
    uri->type=SIP_URI_T;
669
53.5k
  }else if(scheme==SIPS_SCH){
670
367
    if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
671
181
    else goto error_bad_uri;
672
10.7k
  }else if (scheme==TEL_SCH){
673
5.08k
    uri->type=TEL_URI_T;
674
5.64k
  }else if (scheme==URN_SERVICE_SCH){
675
2.06k
    if ((end-(buf+3)) >= URN_SERVICE_STR_LEN
676
1.96k
            && memcmp(buf+3,URN_SERVICE_STR,URN_SERVICE_STR_LEN) == 0) {
677
90
      p+= URN_SERVICE_STR_LEN-1;
678
90
      uri->type=URN_SERVICE_URI_T;
679
90
    }
680
1.97k
    else if ((end-(buf+3)) >= URN_NENA_SERVICE_STR_LEN
681
1.40k
            && memcmp(buf+3,URN_NENA_SERVICE_STR,URN_NENA_SERVICE_STR_LEN) == 0) {
682
123
      p+= URN_NENA_SERVICE_STR_LEN-1;
683
123
      uri->type=URN_NENA_SERVICE_URI_T;
684
1.84k
    }else goto error_bad_uri;
685
3.58k
  }else goto error_bad_uri;
686
687
59.0k
  s=p;
688
7.26M
  for(;p<end; p++){
689
7.23M
    switch((unsigned char)state){
690
58.9k
      case URI_INIT:
691
58.9k
        switch(*p){
692
2.04k
          case '[':
693
            /* uri =  [ipv6address]... */
694
2.04k
            state=URI_HOST6_P;
695
2.04k
            s=p;
696
2.04k
            break;
697
39
          case ']':
698
            /* invalid, no uri can start with ']' */
699
138
          case ':':
700
            /* the same as above for ':' */
701
138
            goto error_bad_char;
702
53
          case '@': /* error no user part */
703
53
            goto error_bad_char;
704
56.7k
          default:
705
56.7k
            state=URI_USER;
706
58.9k
        }
707
58.7k
        break;
708
132k
      case URI_USER:
709
132k
        switch(*p){
710
2.12k
          case '@':
711
            /* found the user*/
712
2.12k
            uri->user.s=s;
713
2.12k
            uri->user.len=p-s;
714
2.12k
            state=URI_HOST;
715
2.12k
            found_user=1;
716
2.12k
            s=p+1; /* skip '@' */
717
2.12k
            break;
718
12.5k
          case ':':
719
            /* found the user, or the host? */
720
12.5k
            uri->user.s=s;
721
12.5k
            uri->user.len=p-s;
722
12.5k
            state=URI_PASSWORD;
723
12.5k
            s=p+1; /* skip ':' */
724
12.5k
            break;
725
40.2k
          case ';':
726
            /* this could be still the user or
727
             * params?*/
728
40.2k
            uri->host.s=s;
729
40.2k
            uri->host.len=p-s;
730
40.2k
            state=URI_PARAM;
731
40.2k
            s=p+1;
732
40.2k
            break;
733
1.59k
          case '?': /* still user or headers? */
734
1.59k
            uri->host.s=s;
735
1.59k
            uri->host.len=p-s;
736
1.59k
            state=URI_HEADERS;
737
1.59k
            s=p+1;
738
1.59k
            break;
739
            /* almost anything permitted in the user part */
740
39
          case '[':
741
92
          case ']': /* the user part cannot contain "[]" */
742
92
            goto error_bad_char;
743
132k
        }
744
132k
        break;
745
132k
      case URI_PASSWORD: /* this can also be the port (missing user)*/
746
65.6k
        switch(*p){
747
442
          case '@':
748
            /* found the password*/
749
442
            uri->passwd.s=s;
750
442
            uri->passwd.len=p-s;
751
442
            port_no=0;
752
442
            state=URI_HOST;
753
442
            found_user=1;
754
442
            s=p+1; /* skip '@' */
755
442
            break;
756
5.51k
          case ';':
757
            /* upps this is the port */
758
5.51k
            uri->port.s=s;
759
5.51k
            uri->port.len=p-s;
760
5.51k
            uri->port_no=port_no;
761
            /* user contains in fact the host */
762
5.51k
            uri->host.s=uri->user.s;
763
5.51k
            uri->host.len=uri->user.len;
764
5.51k
            uri->user.s=0;
765
5.51k
            uri->user.len=0;
766
5.51k
            state=URI_PARAM;
767
5.51k
            found_user=1; /*  there is no user part */
768
5.51k
            s=p+1;
769
5.51k
            break;
770
103
          case '?':
771
            /* upps this is the port */
772
103
            uri->port.s=s;
773
103
            uri->port.len=p-s;
774
103
            uri->port_no=port_no;
775
            /* user contains in fact the host */
776
103
            uri->host.s=uri->user.s;
777
103
            uri->host.len=uri->user.len;
778
103
            uri->user.s=0;
779
103
            uri->user.len=0;
780
103
            state=URI_HEADERS;
781
103
            found_user=1; /*  there is no user part */
782
103
            s=p+1;
783
103
            break;
784
5.10k
          case_port('0', port_no, port_no < INT_MAX / 10, 0);
785
6.16k
          case_port('1', port_no, port_no < INT_MAX / 10, 0);
786
6.49k
          case_port('2', port_no, port_no < INT_MAX / 10, 0);
787
6.49k
          case_port('3', port_no, port_no < INT_MAX / 10, 0);
788
7.75k
          case_port('4', port_no, port_no < INT_MAX / 10, 0);
789
7.75k
          case_port('5', port_no, port_no < INT_MAX / 10, 0);
790
5.50k
          case_port('6', port_no, port_no < INT_MAX / 10, 0);
791
5.82k
          case_port('7', port_no, port_no < INT_MAX / 10, 0);
792
6.30k
          case_port('8', port_no, port_no < INT_MAX / 10, 0);
793
6.30k
          case_port('9', port_no, port_no < INT_MAX / 10, 0);
794
5.02k
          case '[':
795
107
          case ']':
796
238
          case ':':
797
238
            goto error_bad_char;
798
1.08k
          default:
799
            /* it can't be the port, non number found */
800
1.08k
            port_no=0;
801
1.08k
            state=URI_PASSWORD_ALPHA;
802
65.6k
        }
803
65.4k
        break;
804
65.4k
      case URI_PASSWORD_ALPHA:
805
2.69k
        switch(*p){
806
114
          case '@':
807
            /* found the password*/
808
114
            uri->passwd.s=s;
809
114
            uri->passwd.len=p-s;
810
114
            state=URI_HOST;
811
114
            found_user=1;
812
114
            s=p+1; /* skip '@' */
813
114
            break;
814
81
          case ';': /* contains non-numbers => cannot be port no*/
815
124
          case '?':
816
124
            goto error_bad_port;
817
39
          case '[':
818
78
          case ']':
819
163
          case ':':
820
163
            goto error_bad_char;
821
2.69k
        }
822
2.40k
        break;
823
17.5k
      case URI_HOST:
824
17.5k
        switch(*p){
825
141
          case '[':
826
141
            state=URI_HOST6_P;
827
141
            break;
828
371
          case ':':
829
698
          case ';':
830
1.05k
          case '?': /* null host name ->invalid */
831
1.13k
          case '&':
832
1.40k
          case '@': /*chars not allowed in hosts names */
833
1.40k
            goto error_bad_host;
834
15.9k
          default:
835
15.9k
            state=URI_HOST_P;
836
17.5k
        }
837
16.1k
        break;
838
204k
      case URI_HOST_P:
839
204k
        switch(*p){
840
204k
          check_host_end;
841
204k
        }
842
203k
        break;
843
203k
      case URI_HOST6_END:
844
1.83k
        switch(*p){
845
1.51k
          check_host_end;
846
57
          default: /*no chars allowed after [ipv6] */
847
57
            goto error_bad_host;
848
1.83k
        }
849
1.70k
        break;
850
2.86k
      case URI_HOST6_P:
851
2.86k
        switch(*p){
852
1.85k
          case ']':
853
1.85k
            state=URI_HOST6_END;
854
1.85k
            break;
855
39
          case '[':
856
78
          case '&':
857
117
          case '@':
858
156
          case ';':
859
195
          case '?':
860
195
            goto error_bad_host;
861
2.86k
        }
862
2.66k
        break;
863
12.3k
      case URI_PORT:
864
12.3k
        switch(*p){
865
910
          case ';':
866
910
            uri->port.s=s;
867
910
            uri->port.len=p-s;
868
910
            uri->port_no=port_no;
869
910
            state=URI_PARAM;
870
910
            s=p+1;
871
910
            break;
872
89
          case '?':
873
89
            uri->port.s=s;
874
89
            uri->port.len=p-s;
875
89
            uri->port_no=port_no;
876
89
            state=URI_HEADERS;
877
89
            s=p+1;
878
89
            break;
879
1.26k
          case_port('0', port_no, 1, 1);
880
1.12k
          case_port('1', port_no, 1, 1);
881
952
          case_port('2', port_no, 1, 1);
882
978
          case_port('3', port_no, 1, 1);
883
1.12k
          case_port('4', port_no, 1, 1);
884
1.34k
          case_port('5', port_no, 1, 1);
885
1.50k
          case_port('6', port_no, 1, 1);
886
1.42k
          case_port('7', port_no, 1, 1);
887
764
          case_port('8', port_no, 1, 1);
888
772
          case_port('9', port_no, 1, 1);
889
684
          case '&':
890
41
          case '@':
891
87
          case ':':
892
1.10k
          default:
893
1.10k
            goto error_bad_port;
894
12.3k
        }
895
10.2k
        break;
896
692k
      case URI_PARAM: /* beginning of a new param */
897
692k
        switch(*p){
898
4.50k
          param_common_cases;
899
          /* recognized params */
900
154k
          case 't':
901
182k
          case 'T':
902
182k
            b=p;
903
182k
            state=PT_T;
904
182k
            break;
905
5.95k
          case 'u':
906
24.2k
          case 'U':
907
24.2k
            b=p;
908
24.2k
            state=PU_U;
909
24.2k
            break;
910
29.0k
          case 'm':
911
129k
          case 'M':
912
129k
            b=p;
913
129k
            state=PM_M;
914
129k
            break;
915
14.9k
          case 'l':
916
18.8k
          case 'L':
917
18.8k
            b=p;
918
18.8k
            state=PLR_L;
919
18.8k
            break;
920
5.42k
          case 'g':
921
12.3k
          case 'G':
922
12.3k
            b=p;
923
12.3k
            state=PG_G;
924
12.3k
            break;
925
15.1k
          case 'r':
926
20.7k
          case 'R':
927
20.7k
            b=p;
928
20.7k
            state=PR2_R;
929
20.7k
            break;
930
120k
          case 'p':
931
138k
          case 'P':
932
138k
            b=p;
933
138k
            state=PN_P;
934
138k
            break;
935
103k
          default:
936
103k
            b=p;
937
103k
            state=URI_PARAM_P;
938
692k
        }
939
690k
        break;
940
2.39M
      case URI_PARAM_P: /* ignore current param */
941
        /* supported params:
942
         *  maddr, transport, ttl, lr, user, method, r2  */
943
2.39M
        switch(*p){
944
17.1k
          u_param_common_cases;
945
122k
          case '=':
946
122k
            v=p + 1;
947
122k
            state=URI_PARAM_VAL_P;
948
122k
            break;
949
2.39M
        };
950
2.39M
        break;
951
463k
      case URI_PARAM_VAL_P: /* value of the ignored current param */
952
463k
        switch(*p){
953
463k
          u_param_common_cases;
954
463k
        };
955
463k
        break;
956
      /* ugly but fast param names parsing */
957
      /*transport */
958
182k
      param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
959
182k
      param_switch(PT_R,  'a', 'A', PT_A);
960
145k
      param_switch(PT_A,  'n', 'N', PT_N);
961
134k
      param_switch(PT_N,  's', 'S', PT_S);
962
121k
      param_switch(PT_S,  'p', 'P', PT_P);
963
115k
      param_switch(PT_P,  'o', 'O', PT_O);
964
106k
      param_switch(PT_O,  'r', 'R', PT_R2);
965
101k
      param_switch(PT_R2, 't', 'T', PT_T2);
966
95.6k
      param_switch1(PT_T2, '=',  PT_eq);
967
      /* value parsing */
968
89.9k
      case PT_eq:
969
80.4k
        param=&uri->transport;
970
80.4k
        param_val=&uri->transport_val;
971
80.4k
        uri->proto = PROTO_OTHER;
972
80.4k
        switch (*p){
973
82
          param_common_cases;
974
6.97k
          case 'u':
975
13.2k
          case 'U':
976
13.2k
            v=p;
977
13.2k
            state=VU_U;
978
13.2k
            break;
979
30.9k
          case 't':
980
35.0k
          case 'T':
981
35.0k
            v=p;
982
35.0k
            state=VT_T;
983
35.0k
            break;
984
6.88k
          case 's':
985
14.2k
          case 'S':
986
14.2k
            v=p;
987
14.2k
            state=VS_S;
988
14.2k
            break;
989
4.68k
          case 'w':
990
13.2k
          case 'W':
991
13.2k
            v=p;
992
13.2k
            state=VW_W;
993
13.2k
            break;
994
3.09k
          default:
995
3.09k
            v=p;
996
3.09k
            state=URI_VAL_P;
997
80.4k
        }
998
80.3k
        break;
999
        /* generic value */
1000
335k
      case URI_VAL_P:
1001
335k
        switch(*p){
1002
335k
          value_common_cases;
1003
335k
        }
1004
333k
        break;
1005
      /* udp */
1006
333k
      value_switch(VU_U,  'd', 'D', VU_D);
1007
13.2k
      value_switch(VU_D,  'p', 'P', VU_P_FIN);
1008
6.37k
      transport_fin(VU_P_FIN, PROTO_UDP);
1009
      /* tcp */
1010
34.9k
      value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
1011
34.9k
      value_switch(VT_C,  'p', 'P', VT_P_FIN);
1012
15.2k
      transport_fin(VT_P_FIN, PROTO_TCP);
1013
      /* tls */
1014
16.8k
      value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
1015
16.8k
      transport_fin(VTLS_S_FIN, PROTO_TLS);
1016
      /* sctp */
1017
14.2k
      value_switch(VS_S, 'c', 'C', VS_C);
1018
14.2k
      value_switch(VS_C, 't', 'T', VS_T);
1019
9.94k
      value_switch(VS_T, 'p', 'P', VS_P_FIN);
1020
5.04k
      transport_fin(VS_P_FIN, PROTO_SCTP);
1021
      /* ws */
1022
13.2k
      value_switch(VW_W, 's', 'S', VW_S);
1023
13.1k
      case VW_S:
1024
7.93k
        if (*p == 's' || *p == 'S') {
1025
2.16k
          state=(VWS_S_FIN);
1026
2.16k
          break;
1027
2.16k
        }
1028
        /* if not a 's' transiting to VWS_S_FIN, fallback
1029
         * to testing as existing VW_S_FIN (NOTE the missing break) */
1030
5.76k
        state=(VW_S_FIN);
1031
5.76k
      transport_fin(VW_S_FIN, PROTO_WS);
1032
5.72k
      transport_fin(VWS_S_FIN, PROTO_WSS);
1033
1034
      /* ttl */
1035
13.2k
      param_switch(PTTL_T2,  'l', 'L', PTTL_L);
1036
13.2k
      param_switch1(PTTL_L,  '=', PTTL_eq);
1037
6.44k
      case PTTL_eq:
1038
3.19k
        param=&uri->ttl;
1039
3.19k
        param_val=&uri->ttl_val;
1040
3.19k
        switch(*p){
1041
104
          param_common_cases;
1042
875
          default:
1043
875
            v=p;
1044
875
            state=URI_VAL_P;
1045
3.19k
        }
1046
3.14k
        break;
1047
1048
      /* user param */
1049
24.2k
      param_switch(PU_U, 's', 'S', PU_S);
1050
24.1k
      param_switch(PU_S, 'e', 'E', PU_E);
1051
16.8k
      param_switch(PU_E, 'r', 'R', PU_R);
1052
10.9k
      param_switch1(PU_R, '=', PU_eq);
1053
6.02k
      case PU_eq:
1054
2.06k
        param=&uri->user_param;
1055
2.06k
        param_val=&uri->user_param_val;
1056
2.06k
        switch(*p){
1057
83
          param_common_cases;
1058
783
          default:
1059
783
            v=p;
1060
783
            state=URI_VAL_P;
1061
2.06k
        }
1062
2.02k
        break;
1063
1064
      /* method*/
1065
129k
      param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
1066
129k
      param_switch(PM_E, 't', 'T', PM_T);
1067
23.8k
      param_switch(PM_T, 'h', 'H', PM_H);
1068
18.8k
      param_switch(PM_H, 'o', 'O', PM_O);
1069
14.9k
      param_switch(PM_O, 'd', 'D', PM_D);
1070
10.5k
      param_switch1(PM_D, '=', PM_eq);
1071
4.58k
      case PM_eq:
1072
2.10k
        param=&uri->method;
1073
2.10k
        param_val=&uri->method_val;
1074
2.10k
        switch(*p){
1075
82
          param_common_cases;
1076
473
          default:
1077
473
            v=p;
1078
473
            state=URI_VAL_P;
1079
2.10k
        }
1080
2.06k
        break;
1081
1082
      /*maddr*/
1083
73.8k
      param_switch(PMA_A,  'd', 'D', PMA_D);
1084
73.7k
      param_switch(PMA_D,  'd', 'D', PMA_D2);
1085
65.9k
      param_switch(PMA_D2, 'r', 'R', PMA_R);
1086
49.9k
      param_switch1(PMA_R, '=', PMA_eq);
1087
44.7k
      case PMA_eq:
1088
26.3k
        param=&uri->maddr;
1089
26.3k
        param_val=&uri->maddr_val;
1090
26.3k
        switch(*p){
1091
82
          param_common_cases;
1092
4.37k
          default:
1093
4.37k
            v=p;
1094
4.37k
            state=URI_VAL_P;
1095
26.3k
        }
1096
26.3k
        break;
1097
1098
      /* lr */
1099
26.3k
      param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
1100
18.7k
      case PLR_R_FIN:
1101
8.96k
        switch(*p){
1102
124
          case '@':
1103
124
            still_at_user;
1104
85
            break;
1105
6.19k
          case '=':
1106
6.19k
            state=PLR_eq;
1107
6.19k
            break;
1108
1.36k
          semicolon_case;
1109
1.36k
            uri->lr.s=b;
1110
1.36k
            uri->lr.len=(p-b);
1111
1.36k
            break;
1112
144
          question_case;
1113
144
            uri->lr.s=b;
1114
144
            uri->lr.len=(p-b);
1115
144
            break;
1116
471
          colon_case;
1117
471
            break;
1118
666
          default:
1119
666
            state=URI_PARAM_P;
1120
8.96k
        }
1121
8.93k
        break;
1122
        /* handle lr=something case */
1123
8.93k
      case PLR_eq:
1124
6.18k
        param=&uri->lr;
1125
6.18k
        param_val=&uri->lr_val;
1126
6.18k
        switch(*p){
1127
96
          param_common_cases;
1128
1.57k
          default:
1129
1.57k
            v=p;
1130
1.57k
            state=URI_VAL_P;
1131
6.18k
        }
1132
6.14k
        break;
1133
1134
      /* r2 */
1135
20.6k
      param_switch1(PR2_R,  '2', PR2_2_FIN);
1136
20.5k
      case PR2_2_FIN:
1137
8.98k
        switch(*p){
1138
100
          case '@':
1139
100
            still_at_user;
1140
43
            break;
1141
6.47k
          case '=':
1142
6.47k
            state=PR2_eq;
1143
6.47k
            break;
1144
729
          semicolon_case;
1145
729
            uri->r2.s=b;
1146
729
            uri->r2.len=(p-b);
1147
729
            break;
1148
130
          question_case;
1149
130
            uri->r2.s=b;
1150
130
            uri->r2.len=(p-b);
1151
130
            break;
1152
872
          colon_case;
1153
872
            break;
1154
683
          default:
1155
683
            state=URI_PARAM_P;
1156
8.98k
        }
1157
8.92k
        break;
1158
        /* handle r2=something case */
1159
8.92k
      case PR2_eq:
1160
6.45k
        param=&uri->r2;
1161
6.45k
        param_val=&uri->r2_val;
1162
6.45k
        switch(*p){
1163
82
          param_common_cases;
1164
1.37k
          default:
1165
1.37k
            v=p;
1166
1.37k
            state=URI_VAL_P;
1167
6.45k
        }
1168
6.41k
        break;
1169
1170
1171
      /* gr */
1172
12.3k
      param_switch(PG_G,  'r', 'R', PG_G_FIN);
1173
12.3k
      case PG_G_FIN:
1174
6.97k
        switch(*p){
1175
96
          case '@':
1176
96
            still_at_user;
1177
43
            break;
1178
3.55k
          case '=':
1179
3.55k
            state=PG_eq;
1180
3.55k
            break;
1181
1.14k
          semicolon_case;
1182
1.14k
            uri->gr.s=b;
1183
1.14k
            uri->gr.len=(p-b);
1184
1.14k
            break;
1185
144
          question_case;
1186
144
            uri->gr.s=b;
1187
144
            uri->gr.len=(p-b);
1188
144
            break;
1189
685
          colon_case;
1190
685
            break;
1191
1.34k
          default:
1192
1.34k
            state=URI_PARAM_P;
1193
6.97k
        }
1194
6.91k
        break;
1195
        /* handle gr=something case */
1196
6.91k
      case PG_eq:
1197
3.53k
        param=&uri->gr;
1198
3.53k
        param_val=&uri->gr_val;
1199
3.53k
        switch(*p){
1200
120
          param_common_cases;
1201
1.68k
          default:
1202
1.68k
            v=p;
1203
1.68k
            state=URI_VAL_P;
1204
3.53k
        }
1205
3.47k
        break;
1206
1207
1208
      /* pn-* */
1209
138k
      param_switch(PN_P, 'n', 'N', PN_N);
1210
138k
      param_switch1(PN_N, '-', PN_dash);
1211
119k
      param_switch(PN_dash, 'p', 'P', PN_P2);
1212
1213
110k
      param_switch_bigger(PN_P2, 'r', 'R', 'a', 'A', 'u', 'U',
1214
101k
                          PN_PR, PN3_A, PN4_U);
1215
101k
      param_switch_big(PN_PR, 'o', 'O', 'i', 'I', PN1_O, PN2_I);
1216
1217
      /* pn-provider */
1218
53.1k
      param_switch(PN1_O, 'v', 'V', PN1_V);
1219
35.5k
      param_switch(PN1_V, 'i', 'I', PN1_I);
1220
30.5k
      param_switch(PN1_I, 'd', 'D', PN1_D);
1221
27.0k
      param_switch(PN1_D, 'e', 'E', PN1_E);
1222
22.5k
      param_switch(PN1_E, 'r', 'R', PN1_FIN);
1223
18.4k
      case PN1_FIN:
1224
16.0k
        param=&uri->pn_provider;
1225
16.0k
        switch(*p){
1226
96
          case '@':
1227
96
            still_at_user;
1228
43
            break;
1229
13.5k
          case '=':
1230
13.5k
            state=PN1_eq;
1231
13.5k
            break;
1232
973
          semicolon_case;
1233
973
            uri->pn_provider.s=b;
1234
973
            uri->pn_provider.len=(p-b);
1235
973
            break;
1236
130
          question_case;
1237
130
            uri->pn_provider.s=b;
1238
130
            uri->pn_provider.len=(p-b);
1239
130
            break;
1240
485
          colon_case;
1241
485
            break;
1242
803
          default:
1243
803
            state=URI_PARAM_P;
1244
16.0k
        }
1245
15.9k
        break;
1246
        /* handle pn-provider=something case */
1247
15.9k
      case PN1_eq:
1248
13.5k
        param=&uri->pn_provider;
1249
13.5k
        param_val=&uri->pn_provider_val;
1250
13.5k
        switch(*p){
1251
83
          param_common_cases;
1252
9.01k
          default:
1253
9.01k
            v=p;
1254
9.01k
            state=URI_VAL_P;
1255
13.5k
        }
1256
13.4k
        break;
1257
1258
      /* pn-prid */
1259
13.4k
      param_switch(PN2_I, 'd', 'D', PN2_D);
1260
10.8k
      param_xswitch1(PN2_D, '=', PN2_eq);
1261
2.52k
      case PN2_eq:
1262
2.47k
        param=&uri->pn_prid;
1263
2.47k
        param_val=&uri->pn_prid_val;
1264
2.47k
        switch(*p){
1265
82
          param_common_cases;
1266
559
          default:
1267
559
            v=p;
1268
559
            state=URI_VAL_P;
1269
2.47k
        }
1270
2.44k
        break;
1271
1272
      /* pn-param */
1273
19.8k
      param_switch(PN3_A, 'r', 'R', PN3_R);
1274
19.8k
      param_switch(PN3_R, 'a', 'A', PN3_A2);
1275
12.9k
      param_switch(PN3_A2, 'm', 'M', PN3_M);
1276
8.96k
      param_xswitch1(PN3_M, '=', PN3_eq);
1277
5.52k
      case PN3_eq:
1278
5.49k
        param=&uri->pn_param;
1279
5.49k
        param_val=&uri->pn_param_val;
1280
5.49k
        switch(*p){
1281
82
          param_common_cases;
1282
1.05k
          default:
1283
1.05k
            v=p;
1284
1.05k
            state=URI_VAL_P;
1285
5.49k
        }
1286
5.45k
        break;
1287
1288
      /* pn-purr */
1289
18.8k
      param_switch(PN4_U, 'r', 'R', PN4_R);
1290
18.7k
      param_switch(PN4_R, 'r', 'R', PN4_R2);
1291
10.7k
      param_xswitch1(PN4_R2, '=', PN4_eq);
1292
3.81k
      case PN4_eq:
1293
3.77k
        param=&uri->pn_purr;
1294
3.77k
        param_val=&uri->pn_purr_val;
1295
3.77k
        switch(*p){
1296
96
          param_common_cases;
1297
479
          default:
1298
479
            v=p;
1299
479
            state=URI_VAL_P;
1300
3.77k
        }
1301
3.72k
        break;
1302
1303
1304
79.9k
      case URI_HEADERS:
1305
        /* for now nobody needs them so we completely ignore the
1306
         * headers (they are not allowed in request uri) --andrei */
1307
79.9k
        switch(*p){
1308
8.68k
          case '@':
1309
            /* yak, we are still at user */
1310
8.68k
            still_at_user;
1311
5.52k
            break;
1312
11.6k
          case ';':
1313
            /* we might be still parsing user, try it */
1314
11.6k
            if (found_user) goto error_bad_char;
1315
5.52k
            error_headers=1; /* if this is not the user
1316
                      we have an error */
1317
            /* if pass is set => it cannot be user:pass
1318
             * => error (';') is illegal in a header */
1319
5.52k
            if (pass) goto error_headers;
1320
5.31k
            break;
1321
5.31k
          case ':':
1322
3.58k
            if (found_user==0){
1323
              /*might be pass but only if user not found yet*/
1324
2.30k
              if (pass){
1325
130
                found_user=1; /* no user */
1326
130
                pass=0;
1327
2.17k
              }else{
1328
2.17k
                pass=p;
1329
2.17k
              }
1330
2.30k
            }
1331
3.58k
            break;
1332
2.19k
          case '?':
1333
2.19k
            if (pass){
1334
44
              found_user=1; /* no user, pass cannot contain '?'*/
1335
44
              pass=0;
1336
44
            }
1337
2.19k
            break;
1338
79.9k
        }
1339
70.4k
        break;
1340
70.4k
      default:
1341
0
        goto error_bug;
1342
7.23M
    }
1343
7.23M
  }
1344
1345
  /*end of uri */
1346
29.9k
  switch (state){
1347
77
    case URI_INIT: /* error empty uri */
1348
77
      goto error_too_short;
1349
110
    case URI_USER:
1350
      /* this is the host, it can't be the user */
1351
110
      if (found_user) goto error_bad_uri;
1352
110
      uri->host.s=s;
1353
110
      uri->host.len=p-s;
1354
110
      state=URI_HOST;
1355
110
      break;
1356
5.14k
    case URI_PASSWORD:
1357
      /* this is the port, it can't be the passwd */
1358
5.14k
      if (found_user) goto error_bad_port;
1359
5.14k
      if (port_no > USHRT_MAX) goto error_bad_port;
1360
276
      uri->port.s=s;
1361
276
      uri->port.len=p-s;
1362
276
      uri->port_no=port_no;
1363
276
      uri->host=uri->user;
1364
276
      uri->user.s=0;
1365
276
      uri->user.len=0;
1366
276
      break;
1367
683
    case URI_PASSWORD_ALPHA:
1368
      /* this is the port, it can't be the passwd */
1369
683
      goto error_bad_port;
1370
532
    case URI_HOST_P:
1371
548
    case URI_HOST6_END:
1372
548
      uri->host.s=s;
1373
548
      uri->host.len=p-s;
1374
548
      break;
1375
10.1k
    case URI_HOST: /* error: null host */
1376
10.2k
    case URI_HOST6_P: /* error: unterminated ipv6 reference*/
1377
10.2k
      goto error_bad_host;
1378
401
    case URI_PORT:
1379
401
      uri->port.s=s;
1380
401
      uri->port.len=p-s;
1381
401
      uri->port_no=port_no;
1382
401
      break;
1383
1.93k
    case URI_PARAM:
1384
4.52k
    case URI_PARAM_P:
1385
4.61k
    case URI_PARAM_VAL_P:
1386
4.61k
      u_param_set(b, v);
1387
    /* intermediate param states */
1388
4.66k
    case PT_T: /* transport */
1389
4.69k
    case PT_R:
1390
4.72k
    case PT_A:
1391
4.75k
    case PT_N:
1392
4.78k
    case PT_S:
1393
4.80k
    case PT_P:
1394
4.83k
    case PT_O:
1395
4.85k
    case PT_R2:
1396
4.87k
    case PT_T2:
1397
4.89k
    case PT_eq: /* ignore empty transport params */
1398
4.92k
    case PTTL_T2: /* ttl */
1399
4.95k
    case PTTL_L:
1400
4.96k
    case PTTL_eq:
1401
4.99k
    case PU_U:  /* user */
1402
5.02k
    case PU_S:
1403
5.05k
    case PU_E:
1404
5.08k
    case PU_R:
1405
5.10k
    case PU_eq:
1406
5.14k
    case PM_M: /* method */
1407
5.17k
    case PM_E:
1408
5.20k
    case PM_T:
1409
5.22k
    case PM_H:
1410
5.25k
    case PM_O:
1411
5.27k
    case PM_D:
1412
5.29k
    case PM_eq:
1413
5.32k
    case PLR_L: /* lr */
1414
5.37k
    case PR2_R:  /* r2 */
1415
5.40k
    case PG_G: /* gr */
1416
5.40k
      uri->params.s=s;
1417
5.40k
      uri->params.len=p-s;
1418
5.40k
      break;
1419
    /* fin param states */
1420
26
    case PLR_R_FIN:
1421
34
    case PLR_eq:
1422
34
      uri->params.s=s;
1423
34
      uri->params.len=p-s;
1424
34
      uri->lr.s=b;
1425
34
      uri->lr.len=p-b;
1426
34
      break;
1427
18
    case PR2_2_FIN:
1428
35
    case PR2_eq:
1429
35
      uri->params.s=s;
1430
35
      uri->params.len=p-s;
1431
35
      uri->r2.s=b;
1432
35
      uri->r2.len=p-b;
1433
35
      break;
1434
28
    case PG_G_FIN:
1435
41
    case PG_eq:
1436
41
      uri->params.s=s;
1437
41
      uri->params.len=p-s;
1438
41
      uri->gr.s=b;
1439
41
      uri->gr.len=p-b;
1440
41
      break;
1441
24
    case PN1_FIN:
1442
33
    case PN1_eq:
1443
33
      uri->params.s=s;
1444
33
      uri->params.len=p-s;
1445
33
      uri->pn_provider.s=b;
1446
33
      uri->pn_provider.len=p-b;
1447
33
      break;
1448
699
    case URI_VAL_P:
1449
    /* intermediate value states */
1450
724
    case VU_U:
1451
749
    case VU_D:
1452
769
    case VT_T:
1453
793
    case VT_C:
1454
816
    case VTLS_L:
1455
842
    case VS_S:
1456
869
    case VS_C:
1457
894
    case VW_W:
1458
915
    case VS_T:
1459
915
      uri->params.s=s;
1460
915
      uri->params.len=p-s;
1461
915
      param_set(b, v);
1462
915
      break;
1463
    /* fin value states */
1464
22
    case VU_P_FIN:
1465
22
      uri->params.s=s;
1466
22
      uri->params.len=p-s;
1467
22
      param_set(b, v);
1468
22
      uri->proto=PROTO_UDP;
1469
22
      break;
1470
17
    case VT_P_FIN:
1471
17
      uri->params.s=s;
1472
17
      uri->params.len=p-s;
1473
17
      param_set(b, v);
1474
17
      uri->proto=PROTO_TCP;
1475
17
      break;
1476
20
    case VTLS_S_FIN:
1477
20
      uri->params.s=s;
1478
20
      uri->params.len=p-s;
1479
20
      param_set(b, v);
1480
20
      uri->proto=PROTO_TLS;
1481
20
      break;
1482
22
    case VS_P_FIN:
1483
22
      uri->params.s=s;
1484
22
      uri->params.len=p-s;
1485
22
      param_set(b, v);
1486
22
      uri->proto=PROTO_SCTP;
1487
22
      break;
1488
25
    case VW_S:
1489
25
    case VW_S_FIN:
1490
25
      uri->params.s=s;
1491
25
      uri->params.len=p-s;
1492
25
      param_set(b, v);
1493
25
      uri->proto=PROTO_WS;
1494
25
      break;
1495
19
    case VWS_S_FIN:
1496
19
      uri->params.s=s;
1497
19
      uri->params.len=p-s;
1498
19
      param_set(b, v);
1499
19
      uri->proto=PROTO_WSS;
1500
19
      break;
1501
    /* headers */
1502
4.88k
    case URI_HEADERS:
1503
4.88k
      uri->headers.s=s;
1504
4.88k
      uri->headers.len=p-s;
1505
4.88k
      if (error_headers) goto error_headers;
1506
1.98k
      break;
1507
    /* intermediate PN param states */
1508
1.98k
    case PN_P:
1509
74
    case PN_N:
1510
90
    case PN_dash:
1511
118
    case PN_P2:
1512
142
    case PN_PR:
1513
167
    case PN1_O:
1514
188
    case PN1_V:
1515
210
    case PN1_I:
1516
231
    case PN1_D:
1517
251
    case PN1_E:
1518
275
    case PN2_I:
1519
302
    case PN3_A:
1520
328
    case PN3_R:
1521
355
    case PN3_A2:
1522
381
    case PN4_U:
1523
403
    case PN4_R:
1524
403
      uri->params.s=s;
1525
403
      uri->params.len=p-s;
1526
403
      break;
1527
93
    case PN2_D:
1528
134
    case PN2_eq:
1529
186
    case PN3_M:
1530
212
    case PN3_eq:
1531
279
    case PN4_R2:
1532
323
    case PN4_eq:
1533
323
      goto error_bad_uri;
1534
489
    default:
1535
489
      goto error_bug;
1536
29.9k
  }
1537
10.3k
  switch(uri->type){
1538
4.05k
    case TEL_URI_T:
1539
4.05k
    case TELS_URI_T:
1540
      /* fix tel uris, move the number in uri and empty the host */
1541
4.05k
      uri->user=uri->host;
1542
      /* TEL does not have a host part, still most of the code expects
1543
       * one, so lets keep the pointer, but set a 0 length */
1544
4.05k
      uri->host.len=0;
1545
4.05k
      break;
1546
6.20k
    case SIP_URI_T:
1547
6.21k
    case SIPS_URI_T:
1548
6.22k
    case URN_SERVICE_URI_T:
1549
      /* nothing to do for these URIs */
1550
6.22k
      break;
1551
29
    case URN_NENA_SERVICE_URI_T:
1552
29
      uri->user.s=0;
1553
29
      uri->user.len=0;
1554
      /* keep the service name as host part */
1555
29
      break;
1556
0
    case ERROR_URI_T:
1557
0
      LM_ERR("unexpected error (BUG?)\n");
1558
0
      goto error_bad_uri;
1559
0
      break; /* do nothing, avoids a compilation warning */
1560
10.3k
  }
1561
#ifdef EXTRA_DEBUG
1562
  /* do stuff */
1563
  LM_DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
1564
      " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
1565
      " headers=<%.*s>(%d)\n",
1566
      uri->type,
1567
      uri->user.len, ZSW(uri->user.s), uri->user.len,
1568
      uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
1569
      uri->host.len, ZSW(uri->host.s), uri->host.len,
1570
      uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
1571
      uri->params.len, ZSW(uri->params.s), uri->params.len,
1572
      uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1573
    );
1574
  LM_DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1575
      uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1576
      ZSW(uri->transport_val.s), uri->proto);
1577
  LM_DBG("   user-param=<%.*s>, val=<%.*s>\n",
1578
      uri->user_param.len, ZSW(uri->user_param.s),
1579
      uri->user_param_val.len, ZSW(uri->user_param_val.s));
1580
  LM_DBG("   method=<%.*s>, val=<%.*s>\n",
1581
      uri->method.len, ZSW(uri->method.s),
1582
      uri->method_val.len, ZSW(uri->method_val.s));
1583
  LM_DBG("   ttl=<%.*s>, val=<%.*s>\n",
1584
      uri->ttl.len, ZSW(uri->ttl.s),
1585
      uri->ttl_val.len, ZSW(uri->ttl_val.s));
1586
  LM_DBG("   maddr=<%.*s>, val=<%.*s>\n",
1587
      uri->maddr.len, ZSW(uri->maddr.s),
1588
      uri->maddr_val.len, ZSW(uri->maddr_val.s));
1589
  LM_DBG("   lr=<%.*s>, val=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s),
1590
      uri->lr_val.len, ZSW(uri->lr_val.s));
1591
  LM_DBG("   r2=<%.*s>, val=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s),
1592
      uri->r2_val.len, ZSW(uri->r2_val.s));
1593
  for(i=0; i<URI_MAX_U_PARAMS && uri->u_name[i].s; i++)
1594
    LM_DBG("uname=[%p]-><%.*s> uval=[%p]-><%.*s>\n",
1595
      uri->u_name[i].s, uri->u_name[i].len, uri->u_name[i].s,
1596
      uri->u_val[i].s, uri->u_val[i].len, uri->u_val[i].s);
1597
  if (i!=uri->u_params_no)
1598
    LM_ERR("inconsisten # of u_name:[%d]!=[%d]\n", i, uri->u_params_no);
1599
#endif
1600
10.3k
  return 0;
1601
1602
77.5k
error_too_short:
1603
77.5k
  LM_ERR("uri too short: <%.*s> (%d)\n",
1604
77.5k
      len, ZSW(buf), len);
1605
77.5k
  goto error_exit;
1606
24.9k
error_bad_char:
1607
24.9k
  LM_ERR("bad char '%c' in state %d"
1608
24.9k
      " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1609
24.9k
      p < end ? *p : *(buf+len-1), state, (int)(p-buf), ZSW(buf),
1610
0
      (int)(p-buf), len, ZSW(buf), len);
1611
24.9k
  goto error_exit;
1612
11.9k
error_bad_host:
1613
11.9k
  LM_ERR("bad host in uri (error at char %c in"
1614
11.9k
      " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1615
11.9k
      p < end ? *p : *(buf+len-1), state, (int)(p-buf), ZSW(buf),
1616
0
      (int)(p-buf), len, ZSW(buf), len);
1617
11.9k
  goto error_exit;
1618
7.81k
error_bad_port:
1619
7.81k
  LM_ERR("bad port in uri (error at char '%c' in"
1620
7.81k
      " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1621
7.81k
      p < end ? *p : *(buf+len-1), state, (int)(p-buf), ZSW(buf),
1622
0
      (int)(p-buf), len, ZSW(buf), len);
1623
7.81k
  goto error_exit;
1624
5.93k
error_bad_uri:
1625
5.93k
  LM_ERR("bad uri, state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1626
5.93k
       state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
1627
0
       ZSW(buf), len);
1628
5.93k
  goto error_exit;
1629
3.10k
error_headers:
1630
3.10k
  LM_ERR("bad uri headers: <%.*s>(%d) / <%.*s>(%d)\n",
1631
3.10k
      uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1632
0
      len, ZSW(buf), len);
1633
3.10k
  goto error_exit;
1634
489
error_bug:
1635
489
  LM_ERR("bad state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1636
489
       state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
1637
131k
error_exit:
1638
131k
  ser_error=E_BAD_URI;
1639
131k
  uri->type=ERROR_URI_T;
1640
131k
  update_stat(bad_URIs, 1);
1641
131k
  return E_BAD_URI;
1642
489
}
1643
1644
/* Trim a URI userinfo str at the first ';'; see trim_user_params() in
1645
 * parse_uri.h for the full contract and caveats. */
1646
void trim_user_params(str *user)
1647
0
{
1648
0
  char *semi = q_memchr(user->s, ';', user->len);
1649
1650
0
  if (semi)
1651
0
    user->len = semi - user->s;
1652
0
}
1653
1654
1655
int parse_sip_msg_uri(struct sip_msg* msg)
1656
72.7k
{
1657
72.7k
  char* tmp;
1658
72.7k
  int tmp_len;
1659
72.7k
  if (msg->parsed_uri_ok) return 1;
1660
1661
72.7k
  if (msg->new_uri.s){
1662
0
    tmp=msg->new_uri.s;
1663
0
    tmp_len=msg->new_uri.len;
1664
72.7k
  }else{
1665
72.7k
    tmp=msg->first_line.u.request.uri.s;
1666
72.7k
    tmp_len=msg->first_line.u.request.uri.len;
1667
72.7k
  }
1668
72.7k
  if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1669
70.8k
    LM_ERR("bad uri <%.*s>\n", tmp_len, tmp);
1670
70.8k
    msg->parsed_uri_ok=0;
1671
70.8k
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM, "error parsing r-uri");
1672
70.8k
    set_err_reply(400, "bad r-uri");
1673
70.8k
    return -1;
1674
70.8k
  }
1675
1.93k
  msg->parsed_uri_ok=1;
1676
1.93k
  return 0;
1677
72.7k
}
1678
1679
1680
int parse_orig_ruri(struct sip_msg* msg)
1681
55.0k
{
1682
55.0k
  str *uri;
1683
1684
55.0k
  if (msg->parsed_orig_ruri_ok)
1685
0
    return 1;
1686
1687
55.0k
  uri = &REQ_LINE(msg).uri;
1688
1689
55.0k
  if (parse_uri(uri->s, uri->len, &msg->parsed_orig_ruri)<0) {
1690
53.1k
    LM_ERR("bad uri <%.*s>\n", uri->len, ZSW(uri->s));
1691
53.1k
    msg->parsed_orig_ruri_ok = 0;
1692
53.1k
    set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
1693
53.1k
        "error parsing incoming uri");
1694
53.1k
    set_err_reply(400, "bad i-uri");
1695
53.1k
    return -1;
1696
53.1k
  }
1697
1698
1.93k
  msg->parsed_orig_ruri_ok = 1;
1699
1.93k
  return 0;
1700
55.0k
}
1701
1702
#define compare_uri_val(field,cmpfunc) \
1703
0
  do { \
1704
0
    if (first.field.len != second.field.len) \
1705
0
    { \
1706
0
      LM_DBG("Different URI field - " #field "\n"); \
1707
0
      return 1; \
1708
0
    } \
1709
0
    else \
1710
0
    { \
1711
0
      if (first.field.len != 0) \
1712
0
        if (cmpfunc(first.field.s,second.field.s,first.field.len)) \
1713
0
        { \
1714
0
          LM_DBG("Different URI field - " #field "\n"); \
1715
0
          return 1; \
1716
0
        } \
1717
0
    } \
1718
0
  } while (0)
1719
1720
/* Compare 2 SIP URIs according to RFC 3261
1721
 *
1722
 * Return value : 0 if URIs match
1723
 *          1 if URIs don't match
1724
 *         -1 if errors have occurred
1725
 */
1726
int compare_uris(str *raw_uri_a,struct sip_uri* parsed_uri_a,
1727
          str *raw_uri_b,struct sip_uri *parsed_uri_b)
1728
0
{
1729
0
  #define UNESCAPED_BUF_LEN 1024
1730
0
  char unescaped_a[UNESCAPED_BUF_LEN], unescaped_b[UNESCAPED_BUF_LEN];
1731
1732
0
  str unescaped_userA={unescaped_a, UNESCAPED_BUF_LEN};
1733
0
  str unescaped_userB={unescaped_b, UNESCAPED_BUF_LEN};
1734
1735
0
  struct sip_uri first;
1736
0
  struct sip_uri second;
1737
0
  char matched[URI_MAX_U_PARAMS];
1738
0
  int i,j;
1739
1740
0
  if ( (!raw_uri_a && !parsed_uri_a) || (!raw_uri_b && !parsed_uri_b) )
1741
0
  {
1742
0
    LM_ERR("Provide either a raw or parsed form of a SIP URI\n");
1743
0
    return -1;
1744
0
  }
1745
1746
0
  if (raw_uri_a && raw_uri_b)
1747
0
  {
1748
1749
    /* maybe we're lucky and straight-forward comparison succeeds */
1750
0
    if (raw_uri_a->len == raw_uri_b->len)
1751
0
      if (strncasecmp(raw_uri_a->s,raw_uri_b->s,raw_uri_a->len) == 0)
1752
0
      {
1753
0
        LM_DBG("straight-forward URI match\n");
1754
0
        if (parse_uri(raw_uri_a->s,raw_uri_a->len,&first) < 0)
1755
0
        {
1756
0
          LM_ERR("Failed to parse first URI\n");
1757
0
          return -1;
1758
0
        }
1759
0
        if (parse_uri(raw_uri_b->s,raw_uri_b->len,&second) < 0)
1760
0
        {
1761
0
          LM_ERR("Failed to parse second URI\n");
1762
0
          return -1;
1763
0
        }
1764
0
        if (unescape_user(&first.user, &unescaped_userA) < 0 ||
1765
0
            unescape_user(&second.user, &unescaped_userB) < 0) {
1766
0
          LM_ERR("Failed to unescape user!\n");
1767
0
          return -1;
1768
0
        }
1769
0
        first.user = unescaped_userA;
1770
0
        second.user = unescaped_userB;
1771
0
        compare_uri_val(user,strncmp);
1772
0
        compare_uri_val(passwd,strncmp);
1773
0
        return 0;
1774
0
      }
1775
0
  }
1776
1777
  /* XXX - maybe if we have two parsed sip_uris,
1778
   * or only one parsed and one raw,
1779
   * it should be possible to do a straight-forward
1780
   * URI match ? */
1781
1782
0
  if (parsed_uri_a)
1783
0
    first = *parsed_uri_a;
1784
0
  else
1785
0
  {
1786
0
    if (parse_uri(raw_uri_a->s,raw_uri_a->len,&first) < 0)
1787
0
    {
1788
0
      LM_ERR("Failed to parse first URI\n");
1789
0
      return -1;
1790
0
    }
1791
0
  }
1792
1793
0
  if (parsed_uri_b)
1794
0
    second = *parsed_uri_b;
1795
0
  else
1796
0
  {
1797
0
    if (parse_uri(raw_uri_b->s,raw_uri_b->len,&second) < 0)
1798
0
    {
1799
0
      LM_ERR("Failed to parse second URI\n");
1800
0
      return -1;
1801
0
    }
1802
0
  }
1803
1804
0
  if (first.type != second.type)
1805
0
  {
1806
0
    LM_DBG("Different uri types\n");
1807
0
    return 1;
1808
0
  }
1809
1810
0
  if (unescape_user(&first.user, &unescaped_userA) < 0 ||
1811
0
      unescape_user(&second.user, &unescaped_userB) < 0) {
1812
0
    LM_ERR("Failed to unescape user!\n");
1813
0
    return -1;
1814
0
  }
1815
1816
0
  first.user = unescaped_userA;
1817
0
  second.user = unescaped_userB;
1818
1819
0
  compare_uri_val(user,strncmp);
1820
0
  compare_uri_val(passwd,strncmp);
1821
0
  compare_uri_val(host,strncasecmp);
1822
0
  compare_uri_val(port,strncmp);
1823
1824
0
  compare_uri_val(transport_val,strncasecmp);
1825
0
  compare_uri_val(ttl_val,strncasecmp);
1826
0
  compare_uri_val(user_param_val,strncasecmp);
1827
0
  compare_uri_val(maddr_val,strncasecmp);
1828
0
  compare_uri_val(method_val,strncasecmp);
1829
0
  compare_uri_val(lr_val,strncasecmp);
1830
0
  compare_uri_val(r2_val,strncasecmp);
1831
0
  compare_uri_val(gr_val,strncasecmp);
1832
0
  compare_uri_val(pn_provider_val,strncasecmp);
1833
0
  compare_uri_val(pn_prid_val,strncasecmp);
1834
0
  compare_uri_val(pn_param_val,strncasecmp);
1835
0
  compare_uri_val(pn_purr_val,strncasecmp);
1836
1837
0
  if (first.u_params_no == 0 || second.u_params_no == 0)
1838
    /* one URI doesn't have other params,
1839
     * automatically all unknown params in other URI match
1840
     */
1841
0
    goto headers_check;
1842
1843
0
  memset(matched,0,URI_MAX_U_PARAMS);
1844
1845
0
  for (i=0;i<first.u_params_no;i++)
1846
0
    for (j=0;j<second.u_params_no;j++)
1847
0
      if (matched[j] == 0 &&
1848
0
        (first.u_name[i].len == second.u_name[j].len &&
1849
0
                strncasecmp(first.u_name[i].s,second.u_name[j].s,
1850
0
              first.u_name[i].len) == 0))
1851
0
        {
1852
                    /* point of no return - matching unknown parameter values */
1853
0
          if (first.u_val[i].len != second.u_val[j].len)
1854
0
          {
1855
0
            LM_DBG("Different URI param value for param %.*s\n",
1856
0
                first.u_name[i].len,first.u_name[i].s);
1857
0
            return 1;
1858
0
          }
1859
0
          else
1860
0
          {
1861
0
            if (first.u_val[i].len == 0)
1862
0
            {
1863
              /* no value for unknown params - match */
1864
0
              matched[j] = 1;
1865
0
              break;
1866
0
            }
1867
1868
0
            if (strncasecmp(first.u_val[i].s,second.u_val[j].s,
1869
0
              second.u_val[j].len))
1870
0
            {
1871
0
              LM_DBG("Different URI param value for param %.*s\n",
1872
0
                first.u_name[i].len,first.u_name[i].s);
1873
0
              return 1;
1874
0
            }
1875
0
            else
1876
0
            {
1877
0
              matched[j] = 1;
1878
0
              break;
1879
0
            }
1880
0
          }
1881
0
        }
1882
1883
  /* got here, it means all unknown params in first URI have been resolved
1884
    => first URI matched second URI, and the other way around
1885
  */
1886
1887
0
headers_check:
1888
   /* XXX Do we really care ? */
1889
0
  compare_uri_val(headers,strncasecmp);
1890
0
  return 0;
1891
0
}