1
0
Fork 0
mirror of https://bitbucket.org/King_DuckZ/keepupnpup.git synced 2024-11-07 21:29:00 +00:00

Auto delete mapping if needed to make room for the new one.

This commit is contained in:
King_DuckZ 2016-09-15 01:35:04 +02:00
parent 7611e2ee44
commit 9dea5d839e
3 changed files with 88 additions and 6 deletions

View file

@ -23,12 +23,18 @@
#include <ciso646> #include <ciso646>
namespace { namespace {
bool has_mapping (const std::vector<kuu::Redirection>& parRedirs, const std::string& parAddr, uint16_t parPort, kuu::Protocol parProtocol) { enum CurrentMappingType {
NoMapping,
PresentWithSameIP,
PresentWithDifferentIP
};
CurrentMappingType has_mapping (const std::vector<kuu::Redirection>& parRedirs, const std::string& parAddr, uint16_t parPort, kuu::Protocol parProtocol) {
for (auto& redir : parRedirs) { for (auto& redir : parRedirs) {
if (redir.protocol == parProtocol and redir.internal_port == parPort and redir.internal_client == parAddr) if (redir.protocol == parProtocol and redir.internal_port == parPort)
return true; return (redir.internal_client == parAddr ? PresentWithSameIP : PresentWithDifferentIP);
} }
return false; return NoMapping;
} }
void add_bindings (kuu::UPNP& parUpnp, const std::string& parHost, const kuu::RedirectSetting::PortMappingsList& parPortMappings, const std::string& parDesc) { void add_bindings (kuu::UPNP& parUpnp, const std::string& parHost, const kuu::RedirectSetting::PortMappingsList& parPortMappings, const std::string& parDesc) {
@ -36,8 +42,26 @@ namespace {
for (auto& mapping : parPortMappings) { for (auto& mapping : parPortMappings) {
//std::cout << "Adding " << mapping.port << " --> " << parHost << ":" << mapping.internal_port << " " << mapping.protocol << '\n'; //std::cout << "Adding " << mapping.port << " --> " << parHost << ":" << mapping.internal_port << " " << mapping.protocol << '\n';
if (not has_mapping(redirs, parHost, mapping.port, mapping.protocol)) bool try_add_mapping = true;
parUpnp.add_port_mapping(mapping.port, mapping.internal_port, parHost, parDesc, 0, mapping.protocol); try {
const CurrentMappingType curr_mapping =
has_mapping(redirs, parHost, mapping.port, mapping.protocol);
switch (curr_mapping) {
case PresentWithDifferentIP:
parUpnp.remove_port_mapping(mapping.port, parHost, mapping.protocol);
case NoMapping:
parUpnp.add_port_mapping(mapping.port, mapping.internal_port, parHost, parDesc, 0, mapping.protocol);
break;
case PresentWithSameIP:
break;
};
}
catch (const kuu::UPNPException& e) {
std::cerr << e.what() << std::endl;
}
} }
} }

View file

@ -19,12 +19,14 @@
#include "miniupnpc.h" #include "miniupnpc.h"
#include "upnpcommands.h" #include "upnpcommands.h"
#include "upnperrors.h" #include "upnperrors.h"
#include "enum.h"
#include <array> #include <array>
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include <ciso646> #include <ciso646>
#include <strings.h> #include <strings.h>
#include <cassert> #include <cassert>
#include <cstdint>
#if !defined(NDEBUG) #if !defined(NDEBUG)
# define KUU_VERBOSE # define KUU_VERBOSE
@ -35,6 +37,12 @@
#endif #endif
namespace kuu { namespace kuu {
BETTER_ENUM(UPNPDeleteErrors, uint16_t,
InvalidArgs = 402, //See UPnP Device Architecture section on Control.
NotAuthorized = 606, //The action requested REQUIRES authorization and the sender was not authorized.
NoSuchEntryInArray = 714 //The specified value does not exist in the array
);
namespace { namespace {
void freeUPNPDevlist (struct UPNPDev* parDele) { void freeUPNPDevlist (struct UPNPDev* parDele) {
#if defined(KUU_VERBOSE) #if defined(KUU_VERBOSE)
@ -328,4 +336,48 @@ namespace kuu {
throw UPNPException(r, oss.str().c_str(), strupnperror(r)); throw UPNPException(r, oss.str().c_str(), strupnperror(r));
} }
} }
void throw_if_dele_failed (int parRetval, uint16_t parExtPort, const std::string& parAddr, Protocol parProtocol) {
if (not parRetval)
return;
std::ostringstream oss;
oss << "Unable to delete " << parProtocol << ' ' << parAddr <<
':' << parExtPort << " - error " << parRetval << ": ";
switch (parRetval) {
case UPNPDeleteErrors::NotAuthorized:
oss << "The action requested REQUIRES authorization and the sender was not authorized";
break;
case UPNPDeleteErrors::NoSuchEntryInArray:
oss << "The specified value does not exist in the array";
break;
case UPNPDeleteErrors::InvalidArgs:
oss << "See UPnP Device Architecture section on Control";
break;
default:
oss << "Unknown error";
}
throw UPNPException(parRetval, oss.str().c_str(), strupnperror(parRetval));
}
void UPNP::remove_port_mapping (
uint16_t parExtPort,
const std::string& parAddr,
Protocol parProtocol
) {
const int dele_retval = UPNP_DeletePortMapping(
m_local_data->urls->controlURL,
m_local_data->data.first.servicetype,
std::to_string(parExtPort).c_str(),
parProtocol._to_string(),
parAddr.c_str()
);
throw_if_dele_failed(dele_retval, parExtPort, parAddr, parProtocol);
}
} //namespace kuu } //namespace kuu

View file

@ -52,6 +52,12 @@ namespace kuu {
Protocol parProtocol Protocol parProtocol
); );
void remove_port_mapping (
uint16_t parExtPort,
const std::string& parAddr,
Protocol parProtocol
);
private: private:
struct LocalData; struct LocalData;