forked from premiere/premiere-libtorrent
apparently on VPNs it's common for the gateway for a route to be outside of the netmask of the network it's a router for. fix that in get_gateway
This commit is contained in:
parent
6d5bdbdb1a
commit
0a4a06ce74
|
@ -801,7 +801,7 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl
|
|||
// IPv6 gateways aren't addressed in the same network as the
|
||||
// interface, but they are addressed by the local network address
|
||||
// space. So this check only works for IPv4.
|
||||
&& (!v4 || match_addr_mask(r.gateway, iface.interface_address, iface.netmask))
|
||||
&& (!v4 || match_addr_mask(r.gateway, iface.interface_address, r.netmask))
|
||||
// in case there are multiple networks on the same networking
|
||||
// device, the source hint may be the only thing telling them
|
||||
// apart
|
||||
|
|
|
@ -180,21 +180,22 @@ TORRENT_TEST(build_netmask_unknown)
|
|||
}
|
||||
|
||||
namespace {
|
||||
ip_route rt(char const* ip, char const* device, char const* gateway)
|
||||
ip_route rt(char const* ip, char const* device, char const* gateway, char const* mask)
|
||||
{
|
||||
ip_route ret;
|
||||
ret.destination = address::from_string(ip);
|
||||
ret.gateway = address::from_string(gateway);
|
||||
ret.netmask = address::from_string(mask);
|
||||
std::strncpy(ret.name, device, sizeof(ret.name));
|
||||
ret.name[sizeof(ret.name) - 1] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
ip_interface ip(char const* addr, char const* mask, char const* name)
|
||||
ip_interface ip(char const* addr, char const* name)
|
||||
{
|
||||
ip_interface ret;
|
||||
ret.interface_address = address::from_string(addr);
|
||||
ret.netmask = address::from_string(mask);
|
||||
ret.netmask = address::from_string("255.255.255.255");
|
||||
std::strncpy(ret.name, name, sizeof(ret.name));
|
||||
return ret;
|
||||
}
|
||||
|
@ -203,70 +204,81 @@ namespace {
|
|||
TORRENT_TEST(get_gateway_basic)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1"),
|
||||
rt("::", "eth0", "2a02::1234")
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1", "255.255.255.0"),
|
||||
rt("::", "eth0", "2a02::1234", "ffff::")
|
||||
};
|
||||
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "255.255.0.0", "eth0"), routes) == address::from_string("192.168.0.1"));
|
||||
TEST_CHECK(get_gateway(ip("2a02::4567", "ffff::", "eth0"), routes) == address::from_string("2a02::1234"));
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "eth0"), routes) == address::from_string("192.168.0.1"));
|
||||
TEST_CHECK(get_gateway(ip("2a02::4567", "eth0"), routes) == address::from_string("2a02::1234"));
|
||||
|
||||
// the device name does not match the route
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "255.255.0.0", "eth1"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("2a02::4567", "ffff::", "eth1"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "eth1"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("2a02::4567", "eth1"), routes) == none);
|
||||
|
||||
// the gateway for the route is outside of this local network, it cannot be
|
||||
// used for this network
|
||||
TEST_CHECK(get_gateway(ip("192.168.1.130", "255.255.255.0", "eth0"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("192.168.1.130", "eth0"), routes) == none);
|
||||
|
||||
// for IPv6, the address family and device name matches, so it's a match
|
||||
TEST_CHECK(get_gateway(ip("2a02:8000::0123:4567", "ffff:ffff::", "eth0"), routes) == address::from_string("2a02::1234"));
|
||||
TEST_CHECK(get_gateway(ip("2a02:8000::0123:4567", "eth0"), routes) == address::from_string("2a02::1234"));
|
||||
}
|
||||
|
||||
TORRENT_TEST(get_gateway_no_default_route)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("192.168.0.0", "eth0", "0.0.0.0"),
|
||||
rt("2a02::", "eth0", "::")
|
||||
rt("192.168.0.0", "eth0", "0.0.0.0", "0.0.0.0"),
|
||||
rt("2a02::", "eth0", "::", "ffff::")
|
||||
};
|
||||
|
||||
// no default route
|
||||
TEST_CHECK(get_gateway(ip("192.168.1.130", "255.255.0.0", "eth0"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("2a02::1234", "ffff::", "eth0"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("192.168.1.130", "eth0"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("2a02::1234", "eth0"), routes) == none);
|
||||
}
|
||||
|
||||
TORRENT_TEST(get_gateway_local_v6)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("2a02::", "eth0", "::")
|
||||
rt("2a02::", "eth0", "::", "ffff::")
|
||||
};
|
||||
|
||||
// local IPv6 addresses never have a gateway
|
||||
TEST_CHECK(get_gateway(ip("fe80::1234", "ffff::", "eth0"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("fe80::1234", "eth0"), routes) == none);
|
||||
}
|
||||
|
||||
// an odd, imaginary setup, where the loopback network has a gateway
|
||||
TORRENT_TEST(get_gateway_loopback)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1"),
|
||||
rt("0.0.0.0", "lo", "127.1.1.1"),
|
||||
rt("::", "eth0", "fec0::1234"),
|
||||
rt("::", "lo", "::2")
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1", "255.255.0.0"),
|
||||
rt("0.0.0.0", "lo", "127.1.1.1", "255.0.0.0"),
|
||||
rt("::", "eth0", "fec0::1234", "ffff::"),
|
||||
rt("::", "lo", "::2", "ffff:ffff:ffff:ffff::")
|
||||
};
|
||||
|
||||
TEST_CHECK(get_gateway(ip("127.0.0.1", "255.0.0.0", "lo"), routes) == address::from_string("127.1.1.1"));
|
||||
TEST_CHECK(get_gateway(ip("127.0.0.1", "lo"), routes) == address::from_string("127.1.1.1"));
|
||||
|
||||
// with IPv6, there are no gateways for local or loopback addresses
|
||||
TEST_CHECK(get_gateway(ip("::1", "ffff:ffff:ffff:ffff::", "lo"), routes) == none);
|
||||
TEST_CHECK(get_gateway(ip("::1", "lo"), routes) == none);
|
||||
}
|
||||
|
||||
TORRENT_TEST(get_gateway_netmask)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("0.0.0.0", "eth0", "192.168.1.1", "255.255.255.0"),
|
||||
rt("0.0.0.0", "eth0", "192.168.2.1", "0.0.0.0")
|
||||
};
|
||||
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "eth0"), routes) == address::from_string("192.168.2.1"));
|
||||
TEST_CHECK(get_gateway(ip("192.168.1.130", "eth0"), routes) == address::from_string("192.168.1.1"));
|
||||
}
|
||||
|
||||
TORRENT_TEST(get_gateway_multi_homed)
|
||||
{
|
||||
std::vector<ip_route> const routes = {
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1"),
|
||||
rt("0.0.0.0", "eth0", "10.0.0.1")
|
||||
rt("0.0.0.0", "eth0", "192.168.0.1", "255.255.0.0"),
|
||||
rt("0.0.0.0", "eth0", "10.0.0.1", "255.0.0.0")
|
||||
};
|
||||
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "255.255.0.0", "eth0"), routes) == address::from_string("192.168.0.1"));
|
||||
TEST_CHECK(get_gateway(ip("10.0.1.130", "255.0.0.0", "eth0"), routes) == address::from_string("10.0.0.1"));
|
||||
TEST_CHECK(get_gateway(ip("192.168.0.130", "eth0"), routes) == address::from_string("192.168.0.1"));
|
||||
TEST_CHECK(get_gateway(ip("10.0.1.130", "eth0"), routes) == address::from_string("10.0.0.1"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue