Commit 20f40205 authored by Stepan Salenikovich's avatar Stepan Salenikovich

add connectivityChanged API

This allows the clients to notify the daemon when the conenctivity
(ie: network status) has changed. The daemon will then try to detect
the new IGD (UPnP) and re-connect all enabled accounts.

Change-Id: I5c8fc57f75e48d86eda5d195b0586c61a26134ad
Tuleap: #841
parent eb67d2fc
......@@ -1103,5 +1103,15 @@
</arg>
</signal>
<method name="connectivityChanged" tp:name-for-bindings="connectivityChanged">
<tp:added version="2.3.0"/>
<tp:docstring>
This notifies the daemon that the network connectivity has changed, eg:
- interface has disconnected from the network
- interface connected to a different network
- connected interface has changed (wifi to eth)
</tp:docstring>
</method>
</interface>
</node>
......@@ -540,3 +540,9 @@ DBusConfigurationManager::importAccounts(const std::string& archivePath, const s
{
return DRing::importAccounts(archivePath, password);
}
void
DBusConfigurationManager::connectivityChanged()
{
DRing::connectivityChanged();
}
......@@ -139,6 +139,7 @@ class DBusConfigurationManager :
void sendTrustRequest(const std::string& accountId, const std::string& to, const std::vector<uint8_t>& payload);
int exportAccounts(const std::vector<std::string>& accountIDs, const std::string& filepath, const std::string& password);
int importAccounts(const std::string& archivePath, const std::string& password);
void connectivityChanged();
};
#endif // __RING_DBUSCONFIGURATIONMANAGER_H__
......@@ -296,6 +296,11 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
*/
mutable std::mt19937_64 rand_;
/**
* Inform the account that the network status has changed.
*/
virtual void connectivityChanged() {};
private:
NON_COPYABLE(Account);
......
......@@ -40,6 +40,7 @@
#include "system_codec_container.h"
#include "account_const.h"
#include "client/ring_signal.h"
#include "upnp/upnp_context.h"
#include <dirent.h>
......@@ -790,4 +791,24 @@ setCredentials(const std::string& accountID,
}
}
void
connectivityChanged()
{
RING_WARN("received connectivity changed - trying to re-connect enabled accounts");
// reset the UPnP context
try {
ring::upnp::getUPnPContext()->connectivityChanged();
} catch (std::runtime_error& e) {
RING_ERR("UPnP context error: %s", e.what());
}
auto account_list = ring::Manager::instance().getAccountList();
for (auto account_id : account_list) {
if (auto account = ring::Manager::instance().getAccount(account_id)) {
account->connectivityChanged();
}
}
}
} // namespace DRing
......@@ -156,6 +156,11 @@ void sendTrustRequest(const std::string& accountId, const std::string& to, const
int exportAccounts(std::vector<std::string> accountIDs, std::string filepath, std::string password);
int importAccounts(std::string archivePath, std::string password);
/*
* Network connectivity
*/
void connectivityChanged();
struct AudioSignal {
struct DeviceEvent {
constexpr static const char* name = "audioDeviceEvent";
......
......@@ -755,7 +755,7 @@ RingAccount::mapPortUPnP()
std::weak_ptr<RingAccount> w = std::static_pointer_cast<RingAccount>(shared_from_this());
upnp_->setIGDListener([w] {
if (auto shared = w.lock())
shared->connectivityChanged();
shared->igdChanged();
});
return added;
}
......@@ -1065,6 +1065,22 @@ RingAccount::doUnregister(std::function<void(bool)> released_cb)
released_cb(false);
}
void
RingAccount::connectivityChanged()
{
if (not isUsable()) {
// nothing to do
return;
}
auto shared = std::static_pointer_cast<RingAccount>(shared_from_this());
doUnregister([shared](bool /* transport_free */) {
if (shared->isUsable())
shared->doRegister();
});
}
bool
RingAccount::findCertificate(const dht::InfoHash& h, std::function<void(const std::shared_ptr<dht::crypto::Certificate>)> cb)
{
......@@ -1402,7 +1418,7 @@ RingAccount::sendTrustRequest(const std::string& to, const std::vector<uint8_t>&
}
void
RingAccount::connectivityChanged()
RingAccount::igdChanged()
{
if (not dht_.isRunning())
return;
......
......@@ -254,7 +254,7 @@ class RingAccount : public SIPAccountBase {
void sendTrustRequest(const std::string& to, const std::vector<uint8_t>& payload);
virtual void sendTextMessage(const std::string& to, const std::map<std::string, std::string>& payloads, uint64_t id) override;
void connectivityChanged();
void connectivityChanged() override;
private:
NON_COPYABLE(RingAccount);
......@@ -287,6 +287,8 @@ class RingAccount : public SIPAccountBase {
*/
bool mapPortUPnP();
void igdChanged();
dht::DhtRunner dht_ {};
dht::InfoHash callKey_;
......
......@@ -892,6 +892,21 @@ void SIPAccount::doUnregister(std::function<void(bool)> released_cb)
upnp_->removeMappings();
}
void
SIPAccount::connectivityChanged()
{
if (not isUsable()) {
// nothing to do
return;
}
auto shared = std::static_pointer_cast<SIPAccount>(shared_from_this());
doUnregister([shared](bool /* transport_free */) {
if (shared->isUsable())
shared->doRegister();
});
}
void SIPAccount::startKeepAliveTimer()
{
if (isTlsEnabled())
......
......@@ -493,6 +493,8 @@ class SIPAccount : public SIPAccountBase {
const std::map<std::string, std::string>& payloads,
uint64_t id) override;
void connectivityChanged() override;
private:
void doRegister1_();
void doRegister2_();
......
......@@ -247,6 +247,8 @@ public:
void onTextMessage(const std::string& from, const std::map<std::string, std::string>& payloads);
void connectivityChanged() override {};
protected:
virtual void serialize(YAML::Emitter &out) override;
virtual void serializeTls(YAML::Emitter &out);
......
......@@ -179,6 +179,26 @@ UPnPContext::~UPnPContext()
#endif
}
void
UPnPContext::connectivityChanged()
{
{
std::lock_guard<std::mutex> lock(validIGDMutex_);
/* when the network changes, we're likely no longer connected to the same IGD, or if we are
* we might now have a different IP, thus we clear the list of IGDs and notify the listeners
* so that they can attempt to re-do the port mappings once we detect an IGD
*/
validIGDs_.clear();
validIGDCondVar_.notify_all();
for (const auto& l : igdListeners_)
l.second();
}
// send out a new search request
searchForIGD();
}
void
UPnPContext::searchForIGD()
{
......
......@@ -110,6 +110,12 @@ public:
*/
int handleUPnPEvents(Upnp_EventType event_type, void* event);
/**
* Inform the UPnP context that the network status has changed. This clears the list of known
* IGDs
*/
void connectivityChanged();
#else
/* use default constructor and destructor */
UPnPContext() = default;
......
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