Commit d0095948 authored by Simon Morlat's avatar Simon Morlat

Allow the tunnel mode to work with any proxy config (except for sips destinations)

fix the tunnel tests, that were not working correctly.
parent c828b54b
......@@ -106,6 +106,7 @@ void TunnelManager::startClient() {
}
mTunnelClient->setHttpProxy(mHttpProxyHost.c_str(), mHttpProxyPort, mHttpUserName.c_str(), mHttpPasswd.c_str());
mTunnelClient->start();
sal_set_tunnel(mCore->sal, mTunnelClient);
}
bool TunnelManager::isConnected() const {
......@@ -185,12 +186,13 @@ void TunnelManager::processTunnelEvent(const Event &ev){
ms_message("TunnelManager: tunnel is connected");
if(mState == connecting) {
linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories);
mState = ready;
if(mTunnelizeSipPackets) {
doUnregistration();
sal_enable_tunnel(mCore->sal, mTunnelClient);
_linphone_core_apply_transports(mCore);
doRegistration();
}
mState = ready;
}
} else {
ms_error("TunnelManager: tunnel has been disconnected");
......@@ -219,17 +221,15 @@ void TunnelManager::setMode(LinphoneTunnelMode mode) {
case LinphoneTunnelModeDisable:
if(mState == ready) {
linphone_core_set_rtp_transport_factories(mCore,NULL);
mState = disabled;
mMode = mode;
if(mTunnelizeSipPackets) {
doUnregistration();
sal_disable_tunnel(mCore->sal);
_linphone_core_apply_transports(mCore);
}
sal_set_tunnel(mCore->sal,NULL);
delete mTunnelClient;
mTunnelClient=NULL;
if(mTunnelizeSipPackets) {
doRegistration();
}
mState = disabled;
mMode = mode;
} else {
ms_error("TunnelManager: could not change mode. Bad state");
}
......@@ -385,6 +385,18 @@ bool TunnelManager::startAutoDetection() {
return true;
}
bool TunnelManager::isActivated() const{
switch(getMode()){
case LinphoneTunnelModeAuto:
return !mState==disabled;
case LinphoneTunnelModeDisable:
return false;
case LinphoneTunnelModeEnable:
return true;
}
return false;
}
void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd) {
mHttpUserName=username?username:"";
mHttpPasswd=passwd?passwd:"";
......@@ -392,7 +404,7 @@ void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd
}
void TunnelManager::tunnelizeSipPackets(bool enable){
mTunnelizeSipPackets = enable;
mTunnelizeSipPackets = enable;
}
bool TunnelManager::tunnelizeSipPacketsEnabled() const {
......
......@@ -142,6 +142,7 @@ namespace belledonnecomm {
*/
bool isConnected() const;
bool isActivated() const;
private:
enum State {
disabled,
......@@ -199,10 +200,6 @@ namespace belledonnecomm {
LinphoneRtpTransportFactories mTransportFactories;
Mutex mMutex;
std::queue<Event> mEvq;
#ifndef USE_BELLESIP
TunnelSocket *mSipSocket;
eXosip_transport_hooks_t mExosipTransport;
#endif
};
/**
......
......@@ -554,19 +554,24 @@ int sal_transport_available(Sal *sal, SalTransport t){
return FALSE;
}
int sal_add_listen_port(Sal *ctx, SalAddress* addr){
static int sal_add_listen_port(Sal *ctx, SalAddress* addr, bool_t is_tunneled){
int result;
belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack,
belle_sip_listening_point_t* lp;
if (is_tunneled){
if (sal_address_get_transport(addr)!=SalTransportUDP){
ms_error("Tunneled mode is only available for UDP kind of transports.");
return -1;
}
lp = belle_sip_tunnel_listening_point_new(ctx->stack, ctx->tunnel_client);
if (!lp){
ms_error("Could not create tunnel listening point.");
return -1;
}
}else{
lp = belle_sip_stack_create_listening_point(ctx->stack,
sal_address_get_domain(addr),
sal_address_get_port(addr),
sal_transport_to_string(sal_address_get_transport(addr)));
if (sal_address_get_port(addr)==-1 && lp==NULL){
int random_port=(0xDFFF&ortp_random())+1024;
ms_warning("This version of belle-sip doesn't support random port, choosing one here.");
lp = belle_sip_stack_create_listening_point(ctx->stack,
sal_address_get_domain(addr),
random_port,
sal_transport_to_string(sal_address_get_transport(addr)));
}
if (lp) {
belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive);
......@@ -578,13 +583,13 @@ int sal_add_listen_port(Sal *ctx, SalAddress* addr){
return result;
}
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure) {
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled) {
SalAddress* sal_addr = sal_address_new(NULL);
int result;
sal_address_set_domain(sal_addr,addr);
sal_address_set_port(sal_addr,port);
sal_address_set_transport(sal_addr,tr);
result = sal_add_listen_port(ctx,sal_addr);
result = sal_add_listen_port(ctx, sal_addr, is_tunneled);
sal_address_destroy(sal_addr);
return result;
}
......@@ -646,43 +651,15 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value){
}
}
}
int sal_enable_tunnel(Sal *ctx, void *tunnelclient) {
int sal_set_tunnel(Sal *ctx, void *tunnelclient) {
#ifdef TUNNEL_ENABLED
belle_sip_listening_point_t *lp_udp = NULL;
if(ctx->lp_tunnel != NULL) {
ortp_error("sal_enable_tunnel(): tunnel is already enabled");
return -1;
}
while((lp_udp = belle_sip_provider_get_listening_point(ctx->prov, "udp")) != NULL) {
belle_sip_object_ref(lp_udp);
belle_sip_provider_remove_listening_point(ctx->prov, lp_udp);
ctx->udp_listening_points = ms_list_append(ctx->udp_listening_points, lp_udp);
}
ctx->lp_tunnel = belle_sip_tunnel_listening_point_new(ctx->stack, tunnelclient);
if(ctx->lp_tunnel == NULL) return -1;
belle_sip_listening_point_set_keep_alive(ctx->lp_tunnel, ctx->keep_alive);
belle_sip_provider_add_listening_point(ctx->prov, ctx->lp_tunnel);
belle_sip_object_ref(ctx->lp_tunnel);
ctx->tunnel_client=tunnelclient;
return 0;
#else
return 0;
#endif
}
void sal_disable_tunnel(Sal *ctx) {
#ifdef TUNNEL_ENABLED
MSList *it;
if(ctx->lp_tunnel) {
belle_sip_provider_remove_listening_point(ctx->prov, ctx->lp_tunnel);
belle_sip_object_unref(ctx->lp_tunnel);
ctx->lp_tunnel = NULL;
for(it=ctx->udp_listening_points; it!=NULL; it=it->next) {
belle_sip_provider_add_listening_point(ctx->prov, (belle_sip_listening_point_t *)it->data);
}
ms_list_free_with_data(ctx->udp_listening_points, belle_sip_object_unref);
ctx->udp_listening_points = NULL;
}
return -1;
#endif
}
/**
* returns keepalive period in ms
* 0 desactiaved
......
......@@ -33,8 +33,7 @@ struct Sal{
belle_sip_provider_t *prov;
belle_sip_header_user_agent_t* user_agent;
belle_sip_listener_t *listener;
belle_sip_listening_point_t *lp_tunnel;
MSList *udp_listening_points;
void *tunnel_client;
void *up; /*user pointer*/
int session_expires;
unsigned int keep_alive;
......
......@@ -285,6 +285,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
const MSList *elem=sal_op_get_route_addresses(op);
const char *transport;
const char *method=belle_sip_request_get_method(request);
belle_sip_listening_point_t *udplp=belle_sip_provider_get_listening_point(prov,"UDP");
if (elem) {
outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data);
......@@ -297,7 +298,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
/*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use
* the first available transport*/
if (!belle_sip_uri_is_secure(next_hop_uri)){
if (belle_sip_provider_get_listening_point(prov,"UDP")==0){
if (udplp==NULL){
if (belle_sip_provider_get_listening_point(prov,"TCP")!=NULL){
transport="tcp";
}else if (belle_sip_provider_get_listening_point(prov,"TLS")!=NULL ){
......@@ -309,6 +310,11 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
belle_sip_uri_set_transport_param(next_hop_uri,transport);
}
}
}else{
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(udplp,belle_sip_tunnel_listening_point_t)){
/* our tunnel mode only supports UDP. Force transport to be set to UDP */
belle_sip_uri_set_transport_param(next_hop_uri,"udp");
}
}
if ((strcmp(method,"REGISTER")==0 || strcmp(method,"SUBSCRIBE")==0) && transport &&
(strcasecmp(transport,"TCP")==0 || strcasecmp(transport,"TLS")==0)){
......
......@@ -246,6 +246,10 @@ bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->isConnected();
}
bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->isActivated();
}
static OrtpLogFunc tunnelOrtpLogHandler=NULL;
/*
......
......@@ -188,6 +188,15 @@ LINPHONE_PUBLIC void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTu
**/
LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel);
/**
* Returns whether the tunnel is activated. If mode is set to auto, this gives indication whether the automatic detection determined
* that tunnel was necessary or not.
* @param tunnel the tunnel
* @return TRUE if tunnel is in use, FALSE otherwise.
**/
LINPHONE_PUBLIC bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunnel);
/**
* Check whether the tunnel is connected
* @param tunnel LinphoneTunnel object
......
......@@ -2975,7 +2975,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
linphone_call_handle_stream_events(call,0);
linphone_call_handle_stream_events(call,1);
if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 )
if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL
&& call->audiostream->ms.state==MSStreamStarted && disconnect_timeout>0 )
disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout);
if (disconnected)
linphone_core_disconnected(call->core,call);
......
......@@ -2151,7 +2151,7 @@ static bool_t transports_unchanged(const LCSipTransports * tr1, const LCSipTrans
tr2->tls_port==tr1->tls_port;
}
static int apply_transports(LinphoneCore *lc){
int _linphone_core_apply_transports(LinphoneCore *lc){
Sal *sal=lc->sal;
const char *anyaddr;
LCSipTransports *tr=&lc->sip_conf.transports;
......@@ -2165,20 +2165,26 @@ static int apply_transports(LinphoneCore *lc){
anyaddr="0.0.0.0";
sal_unlisten_ports(sal);
if (tr->udp_port!=0){
if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
transport_error(lc,"udp",tr->udp_port);
if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)){
if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,TRUE)!=0){
transport_error(lc,"udp+tunnel",tr->udp_port);
}
}
if (tr->tcp_port!=0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
transport_error(lc,"tcp",tr->tcp_port);
}else{
if (tr->udp_port!=0){
if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){
transport_error(lc,"udp",tr->udp_port);
}
}
}
if (linphone_core_sip_transport_supported(lc,LinphoneTransportTls)){
if (tr->tls_port!=0){
if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,TRUE)!=0){
transport_error(lc,"tls",tr->tls_port);
if (tr->tcp_port!=0){
if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){
transport_error(lc,"tcp",tr->tcp_port);
}
}
if (linphone_core_sip_transport_supported(lc,LinphoneTransportTls)){
if (tr->tls_port!=0){
if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,FALSE)!=0){
transport_error(lc,"tls",tr->tls_port);
}
}
}
}
......@@ -2231,7 +2237,7 @@ int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * t
}
if (lc->sal==NULL) return 0;
return apply_transports(lc);
return _linphone_core_apply_transports(lc);
}
/**
......@@ -2296,7 +2302,7 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
lc->sip_conf.ipv6_enabled=val;
if (lc->sal){
/* we need to update the sip stack */
apply_transports(lc);
_linphone_core_apply_transports(lc);
}
/*update the localip immediately for the network monitor to avoid to "discover" later that we switched to ipv6*/
linphone_core_get_local_ip(lc,AF_UNSPEC,NULL,lc->localip);
......@@ -6830,7 +6836,7 @@ void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){
sal_set_dscp(lc->sal,dscp);
if (linphone_core_ready(lc)){
lp_config_set_int_hex(lc->config,"sip","dscp",dscp);
apply_transports(lc);
_linphone_core_apply_transports(lc);
}
}
......
......@@ -414,7 +414,7 @@ void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call);
void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md);
void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call);
void linphone_call_set_state_base(LinphoneCall *call, LinphoneCallState cstate, const char *message,bool_t silently);
int _linphone_core_apply_transports(LinphoneCore *lc);
const char * linphone_core_get_identity(LinphoneCore *lc);
void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose);
......
......@@ -65,7 +65,7 @@ typedef enum {
SalTransportUDP, /*UDP*/
SalTransportTCP, /*TCP*/
SalTransportTLS, /*TLS*/
SalTransportDTLS /*DTLS*/
SalTransportDTLS, /*DTLS*/
}SalTransport;
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
......@@ -516,7 +516,7 @@ void sal_signing_key_delete(SalSigningKey *key);
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure);
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled);
int sal_get_listening_port(Sal *ctx, SalTransport tr);
int sal_unlisten_ports(Sal *ctx);
int sal_transport_available(Sal *ctx, SalTransport t);
......@@ -533,8 +533,7 @@ void sal_append_stack_string_to_user_agent(Sal *ctx);
/*keepalive period in ms*/
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
int sal_enable_tunnel(Sal *ctx, void *tunnelclient);
void sal_disable_tunnel(Sal *ctx);
int sal_set_tunnel(Sal *ctx, void *tunnelclient);
/*Default value is true*/
void sal_enable_sip_update_method(Sal *ctx,bool_t value);
......
oRTP @ 49796063
Subproject commit 99edd188a5f0c708bf044d4c39da1aac436acba4
Subproject commit 497960634594593bd5441804fc548587b06389c6
......@@ -61,7 +61,6 @@ static char* get_public_contact_ip(LinphoneCore* lc) {
}
static void call_with_transport_base(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption) {
if (linphone_core_tunnel_available()){
char *tmp_char;
LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCoreManager *marie = linphone_core_manager_new( "marie_rc");
LinphoneCall *pauline_call;
......@@ -81,28 +80,23 @@ static void call_with_transport_base(LinphoneTunnelMode tunnel_mode, bool_t with
LinphoneTunnel *tunnel = linphone_core_get_tunnel(pauline->lc);
LinphoneTunnelConfig *config = linphone_tunnel_config_new();
/*tunnel works only in UDP mode*/
linphone_proxy_config_edit(proxy);
linphone_address_set_transport(server_addr, LinphoneTransportUdp);
linphone_address_set_transport(route, LinphoneTransportUdp);
tmp_char = linphone_address_as_string(server_addr);
linphone_proxy_config_set_server_addr(proxy, tmp_char);
ms_free(tmp_char);
tmp_char = linphone_address_as_string(route);
linphone_proxy_config_set_route(proxy, tmp_char);
ms_free(tmp_char);
linphone_tunnel_config_set_host(config, "tunnel.linphone.org");
linphone_tunnel_config_set_port(config, 443);
linphone_tunnel_config_set_remote_udp_mirror_port(config, 12345);
linphone_tunnel_add_server(tunnel, config);
linphone_tunnel_set_mode(tunnel, tunnel_mode);
linphone_tunnel_enable_sip(tunnel, with_sip);
linphone_proxy_config_done(proxy);
/*enabling the tunnel cause another REGISTER to be made*/
CU_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneRegistrationOk,2));
/*
* Enabling the tunnel with sip cause another REGISTER to be made.
* In automatic mode, the udp test should conclude (assuming we have a normal network), that no
* tunnel is needed. Thus the number of registrations should stay to 1.
* The library is missing a notification of "tunnel connectivity test finished" to enable the
* full testing of the automatic mode.
*/
if(tunnel_mode == LinphoneTunnelModeEnable) {
if(tunnel_mode == LinphoneTunnelModeEnable && with_sip) {
CU_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneRegistrationOk,2));
/* Ensure that we did use the tunnel. If so, we should see contact changed from:
Contact: <sip:pauline@192.168.0.201>;.[...]
To:
......
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