mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
Fix registration issues when tunneling is enabled
This commit is contained in:
parent
54a47a2bd7
commit
df4385b17c
5 changed files with 78 additions and 97 deletions
|
|
@ -111,6 +111,7 @@ void TunnelManager::startClient() {
|
|||
if(mTunnelizeSipPackets) {
|
||||
sal_enable_tunnel(mCore->sal, mTunnelClient);
|
||||
}
|
||||
mConnecting = true;
|
||||
}
|
||||
|
||||
void TunnelManager::stopClient(){
|
||||
|
|
@ -148,11 +149,12 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :
|
|||
mExosipTransport(NULL),
|
||||
#endif
|
||||
mMode(LinphoneTunnelModeDisable),
|
||||
mTunnelClient(NULL),
|
||||
mIsConnected(false),
|
||||
mHttpProxyPort(0),
|
||||
mPreviousRegistrationEnabled(false),
|
||||
mAutoDetecting(false),
|
||||
mConnecting(false),
|
||||
mScheduledRegistration(false),
|
||||
mTunnelizeSipPackets(true),
|
||||
mTunnelClient(NULL),
|
||||
mHttpProxyPort(0),
|
||||
mVTable(NULL)
|
||||
{
|
||||
linphone_core_add_iterate_hook(mCore,(LinphoneCoreIterateHook)sOnIterate,this);
|
||||
|
|
@ -175,79 +177,46 @@ TunnelManager::~TunnelManager(){
|
|||
linphone_vtable_destroy(mVTable);
|
||||
}
|
||||
|
||||
void TunnelManager::registration(){
|
||||
// registration occurs always after an unregistation has been made. First we
|
||||
// need to reset the previous registration mode
|
||||
void TunnelManager::doRegistration(){
|
||||
LinphoneProxyConfig* lProxy;
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
if (lProxy) {
|
||||
linphone_proxy_config_edit(lProxy);
|
||||
linphone_proxy_config_enable_register(lProxy,mPreviousRegistrationEnabled);
|
||||
linphone_proxy_config_done(lProxy);
|
||||
if(linphone_proxy_config_get_state(lProxy) != LinphoneRegistrationProgress) {
|
||||
linphone_proxy_config_refresh_register(lProxy);
|
||||
mScheduledRegistration = false;
|
||||
} else {
|
||||
mScheduledRegistration = true;
|
||||
}
|
||||
} else {
|
||||
mScheduledRegistration = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelManager::processTunnelEvent(const Event &ev){
|
||||
if (ev.mData.mConnected){
|
||||
ms_message("Tunnel is up, registering now");
|
||||
registration();
|
||||
doRegistration();
|
||||
} else {
|
||||
ms_error("Tunnel has been disconnected");
|
||||
}
|
||||
mConnecting = false;
|
||||
}
|
||||
|
||||
void TunnelManager::waitUnRegistration() {
|
||||
LinphoneProxyConfig* lProxy;
|
||||
|
||||
linphone_core_get_default_proxy(mCore, &lProxy);
|
||||
if (lProxy){
|
||||
mPreviousRegistrationEnabled=linphone_proxy_config_register_enabled(lProxy);
|
||||
if (linphone_proxy_config_is_registered(lProxy)) {
|
||||
int i=0;
|
||||
linphone_proxy_config_edit(lProxy);
|
||||
linphone_proxy_config_enable_register(lProxy,FALSE);
|
||||
linphone_proxy_config_done(lProxy);
|
||||
sal_unregister(lProxy->op);
|
||||
//make sure unregister is sent and authenticated
|
||||
do{
|
||||
linphone_core_iterate(mCore);
|
||||
ms_usleep(20000);
|
||||
if (i>100){
|
||||
ms_message("tunnel: timeout for unregistration expired, giving up");
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}while(linphone_proxy_config_is_registered(lProxy));
|
||||
ms_message("Unregistration %s", linphone_proxy_config_is_registered(lProxy)?"failed":"succeeded");
|
||||
}else{
|
||||
ms_message("No registration pending");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Each time tunnel is enabled/disabled, we need to unregister previous session and re-register. Since tunnel initialization
|
||||
is asynchronous, we temporary disable auto register while tunnel sets up, and reenable it when re-registering. */
|
||||
void TunnelManager::setMode(LinphoneTunnelMode mode) {
|
||||
if(mMode != mode) {
|
||||
waitUnRegistration();
|
||||
switch(mode) {
|
||||
case LinphoneTunnelModeEnable:
|
||||
mMode = mode;
|
||||
startClient();
|
||||
/* registration is done by proccessTunnelEvent() when the tunnel
|
||||
the tunnel succeed to connect */
|
||||
break;
|
||||
case LinphoneTunnelModeDisable:
|
||||
mMode = mode;
|
||||
stopClient();
|
||||
registration();
|
||||
doRegistration();
|
||||
break;
|
||||
case LinphoneTunnelModeAuto:
|
||||
mMode = mode;
|
||||
autoDetect();
|
||||
/* Registration is not needed because processUdpMirrorEvent() will
|
||||
call either connect() or disconnect(). Should disconnect() is called,
|
||||
processUdpMirrorEvent() care to call registratin() */
|
||||
break;
|
||||
default:
|
||||
ms_error("TunnelManager::setMode(): invalid mode (%d)", mode);
|
||||
|
|
@ -263,6 +232,9 @@ void TunnelManager::tunnelCallback(bool connected, TunnelManager *zis){
|
|||
}
|
||||
|
||||
void TunnelManager::onIterate(){
|
||||
if(mScheduledRegistration) {
|
||||
doRegistration();
|
||||
}
|
||||
mMutex.lock();
|
||||
while(!mEvq.empty()){
|
||||
Event ev=mEvq.front();
|
||||
|
|
@ -331,18 +303,18 @@ void TunnelManager::processUdpMirrorEvent(const Event &ev){
|
|||
if (ev.mData.mHaveUdp) {
|
||||
LOGI("Tunnel is not required, disabling");
|
||||
stopClient();
|
||||
registration();
|
||||
doRegistration();
|
||||
mAutoDetecting = false;
|
||||
} else {
|
||||
mCurrentUdpMirrorClient++;
|
||||
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
|
||||
// enable tunnel but also try backup server
|
||||
LOGI("Tunnel is required, enabling; Trying backup udp mirror");
|
||||
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
} else {
|
||||
LOGI("Tunnel is required, enabling; no backup udp mirror available");
|
||||
startClient();
|
||||
mAutoDetecting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -369,7 +341,10 @@ void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) {
|
|||
}
|
||||
|
||||
void TunnelManager::autoDetect() {
|
||||
// first check if udp mirrors was provisionned
|
||||
if(mAutoDetecting) {
|
||||
LOGE("Cannot start auto detection. One auto detection is going on");
|
||||
return;
|
||||
}
|
||||
if (mUdpMirrorClients.empty()) {
|
||||
LOGE("No UDP mirror server configured aborting auto detection");
|
||||
return;
|
||||
|
|
@ -377,6 +352,7 @@ void TunnelManager::autoDetect() {
|
|||
mCurrentUdpMirrorClient = mUdpMirrorClients.begin();
|
||||
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
|
||||
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
|
||||
mAutoDetecting = true;
|
||||
}
|
||||
|
||||
void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd) {
|
||||
|
|
@ -389,10 +365,9 @@ void TunnelManager::tunnelizeSipPackets(bool enable){
|
|||
if(enable != mTunnelizeSipPackets) {
|
||||
mTunnelizeSipPackets = enable;
|
||||
if(isConnected()) {
|
||||
waitUnRegistration();
|
||||
if(mTunnelizeSipPackets) sal_enable_tunnel(mCore->sal, mTunnelClient);
|
||||
else sal_disable_tunnel(mCore->sal);
|
||||
registration();
|
||||
doRegistration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,37 +167,37 @@ namespace belledonnecomm {
|
|||
|
||||
private:
|
||||
void onIterate();
|
||||
void registration();
|
||||
void waitUnRegistration();
|
||||
void processTunnelEvent(const Event &ev);
|
||||
void processUdpMirrorEvent(const Event &ev);
|
||||
void postEvent(const Event &ev);
|
||||
void doRegistration();
|
||||
void startClient();
|
||||
void stopClient();
|
||||
void autoDetect();
|
||||
void processTunnelEvent(const Event &ev);
|
||||
void processUdpMirrorEvent(const Event &ev);
|
||||
void postEvent(const Event &ev);
|
||||
|
||||
private:
|
||||
LinphoneCore* mCore;
|
||||
#ifndef USE_BELLESIP
|
||||
TunnelSocket *mSipSocket;
|
||||
eXosip_transport_hooks_t mExosipTransport;
|
||||
#endif
|
||||
LinphoneTunnelMode mMode;
|
||||
std::queue<Event> mEvq;
|
||||
std::list <ServerAddr> mServerAddrs;
|
||||
UdpMirrorClientList mUdpMirrorClients;
|
||||
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
|
||||
bool mAutoDetecting;
|
||||
bool mConnecting;
|
||||
bool mScheduledRegistration;
|
||||
bool mTunnelizeSipPackets;
|
||||
TunnelClient* mTunnelClient;
|
||||
Mutex mMutex;
|
||||
bool mIsConnected;
|
||||
LinphoneRtpTransportFactories mTransportFactories;
|
||||
std::string mHttpUserName;
|
||||
std::string mHttpPasswd;
|
||||
std::string mHttpProxyHost;
|
||||
int mHttpProxyPort;
|
||||
bool mPreviousRegistrationEnabled;
|
||||
bool mTunnelizeSipPackets;
|
||||
LinphoneCoreVTable *mVTable;
|
||||
std::list <ServerAddr> mServerAddrs;
|
||||
UdpMirrorClientList mUdpMirrorClients;
|
||||
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
|
||||
LinphoneRtpTransportFactories mTransportFactories;
|
||||
Mutex mMutex;
|
||||
std::queue<Event> mEvq;
|
||||
#ifndef USE_BELLESIP
|
||||
TunnelSocket *mSipSocket;
|
||||
eXosip_transport_hooks_t mExosipTransport;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -268,7 +268,6 @@ LINPHONE_PUBLIC void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
|
|||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -1408,12 +1408,7 @@ static bool_t can_register(LinphoneProxyConfig *cfg){
|
|||
}
|
||||
#endif //BUILD_UPNP
|
||||
if (lc->sip_conf.register_only_when_network_is_up){
|
||||
LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc);
|
||||
if (tunnel && linphone_tunnel_get_mode(tunnel)){
|
||||
return linphone_tunnel_connected(tunnel);
|
||||
}else{
|
||||
return lc->network_reachable;
|
||||
}
|
||||
return lc->network_reachable;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static char* get_public_contact_ip(LinphoneCore* lc) {
|
|||
ms_free(contact);
|
||||
return ms_strdup(contact_host_ip);
|
||||
}
|
||||
static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, LinphoneMediaEncryption encryption) {
|
||||
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");
|
||||
|
|
@ -69,7 +69,7 @@ static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, Linphon
|
|||
LinphoneAddress *server_addr = linphone_address_new(linphone_proxy_config_get_server_addr(proxy));
|
||||
LinphoneAddress *route = linphone_address_new(linphone_proxy_config_get_route(proxy));
|
||||
const char * tunnel_ip = get_ip_from_hostname("tunnel.linphone.org");
|
||||
char *public_ip;
|
||||
char *public_ip, *public_ip2=NULL;
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneRegistrationOk,1));
|
||||
public_ip = get_public_contact_ip(pauline->lc);
|
||||
|
|
@ -77,7 +77,7 @@ static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, Linphon
|
|||
|
||||
linphone_core_set_media_encryption(pauline->lc, encryption);
|
||||
|
||||
if (use_tunnel){
|
||||
if (tunnel_mode != LinphoneTunnelModeDisable){
|
||||
LinphoneTunnel *tunnel = linphone_core_get_tunnel(pauline->lc);
|
||||
LinphoneTunnelConfig *config = linphone_tunnel_config_new();
|
||||
|
||||
|
|
@ -91,24 +91,30 @@ static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, Linphon
|
|||
tmp_char = linphone_address_as_string(route);
|
||||
linphone_proxy_config_set_route(proxy, tmp_char);
|
||||
ms_free(tmp_char);
|
||||
linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeEnable);
|
||||
if(with_sip) linphone_tunnel_enable_sip(tunnel, with_sip);
|
||||
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));
|
||||
|
||||
/* Ensure that we did use the tunnel. If so, we should see contact changed from:
|
||||
Contact: <sip:pauline@192.168.0.201>;.[...]
|
||||
To:
|
||||
Contact: <sip:pauline@91.121.209.194:43867>;[....] (91.121.209.194 must be tunnel.liphone.org)
|
||||
*/
|
||||
ms_free(public_ip);
|
||||
public_ip = get_public_contact_ip(pauline->lc);
|
||||
CU_ASSERT_STRING_EQUAL(public_ip, tunnel_ip);
|
||||
if(tunnel_mode == LinphoneTunnelModeEnable) {
|
||||
/* Ensure that we did use the tunnel. If so, we should see contact changed from:
|
||||
Contact: <sip:pauline@192.168.0.201>;.[...]
|
||||
To:
|
||||
Contact: <sip:pauline@91.121.209.194:43867>;[....] (91.121.209.194 must be tunnel.liphone.org)
|
||||
*/
|
||||
ms_free(public_ip);
|
||||
public_ip = get_public_contact_ip(pauline->lc);
|
||||
CU_ASSERT_STRING_EQUAL(public_ip, tunnel_ip);
|
||||
} else {
|
||||
public_ip2 = get_public_contact_ip(pauline->lc);
|
||||
CU_ASSERT_STRING_EQUAL(public_ip, public_ip2);
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
|
@ -121,6 +127,7 @@ static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, Linphon
|
|||
end_call(pauline,marie);
|
||||
|
||||
ms_free(public_ip);
|
||||
if(public_ip2 != NULL) ms_free(public_ip2);
|
||||
linphone_address_destroy(server_addr);
|
||||
linphone_address_destroy(route);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
|
@ -131,21 +138,26 @@ static void call_with_transport_base(bool_t use_tunnel, bool_t with_sip, Linphon
|
|||
}
|
||||
|
||||
static void call_with_tunnel(void) {
|
||||
call_with_transport_base(TRUE, TRUE, LinphoneMediaEncryptionNone);
|
||||
call_with_transport_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone);
|
||||
}
|
||||
|
||||
static void call_with_tunnel_srtp(void) {
|
||||
call_with_transport_base(TRUE, TRUE, LinphoneMediaEncryptionSRTP);
|
||||
call_with_transport_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionSRTP);
|
||||
}
|
||||
|
||||
static void call_with_tunnel_without_sip(void) {
|
||||
call_with_transport_base(TRUE, FALSE, LinphoneMediaEncryptionNone);
|
||||
call_with_transport_base(LinphoneTunnelModeEnable, FALSE, LinphoneMediaEncryptionNone);
|
||||
}
|
||||
|
||||
static void call_with_tunnel_auto(void) {
|
||||
call_with_transport_base(LinphoneTunnelModeAuto, TRUE, LinphoneMediaEncryptionNone);
|
||||
}
|
||||
|
||||
test_t transport_tests[] = {
|
||||
{ "Tunnel only", call_with_tunnel },
|
||||
{ "Tunnel with SRTP", call_with_tunnel_srtp },
|
||||
{ "Tunnel without SIP", call_with_tunnel_without_sip }
|
||||
{ "Tunnel without SIP", call_with_tunnel_without_sip },
|
||||
{ "Tunnel in automatic mode", call_with_tunnel_auto }
|
||||
};
|
||||
|
||||
test_suite_t transport_test_suite = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue