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
*/
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
/**
* 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);
......@@ -599,7 +608,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#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;
......@@ -610,7 +619,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#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;
......@@ -621,7 +630,7 @@ BELLESIP_EXPORT void belle_sip_header_subscription_state_set_retry_after(belle_s
#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;
......
......@@ -187,6 +187,7 @@ struct _belle_sip_header_address {
char* displayname;
belle_sip_uri_t* uri;
belle_generic_uri_t* absolute_uri;
unsigned char automatic;
};
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
}
}
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) {
return address->absolute_uri;
}
......@@ -365,9 +374,8 @@ GET_SET_STRING(belle_sip_header_allow,method);
struct _belle_sip_header_contact {
belle_sip_header_address_t address;
unsigned char wildcard;
unsigned char automatic;
unsigned char unknown;
unsigned char pad[1];
unsigned char pad[2];
};
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){
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) {
......@@ -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){
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){
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){
......
......@@ -449,57 +449,35 @@ static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_si
return 0;
}
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_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;
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_provider_t *prov=BELLE_SIP_PROVIDER(obj);
if (belle_sip_message_is_request(msg)){
const belle_sip_list_t *rroutes;
/*probably better to be in channel*/
fix_outgoing_via(prov, chan, msg);
for (rroutes=belle_sip_message_get_headers(msg,"Record-Route");rroutes!=NULL;rroutes=rroutes->next){
belle_sip_header_record_route_t* rr=(belle_sip_header_record_route_t*)rroutes->data;
if (belle_sip_header_record_route_get_auto_outgoing(rr)) {
belle_sip_uri_t *rr_uri = belle_sip_channel_create_routable_uri(chan);
belle_sip_header_address_set_uri((belle_sip_header_address_t*) rr, rr_uri);
}
}
}
for (contacts=belle_sip_message_get_headers(msg,"Contact");contacts!=NULL;contacts=contacts->next){
belle_sip_uri_t* uri;
const char *transport;
contact=(belle_sip_header_contact_t*)contacts->data;
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 (belle_sip_header_contact_is_wildcard(contact)) continue;
if (contact && belle_sip_header_contact_is_wildcard(contact)) return;
/* 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 (!(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_contact_get_automatic(contact)) continue;
if (!belle_sip_header_address_get_automatic(addr)) return;
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);
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(contact_uri,ip);
transport=belle_sip_channel_get_transport_name_lower_case(chan);
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,
......@@ -509,16 +487,45 @@ static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_chan
* 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 (!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(contact_uri,port);
belle_sip_uri_set_port(uri,port);
}else{
belle_sip_uri_set_port(contact_uri,0);
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){
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");
const belle_sip_list_t *contacts;
belle_sip_header_refer_to_t *refer_to;
belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj);
if (belle_sip_message_is_request(msg)){
const belle_sip_list_t *rroutes;
/*probably better to be in channel*/
fix_outgoing_via(prov, chan, msg);
for (rroutes=belle_sip_message_get_headers(msg,"Record-Route");rroutes!=NULL;rroutes=rroutes->next){
belle_sip_header_record_route_t* rr=(belle_sip_header_record_route_t*)rroutes->data;
if (belle_sip_header_record_route_get_auto_outgoing(rr)) {
belle_sip_uri_t *rr_uri = belle_sip_channel_create_routable_uri(chan);
belle_sip_header_address_set_uri((belle_sip_header_address_t*) rr, rr_uri);
}
}
}
for (contacts=belle_sip_message_get_headers(msg,"Contact");contacts!=NULL;contacts=contacts->next){
contact=(belle_sip_header_address_t*)contacts->data;
fix_automatic_header_address(prov, chan, contact);
}
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.
* 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