Commit cf902275 authored by Gautier Pelloux-Prayer's avatar Gautier Pelloux-Prayer
Browse files

tunnel: add a test when having several tunnel configs

parent 0c389ec6
......@@ -148,7 +148,8 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :
mTunnelClient(NULL),
mHttpProxyPort(0),
mVTable(NULL),
mLongRunningTaskId(0)
mLongRunningTaskId(0),
mSimulateUdpLoss(false)
{
linphone_core_add_iterate_hook(mCore,(LinphoneCoreIterateHook)sOnIterate,this);
mTransportFactories.audio_rtcp_func=sCreateRtpTransport;
......@@ -342,18 +343,12 @@ LinphoneTunnelMode TunnelManager::getMode() const {
void TunnelManager::processUdpMirrorEvent(const Event &ev){
if(mState != autodetecting) return;
if (ev.mData.mHaveUdp) {
ms_message("TunnelManager: UDP mirror test succeed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
if(mTunnelClient) {
if(mTunnelizeSipPackets) doUnregistration();
sal_set_tunnel(mCore->sal,NULL);
delete mTunnelClient;
mTunnelClient = NULL;
if(mTunnelizeSipPackets) doRegistration();
if (mSimulateUdpLoss || !ev.mData.mHaveUdp) {
if (mSimulateUdpLoss) {
ms_message("TunnelManager: simulate UDP lost on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
} else {
ms_message("TunnelManager: UDP mirror test failed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
}
mState = disabled;
} else {
ms_message("TunnelManager: UDP mirror test failed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
mCurrentUdpMirrorClient++;
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
ms_message("TunnelManager: trying another UDP mirror on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
......@@ -370,6 +365,16 @@ void TunnelManager::processUdpMirrorEvent(const Event &ev){
mState = ready;
}
}
} else {
ms_message("TunnelManager: UDP mirror test succeed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
if(mTunnelClient) {
if(mTunnelizeSipPackets) doUnregistration();
sal_set_tunnel(mCore->sal,NULL);
delete mTunnelClient;
mTunnelClient = NULL;
if(mTunnelizeSipPackets) doRegistration();
}
mState = disabled;
}
}
......@@ -390,6 +395,7 @@ void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) {
void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) {
TunnelManager *tunnel = bcTunnel(linphone_core_get_tunnel(lc));
if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto && tunnel->mState != connecting && tunnel->mState != autodetecting) {
LOGI("TunnelManager: Network is now reachable, starting auto detection");
tunnel->startAutoDetection();
tunnel->mState = autodetecting;
}
......@@ -455,3 +461,7 @@ void TunnelManager::setHttpProxy(const char *host,int port, const char *username
LinphoneCore *TunnelManager::getLinphoneCore() const{
return mCore;
}
void TunnelManager::simulateUdpLoss(bool enabled) {
mSimulateUdpLoss = enabled;
}
......@@ -155,6 +155,9 @@ namespace belledonnecomm {
bool isConnected() const;
bool isActivated() const;
void simulateUdpLoss(bool enabled);
private:
enum State {
disabled,
......@@ -215,6 +218,7 @@ namespace belledonnecomm {
std::queue<Event> mEvq;
char mLocalAddr[64];
unsigned long mLongRunningTaskId;
bool mSimulateUdpLoss;
};
/**
......
......@@ -377,3 +377,7 @@ void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel) {
bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel) {
return linphone_tunnel_get_mode(tunnel) == LinphoneTunnelModeAuto;
}
void linphone_tunnel_simulate_udp_loss(LinphoneTunnel *tunnel, bool_t enabled) {
bcTunnel(tunnel)->simulateUdpLoss(enabled);
}
......@@ -357,6 +357,8 @@ LINPHONE_PUBLIC void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
*/
LINPHONE_PUBLIC bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC void linphone_tunnel_simulate_udp_loss(LinphoneTunnel *tunnel, bool_t enabled);
/**
* @}
**/
......
......@@ -1725,9 +1725,9 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
lc->config=lp_config_ref(config);
lc->data=userdata;
lc->ringstream_autorelease=TRUE;
linphone_core_add_friend_list(lc, NULL);
linphone_task_list_init(&lc->hooks);
internal_vtable->notify_received = linphone_core_internal_notify_received;
......@@ -3226,7 +3226,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
linphone_core_notify_display_warning(lc,_("Sorry, we have reached the maximum number of simultaneous calls"));
return NULL;
}
cp = linphone_call_params_copy(params);
real_url=linphone_address_as_string(addr);
......@@ -6568,7 +6568,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
linphone_core_iterate(lc);
ms_usleep(50000);
}
lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release);
linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down");
......@@ -6633,13 +6633,13 @@ static void linphone_core_uninit(LinphoneCore *lc)
if (lc->ringtoneplayer) {
linphone_ringtoneplayer_destroy(lc->ringtoneplayer);
}
linphone_core_free_payload_types(lc);
if (lc->supported_formats) ms_free(lc->supported_formats);
linphone_core_message_storage_close(lc);
linphone_core_call_log_storage_close(lc);
linphone_core_friends_storage_close(lc);
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
linphone_core_deactivate_log_serialization_if_needed();
ms_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy);
......@@ -7142,7 +7142,7 @@ LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCore *lc, const cha
/**
* Check if a call will need the sound resources in near future (typically an outgoing call that is awaiting
* Check if a call will need the sound resources in near future (typically an outgoing call that is awaiting
* response).
* In liblinphone, it is not possible to have two independant calls using sound device or camera at the same time.
* In order to prevent this situation, an application can use linphone_core_sound_resources_locked() to know whether
......
......@@ -23,6 +23,28 @@
#include "private.h"
#include "liblinphone_tester.h"
/* Retrieve the public IP from a given hostname */
static const char* get_ip_from_hostname(const char * tunnel_hostname){
struct addrinfo hints;
struct addrinfo *res = NULL, *it = NULL;
struct sockaddr_in *add;
char * output = NULL;
int err;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((err = getaddrinfo(tunnel_hostname, NULL, &hints, &res))){
ms_error("error while retrieving IP from %s: %s", tunnel_hostname, gai_strerror(err));
return NULL;
}
for (it=res; it!=NULL; it=it->ai_next){
add = (struct sockaddr_in *) it->ai_addr;
output = inet_ntoa( add->sin_addr );
}
freeaddrinfo(res);
return output;
}
static char* get_public_contact_ip(LinphoneCore* lc) {
const LinphoneAddress * contact = linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(lc));
BC_ASSERT_PTR_NOT_NULL(contact);
......@@ -30,24 +52,17 @@ static char* get_public_contact_ip(LinphoneCore* lc) {
}
static void call_with_tunnel_base_with_config_files(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption, bool_t with_video_and_ice, const char *marie_rc, const char *pauline_rc) {
static void call_with_tunnel_base(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption, bool_t with_video_and_ice) {
if (linphone_core_tunnel_available()){
LinphoneCoreManager *pauline = linphone_core_manager_new( pauline_rc);
LinphoneCoreManager *marie = linphone_core_manager_new( marie_rc);
LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCoreManager *marie = linphone_core_manager_new( "marie_rc");
LinphoneCall *pauline_call, *marie_call;
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(pauline->lc);
LinphoneAddress *server_addr = linphone_address_new(linphone_proxy_config_get_server_addr(proxy));
LinphoneAddress *route = linphone_address_new(linphone_proxy_config_get_route(proxy));
LinphoneAddress *tunnel_name, *tunnel_ip_addr;
const char * tunnel_ip;
const char * tunnel_ip = get_ip_from_hostname("tunnel.linphone.org");
char *public_ip, *public_ip2=NULL;
linphone_core_enable_dns_srv(pauline->lc,FALSE);
tunnel_name = linphone_address_new("sip:tunnel.wildcard2.linphone.org:443");
tunnel_ip_addr = linphone_core_manager_resolve(pauline, tunnel_name);
tunnel_ip = linphone_address_get_domain(tunnel_ip_addr);
linphone_core_enable_dns_srv(pauline->lc,TRUE);
BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneRegistrationOk,1));
public_ip = get_public_contact_ip(pauline->lc);
BC_ASSERT_STRING_NOT_EQUAL(public_ip, tunnel_ip);
......@@ -78,15 +93,13 @@ static void call_with_tunnel_base_with_config_files(LinphoneTunnelMode tunnel_mo
LinphoneTunnel *tunnel = linphone_core_get_tunnel(pauline->lc);
LinphoneTunnelConfig *config = linphone_tunnel_config_new();
linphone_tunnel_config_set_host(config, tunnel_ip);
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_tunnel_config_unref(config);
/*
* 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
......@@ -146,8 +159,6 @@ static void call_with_tunnel_base_with_config_files(LinphoneTunnelMode tunnel_mo
if(public_ip2 != NULL) ms_free(public_ip2);
linphone_address_destroy(server_addr);
linphone_address_destroy(route);
linphone_address_destroy(tunnel_name);
linphone_address_destroy(tunnel_ip_addr);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}else{
......@@ -155,9 +166,6 @@ static void call_with_tunnel_base_with_config_files(LinphoneTunnelMode tunnel_mo
}
}
static void call_with_tunnel_base(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption, bool_t with_video_and_ice) {
call_with_tunnel_base_with_config_files(tunnel_mode, with_sip, encryption, with_video_and_ice, "marie_rc", "pauline_rc");
}
static void call_with_tunnel(void) {
call_with_tunnel_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, FALSE);
......@@ -171,10 +179,6 @@ static void call_with_tunnel_without_sip(void) {
call_with_tunnel_base(LinphoneTunnelModeEnable, FALSE, LinphoneMediaEncryptionNone, FALSE);
}
static void call_with_tunnel_verify_server_certificate(void) {
call_with_tunnel_base_with_config_files(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, FALSE, "marie_rc", "pauline_tunnel_verify_server_certificate_rc");
}
static void call_with_tunnel_auto(void) {
call_with_tunnel_base(LinphoneTunnelModeAuto, TRUE, LinphoneMediaEncryptionNone, FALSE);
}
......@@ -240,11 +244,55 @@ static void tunnel_ice_call(void) {
else
ms_warning("Could not test %s because tunnel functionality is not available",__FUNCTION__);
}
static void register_on_second_tunnel(void) {
if (linphone_core_tunnel_available()) {
LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_rc");
LinphoneTunnel *tunnel = linphone_core_get_tunnel(pauline->lc);
LinphoneTunnelConfig *config = linphone_tunnel_config_new();
const char * tunnel_ip = get_ip_from_hostname("tunnel.linphone.org");
char* public_ip;
linphone_tunnel_simulate_udp_loss(tunnel, TRUE);
// add a first tunnel config with an invalid port
linphone_tunnel_config_set_port(config, 4141);
linphone_tunnel_config_set_host(config, "tunnel.linphone2.org");
linphone_tunnel_config_set_remote_udp_mirror_port(config, 54321);
linphone_tunnel_add_server(tunnel, config);
// then a proper server
linphone_tunnel_config_set_port(config, 443);
linphone_tunnel_config_set_host(config, "tunnel.linphone.org");
linphone_tunnel_config_set_remote_udp_mirror_port(config, 12345);
linphone_tunnel_add_server(tunnel, config);
linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeAuto);
linphone_tunnel_enable_sip(tunnel, TRUE);
reset_counters(&pauline->stat);
linphone_core_refresh_registers(pauline->lc);
// we should expect 2 registers: since tunnel autodetection takes several seconds, a first
// register will be made, then tunnel will be configured and another register will be fired up
BC_ASSERT_TRUE(wait_for(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk,2));
public_ip = get_public_contact_ip(pauline->lc);
BC_ASSERT_STRING_EQUAL(public_ip, tunnel_ip);
ms_free(public_ip);
linphone_tunnel_config_unref(config);
linphone_core_manager_destroy(pauline);
} else {
ms_warning("Could not test %s because tunnel functionality is not available",__FUNCTION__);
}
}
test_t tunnel_tests[] = {
TEST_NO_TAG("Simple", call_with_tunnel),
TEST_NO_TAG("With SRTP", call_with_tunnel_srtp),
TEST_NO_TAG("Without SIP", call_with_tunnel_without_sip),
TEST_NO_TAG("Verify Server Certificate", call_with_tunnel_verify_server_certificate),
TEST_NO_TAG("In automatic mode", call_with_tunnel_auto),
TEST_NO_TAG("In automatic mode with SRTP without SIP", call_with_tunnel_auto_without_sip_with_srtp),
TEST_NO_TAG("Ice call", tunnel_ice_call),
......@@ -257,6 +305,7 @@ test_t tunnel_tests[] = {
TEST_NO_TAG("DTLS ice video call", tunnel_dtls_video_ice_call),
TEST_NO_TAG("ZRTP ice video call", tunnel_zrtp_video_ice_call),
#endif
TEST_NO_TAG("Register on second tunnel", register_on_second_tunnel),
};
test_suite_t tunnel_test_suite = {"Tunnel", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
......
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