add upnp/natpmp support
Change-Id: I4945a7df3a30cb39d81a33fc7a32e9fea600bdff
diff --git a/src/upnp/protocol/natpmp/nat_pmp.cpp b/src/upnp/protocol/natpmp/nat_pmp.cpp
index 599205e..2f48713 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.cpp
+++ b/src/upnp/protocol/natpmp/nat_pmp.cpp
@@ -21,11 +21,11 @@
namespace dhtnet {
namespace upnp {
-NatPmp::NatPmp()
+NatPmp::NatPmp(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger)
+ : UPnPProtocol(logger), ioContext(ctx), searchForIgdTimer_(*ctx)
{
// JAMI_DBG("NAT-PMP: Instance [%p] created", this);
- runOnNatPmpQueue([this] {
- threadId_ = getCurrentThread();
+ ioContext->dispatch([this] {
igd_ = std::make_shared<PMPIGD>();
});
}
@@ -38,15 +38,6 @@
void
NatPmp::initNatPmp()
{
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak()] {
- if (auto pmpThis = w.lock()) {
- pmpThis->initNatPmp();
- }
- });
- return;
- }
-
initialized_ = false;
{
@@ -82,8 +73,7 @@
err = NATPMP_ERR_CANNOTGETGATEWAY;
} else {
// JAMI_WARN("NAT-PMP: Trying to initialize using detected gateway %s",
- localGw.toString().c_str());
-
+ // localGw.toString().c_str());
struct in_addr inaddr;
inet_pton(AF_INET, localGw.toString().c_str(), &inaddr);
err = initnatpmp(&natpmpHdl_, 1, inaddr.s_addr);
@@ -119,17 +109,6 @@
void
NatPmp::setObserver(UpnpMappingObserver* obs)
{
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak(), obs] {
- if (auto pmpThis = w.lock()) {
- pmpThis->setObserver(obs);
- }
- });
- return;
- }
-
- // JAMI_DBG("NAT-PMP: Setting observer to %p", obs);
-
observer_ = obs;
}
@@ -152,10 +131,8 @@
std::unique_lock<std::mutex> lk(natpmpMutex_);
std::condition_variable cv {};
- runOnNatPmpQueue([w = weak(), &cv = cv] {
- if (auto pmpThis = w.lock()) {
- pmpThis->terminate(cv);
- }
+ ioContext->dispatch([&] {
+ terminate(cv);
});
if (cv.wait_for(lk, std::chrono::seconds(10), [this] { return shutdownComplete_; })) {
@@ -175,15 +152,6 @@
void
NatPmp::clearIgds()
{
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak()] {
- if (auto pmpThis = w.lock()) {
- pmpThis->clearIgds();
- }
- });
- return;
- }
-
bool do_close = false;
if (igd_) {
@@ -194,8 +162,7 @@
}
initialized_ = false;
- if (searchForIgdTimer_)
- searchForIgdTimer_->cancel();
+ searchForIgdTimer_.cancel();
igdSearchCounter_ = 0;
@@ -208,15 +175,6 @@
void
NatPmp::searchForIgd()
{
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak()] {
- if (auto pmpThis = w.lock()) {
- pmpThis->searchForIgd();
- }
- });
- return;
- }
-
if (not initialized_) {
initNatPmp();
}
@@ -227,12 +185,11 @@
// JAMI_DBG("NAT-PMP: Start search for IGDs. Attempt %i", igdSearchCounter_);
// Cancel the current timer (if any) and re-schedule.
- if (searchForIgdTimer_)
- searchForIgdTimer_->cancel();
-
- searchForIgdTimer_ = getNatpmpScheduler()->scheduleIn([this] { searchForIgd(); },
- NATPMP_SEARCH_RETRY_UNIT
- * igdSearchCounter_);
+ searchForIgdTimer_.expires_after(NATPMP_SEARCH_RETRY_UNIT * igdSearchCounter_);
+ searchForIgdTimer_.async_wait([this](const asio::error_code& ec) {
+ if (!ec)
+ searchForIgd();
+ });
} else {
// JAMI_WARN("NAT-PMP: Setup failed after %u trials. NAT-PMP will be disabled!",
// MAX_RESTART_SEARCH_RETRIES);
@@ -291,14 +248,14 @@
NatPmp::requestMappingAdd(const Mapping& mapping)
{
// Process on nat-pmp thread.
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak(), mapping] {
+ /*if (not isValidThread()) {
+ ioContext->post([w = weak(), mapping] {
if (auto pmpThis = w.lock()) {
pmpThis->requestMappingAdd(mapping);
}
});
return;
- }
+ }*/
Mapping map(mapping);
assert(map.getIgd());
@@ -329,14 +286,14 @@
NatPmp::requestMappingRenew(const Mapping& mapping)
{
// Process on nat-pmp thread.
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak(), mapping] {
+ /*if (not isValidThread()) {
+ ioContext->post([w = weak(), mapping] {
if (auto pmpThis = w.lock()) {
pmpThis->requestMappingRenew(mapping);
}
});
return;
- }
+ }*/
Mapping map(mapping);
auto err = addPortMapping(map);
@@ -401,7 +358,7 @@
int
NatPmp::sendMappingRequest(const Mapping& mapping, uint32_t& lifetime)
{
- CHECK_VALID_THREAD();
+ //CHECK_VALID_THREAD();
int err = sendnewportmappingrequest(&natpmpHdl_,
mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP
@@ -478,16 +435,12 @@
void
NatPmp::requestMappingRemove(const Mapping& mapping)
{
- // Process on nat-pmp thread.
- if (not isValidThread()) {
- runOnNatPmpQueue([w = weak(), mapping] {
- if (auto pmpThis = w.lock()) {
- Mapping map {mapping};
- pmpThis->removePortMapping(map);
- }
- });
- return;
- }
+ ioContext->dispatch([w = weak(), mapping] {
+ if (auto pmpThis = w.lock()) {
+ Mapping map {mapping};
+ pmpThis->removePortMapping(map);
+ }
+ });
}
void
@@ -522,7 +475,7 @@
void
NatPmp::getIgdPublicAddress()
{
- CHECK_VALID_THREAD();
+ //CHECK_VALID_THREAD();
// Set the public address for this IGD if it does not
// have one already.
@@ -585,7 +538,7 @@
void
NatPmp::removeAllMappings()
{
- CHECK_VALID_THREAD();
+ //CHECK_VALID_THREAD();
// JAMI_WARN("NAT-PMP: Send request to close all existing mappings to IGD %s",
// igd_->toString().c_str());
@@ -721,7 +674,7 @@
if (observer_ == nullptr)
return;
// Process the response on the context thread.
- runOnUpnpContextQueue([obs = observer_, igd = igd_, event] { obs->onIgdUpdated(igd, event); });
+ ioContext->post([obs = observer_, igd = igd_, event] { obs->onIgdUpdated(igd, event); });
}
void
@@ -731,7 +684,7 @@
return;
// Process the response on the context thread.
- runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingAdded(igd, map); });
+ ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingAdded(igd, map); });
}
void
@@ -741,7 +694,7 @@
return;
// Process the response on the context thread.
- runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRequestFailed(map); });
+ ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRequestFailed(map); });
}
void
@@ -751,7 +704,7 @@
return;
// Process the response on the context thread.
- runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRenewed(igd, map); });
+ ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRenewed(igd, map); });
}
void
@@ -761,7 +714,7 @@
return;
// Process the response on the context thread.
- runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRemoved(igd, map); });
+ ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRemoved(igd, map); });
}
} // namespace upnp
diff --git a/src/upnp/protocol/natpmp/nat_pmp.h b/src/upnp/protocol/natpmp/nat_pmp.h
index 30642a0..fbc2fc0 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.h
+++ b/src/upnp/protocol/natpmp/nat_pmp.h
@@ -16,14 +16,10 @@
*/
#pragma once
-#include "connectivity/upnp/protocol/upnp_protocol.h"
-#include "connectivity/upnp/protocol/igd.h"
+#include "../upnp_protocol.h"
+#include "../igd.h"
#include "pmp_igd.h"
-
-#include "logger.h"
-#include "connectivity/ip_utils.h"
-#include "noncopyable.h"
-#include "compiler_intrinsics.h"
+#include "ip_utils.h"
// uncomment to enable native natpmp error messages
//#define ENABLE_STRNATPMPERR 1
@@ -53,7 +49,7 @@
class NatPmp : public UPnPProtocol
{
public:
- NatPmp();
+ NatPmp(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger);
~NatPmp();
// Set the observer.
@@ -94,21 +90,11 @@
void terminate() override;
private:
- NON_COPYABLE(NatPmp);
+ NatPmp& operator=(const NatPmp&) = delete;
+ NatPmp(const NatPmp&) = delete;
std::weak_ptr<NatPmp> weak() { return std::static_pointer_cast<NatPmp>(shared_from_this()); }
- // Helpers to run tasks on NAT-PMP internal execution queue.
- ScheduledExecutor* getNatpmpScheduler() { return &natpmpScheduler_; }
- template<typename Callback>
- void runOnNatPmpQueue(Callback&& cb)
- {
- natpmpScheduler_.run([cb = std::forward<Callback>(cb)]() mutable { cb(); });
- }
-
- // Helpers to run tasks on UPNP context execution queue.
- ScheduledExecutor* getUpnContextScheduler() { return UpnpThreadUtil::getScheduler(); }
-
void terminate(std::condition_variable& cv);
void initNatPmp();
@@ -147,8 +133,8 @@
// Data members
std::shared_ptr<PMPIGD> igd_;
natpmp_t natpmpHdl_;
- ScheduledExecutor natpmpScheduler_ {"natpmp"};
- std::shared_ptr<Task> searchForIgdTimer_ {};
+ std::shared_ptr<asio::io_context> ioContext;
+ asio::steady_timer searchForIgdTimer_;
unsigned int igdSearchCounter_ {0};
UpnpMappingObserver* observer_ {nullptr};
IpAddr hostAddress_ {};
diff --git a/src/upnp/protocol/natpmp/pmp_igd.h b/src/upnp/protocol/natpmp/pmp_igd.h
index df1c44b..1ca7fe7 100644
--- a/src/upnp/protocol/natpmp/pmp_igd.h
+++ b/src/upnp/protocol/natpmp/pmp_igd.h
@@ -17,8 +17,7 @@
#pragma once
#include "../igd.h"
-#include "noncopyable.h"
-#include "connectivity/ip_utils.h"
+#include "ip_utils.h"
#include <map>
#include <atomic>