diff --git a/include/libtorrent/enum_net.hpp b/include/libtorrent/enum_net.hpp
index 033c6dc47..5ac724356 100644
--- a/include/libtorrent/enum_net.hpp
+++ b/include/libtorrent/enum_net.hpp
@@ -107,13 +107,6 @@ namespace libtorrent {
TORRENT_EXTRA_EXPORT boost::optional
get_gateway(
ip_interface const& iface, span routes);
- TORRENT_EXTRA_EXPORT boost::optional get_default_route(io_service& ios
- , string_view device, bool v6, error_code& ec);
-
- // returns the first default gateway found if device is empty
- TORRENT_EXTRA_EXPORT address get_default_gateway(io_service& ios
- , string_view device, bool v6, error_code& ec);
-
// attempt to bind socket to the device with the specified name. For systems
// that don't support SO_BINDTODEVICE the socket will be bound to one of the
// IP addresses of the specified device. In this case it is necessary to
diff --git a/include/libtorrent/natpmp.hpp b/include/libtorrent/natpmp.hpp
index deb1d4cbc..63e804bd0 100644
--- a/include/libtorrent/natpmp.hpp
+++ b/include/libtorrent/natpmp.hpp
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/debug.hpp"
#include "libtorrent/aux_/portmap.hpp"
#include "libtorrent/aux_/vector.hpp"
+#include "libtorrent/enum_net.hpp" // for ip_interface
namespace libtorrent {
@@ -85,7 +86,7 @@ struct TORRENT_EXTRA_EXPORT natpmp
{
natpmp(io_service& ios, aux::portmap_callback& cb);
- void start(address local_address, std::string device);
+ void start(ip_interface const& ip);
// maps the ports, if a port is set to 0
// it will not be mapped
diff --git a/src/enum_net.cpp b/src/enum_net.cpp
index c5d74034e..7d5d4b996 100644
--- a/src/enum_net.cpp
+++ b/src/enum_net.cpp
@@ -817,28 +817,6 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl
return {};
}
- boost::optional get_default_route(io_service& ios
- , string_view const device, bool const v6, error_code& ec)
- {
- std::vector const ret = enum_routes(ios, ec);
- auto const i = std::find_if(ret.begin(), ret.end()
- , [device,v6](ip_route const& r)
- {
- return r.destination.is_unspecified()
- && r.destination.is_v6() == v6
- && (device.empty() || r.name == device);
- });
- if (i == ret.end()) return boost::none;
- return *i;
- }
-
- address get_default_gateway(io_service& ios
- , string_view const device, bool const v6, error_code& ec)
- {
- auto const default_route = get_default_route(ios, device, v6, ec);
- return default_route ? default_route->gateway : address();
- }
-
std::vector enum_routes(io_service& ios, error_code& ec)
{
std::vector ret;
diff --git a/src/natpmp.cpp b/src/natpmp.cpp
index 5876683ea..84261edd4 100644
--- a/src/natpmp.cpp
+++ b/src/natpmp.cpp
@@ -146,28 +146,31 @@ natpmp::natpmp(io_service& ios
m_mappings.reserve(10);
}
-void natpmp::start(address local_address, std::string device)
+void natpmp::start(ip_interface const& ip)
{
TORRENT_ASSERT(is_single_thread());
- error_code ec;
-
// assume servers support PCP and fall back to NAT-PMP
// if necessary
m_version = version_pcp;
- // we really want a device name to get the right default gateway
- // try to find one even if the listen socket isn't bound to a device
- if (device.empty())
+ address const& local_address = ip.interface_address;
+
+ error_code ec;
+ auto const routes = enum_routes(get_io_service(m_socket), ec);
+ if (ec)
{
- device = device_for_address(local_address, get_io_service(m_socket), ec);
- // if this fails fall back to using the first default gateway in the
- // routing table
- ec.clear();
+#ifndef TORRENT_DISABLE_LOGGING
+ if (should_log())
+ {
+ log("failed to enumerate routes: %s"
+ , convert_from_native(ec.message()).c_str());
+ }
+#endif
+ disable(ec);
}
- auto const route = get_default_route(get_io_service(m_socket)
- , device, local_address.is_v6(), ec);
+ auto const route = get_gateway(ip, routes);
if (!route)
{
@@ -175,7 +178,7 @@ void natpmp::start(address local_address, std::string device)
if (should_log())
{
log("failed to find default route for \"%s\" %s: %s"
- , device.c_str(), local_address.to_string().c_str()
+ , ip.name, local_address.to_string().c_str()
, convert_from_native(ec.message()).c_str());
}
#endif
@@ -183,65 +186,16 @@ void natpmp::start(address local_address, std::string device)
return;
}
- if (device.empty()) device = route->name;
-
- TORRENT_ASSERT(!device.empty());
-
- // PCP requires reporting the source address at the application
- // layer so the socket MUST be bound to a specific address
- // if the caller didn't specify one then get the first suitable
- // address from the OS
- if (local_address.is_unspecified())
- {
- std::vector const net = enum_net_interfaces(
- get_io_service(m_socket), ec);
-
- auto const it = std::find_if(net.begin(), net.end(), [&](ip_interface const& i)
- {
- return i.interface_address.is_v4() == local_address.is_v4()
- && (i.interface_address.is_v4() || !is_local(i.interface_address))
- && i.name == device;
- });
-
- if (it != net.end())
- {
- local_address = it->interface_address;
- }
- else
- {
- // if we can't get a specific address to bind to we'll have
- // to fall back to NAT-PMP
- // but NAT-PMP doesn't support IPv6 so if that's what is being
- // requested we can't do anything
- if (local_address.is_v6())
- {
- if (!ec) ec = boost::asio::error::address_family_not_supported;
-#ifndef TORRENT_DISABLE_LOGGING
- if (should_log())
- {
- log("cannot map IPv6 without a local address, %s"
- , convert_from_native(ec.message()).c_str());
- }
-#endif
- disable(ec);
- return;
- }
-
- m_version = version_natpmp;
- ec.clear();
- }
- }
-
m_disabled = false;
- udp::endpoint const nat_endpoint(route->gateway, 5351);
+ udp::endpoint const nat_endpoint(*route, 5351);
if (nat_endpoint == m_nat_endpoint) return;
m_nat_endpoint = nat_endpoint;
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
- log("found router at: %s"
+ log("found gateway at: %s"
, print_address(m_nat_endpoint.address()).c_str());
}
#endif
diff --git a/src/session_impl.cpp b/src/session_impl.cpp
index 8ae59af11..2d93853c7 100644
--- a/src/session_impl.cpp
+++ b/src/session_impl.cpp
@@ -5464,7 +5464,11 @@ namespace aux {
// the natpmp constructor may fail and call the callbacks
// into the session_impl.
s.natpmp_mapper = std::make_shared(m_io_service, *this);
- s.natpmp_mapper->start(s.local_endpoint.address(), s.device);
+ ip_interface ip;
+ ip.interface_address = s.local_endpoint.address();
+ ip.netmask = s.netmask;
+ std::strncpy(ip.name, s.device.c_str(), sizeof(ip.name));
+ s.natpmp_mapper->start(ip);
}
}
diff --git a/test/enum_if.cpp b/test/enum_if.cpp
index 4164ad866..1b3c530a8 100644
--- a/test/enum_if.cpp
+++ b/test/enum_if.cpp
@@ -42,15 +42,6 @@ int main()
io_service ios;
error_code ec;
- address def_gw = get_default_gateway(ios, "", false, ec);
- if (ec)
- {
- std::printf("%s\n", ec.message().c_str());
- return 1;
- }
-
- std::printf("Default gateway: %s\n", def_gw.to_string(ec).c_str());
-
std::printf("=========== Routes ===========\n");
auto const routes = enum_routes(ios, ec);
if (ec)