summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Network/MiniUPnPInterface.cpp45
-rw-r--r--Swiften/Network/MiniUPnPInterface.h15
-rw-r--r--Swiften/Network/NATPMPInterface.cpp40
-rw-r--r--Swiften/Network/NATPMPInterface.h11
4 files changed, 65 insertions, 46 deletions
diff --git a/Swiften/Network/MiniUPnPInterface.cpp b/Swiften/Network/MiniUPnPInterface.cpp
index c9f682f..c729371 100644
--- a/Swiften/Network/MiniUPnPInterface.cpp
+++ b/Swiften/Network/MiniUPnPInterface.cpp
@@ -6,42 +6,53 @@
#include <Swiften/Network/MiniUPnPInterface.h>
+#include <miniupnpc.h>
#include <upnpcommands.h>
#include <upnperrors.h>
+#include <boost/smart_ptr/make_shared.hpp>
#include <boost/lexical_cast.hpp>
#include <Swiften/Base/Log.h>
namespace Swift {
-MiniUPnPInterface::MiniUPnPInterface() : isValid(false) {
+struct MiniUPnPInterface::Private {
+ bool isValid;
+ std::string localAddress;
+ UPNPDev* deviceList;
+ UPNPUrls urls;
+ IGDdatas data;
+};
+
+MiniUPnPInterface::MiniUPnPInterface() : p(boost::make_shared<Private>()) {
+ p->isValid = false;
int error = 0;
- deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
- if (!deviceList) {
+ p->deviceList = upnpDiscover(1500 /* timeout in ms */, 0, 0, 0, 0 /* do IPv6? */, &error);
+ if (!p->deviceList) {
return;
}
char lanAddress[64];
- if (!UPNP_GetValidIGD(deviceList, &urls, &data, lanAddress, sizeof(lanAddress))) {
+ if (!UPNP_GetValidIGD(p->deviceList, &p->urls, &p->data, lanAddress, sizeof(lanAddress))) {
return;
}
- localAddress = std::string(lanAddress);
- isValid = true;
+ p->localAddress = std::string(lanAddress);
+ p->isValid = true;
}
MiniUPnPInterface::~MiniUPnPInterface() {
- if (isValid) {
- FreeUPNPUrls(&urls);
+ if (p->isValid) {
+ FreeUPNPUrls(&p->urls);
}
- freeUPNPDevlist(deviceList);
+ freeUPNPDevlist(p->deviceList);
}
boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
- if (!isValid) {
+ if (!p->isValid) {
return boost::optional<HostAddress>();
}
char externalIPAddress[40];
- int ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
+ int ret = UPNP_GetExternalIPAddress(p->urls.controlURL, p->data.first.servicetype, externalIPAddress);
if (ret != UPNPCOMMAND_SUCCESS) {
return boost::optional<HostAddress>();
}
@@ -51,7 +62,7 @@ boost::optional<HostAddress> MiniUPnPInterface::getPublicIP() {
}
boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLocalPort, int actualPublicPort) {
- if (!isValid) {
+ if (!p->isValid) {
return boost::optional<NATPortMapping>();
}
@@ -61,7 +72,7 @@ boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLoca
std::string localPort = boost::lexical_cast<std::string>(mapping.getLocalPort());
std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds());
- int ret = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), localPort.c_str(), localAddress.c_str(), 0, mapping.getPublicPort() == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str());
+ int ret = UPNP_AddPortMapping(p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), localPort.c_str(), p->localAddress.c_str(), 0, mapping.getPublicPort() == NATPortMapping::TCP ? "TCP" : "UDP", 0, leaseSeconds.c_str());
if (ret == UPNPCOMMAND_SUCCESS) {
return mapping;
}
@@ -71,7 +82,7 @@ boost::optional<NATPortMapping> MiniUPnPInterface::addPortForward(int actualLoca
}
bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) {
- if (!isValid) {
+ if (!p->isValid) {
return false;
}
@@ -79,8 +90,12 @@ bool MiniUPnPInterface::removePortForward(const NATPortMapping& mapping) {
std::string localPort = boost::lexical_cast<std::string>(mapping.getLocalPort());
std::string leaseSeconds = boost::lexical_cast<std::string>(mapping.getLeaseInSeconds());
- int ret = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, publicPort.c_str(), mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0);
+ int ret = UPNP_DeletePortMapping(p->urls.controlURL, p->data.first.servicetype, publicPort.c_str(), mapping.getProtocol() == NATPortMapping::TCP ? "TCP" : "UDP", 0);
return ret == UPNPCOMMAND_SUCCESS;
}
+bool MiniUPnPInterface::isAvailable() {
+ return p->isValid;
+}
+
}
diff --git a/Swiften/Network/MiniUPnPInterface.h b/Swiften/Network/MiniUPnPInterface.h
index ae9be66..ced7db2 100644
--- a/Swiften/Network/MiniUPnPInterface.h
+++ b/Swiften/Network/MiniUPnPInterface.h
@@ -7,30 +7,25 @@
#pragma once
#include <boost/optional.hpp>
-#include <miniupnpc.h>
+#include <boost/noncopyable.hpp>
#include <Swiften/Network/NATPortMapping.h>
#include <Swiften/Network/NATTraversalInterface.h>
namespace Swift {
- class MiniUPnPInterface : public NATTraversalInterface {
+ class MiniUPnPInterface : public NATTraversalInterface, boost::noncopyable {
public:
MiniUPnPInterface();
~MiniUPnPInterface();
- virtual bool isAvailable() {
- return isValid;
- }
+ virtual bool isAvailable();
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;
+ class Private;
+ boost::shared_ptr<Private> p;
};
}
diff --git a/Swiften/Network/NATPMPInterface.cpp b/Swiften/Network/NATPMPInterface.cpp
index 36553ed..220e3e9 100644
--- a/Swiften/Network/NATPMPInterface.cpp
+++ b/Swiften/Network/NATPMPInterface.cpp
@@ -6,18 +6,28 @@
#include <Swiften/Network/NATPMPInterface.h>
+#include <boost/smart_ptr/make_shared.hpp>
+
#include <Swiften/Base/Log.h>
+// This has to be included after the previous headers, because of WIN32 macro
+// being defined somewhere.
+#include <natpmp.h>
+
#pragma GCC diagnostic ignored "-Wold-style-cast"
namespace Swift {
-NATPMPInterface::NATPMPInterface() {
- initnatpmp(&natpmp, 0, 0);
+struct NATPMPInterface::Private {
+ natpmp_t natpmp;
+};
+
+NATPMPInterface::NATPMPInterface() : p(boost::make_shared<Private>()) {
+ initnatpmp(&p->natpmp, 0, 0);
}
NATPMPInterface::~NATPMPInterface() {
- closenatpmp(&natpmp);
+ closenatpmp(&p->natpmp);
}
bool NATPMPInterface::isAvailable() {
@@ -25,7 +35,7 @@ bool NATPMPInterface::isAvailable() {
}
boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
- if (sendpublicaddressrequest(&natpmp) < 0) {
+ if (sendpublicaddressrequest(&p->natpmp) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP public address request!" << std::endl;
return boost::optional<HostAddress>();
}
@@ -36,10 +46,10 @@ boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while (r == NATPMP_TRYAGAIN);
if (r == 0) {
@@ -53,7 +63,7 @@ boost::optional<HostAddress> NATPMPInterface::getPublicIP() {
boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, int publicPort) {
NATPortMapping mapping(localPort, publicPort, NATPortMapping::TCP);
- if (sendnewportmappingrequest(&natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.getLeaseInSeconds(), mapping.getPublicPort(), mapping.getLocalPort()) < 0) {
+ if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, mapping.getLeaseInSeconds(), mapping.getPublicPort(), mapping.getLocalPort()) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP port forwarding request!" << std::endl;
return boost::optional<NATPortMapping>();
}
@@ -64,10 +74,10 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while(r == NATPMP_TRYAGAIN);
if (r == 0) {
@@ -81,7 +91,7 @@ boost::optional<NATPortMapping> NATPMPInterface::addPortForward(int localPort, i
}
bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) {
- if (sendnewportmappingrequest(&natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.getLocalPort()) < 0) {
+ if (sendnewportmappingrequest(&p->natpmp, mapping.getProtocol() == NATPortMapping::TCP ? NATPMP_PROTOCOL_TCP : NATPMP_PROTOCOL_UDP, 0, 0, mapping.getLocalPort()) < 0) {
SWIFT_LOG(debug) << "Failed to send NAT-PMP remove forwarding request!" << std::endl;
return false;
}
@@ -92,10 +102,10 @@ bool NATPMPInterface::removePortForward(const NATPortMapping& mapping) {
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
- FD_SET(natpmp.s, &fds);
- getnatpmprequesttimeout(&natpmp, &timeout);
+ FD_SET(p->natpmp.s, &fds);
+ getnatpmprequesttimeout(&p->natpmp, &timeout);
select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
- r = readnatpmpresponseorretry(&natpmp, &response);
+ r = readnatpmpresponseorretry(&p->natpmp, &response);
} while(r == NATPMP_TRYAGAIN);
if (r == 0) {
diff --git a/Swiften/Network/NATPMPInterface.h b/Swiften/Network/NATPMPInterface.h
index 6e7fb73..7073bd2 100644
--- a/Swiften/Network/NATPMPInterface.h
+++ b/Swiften/Network/NATPMPInterface.h
@@ -7,15 +7,13 @@
#pragma once
#include <boost/optional.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
#include <Swiften/Network/NATPortMapping.h>
#include <Swiften/Network/NATTraversalInterface.h>
-// This has to be included after the previous headers, because of WIN32 macro
-// being defined somewhere.
-#include <natpmp.h>
-
namespace Swift {
- class NATPMPInterface : public NATTraversalInterface {
+ class NATPMPInterface : public NATTraversalInterface, boost::noncopyable {
public:
NATPMPInterface();
~NATPMPInterface();
@@ -27,6 +25,7 @@ namespace Swift {
virtual bool removePortForward(const NATPortMapping&);
private:
- natpmp_t natpmp;
+ class Private;
+ boost::shared_ptr<Private> p;
};
}