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)
pull/1282/head
Jason Rhinelander 4 years ago
parent 72bf215da4
commit bdc9c7bfa8

@ -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
$<TARGET_OBJECTS:tuntap>

@ -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);

@ -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)

@ -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;

@ -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());
}

@ -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())
{

@ -4,6 +4,7 @@
#include <dns/server.hpp>
#include <ev/ev.h>
#include <ev/vpnio.hpp>
#include <net/ip.hpp>
#include <net/ip_packet.hpp>
#include <net/net.hpp>
#include <service/endpoint.hpp>
@ -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;
}

@ -0,0 +1,28 @@
#include <net/ip.hpp>
#include <cstring>
namespace llarp::net {
huint128_t
In6ToHUInt(in6_addr addr)
{
uint8_t* ptr = reinterpret_cast<uint8_t*>(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

@ -0,0 +1,28 @@
#pragma once
#include <net/net_int.hpp>
#include <net/net.hpp>
#include <cstdint>
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

@ -1,4 +1,5 @@
#include <net/ip_packet.hpp>
#include <net/ip.hpp>
#include <util/buffer.hpp>
#include <util/endian.hpp>
@ -27,44 +28,6 @@ namespace llarp
return (uint32_t*)addr.s6_addr;
}
huint128_t
IPPacket::In6ToHUInt(in6_addr addr)
{
uint8_t* ptr = reinterpret_cast<uint8_t*>(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
{

@ -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;

@ -0,0 +1,76 @@
#include <net/ip_range.hpp>
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

@ -0,0 +1,61 @@
#pragma once
#include <ostream>
#include <net/ip.hpp>
#include <util/bits.hpp>
#include <util/types.hpp>
#include <string>
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

@ -1,7 +1,7 @@
#ifndef LLARP_NET_IP_RANGE_MAP_HPP
#define LLARP_NET_IP_RANGE_MAP_HPP
#include <net/ip.hpp>
#include <net/ip_range.hpp>
namespace llarp
{
@ -86,4 +86,4 @@ namespace llarp
} // namespace net
} // namespace llarp
#endif
#endif

@ -15,6 +15,7 @@
#endif
#include <net/ip.hpp>
#include <net/ip_range.hpp>
#include <util/logging/logger.hpp>
#include <util/str.hpp>
@ -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)
{

@ -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

@ -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());
}

@ -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);
}

@ -1,8 +1,8 @@
#include <gtest/gtest.h>
#include <net/net.hpp>
#include <net/net_int.hpp>
#include <net/ip.hpp>
#include <net/ip_range.hpp>
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)));
}

Loading…
Cancel
Save