SockAddr endian cleanups & add uint128 ctors

- Make SockAddr endian arguments explicit
- Consolidate port-less contructors and port constructors into one with
  a default port of 0.
- Add {h,n}uint128_t ctors for construction from IPv6 addrs
pull/1573/head
Jason Rhinelander 3 years ago
parent fe0d099e86
commit d1dadb530c

@ -61,8 +61,8 @@ namespace llarp
hdr->ttl = 64;
hdr->frag_off = htons(0b0100000000000000);
hdr->saddr = from.getIPv4();
hdr->daddr = to.getIPv4();
hdr->saddr = from.getIPv4().n;
hdr->daddr = to.getIPv4().n;
// make udp packet
uint8_t* ptr = pkt.buf + 20;
@ -98,8 +98,8 @@ namespace llarp
const uint8_t* ptr = pkt.buf + ip_header_size;
const auto dst = ToNet(pkt.dstv4());
const auto src = ToNet(pkt.srcv4());
const SockAddr laddr{src.n, *reinterpret_cast<const uint16_t*>(ptr)};
const SockAddr raddr{dst.n, *reinterpret_cast<const uint16_t*>(ptr + 2)};
const SockAddr laddr{src, nuint16_t{*reinterpret_cast<const uint16_t*>(ptr)}};
const SockAddr raddr{dst, nuint16_t{*reinterpret_cast<const uint16_t*>(ptr + 2)}};
OwnedBuffer buf{pkt.sz - (udp_header_size + ip_header_size)};
std::copy_n(ptr + udp_header_size, buf.sz, buf.buf.get());

@ -4,27 +4,42 @@
namespace llarp
{
template <>
huint16_t
ToHost(nuint16_t n)
{
return xntohs(n);
}
huint32_t
ToHost(nuint32_t n)
{
return xntohl(n);
}
template <>
huint128_t
ToHost(nuint128_t n)
{
return {ntoh128(n.n)};
}
nuint16_t
ToNet(huint16_t h)
{
return xhtons(h);
}
template <>
nuint32_t
ToNet(huint32_t h)
{
return xhtonl(h);
}
nuint128_t
ToNet(huint128_t h)
{
return {hton128(h.h)};
}
template <>
void
huint32_t::ToV6(V6Container& c)

@ -220,14 +220,13 @@ namespace llarp
return huint16_t{ntohs(x.n)};
}
template <typename UInt_t>
huint_t<UInt_t>
ToHost(nuint_t<UInt_t> h);
template <typename UInt_t>
nuint_t<UInt_t>
ToNet(huint_t<UInt_t> h);
huint16_t ToHost(nuint16_t);
huint32_t ToHost(nuint32_t);
huint128_t ToHost(nuint128_t);
nuint16_t ToNet(huint16_t);
nuint32_t ToNet(huint32_t);
nuint128_t ToNet(huint128_t);
} // namespace llarp
namespace std

@ -39,23 +39,32 @@ namespace llarp
init();
}
SockAddr::SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
SockAddr::SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, huint16_t port)
{
init();
setIPv4(a, b, c, d);
setPort(port);
}
SockAddr::SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port)
: SockAddr{a, b, c, d}
SockAddr::SockAddr(nuint32_t ip, nuint16_t port)
{
init();
setIPv4(ip);
setPort(port);
}
SockAddr::SockAddr(uint32_t ip, uint16_t port)
SockAddr::SockAddr(huint128_t ip, huint16_t port)
{
init();
setIPv4(ip);
setPort(ntohs(port));
setIPv6(ip);
setPort(port);
}
SockAddr::SockAddr(nuint128_t ip, nuint16_t port)
{
init();
setIPv6(ip);
setPort(port);
}
SockAddr::SockAddr(std::string_view addr)
@ -66,13 +75,13 @@ namespace llarp
SockAddr::SockAddr(std::string_view addr, uint16_t port)
{
init();
setPort(port);
setPort(huint16_t{port});
fromString(addr, false);
}
SockAddr::SockAddr(const AddressInfo& info) : SockAddr{info.ip}
{
setPort(info.port);
setPort(huint16_t{info.port});
}
SockAddr::SockAddr(const SockAddr& other)
@ -138,12 +147,14 @@ namespace llarp
memcpy(&m_addr, &other, sizeof(sockaddr_in6));
if (ipv6_is_mapped_ipv4(other.sin6_addr))
{
setIPv4(
other.sin6_addr.s6_addr[12],
other.sin6_addr.s6_addr[13],
other.sin6_addr.s6_addr[14],
other.sin6_addr.s6_addr[15]);
setPort(ntohs(other.sin6_port));
m_addr4.sin_port = m_addr.sin6_port;
}
m_empty = false;
return *this;
@ -161,7 +172,10 @@ namespace llarp
memcpy(&m_addr.sin6_addr.s6_addr, &other.s6_addr, sizeof(m_addr.sin6_addr.s6_addr));
if (ipv6_is_mapped_ipv4(other))
{
setIPv4(other.s6_addr[12], other.s6_addr[13], other.s6_addr[14], other.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port;
}
m_empty = false;
return *this;
@ -302,14 +316,14 @@ namespace llarp
return m_empty;
}
uint32_t
nuint32_t
SockAddr::getIPv4() const
{
return m_addr4.sin_addr.s_addr;
return {m_addr4.sin_addr.s_addr};
}
void
SockAddr::setIPv4(uint32_t ip)
SockAddr::setIPv4(nuint32_t ip)
{
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
@ -317,10 +331,16 @@ namespace llarp
applyIPv4MapBytes();
std::memcpy(ip6 + 12, &ip, 4);
m_addr4.sin_addr.s_addr = ip;
m_addr4.sin_addr.s_addr = ip.n;
m_empty = false;
}
void
SockAddr::setIPv4(huint32_t ip)
{
setIPv4(ToNet(ip));
}
void
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
@ -339,10 +359,37 @@ namespace llarp
}
void
SockAddr::setPort(uint16_t port)
SockAddr::setIPv6(huint128_t ip)
{
return setIPv6(ToNet(ip));
}
void
SockAddr::setIPv6(nuint128_t ip)
{
std::memcpy(&m_addr.sin6_addr, &ip, sizeof(m_addr.sin6_addr));
if (ipv6_is_mapped_ipv4(m_addr.sin6_addr))
{
setIPv4(
m_addr.sin6_addr.s6_addr[12],
m_addr.sin6_addr.s6_addr[13],
m_addr.sin6_addr.s6_addr[14],
m_addr.sin6_addr.s6_addr[15]);
m_addr4.sin_port = m_addr.sin6_port;
}
}
void
SockAddr::setPort(nuint16_t port)
{
m_addr.sin6_port = port.n;
m_addr4.sin_port = port.n;
}
void
SockAddr::setPort(huint16_t port)
{
m_addr.sin6_port = htons(port);
m_addr4.sin_port = htons(port);
setPort(ToNet(port));
}
uint16_t

@ -27,11 +27,20 @@ namespace llarp
struct SockAddr
{
SockAddr();
SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port);
// IPv4 constructors:
SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, huint16_t port = {0});
SockAddr(nuint32_t ip, nuint16_t port);
SockAddr(huint32_t ip, huint16_t port);
// IPv6 (or IPv4 if given a special IPv4-mapped IPv6 addr) in host order (including port).
SockAddr(huint128_t ip, huint16_t port = {0});
// IPv6 (or IPv4 if given a special IPv4-mapped IPv6 addr) in network order. NB: port is also
// in network order!
SockAddr(nuint128_t ip, nuint16_t port = {0});
// String ctors
SockAddr(std::string_view addr);
SockAddr(std::string_view addr, uint16_t port);
SockAddr(uint32_t ip, uint16_t port);
SockAddr(std::string_view addr, uint16_t port); // port is in native (host) order
SockAddr(const AddressInfo&);
@ -81,23 +90,44 @@ namespace llarp
void
setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
/// port is in host order
void
setIPv4(uint32_t ip);
setIPv4(nuint32_t ip);
void
setPort(uint16_t port);
setIPv4(huint32_t ip);
/// port is in host order
void
setIPv6(huint128_t ip);
void
setIPv6(nuint128_t ip);
void
setPort(huint16_t port);
void
setPort(nuint16_t port);
// Port is a native (host) value
void
setPort(uint16_t port)
{
setPort(huint16_t{port});
}
/// port is always returned in native (host) order
uint16_t
getPort() const;
huint128_t
asIPv6() const;
/// in network order
uint32_t
nuint128_t
getIPv6() const;
nuint32_t
getIPv4() const;
/// in host order
huint128_t
asIPv6() const;
huint32_t
asIPv4() const;

@ -2,6 +2,7 @@
#include <net/ip.hpp>
#include <net/ip_range.hpp>
#include <net/net.hpp>
#include <oxenmq/hex.h>
#include <catch2/catch.hpp>
@ -102,3 +103,30 @@ TEST_CASE("Bogon")
REQUIRE_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(79, 12, 3, 4)));
}
}
TEST_CASE("uint128_t")
{
SECTION("layout")
{
llarp::uint128_t i{0x0011223f44556677ULL, 0x8899aabbc3ddeeffULL};
REQUIRE(oxenmq::to_hex(std::string_view{reinterpret_cast<const char*>(&i), sizeof(i)}) ==
#ifdef __BIG_ENDIAN__
"0011223f445566778899aabbc3ddeeff"
#else
"ffeeddc3bbaa9988776655443f221100"
#endif
);
}
SECTION("ntoh")
{
llarp::uint128_t i{0x0011223f44556677ULL, 0x8899aabbc3ddeeffULL};
auto be = ntoh128(i);
REQUIRE(be == llarp::uint128_t{0xffeeddc3bbaa9988ULL, 0x776655443f221100ULL});
}
SECTION("hton")
{
llarp::uint128_t i{0x0011223f44556677ULL, 0x8899aabbc3ddeeffULL};
auto be = ntoh128(i);
REQUIRE(be == llarp::uint128_t{0xffeeddc3bbaa9988ULL, 0x776655443f221100ULL});
}
}

Loading…
Cancel
Save