summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-09-28 20:01:57 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-09-29 18:07:17 (GMT)
commitdfccb5703c4d85ab1a54429016b103101bdc54ae (patch)
tree05ac257e6dc7609a5b02e94e59b52f44b74f123d /Swiften
parent6cea7fdfea93e54543c6757909a8fae7348754fc (diff)
downloadswift-dfccb5703c4d85ab1a54429016b103101bdc54ae.zip
swift-dfccb5703c4d85ab1a54429016b103101bdc54ae.tar.bz2
File Transfer refactoring.
NAT traversal classes refactoring. Added beginnings of a NetworkTool.
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Examples/NetworkTool/.gitignore1
-rw-r--r--Swiften/Examples/NetworkTool/SConscript9
-rw-r--r--Swiften/Examples/NetworkTool/main.cpp81
-rw-r--r--Swiften/Examples/SConscript1
-rw-r--r--Swiften/FileTransfer/ConnectivityManager.cpp2
-rw-r--r--Swiften/FileTransfer/ConnectivityManager.h3
-rw-r--r--Swiften/Network/MiniUPnPInterface.cpp86
-rw-r--r--Swiften/Network/MiniUPnPInterface.h36
-rw-r--r--Swiften/Network/NATPMPInterface.cpp112
-rw-r--r--Swiften/Network/NATPMPInterface.h30
-rw-r--r--Swiften/Network/NATPMPNATTraversalForwardPortRequest.cpp64
-rw-r--r--Swiften/Network/NATPMPNATTraversalForwardPortRequest.h29
-rw-r--r--Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.cpp66
-rw-r--r--Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.h26
-rw-r--r--Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp70
-rw-r--r--Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h29
-rw-r--r--Swiften/Network/NATPortMapping.h27
-rw-r--r--Swiften/Network/NATTraversalForwardPortRequest.h18
-rw-r--r--Swiften/Network/NATTraversalInterface.cpp17
-rw-r--r--Swiften/Network/NATTraversalInterface.h25
-rw-r--r--Swiften/Network/NATTraverser.h4
-rw-r--r--Swiften/Network/NullNATTraversalInterface.h33
-rw-r--r--Swiften/Network/NullNATTraverser.cpp6
-rw-r--r--Swiften/Network/NullNATTraverser.h4
-rw-r--r--Swiften/Network/PlatformNATTraversalRequest.cpp25
-rw-r--r--Swiften/Network/PlatformNATTraversalRequest.h31
-rw-r--r--Swiften/Network/PlatformNATTraversalWorker.cpp195
-rw-r--r--Swiften/Network/PlatformNATTraversalWorker.h82
-rw-r--r--Swiften/Network/SConscript12
-rw-r--r--Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp71
-rw-r--r--Swiften/Network/UPnPNATTraversalForwardPortRequest.h29
-rw-r--r--Swiften/Network/UPnPNATTraversalGetPublicIPRequest.cpp57
-rw-r--r--Swiften/Network/UPnPNATTraversalGetPublicIPRequest.h26
-rw-r--r--Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp77
-rw-r--r--Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h29
35 files changed, 630 insertions, 783 deletions
diff --git a/Swiften/Examples/NetworkTool/.gitignore b/Swiften/Examples/NetworkTool/.gitignore
new file mode 100644
index 0000000..ab9c4e7
--- /dev/null
+++ b/Swiften/Examples/NetworkTool/.gitignore
@@ -0,0 +1 @@
+NetworkTool
diff --git a/Swiften/Examples/NetworkTool/SConscript b/Swiften/Examples/NetworkTool/SConscript
new file mode 100644
index 0000000..0b27f0d
--- /dev/null
+++ b/Swiften/Examples/NetworkTool/SConscript
@@ -0,0 +1,9 @@
+Import("env")
+
+myenv = env.Clone()
+myenv.MergeFlags(myenv["SWIFTEN_FLAGS"])
+myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"])
+
+linkLocalTool = myenv.Program("NetworkTool", [
+ "main.cpp"
+ ])
diff --git a/Swiften/Examples/NetworkTool/main.cpp b/Swiften/Examples/NetworkTool/main.cpp
new file mode 100644
index 0000000..fa19e14
--- /dev/null
+++ b/Swiften/Examples/NetworkTool/main.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+
+#include <Swiften/EventLoop/SimpleEventLoop.h>
+#include <Swiften/Network/PlatformNATTraversalWorker.h>
+#include <Swiften/Network/NATTraversalGetPublicIPRequest.h>
+#include <Swiften/Network/NATTraversalForwardPortRequest.h>
+#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h>
+
+using namespace Swift;
+
+SimpleEventLoop eventLoop;
+
+void handleGetPublicIPRequestResponse(const boost::optional<HostAddress>& result) {
+ if (result) {
+ std::cerr << "Result: " << result->toString() << std::endl;;
+ }
+ else {
+ std::cerr << "No result" << std::endl;
+ }
+ eventLoop.stop();
+}
+
+void handleGetForwardPortRequestResponse(const boost::optional<NATPortMapping>& result) {
+ if (result) {
+ std::cerr << "Result: " << result->publicPort << " -> " << result->localPort << std::endl;;
+ }
+ else {
+ std::cerr << "No result" << std::endl;
+ }
+ eventLoop.stop();
+}
+
+void handleRemovePortForwardingRequestResponse(bool result) {
+ if (result) {
+ std::cerr << "Result: OK" << std::endl;
+ }
+ else {
+ std::cerr << "Result: ERROR" << std::endl;
+ }
+ eventLoop.stop();
+}
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ std::cerr << "Invalid parameters" << std::endl;
+ return -1;
+ }
+
+ PlatformNATTraversalWorker natTraverser(&eventLoop);
+ if (std::string(argv[1]) == "get-public-ip") {
+ boost::shared_ptr<NATTraversalGetPublicIPRequest> query = natTraverser.createGetPublicIPRequest();
+ query->onResult.connect(boost::bind(&handleGetPublicIPRequestResponse, _1));
+ query->run();
+ eventLoop.run();
+ }
+ else if (std::string(argv[1]) == "add-port-forward") {
+ if (argc < 4) {
+ std::cerr << "Invalid parameters" << std::endl;
+ }
+ boost::shared_ptr<NATTraversalForwardPortRequest> query = natTraverser.createForwardPortRequest(boost::lexical_cast<int>(argv[2]), boost::lexical_cast<int>(argv[3]));
+ query->onResult.connect(boost::bind(&handleGetForwardPortRequestResponse, _1));
+ query->run();
+ eventLoop.run();
+ }
+ else if (std::string(argv[1]) == "remove-port-forward") {
+ if (argc < 4) {
+ std::cerr << "Invalid parameters" << std::endl;
+ }
+ boost::shared_ptr<NATTraversalRemovePortForwardingRequest> query = natTraverser.createRemovePortForwardingRequest(boost::lexical_cast<int>(argv[2]), boost::lexical_cast<int>(argv[3]));
+ query->onResult.connect(boost::bind(&handleRemovePortForwardingRequestResponse, _1));
+ query->run();
+ eventLoop.run();
+ }
+}
diff --git a/Swiften/Examples/SConscript b/Swiften/Examples/SConscript
index 9b9a35a..fb568fc 100644
--- a/Swiften/Examples/SConscript
+++ b/Swiften/Examples/SConscript
@@ -7,6 +7,7 @@ SConscript(dirs = [
"SendFile",
"ConnectivityTest",
"LinkLocalTool",
+ "NetworkTool",
"ParserTester",
"BenchTool",
])
diff --git a/Swiften/FileTransfer/ConnectivityManager.cpp b/Swiften/FileTransfer/ConnectivityManager.cpp
index 1002b45..7d25991 100644
--- a/Swiften/FileTransfer/ConnectivityManager.cpp
+++ b/Swiften/FileTransfer/ConnectivityManager.cpp
@@ -92,7 +92,7 @@ void ConnectivityManager::natTraversalGetPublicIPResult(boost::optional<HostAddr
}
}
-void ConnectivityManager::natTraversalForwardPortResult(boost::optional<NATTraversalForwardPortRequest::PortMapping> mapping) {
+void ConnectivityManager::natTraversalForwardPortResult(boost::optional<NATPortMapping> mapping) {
if (mapping) {
SWIFT_LOG(debug) << "Mapping port was successful." << std::endl;
} else {
diff --git a/Swiften/FileTransfer/ConnectivityManager.h b/Swiften/FileTransfer/ConnectivityManager.h
index 41e0ab6..c094c02 100644
--- a/Swiften/FileTransfer/ConnectivityManager.h
+++ b/Swiften/FileTransfer/ConnectivityManager.h
@@ -14,6 +14,7 @@
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/NATTraverser.h>
#include <Swiften/Network/NATTraversalForwardPortRequest.h>
+#include <Swiften/Network/NATPortMapping.h>
namespace Swift {
@@ -32,7 +33,7 @@ public:
private:
void natTraversalGetPublicIPResult(boost::optional<HostAddress> address);
- void natTraversalForwardPortResult(boost::optional<NATTraversalForwardPortRequest::PortMapping> mapping);
+ void natTraversalForwardPortResult(boost::optional<NATPortMapping> mapping);
private:
NATTraverser* natTraversalWorker;
diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp
new file mode 100644
index 0000000..f6e3b5d
--- /dev/null
+++ b/Swiften/Network/MiniUPnPInterface.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Network/MiniUPnPInterface.h>
+
+#include <upnpcommands.h>
+#include <upnperrors.h>
+#include <boost/lexical_cast.hpp>
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+MiniUPnPInterface::MiniUPnPInterface() : isValid(false) {
+ int error = 0;
+ deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
+ if (!deviceList) {
+ return;
+ }
+
+ char lanAddress[64];
+ if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddress, sizeof(lanAddress))) {
+ return;
+ }
+ localAddress = std::string(lanAddress);
+ isValid = true;
+}
+
+MiniUPnPInterface::~MiniUPnPInterface() {
+ if (isValid) {
+ FreeUPNPUrls(&urls);
+ }
+ freeUPNPDevlist(deviceList);
+}
+
+boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
+ if (!isValid) {
+ return boost::optional<HostAddress>();
+ }
+ char externalIPAddress[40];
+ int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
+ if (ret != UPNPCOMMAND_SUCCESS) {
+ return boost::optional<HostAddress>();
+ }
+ else {
+ return HostAddress(std::string(externalIPAddress));
+ }
+}
+
+boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) {
+ if (!isValid) {
+ return boost::optional<NATPortMapping>();
+ }
+
+ NATPortMapping mapping(actualLocalPort, actualPublicPort, NATPortMapping::TCP);
+
+ std::string publicPort = boost::lexical_cast<std::string>(mapping.publicPort);
+ std::string localPort = boost::lexical_cast<std::string>(mapping.localPort);
+ std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.leaseInSeconds);
+
+ int ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), localPort.c_str(), localAddress.c_str(), 0, mapping.protocol == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str());
+ if (ret == UPNPCOMMAND_SUCCESS) {
+ return mapping;
+ }
+ else {
+ return boost::optional<NATPortMapping>();
+ }
+}
+
+bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) {
+ if (!isValid) {
+ return false;
+ }
+
+ std::string publicPort = boost::lexical_cast<std::string>(mapping.publicPort);
+ std::string localPort = boost::lexical_cast<std::string>(mapping.localPort);
+ std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.leaseInSeconds);
+
+ int ret = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), mapping.protocol == NATPortMapping::TCP ? "TCP" : "UDP", 0);
+ return ret == UPNPCOMMAND_SUCCESS;
+}
+
+}
diff --git a/Swiften/Network/MiniUPnPInterface.h b/Swiften/Network/MiniUPnPInterface.h
new file mode 100644
index 0000000..ae9be66
--- /dev/null
+++ b/Swiften/Network/MiniUPnPInterface.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+#include <miniupnpc.h>
+
+#include <Swiften/Network/NATPortMapping.h>
+#include <Swiften/Network/NATTraversalInterface.h>
+
+namespace Swift {
+ class MiniUPnPInterface : public NATTraversalInterface {
+ public:
+ MiniUPnPInterface();
+ ~MiniUPnPInterface();
+
+ virtual bool isAvailable() {
+ return isValid;
+ }
+
+ boost::optional<HostAddress> getPublicIP();
+ boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort);
+ bool removePortForward(const NATPortMapping&);
+
+ private:
+ bool isValid;
+ std::string localAddress;
+ UPNPDev* deviceList;
+ UPNPUrls urls;
+ IGDdatas data;
+ };
+}
diff --git a/Swiften/Network/NATPMPInterface.cpp b/Swiften/Network/NATPMPInterface.cpp
new file mode 100644
index 0000000..74f582c
--- /dev/null
+++ b/Swiften/Network/NATPMPInterface.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Network/NATPMPInterface.h>
+
+#include <Swiften/Base/Log.h>
+
+
+namespace Swift {
+
+NATPMPInterface::NATPMPInterface() {
+ initnatpmp(&natpmp, 0, 0);
+}
+
+NATPMPInterface::~NATPMPInterface() {
+ closenatpmp(&natpmp);
+}
+
+bool NATPMPInterface::isAvailable() {
+ return getPublicIP();
+}
+
+boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
+ if (sendpublicaddressrequest(&natpmp) < 0) {
+ SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl;
+ return boost::optional<HostAddress>();
+ }
+
+ int r = 0;
+ natpmpresp_t response;
+ do {
+ fd_set fds;
+ struct timeval timeout;
+ FD_ZERO(&fds);
+ FD_SET(natpmp.s, &fds);
+ getnatpmprequesttimeout(&natpmp, &timeout);
+ select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ r = readnatpmpresponseorretry(&natpmp, &response);
+ } while (r == NATPMP_TRYAGAIN);
+
+ if (r == 0) {
+ return boost::optional<HostAddress>(HostAddress(reinterpret_cast<const unsigned char*>(&(response.pnu.publicaddress.addr)), 4));
+ }
+ else {
+ SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl;
+ return boost::optional<HostAddress>();
+ }
+}
+
+boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) {
+ NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP);
+ if (sendnewportmappingrequest(&natpmp, mapping.protocol == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.leaseInSeconds, mapping.publicPort, mapping.localPort) < 0) {
+ SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl;
+ return boost::optional<NATPortMapping>();
+ }
+
+ int r = 0;
+ natpmpresp_t response;
+ do {
+ fd_set fds;
+ struct timeval timeout;
+ FD_ZERO(&fds);
+ FD_SET(natpmp.s, &fds);
+ getnatpmprequesttimeout(&natpmp, &timeout);
+ select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ r = readnatpmpresponseorretry(&natpmp, &response);
+ } while(r == NATPMP_TRYAGAIN);
+
+ if (r == 0) {
+ mapping.localPort = response.pnu.newportmapping.privateport;
+ mapping.publicPort = response.pnu.newportmapping.mappedpublicport;
+ mapping.leaseInSeconds = response.pnu.newportmapping.lifetime;
+ return mapping;
+ }
+ else {
+ SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl;
+ return boost::optional<NATPortMapping>();
+ }
+}
+
+bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) {
+ if (sendnewportmappingrequest(&natpmp, mapping.protocol == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.localPort) < 0) {
+ SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl;
+ return false;
+ }
+
+ int r = 0;
+ natpmpresp_t response;
+ do {
+ fd_set fds;
+ struct timeval timeout;
+ FD_ZERO(&fds);
+ FD_SET(natpmp.s, &fds);
+ getnatpmprequesttimeout(&natpmp, &timeout);
+ select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ r = readnatpmpresponseorretry(&natpmp, &response);
+ } while(r == NATPMP_TRYAGAIN);
+
+ if (r == 0) {
+ return true;
+ }
+ else {
+ SWIFT_LOG(debug) << "Invalid NAT-PMP response." << std::endl;
+ return false;
+ }
+}
+
+
+}
diff --git a/Swiften/Network/NATPMPInterface.h b/Swiften/Network/NATPMPInterface.h
new file mode 100644
index 0000000..55f5b87
--- /dev/null
+++ b/Swiften/Network/NATPMPInterface.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+#include <natpmp.h>
+
+#include <Swiften/Network/NATPortMapping.h>
+#include <Swiften/Network/NATTraversalInterface.h>
+
+namespace Swift {
+ class NATPMPInterface : public NATTraversalInterface {
+ public:
+ NATPMPInterface();
+ ~NATPMPInterface();
+
+ virtual bool isAvailable();
+
+ virtual boost::optional<HostAddress> getPublicIP();
+ virtual boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort);
+ virtual bool removePortForward(const NATPortMapping&);
+
+ private:
+ natpmp_t natpmp;
+ };
+}
diff --git a/Swiften/Network/NATPMPNATTraversalForwardPortRequest.cpp b/Swiften/Network/NATPMPNATTraversalForwardPortRequest.cpp
deleted file mode 100644
index d7ef88a..0000000
--- a/Swiften/Network/NATPMPNATTraversalForwardPortRequest.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "NATPMPNATTraversalForwardPortRequest.h"
-
-#include <natpmp.h>
-
-#include <Swiften/Base/Log.h>
-
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-
-namespace Swift {
-
-NATPMPNATTraversalForwardPortRequest::NATPMPNATTraversalForwardPortRequest(NATTraversalForwardPortRequest::PortMapping mapping, PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker), mapping(mapping) {
-
-}
-
-NATPMPNATTraversalForwardPortRequest::~NATPMPNATTraversalForwardPortRequest() {
-
-}
-
-void NATPMPNATTraversalForwardPortRequest::runBlocking() {
- boost::optional<PortMapping> result;
-
- natpmp_t natpmp;
- natpmpresp_t response;
- initnatpmp(&natpmp, 0, 0);
-
- do {
- if (sendnewportmappingrequest(&natpmp, mapping.protocol == PortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.leaseInSeconds, mapping.publicPort, mapping.localPort) != 2) {
- SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl;
- break;
- }
- int r = 0;
-
- do {
- fd_set fds;
- struct timeval timeout;
- FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
- select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
- } while(r == NATPMP_TRYAGAIN);
-
- if (r == 0) {
- if (response.pnu.newportmapping.privateport == mapping.localPort &&
- response.pnu.newportmapping.mappedpublicport == mapping.publicPort) {
- mapping.leaseInSeconds = response.pnu.newportmapping.lifetime;
- result = boost::optional<PortMapping>(mapping);
- }
- } else {
- SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl;
- }
- } while(false);
- closenatpmp(&natpmp);
-
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/NATPMPNATTraversalForwardPortRequest.h b/Swiften/Network/NATPMPNATTraversalForwardPortRequest.h
deleted file mode 100644
index 99a5d04..0000000
--- a/Swiften/Network/NATPMPNATTraversalForwardPortRequest.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/NATTraversalForwardPortRequest.h>
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-
-namespace Swift {
-
-class NATPMPNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest, public PlatformNATTraversalRequest {
-public:
- NATPMPNATTraversalForwardPortRequest(NATTraversalForwardPortRequest::PortMapping, PlatformNATTraversalWorker*);
- virtual ~NATPMPNATTraversalForwardPortRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-
-private:
- NATTraversalForwardPortRequest::PortMapping mapping;
-};
-
-}
diff --git a/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.cpp b/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.cpp
deleted file mode 100644
index 0f6067d..0000000
--- a/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "NATPMPNATTraversalGetPublicIPRequest.h"
-
-#include <natpmp.h>
-
-#include <Swiften/Base/Log.h>
-
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-
-namespace Swift {
-
-NATPMPNATTraversalGetPublicIPRequest::NATPMPNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) {
-
-}
-
-NATPMPNATTraversalGetPublicIPRequest::~NATPMPNATTraversalGetPublicIPRequest() {
-
-}
-
-/*
-TODO: a non-blocking solution should be possible too here
-void NATPMPNATTraversalGetPublicIPRequest::run() {
- // we can run directly since libnatpmp's API is asynchronous
- runBlocking();
-}*/
-
-void NATPMPNATTraversalGetPublicIPRequest::runBlocking() {
- boost::optional<HostAddress> result;
-
- natpmp_t natpmp;
- natpmpresp_t response;
- initnatpmp(&natpmp, 0, 0);
-
- do {
- if (sendpublicaddressrequest(&natpmp) != 2) {
- SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl;
- break;
- }
- int r = 0;
-
- do {
- fd_set fds;
- struct timeval timeout;
- FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
- select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
- } while(r == NATPMP_TRYAGAIN);
-
- if (r == 0) {
- result = boost::optional<HostAddress>(HostAddress(reinterpret_cast<const unsigned char*>(&(response.pnu.publicaddress.addr)), 4));
- } else {
- SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl;
- }
- } while(false);
- closenatpmp(&natpmp);
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.h b/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.h
deleted file mode 100644
index dba447c..0000000
--- a/Swiften/Network/NATPMPNATTraversalGetPublicIPRequest.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-#include <Swiften/Network/NATTraversalGetPublicIPRequest.h>
-
-namespace Swift {
-
-class NATPMPNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest, public PlatformNATTraversalRequest {
-public:
- NATPMPNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker*);
- virtual ~NATPMPNATTraversalGetPublicIPRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-};
-
-}
diff --git a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp
deleted file mode 100644
index 8ba20a6..0000000
--- a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "NATPMPNATTraversalRemovePortForwardingRequest.h"
-
-#include <boost/format.hpp>
-
-#include <natpmp.h>
-
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Base/Log.h>
-#include <Swiften/Network/NetworkInterface.h>
-#include <Swiften/Network/PlatformNetworkEnvironment.h>
-
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-
-namespace Swift {
-
-NATPMPNATTraversalRemovePortForwardingRequest::NATPMPNATTraversalRemovePortForwardingRequest(PortMapping mapping, PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker), mapping(mapping) {
-
-}
-
-NATPMPNATTraversalRemovePortForwardingRequest::~NATPMPNATTraversalRemovePortForwardingRequest() {
-
-}
-
-void NATPMPNATTraversalRemovePortForwardingRequest::runBlocking() {
- boost::optional<bool> result;
-
- natpmp_t natpmp;
- natpmpresp_t response;
- initnatpmp(&natpmp, 0, 0);
-
- do {
- if (sendnewportmappingrequest(&natpmp, mapping.protocol == PortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.localPort) != 2) {
- SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl;
- break;
- }
- int r = 0;
-
- do {
- fd_set fds;
- struct timeval timeout;
- FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
- select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
- } while(r == NATPMP_TRYAGAIN);
-
- if (r == 0) {
- if (response.pnu.newportmapping.privateport == mapping.localPort &&
- response.pnu.newportmapping.mappedpublicport == mapping.publicPort) {
- mapping.leaseInSeconds = response.pnu.newportmapping.lifetime;
- result = boost::optional<bool>(true);
- }
- } else {
- result = boost::optional<bool>(false);
- SWIFT_LOG(debug) << "Inavlid NAT-PMP response." << std::endl;
- }
- } while(false);
- closenatpmp(&natpmp);
-
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h
deleted file mode 100644
index aefbdc0..0000000
--- a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h>
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-
-namespace Swift {
-
-class NATPMPNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest, public PlatformNATTraversalRequest {
-public:
- NATPMPNATTraversalRemovePortForwardingRequest(PortMapping, PlatformNATTraversalWorker*);
- virtual ~NATPMPNATTraversalRemovePortForwardingRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-
-private:
- PortMapping mapping;
-};
-
-}
diff --git a/Swiften/Network/NATPortMapping.h b/Swiften/Network/NATPortMapping.h
new file mode 100644
index 0000000..82f62bb
--- /dev/null
+++ b/Swiften/Network/NATPortMapping.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Network/HostAddress.h>
+
+namespace Swift {
+ struct NATPortMapping {
+ enum Protocol {
+ TCP,
+ UDP,
+ };
+
+ NATPortMapping(int localPort, int publicPort, Protocol protocol = TCP, int leaseInSeconds = 60 * 60 * 24) : publicPort(publicPort), localPort(localPort), protocol(protocol), leaseInSeconds(leaseInSeconds) {
+
+ }
+
+ int publicPort;
+ int localPort;
+ Protocol protocol;
+ int leaseInSeconds;
+ };
+}
diff --git a/Swiften/Network/NATTraversalForwardPortRequest.h b/Swiften/Network/NATTraversalForwardPortRequest.h
index 8cdbd3d..1bbc9ca 100644
--- a/Swiften/Network/NATTraversalForwardPortRequest.h
+++ b/Swiften/Network/NATTraversalForwardPortRequest.h
@@ -7,28 +7,16 @@
#pragma once
#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Network/HostAddress.h>
+
+#include <Swiften/Network/NATPortMapping.h>
namespace Swift {
class NATTraversalForwardPortRequest {
public:
- struct PortMapping {
- enum Protocol {
- TCP,
- UDP,
- };
-
- unsigned int publicPort;
- unsigned int localPort;
- Protocol protocol;
- unsigned long leaseInSeconds;
- };
-
- public:
virtual ~NATTraversalForwardPortRequest();
virtual void run() = 0;
- boost::signal<void (boost::optional<PortMapping>)> onResult;
+ boost::signal<void (boost::optional<NATPortMapping>)> onResult;
};
}
diff --git a/Swiften/Network/NATTraversalInterface.cpp b/Swiften/Network/NATTraversalInterface.cpp
new file mode 100644
index 0000000..f8a0cc2
--- /dev/null
+++ b/Swiften/Network/NATTraversalInterface.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Network/NATTraversalInterface.h>
+
+#include <Swiften/Base/Log.h>
+
+
+namespace Swift {
+
+NATTraversalInterface::~NATTraversalInterface() {
+}
+
+}
diff --git a/Swiften/Network/NATTraversalInterface.h b/Swiften/Network/NATTraversalInterface.h
new file mode 100644
index 0000000..428db10
--- /dev/null
+++ b/Swiften/Network/NATTraversalInterface.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+#include <natpmp.h>
+
+#include <Swiften/Network/NATPortMapping.h>
+
+namespace Swift {
+ class NATTraversalInterface {
+ public:
+ virtual ~NATTraversalInterface();
+
+ virtual bool isAvailable() = 0;
+
+ virtual boost::optional<HostAddress> getPublicIP() = 0;
+ virtual boost::optional<NATPortMapping> addPortForward(int localPort, int publicPort) = 0;
+ virtual bool removePortForward(const NATPortMapping&) = 0;
+ };
+}
diff --git a/Swiften/Network/NATTraverser.h b/Swiften/Network/NATTraverser.h
index 4afd624..e48ce26 100644
--- a/Swiften/Network/NATTraverser.h
+++ b/Swiften/Network/NATTraverser.h
@@ -18,7 +18,7 @@ namespace Swift {
virtual ~NATTraverser();
virtual boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest() = 0;
- virtual boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(unsigned int localPort, unsigned int publicPort) = 0;
- virtual boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(unsigned int localPort, unsigned int publicPort) = 0;
+ virtual boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort) = 0;
+ virtual boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort) = 0;
};
}
diff --git a/Swiften/Network/NullNATTraversalInterface.h b/Swiften/Network/NullNATTraversalInterface.h
new file mode 100644
index 0000000..c76634f
--- /dev/null
+++ b/Swiften/Network/NullNATTraversalInterface.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+#include <natpmp.h>
+
+#include <Swiften/Network/NATTraversalInterface.h>
+
+namespace Swift {
+ class NullNATTraversalInterface : public NATTraversalInterface {
+ public:
+ virtual bool isAvailable() {
+ return true;
+ }
+
+ virtual boost::optional<HostAddress> getPublicIP() {
+ return boost::optional<HostAddress>();
+ }
+
+ virtual boost::optional<NATPortMapping> addPortForward(int, int) {
+ return boost::optional<NATPortMapping>();
+ }
+
+ virtual bool removePortForward(const NATPortMapping&) {
+ return false;
+ }
+ };
+}
diff --git a/Swiften/Network/NullNATTraverser.cpp b/Swiften/Network/NullNATTraverser.cpp
index 018ef91..8cb35cd 100644
--- a/Swiften/Network/NullNATTraverser.cpp
+++ b/Swiften/Network/NullNATTraverser.cpp
@@ -35,7 +35,7 @@ class NullNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest
}
virtual void run() {
- eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<PortMapping>()));
+ eventLoop->postEvent(boost::bind(boost::ref(onResult), boost::optional<NATPortMapping>()));
}
private:
@@ -62,11 +62,11 @@ boost::shared_ptr<NATTraversalGetPublicIPRequest> NullNATTraverser::createGetPub
return boost::make_shared<NullNATTraversalGetPublicIPRequest>(eventLoop);
}
-boost::shared_ptr<NATTraversalForwardPortRequest> NullNATTraverser::createForwardPortRequest(unsigned int, unsigned int) {
+boost::shared_ptr<NATTraversalForwardPortRequest> NullNATTraverser::createForwardPortRequest(int, int) {
return boost::make_shared<NullNATTraversalForwardPortRequest>(eventLoop);
}
-boost::shared_ptr<NATTraversalRemovePortForwardingRequest> NullNATTraverser::createRemovePortForwardingRequest(unsigned int, unsigned int) {
+boost::shared_ptr<NATTraversalRemovePortForwardingRequest> NullNATTraverser::createRemovePortForwardingRequest(int, int) {
return boost::make_shared<NullNATTraversalRemovePortForwardingRequest>(eventLoop);
}
diff --git a/Swiften/Network/NullNATTraverser.h b/Swiften/Network/NullNATTraverser.h
index 1b66a7d..5775a9b 100644
--- a/Swiften/Network/NullNATTraverser.h
+++ b/Swiften/Network/NullNATTraverser.h
@@ -16,8 +16,8 @@ namespace Swift {
NullNATTraverser(EventLoop* eventLoop);
boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest();
- boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(unsigned int localPort, unsigned int publicPort);
- boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(unsigned int localPort, unsigned int publicPort);
+ boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort);
+ boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort);
private:
EventLoop* eventLoop;
diff --git a/Swiften/Network/PlatformNATTraversalRequest.cpp b/Swiften/Network/PlatformNATTraversalRequest.cpp
deleted file mode 100644
index f875630..0000000
--- a/Swiften/Network/PlatformNATTraversalRequest.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "PlatformNATTraversalRequest.h"
-
-#include <Swiften/Network/PlatformNATTraversalWorker.h>
-
-namespace Swift {
-
-PlatformNATTraversalRequest::PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker) : worker(worker) {
-
-}
-
-PlatformNATTraversalRequest::~PlatformNATTraversalRequest() {
-
-}
-
-void PlatformNATTraversalRequest::doRun() {
- worker->addRequestToQueue(shared_from_this());
-}
-
-}
diff --git a/Swiften/Network/PlatformNATTraversalRequest.h b/Swiften/Network/PlatformNATTraversalRequest.h
deleted file mode 100644
index a891bab..0000000
--- a/Swiften/Network/PlatformNATTraversalRequest.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace Swift {
-
-class PlatformNATTraversalWorker;
-
-class PlatformNATTraversalRequest : public boost::enable_shared_from_this<PlatformNATTraversalRequest> {
-public:
- typedef boost::shared_ptr<PlatformNATTraversalRequest> ref;
-
-public:
- PlatformNATTraversalRequest(PlatformNATTraversalWorker* worker);
- virtual ~PlatformNATTraversalRequest();
-
- virtual void doRun();
- virtual void runBlocking() = 0;
-
-private:
- PlatformNATTraversalWorker* worker;
-};
-
-}
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;
- }
- }
-}
-
}
diff --git a/Swiften/Network/PlatformNATTraversalWorker.h b/Swiften/Network/PlatformNATTraversalWorker.h
index 9de1258..94d3339 100644
--- a/Swiften/Network/PlatformNATTraversalWorker.h
+++ b/Swiften/Network/PlatformNATTraversalWorker.h
@@ -11,51 +11,51 @@
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
+#include <boost/logic/tribool.hpp>
#include <Swiften/Network/NATTraverser.h>
#include <Swiften/Network/HostAddressPort.h>
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
+#include <Swiften/Network/NullNATTraversalInterface.h>
namespace Swift {
-
-class EventLoop;
-class NATTraversalGetPublicIPRequest;
-class NATTraversalForwardPortRequest;
-class NATTraversalRemovePortForwardingRequest;
-
-class PlatformNATTraversalWorker : public NATTraverser {
-private:
- enum BackendType {
- NotYetDecided,
- UPnP,
- NATPMP,
- None,
+ class EventLoop;
+ class NATTraversalGetPublicIPRequest;
+ class NATTraversalForwardPortRequest;
+ class NATTraversalRemovePortForwardingRequest;
+ class PlatformNATTraversalRequest;
+ class NATPMPInterface;
+ class MiniUPnPInterface;
+ class NATTraversalInterface;
+ class NATPortMapping;
+
+ class PlatformNATTraversalWorker : public NATTraverser {
+ friend class PlatformNATTraversalRequest;
+
+ public:
+ PlatformNATTraversalWorker(EventLoop* eventLoop);
+ ~PlatformNATTraversalWorker();
+
+ boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest();
+ boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(int localPort, int publicPort);
+ boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(int localPort, int publicPort);
+
+ private:
+ NATTraversalInterface* getNATTraversalInterface() const;
+ void addRequestToQueue(boost::shared_ptr<PlatformNATTraversalRequest>);
+ void run();
+
+ private:
+ EventLoop* eventLoop;
+ bool stopRequested;
+ boost::thread* thread;
+ std::deque<boost::shared_ptr<PlatformNATTraversalRequest> > queue;
+ boost::mutex queueMutex;
+ boost::condition_variable queueNonEmpty;
+
+ NullNATTraversalInterface* nullNATTraversalInterface;
+ mutable boost::logic::tribool natPMPSupported;
+ mutable NATPMPInterface* natPMPInterface;
+ mutable boost::logic::tribool miniUPnPSupported;
+ mutable MiniUPnPInterface* miniUPnPInterface;
};
-
-public:
- PlatformNATTraversalWorker(EventLoop* eventLoop);
- ~PlatformNATTraversalWorker();
-
- boost::shared_ptr<NATTraversalGetPublicIPRequest> createGetPublicIPRequest();
- boost::shared_ptr<NATTraversalForwardPortRequest> createForwardPortRequest(unsigned int localPort, unsigned int publicPort);
- boost::shared_ptr<NATTraversalRemovePortForwardingRequest> createRemovePortForwardingRequest(unsigned int localPort, unsigned int publicPort);
-
- void run();
- void addRequestToQueue(PlatformNATTraversalRequest::ref);
-
-private:
- void checkAvailableNATTraversalProtocols();
- void handleUPnPGetPublicIPResult(boost::optional<HostAddress> address);
- void handleNATPMPGetPublicIPResult(boost::optional<HostAddress> address);
-
-private:
- BackendType backendType;
- EventLoop* eventLoop;
- bool stopRequested;
- boost::thread* thread;
- std::deque<PlatformNATTraversalRequest::ref> queue;
- boost::mutex queueMutex;
- boost::condition_variable queueNonEmpty;
-};
-
}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index e44f868..49df18f 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -47,6 +47,7 @@ sourceList = [
"NATTraversalGetPublicIPRequest.cpp",
"NATTraversalForwardPortRequest.cpp",
"NATTraversalRemovePortForwardingRequest.cpp",
+ "NATTraversalInterface.cpp",
]
if myenv.get("HAVE_CARES", False) :
@@ -75,22 +76,17 @@ if myenv["experimental"] :
natpmp_env = myenv.Clone()
natpmp_env.Append(CPPDEFINES = natpmp_env["LIBNATPMP_FLAGS"].get("INTERNAL_CPPDEFINES", []))
objects += natpmp_env.SwiftenObject([
- "NATPMPNATTraversalGetPublicIPRequest.cpp",
- "NATPMPNATTraversalForwardPortRequest.cpp",
- "NATPMPNATTraversalRemovePortForwardingRequest.cpp"
+ "NATPMPInterface.cpp",
])
# LibMINIUPnP classes
upnp_env = myenv.Clone()
upnp_env.Append(CPPDEFINES = upnp_env["LIBMINIUPNPC_FLAGS"].get("INTERNAL_CPPDEFINES", []))
objects += upnp_env.SwiftenObject([
- "UPnPNATTraversalGetPublicIPRequest.cpp",
- "UPnPNATTraversalForwardPortRequest.cpp",
- "UPnPNATTraversalRemovePortForwardingRequest.cpp",
+ "MiniUPnPInterface.cpp",
])
objects += myenv.SwiftenObject([
"PlatformNATTraversalWorker.cpp",
- "PlatformNATTraversalRequest.cpp",
- ])
+ ])
swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp b/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp
deleted file mode 100644
index 6fcc01a..0000000
--- a/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "UPnPNATTraversalForwardPortRequest.h"
-
-#include <boost/format.hpp>
-
-#include <miniupnpc.h>
-#include <upnpcommands.h>
-#include <upnperrors.h>
-
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Network/NetworkInterface.h>
-#include <Swiften/Network/PlatformNetworkEnvironment.h>
-
-namespace Swift {
-
-UPnPNATTraversalForwardPortRequest::UPnPNATTraversalForwardPortRequest(NATTraversalForwardPortRequest::PortMapping mapping, PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker), mapping(mapping) {
-
-}
-
-UPnPNATTraversalForwardPortRequest::~UPnPNATTraversalForwardPortRequest() {
-
-}
-
-void UPnPNATTraversalForwardPortRequest::runBlocking() {
- boost::optional<PortMapping> result;
-
- UPNPDev* deviceList = 0;
- int error = 0;
- char lanAddrress[64];
-
- std::string publicPort = str(boost::format("%d") % mapping.publicPort);
- std::string localPort = str(boost::format("%d") % mapping.localPort);
- std::string internalClient = PlatformNetworkEnvironment().getLocalAddress().toString();
- std::string leaseSeconds = str(boost::format("%d") % mapping.leaseInSeconds);
- UPNPUrls urls;
- IGDdatas data;
-
- do {
- // find valid IGD
- deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
- if (!deviceList) {
- break;
- }
-
- if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddrress, sizeof(lanAddrress))) {
- break;
- }
-
- /*
- int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
- if (ret != UPNPCOMMAND_SUCCESS) {
- break;
- }*/
-
- int ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), localPort.c_str(), internalClient.c_str(), 0, mapping.protocol == NATTraversalForwardPortRequest::PortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str());
- if (ret == UPNPCOMMAND_SUCCESS) {
- result = boost::optional<NATTraversalForwardPortRequest::PortMapping>(mapping);
- }
- } while(false);
-
- freeUPNPDevlist(deviceList); deviceList = 0;
-
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/UPnPNATTraversalForwardPortRequest.h b/Swiften/Network/UPnPNATTraversalForwardPortRequest.h
deleted file mode 100644
index 777ab26..0000000
--- a/Swiften/Network/UPnPNATTraversalForwardPortRequest.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/NATTraversalForwardPortRequest.h>
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-
-namespace Swift {
-
-class UPnPNATTraversalForwardPortRequest : public NATTraversalForwardPortRequest, public PlatformNATTraversalRequest {
-public:
- UPnPNATTraversalForwardPortRequest(NATTraversalForwardPortRequest::PortMapping, PlatformNATTraversalWorker*);
- virtual ~UPnPNATTraversalForwardPortRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-
-private:
- NATTraversalForwardPortRequest::PortMapping mapping;
-};
-
-}
diff --git a/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.cpp b/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.cpp
deleted file mode 100644
index 4ed2f5f..0000000
--- a/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "UPnPNATTraversalGetPublicIPRequest.h"
-
-#include <miniupnpc.h>
-#include <upnpcommands.h>
-#include <upnperrors.h>
-
-namespace Swift {
-
-UPnPNATTraversalGetPublicIPRequest::UPnPNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker) {
-
-}
-
-UPnPNATTraversalGetPublicIPRequest::~UPnPNATTraversalGetPublicIPRequest() {
-
-}
-
-void UPnPNATTraversalGetPublicIPRequest::runBlocking() {
- boost::optional<HostAddress> result;
-
- UPNPDev* deviceList = 0;
- int error = 0;
- char lanAddrress[64];
- char externalIPAddress[40];
- UPNPUrls urls;
- IGDdatas data;
-
- do {
- // find valid IGD
- deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
- if (!deviceList) {
- break;
- }
-
- if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddrress, sizeof(lanAddrress))) {
- break;
- }
-
- int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
- if (ret != UPNPCOMMAND_SUCCESS) {
- break;
- } else {
- result = HostAddress(std::string(externalIPAddress));
- }
- } while(false);
-
- freeUPNPDevlist(deviceList); deviceList = 0;
-
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.h b/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.h
deleted file mode 100644
index 884f1de..0000000
--- a/Swiften/Network/UPnPNATTraversalGetPublicIPRequest.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/NATTraversalGetPublicIPRequest.h>
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-
-namespace Swift {
-
-class UPnPNATTraversalGetPublicIPRequest : public NATTraversalGetPublicIPRequest, public PlatformNATTraversalRequest {
-public:
- UPnPNATTraversalGetPublicIPRequest(PlatformNATTraversalWorker*);
- virtual ~UPnPNATTraversalGetPublicIPRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-};
-
-}
diff --git a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp
deleted file mode 100644
index 9b83173..0000000
--- a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include "UPnPNATTraversalRemovePortForwardingRequest.h"
-
-#include <boost/format.hpp>
-
-#include <miniupnpc.h>
-#include <upnpcommands.h>
-#include <upnperrors.h>
-
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Base/Log.h>
-#include <Swiften/Network/NetworkInterface.h>
-#include <Swiften/Network/PlatformNetworkEnvironment.h>
-
-namespace Swift {
-
-UPnPNATTraversalRemovePortForwardingRequest::UPnPNATTraversalRemovePortForwardingRequest(NATTraversalRemovePortForwardingRequest::PortMapping mapping, PlatformNATTraversalWorker* worker) : PlatformNATTraversalRequest(worker), mapping(mapping) {
-
-}
-
-UPnPNATTraversalRemovePortForwardingRequest::~UPnPNATTraversalRemovePortForwardingRequest() {
-
-}
-
-void UPnPNATTraversalRemovePortForwardingRequest::runBlocking() {
- boost::optional<bool> result;
-
- UPNPDev* deviceList = 0;
- int error = 0;
- char lanAddrress[64];
-
- std::string publicPort = str(boost::format("%d") % mapping.publicPort);
- std::string localPort = str(boost::format("%d") % mapping.localPort);
- std::string internalClient = PlatformNetworkEnvironment().getLocalAddress().toString();
- std::string leaseSeconds = str(boost::format("%d") % mapping.leaseInSeconds);
- UPNPUrls urls;
- IGDdatas data;
-
- do {
- // find valid IGD
- deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
- if (!deviceList) {
- break;
- }
-
- if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddrress, sizeof(lanAddrress))) {
- break;
- }
-
- /*
- int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
- if (ret != UPNPCOMMAND_SUCCESS) {
- break;
- }*/
- SWIFT_LOG(debug) << "Start removing port forwarding..." << std::endl;
- int ret = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), mapping.protocol == NATTraversalRemovePortForwardingRequest::PortMapping::TCP ? "TCP" : "UDP", 0);
-
- if (ret == UPNPCOMMAND_SUCCESS) {
- SWIFT_LOG(debug) << "Removing port " << publicPort << " successfull." << std::endl;
- result = true;
- } else {
- SWIFT_LOG(debug) << "Removing port " << publicPort << " failed." << std::endl;
- result = false;
- }
- } while(false);
-
- freeUPNPDevlist(deviceList); deviceList = 0;
-
- onResult(result);
-}
-
-}
diff --git a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h
deleted file mode 100644
index 644eae7..0000000
--- a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2011 Tobias Markmann
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Network/PlatformNATTraversalRequest.h>
-#include <Swiften/Network/NATTraversalRemovePortForwardingRequest.h>
-
-namespace Swift {
-
-class UPnPNATTraversalRemovePortForwardingRequest : public NATTraversalRemovePortForwardingRequest, public PlatformNATTraversalRequest {
-public:
- UPnPNATTraversalRemovePortForwardingRequest(NATTraversalRemovePortForwardingRequest::PortMapping, PlatformNATTraversalWorker*);
- virtual ~UPnPNATTraversalRemovePortForwardingRequest();
-
- virtual void runBlocking();
-
- virtual void run() {
- doRun();
- }
-
-private:
- NATTraversalRemovePortForwardingRequest::PortMapping mapping;
-};
-
-}