Commit 6e538af0 authored by Simon Morlat's avatar Simon Morlat

extend the notion of automatic contact to header_address, so that refer-to can...

extend the notion of automatic contact to header_address, so that refer-to can be benefit from this option as well.
parent c840e219
...@@ -83,6 +83,14 @@ BELLESIP_EXPORT belle_generic_uri_t* belle_sip_header_address_get_absolute_uri(c ...@@ -83,6 +83,14 @@ BELLESIP_EXPORT belle_generic_uri_t* belle_sip_header_address_get_absolute_uri(c
*/ */
BELLESIP_EXPORT void belle_sip_header_address_set_absolute_uri(belle_sip_header_address_t* address, belle_generic_uri_t* uri); BELLESIP_EXPORT void belle_sip_header_address_set_absolute_uri(belle_sip_header_address_t* address, belle_generic_uri_t* uri);
/**
* Enable automatic filling of the contact ip, port and transport according to the channel that sends this message.
**/
BELLESIP_EXPORT void belle_sip_header_address_set_automatic(belle_sip_header_address_t *address, int automatic);
BELLESIP_EXPORT int belle_sip_header_address_get_automatic(const belle_sip_header_address_t *address);
/** /**
* *
*/ */
...@@ -193,6 +201,7 @@ BELLESIP_EXPORT belle_sip_header_contact_t* belle_sip_header_contact_create (con ...@@ -193,6 +201,7 @@ BELLESIP_EXPORT belle_sip_header_contact_t* belle_sip_header_contact_create (con
/** /**
* Enable automatic filling of the contact ip, port and transport according to the channel that sends this message. * Enable automatic filling of the contact ip, port and transport according to the channel that sends this message.
* @deprecated use belle_sip_header_address_set_automatic();
**/ **/
BELLESIP_EXPORT void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled); BELLESIP_EXPORT void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled);
...@@ -599,7 +608,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s ...@@ -599,7 +608,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#define BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED "terminated" #define BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED "terminated"
/****************************** /******************************
* Refer-To header object inherent from header_address * Refer-To header object inherits from header_address
* *
******************************/ ******************************/
typedef struct _belle_sip_header_refer_to belle_sip_header_refer_to_t; typedef struct _belle_sip_header_refer_to belle_sip_header_refer_to_t;
...@@ -610,7 +619,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s ...@@ -610,7 +619,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#define BELLE_SIP_REFER_TO "Refer-To" #define BELLE_SIP_REFER_TO "Refer-To"
/****************************** /******************************
* Referred-by header object inherent from header_address * Referred-by header object inherits from header_address
* *
******************************/ ******************************/
typedef struct _belle_sip_header_referred_by belle_sip_header_referred_by_t; typedef struct _belle_sip_header_referred_by belle_sip_header_referred_by_t;
...@@ -621,7 +630,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s ...@@ -621,7 +630,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#define BELLE_SIP_REFERRED_BY "Referred-By" #define BELLE_SIP_REFERRED_BY "Referred-By"
/****************************** /******************************
* Replace header object inherent from parameters * Replace header object inherits from parameters
* *
******************************/ ******************************/
typedef struct _belle_sip_header_replaces belle_sip_header_replaces_t; typedef struct _belle_sip_header_replaces belle_sip_header_replaces_t;
......
...@@ -187,6 +187,7 @@ struct _belle_sip_header_address { ...@@ -187,6 +187,7 @@ struct _belle_sip_header_address {
char* displayname; char* displayname;
belle_sip_uri_t* uri; belle_sip_uri_t* uri;
belle_generic_uri_t* absolute_uri; belle_generic_uri_t* absolute_uri;
unsigned char automatic;
}; };
static void belle_sip_header_address_init(belle_sip_header_address_t* object){ static void belle_sip_header_address_init(belle_sip_header_address_t* object){
...@@ -287,6 +288,14 @@ void belle_sip_header_address_set_uri(belle_sip_header_address_t* address, belle ...@@ -287,6 +288,14 @@ void belle_sip_header_address_set_uri(belle_sip_header_address_t* address, belle
} }
} }
void belle_sip_header_address_set_automatic(belle_sip_header_address_t *address, int automatic){
address->automatic = (unsigned char)automatic;
}
int belle_sip_header_address_get_automatic(const belle_sip_header_address_t *address){
return address->automatic;
}
belle_generic_uri_t* belle_sip_header_address_get_absolute_uri(const belle_sip_header_address_t* address) { belle_generic_uri_t* belle_sip_header_address_get_absolute_uri(const belle_sip_header_address_t* address) {
return address->absolute_uri; return address->absolute_uri;
} }
...@@ -365,9 +374,8 @@ GET_SET_STRING(belle_sip_header_allow,method); ...@@ -365,9 +374,8 @@ GET_SET_STRING(belle_sip_header_allow,method);
struct _belle_sip_header_contact { struct _belle_sip_header_contact {
belle_sip_header_address_t address; belle_sip_header_address_t address;
unsigned char wildcard; unsigned char wildcard;
unsigned char automatic;
unsigned char unknown; unsigned char unknown;
unsigned char pad[1]; unsigned char pad[2];
}; };
void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) { void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) {
...@@ -375,7 +383,6 @@ void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) { ...@@ -375,7 +383,6 @@ void belle_sip_header_contact_destroy(belle_sip_header_contact_t* contact) {
void belle_sip_header_contact_clone(belle_sip_header_contact_t *contact, const belle_sip_header_contact_t *orig){ void belle_sip_header_contact_clone(belle_sip_header_contact_t *contact, const belle_sip_header_contact_t *orig){
contact->wildcard=orig->wildcard; contact->wildcard=orig->wildcard;
contact->automatic=orig->automatic;
} }
belle_sip_error_code belle_sip_header_contact_marshal(belle_sip_header_contact_t* contact, char* buff, size_t buff_size, size_t *offset) { belle_sip_error_code belle_sip_header_contact_marshal(belle_sip_header_contact_t* contact, char* buff, size_t buff_size, size_t *offset) {
...@@ -432,11 +439,11 @@ unsigned int belle_sip_header_contact_not_equals(const belle_sip_header_contact_ ...@@ -432,11 +439,11 @@ unsigned int belle_sip_header_contact_not_equals(const belle_sip_header_contact_
} }
void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled){ void belle_sip_header_contact_set_automatic(belle_sip_header_contact_t *a, int enabled){
a->automatic=enabled; belle_sip_header_address_set_automatic((belle_sip_header_address_t*)a, enabled);
} }
int belle_sip_header_contact_get_automatic(const belle_sip_header_contact_t *a){ int belle_sip_header_contact_get_automatic(const belle_sip_header_contact_t *a){
return a->automatic; return belle_sip_header_address_get_automatic((belle_sip_header_address_t*)a);
} }
void belle_sip_header_contact_set_unknown(belle_sip_header_contact_t *a, int value){ void belle_sip_header_contact_set_unknown(belle_sip_header_contact_t *a, int value){
......
...@@ -449,13 +449,60 @@ static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_si ...@@ -449,13 +449,60 @@ static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_si
return 0; return 0;
} }
static void fix_automatic_header_address(belle_sip_provider_t *prov, belle_sip_channel_t *chan, belle_sip_header_address_t *addr){
const char *ip=NULL;
int port=0;
belle_sip_uri_t* uri;
const char *transport;
belle_sip_header_contact_t *contact = BELLE_SIP_OBJECT_IS_INSTANCE_OF(addr, belle_sip_header_contact_t) ? (belle_sip_header_contact_t*)addr : NULL;
if (contact && belle_sip_header_contact_is_wildcard(contact)) return;
/* fix the contact if in automatic mode or null uri (for backward compatibility)*/
if (!(uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)addr))) {
uri = belle_sip_uri_new();
belle_sip_header_address_set_uri((belle_sip_header_address_t*)addr,uri);
belle_sip_header_address_set_automatic(addr,TRUE);
}else if (belle_sip_uri_get_host(uri)==NULL){
belle_sip_header_address_set_automatic(addr,TRUE);
}
if (!belle_sip_header_address_get_automatic(addr)) return;
if (prov->nat_helper){
ip=chan->public_ip ? chan->public_ip : chan->local_ip;
port=chan->public_port ? chan->public_port : chan->local_port;
if (contact) belle_sip_header_contact_set_unknown(contact,!chan->learnt_ip_port);
}else{
ip=chan->local_ip;
port=chan->local_port;
}
belle_sip_uri_set_host(uri, ip);
transport = belle_sip_channel_get_transport_name_lower_case(chan);
/* Enforce a transport name in "sip" scheme.
* RFC3263 (locating SIP servers) says that UDP SHOULD be used in absence of transport parameter,
* when port or numeric IP are provided. It is a SHOULD, not a must.
* We need in this case that the automatic Contact exactly matches the socket that is going
* to be used for sending the messages.
* TODO: we may need to do the same for sips, but dtls is currently not supported.
**/
if (!belle_sip_uri_is_secure(uri))
belle_sip_uri_set_transport_param(uri,transport);
if (port!=belle_sip_listening_point_get_well_known_port(transport)) {
belle_sip_uri_set_port(uri,port);
}else{
belle_sip_uri_set_port(uri,0);
}
}
static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_message_t *msg){ static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_message_t *msg){
belle_sip_header_contact_t* contact; belle_sip_header_address_t* contact;
belle_sip_header_content_length_t* content_length = (belle_sip_header_content_length_t*)belle_sip_message_get_header(msg,"Content-Length"); belle_sip_header_content_length_t* content_length = (belle_sip_header_content_length_t*)belle_sip_message_get_header(msg,"Content-Length");
belle_sip_uri_t* contact_uri;
const belle_sip_list_t *contacts; const belle_sip_list_t *contacts;
const char *ip=NULL; belle_sip_header_refer_to_t *refer_to;
int port=0;
belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj); belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj);
if (belle_sip_message_is_request(msg)){ if (belle_sip_message_is_request(msg)){
...@@ -473,52 +520,12 @@ static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_chan ...@@ -473,52 +520,12 @@ static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_chan
} }
for (contacts=belle_sip_message_get_headers(msg,"Contact");contacts!=NULL;contacts=contacts->next){ for (contacts=belle_sip_message_get_headers(msg,"Contact");contacts!=NULL;contacts=contacts->next){
const char *transport; contact=(belle_sip_header_address_t*)contacts->data;
contact=(belle_sip_header_contact_t*)contacts->data; fix_automatic_header_address(prov, chan, contact);
if (belle_sip_header_contact_is_wildcard(contact)) continue;
/* fix the contact if in automatic mode or null uri (for backward compatibility)*/
if (!(contact_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)contact))) {
contact_uri = belle_sip_uri_new();
belle_sip_header_address_set_uri((belle_sip_header_address_t*)contact,contact_uri);
belle_sip_header_contact_set_automatic(contact,TRUE);
}else if (belle_sip_uri_get_host(contact_uri)==NULL){
belle_sip_header_contact_set_automatic(contact,TRUE);
}
if (!belle_sip_header_contact_get_automatic(contact)) continue;
if (ip==NULL){
if (prov->nat_helper){
ip=chan->public_ip ? chan->public_ip : chan->local_ip;
port=chan->public_port ? chan->public_port : chan->local_port;
belle_sip_header_contact_set_unknown(contact,!chan->learnt_ip_port);
}else{
ip=chan->local_ip;
port=chan->local_port;
}
}
belle_sip_uri_set_host(contact_uri,ip);
transport=belle_sip_channel_get_transport_name_lower_case(chan);
/* Enforce a transport name in "sip" scheme.
* RFC3263 (locating SIP servers) says that UDP SHOULD be used in absence of transport parameter,
* when port or numeric IP are provided. It is a SHOULD, not a must.
* We need in this case that the automatic Contact exactly matches the socket that is going
* to be used for sending the messages.
* TODO: we may need to do the same for sips, but dtls is currently not supported.
**/
if (!belle_sip_uri_is_secure(contact_uri))
belle_sip_uri_set_transport_param(contact_uri,transport);
if (port!=belle_sip_listening_point_get_well_known_port(transport)) {
belle_sip_uri_set_port(contact_uri,port);
}else{
belle_sip_uri_set_port(contact_uri,0);
}
} }
refer_to = belle_sip_message_get_header_by_type(msg, belle_sip_header_refer_to_t);
if (refer_to) fix_automatic_header_address(prov, chan, (belle_sip_header_address_t*)refer_to);
/* /*
* According to RFC3261, content-length is mandatory for stream based transport, but optional for datagram transport. * According to RFC3261, content-length is mandatory for stream based transport, but optional for datagram transport.
* However some servers (opensips) are confused when they receive a SIP/UDP packet without Content-Length (they shouldn't). * However some servers (opensips) are confused when they receive a SIP/UDP packet without Content-Length (they shouldn't).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment