mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-20 20:48:07 +00:00
Merge branch 'master' of git.sv.gnu.org:/srv/git/linphone
This commit is contained in:
commit
4ec52ea7f7
5 changed files with 160 additions and 67 deletions
|
|
@ -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,¶m);
|
||||
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){
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue