diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-09-28 20:01:57 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-09-29 18:07:17 (GMT) |
commit | dfccb5703c4d85ab1a54429016b103101bdc54ae (patch) | |
tree | 05ac257e6dc7609a5b02e94e59b52f44b74f123d /Swiften/Network/PlatformNATTraversalWorker.cpp | |
parent | 6cea7fdfea93e54543c6757909a8fae7348754fc (diff) | |
download | swift-contrib-dfccb5703c4d85ab1a54429016b103101bdc54ae.zip swift-contrib-dfccb5703c4d85ab1a54429016b103101bdc54ae.tar.bz2 |
File Transfer refactoring.
NAT traversal classes refactoring.
Added beginnings of a NetworkTool.
Diffstat (limited to 'Swiften/Network/PlatformNATTraversalWorker.cpp')
-rw-r--r-- | Swiften/Network/PlatformNATTraversalWorker.cpp | 195 |
1 files changed, 114 insertions, 81 deletions
diff --git a/Swiften/Network/PlatformNATTraversalWorker.cpp b/Swiften/Network/PlatformNATTraversalWorker.cpp index e0dcab5..c962b3b 100644 --- a/Swiften/Network/PlatformNATTraversalWorker.cpp +++ b/Swiften/Network/PlatformNATTraversalWorker.cpp @@ -7,18 +7,94 @@ #include "PlatformNATTraversalWorker.h" #include <boost/smart_ptr/make_shared.hpp> +#include <boost/enable_shared_from_this.hpp> + #include <Swiften/Base/Log.h> -#include <Swiften/Network/UPnPNATTraversalGetPublicIPRequest.h> -#include <Swiften/Network/UPnPNATTraversalForwardPortRequest.h> -#include <Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h> -#include <Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.h> -#include <Swiften/Network/NATPMPNATTraversalForwardPortRequest.h> -#include <Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h> +#include <Swiften/Network/NATTraversalGetPublicIPRequest.h> +#include <Swiften/Network/NATTraversalForwardPortRequest.h> +#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h> +#include <Swiften/Network/NATPMPInterface.h> +#include <Swiften/Network/MiniUPnPInterface.h> namespace Swift { -PlatformNATTraversalWorker::PlatformNATTraversalWorker(EventLoop* eventLoop) : backendType(NotYetDecided), eventLoop(eventLoop), stopRequested(false) { - checkAvailableNATTraversalProtocols(); +class PlatformNATTraversalRequest : public boost::enable_shared_from_this<PlatformNATTraversalRequest> { + public: + typedef boost::shared_ptr<PlatformNATTraversalRequest> ref; + + public: + PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker) : worker(worker) { + } + + virtual ~PlatformNATTraversalRequest() { + } + + virtual void doRun() { + worker->addRequestToQueue(shared_from_this()); + } + + NATTraversalInterface* getNATTraversalInterface() const { + return worker->getNATTraversalInterface(); + } + + + virtual void runBlocking() = 0; + + private: + PlatformNATTraversalWorker* worker; +}; + +class PlatformNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->getPublicIP()); + } +}; + +class PlatformNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalForwardPortRequest(PlatformNATTraversalWorker* worker, unsigned int localIP, unsigned int publicIP) : PlatformNATTraversalRequest(worker), localIP(localIP), publicIP(publicIP) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->addPortForward(localIP, publicIP)); + } + + private: + unsigned int localIP; + unsigned int publicIP; +}; + +class PlatformNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest, public PlatformNATTraversalRequest { + public: + PlatformNATTraversalRemovePortForwardingRequest(PlatformNATTraversalWorker* worker, const NATPortMapping& mapping) : PlatformNATTraversalRequest(worker), mapping(mapping) { + } + + virtual void run() { + doRun(); + } + + virtual void runBlocking() { + onResult(getNATTraversalInterface()->removePortForward(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(); thread = new boost::thread(boost::bind(&PlatformNATTraversalWorker::run, this)); } @@ -27,57 +103,43 @@ PlatformNATTraversalWorker::~PlatformNATTraversalWorker() { addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>()); thread->join(); delete thread; + delete natPMPInterface; + delete miniUPnPInterface; + delete nullNATTraversalInterface; } -boost::shared_ptr<NATTraversalGetPublicIPRequest> PlatformNATTraversalWorker::createGetPublicIPRequest() { - switch(backendType) { - case UPnP: - return boost::make_shared<UPnPNATTraversalGetPublicIPRequest>(this); - case NATPMP: - return boost::make_shared<NATPMPNATTraversalGetPublicIPRequest>(this); - case NotYetDecided: - case None: - break; +NATTraversalInterface* PlatformNATTraversalWorker::getNATTraversalInterface() const { + if (boost::logic::indeterminate(miniUPnPSupported)) { + miniUPnPInterface = new MiniUPnPInterface(); + miniUPnPSupported = miniUPnPInterface->isAvailable(); + } + if (miniUPnPSupported) { + return miniUPnPInterface; } - return boost::shared_ptr<NATTraversalGetPublicIPRequest>(); -} -boost::shared_ptr<NATTraversalForwardPortRequest> PlatformNATTraversalWorker::createForwardPortRequest(unsigned int localPort, unsigned int publicPort) { - NATTraversalForwardPortRequest::PortMapping mapping; - mapping.protocol = NATTraversalForwardPortRequest::PortMapping::TCP; - mapping.leaseInSeconds = 60 * 60 * 24; - mapping.localPort = localPort; - mapping.publicPort = publicPort; - - switch(backendType) { - case UPnP: - return boost::make_shared<UPnPNATTraversalForwardPortRequest>(mapping, this); - case NATPMP: - return boost::make_shared<NATPMPNATTraversalForwardPortRequest>(mapping, this); - case NotYetDecided: - case None: - break; + + if (boost::logic::indeterminate(natPMPSupported)) { + natPMPInterface = new NATPMPInterface(); + natPMPSupported = natPMPInterface->isAvailable(); + } + if (natPMPSupported) { + return natPMPInterface; } - return boost::shared_ptr<NATTraversalForwardPortRequest>(); + + return nullNATTraversalInterface; } -boost::shared_ptr<NATTraversalRemovePortForwardingRequest> PlatformNATTraversalWorker::createRemovePortForwardingRequest(unsigned int localPort, unsigned int publicPort) { - NATTraversalRemovePortForwardingRequest::PortMapping mapping; - mapping.protocol = NATTraversalRemovePortForwardingRequest::PortMapping::TCP; - mapping.leaseInSeconds = 60 * 60 * 24; - mapping.localPort = localPort; - mapping.publicPort = publicPort; - - switch(backendType) { - case UPnP: - return boost::make_shared<UPnPNATTraversalRemovePortForwardingRequest>(mapping, this); - case NATPMP: - return boost::make_shared<NATPMPNATTraversalRemovePortForwardingRequest>(mapping, this); - case NotYetDecided: - case None: - break; - } - return boost::shared_ptr<NATTraversalRemovePortForwardingRequest>(); +boost::shared_ptr<NATTraversalGetPublicIPRequest> PlatformNATTraversalWorker::createGetPublicIPRequest() { + return boost::make_shared<PlatformNATTraversalGetPublicIPRequest>(this); +} + +boost::shared_ptr<NATTraversalForwardPortRequest> PlatformNATTraversalWorker::createForwardPortRequest(int localPort, int publicPort) { + return boost::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); } void PlatformNATTraversalWorker::run() { @@ -107,33 +169,4 @@ void PlatformNATTraversalWorker::addRequestToQueue(PlatformNATTraversalRequest:: queueNonEmpty.notify_one(); } -void PlatformNATTraversalWorker::checkAvailableNATTraversalProtocols() { - boost::shared_ptr<UPnPNATTraversalGetPublicIPRequest> upnpRequest = boost::make_shared<UPnPNATTraversalGetPublicIPRequest>(this); - upnpRequest->onResult.connect(boost::bind(&PlatformNATTraversalWorker::handleUPnPGetPublicIPResult, this, _1)); - - boost::shared_ptr<NATPMPNATTraversalGetPublicIPRequest> natpmpRequest = boost::make_shared<NATPMPNATTraversalGetPublicIPRequest>(this); - natpmpRequest->onResult.connect(boost::bind(&PlatformNATTraversalWorker::handleNATPMPGetPublicIPResult, this, _1)); - - upnpRequest->run(); - natpmpRequest->run(); -} - -void PlatformNATTraversalWorker::handleUPnPGetPublicIPResult(boost::optional<HostAddress> address) { - if (backendType == NotYetDecided || backendType == None) { - if (address) { - SWIFT_LOG(debug) << "Found UPnP IGD in the local network." << std::endl; - backendType = UPnP; - } - } -} - -void PlatformNATTraversalWorker::handleNATPMPGetPublicIPResult(boost::optional<HostAddress> address) { - if (backendType == NotYetDecided || backendType == None) { - if (address) { - SWIFT_LOG(debug) << "Found NAT-PMP device in the local network." << std::endl; - backendType = NATPMP; - } - } -} - } |