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