core: Fixes for WSS (secure WebSocket) transport and Via:s
[sip-router] / parser / parse_uri.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser 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  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * --------
29  * 2003-04-04  convenience inbound-uri parser parse_orig_ruri
30  *             introduced (jiri)
31  * 2003-04-11  new parse_uri introduced (better, parses also some parameters,
32  *              works in one pass) (andrei)
33  * 2003-04-11  ser_error is now set in parse_uri (andrei)
34  * 2003-04-26  ZSW (jiri)
35  * 2003-07-03  sips:, r2, lr=on support added (andrei)
36  * 2005-02-25  preliminary tel uri support (andrei)
37  * 2005-03-03  more tel uri fixes (andrei)
38  * 2006-04-20  comp uri param. support (rfc3486) if defined USE_COMP  (andrei)
39  * 2007-09-10  introduced phone2tel option which allows NOT to consider
40  *             user=phone URIs as TEL URIs
41  *
42  */
43
44 /** @file
45  * @brief Parser :: Parse URI's
46  *
47  * @ingroup parser
48  */
49
50
51 #include "../globals.h"
52 #include "parse_uri.h"
53 #include <string.h>
54 #include "../dprint.h"
55 #include "../ut.h"   /* q_memchr */
56 #include "../error.h"
57 #include "../core_stats.h"
58
59 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
60  * len= len of uri
61  * returns: fills uri & returns <0 on error or 0 if ok 
62  */
63 int parse_uri(char* buf, int len, struct sip_uri* uri)
64 {
65         enum states  {  URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
66                                         URI_HOST, URI_HOST_P,
67                                         URI_HOST6_P, URI_HOST6_END, URI_PORT, 
68                                         URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
69                                         /* param states */
70                                         /* transport */
71                                         PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
72                                         PT_eq,
73                                         /* ttl */
74                                               PTTL_T2, PTTL_L, PTTL_eq,
75                                         /* user */
76                                         PU_U, PU_S, PU_E, PU_R, PU_eq,
77                                         /* method */
78                                         PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
79                                         /* maddr */
80                                               PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
81                                         /* lr */
82                                         PLR_L, PLR_R_FIN, PLR_eq,
83                                         /* r2 */
84                                         PR2_R, PR2_2_FIN, PR2_eq,
85                                         /* gr */
86                                         PGR_G, PGR_R_FIN, PGR_eq,
87 #ifdef USE_COMP
88                                         /* comp */
89                                         PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
90                                         
91                                         /* comp values */
92                                         /* sigcomp */
93                                         VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
94                                         VCOMP_SIGC_C, VCOMP_SIGC_O,  VCOMP_SIGC_M,
95                                         VCOMP_SIGC_P_FIN,
96                                         /* sergz */
97                                                         VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
98                                                         VCOMP_SGZ_Z_FIN,
99 #endif
100                                         
101                                         /* transport values */
102                                         /* udp */
103                                         VU_U, VU_D, VU_P_FIN,
104                                         /* tcp */
105                                         VT_T, VT_C, VT_P_FIN,
106                                         /* tls */
107                                               VTLS_L, VTLS_S_FIN,
108                                         /* sctp */
109                                         VS_S, VS_C, VS_T, VS_P_FIN,
110                                         /* ws */
111                                         VW_W, VW_S_FIN
112         };
113         register enum states state;
114         char* s;
115         char* b; /* param start */
116         char *v; /* value start */
117         str* param; /* current param */
118         str* param_val; /* current param val */
119         str user;
120         str password;
121         int port_no;
122         register char* p;
123         char* end;
124         char* pass;
125         int found_user;
126         int error_headers;
127         unsigned int scheme;
128         uri_type backup_urit;
129         uri_flags backup_urif;
130
131 #ifdef USE_COMP
132         str comp_str; /* not returned for now */
133         str comp_val; /* not returned for now */
134 #endif
135         
136 #define SIP_SCH         0x3a706973
137 #define SIPS_SCH        0x73706973
138 #define TEL_SCH         0x3a6c6574
139 #define URN_SCH         0x3a6e7275
140         
141 #define case_port( ch, var) \
142         case ch: \
143                          (var)=(var)*10+ch-'0'; \
144                          break
145                          
146 #define still_at_user  \
147                                                 if (found_user==0){ \
148                                                         user.s=uri->host.s; \
149                                                         if (pass){\
150                                                                 user.len=pass-user.s; \
151                                                                 password.s=pass+1; \
152                                                                 password.len=p-password.s; \
153                                                         }else{ \
154                                                                 user.len=p-user.s; \
155                                                         }\
156                                                         /* save the uri type/scheme */ \
157                                                         backup_urit=uri->type; \
158                                                         backup_urif=uri->flags; \
159                                                         /* everything else is 0 */ \
160                                                         memset(uri, 0, sizeof(struct sip_uri)); \
161                                                         /* restore the scheme & flags, copy user & pass */ \
162                                                         uri->type=backup_urit; \
163                                                         uri->flags=backup_urif; \
164                                                         uri->user=user; \
165                                                         if (pass)       uri->passwd=password;  \
166                                                         s=p+1; \
167                                                         found_user=1;\
168                                                         error_headers=0; \
169                                                         state=URI_HOST; \
170                                                 }else goto error_bad_char 
171
172 #define check_host_end \
173                                         case ':': \
174                                                 /* found the host */ \
175                                                 uri->host.s=s; \
176                                                 uri->host.len=p-s; \
177                                                 state=URI_PORT; \
178                                                 s=p+1; \
179                                                 break; \
180                                         case ';': \
181                                                 uri->host.s=s; \
182                                                 uri->host.len=p-s; \
183                                                 state=URI_PARAM; \
184                                                 s=p+1; \
185                                                 break; \
186                                         case '?': \
187                                                 uri->host.s=s; \
188                                                 uri->host.len=p-s; \
189                                                 state=URI_HEADERS; \
190                                                 s=p+1; \
191                                                 break; \
192                                         case '&': \
193                                         case '@': \
194                                                 goto error_bad_char 
195
196
197 #define param_set(t_start, v_start) \
198                                         param->s=(t_start);\
199                                         param->len=(p-(t_start));\
200                                         param_val->s=(v_start); \
201                                         param_val->len=(p-(v_start)) 
202
203 #define semicolon_case \
204                                         case';': \
205                                                 if (pass){ \
206                                                         found_user=1;/* no user, pass cannot contain ';'*/ \
207                                                         pass=0; \
208                                                 } \
209                                                 state=URI_PARAM   /* new param */ 
210
211 #define question_case \
212                                         case '?': \
213                                                 uri->params.s=s; \
214                                                 uri->params.len=p-s; \
215                                                 state=URI_HEADERS; \
216                                                 s=p+1; \
217                                                 if (pass){ \
218                                                         found_user=1;/* no user, pass cannot contain '?'*/ \
219                                                         pass=0; \
220                                                 }
221
222 #define colon_case \
223                                         case ':': \
224                                                 if (found_user==0){ \
225                                                         /*might be pass but only if user not found yet*/ \
226                                                         if (pass){ \
227                                                                 found_user=1; /* no user */ \
228                                                                 pass=0; \
229                                                         }else{ \
230                                                                 pass=p; \
231                                                         } \
232                                                 } \
233                                                 state=URI_PARAM_P /* generic param */
234
235 #define param_common_cases \
236                                         case '@': \
237                                                 /* ughhh, this is still the user */ \
238                                                 still_at_user; \
239                                                 break; \
240                                         semicolon_case; \
241                                                 break; \
242                                         question_case; \
243                                                 break; \
244                                         colon_case; \
245                                                 break
246
247 #define value_common_cases \
248                                         case '@': \
249                                                 /* ughhh, this is still the user */ \
250                                                 still_at_user; \
251                                                 break; \
252                                         semicolon_case; \
253                                                 param_set(b, v); \
254                                                 break; \
255                                         question_case; \
256                                                 param_set(b, v); \
257                                                 break; \
258                                         colon_case; \
259                                                 state=URI_VAL_P; \
260                                                 break
261
262 #define param_switch(old_state, c1, c2, new_state) \
263                         case old_state: \
264                                 switch(*p){ \
265                                         case c1: \
266                                         case c2: \
267                                                 state=(new_state); \
268                                                 break; \
269                                         param_common_cases; \
270                                         default: \
271                                                 state=URI_PARAM_P; \
272                                 } \
273                                 break
274 #define param_switch1(old_state, c1, new_state) \
275                         case old_state: \
276                                 switch(*p){ \
277                                         case c1: \
278                                                 state=(new_state); \
279                                                 break; \
280                                         param_common_cases; \
281                                         default: \
282                                                 state=URI_PARAM_P; \
283                                 } \
284                                 break
285 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
286                         case old_state : \
287                                 switch(*p){ \
288                                         case c1: \
289                                         case c2: \
290                                                 state=(new_state_c); \
291                                                 break; \
292                                         case d1: \
293                                         case d2: \
294                                                 state=(new_state_d); \
295                                                 break; \
296                                         param_common_cases; \
297                                         default: \
298                                                 state=URI_PARAM_P; \
299                                 } \
300                                 break
301 #define value_switch(old_state, c1, c2, new_state) \
302                         case old_state: \
303                                 switch(*p){ \
304                                         case c1: \
305                                         case c2: \
306                                                 state=(new_state); \
307                                                 break; \
308                                         value_common_cases; \
309                                         default: \
310                                                 state=URI_VAL_P; \
311                                 } \
312                                 break
313 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
314                         case old_state: \
315                                 switch(*p){ \
316                                         case c1: \
317                                         case c2: \
318                                                 state=(new_state_c); \
319                                                 break; \
320                                         case d1: \
321                                         case d2: \
322                                                 state=(new_state_d); \
323                                                 break; \
324                                         value_common_cases; \
325                                         default: \
326                                                 state=URI_VAL_P; \
327                                 } \
328                                 break
329
330 #define transport_fin(c_state, proto_no) \
331                         case c_state: \
332                                 switch(*p){ \
333                                         case '@': \
334                                                 still_at_user; \
335                                                 break; \
336                                         semicolon_case; \
337                                                 param_set(b, v); \
338                                                 uri->proto=(proto_no); \
339                                                 break; \
340                                         question_case; \
341                                                 param_set(b, v); \
342                                                 uri->proto=(proto_no); \
343                                                 break; \
344                                         colon_case;  \
345                                         default: \
346                                                 state=URI_VAL_P; \
347                                                 break; \
348                                 } \
349                                 break
350                         
351
352 #ifdef USE_COMP
353 #define comp_fin(c_state, comp_no) \
354                         case c_state: \
355                                 switch(*p){ \
356                                         case '@': \
357                                                 still_at_user; \
358                                                 break; \
359                                         semicolon_case; \
360                                                 /* param_set(b, v); */ \
361                                                 uri->comp=(comp_no); \
362                                                 break; \
363                                         question_case; \
364                                                 /* param_set(b, v) */; \
365                                                 uri->comp=(comp_no); \
366                                                 break; \
367                                         colon_case;  \
368                                         default: \
369                                                 state=URI_VAL_P; \
370                                                 break; \
371                                 } \
372                                 break
373                         
374 #endif
375
376         /* init */
377         end=buf+len;
378         p=buf+4;
379         found_user=0;
380         error_headers=0;
381         b=v=0;
382         param=param_val=0;
383         pass=0;
384         password.s=0; /* fixes gcc 4.0 warning */
385         password.len=0;
386         port_no=0;
387         state=URI_INIT;
388         memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
389         /*look for sip:, sips: ,tel: or urn:*/
390         if (len<5) goto error_too_short;
391         scheme=buf[0]+(buf[1]<<8)+(buf[2]<<16)+(buf[3]<<24);
392         scheme|=0x20202020;
393         if (scheme==SIP_SCH){
394                 uri->type=SIP_URI_T;
395         }else if(scheme==SIPS_SCH){
396                 if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
397                 else goto error_bad_uri;
398         }else if (scheme==TEL_SCH){
399                 uri->type=TEL_URI_T;
400         }else if (scheme==URN_SCH){
401                 uri->type=URN_URI_T;
402         }else goto error_bad_uri;
403         
404         s=p;
405         for(;p<end; p++){
406                 switch((unsigned char)state){
407                         case URI_INIT:
408                                 switch(*p){
409                                         case '[':
410                                                 /* uri =  [ipv6address]... */
411                                                 state=URI_HOST6_P;
412                                                 s=p;
413                                                 break;
414                                         case ']':
415                                                 /* invalid, no uri can start with ']' */
416                                         case ':':
417                                                 /* the same as above for ':' */
418                                                 goto error_bad_char;
419                                         case '@': /* error no user part, or
420                                                                  be forgiving and accept it ? */
421                                         default:
422                                                 state=URI_USER;
423                                 }
424                                 break; 
425                         case URI_USER:
426                                 switch(*p){
427                                         case '@':
428                                                 /* found the user*/
429                                                 uri->user.s=s;
430                                                 uri->user.len=p-s;
431                                                 state=URI_HOST;
432                                                 found_user=1;
433                                                 s=p+1; /* skip '@' */
434                                                 break;
435                                         case ':':
436                                                 /* found the user, or the host? */
437                                                 uri->user.s=s;
438                                                 uri->user.len=p-s;
439                                                 state=URI_PASSWORD;
440                                                 s=p+1; /* skip ':' */
441                                                 break;
442                                         case ';':
443                                                 /* this could be still the user or
444                                                  * params?*/
445                                                 uri->host.s=s;
446                                                 uri->host.len=p-s;
447                                                 state=URI_PARAM;
448                                                 s=p+1;
449                                                 break;
450                                         case '?': /* still user or headers? */
451                                                 uri->host.s=s;
452                                                 uri->host.len=p-s;
453                                                 state=URI_HEADERS;
454                                                 s=p+1;
455                                                 break;
456                                                 /* almost anything permitted in the user part */
457                                         case '.':
458                                         case '-':
459                                         case '(':
460                                         case ')':
461                                                 /* tel uri visual separators, set flag meaning, that
462                                                  * user should be normalized before usage
463                                                  */
464                                                 uri->flags|=URI_USER_NORMALIZE;
465                                                 break;
466                                         case '[':
467                                         case ']': /* the user part cannot contain "[]" */
468                                                 goto error_bad_char;
469                                 }
470                                 break;
471                         case URI_PASSWORD: /* this can also be the port (missing user)*/
472                                 switch(*p){
473                                         case '@':
474                                                 /* found the password*/
475                                                 uri->passwd.s=s;
476                                                 uri->passwd.len=p-s;
477                                                 port_no=0;
478                                                 state=URI_HOST;
479                                                 found_user=1;
480                                                 s=p+1; /* skip '@' */
481                                                 break;
482                                         case ';':
483                                                 /* upps this is the port */
484                                                 uri->port.s=s;
485                                                 uri->port.len=p-s;
486                                                 uri->port_no=port_no;
487                                                 /* user contains in fact the host */
488                                                 uri->host.s=uri->user.s;
489                                                 uri->host.len=uri->user.len;
490                                                 uri->user.s=0;
491                                                 uri->user.len=0;
492                                                 state=URI_PARAM;
493                                                 found_user=1; /*  there is no user part */
494                                                 s=p+1;
495                                                 break;
496                                         case '?':
497                                                 /* upps this is the port */
498                                                 uri->port.s=s;
499                                                 uri->port.len=p-s;
500                                                 uri->port_no=port_no;
501                                                 /* user contains in fact the host */
502                                                 uri->host.s=uri->user.s;
503                                                 uri->host.len=uri->user.len;
504                                                 uri->user.s=0;
505                                                 uri->user.len=0;
506                                                 state=URI_HEADERS;
507                                                 found_user=1; /*  there is no user part */
508                                                 s=p+1;
509                                                 break;
510                                         case_port('0', port_no);
511                                         case_port('1', port_no);
512                                         case_port('2', port_no);
513                                         case_port('3', port_no);
514                                         case_port('4', port_no);
515                                         case_port('5', port_no);
516                                         case_port('6', port_no);
517                                         case_port('7', port_no);
518                                         case_port('8', port_no);
519                                         case_port('9', port_no);
520                                         case '[':
521                                         case ']':
522                                         case ':':
523                                                 goto error_bad_char;
524                                         default:
525                                                 /* it can't be the port, non number found */
526                                                 port_no=0;
527                                                 state=URI_PASSWORD_ALPHA;
528                                 }
529                                 break;
530                         case URI_PASSWORD_ALPHA:
531                                 switch(*p){
532                                         case '@':
533                                                 /* found the password*/
534                                                 uri->passwd.s=s;
535                                                 uri->passwd.len=p-s;
536                                                 state=URI_HOST;
537                                                 found_user=1;
538                                                 s=p+1; /* skip '@' */
539                                                 break;
540                                         case ';': /* contains non-numbers => cannot be port no*/
541                                         case '?':
542                                                 goto error_bad_port;
543                                         case '[':
544                                         case ']':
545                                         case ':':
546                                                 goto error_bad_char;
547                                 }
548                                 break;
549                         case URI_HOST:
550                                 switch(*p){
551                                         case '[':
552                                                 state=URI_HOST6_P;
553                                                 break;
554                                         case ':': 
555                                         case ';':
556                                         case '?': /* null host name ->invalid */
557                                         case '&':
558                                         case '@': /*chars not allowed in hosts names */
559                                                 goto error_bad_host;
560                                         default:
561                                                 state=URI_HOST_P;
562                                 }
563                                 break;
564                         case URI_HOST_P:
565                                 switch(*p){
566                                         check_host_end;
567                                 }
568                                 break;
569                         case URI_HOST6_END:
570                                 switch(*p){
571                                         check_host_end;
572                                         default: /*no chars allowed after [ipv6] */
573                                                 goto error_bad_host;
574                                 }
575                                 break;
576                         case URI_HOST6_P:
577                                 switch(*p){
578                                         case ']':
579                                                 state=URI_HOST6_END;
580                                                 break;
581                                         case '[':
582                                         case '&':
583                                         case '@':
584                                         case ';':
585                                         case '?':
586                                                 goto error_bad_host;
587                                 }
588                                 break;
589                         case URI_PORT:
590                                 switch(*p){
591                                         case ';':
592                                                 uri->port.s=s;
593                                                 uri->port.len=p-s;
594                                                 uri->port_no=port_no;
595                                                 state=URI_PARAM;
596                                                 s=p+1;
597                                                 break;
598                                         case '?':
599                                                 uri->port.s=s;
600                                                 uri->port.len=p-s;
601                                                 uri->port_no=port_no;
602                                                 state=URI_HEADERS;
603                                                 s=p+1;
604                                                 break;
605                                         case_port('0', port_no);
606                                         case_port('1', port_no);
607                                         case_port('2', port_no);
608                                         case_port('3', port_no);
609                                         case_port('4', port_no);
610                                         case_port('5', port_no);
611                                         case_port('6', port_no);
612                                         case_port('7', port_no);
613                                         case_port('8', port_no);
614                                         case_port('9', port_no);
615                                         case '&':
616                                         case '@':
617                                         case ':':
618                                         default:
619                                                 goto error_bad_port;
620                                 }
621                                 break;
622                         case URI_PARAM: /* beginning of a new param */
623                                 switch(*p){
624                                         param_common_cases;
625                                         /* recognized params */
626                                         case 't':
627                                         case 'T':
628                                                 b=p;
629                                                 state=PT_T;
630                                                 break;
631                                         case 'u':
632                                         case 'U':
633                                                 b=p;
634                                                 state=PU_U;
635                                                 break;
636                                         case 'm':
637                                         case 'M':
638                                                 b=p;
639                                                 state=PM_M;
640                                                 break;
641                                         case 'l':
642                                         case 'L':
643                                                 b=p;
644                                                 state=PLR_L;
645                                                 break;
646                                         case 'r':
647                                         case 'R':
648                                                 b=p;
649                                                 state=PR2_R;
650                                                 break;
651                                         case 'g':
652                                         case 'G':
653                                                 b=p;
654                                                 state=PGR_G;
655                                                 break;
656 #ifdef USE_COMP
657                                         case 'c':
658                                         case 'C':
659                                                 b=p;
660                                                 state=PCOMP_C;
661                                                 break;
662 #endif
663                                         default:
664                                                 state=URI_PARAM_P;
665                                 }
666                                 break;
667                         case URI_PARAM_P: /* ignore current param */
668                                 /* supported params:
669                                  *  maddr, transport, ttl, lr, user, method, r2  */
670                                 switch(*p){
671                                         param_common_cases;
672                                 };
673                                 break;
674                         /* ugly but fast param names parsing */
675                         /*transport */
676                         param_switch_big(PT_T,  'r', 'R', 't', 'T', PT_R, PTTL_T2);
677                         param_switch(PT_R,  'a', 'A', PT_A);
678                         param_switch(PT_A,  'n', 'N', PT_N);
679                         param_switch(PT_N,  's', 'S', PT_S);
680                         param_switch(PT_S,  'p', 'P', PT_P);
681                         param_switch(PT_P,  'o', 'O', PT_O);
682                         param_switch(PT_O,  'r', 'R', PT_R2);
683                         param_switch(PT_R2, 't', 'T', PT_T2);
684                         param_switch1(PT_T2, '=',  PT_eq);
685                         /* value parsing */
686                         case PT_eq:
687                                 param=&uri->transport;
688                                 param_val=&uri->transport_val;
689                                 switch (*p){
690                                         param_common_cases;
691                                         case 'u':
692                                         case 'U':
693                                                 v=p;
694                                                 state=VU_U;
695                                                 break;
696                                         case 't':
697                                         case 'T':
698                                                 v=p;
699                                                 state=VT_T;
700                                                 break;
701                                         case 's':
702                                         case 'S':
703                                                 v=p;
704                                                 state=VS_S;
705                                                 break;
706                                         case 'w':
707                                         case 'W':
708                                                 v=p;
709                                                 state=VW_W;
710                                                 break;
711                                         default:
712                                                 v=p;
713                                                 state=URI_VAL_P;
714                                 }
715                                 break;
716                                 /* generic value */
717                         case URI_VAL_P:
718                                 switch(*p){
719                                         value_common_cases;
720                                 }
721                                 break;
722                         /* udp */
723                         value_switch(VU_U,  'd', 'D', VU_D);
724                         value_switch(VU_D,  'p', 'P', VU_P_FIN);
725                         transport_fin(VU_P_FIN, PROTO_UDP);
726                         /* tcp */
727                         value_switch_big(VT_T,  'c', 'C', 'l', 'L', VT_C, VTLS_L);
728                         value_switch(VT_C,  'p', 'P', VT_P_FIN);
729                         transport_fin(VT_P_FIN, PROTO_TCP);
730                         /* tls */
731                         value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
732                         transport_fin(VTLS_S_FIN, PROTO_TLS);
733                         /* sctp */
734                         value_switch(VS_S, 'c', 'C', VS_C);
735                         value_switch(VS_C, 't', 'T', VS_T);
736                         value_switch(VS_T, 'p', 'P', VS_P_FIN);
737                         transport_fin(VS_P_FIN, PROTO_SCTP);
738                         /* ws */
739                         value_switch(VW_W, 's', 'S', VW_S_FIN);
740                         transport_fin(VW_S_FIN, PROTO_WS);
741                         
742                         /* ttl */
743                         param_switch(PTTL_T2,  'l', 'L', PTTL_L);
744                         param_switch1(PTTL_L,  '=', PTTL_eq);
745                         case PTTL_eq:
746                                 param=&uri->ttl;
747                                 param_val=&uri->ttl_val;
748                                 switch(*p){
749                                         param_common_cases;
750                                         default:
751                                                 v=p;
752                                                 state=URI_VAL_P;
753                                 }
754                                 break;
755                         
756                         /* user param */
757                         param_switch(PU_U, 's', 'S', PU_S);
758                         param_switch(PU_S, 'e', 'E', PU_E);
759                         param_switch(PU_E, 'r', 'R', PU_R);
760                         param_switch1(PU_R, '=', PU_eq);
761                         case PU_eq:
762                                 param=&uri->user_param;
763                                 param_val=&uri->user_param_val;
764                                 switch(*p){
765                                         param_common_cases;
766                                         default:
767                                                 v=p;
768                                                 state=URI_VAL_P;
769                                 }
770                                 break;
771                         
772                         /* method*/
773                         param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
774                         param_switch(PM_E, 't', 'T', PM_T);
775                         param_switch(PM_T, 'h', 'H', PM_H);
776                         param_switch(PM_H, 'o', 'O', PM_O);
777                         param_switch(PM_O, 'd', 'D', PM_D);
778                         param_switch1(PM_D, '=', PM_eq);
779                         case PM_eq:
780                                 param=&uri->method;
781                                 param_val=&uri->method_val;
782                                 switch(*p){
783                                         param_common_cases;
784                                         default:
785                                                 v=p;
786                                                 state=URI_VAL_P;
787                                 }
788                                 break;
789
790                         /*maddr*/
791                         param_switch(PMA_A,  'd', 'D', PMA_D);
792                         param_switch(PMA_D,  'd', 'D', PMA_D2);
793                         param_switch(PMA_D2, 'r', 'R', PMA_R);
794                         param_switch1(PMA_R, '=', PMA_eq);
795                         case PMA_eq:
796                                 param=&uri->maddr;
797                                 param_val=&uri->maddr_val;
798                                 switch(*p){
799                                         param_common_cases;
800                                         default:
801                                                 v=p;
802                                                 state=URI_VAL_P;
803                                 }
804                                 break;
805                         
806                         /* lr */
807                         param_switch(PLR_L,  'r', 'R', PLR_R_FIN);
808                         case PLR_R_FIN:
809                                 switch(*p){
810                                         case '@':
811                                                 still_at_user; 
812                                                 break;
813                                         case '=':
814                                                 state=PLR_eq;
815                                                 break;
816                                         semicolon_case; 
817                                                 uri->lr.s=b;
818                                                 uri->lr.len=(p-b);
819                                                 break;
820                                         question_case; 
821                                                 uri->lr.s=b;
822                                                 uri->lr.len=(p-b);
823                                                 break;
824                                         colon_case;
825                                                 break;
826                                         default:
827                                                 state=URI_PARAM_P;
828                                 }
829                                 break;
830                                 /* handle lr=something case */
831                         case PLR_eq:
832                                 param=&uri->lr;
833                                 param_val=&uri->lr_val;
834                                 switch(*p){
835                                         param_common_cases;
836                                         default:
837                                                 v=p;
838                                                 state=URI_VAL_P;
839                                 }
840                                 break;
841                         /* r2 */
842                         param_switch1(PR2_R,  '2', PR2_2_FIN);
843                         case PR2_2_FIN:
844                                 switch(*p){
845                                         case '@':
846                                                 still_at_user; 
847                                                 break;
848                                         case '=':
849                                                 state=PR2_eq;
850                                                 break;
851                                         semicolon_case; 
852                                                 uri->r2.s=b;
853                                                 uri->r2.len=(p-b);
854                                                 break;
855                                         question_case; 
856                                                 uri->r2.s=b;
857                                                 uri->r2.len=(p-b);
858                                                 break;
859                                         colon_case;
860                                                 break;
861                                         default:
862                                                 state=URI_PARAM_P;
863                                 }
864                                 break;
865                                 /* handle lr=something case */
866                         case PR2_eq:
867                                 param=&uri->r2;
868                                 param_val=&uri->r2_val;
869                                 switch(*p){
870                                         param_common_cases;
871                                         default:
872                                                 v=p;
873                                                 state=URI_VAL_P;
874                                 }
875                                 break;
876                         /* gr */
877                         param_switch(PGR_G,  'r', 'R', PGR_R_FIN);
878                         case PGR_R_FIN:
879                                 switch(*p){
880                                         case '@':
881                                                 still_at_user;
882                                                 break;
883                                         case '=':
884                                                 state=PGR_eq;
885                                                 break;
886                                         semicolon_case;
887                                                 uri->gr.s=b;
888                                                 uri->gr.len=(p-b);
889                                                 break;
890                                         question_case;
891                                                 uri->gr.s=b;
892                                                 uri->gr.len=(p-b);
893                                                 break;
894                                         colon_case;
895                                                 break;
896                                         default:
897                                                 state=URI_PARAM_P;
898                                 }
899                                 break;
900                                 /* handle gr=something case */
901                         case PGR_eq:
902                                 param=&uri->gr;
903                                 param_val=&uri->gr_val;
904                                 switch(*p){
905                                         param_common_cases;
906                                         default:
907                                                 v=p;
908                                                 state=URI_VAL_P;
909                                 }
910                                 break;
911
912 #ifdef USE_COMP
913                         param_switch(PCOMP_C,  'o', 'O' , PCOMP_O);
914                         param_switch(PCOMP_O,  'm', 'M' , PCOMP_M);
915                         param_switch(PCOMP_M,  'p', 'P' , PCOMP_P);
916                         param_switch1(PCOMP_P,  '=', PCOMP_eq);
917                         /* value */
918                         case PCOMP_eq:
919                                 param=&comp_str;
920                                 param_val=&comp_val;
921                                 switch (*p){
922                                         param_common_cases;
923                                         case 's':
924                                         case 'S':
925                                                 v=p;
926                                                 state=VCOMP_S;
927                                                 break;
928                                         default:
929                                                 v=p;
930                                                 state=URI_VAL_P;
931                                 }
932                                 break;
933                         /* sigcomp*/
934                         value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
935                                                                         VCOMP_SIGC_I, VCOMP_SGZ_E);
936                         value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
937                         value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
938                         value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
939                         value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
940                         value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
941                         comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
942                         
943                         /* sergz*/
944                         value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
945                         value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
946                         value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
947                         comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
948 #endif
949                                 
950                                 
951                                 
952                         case URI_HEADERS:
953                                 /* for now nobody needs them so we completely ignore the 
954                                  * headers (they are not allowed in request uri) --andrei */
955                                 switch(*p){
956                                         case '@':
957                                                 /* yak, we are still at user */
958                                                 still_at_user;
959                                                 break;
960                                         case ';':
961                                                 /* we might be still parsing user, try it */
962                                                 if (found_user) goto error_bad_char;
963                                                 error_headers=1; /* if this is not the user
964                                                                                         we have an error */
965                                                 /* if pass is set => it cannot be user:pass
966                                                  * => error (';') is illegal in a header */
967                                                 if (pass) goto error_headers;
968                                                 break;
969                                         case ':':
970                                                 if (found_user==0){
971                                                         /*might be pass but only if user not found yet*/
972                                                         if (pass){
973                                                                 found_user=1; /* no user */
974                                                                 pass=0;
975                                                         }else{
976                                                                 pass=p;
977                                                         }
978                                                 }
979                                                 break;
980                                         case '?':
981                                                 if (pass){
982                                                         found_user=1; /* no user, pass cannot contain '?'*/
983                                                         pass=0;
984                                                 }
985                                                 break;
986                                 }
987                                 break;
988                         default:
989                                 goto error_bug;
990                 }
991         }
992         /*end of uri */
993         switch (state){
994                 case URI_INIT: /* error empty uri */
995                         goto error_too_short;
996                 case URI_USER:
997                         /* this is the host, it can't be the user */
998                         if (found_user) goto error_bad_uri;
999                         uri->host.s=s;
1000                         uri->host.len=p-s;
1001                         state=URI_HOST;
1002                         break;
1003                 case URI_PASSWORD:
1004                         /* this is the port, it can't be the passwd */
1005                         if (found_user) goto error_bad_port;
1006                         uri->port.s=s;
1007                         uri->port.len=p-s;
1008                         uri->port_no=port_no;
1009                         uri->host=uri->user;
1010                         uri->user.s=0;
1011                         uri->user.len=0;
1012                         break;
1013                 case URI_PASSWORD_ALPHA:
1014                         /* it might be an urn, check scheme and set host */
1015                         if (scheme==URN_SCH){
1016                                 uri->host.s=s;
1017                                 uri->host.len=p-s;
1018                                 DBG("parsed urn scheme...\n");
1019                         /* this is the port, it can't be the passwd */
1020                         }else goto error_bad_port;
1021                 case URI_HOST_P:
1022                 case URI_HOST6_END:
1023                         uri->host.s=s;
1024                         uri->host.len=p-s;
1025                         break;
1026                 case URI_HOST: /* error: null host */
1027                 case URI_HOST6_P: /* error: unterminated ipv6 reference*/
1028                         goto error_bad_host;
1029                 case URI_PORT:
1030                         uri->port.s=s;
1031                         uri->port.len=p-s;
1032                         uri->port_no=port_no;
1033                         break;
1034                 case URI_PARAM:
1035                 case URI_PARAM_P:
1036                 /* intermediate param states */
1037                 case PT_T: /* transport */
1038                 case PT_R:
1039                 case PT_A:
1040                 case PT_N:
1041                 case PT_S:
1042                 case PT_P:
1043                 case PT_O:
1044                 case PT_R2:
1045                 case PT_T2:
1046                 case PT_eq: /* ignore empty transport params */
1047                 case PTTL_T2: /* ttl */
1048                 case PTTL_L:
1049                 case PTTL_eq:
1050                 case PU_U:  /* user */
1051                 case PU_S:
1052                 case PU_E:
1053                 case PU_R:
1054                 case PU_eq:
1055                 case PM_M: /* method */
1056                 case PM_E:
1057                 case PM_T:
1058                 case PM_H:
1059                 case PM_O:
1060                 case PM_D:
1061                 case PM_eq:
1062                 case PLR_L: /* lr */
1063                 case PR2_R: /* r2 */
1064                 case PGR_G: /* gr */
1065 #ifdef USE_COMP
1066                 case PCOMP_C:
1067                 case PCOMP_O:
1068                 case PCOMP_M:
1069                 case PCOMP_P:
1070                 case PCOMP_eq:
1071 #endif
1072                         uri->params.s=s;
1073                         uri->params.len=p-s;
1074                         break;
1075                 /* fin param states */
1076                 case PLR_R_FIN:
1077                 case PLR_eq:
1078                         uri->params.s=s;
1079                         uri->params.len=p-s;
1080                         uri->lr.s=b;
1081                         uri->lr.len=p-b;
1082                         break;
1083                 case PR2_2_FIN:
1084                 case PR2_eq:
1085                         uri->params.s=s;
1086                         uri->params.len=p-s;
1087                         uri->r2.s=b;
1088                         uri->r2.len=p-b;
1089                         break;
1090                 case PGR_R_FIN:
1091                 case PGR_eq:
1092                         uri->params.s=s;
1093                         uri->params.len=p-s;
1094                         uri->gr.s=b;
1095                         uri->gr.len=p-b;
1096                         break;
1097                 case URI_VAL_P:
1098                 /* intermediate value states */
1099                 case VU_U:
1100                 case VU_D:
1101                 case VT_T:
1102                 case VT_C:
1103                 case VTLS_L:
1104                 case VS_S:
1105                 case VS_C:
1106                 case VS_T:
1107                 case VW_W:
1108                         uri->params.s=s;
1109                         uri->params.len=p-s;
1110                         param_set(b, v);
1111                         break;
1112 #ifdef USE_COMP
1113                 case VCOMP_S:
1114                 case VCOMP_SIGC_I:
1115                 case VCOMP_SIGC_G:
1116                 case VCOMP_SIGC_C:
1117                 case VCOMP_SIGC_O:
1118                 case VCOMP_SIGC_M:
1119                 case VCOMP_SGZ_E:
1120                 case VCOMP_SGZ_R:
1121                 case VCOMP_SGZ_G:
1122                         /* unrecognized comp method, assume none */
1123                         uri->params.s=s;
1124                         uri->params.len=p-s;
1125                         /* uri->comp=COMP_NONE ; */
1126                         break;
1127 #endif
1128                 /* fin value states */
1129                 case VU_P_FIN:
1130                         uri->params.s=s;
1131                         uri->params.len=p-s;
1132                         param_set(b, v);
1133                         uri->proto=PROTO_UDP;
1134                         break;
1135                 case VT_P_FIN:
1136                         uri->params.s=s;
1137                         uri->params.len=p-s;
1138                         param_set(b, v);
1139                         uri->proto=PROTO_TCP;
1140                         break;
1141                 case VTLS_S_FIN:
1142                         uri->params.s=s;
1143                         uri->params.len=p-s;
1144                         param_set(b, v);
1145                         uri->proto=PROTO_TLS;
1146                         break;
1147                 case VS_P_FIN:
1148                         uri->params.s=s;
1149                         uri->params.len=p-s;
1150                         param_set(b, v);
1151                         uri->proto=PROTO_SCTP;
1152                         break;
1153                 case VW_S_FIN:
1154                         uri->params.s=s;
1155                         uri->params.len=p-s;
1156                         param_set(b, v);
1157                         uri->proto=PROTO_WS;
1158                         break;
1159 #ifdef USE_COMP
1160                 case VCOMP_SIGC_P_FIN:
1161                         uri->params.s=s;
1162                         uri->params.len=p-s;
1163                         /* param_set(b, v); */
1164                         uri->comp=COMP_SIGCOMP;
1165                         break;
1166                 case VCOMP_SGZ_Z_FIN:
1167                         uri->params.s=s;
1168                         uri->params.len=p-s;
1169                         /* param_set(b, v); */
1170                         uri->comp=COMP_SERGZ;
1171                         break;
1172 #endif
1173                 /* headers */
1174                 case URI_HEADERS:
1175                         uri->headers.s=s;
1176                         uri->headers.len=p-s;
1177                         if (error_headers) goto error_headers;
1178                         break;
1179                 default:
1180                         goto error_bug;
1181         }
1182         switch(uri->type){
1183                 case SIPS_URI_T:
1184                 case SIP_URI_T:
1185                         /* save the original sip: URI parameters in sip_params */
1186                         uri->sip_params=uri->params;
1187                         if ((phone2tel) &&
1188                              (uri->user_param_val.len == 5) &&
1189                                  (strncmp(uri->user_param_val.s, "phone", 5) == 0)
1190                                 ) {
1191                                 uri->type = TEL_URI_T;
1192                                 uri->flags |= URI_SIP_USER_PHONE;
1193                                 /* move params from user into uri->params */
1194                                 p=q_memchr(uri->user.s, ';', uri->user.len);
1195                                 if (p){
1196                                         /* NOTE: 
1197                                          * specialized uri params (user, maddr, etc.) still hold
1198                                          * the values from the sip-uri envelope
1199                                          * while uri->params point to the params in the embedded tel uri
1200                                          */
1201                                         uri->params.s=p+1;
1202                                         uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1203                                         uri->user.len=p-uri->user.s;
1204                                 } else {
1205                                         uri->params.s=0;
1206                                         uri->params.len=0;
1207                                 }
1208                         } else {
1209                                 uri->flags&=~URI_USER_NORMALIZE;
1210                         }
1211                         break;
1212                 case TEL_URI_T:
1213                 case TELS_URI_T:
1214                         /* fix tel uris, move the number in uri and empty the host */
1215                         uri->user=uri->host;
1216                         uri->host.s="";
1217                         uri->host.len=0;
1218                         break;
1219                 /* urn: do nothing */
1220                 case URN_URI_T:
1221                         break;
1222                 case ERROR_URI_T:
1223                         LOG(L_ERR, "ERROR: parse_uri unexpected error (BUG?)\n"); 
1224                         goto error_bad_uri;
1225                         break; /* do nothing, avoids a compilation warning */
1226         }
1227 #ifdef EXTRA_DEBUG
1228         /* do stuff */
1229         DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
1230                         " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
1231                         " headers=<%.*s>(%d)\n",
1232                         uri->type,
1233                         uri->user.len, ZSW(uri->user.s), uri->user.len,
1234                         uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
1235                         uri->host.len, ZSW(uri->host.s), uri->host.len,
1236                         uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
1237                         uri->params.len, ZSW(uri->params.s), uri->params.len,
1238                         uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1239                 );
1240         DBG(" uri flags : ");
1241                 if (uri->flags & URI_USER_NORMALIZE) DBG("user_need_norm ");
1242                 if (uri->flags & URI_SIP_USER_PHONE) DBG("sip_user_phone ");
1243                 DBG("   value=%d\n",uri->flags);
1244         DBG(" uri params:\n   transport=<%.*s>, val=<%.*s>, proto=%d\n",
1245                         uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1246                         ZSW(uri->transport_val.s), uri->proto);
1247         DBG("   user-param=<%.*s>, val=<%.*s>\n",
1248                         uri->user_param.len, ZSW(uri->user_param.s), 
1249                         uri->user_param_val.len, ZSW(uri->user_param_val.s));
1250         DBG("   method=<%.*s>, val=<%.*s>\n",
1251                         uri->method.len, ZSW(uri->method.s), 
1252                         uri->method_val.len, ZSW(uri->method_val.s));
1253         DBG("   ttl=<%.*s>, val=<%.*s>\n",
1254                         uri->ttl.len, ZSW(uri->ttl.s), 
1255                         uri->ttl_val.len, ZSW(uri->ttl_val.s));
1256         DBG("   maddr=<%.*s>, val=<%.*s>\n",
1257                         uri->maddr.len, ZSW(uri->maddr.s), 
1258                         uri->maddr_val.len, ZSW(uri->maddr_val.s));
1259         DBG("   lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s)); 
1260         DBG("   r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1261 #ifdef USE_COMP
1262         DBG("   comp=%d\n", uri->comp);
1263 #endif
1264
1265 #endif
1266         return 0;
1267         
1268 error_too_short:
1269         DBG("parse_uri: uri too short: <%.*s> (%d)\n",
1270                 len, ZSW(buf), len);
1271         goto error_exit;
1272 error_bad_char:
1273         DBG("parse_uri: bad char '%c' in state %d"
1274                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1275                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1276                 len, ZSW(buf), len);
1277         goto error_exit;
1278 error_bad_host:
1279         DBG("parse_uri: bad host in uri (error at char %c in"
1280                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1281                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1282                 len, ZSW(buf), len);
1283         goto error_exit;
1284 error_bad_port:
1285         DBG("parse_uri: bad port in uri (error at char %c in"
1286                 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1287                 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1288                 len, ZSW(buf), len);
1289         goto error_exit;
1290 error_bad_uri:
1291         DBG("parse_uri: bad uri,  state %d"
1292                 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1293                 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
1294                 ZSW(buf), len);
1295         goto error_exit;
1296 error_headers:
1297         DBG("parse_uri: bad uri headers: <%.*s>(%d)"
1298                 " / <%.*s>(%d)\n",
1299                 uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1300                 len, ZSW(buf), len);
1301         goto error_exit;
1302 error_bug:
1303         LOG(L_CRIT, "BUG: parse_uri: bad  state %d"
1304                         " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1305                          state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
1306 error_exit:
1307         ser_error=E_BAD_URI;
1308         uri->type=ERROR_URI_T;
1309         STATS_BAD_URI();
1310         return E_BAD_URI;
1311 }
1312
1313
1314 static inline int _parse_ruri(str *uri,
1315         int *status, struct sip_uri *parsed_uri)
1316 {
1317         if (*status) return 1;
1318
1319         if (parse_uri(uri->s, uri->len, parsed_uri)<0) {
1320                 LOG(L_ERR, "ERROR: _parse_ruri: bad uri <%.*s>\n", 
1321                                 uri->len, ZSW(uri->s));
1322                 *status=0;
1323                 return -1;
1324         }
1325         *status=1;
1326         return 1;
1327 }
1328
1329 int parse_sip_msg_uri(struct sip_msg* msg)
1330 {
1331         char* tmp;
1332         int tmp_len;
1333         if (msg->parsed_uri_ok) return 1;
1334
1335         if (msg->new_uri.s){
1336                 tmp=msg->new_uri.s;
1337                 tmp_len=msg->new_uri.len;
1338         }else{
1339                 tmp=msg->first_line.u.request.uri.s;
1340                 tmp_len=msg->first_line.u.request.uri.len;
1341         }
1342         if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1343                 DBG("ERROR: parse_sip_msg_uri: bad uri <%.*s>\n",
1344                         tmp_len, tmp);
1345                 msg->parsed_uri_ok=0;
1346                 return -1;
1347         }
1348         msg->parsed_uri_ok=1;
1349         return 1;
1350 }
1351
1352 int parse_orig_ruri(struct sip_msg* msg)
1353 {
1354         int ret;
1355
1356         ret=_parse_ruri(&REQ_LINE(msg).uri,
1357                 &msg->parsed_orig_ruri_ok, &msg->parsed_orig_ruri);
1358         if (ret<0) LOG(L_ERR, "ERROR: parse_orig_ruri failed\n");
1359         return ret;
1360 }
1361
1362 inline int normalize_tel_user(char* res, str* src) {
1363         int i, l;
1364         l=0;
1365         for (i=0; i<src->len; i++) {
1366                 switch (src->s[i]) {
1367                         case '-':
1368                         case '.':
1369                         case '(':
1370                         case ')':
1371                                 break;
1372                         default:
1373                                 res[l++]=src->s[i];
1374                 }
1375         }  
1376         return l;
1377 }
1378
1379
1380 str     s_sip  = STR_STATIC_INIT("sip");
1381 str     s_sips = STR_STATIC_INIT("sips");
1382 str     s_tel  = STR_STATIC_INIT("tel");
1383 str     s_tels = STR_STATIC_INIT("tels");
1384 str     s_urn  = STR_STATIC_INIT("urn");
1385 static str      s_null = STR_STATIC_INIT("");
1386
1387 inline void uri_type_to_str(uri_type type, str *s) {
1388         switch (type) {
1389         case SIP_URI_T:
1390                 *s = s_sip;
1391                 break;
1392         case SIPS_URI_T:
1393                 *s = s_sips;
1394                 break;
1395         case TEL_URI_T:
1396                 *s = s_tel;
1397                 break;
1398         case TELS_URI_T:
1399                 *s = s_tels;
1400                 break;
1401         case URN_URI_T:
1402                 *s = s_urn;
1403                 break;
1404         default:
1405                 *s = s_null;
1406         }
1407 }
1408
1409 static str      s_udp  = STR_STATIC_INIT("udp");
1410 static str      s_tcp  = STR_STATIC_INIT("tcp");
1411 static str      s_tls  = STR_STATIC_INIT("tls");
1412 static str      s_sctp = STR_STATIC_INIT("sctp");
1413 static str      s_ws   = STR_STATIC_INIT("ws");
1414
1415 inline void proto_type_to_str(unsigned short type, str *s) {
1416         switch (type) {
1417         case PROTO_UDP:
1418                 *s = s_udp;
1419                 break;
1420         case PROTO_TCP:
1421                 *s = s_tcp;
1422                 break;
1423         case PROTO_TLS:
1424                 *s = s_tls;
1425                 break;
1426         case PROTO_SCTP:
1427                 *s = s_sctp;
1428                 break;
1429         case PROTO_WS:
1430         case PROTO_WSS:
1431                 *s = s_ws;
1432                 break;
1433         default:
1434                 *s = s_null;
1435         }
1436 }