belle_sip_uri_impl.c 18.9 KB
Newer Older
1
/*
jehan's avatar
jehan committed
2 3 4 5 6
	belle-sip - SIP (RFC3261) library.
    Copyright (C) 2010  Belledonne Communications SARL

    This program is free software: you can redistribute it and/or modify
    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
jehan's avatar
jehan committed
8 9 10 11 12 13 14 15 16 17
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
18

19
#include "belle-sip/sip-uri.h"
20
#include "belle-sip/parameters.h"
21 22
#include <stdlib.h>
#include <string.h>
jehan's avatar
jehan committed
23
#include <stdarg.h>
24 25
#include "grammars/belle_sip_messageParser.h"
#include "grammars/belle_sip_messageLexer.h"
26
#include "belle_sip_internal.h"
jehan's avatar
jehan committed
27
#include "listeningpoint_internal.h"
28 29


jehan's avatar
jehan committed
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 35
#define SIP_URI_GET_SET_UINT(attribute) GET_SET_INT(belle_sip_uri,attribute,unsigned int)
#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

jehan's avatar
jehan committed
39 40
#define SIP_URI_GET_SET_BOOL(attribute) GET_SET_BOOL(belle_sip_uri,attribute,is)
#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



jehan's avatar
jehan committed
45
struct _belle_sip_uri {
46
	belle_sip_parameters_t params;
47
	unsigned int secure;
48
	char* user;
jehan's avatar
jehan committed
49
	char* user_password;
50
	char* host;
jehan's avatar
jehan committed
51
	int port;
52
	belle_sip_parameters_t * header_list;
53
};
54

55
static void belle_sip_uri_destroy(belle_sip_uri_t* uri) {
56 57
	if (uri->user) belle_sip_free (uri->user);
	if (uri->host) belle_sip_free (uri->host);
jehan's avatar
jehan committed
58
	if (uri->user_password) belle_sip_free (uri->user_password);
59 60
	belle_sip_object_unref(BELLE_SIP_OBJECT(uri->header_list));
}
61

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;
jehan's avatar
jehan committed
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 69 70 71 72
	if (orig->header_list){
		uri->header_list=(belle_sip_parameters_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(orig->header_list));
		belle_sip_object_ref(uri->header_list);
	}
	
73 74
}

75 76 77 78
static void encode_params(belle_sip_param_pair_t* container, belle_sip_list_t** newlist) {
	char *escapedName = belle_sip_uri_to_escaped_parameter(container->name);
	char *escapedValue = container->value? belle_sip_uri_to_escaped_parameter(container->value) : NULL;
	*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
79 80
	if (escapedName) free(escapedName);
	if (escapedValue) free(escapedValue);
81 82
}

83 84 85 86
static void encode_headers(belle_sip_param_pair_t* container, belle_sip_list_t** newlist) {
	char *escapedName = belle_sip_uri_to_escaped_header(container->name);
	char *escapedValue = container->value? belle_sip_uri_to_escaped_header(container->value) : NULL;
	*newlist = belle_sip_list_append(*newlist, belle_sip_param_pair_new(escapedName, escapedValue));
87 88
	if (escapedName) free(escapedName);
	if (escapedValue) free(escapedValue);
89 90
}

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;
Ghislain MARY's avatar
Ghislain MARY committed
93
	belle_sip_error_code error=BELLE_SIP_OK;
94

Ghislain MARY's avatar
Ghislain MARY committed
95 96
	error=belle_sip_snprintf(buff,buff_size,offset,"%s:",uri->secure?"sips":"sip");
	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);
jehan's avatar
jehan committed
100
		error=belle_sip_snprintf(buff,buff_size,offset,"%s",escaped_username);
101
		belle_sip_free(escaped_username);
Ghislain MARY's avatar
Ghislain MARY committed
102
		if (error!=BELLE_SIP_OK) return error;
jehan's avatar
jehan committed
103 104 105 106 107 108 109

		if (uri->user_password) {
			char* escaped_password=belle_sip_uri_to_escaped_userpasswd(uri->user_password);
			error=belle_sip_snprintf(buff,buff_size,offset,":%s",escaped_password);
			belle_sip_free(escaped_password);
			if (error!=BELLE_SIP_OK) return error;
		}
jehan's avatar
jehan committed
110
		error=belle_sip_snprintf(buff,buff_size,offset,"@");
jehan's avatar
jehan committed
111 112
		if (error!=BELLE_SIP_OK) return error;

113
	}
jehan's avatar
jehan committed
114

115
	if (uri->host) {
116
		if (strchr(uri->host,':')) { /*ipv6*/
Ghislain MARY's avatar
Ghislain MARY committed
117
			error=belle_sip_snprintf(buff,buff_size,offset,"[%s]",uri->host);
118
		} else {
Ghislain MARY's avatar
Ghislain MARY committed
119
			error=belle_sip_snprintf(buff,buff_size,offset,"%s",uri->host);
120
		}
Ghislain MARY's avatar
Ghislain MARY committed
121
		if (error!=BELLE_SIP_OK) return error;
122 123 124
	} else {
		belle_sip_warning("no host found in this uri");
	}
125
	
126
	if (uri->port!=0) {
Ghislain MARY's avatar
Ghislain MARY committed
127 128
		error=belle_sip_snprintf(buff,buff_size,offset,":%i",uri->port);
		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 137
		if (error!=BELLE_SIP_OK) return error;
	}
138

139 140 141 142 143 144 145 146
	{
		belle_sip_list_t * encheaders = NULL;
		belle_sip_list_for_each2(uri->header_list->param_list, (void (*)(void *, void *))encode_headers, &encheaders);

		for(list=encheaders;list!=NULL;list=list->next){
			belle_sip_param_pair_t* container = list->data;
			if (list == encheaders) {
				//first case
147
				error=belle_sip_snprintf(buff,buff_size,offset,"?%s=%s",container->name,container->value?container->value:"");
148 149
			} else {
				//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

Ghislain MARY's avatar
Ghislain MARY committed
157
	return error;
158
}
159

jehan's avatar
jehan committed
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


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 169
	belle_sip_parameters_init((belle_sip_parameters_t*)l_object); /*super*/
	l_object->header_list = belle_sip_parameters_new();
170
	belle_sip_object_ref(l_object->header_list);
171
	return l_object;
172
}
173

jehan's avatar
jehan committed
174 175 176 177 178 179
belle_sip_uri_t* belle_sip_uri_create (const char* username,const char* host) {
	belle_sip_uri_t* uri = belle_sip_uri_new();
	belle_sip_uri_set_user(uri,username);
	belle_sip_uri_set_host(uri,host);
	return uri;
}
180 181


182
char* belle_sip_uri_to_string(const belle_sip_uri_t* uri)  {
jehan's avatar
jehan committed
183
	return belle_sip_object_to_string(BELLE_SIP_OBJECT(uri));
184 185
}

186

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 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
}

195 196 197 198
void belle_sip_uri_remove_header(belle_sip_uri_t *uri, const char *name){
	belle_sip_parameters_remove_parameter(uri->header_list,name);
}

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
}

203 204 205
int belle_sip_uri_get_listening_port(const belle_sip_uri_t *uri){
	int port=belle_sip_uri_get_port(uri);
	const char *transport=belle_sip_uri_get_transport_param(uri);
jehan's avatar
jehan committed
206 207 208
	if (!transport) {
		transport=belle_sip_uri_is_secure(uri)?"tls":"udp";
	}
Simon Morlat's avatar
Simon Morlat committed
209
	if (port==0)
jehan's avatar
jehan committed
210
		port=belle_sip_listening_point_get_well_known_port(transport);
211 212
	return port;
}
213

214
void belle_sip_uri_fix(belle_sip_uri_t *uri){
jehan's avatar
jehan committed
215
	/*nop, to be removed*/
216 217
}

218
SIP_URI_GET_SET_BOOL(secure)
219

220
SIP_URI_GET_SET_STRING(user)
jehan's avatar
jehan committed
221
SIP_URI_GET_SET_STRING(user_password)
222
SIP_URI_GET_SET_STRING(host)
jehan's avatar
jehan committed
223
SIP_URI_GET_SET_INT(port)
224

225 226 227 228 229 230
SIP_URI_GET_SET_STRING_PARAM(transport)
SIP_URI_GET_SET_STRING_PARAM(user)
SIP_URI_GET_SET_STRING_PARAM(method)
SIP_URI_GET_SET_STRING_PARAM(maddr)
SIP_URI_GET_SET_INT_PARAM(ttl)
SIP_URI_HAS_SET_BOOL_PARAM(lr)
jehan's avatar
jehan committed
231 232


jehan's avatar
jehan committed
233 234 235 236 237 238 239 240
const belle_sip_parameters_t*	belle_sip_uri_get_headers(const belle_sip_uri_t* uri) {
	return uri->header_list;
}


void belle_sip_uri_headers_clean(belle_sip_uri_t* uri) {
	belle_sip_parameters_clean(uri->header_list);
}
jehan's avatar
jehan committed
241

jehan's avatar
jehan committed
242 243 244

static int uri_strncmp_common(const char*a,const char*b,size_t n,int case_sensitive) {
	int result=0;
245
	size_t index_a=0,index_b=0;
jehan's avatar
jehan committed
246 247 248
	char char_a,char_b;

	while (a[index_a]!='\0'&&b[index_b]!='\0'&&index_a<n&&index_b<n) {
jehan's avatar
jehan committed
249 250
		index_a+=belle_sip_get_char(a+index_a,n-index_a,&char_a);
		index_b+=belle_sip_get_char(b+index_b,n-index_b,&char_b);
jehan's avatar
jehan committed
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
		if (!case_sensitive && char_a<0x7B && char_a>0x60) char_a-=0x20;
		if (!case_sensitive && char_b<0x7B && char_b>0x60) char_b-=0x20;
		result+=(char_a!=char_b);
	}
	return result;
}
static int uri_strncmp(const char*a,const char*b,size_t n) {
	return uri_strncmp_common(a,b,n,1);
}
static int uri_strncasecmp(const char*a,const char*b,size_t n) {
	return uri_strncmp_common(a,b,n,0);
}
#define IS_EQUAL(a,b) uri_strncmp(a,b,MIN(strlen(a),strlen(b)))!=0

#define IS_EQUAL_CASE(a,b) uri_strncasecmp(a,b,MIN(strlen(a),strlen(b)))!=0
#define PARAM_CASE_CMP(uri_a,uri_b,param) \
jehan's avatar
jehan committed
267 268
		a_param=belle_sip_parameters_get_case_parameter((belle_sip_parameters_t*) uri_a,param); \
		b_param=belle_sip_parameters_get_case_parameter((belle_sip_parameters_t*) uri_b,param);\
jehan's avatar
jehan committed
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
		if (a_param && b_param) { \
			if (IS_EQUAL_CASE(a_param,b_param)) return 0; \
		} else if (a_param != b_param) {\
			return 0;\
		}

/*
 * RFC 3261            SIP: Session Initiation Protocol           June 2002
 * 19.1.4 URI Comparison

   Some operations in this specification require determining whether two
   SIP or SIPS URIs are equivalent.  In this specification, registrars
   need to compare bindings in Contact URIs in REGISTER requests (see
   Section 10.3.).  SIP and SIPS URIs are compared for equality
   according to the following rules:
*/
int belle_sip_uri_equals(const belle_sip_uri_t* uri_a,const belle_sip_uri_t* uri_b) {
	const belle_sip_list_t *	params;
	const char* b_param;
	const char* a_param;
/*
      o  A SIP and SIPS URI are never equivalent.
*/
	if (belle_sip_uri_is_secure(uri_a)!=belle_sip_uri_is_secure(uri_b)) {
		return 0;
	}
/*
	o  Comparison of the userinfo of SIP and SIPS URIs is case-
         sensitive.  This includes userinfo containing passwords or
         formatted as telephone-subscribers.  Comparison of all other
         components of the URI is case-insensitive unless explicitly
         defined otherwise.
*/
	if (uri_a->user && uri_b->user) {
		if (IS_EQUAL(uri_a->user,uri_b->user)) return 0;
	} else if (uri_a->user != uri_a->user) {
		return 0;
	}
/*
      o  The ordering of parameters and header fields is not significant
         in comparing SIP and SIPS URIs.

      o  Characters other than those in the "reserved" set (see RFC 2396
         [5]) are equivalent to their ""%" HEX HEX" encoding.

      o  An IP address that is the result of a DNS lookup of a host name
         does not match that host name.

      o  For two URIs to be equal, the user, password, host, and port
         components must match.
*/
		if (!uri_a->host || !uri_b->host) {
			return 0;
		} else if  (IS_EQUAL_CASE(uri_a->host,uri_b->host)) {
			return 0;
		}
		if (uri_a->port !=uri_b->port) return 0;
/*
         A URI omitting the user component will not match a URI that
         includes one.  A URI omitting the password component will not
         match a URI that includes one.

         A URI omitting any component with a default value will not
         match a URI explicitly containing that component with its
         default value.  For instance, a URI omitting the optional port
         component will not match a URI explicitly declaring port 5060.
         The same is true for the transport-parameter, ttl-parameter,
         user-parameter, and method components.

            Defining sip:user@host to not be equivalent to
            sip:user@host:5060 is a change from RFC 2543.  When deriving
            addresses from URIs, equivalent addresses are expected from
            equivalent URIs.  The URI sip:user@host:5060 will always
            resolve to port 5060.  The URI sip:user@host may resolve to
            other ports through the DNS SRV mechanisms detailed in [4].

      o  URI uri-parameter components are compared as follows:

         -  Any uri-parameter appearing in both URIs must match.
*/
/*
 *         -  A user, ttl, or method uri-parameter appearing in only one
            URI never matches, even if it contains the default value.
           -  A URI that includes an maddr parameter will not match a URI
            that contains no maddr parameter.
 * */
		PARAM_CASE_CMP(uri_a,uri_b,"transport")
		PARAM_CASE_CMP(uri_a,uri_b,"user")
		PARAM_CASE_CMP(uri_a,uri_b,"ttl")
		PARAM_CASE_CMP(uri_a,uri_b,"method")
		PARAM_CASE_CMP(uri_a,uri_b,"maddr")


		for(params=belle_sip_parameters_get_parameters((belle_sip_parameters_t*) uri_a);params!=NULL;params=params->next) {
			if ((b_param=belle_sip_parameters_get_parameter((belle_sip_parameters_t*) uri_b,(const char*)params->data)) !=NULL) {
				if (IS_EQUAL_CASE(b_param,(const char*)params->data)) return 0;
			}

		}

 /*


         -  All other uri-parameters appearing in only one URI are
            ignored when comparing the URIs.
*/
/* *fixme ignored for now*/
/*
      o  URI header components are never ignored.  Any present header
         component MUST be present in both URIs and match for the URIs
         to match.  The matching rules are defined for each header field
         in Section 20.
 */
382
	return 1;
jehan's avatar
jehan committed
383
}
384

jehan's avatar
jehan committed
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
/*uri checker*/


/*
 * From 19.1.1 SIP and SIPS URI Components
 * 									   				dialog
										reg./redir. Contact/
			default  Req.-URI  To  From  Contact   R-R/Route  external
user          --          o      o    o       o          o         o
password      --          o      o    o       o          o         o
host          --          m      m    m       m          m         m
port          (1)         o      -    -       o          o         o
user-param    ip          o      o    o       o          o         o
method        INVITE      -      -    -       -          -         o
maddr-param   --          o      -    -       o          o         o
ttl-param     1           o      -    -       o          -         o
transp.-param (2)         o      -    -       o          o         o
lr-param      --          o      -    -       -          o         o
other-param   --          o      o    o       o          o         o
headers       --          -      -    -       o          -         o

(1): The default port value is transport and scheme dependent.  The
default  is  5060  for  sip: using UDP, TCP, or SCTP.  The default is
5061 for sip: using TLS over TCP and sips: over TCP.

(2): The default transport is scheme dependent.  For sip:, it is UDP.
For sips:, it is TCP.

Table 1: Use and default values of URI components for SIP header
field values, Request-URI and references*/


typedef enum {
	m /*mandotory*/
	, o /*optionnal*/
	, na /*not allowd*/
} mark;

static const char* mark_to_string(mark value) {
	switch (value) {
	case o: return "optionnal";
	case m: return "mandatory";
	case na: return "not allowed";
	}
	return "unknown";
}

typedef struct uri_components {
	const char * name;
	mark user;
	mark password;
	mark host;
	mark port;
	mark user_param;
	mark method;
	mark maddr_param;
	mark ttl_param;
	mark transp_param;
	mark lr_param;
	mark other_param;
	mark headers;
} uri_components_t;


jehan's avatar
jehan committed
449
/*belle sip allows contact header without host because stack will auutomatically put host if missing*/
jehan's avatar
jehan committed
450 451 452
static  uri_components_t uri_component_use_for_request = 			{"Req.-URI"					,o	,o	,m	,o	,o	,na	,o	,o	,o	,o	,o	,na};
static  uri_components_t uri_component_use_for_header_to = 			{"Header To"				,o	,o	,m	,na	,o	,na	,na	,na	,na	,na	,o	,na};
static  uri_components_t uri_component_use_for_header_from = 		{"Header From"				,o	,o	,m	,na	,o	,na	,na	,na	,na	,na	,o	,na};
jehan's avatar
jehan committed
453 454
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};
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};
jehan's avatar
jehan committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
static  uri_components_t uri_component_use_for_external =			{"External"					,o	,o	,m	,o	,o	,o	,o	,o	,o	,o	,o	,o};


static int check_component(int is_present,mark requirement) {
	switch (requirement) {
	case o: return TRUE;
	case m: return is_present;
	case na: return !is_present;
	}
	return 0;
}

#define CHECK_URI_COMPONENT(uri_component,uri_component_name,component_use_rule,component_use_rule_name) \
if (!check_component(uri_component,component_use_rule)) {\
	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);\
	return FALSE;\
}

static int check_uri_components(const belle_sip_uri_t* uri,  const uri_components_t* components_use) {

jehan's avatar
jehan committed
475 476
	CHECK_URI_COMPONENT(uri->user!=NULL,"user",components_use->user,components_use->name)
	CHECK_URI_COMPONENT(uri->host!=NULL,"host",components_use->host,components_use->name)
jehan's avatar
jehan committed
477 478 479 480 481 482
	CHECK_URI_COMPONENT(uri->port>0,"port",components_use->port,components_use->name)
	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"maddr"),"maddr-param",components_use->maddr_param,components_use->name)
	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"ttl"),"ttl-param",components_use->ttl_param,components_use->name)
	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"transport"),"transp.-param",components_use->transp_param,components_use->name)
	CHECK_URI_COMPONENT(belle_sip_parameters_has_parameter(&uri->params,"lr"),"lr-param",components_use->lr_param,components_use->name)
	/*..*/
jehan's avatar
jehan committed
483
	CHECK_URI_COMPONENT(belle_sip_list_size(belle_sip_parameters_get_parameters(uri->header_list))>0,"headers",components_use->headers,components_use->name)
jehan's avatar
jehan committed
484 485 486 487
	return TRUE;
}

/*return 0 if not compliant*/
jehan's avatar
jehan committed
488 489
int belle_sip_uri_check_components_from_request_uri(const belle_sip_uri_t* uri) {
	return check_uri_components(uri,&uri_component_use_for_request);
jehan's avatar
jehan committed
490
}
jehan's avatar
jehan committed
491
int belle_sip_uri_check_components_from_context(const belle_sip_uri_t* uri,const char* method,const char* header_name) {
jehan's avatar
jehan committed
492 493

	if (strcasecmp(BELLE_SIP_FROM,header_name)==0)
jehan's avatar
jehan committed
494
		return check_uri_components(uri,&uri_component_use_for_header_from);
jehan's avatar
jehan committed
495
	else if (strcasecmp(BELLE_SIP_TO,header_name)==0)
jehan's avatar
jehan committed
496 497 498
		return check_uri_components(uri,&uri_component_use_for_header_to);
	else if (strcasecmp(BELLE_SIP_CONTACT,header_name)==0 && method && strcasecmp("REGISTER",method)==0)
		return check_uri_components(uri,&uri_component_use_for_contact_in_reg);
jehan's avatar
jehan committed
499 500 501
	else if (strcasecmp(BELLE_SIP_CONTACT,header_name)==0
				|| strcasecmp(BELLE_SIP_RECORD_ROUTE,header_name)==0
				|| strcasecmp(BELLE_SIP_ROUTE,header_name)==0)
jehan's avatar
jehan committed
502
		return check_uri_components(uri,&uri_component_use_for_dialog_ct_rr_ro);
jehan's avatar
jehan committed
503
	else
jehan's avatar
jehan committed
504
		return check_uri_components(uri,&uri_component_use_for_external);
jehan's avatar
jehan committed
505 506 507


}