1 /*
2 	belle-sip - SIP (RFC3261) library.
3     Copyright (C) 2010  Belledonne Communications SARL
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "belle-sip/sip-uri.h"
20 #include "belle-sip/parameters.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include "grammars/belle_sip_messageParser.h"
25 #include "grammars/belle_sip_messageLexer.h"
26 #include "belle_sip_internal.h"
27 #include "listeningpoint_internal.h"
28 
29 
30 #define SIP_URI_GET_SET_STRING(attribute) GET_SET_STRING(belle_sip_uri,attribute)
31 #define SIP_URI_GET_SET_STRING_PARAM(attribute) GET_SET_STRING_PARAM2(belle_sip_uri,attribute,attribute##_param)
32 
33 
34 #define SIP_URI_GET_SET_UINT(attribute) GET_SET_INT(belle_sip_uri,attribute,unsigned int)
35 #define SIP_URI_GET_SET_INT(attribute) GET_SET_INT(belle_sip_uri,attribute,int)
36 #define SIP_URI_GET_SET_INT_PARAM(attribute) GET_SET_INT_PARAM2(belle_sip_uri,attribute,int,attribute##_param)
37 
38 
39 #define SIP_URI_GET_SET_BOOL(attribute) GET_SET_BOOL(belle_sip_uri,attribute,is)
40 #define SIP_URI_HAS_SET_BOOL(attribute) GET_SET_BOOL(belle_sip_uri,attribute,has)
41 #define SIP_URI_HAS_SET_BOOL_PARAM(attribute) GET_SET_BOOL_PARAM2(belle_sip_uri,attribute,has,attribute##_param)
42 
43 
44 
45 struct _belle_sip_uri {
46 	belle_sip_parameters_t params;
47 	unsigned int secure;
48 	char* user;
49 	char* user_password;
50 	char* host;
51 	int port;
52 	belle_sip_parameters_t * header_list;
53 };
54 
belle_sip_uri_destroy(belle_sip_uri_t * uri)55 static void belle_sip_uri_destroy(belle_sip_uri_t* uri) {
56 	if (uri->user) belle_sip_free (uri->user);
57 	if (uri->host) belle_sip_free (uri->host);
58 	if (uri->user_password) belle_sip_free (uri->user_password);
59 	belle_sip_object_unref(BELLE_SIP_OBJECT(uri->header_list));
60 }
61 
belle_sip_uri_clone(belle_sip_uri_t * uri,const belle_sip_uri_t * orig)62 static void belle_sip_uri_clone(belle_sip_uri_t* uri, const belle_sip_uri_t *orig){
63 	uri->secure=orig->secure;
64 	uri->user=orig->user?belle_sip_strdup(orig->user):NULL;
65 	uri->user_password=orig->user_password?belle_sip_strdup(orig->user_password):NULL;
66 	uri->host=orig->host?belle_sip_strdup(orig->host):NULL;
67 	uri->port=orig->port;
68 	if (orig->header_list){
69 		uri->header_list=(belle_sip_parameters_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(orig->header_list));
70 		belle_sip_object_ref(uri->header_list);
71 	}
72 
73 }
74 
encode_params(belle_sip_param_pair_t * container,belle_sip_list_t ** newlist)75 static void encode_params(belle_sip_param_pair_t* container, belle_sip_list_t** newlist) {
76 	char *escapedName = belle_sip_uri_to_escaped_parameter(container->name);
77 	char *escapedValue = container->value? belle_sip_uri_to_escaped_parameter(container->value) : NULL;
78 	*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
79 	if (escapedName) free(escapedName);
80 	if (escapedValue) free(escapedValue);
81 }
82 
encode_headers(belle_sip_param_pair_t * container,belle_sip_list_t ** newlist)83 static void encode_headers(belle_sip_param_pair_t* container, belle_sip_list_t** newlist) {
84 	char *escapedName = belle_sip_uri_to_escaped_header(container->name);
85 	char *escapedValue = container->value? belle_sip_uri_to_escaped_header(container->value) : NULL;
86 	*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
87 	if (escapedName) free(escapedName);
88 	if (escapedValue) free(escapedValue);
89 }
90 
belle_sip_uri_marshal(const belle_sip_uri_t * uri,char * buff,size_t buff_size,size_t * offset)91 belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buff, size_t buff_size, size_t *offset) {
92 	const belle_sip_list_t* list;
93 	belle_sip_error_code error=BELLE_SIP_OK;
94 
95 	error=belle_sip_snprintf(buff,buff_size,offset,"%s:",uri->secure?"sips":"sip");
96 	if (error!=BELLE_SIP_OK) return error;
97 
98 	if (uri->user && uri->user[0]!='\0') {
99 		char* escaped_username=belle_sip_uri_to_escaped_username(uri->user);
100 		error=belle_sip_snprintf(buff,buff_size,offset,"%s",escaped_username);
101 		belle_sip_free(escaped_username);
102 		if (error!=BELLE_SIP_OK) return error;
103 
104 		if (uri->user_password) {
105 			char* escaped_password=belle_sip_uri_to_escaped_userpasswd(uri->user_password);
106 			error=belle_sip_snprintf(buff,buff_size,offset,":%s",escaped_password);
107 			belle_sip_free(escaped_password);
108 			if (error!=BELLE_SIP_OK) return error;
109 		}
110 		error=belle_sip_snprintf(buff,buff_size,offset,"@");
111 		if (error!=BELLE_SIP_OK) return error;
112 
113 	}
114 
115 	if (uri->host) {
116 		if (strchr(uri->host,':')) { /*ipv6*/
117 			error=belle_sip_snprintf(buff,buff_size,offset,"[%s]",uri->host);
118 		} else {
119 			error=belle_sip_snprintf(buff,buff_size,offset,"%s",uri->host);
120 		}
121 		if (error!=BELLE_SIP_OK) return error;
122 	} else {
123 		belle_sip_warning("no host found in this uri");
124 	}
125 
126 	if (uri->port!=0) {
127 		error=belle_sip_snprintf(buff,buff_size,offset,":%i",uri->port);
128 		if (error!=BELLE_SIP_OK) return error;
129 	}
130 
131 	{
132 		belle_sip_parameters_t *encparams = belle_sip_parameters_new();
133 		belle_sip_list_for_each2(uri->params.param_list, (void (*)(void *, void *))encode_params, &encparams->param_list);
134 		error=belle_sip_parameters_marshal(encparams,buff,buff_size,offset);
135 		belle_sip_object_unref(encparams);
136 		if (error!=BELLE_SIP_OK) return error;
137 	}
138 
139 	{
140 		belle_sip_list_t * encheaders = NULL;
141 		belle_sip_list_for_each2(uri->header_list->param_list, (void (*)(void *, void *))encode_headers, &encheaders);
142 
143 		for(list=encheaders;list!=NULL;list=list->next){
144 			belle_sip_param_pair_t* container = list->data;
145 			if (list == encheaders) {
146 				//first case
147 				error=belle_sip_snprintf(buff,buff_size,offset,"?%s=%s",container->name,container->value?container->value:"");
148 			} else {
149 				//subsequent headers
150 				error=belle_sip_snprintf(buff,buff_size,offset,"&%s=%s",container->name,container->value?container->value:"");
151 			}
152 			if (error!=BELLE_SIP_OK) break;
153 		}
154 		belle_sip_list_free_with_data(encheaders,(void (*)(void*))belle_sip_param_pair_destroy);
155 	}
156 
157 	return error;
158 }
159 
160 BELLE_SIP_PARSE(uri);
161 
162 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_uri_t);
163 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_uri_t,belle_sip_parameters_t,belle_sip_uri_destroy,belle_sip_uri_clone,belle_sip_uri_marshal,TRUE);
164 
165 
belle_sip_uri_new()166 belle_sip_uri_t* belle_sip_uri_new () {
167 	belle_sip_uri_t* l_object = belle_sip_object_new(belle_sip_uri_t);
168 	belle_sip_parameters_init((belle_sip_parameters_t*)l_object); /*super*/
169 	l_object->header_list = belle_sip_parameters_new();
170 	belle_sip_object_ref(l_object->header_list);
171 	return l_object;
172 }
173 
belle_sip_uri_create(const char * username,const char * host)174 belle_sip_uri_t* belle_sip_uri_create (const char* username,const char* host) {
175 	belle_sip_uri_t* uri = belle_sip_uri_new();
176 	belle_sip_uri_set_user(uri,username);
177 	belle_sip_uri_set_host(uri,host);
178 	return uri;
179 }
180 
181 
belle_sip_uri_to_string(const belle_sip_uri_t * uri)182 char* belle_sip_uri_to_string(const belle_sip_uri_t* uri)  {
183 	return belle_sip_object_to_string(BELLE_SIP_OBJECT(uri));
184 }
185 
186 
belle_sip_uri_get_header(const belle_sip_uri_t * uri,const char * name)187 const char* belle_sip_uri_get_header(const belle_sip_uri_t* uri,const char* name) {
188 	return belle_sip_parameters_get_parameter(uri->header_list,name);
189 }
190 
belle_sip_uri_set_header(belle_sip_uri_t * uri,const char * name,const char * value)191 void belle_sip_uri_set_header(belle_sip_uri_t* uri,const char* name,const char* value) {
192 	belle_sip_parameters_set_parameter(uri->header_list,name,value);
193 }
194 
belle_sip_uri_remove_header(belle_sip_uri_t * uri,const char * name)195 void belle_sip_uri_remove_header(belle_sip_uri_t *uri, const char *name){
196 	belle_sip_parameters_remove_parameter(uri->header_list,name);
197 }
198 
belle_sip_uri_get_header_names(const belle_sip_uri_t * uri)199 const belle_sip_list_t*	belle_sip_uri_get_header_names(const belle_sip_uri_t* uri) {
200 	return belle_sip_parameters_get_parameter_names(uri->header_list);
201 }
202 
belle_sip_uri_get_listening_port(const belle_sip_uri_t * uri)203 int belle_sip_uri_get_listening_port(const belle_sip_uri_t *uri){
204 	int port=belle_sip_uri_get_port(uri);
205 	const char *transport=belle_sip_uri_get_transport_param(uri);
206 	if (!transport) {
207 		transport=belle_sip_uri_is_secure(uri)?"tls":"udp";
208 	}
209 	if (port==0)
210 		port=belle_sip_listening_point_get_well_known_port(transport);
211 	return port;
212 }
213 
belle_sip_uri_fix(belle_sip_uri_t * uri)214 void belle_sip_uri_fix(belle_sip_uri_t *uri){
215 	/*nop, to be removed*/
216 }
217 
218 SIP_URI_GET_SET_BOOL(secure)
219 
SIP_URI_GET_SET_STRING(user)220 SIP_URI_GET_SET_STRING(user)
221 SIP_URI_GET_SET_STRING(user_password)
222 SIP_URI_GET_SET_STRING(host)
223 SIP_URI_GET_SET_INT(port)
224 
225 SIP_URI_GET_SET_STRING_PARAM(transport)
226 SIP_URI_GET_SET_STRING_PARAM(user)
227 SIP_URI_GET_SET_STRING_PARAM(method)
228 SIP_URI_GET_SET_STRING_PARAM(maddr)
229 SIP_URI_GET_SET_INT_PARAM(ttl)
230 SIP_URI_HAS_SET_BOOL_PARAM(lr)
231 
232 
233 const belle_sip_parameters_t*	belle_sip_uri_get_headers(const belle_sip_uri_t* uri) {
234 	return uri->header_list;
235 }
236 
237 
belle_sip_uri_headers_clean(belle_sip_uri_t * uri)238 void belle_sip_uri_headers_clean(belle_sip_uri_t* uri) {
239 	belle_sip_parameters_clean(uri->header_list);
240 }
241 
242 
uri_strcmp(const char * a,const char * b,int case_sensitive)243 static int uri_strcmp(const char*a,const char*b,int case_sensitive) {
244 	int result = 0;
245 	size_t index_a=0,index_b=0;
246 	char char_a,char_b;
247 
248 	if (a == NULL && b == NULL) {
249 		goto end;
250 	}
251 	if ((a != NULL && b == NULL) || (a == NULL && b != NULL)){
252 		result = 1;
253 		goto end;
254 	}
255 
256 	do {
257 		index_a+=belle_sip_get_char(a+index_a,&char_a);
258 		index_b+=belle_sip_get_char(b+index_b,&char_b);
259 		if (!case_sensitive && char_a<0x7B && char_a>0x60) char_a-=0x20;
260 		if (!case_sensitive && char_b<0x7B && char_b>0x60) char_b-=0x20;
261 		result=(char_a!=char_b);
262 		if (result) break;
263 		if (char_a == '\0' || char_b == '\0') break;
264 	}while(1);
265 end:
266 	return result;
267 }
268 
269 #define IS_EQUAL(a,b) (uri_strcmp(a,b,TRUE)==0)
270 
271 #define IS_EQUAL_CASE(a,b) (uri_strcmp(a,b,FALSE)==0)
272 #define PARAM_CASE_CMP(uri_a,uri_b,param) \
273 		a_param=belle_sip_parameters_get_case_parameter((belle_sip_parameters_t*) uri_a,param); \
274 		b_param=belle_sip_parameters_get_case_parameter((belle_sip_parameters_t*) uri_b,param);\
275 		if (!IS_EQUAL_CASE(a_param,b_param)) return 0;
276 
277 /*
278  * RFC 3261            SIP: Session Initiation Protocol           June 2002
279  * 19.1.4 URI Comparison
280 
281    Some operations in this specification require determining whether two
282    SIP or SIPS URIs are equivalent.  In this specification, registrars
283    need to compare bindings in Contact URIs in REGISTER requests (see
284    Section 10.3.).  SIP and SIPS URIs are compared for equality
285    according to the following rules:
286 */
belle_sip_uri_equals(const belle_sip_uri_t * uri_a,const belle_sip_uri_t * uri_b)287 int belle_sip_uri_equals(const belle_sip_uri_t* uri_a,const belle_sip_uri_t* uri_b) {
288 	const belle_sip_list_t *	params;
289 	const char* b_param;
290 	const char* a_param;
291 /*
292       o  A SIP and SIPS URI are never equivalent.
293 */
294 	if (belle_sip_uri_is_secure(uri_a)!=belle_sip_uri_is_secure(uri_b)) {
295 		return 0;
296 	}
297 /*
298 	o  Comparison of the userinfo of SIP and SIPS URIs is case-
299          sensitive.  This includes userinfo containing passwords or
300          formatted as telephone-subscribers.  Comparison of all other
301          components of the URI is case-insensitive unless explicitly
302          defined otherwise.
303 */
304 	if (!IS_EQUAL(uri_a->user,uri_b->user)) return 0;
305 
306 /*
307       o  The ordering of parameters and header fields is not significant
308          in comparing SIP and SIPS URIs.
309 
310       o  Characters other than those in the "reserved" set (see RFC 2396
311          [5]) are equivalent to their ""%" HEX HEX" encoding.
312 
313       o  An IP address that is the result of a DNS lookup of a host name
314          does not match that host name.
315 
316       o  For two URIs to be equal, the user, password, host, and port
317          components must match.
318 */
319 	if (!IS_EQUAL_CASE(uri_a->host,uri_b->host)) {
320 		return 0;
321 	}
322 	if (uri_a->port != uri_b->port) return 0;
323 /*
324          A URI omitting the user component will not match a URI that
325          includes one.  A URI omitting the password component will not
326          match a URI that includes one.
327 
328          A URI omitting any component with a default value will not
329          match a URI explicitly containing that component with its
330          default value.  For instance, a URI omitting the optional port
331          component will not match a URI explicitly declaring port 5060.
332          The same is true for the transport-parameter, ttl-parameter,
333          user-parameter, and method components.
334 
335             Defining sip:user@host to not be equivalent to
336             sip:user@host:5060 is a change from RFC 2543.  When deriving
337             addresses from URIs, equivalent addresses are expected from
338             equivalent URIs.  The URI sip:user@host:5060 will always
339             resolve to port 5060.  The URI sip:user@host may resolve to
340             other ports through the DNS SRV mechanisms detailed in [4].
341 
342       o  URI uri-parameter components are compared as follows:
343 
344          -  Any uri-parameter appearing in both URIs must match.
345 */
346 /*
347  *         -  A user, ttl, or method uri-parameter appearing in only one
348             URI never matches, even if it contains the default value.
349            -  A URI that includes an maddr parameter will not match a URI
350             that contains no maddr parameter.
351  * */
352 	PARAM_CASE_CMP(uri_a,uri_b,"transport")
353 	PARAM_CASE_CMP(uri_a,uri_b,"user")
354 	PARAM_CASE_CMP(uri_a,uri_b,"ttl")
355 	PARAM_CASE_CMP(uri_a,uri_b,"method")
356 	PARAM_CASE_CMP(uri_a,uri_b,"maddr")
357 
358 
359 	for(params=belle_sip_parameters_get_parameters((belle_sip_parameters_t*) uri_a);params!=NULL;params=params->next) {
360 		if ((b_param=belle_sip_parameters_get_parameter((belle_sip_parameters_t*) uri_b,(const char*)params->data)) != NULL) {
361 			if (!IS_EQUAL_CASE(b_param,(const char*)params->data)) return 0;
362 		}
363 	}
364 
365  /*
366 
367 
368          -  All other uri-parameters appearing in only one URI are
369             ignored when comparing the URIs.
370 */
371 /* *fixme ignored for now*/
372 /*
373       o  URI header components are never ignored.  Any present header
374          component MUST be present in both URIs and match for the URIs
375          to match.  The matching rules are defined for each header field
376          in Section 20.
377  */
378 	return 1;
379 }
380 
381 /*uri checker*/
382 
383 
384 /*
385  * From 19.1.1 SIP and SIPS URI Components
386  * 									   				dialog
387 										reg./redir. Contact/
388 			default  Req.-URI  To  From  Contact   R-R/Route  external
389 user          --          o      o    o       o          o         o
390 password      --          o      o    o       o          o         o
391 host          --          m      m    m       m          m         m
392 port          (1)         o      -    -       o          o         o
393 user-param    ip          o      o    o       o          o         o
394 method        INVITE      -      -    -       -          -         o
395 maddr-param   --          o      -    -       o          o         o
396 ttl-param     1           o      -    -       o          -         o
397 transp.-param (2)         o      -    -       o          o         o
398 lr-param      --          o      -    -       -          o         o
399 other-param   --          o      o    o       o          o         o
400 headers       --          -      -    -       o          -         o
401 
402 (1): The default port value is transport and scheme dependent.  The
403 default  is  5060  for  sip: using UDP, TCP, or SCTP.  The default is
404 5061 for sip: using TLS over TCP and sips: over TCP.
405 
406 (2): The default transport is scheme dependent.  For sip:, it is UDP.
407 For sips:, it is TCP.
408 
409 Table 1: Use and default values of URI components for SIP header
410 field values, Request-URI and references*/
411 
412 
413 typedef enum {
414 	m /*mandotory*/
415 	, o /*optionnal*/
416 	, na /*not allowd*/
417 } mark;
418 
mark_to_string(mark value)419 static const char* mark_to_string(mark value) {
420 	switch (value) {
421 	case o: return "optionnal";
422 	case m: return "mandatory";
423 	case na: return "not allowed";
424 	}
425 	return "unknown";
426 }
427 
428 typedef struct uri_components {
429 	const char * name;
430 	mark user;
431 	mark password;
432 	mark host;
433 	mark port;
434 	mark user_param;
435 	mark method;
436 	mark maddr_param;
437 	mark ttl_param;
438 	mark transp_param;
439 	mark lr_param;
440 	mark other_param;
441 	mark headers;
442 } uri_components_t;
443 
444 
445 /*belle sip allows contact header without host because stack will auutomatically put host if missing*/
446 static  uri_components_t uri_component_use_for_request = 			{"Req.-URI"					,o	,o	,m	,o	,o	,na	,o	,o	,o	,o	,o	,na};
447 static  uri_components_t uri_component_use_for_header_to = 			{"Header To"				,o	,o	,m	,na	,o	,na	,na	,na	,na	,na	,o	,na};
448 static  uri_components_t uri_component_use_for_header_from = 		{"Header From"				,o	,o	,m	,na	,o	,na	,na	,na	,na	,na	,o	,na};
449 static  uri_components_t uri_component_use_for_contact_in_reg =		{"Contact in REG"			,o	,o	,/*m*/o	,o	,o	,na	,o	,o	,o	,na	,o	,o};
450 static  uri_components_t uri_component_use_for_dialog_ct_rr_ro =	{"Dialog Contact/R-R/Route"	,o	,o	,/*m*/o	,o	,o	,na	,o	,na	,o	,o	,o	,na};
451 static  uri_components_t uri_component_use_for_external =			{"External"					,o	,o	,m	,o	,o	,o	,o	,o	,o	,o	,o	,o};
452 
453 
check_component(int is_present,mark requirement)454 static int check_component(int is_present,mark requirement) {
455 	switch (requirement) {
456 	case o: return TRUE;
457 	case m: return is_present;
458 	case na: return !is_present;
459 	}
460 	return 0;
461 }
462 
463 #define CHECK_URI_COMPONENT(uri_component,uri_component_name,component_use_rule,component_use_rule_name) \
464 if (!check_component(uri_component,component_use_rule)) {\
465 	belle_sip_error("Uri component [%s] does not follow reqs [%s] for context [%s]", uri_component_name,mark_to_string(component_use_rule),component_use_rule_name);\
466 	return FALSE;\
467 }
468 
check_uri_components(const belle_sip_uri_t * uri,const uri_components_t * components_use)469 static int check_uri_components(const belle_sip_uri_t* uri,  const uri_components_t* components_use) {
470 
471 	CHECK_URI_COMPONENT(uri->user!=NULL,"user",components_use->user,components_use->name)
472 	CHECK_URI_COMPONENT(uri->host!=NULL,"host",components_use->host,components_use->name)
473 	CHECK_URI_COMPONENT(uri->port>0,"port",components_use->port,components_use->name)
474 	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"maddr"),"maddr-param",components_use->maddr_param,components_use->name)
475 	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"ttl"),"ttl-param",components_use->ttl_param,components_use->name)
476 	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"transport"),"transp.-param",components_use->transp_param,components_use->name)
477 	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"lr"),"lr-param",components_use->lr_param,components_use->name)
478 	/*..*/
479 	CHECK_URI_COMPONENT(belle_sip_list_size(belle_sip_parameters_get_parameters(uri->header_list))>0,"headers",components_use->headers,components_use->name)
480 	return TRUE;
481 }
482 
483 /*return 0 if not compliant*/
belle_sip_uri_check_components_from_request_uri(const belle_sip_uri_t * uri)484 int belle_sip_uri_check_components_from_request_uri(const belle_sip_uri_t* uri) {
485 	return check_uri_components(uri,&uri_component_use_for_request);
486 }
belle_sip_uri_check_components_from_context(const belle_sip_uri_t * uri,const char * method,const char * header_name)487 int belle_sip_uri_check_components_from_context(const belle_sip_uri_t* uri,const char* method,const char* header_name) {
488 
489 	if (strcasecmp(BELLE_SIP_FROM,header_name)==0)
490 		return check_uri_components(uri,&uri_component_use_for_header_from);
491 	else if (strcasecmp(BELLE_SIP_TO,header_name)==0)
492 		return check_uri_components(uri,&uri_component_use_for_header_to);
493 	else if (strcasecmp(BELLE_SIP_CONTACT,header_name)==0 && method && strcasecmp("REGISTER",method)==0)
494 		return check_uri_components(uri,&uri_component_use_for_contact_in_reg);
495 	else if (strcasecmp(BELLE_SIP_CONTACT,header_name)==0
496 				|| strcasecmp(BELLE_SIP_RECORD_ROUTE,header_name)==0
497 				|| strcasecmp(BELLE_SIP_ROUTE,header_name)==0)
498 		return check_uri_components(uri,&uri_component_use_for_dialog_ct_rr_ro);
499 	else
500 		return check_uri_components(uri,&uri_component_use_for_external);
501 
502 
503 }
504 /*fast uri implemenation*/
505 typedef belle_sip_uri_t belle_sip_fast_uri_t;
506 BELLE_SIP_PARSE(fast_uri);
507