Commit 4ec52ea7 authored by Simon Morlat's avatar Simon Morlat
Browse files

Merge branch 'master' of git.sv.gnu.org:/srv/git/linphone

parents 451c2ae3 e545c638
......@@ -1417,13 +1417,13 @@ static int apply_transports(LinphoneCore *lc){
sal_unlisten_ports (sal);
if (tr->udp_port>0){
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportDatagram,FALSE)!=0){
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
transport_error(lc,"UDP",tr->udp_port);
return -1;
}
}
if (tr->tcp_port>0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportStream,FALSE)!=0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
transport_error(lc,"TCP",tr->tcp_port);
}
}
......
......@@ -259,7 +259,7 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
linphone_core_get_sip_transports(obj->lc,&tr);
if (tr.udp_port <= 0 && tr.tcp_port>0) {
sal_address_add_param(contact,"transport","tcp");
sal_address_set_param(contact,"transport","TCP");
}
ret=linphone_address_as_string(contact);
linphone_address_destroy(contact);
......
......@@ -24,7 +24,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**/
#include "sal.h"
const char* sal_transport_to_string(SalTransport transport) {
switch (transport) {
case SalTransportUDP:return "UDP";
case SalTransportTCP: return "TCP";
case SalTransportTLS:return "TLS";
case SalTransportDTLS:return "DTLS";
default: {
ms_fatal("Unexpected transport [%i]",transport);
return NULL;
}
}
}
SalTransport sal_transport_parse(const char* param) {
if (strcasecmp("UDP",param)==0) return SalTransportUDP;
if (strcasecmp("TCP",param)==0) return SalTransportTCP;
if (strcasecmp("TLS",param)==0) return SalTransportTLS;
if (strcasecmp("DTLS",param)==0) return SalTransportDTLS;
ms_error("Unkown transport type[%s], returning UDP", param);
return SalTransportUDP;
}
SalMediaDescription *sal_media_description_new(){
SalMediaDescription *md=ms_new0(SalMediaDescription,1);
md->refcount=1;
......
......@@ -40,6 +40,15 @@ struct SalAddress;
typedef struct SalAddress SalAddress;
typedef enum {
SalTransportUDP, /*UDP*/
SalTransportTCP, /*TCP*/
SalTransportTLS, /*TLS*/
SalTransportDTLS /*DTLS*/
}SalTransport;
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
/* Address manipulation API*/
SalAddress * sal_address_new(const char *uri);
SalAddress * sal_address_clone(const SalAddress *addr);
......@@ -49,7 +58,8 @@ char *sal_address_get_display_name_unquoted(const SalAddress *addr);
const char *sal_address_get_username(const SalAddress *addr);
const char *sal_address_get_domain(const SalAddress *addr);
const char * sal_address_get_port(const SalAddress *addr);
int sal_address_get_port_int(const SalAddress *uri);
int sal_address_get_port_int(const SalAddress *addr);
SalTransport sal_address_get_transport(const SalAddress* addr);
void sal_address_set_display_name(SalAddress *addr, const char *display_name);
void sal_address_set_username(SalAddress *addr, const char *username);
......@@ -60,8 +70,8 @@ void sal_address_clean(SalAddress *addr);
char *sal_address_as_string(const SalAddress *u);
char *sal_address_as_string_uri_only(const SalAddress *u);
void sal_address_destroy(SalAddress *u);
void sal_address_add_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_transport(SalAddress* addr,SalTransport transport);
Sal * sal_init();
......@@ -69,10 +79,6 @@ void sal_uninit(Sal* sal);
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
typedef enum {
SalTransportDatagram,
SalTransportStream
}SalTransport;
typedef enum {
SalAudio,
......
......@@ -32,6 +32,10 @@ static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
static void text_received(Sal *sal, eXosip_event_t *ev);
static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer);
static void update_contact_from_response(SalOp *op, osip_message_t *response);
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
void *data;
while(!osip_list_eol(l,0)) {
......@@ -351,11 +355,11 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
int keepalive = ctx->keepalive_period;
switch (tr) {
case SalTransportDatagram:
case SalTransportUDP:
proto=IPPROTO_UDP;
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
break;
case SalTransportStream:
case SalTransportTCP:
proto= IPPROTO_TCP;
keepalive=-1;
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
......@@ -424,7 +428,8 @@ void sal_use_rport(Sal *ctx, bool_t use_rports){
void sal_use_101(Sal *ctx, bool_t use_101){
ctx->use_101=use_101;
}
static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){
static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
osip_via_t *via=NULL;
osip_generic_param_t *param=NULL;
const char *rport=NULL;
......@@ -434,10 +439,7 @@ static int extract_received_rport(osip_message_t *msg, const char **received, in
osip_message_get_via(msg,0,&via);
if (!via) return -1;
/* it is useless to do that with tcp since client socket might have a different port
than the server socket.
*/
if (strcasecmp(via->protocol,"tcp")==0) return -1;
*transport = sal_transport_parse(via->protocol);
if (via->port && via->port[0]!='\0')
*rportval=atoi(via->port);
......@@ -800,9 +802,13 @@ int sal_call_terminate(SalOp *h){
}
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
if (h->pending_auth){
if (h->pending_auth){
push_auth_to_exosip(info);
eXosip_lock();
/*FIXME exosip does not take into account this update register message*/
if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
update_contact_from_response(h,h->pending_auth->response);
};
eXosip_default_action(h->pending_auth);
eXosip_unlock();
ms_message("eXosip_default_action() done");
......@@ -826,7 +832,8 @@ static void set_network_origin(SalOp *op, osip_message_t *req){
const char *received=NULL;
int rport=5060;
char origin[64];
if (extract_received_rport(req,&received,&rport)!=0){
SalTransport transport;
if (extract_received_rport(req,&received,&rport,&transport)!=0){
osip_via_t *via=NULL;
char *tmp;
osip_message_get_via(req,0,&via);
......@@ -834,7 +841,11 @@ static void set_network_origin(SalOp *op, osip_message_t *req){
tmp=osip_via_get_port(via);
if (tmp) rport=atoi(tmp);
}
snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
if (transport != SalTransportUDP) {
snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
} else {
snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
}
__sal_op_set_network_origin(op,origin);
}
......@@ -992,7 +1003,8 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){
static void update_contact_from_response(SalOp *op, osip_message_t *response){
const char *received;
int rport;
if (extract_received_rport(response,&received,&rport)==0){
SalTransport transport;
if (extract_received_rport(response,&received,&rport,&transport)==0){
const char *contact=sal_op_get_contact(op);
if (!contact){
/*no contact given yet, use from instead*/
......@@ -1003,8 +1015,9 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){
char *tmp;
sal_address_set_domain(addr,received);
sal_address_set_port_int(addr,rport);
sal_address_set_transport(addr,transport);
tmp=sal_address_as_string(addr);
ms_message("Contact address updated to %s for this dialog",tmp);
ms_message("Contact address updated to %s",tmp);
sal_op_set_contact(op,tmp);
sal_address_destroy(addr);
ms_free(tmp);
......@@ -1601,39 +1614,22 @@ static void masquerade_via(osip_message_t *msg, const char *ip, const char *port
}
}
static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
osip_message_t *msg;
const char *received;
int rport;
osip_contact_t *ctt=NULL;
char *tmp;
char port[20];
SalAddress *addr;
Sal *sal=op->base.root;
if (sal->double_reg==FALSE) return FALSE;
if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE;
osip_message_get_contact(orig_request,0,&ctt);
if (strcmp(ctt->url->host,received)==0){
/*ip address matches, check ports*/
const char *contact_port=ctt->url->port;
if (contact_port==NULL || contact_port[0]=='\0')
contact_port="5060";
if (atoi(contact_port)==rport){
ms_message("Register has up to date contact, doing nothing.");
return FALSE;
}else ms_message("ports do not match, need to update the register (%s <> %i)", contact_port,rport);
}
static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer) {
osip_contact_t *ctt=NULL;
const char *received;
int rport;
SalTransport transport;
char port[20];
if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
eXosip_lock();
msg=NULL;
eXosip_register_build_register(op->rid,op->expires,&msg);
if (msg==NULL){
eXosip_unlock();
ms_warning("Fail to create a contact updated register.");
return FALSE;
}
osip_message_get_contact(msg,0,&ctt);
osip_message_get_contact(request,0,&ctt);
if (ctt == NULL) {
/*nothing to update*/
eXosip_unlock();
return FALSE;
}
if (ctt->url->host!=NULL){
osip_free(ctt->url->host);
}
......@@ -1643,19 +1639,69 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori
}
snprintf(port,sizeof(port),"%i",rport);
ctt->url->port=osip_strdup(port);
if (op->masquerade_via) masquerade_via(msg,received,port);
eXosip_register_send_register(op->rid,msg);
if (op->masquerade_via) masquerade_via(request,received,port);
if (transport != SalTransportUDP) {
sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
}
eXosip_unlock();
return TRUE;
}
static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
osip_contact_t *ctt=NULL;
SalAddress* ori_contact_address=NULL;
const char *received;
int rport;
SalTransport transport;
char* tmp;
osip_message_t *msg=NULL;
Sal* sal=op->base.root;
if (sal->double_reg==FALSE ) return FALSE;
if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
osip_message_get_contact(orig_request,0,&ctt);
osip_contact_to_str(ctt,&tmp);
addr=sal_address_new(tmp);
osip_free(tmp);
sal_address_clean(addr);
tmp=sal_address_as_string(addr);
sal_op_set_contact(op,tmp);
sal_address_destroy(addr);
ms_message("Resending new register with updated contact %s",tmp);
ms_free(tmp);
return TRUE;
ori_contact_address = sal_address_new((const char*)tmp);
osip_free(tmp);
/*check if contact is up to date*/
if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
&& sal_address_get_port_int(ori_contact_address) == rport
&& sal_address_get_transport(ori_contact_address) == transport) {
ms_message("Register has up to date contact, doing nothing.");
return FALSE;
} else ms_message("contact do not match, need to update the register (%s with %s:%i;transport=%s)"
,tmp
,received
,rport
,sal_transport_to_string(transport));
sal_address_destroy(ori_contact_address);
if (transport == SalTransportUDP) {
eXosip_lock();
eXosip_register_build_register(op->rid,op->expires,&msg);
if (msg==NULL){
eXosip_unlock();
ms_warning("Fail to create a contact updated register.");
return FALSE;
}
if (fix_message_contact(op,msg,last_answer)) {
eXosip_register_send_register(op->rid,msg);
ms_message("Resending new register with updated contact");
return TRUE;
} else {
ms_warning("Fail to send updated register.");
eXosip_unlock();
return FALSE;
}
}
update_contact_from_response(op,last_answer);
return FALSE;
}
static void registration_success(Sal *sal, eXosip_event_t *ev){
......@@ -2081,8 +2127,16 @@ char *sal_address_as_string_uri_only(const SalAddress *u){
osip_free(tmp);
return ret;
}
void sal_address_add_param(SalAddress *u,const char* name,const char* value) {
osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value));
void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
osip_uri_param_t *param=NULL;
osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,&param);
if (param == NULL){
osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value));
} else {
osip_free(param->gvalue);
param->gvalue=osip_strdup(value);
}
}
void sal_address_destroy(SalAddress *u){
......@@ -2110,6 +2164,19 @@ int sal_address_get_port_int(const SalAddress *uri) {
return 5060;
}
}
SalTransport sal_address_get_transport(const SalAddress* addr) {
const osip_from_t *u=(const osip_from_t*)addr;
osip_uri_param_t *transport_param=NULL;
osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
if (transport_param == NULL){
return SalTransportUDP;
} else {
return sal_transport_parse(transport_param->gvalue);
}
}
void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
}
/* sends a reinvite. Local media description may have changed by application since call establishment*/
int sal_call_update(SalOp *h, const char *subject){
......
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