From 560b27b1bf5a08da04e0533d5adb040fec9b319b Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 21 Sep 2016 01:28:37 +0200 Subject: [PATCH] Add an option to delete redirections to current host if they are not in the yaml --- keepupnpup.yml | 1 + src/main.cpp | 39 +++++++++++++++++++++++++++++++++++---- src/settings.cpp | 4 ++++ src/settings.hpp | 1 + 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/keepupnpup.yml b/keepupnpup.yml index c3aab3f..fdb9520 100644 --- a/keepupnpup.yml +++ b/keepupnpup.yml @@ -7,3 +7,4 @@ redirect: - 49164 desc: RoutArm redir autoremove: true + dropunused: true diff --git a/src/main.cpp b/src/main.cpp index 552daed..4cdd4e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace { enum CurrentMappingType { @@ -38,21 +40,47 @@ namespace { return NoMapping; } + void remove_unused_bindings( + kuu::UPNP& parUpnp, + const std::vector& parActiveRedirs, + const std::string& parHost, + const kuu::RedirectSetting::PortMappingsList& parPortMappings + ) { + using boost::adaptors::filtered; + + auto redirs_to_host = parActiveRedirs | + filtered([&](const kuu::Redirection& r) { return parHost == r.remote_host; }); + + for (const auto& redir : redirs_to_host) { + auto it_found = std::find_if( + parPortMappings.begin(), + parPortMappings.end(), + [&](const kuu::PortMapping& m) { + return redir.protocol == m.protocol and + redir.external_port == m.port and + redir.internal_port == m.internal_port; + } + ); + if (it_found == parPortMappings.end()) { + parUpnp.remove_port_mapping(it_found->port, parHost, it_found->protocol); + } + } + } + void add_bindings ( kuu::UPNP& parUpnp, + const std::vector& parActiveRedirs, const std::string& parHost, const kuu::RedirectSetting::PortMappingsList& parPortMappings, const std::string& parDesc, bool parTryForcing ) { - const std::vector redirs = parUpnp.redirections(); - for (auto& mapping : parPortMappings) { //std::cout << "Adding " << mapping.port << " --> " << parHost << ":" << mapping.internal_port << " " << mapping.protocol << '\n'; bool try_add_mapping = true; try { const CurrentMappingType curr_mapping = - has_mapping(redirs, parHost, mapping.port, mapping.protocol); + has_mapping(parActiveRedirs, parHost, mapping.port, mapping.protocol); const CurrentMappingType decided_mapping = (PresentWithDifferentIP == curr_mapping and not parTryForcing ? IgnoreMapping : curr_mapping); @@ -79,8 +107,11 @@ namespace { kuu::UPNP upnp; kuu::RedirectSetting settings = kuu::load_redirect_settings("keepupnpup.yml", upnp.lanaddr()); + const std::vector redirs = upnp.redirections(); - add_bindings(upnp, settings.host, settings.port_mappings, settings.desc, settings.autoremove_old); + add_bindings(upnp, redirs, settings.host, settings.port_mappings, settings.desc, settings.autoremove_old); + if (settings.drop_unused) + remove_unused_bindings(upnp, redirs, settings.host, settings.port_mappings); } } //unnamed namespace diff --git a/src/settings.cpp b/src/settings.cpp index b6b81a4..fa9c874 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -86,6 +86,10 @@ namespace kuu { redir_settings.autoremove_old = to_boolean(redirect_node["autoremove"].as()); else redir_settings.autoremove_old = false; + if (redirect_node["dropunused"]) + redir_settings.drop_unused = to_boolean(redirect_node["dropunused"].as()); + else + redir_settings.drop_unused = false; return redir_settings; } diff --git a/src/settings.hpp b/src/settings.hpp index 90b3c63..ed412fa 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -42,6 +42,7 @@ namespace kuu { std::string desc; PortMappingsList port_mappings; bool autoremove_old; + bool drop_unused; }; RedirectSetting load_redirect_settings (const std::string& parPath, const std::string& parLanAddr);