fix build_netmask to treat the count as a prefix and add tests
This commit is contained in:
parent
af3d084092
commit
96695fa714
|
@ -74,6 +74,15 @@ namespace libtorrent {
|
|||
// internal
|
||||
inline address_v6 make_address_v6(string_view str, boost::system::error_code& ec)
|
||||
{ return address_v6::from_string(str.data(), ec); }
|
||||
// internal
|
||||
inline address make_address(string_view str)
|
||||
{ return address::from_string(str.data()); }
|
||||
// internal
|
||||
inline address_v4 make_address_v4(string_view str)
|
||||
{ return address_v4::from_string(str.data()); }
|
||||
// internal
|
||||
inline address_v6 make_address_v6(string_view str)
|
||||
{ return address_v6::from_string(str.data()); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ namespace libtorrent {
|
|||
TORRENT_EXTRA_EXPORT bool match_addr_mask(address const& a1
|
||||
, address const& a2, address const& mask);
|
||||
|
||||
// return a netmask with the specified address family and the specified
|
||||
// number of prefix bit set, of the most significant bits in the resulting
|
||||
// netmask
|
||||
TORRENT_EXTRA_EXPORT address build_netmask(int bits, int family);
|
||||
|
||||
// returns true if the specified address is on the same
|
||||
// local network as us
|
||||
TORRENT_EXTRA_EXPORT bool in_local_network(io_service& ios, address const& addr
|
||||
|
|
112
src/enum_net.cpp
112
src/enum_net.cpp
|
@ -165,48 +165,6 @@ namespace {
|
|||
);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_GETIPFORWARDTABLE || TORRENT_USE_NETLINK
|
||||
address build_netmask(int bits, int const family)
|
||||
{
|
||||
if (family == AF_INET)
|
||||
{
|
||||
address_v4::bytes_type b;
|
||||
b.fill(0xff);
|
||||
for (int i = int(b.size()) - 1; i >= 0; --i)
|
||||
{
|
||||
if (bits < 8)
|
||||
{
|
||||
b[std::size_t(i)] <<= bits;
|
||||
break;
|
||||
}
|
||||
b[std::size_t(i)] = 0;
|
||||
bits -= 8;
|
||||
}
|
||||
return address_v4(b);
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
address_v6::bytes_type b;
|
||||
b.fill(0xff);
|
||||
for (int i = int(b.size()) - 1; i >= 0; --i)
|
||||
{
|
||||
if (bits < 8)
|
||||
{
|
||||
b[std::size_t(i)] <<= bits;
|
||||
break;
|
||||
}
|
||||
b[std::size_t(i)] = 0;
|
||||
bits -= 8;
|
||||
}
|
||||
return address_v6(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return address();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TORRENT_USE_NETLINK
|
||||
|
||||
int read_nl_sock(int sock, span<char> buf, std::uint32_t const seq, std::uint32_t const pid)
|
||||
|
@ -353,36 +311,7 @@ namespace {
|
|||
return false;
|
||||
|
||||
ip_info->preferred = (addr_msg->ifa_flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0;
|
||||
|
||||
if (addr_msg->ifa_family == AF_INET6)
|
||||
{
|
||||
TORRENT_ASSERT(addr_msg->ifa_prefixlen <= 128);
|
||||
if (addr_msg->ifa_prefixlen > 0)
|
||||
{
|
||||
address_v6::bytes_type mask = {};
|
||||
auto it = mask.begin();
|
||||
if (addr_msg->ifa_prefixlen > 64)
|
||||
{
|
||||
detail::write_uint64(0xffffffffffffffffULL, it);
|
||||
addr_msg->ifa_prefixlen -= 64;
|
||||
}
|
||||
if (addr_msg->ifa_prefixlen > 0)
|
||||
{
|
||||
std::uint64_t const m = ~((1ULL << (64 - addr_msg->ifa_prefixlen)) - 1);
|
||||
detail::write_uint64(m, it);
|
||||
}
|
||||
ip_info->netmask = address_v6(mask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TORRENT_ASSERT(addr_msg->ifa_prefixlen <= 32);
|
||||
if (addr_msg->ifa_prefixlen != 0)
|
||||
{
|
||||
std::uint32_t const m = ~((1U << (32 - addr_msg->ifa_prefixlen)) - 1);
|
||||
ip_info->netmask = address_v4(m);
|
||||
}
|
||||
}
|
||||
ip_info->netmask = build_netmask(addr_msg->ifa_prefixlen, addr_msg->ifa_family);
|
||||
|
||||
ip_info->interface_address = address();
|
||||
int rt_len = int(IFA_PAYLOAD(nl_hdr));
|
||||
|
@ -492,8 +421,47 @@ int _System __libsocket_sysctl(int* mib, u_int namelen, void *oldp, size_t *oldl
|
|||
}
|
||||
#endif
|
||||
|
||||
void build_netmask_impl(span<unsigned char> mask, int prefix_bits)
|
||||
{
|
||||
TORRENT_ASSERT(prefix_bits <= mask.size() * 8);
|
||||
int i = 0;
|
||||
while (prefix_bits >= 8)
|
||||
{
|
||||
mask[i] = 0xff;
|
||||
prefix_bits -= 8;
|
||||
++i;
|
||||
}
|
||||
if (i < mask.size())
|
||||
{
|
||||
mask[i] = (0xff << (8 - prefix_bits)) & 0xff;
|
||||
++i;
|
||||
while (i < mask.size())
|
||||
{
|
||||
mask[i] = 0;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // <anonymous>
|
||||
|
||||
address build_netmask(int prefix_bits, int const family)
|
||||
{
|
||||
if (family == AF_INET)
|
||||
{
|
||||
address_v4::bytes_type b;
|
||||
build_netmask_impl(b, prefix_bits);
|
||||
return address_v4(b);
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
address_v6::bytes_type b;
|
||||
build_netmask_impl(b, prefix_bits);
|
||||
return address_v6(b);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
// return (a1 & mask) == (a2 & mask)
|
||||
bool match_addr_mask(address const& a1, address const& a2, address const& mask)
|
||||
{
|
||||
|
|
|
@ -104,3 +104,63 @@ TORRENT_TEST(is_ip_address)
|
|||
TEST_EQUAL(is_ip_address("::1"), true);
|
||||
TEST_EQUAL(is_ip_address("2001:db8:85a3:0:0:8a2e:370:7334"), true);
|
||||
}
|
||||
|
||||
TORRENT_TEST(build_netmask_v4)
|
||||
{
|
||||
TEST_CHECK(build_netmask(0, AF_INET) == make_address("0.0.0.0"));
|
||||
TEST_CHECK(build_netmask(1, AF_INET) == make_address("128.0.0.0"));
|
||||
TEST_CHECK(build_netmask(2, AF_INET) == make_address("192.0.0.0"));
|
||||
TEST_CHECK(build_netmask(3, AF_INET) == make_address("224.0.0.0"));
|
||||
TEST_CHECK(build_netmask(4, AF_INET) == make_address("240.0.0.0"));
|
||||
TEST_CHECK(build_netmask(5, AF_INET) == make_address("248.0.0.0"));
|
||||
TEST_CHECK(build_netmask(6, AF_INET) == make_address("252.0.0.0"));
|
||||
TEST_CHECK(build_netmask(7, AF_INET) == make_address("254.0.0.0"));
|
||||
TEST_CHECK(build_netmask(8, AF_INET) == make_address("255.0.0.0"));
|
||||
TEST_CHECK(build_netmask(9, AF_INET) == make_address("255.128.0.0"));
|
||||
TEST_CHECK(build_netmask(10, AF_INET) == make_address("255.192.0.0"));
|
||||
TEST_CHECK(build_netmask(11, AF_INET) == make_address("255.224.0.0"));
|
||||
|
||||
TEST_CHECK(build_netmask(22, AF_INET) == make_address("255.255.252.0"));
|
||||
TEST_CHECK(build_netmask(23, AF_INET) == make_address("255.255.254.0"));
|
||||
TEST_CHECK(build_netmask(24, AF_INET) == make_address("255.255.255.0"));
|
||||
TEST_CHECK(build_netmask(25, AF_INET) == make_address("255.255.255.128"));
|
||||
TEST_CHECK(build_netmask(26, AF_INET) == make_address("255.255.255.192"));
|
||||
TEST_CHECK(build_netmask(27, AF_INET) == make_address("255.255.255.224"));
|
||||
TEST_CHECK(build_netmask(28, AF_INET) == make_address("255.255.255.240"));
|
||||
TEST_CHECK(build_netmask(29, AF_INET) == make_address("255.255.255.248"));
|
||||
TEST_CHECK(build_netmask(30, AF_INET) == make_address("255.255.255.252"));
|
||||
TEST_CHECK(build_netmask(31, AF_INET) == make_address("255.255.255.254"));
|
||||
TEST_CHECK(build_netmask(32, AF_INET) == make_address("255.255.255.255"));
|
||||
}
|
||||
|
||||
TORRENT_TEST(build_netmask_v6)
|
||||
{
|
||||
TEST_CHECK(build_netmask(0, AF_INET6) == make_address("::"));
|
||||
TEST_CHECK(build_netmask(1, AF_INET6) == make_address("8000::"));
|
||||
TEST_CHECK(build_netmask(2, AF_INET6) == make_address("c000::"));
|
||||
TEST_CHECK(build_netmask(3, AF_INET6) == make_address("e000::"));
|
||||
TEST_CHECK(build_netmask(4, AF_INET6) == make_address("f000::"));
|
||||
TEST_CHECK(build_netmask(5, AF_INET6) == make_address("f800::"));
|
||||
TEST_CHECK(build_netmask(6, AF_INET6) == make_address("fc00::"));
|
||||
TEST_CHECK(build_netmask(7, AF_INET6) == make_address("fe00::"));
|
||||
TEST_CHECK(build_netmask(8, AF_INET6) == make_address("ff00::"));
|
||||
TEST_CHECK(build_netmask(9, AF_INET6) == make_address("ff80::"));
|
||||
TEST_CHECK(build_netmask(10, AF_INET6) == make_address("ffc0::"));
|
||||
TEST_CHECK(build_netmask(11, AF_INET6) == make_address("ffe0::"));
|
||||
|
||||
TEST_CHECK(build_netmask(119, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00"));
|
||||
TEST_CHECK(build_netmask(120, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
|
||||
TEST_CHECK(build_netmask(121, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80"));
|
||||
TEST_CHECK(build_netmask(122, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0"));
|
||||
TEST_CHECK(build_netmask(123, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0"));
|
||||
TEST_CHECK(build_netmask(124, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0"));
|
||||
TEST_CHECK(build_netmask(125, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8"));
|
||||
TEST_CHECK(build_netmask(126, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc"));
|
||||
TEST_CHECK(build_netmask(127, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"));
|
||||
TEST_CHECK(build_netmask(128, AF_INET6) == make_address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
|
||||
}
|
||||
|
||||
TORRENT_TEST(build_netmask_unknown)
|
||||
{
|
||||
TEST_CHECK(build_netmask(0, -1) == address{});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue