From bdc9c7bfa883137c2d949072a1ad991181061426 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Wed, 20 May 2020 16:14:05 -0300 Subject: [PATCH] Move IPRange out of net.hpp; free up TruncateV6 etc. - Move IPRange into its own net/ip_range.hpp - Move the static net::IPPacket::TruncateV6, etc. functions to free net::TruncateV6, etc. functions (now from net/ip.hpp instead of net/ip_packet.hpp). - Make net::TruncateV6 and net::ExpandV4 constexpr. - Add IPRange::FromIPv4 factory function (to replace the iprange_ipv4 free function) --- llarp/CMakeLists.txt | 3 ++ llarp/dns/message.cpp | 2 +- llarp/dns/name.cpp | 2 +- llarp/exit/endpoint.cpp | 6 +-- llarp/handlers/exit.cpp | 2 +- llarp/handlers/tun.cpp | 8 ++-- llarp/handlers/tun.hpp | 5 ++- llarp/net/ip.cpp | 28 ++++++++++++ llarp/net/ip.hpp | 28 ++++++++++++ llarp/net/ip_packet.cpp | 39 +---------------- llarp/net/ip_packet.hpp | 12 ------ llarp/net/ip_range.cpp | 76 +++++++++++++++++++++++++++++++++ llarp/net/ip_range.hpp | 61 ++++++++++++++++++++++++++ llarp/net/ip_range_map.hpp | 4 +- llarp/net/net.cpp | 75 ++------------------------------ llarp/net/net.hpp | 46 -------------------- llarp/net/net_int.cpp | 2 +- test/dns/test_llarp_dns_dns.cpp | 2 +- test/net/test_llarp_net.cpp | 12 +++--- 19 files changed, 223 insertions(+), 190 deletions(-) create mode 100644 llarp/net/ip.cpp create mode 100644 llarp/net/ip.hpp create mode 100644 llarp/net/ip_range.cpp create mode 100644 llarp/net/ip_range.hpp diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index 8fa0390f7..fdb201425 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -60,7 +60,10 @@ add_library(lokinet-platform ev/pipe.cpp ev/vpnio.cpp ev/ev_libuv.cpp + + net/ip.cpp net/ip_packet.cpp + net/ip_range.cpp net/net.cpp net/net_int.cpp $ diff --git a/llarp/dns/message.cpp b/llarp/dns/message.cpp index fd98db744..f91d559ca 100644 --- a/llarp/dns/message.cpp +++ b/llarp/dns/message.cpp @@ -158,7 +158,7 @@ namespace llarp } else { - const auto addr = net::IPPacket::TruncateV6(ip); + const auto addr = net::TruncateV6(ip); rec.rr_type = qTypeA; rec.rData.resize(4); htobe32buf(rec.rData.data(), addr.h); diff --git a/llarp/dns/name.cpp b/llarp/dns/name.cpp index d67ee99ee..3af1a961a 100644 --- a/llarp/dns/name.cpp +++ b/llarp/dns/name.cpp @@ -98,7 +98,7 @@ namespace llarp sub = sub.substr(pos + 1); pos = sub.find('.'); a = atoi(sub.substr(0, pos).c_str()); - ip = net::IPPacket::ExpandV4(llarp::ipaddr_ipv4_bits(a, b, c, d)); + ip = net::ExpandV4(llarp::ipaddr_ipv4_bits(a, b, c, d)); return true; } if (numdots == 32 && isV6) diff --git a/llarp/exit/endpoint.cpp b/llarp/exit/endpoint.cpp index 752985d24..3ff349fcb 100644 --- a/llarp/exit/endpoint.cpp +++ b/llarp/exit/endpoint.cpp @@ -129,10 +129,10 @@ namespace llarp { huint32_t dst; if (m_RewriteSource) - dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr()); + dst = net::TruncateV6(m_Parent->GetIfAddr()); else dst = pkt.dstv4(); - pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(m_IP)), xhtonl(dst)); + pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(m_IP)), xhtonl(dst)); } else { @@ -160,7 +160,7 @@ namespace llarp pkt.UpdateIPv6Address(src, m_IP); else pkt.UpdateIPv4Address( - xhtonl(net::IPPacket::TruncateV6(src)), xhtonl(net::IPPacket::TruncateV6(m_IP))); + xhtonl(net::TruncateV6(src)), xhtonl(net::TruncateV6(m_IP))); const auto _pktbuf = pkt.Buffer(); const llarp_buffer_t& pktbuf = _pktbuf.underlying; diff --git a/llarp/handlers/exit.cpp b/llarp/handlers/exit.cpp index d52c49dd6..19e6cb10d 100644 --- a/llarp/handlers/exit.cpp +++ b/llarp/handlers/exit.cpp @@ -487,7 +487,7 @@ namespace llarp pkt.UpdateIPv6Address(from, m_IfAddr); else pkt.UpdateIPv4Address( - xhtonl(net::IPPacket::TruncateV6(from)), xhtonl(net::IPPacket::TruncateV6(m_IfAddr))); + xhtonl(net::TruncateV6(from)), xhtonl(net::TruncateV6(m_IfAddr))); return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer()); } diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index d7dee142a..a473f00b3 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -236,7 +236,7 @@ namespace llarp huint128_t ipv6; if (ip.FromString(ip_str)) { - ipv6 = net::IPPacket::ExpandV4(ip); + ipv6 = net::ExpandV4(ip); } else if (ipv6.FromString(ip_str)) { @@ -767,7 +767,7 @@ namespace llarp } if (ip.FromString(ifaddr)) { - m_OurIP = net::IPPacket::ExpandV4(ip); + m_OurIP = net::ExpandV4(ip); m_OurRange.netmask_bits = netmask_ipv6_bits(netmask + 96); } else if (m_OurIP.FromString(ifaddr)) @@ -866,7 +866,7 @@ namespace llarp huint128_t dst; if (pkt.IsV4()) - dst = net::IPPacket::ExpandV4(pkt.dstv4()); + dst = net::ExpandV4(pkt.dstv4()); else dst = pkt.dstv6(); @@ -951,7 +951,7 @@ namespace llarp return false; } pkt.UpdateIPv4Address( - xhtonl(net::IPPacket::TruncateV6(themIP)), xhtonl(net::IPPacket::TruncateV6(usIP))); + xhtonl(net::TruncateV6(themIP)), xhtonl(net::TruncateV6(usIP))); } else if (pkt.IsV6()) { diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 36d7e1dc8..9a742da1a 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -242,7 +243,7 @@ namespace llarp { if (pkt.IsV4()) { - pkt.UpdateIPv6Address(net::IPPacket::ExpandV4(pkt.srcv4()), m_OurIP); + pkt.UpdateIPv6Address(net::ExpandV4(pkt.srcv4()), m_OurIP); } else { @@ -253,7 +254,7 @@ namespace llarp { if (pkt.IsV4()) pkt.UpdateIPv4Address( - xhtonl(pkt.srcv4()), xhtonl(net::IPPacket::TruncateV6(m_OurIP))); + xhtonl(pkt.srcv4()), xhtonl(net::TruncateV6(m_OurIP))); else return false; } diff --git a/llarp/net/ip.cpp b/llarp/net/ip.cpp new file mode 100644 index 000000000..76222c53c --- /dev/null +++ b/llarp/net/ip.cpp @@ -0,0 +1,28 @@ +#include +#include + +namespace llarp::net { + + huint128_t + In6ToHUInt(in6_addr addr) + { + uint8_t* ptr = reinterpret_cast(addr.s6_addr); + uint128_t x{0}; + for (int i = 0; i < 16; i++) + { + x <<= 8; + x |= ptr[i]; + } + return huint128_t{x}; + } + + in6_addr + HUIntToIn6(huint128_t x) + { + in6_addr addr; + auto i = ntoh128(x.h); + std::memcpy(&addr, &i, 16); + return addr; + } + +} // namespace llarp::net diff --git a/llarp/net/ip.hpp b/llarp/net/ip.hpp new file mode 100644 index 000000000..88f2f436e --- /dev/null +++ b/llarp/net/ip.hpp @@ -0,0 +1,28 @@ +#pragma once +#include +#include +#include + +namespace llarp::net +{ + huint128_t + In6ToHUInt(in6_addr addr); + + in6_addr + HUIntToIn6(huint128_t x); + + constexpr huint128_t + ExpandV4(huint32_t x) + { + return huint128_t{0xffff'0000'0000UL} | huint128_t{x.h}; + } + + constexpr huint32_t + TruncateV6(huint128_t x) + { + huint32_t ret = {0}; + ret.h = (uint32_t)(x.h & 0x0000'0000'ffff'ffffUL); + return ret; + } + +} // namespace llarp::net diff --git a/llarp/net/ip_packet.cpp b/llarp/net/ip_packet.cpp index fe92b026b..a66a22c1c 100644 --- a/llarp/net/ip_packet.cpp +++ b/llarp/net/ip_packet.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -27,44 +28,6 @@ namespace llarp return (uint32_t*)addr.s6_addr; } - huint128_t - IPPacket::In6ToHUInt(in6_addr addr) - { - uint8_t* ptr = reinterpret_cast(addr.s6_addr); - uint128_t x{0}; - for (int i = 0; i < 16; i++) - { - x <<= 8; - x |= ptr[i]; - } - return huint128_t{x}; - } - - in6_addr - IPPacket::HUIntToIn6(huint128_t x) - { - in6_addr addr; - auto i = ntoh128(x.h); - memcpy(&addr, &i, 16); - return addr; - } - - huint128_t - IPPacket::ExpandV4(huint32_t i) - { - huint128_t ff = {0xff}; - huint128_t expanded{i.h}; - return (ff << 40) | (ff << 32) | expanded; - } - - huint32_t - IPPacket::TruncateV6(huint128_t i) - { - huint32_t ret = {0}; - ret.h = (uint32_t)(i.h & (0x00000000ffffffffUL)); - return ret; - } - huint128_t IPPacket::srcv6() const { diff --git a/llarp/net/ip_packet.hpp b/llarp/net/ip_packet.hpp index 7e61aeae9..49cf6de02 100644 --- a/llarp/net/ip_packet.hpp +++ b/llarp/net/ip_packet.hpp @@ -98,18 +98,6 @@ namespace llarp /// an Packet struct IPPacket { - static huint128_t - In6ToHUInt(in6_addr addr); - - static in6_addr - HUIntToIn6(huint128_t x); - - static huint128_t - ExpandV4(huint32_t x); - - static huint32_t - TruncateV6(huint128_t x); - static constexpr size_t MaxSize = 1500; llarp_time_t timestamp; size_t sz; diff --git a/llarp/net/ip_range.cpp b/llarp/net/ip_range.cpp new file mode 100644 index 000000000..1d6bf5378 --- /dev/null +++ b/llarp/net/ip_range.cpp @@ -0,0 +1,76 @@ +#include + +namespace llarp +{ + + bool + IPRange::ContainsV4(const huint32_t& ip) const + { + return Contains(net::ExpandV4(ip)); + } + + bool + IPRange::FromString(std::string str) + { + const auto colinpos = str.find(":"); + const auto slashpos = str.find("/"); + std::string bitsstr; + if (slashpos != std::string::npos) + { + bitsstr = str.substr(slashpos + 1); + str = str.substr(0, slashpos); + } + if (colinpos == std::string::npos) + { + huint32_t ip; + if (!ip.FromString(str)) + return false; + addr = net::ExpandV4(ip); + if (!bitsstr.empty()) + { + auto bits = atoi(bitsstr.c_str()); + if (bits < 0 || bits > 32) + return false; + netmask_bits = netmask_ipv6_bits(96 + bits); + } + else + netmask_bits = netmask_ipv6_bits(128); + } + else + { + if (!addr.FromString(str)) + return false; + if (!bitsstr.empty()) + { + auto bits = atoi(bitsstr.c_str()); + if (bits < 0 || bits > 128) + return false; + netmask_bits = netmask_ipv6_bits(bits); + } + else + { + netmask_bits = netmask_ipv6_bits(128); + } + } + return true; + } + + std::string + IPRange::ToString() const + { + char buf[INET6_ADDRSTRLEN + 1] = {0}; + std::string str; + in6_addr inaddr = {}; + size_t numset = 0; + uint128_t bits = netmask_bits.h; + while (bits) + { + if (bits & 1) + numset++; + bits >>= 1; + } + str += inet_ntop(AF_INET6, &inaddr, buf, sizeof(buf)); + return str + "/" + std::to_string(numset); + } + +} // namespace llarp diff --git a/llarp/net/ip_range.hpp b/llarp/net/ip_range.hpp new file mode 100644 index 000000000..0524a3cd0 --- /dev/null +++ b/llarp/net/ip_range.hpp @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace llarp +{ + struct IPRange + { + using Addr_t = huint128_t; + huint128_t addr = {0}; + huint128_t netmask_bits = {0}; + + static constexpr IPRange + FromIPv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask) + { + return IPRange{net::ExpandV4(ipaddr_ipv4_bits(a, b, c, d)), + netmask_ipv6_bits(mask + 96)}; + } + + /// return true if ip is contained in this ip range + constexpr bool + Contains(const Addr_t& ip) const + { + return (addr & netmask_bits) == (ip & netmask_bits); + } + + bool + ContainsV4(const huint32_t& ip) const; + + friend std::ostream& + operator<<(std::ostream& out, const IPRange& a) + { + return out << a.ToString(); + } + + /// get the highest address on this range + huint128_t + HighestAddr() const + { + return (addr & netmask_bits) + (huint128_t{1} << (128 - bits::count_bits_128(netmask_bits.h))) + - huint128_t{1}; + } + + bool + operator<(const IPRange& other) const + { + return (this->addr & this->netmask_bits) < (other.addr & other.netmask_bits) + || this->netmask_bits < other.netmask_bits; + } + + std::string + ToString() const; + + bool + FromString(std::string str); + }; + +} // namespace llarp diff --git a/llarp/net/ip_range_map.hpp b/llarp/net/ip_range_map.hpp index 0a562911e..d1c3e6727 100644 --- a/llarp/net/ip_range_map.hpp +++ b/llarp/net/ip_range_map.hpp @@ -1,7 +1,7 @@ #ifndef LLARP_NET_IP_RANGE_MAP_HPP #define LLARP_NET_IP_RANGE_MAP_HPP -#include +#include namespace llarp { @@ -86,4 +86,4 @@ namespace llarp } // namespace net } // namespace llarp -#endif \ No newline at end of file +#endif diff --git a/llarp/net/net.cpp b/llarp/net/net.cpp index e5b4069b1..bf9d99ee9 100644 --- a/llarp/net/net.cpp +++ b/llarp/net/net.cpp @@ -15,6 +15,7 @@ #endif #include +#include #include #include @@ -464,8 +465,8 @@ namespace llarp if (addr->sin_addr.s_addr) // skip unconfig'd adapters (windows passes these through the unix-y // wrapper) - currentRanges.emplace_back(IPRange{net::IPPacket::ExpandV4(xntohl(ifaddr)), - net::IPPacket::ExpandV4(xntohl(ifmask))}); + currentRanges.emplace_back(IPRange{net::ExpandV4(xntohl(ifaddr)), + net::ExpandV4(xntohl(ifmask))}); } }); // try 10.x.0.0/16 @@ -602,76 +603,6 @@ namespace llarp return IsBogon(host); } - bool - IPRange::ContainsV4(const huint32_t& ip) const - { - return Contains(net::IPPacket::ExpandV4(ip)); - } - - bool - IPRange::FromString(std::string str) - { - const auto colinpos = str.find(":"); - const auto slashpos = str.find("/"); - std::string bitsstr; - if (slashpos != std::string::npos) - { - bitsstr = str.substr(slashpos + 1); - str = str.substr(0, slashpos); - } - if (colinpos == std::string::npos) - { - huint32_t ip; - if (!ip.FromString(str)) - return false; - addr = net::IPPacket::ExpandV4(ip); - if (!bitsstr.empty()) - { - auto bits = atoi(bitsstr.c_str()); - if (bits < 0 || bits > 32) - return false; - netmask_bits = netmask_ipv6_bits(96 + bits); - } - else - netmask_bits = netmask_ipv6_bits(128); - } - else - { - if (!addr.FromString(str)) - return false; - if (!bitsstr.empty()) - { - auto bits = atoi(bitsstr.c_str()); - if (bits < 0 || bits > 128) - return false; - netmask_bits = netmask_ipv6_bits(bits); - } - else - { - netmask_bits = netmask_ipv6_bits(128); - } - } - return true; - } - - std::string - IPRange::ToString() const - { - char buf[INET6_ADDRSTRLEN + 1] = {0}; - std::string str; - in6_addr inaddr = {}; - size_t numset = 0; - uint128_t bits = netmask_bits.h; - while (bits) - { - if (bits & 1) - numset++; - bits >>= 1; - } - str += inet_ntop(AF_INET6, &inaddr, buf, sizeof(buf)); - return str + "/" + std::to_string(numset); - } - IPRange iprange_ipv4(byte_t a, byte_t b, byte_t c, byte_t d, byte_t mask) { diff --git a/llarp/net/net.hpp b/llarp/net/net.hpp index c547644b9..b1b5ace7b 100644 --- a/llarp/net/net.hpp +++ b/llarp/net/net.hpp @@ -57,52 +57,6 @@ llarp_getPrivateIfs(); namespace llarp { - struct IPRange - { - using Addr_t = huint128_t; - huint128_t addr = {0}; - huint128_t netmask_bits = {0}; - - /// return true if ip is contained in this ip range - bool - Contains(const Addr_t& ip) const - { - return (addr & netmask_bits) == (ip & netmask_bits); - } - - bool - ContainsV4(const huint32_t& ip) const; - - friend std::ostream& - operator<<(std::ostream& out, const IPRange& a) - { - return out << a.ToString(); - } - - /// get the highest address on this range - huint128_t - HighestAddr() const - { - return (addr & netmask_bits) + (huint128_t{1} << (128 - bits::count_bits_128(netmask_bits.h))) - - huint128_t{1}; - } - - bool - operator<(const IPRange& other) const - { - return (this->addr & this->netmask_bits) < (other.addr & other.netmask_bits) - || this->netmask_bits < other.netmask_bits; - } - - std::string - ToString() const; - - bool - FromString(std::string str); - }; - - huint128_t - ExpandV4(huint32_t x); /// get a netmask with the higest numset bits set constexpr huint128_t diff --git a/llarp/net/net_int.cpp b/llarp/net/net_int.cpp index 91dfcd7e3..2de49fd5e 100644 --- a/llarp/net/net_int.cpp +++ b/llarp/net/net_int.cpp @@ -20,7 +20,7 @@ namespace llarp huint128_t::ToV6(V6Container& c) { c.resize(16); - const in6_addr addr = net::IPPacket::HUIntToIn6(*this); + const in6_addr addr = net::HUIntToIn6(*this); std::copy_n(addr.s6_addr, 16, c.begin()); } diff --git a/test/dns/test_llarp_dns_dns.cpp b/test/dns/test_llarp_dns_dns.cpp index 23d30fd4b..d18468215 100644 --- a/test/dns/test_llarp_dns_dns.cpp +++ b/test/dns/test_llarp_dns_dns.cpp @@ -52,7 +52,7 @@ TEST_F(DNSLibTest, TestPTR) { llarp::huint128_t ip = {0}; llarp::huint128_t expected = - llarp::net::IPPacket::ExpandV4(llarp::ipaddr_ipv4_bits(10, 10, 10, 1)); + llarp::net::ExpandV4(llarp::ipaddr_ipv4_bits(10, 10, 10, 1)); ASSERT_TRUE(llarp::dns::DecodePTR("1.10.10.10.in-addr.arpa.", ip)); ASSERT_EQ(ip, expected); } diff --git a/test/net/test_llarp_net.cpp b/test/net/test_llarp_net.cpp index 44472d60a..6b8c1102e 100644 --- a/test/net/test_llarp_net.cpp +++ b/test/net/test_llarp_net.cpp @@ -1,8 +1,8 @@ #include -#include #include #include +#include struct TestNet : public ::testing::Test { @@ -26,7 +26,7 @@ TEST_F(TestNet, TestIn6AddrToHUIntLoopback) llarp::huint128_t loopback = {0}; ASSERT_TRUE(loopback.FromString("::1")); in6_addr addr = IN6ADDR_LOOPBACK_INIT; - auto huint = llarp::net::IPPacket::In6ToHUInt(addr); + auto huint = llarp::net::In6ToHUInt(addr); ASSERT_EQ(huint, loopback); } @@ -35,7 +35,7 @@ TEST_F(TestNet, TestIn6AddrToHUInt) llarp::huint128_t huint_parsed = {0}; ASSERT_TRUE(huint_parsed.FromString("fd00::1")); in6_addr addr = { { { 0xfd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } }; - auto huint = llarp::net::IPPacket::In6ToHUInt(addr); + auto huint = llarp::net::In6ToHUInt(addr); ASSERT_EQ(huint, huint_parsed); huint_parsed.h ++; ASSERT_NE(huint, huint_parsed); @@ -44,19 +44,19 @@ TEST_F(TestNet, TestIn6AddrToHUInt) TEST_F(TestNet, TestRangeContains8) { - ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 1, 8) + ASSERT_TRUE(llarp::IPRange::FromIPv4(10, 0, 0, 1, 8) .ContainsV4(llarp::ipaddr_ipv4_bits(10, 40, 11, 6))); } TEST_F(TestNet, TestRangeContains24) { - ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24) + ASSERT_TRUE(llarp::IPRange::FromIPv4(10, 200, 0, 1, 24) .ContainsV4(llarp::ipaddr_ipv4_bits(10, 200, 0, 253))); } TEST_F(TestNet, TestRangeContainsFail) { - ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24) + ASSERT_TRUE(!llarp::IPRange::FromIPv4(192, 168, 0, 1, 24) .ContainsV4(llarp::ipaddr_ipv4_bits(10, 200, 0, 253))); }