summaryrefslogtreecommitdiffstats
path: root/tinySIP/src/tsip_uri.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinySIP/src/tsip_uri.c')
-rwxr-xr-xtinySIP/src/tsip_uri.c428
1 files changed, 212 insertions, 216 deletions
diff --git a/tinySIP/src/tsip_uri.c b/tinySIP/src/tsip_uri.c
index 90d9859..2fd3a0b 100755
--- a/tinySIP/src/tsip_uri.c
+++ b/tinySIP/src/tsip_uri.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO 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 DOUBANGO.
*
@@ -51,44 +51,44 @@
*/
tsip_uri_t* tsip_uri_create(tsip_uri_type_t type)
{
- return tsk_object_new(tsip_uri_def_t, type);
+ return tsk_object_new(tsip_uri_def_t, type);
}
/* internal function used to serialize a SIP/SIPS/TEL URI */
int __tsip_uri_serialize(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_buffer_t *output)
{
- tsk_istr_t port;
-
- if(uri->port){
- tsk_itoa(uri->port, &port);
- }
-
- /* sip:alice:secretword@atlanta.com:65535 */
- tsk_buffer_append_2(output, "%s:%s%s%s%s%s%s%s%s%s",
-
- uri->scheme ? uri->scheme : "sip", /* default scheme is sip: */
-
- uri->user_name ? uri->user_name : "",
-
- uri->password ? ":" : "",
- uri->password ? uri->password : "",
-
- uri->host ? (uri->user_name ? "@" : "") : "",
- uri->host_type == host_ipv6 ? "[" : "",
- uri->host ? uri->host : "",
- uri->host_type == host_ipv6 ? "]" : "",
-
- uri->port ? ":" : "",
- uri->port ? port : ""
- );
-
- /* Params */
- if(with_params && !TSK_LIST_IS_EMPTY(uri->params)){
- tsk_buffer_append(output, ";", 1);
- tsk_params_tostring(uri->params, ';', output);
- }
-
- return 0;
+ tsk_istr_t port;
+
+ if(uri->port) {
+ tsk_itoa(uri->port, &port);
+ }
+
+ /* sip:alice:secretword@atlanta.com:65535 */
+ tsk_buffer_append_2(output, "%s:%s%s%s%s%s%s%s%s%s",
+
+ uri->scheme ? uri->scheme : "sip", /* default scheme is sip: */
+
+ uri->user_name ? uri->user_name : "",
+
+ uri->password ? ":" : "",
+ uri->password ? uri->password : "",
+
+ uri->host ? (uri->user_name ? "@" : "") : "",
+ uri->host_type == host_ipv6 ? "[" : "",
+ uri->host ? uri->host : "",
+ uri->host_type == host_ipv6 ? "]" : "",
+
+ uri->port ? ":" : "",
+ uri->port ? port : ""
+ );
+
+ /* Params */
+ if(with_params && !TSK_LIST_IS_EMPTY(uri->params)) {
+ tsk_buffer_append(output, ";", 1);
+ tsk_params_tostring(uri->params, ';', output);
+ }
+
+ return 0;
}
/**@ingroup tsip_uri_group
@@ -101,26 +101,26 @@ int __tsip_uri_serialize(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_buff
*/
int tsip_uri_serialize(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bool_t quote, tsk_buffer_t *output)
{
- if(uri && output){
- int ret = 0;
- if(quote){
- if(uri->display_name){
- tsk_buffer_append_2(output, "\"%s\"", uri->display_name);
- }
-
- tsk_buffer_append(output, "<", 1);
- ret = __tsip_uri_serialize(uri, with_params, output);
- tsk_buffer_append(output, ">", 1);
- }
- else{
- ret = __tsip_uri_serialize(uri, with_params, output);
- }
- return ret;
- }
- else{
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(uri && output) {
+ int ret = 0;
+ if(quote) {
+ if(uri->display_name) {
+ tsk_buffer_append_2(output, "\"%s\"", uri->display_name);
+ }
+
+ tsk_buffer_append(output, "<", 1);
+ ret = __tsip_uri_serialize(uri, with_params, output);
+ tsk_buffer_append(output, ">", 1);
+ }
+ else {
+ ret = __tsip_uri_serialize(uri, with_params, output);
+ }
+ return ret;
+ }
+ else {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
}
/**@ingroup tsip_uri_group
@@ -132,18 +132,18 @@ int tsip_uri_serialize(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bool_t
*/
char* tsip_uri_tostring(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bool_t quote)
{
- tsk_buffer_t *output = tsk_buffer_create_null();
- char* ret = 0;
-
- if(!tsip_uri_serialize(uri, with_params, quote, output)){
- ret = tsk_strndup((const char*)output->data, output->size);
- }
- else{
- TSK_DEBUG_ERROR("Failed to serialize URI.");
- }
-
- TSK_OBJECT_SAFE_FREE(output);
- return ret;
+ tsk_buffer_t *output = tsk_buffer_create_null();
+ char* ret = 0;
+
+ if(!tsip_uri_serialize(uri, with_params, quote, output)) {
+ ret = tsk_strndup((const char*)output->data, output->size);
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to serialize URI.");
+ }
+
+ TSK_OBJECT_SAFE_FREE(output);
+ return ret;
}
/**@ingroup tsip_uri_group
@@ -155,14 +155,14 @@ char* tsip_uri_tostring(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bool_
*/
tsip_uri_t *tsip_uri_clone(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bool_t quote)
{
- tsip_uri_t *newuri = tsk_null;
- tsk_buffer_t *output = tsk_buffer_create_null();
- if((tsip_uri_serialize(uri, with_params, quote, output)) == 0){
- newuri = tsip_uri_parse(output->data, output->size);
- }
- TSK_OBJECT_SAFE_FREE(output);
-
- return newuri;
+ tsip_uri_t *newuri = tsk_null;
+ tsk_buffer_t *output = tsk_buffer_create_null();
+ if((tsip_uri_serialize(uri, with_params, quote, output)) == 0) {
+ newuri = tsip_uri_parse(output->data, output->size);
+ }
+ TSK_OBJECT_SAFE_FREE(output);
+
+ return newuri;
}
@@ -178,64 +178,63 @@ tsip_uri_t *tsip_uri_clone(const tsip_uri_t *uri, tsk_bool_t with_params, tsk_bo
static tsk_object_t* tsip_uri_ctor(tsk_object_t *self, va_list * app)
{
- tsip_uri_t *uri = self;
- if(uri)
- {
- uri->type = va_arg(*app, tsip_uri_type_t);
- uri->params = tsk_list_create(); /* Empty list. */
- }
- else
- {
- TSK_DEBUG_ERROR("Failed to create new SIP/SIPS/TEL.");
- }
- return self;
+ tsip_uri_t *uri = self;
+ if(uri) {
+ uri->type = va_arg(*app, tsip_uri_type_t);
+ uri->params = tsk_list_create(); /* Empty list. */
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create new SIP/SIPS/TEL.");
+ }
+ return self;
}
static tsk_object_t* tsip_uri_dtor(tsk_object_t *self)
{
- tsip_uri_t *uri = self;
- if(uri)
- {
- TSK_FREE(uri->scheme);
- TSK_FREE(uri->host);
- TSK_FREE(uri->user_name);
- TSK_FREE(uri->password);
- TSK_FREE(uri->display_name);
- TSK_OBJECT_SAFE_FREE(uri->params);
- }
- else TSK_DEBUG_ERROR("Null SIP/SIPS/TEL URI.");
-
- return self;
+ tsip_uri_t *uri = self;
+ if(uri) {
+ TSK_FREE(uri->scheme);
+ TSK_FREE(uri->host);
+ TSK_FREE(uri->user_name);
+ TSK_FREE(uri->password);
+ TSK_FREE(uri->display_name);
+ TSK_OBJECT_SAFE_FREE(uri->params);
+ }
+ else {
+ TSK_DEBUG_ERROR("Null SIP/SIPS/TEL URI.");
+ }
+
+ return self;
}
int tsip_uri_strcmp(const char* s1, const char* s2, tsk_bool_t case_sensitive)
{
- if(s1 && s2){
- tsk_bool_t s1_is_encoded = tsk_false;
- tsk_bool_t s2_is_encoded = tsk_false;
- char* s1_decoded = (char*)s1;
- char* s2_decoded = (char*)s2;
- int ret;
-
- if(tsk_strcontains(s1, tsk_strlen(s1), "%")){
- s1_is_encoded = 1;
- s1_decoded = tsk_url_decode(s1);
- }
- if(tsk_strcontains(s2, tsk_strlen(s2), "%")){
- s2_is_encoded = 1;
- s2_decoded = tsk_url_decode(s2);
- }
-
- ret = case_sensitive ? tsk_strcmp(s1_decoded, s2_decoded) : tsk_stricmp(s1_decoded, s2_decoded);
- if(s1_is_encoded){
- TSK_FREE(s1_decoded);
- }
- if(s2_is_encoded){
- TSK_FREE(s2_decoded);
- }
- return ret;
- }
- return case_sensitive ? tsk_strcmp(s1, s2) : tsk_stricmp(s1, s2);
+ if(s1 && s2) {
+ tsk_bool_t s1_is_encoded = tsk_false;
+ tsk_bool_t s2_is_encoded = tsk_false;
+ char* s1_decoded = (char*)s1;
+ char* s2_decoded = (char*)s2;
+ int ret;
+
+ if(tsk_strcontains(s1, tsk_strlen(s1), "%")) {
+ s1_is_encoded = 1;
+ s1_decoded = tsk_url_decode(s1);
+ }
+ if(tsk_strcontains(s2, tsk_strlen(s2), "%")) {
+ s2_is_encoded = 1;
+ s2_decoded = tsk_url_decode(s2);
+ }
+
+ ret = case_sensitive ? tsk_strcmp(s1_decoded, s2_decoded) : tsk_stricmp(s1_decoded, s2_decoded);
+ if(s1_is_encoded) {
+ TSK_FREE(s1_decoded);
+ }
+ if(s2_is_encoded) {
+ TSK_FREE(s2_decoded);
+ }
+ return ret;
+ }
+ return case_sensitive ? tsk_strcmp(s1, s2) : tsk_stricmp(s1, s2);
}
#define tsip_uri_strequals(s1, s2) !tsip_uri_strcmp(s1, s2, tsk_true)
#define tsip_uri_striequals(s1, s2) !tsip_uri_strcmp(s1, s2, tsk_false)
@@ -243,103 +242,100 @@ int tsip_uri_strcmp(const char* s1, const char* s2, tsk_bool_t case_sensitive)
// FIXME: tel uris are compared as per RFC 3966 section 4
static int tsip_uri_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
{
- if(obj1 && obj2){
- const tsip_uri_t* uri1 = obj1;
- const tsip_uri_t* uri2 = obj2;
- const tsk_param_t* param1;
- const tsk_param_t* param2;
- const tsk_list_item_t *item;
-
- /* RFC 3261 - 19.1.4 URI Comparison
-
- 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.
-
- An IP address that is the result of a DNS lookup of a host name does not match that host name.
-
- For two URIs to be equal, the user, password, host, and port components must match.
-
- 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.
-
- userinfo = ( user / telephone-subscriber ) [ ":" password ] "@"
- */
- if(!tsk_strequals(uri1->scheme, uri2->scheme) ||
- !tsip_uri_strequals(uri1->user_name, uri2->user_name) ||
- !tsip_uri_strequals(uri1->host, uri2->host) ||
- !tsk_strequals(uri1->password, uri2->password) ||
- uri1->port != uri2->port){
- return -2;
- }
-
- /* Is there parameters */
- if((!uri1->params && !uri2->params) || (TSK_LIST_IS_EMPTY(uri1->params) && TSK_LIST_IS_EMPTY(uri2->params))){
- return 0;
- }
-
- /* RFC 3261 - 19.1.4 URI Comparison
-
- 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.
-
- - 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.
- */
+ if(obj1 && obj2) {
+ const tsip_uri_t* uri1 = obj1;
+ const tsip_uri_t* uri2 = obj2;
+ const tsk_param_t* param1;
+ const tsk_param_t* param2;
+ const tsk_list_item_t *item;
+
+ /* RFC 3261 - 19.1.4 URI Comparison
+
+ 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.
+
+ An IP address that is the result of a DNS lookup of a host name does not match that host name.
+
+ For two URIs to be equal, the user, password, host, and port components must match.
+
+ 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.
+
+ userinfo = ( user / telephone-subscriber ) [ ":" password ] "@"
+ */
+ if(!tsk_strequals(uri1->scheme, uri2->scheme) ||
+ !tsip_uri_strequals(uri1->user_name, uri2->user_name) ||
+ !tsip_uri_strequals(uri1->host, uri2->host) ||
+ !tsk_strequals(uri1->password, uri2->password) ||
+ uri1->port != uri2->port) {
+ return -2;
+ }
+
+ /* Is there parameters */
+ if((!uri1->params && !uri2->params) || (TSK_LIST_IS_EMPTY(uri1->params) && TSK_LIST_IS_EMPTY(uri2->params))) {
+ return 0;
+ }
+
+ /* RFC 3261 - 19.1.4 URI Comparison
+
+ 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.
+
+ - 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.
+ */
#define TSIP_URI_CMP_PARAMETER(pname) \
param1 = tsk_params_get_param_by_name(uri1->params, pname);\
param2 = tsk_params_get_param_by_name(uri2->params, pname);\
if((param1 || param2) && ((param1 && !param2) || (!param1 && param2) || (!tsip_uri_striequals(param1->value, param2->value)))){\
return -3;\
}
- TSIP_URI_CMP_PARAMETER("transport");
- TSIP_URI_CMP_PARAMETER("ttl");
- TSIP_URI_CMP_PARAMETER("user");
- TSIP_URI_CMP_PARAMETER("method");
- TSIP_URI_CMP_PARAMETER("maddr");
-
- /* RFC 3261 - 19.1.4 URI Comparison
-
- URI uri-parameter components are compared as follows:
-
- 1 - Any uri-parameter appearing in both URIs must match.
- 2 - All other uri-parameters appearing in only one URI are ignored when comparing the URIs.
-
- 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.
- */
- tsk_list_foreach(item, uri1->params)
- {
- param1 = item->data;
- if((param2 = tsk_params_get_param_by_name(uri2->params, param1->name))){
- if(!tsip_uri_striequals(param1->value, param2->value)){
- return -4;
- }
- }
- }
- tsk_list_foreach(item, uri2->params)
- {
- param2 = item->data;
- if((param1 = tsk_params_get_param_by_name(uri1->params, param2->name))){
- if(!tsk_striequals(param1->value, param2->value)){
- return -4;
- }
- }
- }
-
- return 0;
- }
- else{
- return (!obj1 && !obj2) ? 0 : -1;
- }
+ TSIP_URI_CMP_PARAMETER("transport");
+ TSIP_URI_CMP_PARAMETER("ttl");
+ TSIP_URI_CMP_PARAMETER("user");
+ TSIP_URI_CMP_PARAMETER("method");
+ TSIP_URI_CMP_PARAMETER("maddr");
+
+ /* RFC 3261 - 19.1.4 URI Comparison
+
+ URI uri-parameter components are compared as follows:
+
+ 1 - Any uri-parameter appearing in both URIs must match.
+ 2 - All other uri-parameters appearing in only one URI are ignored when comparing the URIs.
+
+ 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.
+ */
+ tsk_list_foreach(item, uri1->params) {
+ param1 = item->data;
+ if((param2 = tsk_params_get_param_by_name(uri2->params, param1->name))) {
+ if(!tsip_uri_striequals(param1->value, param2->value)) {
+ return -4;
+ }
+ }
+ }
+ tsk_list_foreach(item, uri2->params) {
+ param2 = item->data;
+ if((param1 = tsk_params_get_param_by_name(uri1->params, param2->name))) {
+ if(!tsk_striequals(param1->value, param2->value)) {
+ return -4;
+ }
+ }
+ }
+
+ return 0;
+ }
+ else {
+ return (!obj1 && !obj2) ? 0 : -1;
+ }
}
-static const tsk_object_def_t tsip_uri_def_s =
-{
- sizeof(tsip_uri_t),
- tsip_uri_ctor,
- tsip_uri_dtor,
- tsip_uri_cmp
+static const tsk_object_def_t tsip_uri_def_s = {
+ sizeof(tsip_uri_t),
+ tsip_uri_ctor,
+ tsip_uri_dtor,
+ tsip_uri_cmp
};
const tsk_object_def_t *tsip_uri_def_t = &tsip_uri_def_s;
OpenPOWER on IntegriCloud