diff options
Diffstat (limited to 'Swiften/Network/PlatformNATTraversalWorker.cpp')
-rw-r--r-- | Swiften/Network/PlatformNATTraversalWorker.cpp | 255 |
1 files changed, 139 insertions, 116 deletions
diff --git a/Swiften/Network/PlatformNATTraversalWorker.cpp b/Swiften/Network/PlatformNATTraversalWorker.cpp index 133b006..5431379 100644 --- a/Swiften/Network/PlatformNATTraversalWorker.cpp +++ b/Swiften/Network/PlatformNATTraversalWorker.cpp @@ -4,13 +4,21 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ -#include "PlatformNATTraversalWorker.h" +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swiften/Network/PlatformNATTraversalWorker.h> + +#include <memory> -#include <boost/smart_ptr/make_shared.hpp> -#include <boost/enable_shared_from_this.hpp> #include <boost/numeric/conversion/cast.hpp> #include <Swiften/Base/Log.h> +#include <Swiften/EventLoop/EventLoop.h> +#include <Swiften/EventLoop/EventOwner.h> #include <Swiften/Network/NATTraversalGetPublicIPRequest.h> #include <Swiften/Network/NATTraversalForwardPortRequest.h> #include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> @@ -23,179 +31,194 @@ namespace Swift { -class PlatformNATTraversalRequest : public boost::enable_shared_from_this<PlatformNATTraversalRequest> { - public: - typedef boost::shared_ptr<PlatformNATTraversalRequest> ref; +class PlatformNATTraversalRequest : public std::enable_shared_from_this<PlatformNATTraversalRequest>, public EventOwner { + public: + typedef std::shared_ptr<PlatformNATTraversalRequest> ref; - public: - PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker) : worker(worker) { - } + public: + PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker) : worker(worker) { + } - virtual ~PlatformNATTraversalRequest() { - } + virtual ~PlatformNATTraversalRequest() { + } - virtual void doRun() { - worker->addRequestToQueue(shared_from_this()); - } + virtual void doRun() { + worker->addRequestToQueue(shared_from_this()); + } - NATTraversalInterface* getNATTraversalInterface() const { - return worker->getNATTraversalInterface(); - } + NATTraversalInterface* getNATTraversalInterface() const { + return worker->getNATTraversalInterface(); + } + EventLoop* getEventLoop() const { + return worker->getEventLoop(); + } - virtual void runBlocking() = 0; - private: - PlatformNATTraversalWorker* worker; + virtual void runBlocking() = 0; + + private: + PlatformNATTraversalWorker* worker; }; class PlatformNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest, public PlatformNATTraversalRequest { - public: - PlatformNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) { - } + public: + PlatformNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) { + } + + virtual ~PlatformNATTraversalGetPublicIPRequest() { + } - virtual void start() { - doRun(); - } + virtual void start() { + doRun(); + } - virtual void stop() { - // TODO - } + virtual void stop() { + onResult.disconnect_all_slots(); + } - virtual void runBlocking() { - onResult(getNATTraversalInterface()->getPublicIP()); - } + virtual void runBlocking() { + getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->getPublicIP()), shared_from_this()); + } }; class PlatformNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest, public PlatformNATTraversalRequest { - public: - PlatformNATTraversalForwardPortRequest(PlatformNATTraversalWorker* worker, unsigned int localIP, unsigned int publicIP) : PlatformNATTraversalRequest(worker), localIP(localIP), publicIP(publicIP) { - } + public: + PlatformNATTraversalForwardPortRequest(PlatformNATTraversalWorker* worker, unsigned short localPort, unsigned short publicPort) : PlatformNATTraversalRequest(worker), localPort(localPort), publicPort(publicPort) { + } - virtual void start() { - doRun(); - } + virtual ~PlatformNATTraversalForwardPortRequest() { + } - virtual void stop() { - // TODO - } + virtual void start() { + doRun(); + } - virtual void runBlocking() { - onResult(getNATTraversalInterface()->addPortForward(boost::numeric_cast<int>(localIP), boost::numeric_cast<int>(publicIP))); - } + virtual void stop() { + onResult.disconnect_all_slots(); + } - private: - unsigned int localIP; - unsigned int publicIP; + virtual void runBlocking() { + getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->addPortForward(localPort, publicPort)), shared_from_this()); + } + + private: + unsigned short localPort; + unsigned short publicPort; }; class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest, public PlatformNATTraversalRequest { - public: - PlatformNATTraversalRemovePortForwardingRequest(PlatformNATTraversalWorker* worker, const NATPortMapping& mapping) : PlatformNATTraversalRequest(worker), mapping(mapping) { - } + public: + PlatformNATTraversalRemovePortForwardingRequest(PlatformNATTraversalWorker* worker, const NATPortMapping& mapping) : PlatformNATTraversalRequest(worker), mapping(mapping) { + } + + virtual ~PlatformNATTraversalRemovePortForwardingRequest() { + } - virtual void start() { - doRun(); - } + virtual void start() { + doRun(); + } - virtual void stop() { - // TODO - } + virtual void stop() { + onResult.disconnect_all_slots(); + } - virtual void runBlocking() { - onResult(getNATTraversalInterface()->removePortForward(mapping)); - } + virtual void runBlocking() { + getEventLoop()->postEvent(boost::bind(boost::ref(onResult), getNATTraversalInterface()->removePortForward(mapping)), shared_from_this()); + } - private: - NATPortMapping mapping; + private: + NATPortMapping mapping; }; -PlatformNATTraversalWorker::PlatformNATTraversalWorker(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false), natPMPSupported(boost::logic::indeterminate), natPMPInterface(NULL), miniUPnPSupported(boost::logic::indeterminate), miniUPnPInterface(NULL) { - nullNATTraversalInterface = new NullNATTraversalInterface(); - // FIXME: This should be done from start(), and the current start() should be an internal method - thread = new boost::thread(boost::bind(&PlatformNATTraversalWorker::start, this)); +PlatformNATTraversalWorker::PlatformNATTraversalWorker(EventLoop* eventLoop) : eventLoop(eventLoop), stopRequested(false), natPMPSupported(boost::logic::indeterminate), natPMPInterface(nullptr), miniUPnPSupported(boost::logic::indeterminate), miniUPnPInterface(nullptr) { + nullNATTraversalInterface = new NullNATTraversalInterface(); + // FIXME: This should be done from start(), and the current start() should be an internal method + thread = new std::thread(boost::bind(&PlatformNATTraversalWorker::start, this)); } PlatformNATTraversalWorker::~PlatformNATTraversalWorker() { - stopRequested = true; - addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>()); - thread->join(); - delete thread; + stopRequested = true; + addRequestToQueue(std::shared_ptr<PlatformNATTraversalRequest>()); + thread->join(); + delete thread; #ifdef HAVE_LIBNATPMP - delete natPMPInterface; + delete natPMPInterface; #endif #ifdef HAVE_LIBMINIUPNPC - delete miniUPnPInterface; + delete miniUPnPInterface; #endif - delete nullNATTraversalInterface; + delete nullNATTraversalInterface; } NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() const { #ifdef HAVE_LIBMINIUPNPC - if (boost::logic::indeterminate(miniUPnPSupported)) { - miniUPnPInterface = new MiniUPnPInterface(); - miniUPnPSupported = miniUPnPInterface->isAvailable(); - } - if (miniUPnPSupported) { - return miniUPnPInterface; - } + if (boost::logic::indeterminate(miniUPnPSupported)) { + miniUPnPInterface = new MiniUPnPInterface(); + miniUPnPSupported = miniUPnPInterface->isAvailable(); + } + SWIFT_LOG(debug) << "UPnP NAT traversal supported: " << static_cast<bool>(miniUPnPSupported); + if (miniUPnPSupported) { + return miniUPnPInterface; + } #endif #ifdef HAVE_LIBNATPMP - if (boost::logic::indeterminate(natPMPSupported)) { - natPMPInterface = new NATPMPInterface(); - natPMPSupported = natPMPInterface->isAvailable(); - } - if (natPMPSupported) { - return natPMPInterface; - } + if (boost::logic::indeterminate(natPMPSupported)) { + natPMPInterface = new NATPMPInterface(); + natPMPSupported = natPMPInterface->isAvailable(); + } + SWIFT_LOG(debug) << "NAT-PMP NAT traversal supported: " << static_cast<bool>(natPMPSupported); + if (natPMPSupported) { + return natPMPInterface; + } #endif - return nullNATTraversalInterface; + return nullNATTraversalInterface; } -boost::shared_ptr<NATTraversalGetPublicIPRequest> PlatformNATTraversalWorker::createGetPublicIPRequest() { - return boost::make_shared<PlatformNATTraversalGetPublicIPRequest>(this); +std::shared_ptr<NATTraversalGetPublicIPRequest> PlatformNATTraversalWorker::createGetPublicIPRequest() { + return std::make_shared<PlatformNATTraversalGetPublicIPRequest>(this); } -boost::shared_ptr<NATTraversalForwardPortRequest> PlatformNATTraversalWorker::createForwardPortRequest(int localPort, int publicPort) { - return boost::make_shared<PlatformNATTraversalForwardPortRequest>(this, localPort, publicPort); +std::shared_ptr<NATTraversalForwardPortRequest> PlatformNATTraversalWorker::createForwardPortRequest(unsigned short localPort, unsigned short publicPort) { + return std::make_shared<PlatformNATTraversalForwardPortRequest>(this, localPort, publicPort); } -boost::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalWorker::createRemovePortForwardingRequest(int localPort, int publicPort) { - NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); // FIXME - return boost::make_shared<PlatformNATTraversalRemovePortForwardingRequest>(this, mapping); +std::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalWorker::createRemovePortForwardingRequest(unsigned short localPort, unsigned short publicPort) { + NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP); // FIXME + return std::make_shared<PlatformNATTraversalRemovePortForwardingRequest>(this, mapping); } void PlatformNATTraversalWorker::start() { - while (!stopRequested) { - PlatformNATTraversalRequest::ref request; - { - boost::unique_lock<boost::mutex> lock(queueMutex); - while (queue.empty()) { - queueNonEmpty.wait(lock); - } - request = queue.front(); - queue.pop_front(); - } - // Check whether we don't have a non-null request (used to stop the - // worker) - if (request) { - request->runBlocking(); - } - } + while (!stopRequested) { + PlatformNATTraversalRequest::ref request; + { + std::unique_lock<std::mutex> lock(queueMutex); + while (queue.empty()) { + queueNonEmpty.wait(lock); + } + request = queue.front(); + queue.pop_front(); + } + // Check whether we don't have a non-null request (used to stop the + // worker) + if (request) { + request->runBlocking(); + } + } } void PlatformNATTraversalWorker::stop() { - // TODO + // TODO } void PlatformNATTraversalWorker::addRequestToQueue(PlatformNATTraversalRequest::ref request) { - { - boost::lock_guard<boost::mutex> lock(queueMutex); - queue.push_back(request); - } - queueNonEmpty.notify_one(); + { + std::lock_guard<std::mutex> lock(queueMutex); + queue.push_back(request); + } + queueNonEmpty.notify_one(); } } |