diff options
-rw-r--r-- | Swiften/Network/MiniUPnPInterface.cpp | 45 | ||||
-rw-r--r-- | Swiften/Network/MiniUPnPInterface.h | 15 | ||||
-rw-r--r-- | Swiften/Network/NATPMPInterface.cpp | 40 | ||||
-rw-r--r-- | Swiften/Network/NATPMPInterface.h | 11 |
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; }; } |