From 1800359adf7e917935a66ce473a7cdbbe4b32017 Mon Sep 17 00:00:00 2001 From: Vladimir Pouzanov Date: Fri, 31 May 2024 18:32:30 +0000 Subject: [PATCH] Add support for overriding the NAT-PMP gateway with a nat_pmp_gateway config option. --- include/libtorrent/natpmp.hpp | 2 +- include/libtorrent/settings_pack.hpp | 5 +++++ src/natpmp.cpp | 30 ++++++++++++++++------------ src/session_impl.cpp | 6 +++++- src/settings_pack.cpp | 3 ++- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/include/libtorrent/natpmp.hpp b/include/libtorrent/natpmp.hpp index 68ebf5b17d5..d4e1422c848 100644 --- a/include/libtorrent/natpmp.hpp +++ b/include/libtorrent/natpmp.hpp @@ -91,7 +91,7 @@ struct TORRENT_EXTRA_EXPORT natpmp final { natpmp(io_context& ios, aux::portmap_callback& cb, aux::listen_socket_handle ls); - void start(ip_interface const& ip); + void start(ip_interface const& ip, boost::optional
const& gateway); // maps the ports, if a port is set to 0 // it will not be mapped diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index b35729d6dff..18f49d03850 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -391,6 +391,11 @@ namespace aux { // ``router.bt.ouinet.work:6881``, dht_bootstrap_nodes, + // Overrides the NAT-PMP service gateway. When set, libtorrent won't try + // to resolve the default gateway and instead will send the requests to + // the address specified. + nat_pmp_gateway, + max_string_setting_internal }; diff --git a/src/natpmp.cpp b/src/natpmp.cpp index 6011afe48ba..7042ca3aef9 100644 --- a/src/natpmp.cpp +++ b/src/natpmp.cpp @@ -152,31 +152,35 @@ natpmp::natpmp(io_context& ios m_mappings.reserve(10); } -void natpmp::start(ip_interface const& ip) +void natpmp::start(ip_interface const& ip, boost::optional
const& gateway) { TORRENT_ASSERT(is_single_thread()); // assume servers support PCP and fall back to NAT-PMP // if necessary m_version = version_pcp; - + error_code ec; address const& local_address = ip.interface_address; - error_code ec; - auto const routes = enum_routes(m_ioc, ec); - if (ec) + boost::optional
route = gateway; + if (!route) { -#ifndef TORRENT_DISABLE_LOGGING - if (should_log()) + + auto const routes = enum_routes(m_ioc, ec); + if (ec) { - log("failed to enumerate routes: %s" - , convert_from_native(ec.message()).c_str()); + #ifndef TORRENT_DISABLE_LOGGING + if (should_log()) + { + log("failed to enumerate routes: %s" + , convert_from_native(ec.message()).c_str()); + } + #endif + disable(ec); } -#endif - disable(ec); - } - auto const route = get_gateway(ip, routes); + route = get_gateway(ip, routes); + } if (!route) { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index fe8598524ff..ec3c3e8a5ed 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -5676,7 +5676,11 @@ namespace { ip.netmask = s->netmask; std::strncpy(ip.name, s->device.c_str(), sizeof(ip.name) - 1); ip.name[sizeof(ip.name) - 1] = '\0'; - s->natpmp_mapper->start(ip); + + error_code ignored; + std::string gateway = m_settings.get_str(settings_pack::nat_pmp_gateway); + boost::optional
gateway_addr = make_address(gateway, ignored); + s->natpmp_mapper->start(ip, gateway == "" ? boost::none : gateway_addr); } } diff --git a/src/settings_pack.cpp b/src/settings_pack.cpp index 72d0a886fd9..61300b84b34 100644 --- a/src/settings_pack.cpp +++ b/src/settings_pack.cpp @@ -149,7 +149,8 @@ constexpr int DISK_WRITE_MODE = settings_pack::enable_os_cache; SET(proxy_password, "", &session_impl::update_proxy), SET(i2p_hostname, "", &session_impl::update_i2p_bridge), SET(peer_fingerprint, "-LT20B0-", nullptr), - SET(dht_bootstrap_nodes, "dht.libtorrent.org:25401", &session_impl::update_dht_bootstrap_nodes) + SET(dht_bootstrap_nodes, "dht.libtorrent.org:25401", &session_impl::update_dht_bootstrap_nodes), + SET(nat_pmp_gateway, "", &session_impl::update_upnp) }}); CONSTEXPR_SETTINGS