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:
parent
7611e2ee44
commit
9dea5d839e
3 changed files with 88 additions and 6 deletions
34
src/main.cpp
34
src/main.cpp
|
@ -23,12 +23,18 @@
|
|||
#include <ciso646>
|
||||
|
||||
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) {
|
||||
if (redir.protocol == parProtocol and redir.internal_port == parPort and redir.internal_client == parAddr)
|
||||
return true;
|
||||
if (redir.protocol == parProtocol and redir.internal_port == parPort)
|
||||
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) {
|
||||
|
@ -36,8 +42,26 @@ namespace {
|
|||
|
||||
for (auto& mapping : parPortMappings) {
|
||||
//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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
52
src/upnp.cpp
52
src/upnp.cpp
|
@ -19,12 +19,14 @@
|
|||
#include "miniupnpc.h"
|
||||
#include "upnpcommands.h"
|
||||
#include "upnperrors.h"
|
||||
#include "enum.h"
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <ciso646>
|
||||
#include <strings.h>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
# define KUU_VERBOSE
|
||||
|
@ -35,6 +37,12 @@
|
|||
#endif
|
||||
|
||||
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 {
|
||||
void freeUPNPDevlist (struct UPNPDev* parDele) {
|
||||
#if defined(KUU_VERBOSE)
|
||||
|
@ -328,4 +336,48 @@ namespace kuu {
|
|||
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
|
||||
|
|
|
@ -52,6 +52,12 @@ namespace kuu {
|
|||
Protocol parProtocol
|
||||
);
|
||||
|
||||
void remove_port_mapping (
|
||||
uint16_t parExtPort,
|
||||
const std::string& parAddr,
|
||||
Protocol parProtocol
|
||||
);
|
||||
|
||||
private:
|
||||
struct LocalData;
|
||||
|
||||
|
|
Loading…
Reference in a new issue