Support SockAddr in from sockaddr and friends

pull/1257/head
Stephen Shelton 4 years ago
parent e944bcb28a
commit 78d09f2ae5
No known key found for this signature in database
GPG Key ID: EE4BADACCE8B631C

@ -2,6 +2,7 @@
#include <netinet/in.h>
#include <util/str.hpp>
#include <util/logging/logger.hpp>
#include <util/mem.hpp>
#include <charconv>
@ -18,6 +19,16 @@ namespace llarp
llarp::Zero(&m_addr, sizeof(m_addr));
}
void
SockAddr::applySIITBytes()
{
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
// SIIT == Stateless IP/ICMP Translation (represent IPv4 with IPv6)
ip6[10] = 0xff;
ip6[11] = 0xff;
}
SockAddr::SockAddr()
{
init();
@ -42,30 +53,76 @@ namespace llarp
fromString(addr);
}
SockAddr::SockAddr(const SockAddr&)
SockAddr::SockAddr(const SockAddr& other)
{
throw std::runtime_error("FIXME");
*this = other;
}
SockAddr&
SockAddr::operator=(const SockAddr&) const
SockAddr::operator=(const SockAddr& other)
{
throw std::runtime_error("FIXME");
*this = other.m_addr;
return *this;
}
SockAddr::SockAddr(const sockaddr& addr)
{
throw std::runtime_error("FIXME");
*this = addr;
}
SockAddr&
SockAddr::operator=(const sockaddr& other)
{
if (other.sa_family == AF_INET6)
*this = (const sockaddr_in6&)other;
else if (other.sa_family == AF_INET)
*this = (const sockaddr_in&)other;
else
throw std::invalid_argument("Invalid sockaddr (not AF_INET or AF_INET6)");
return *this;
}
SockAddr::SockAddr(const sockaddr_in& addr)
{
throw std::runtime_error("FIXME");
*this = addr;
}
SockAddr&
SockAddr::operator=(const sockaddr_in& other)
{
init();
applySIITBytes();
// avoid byte order conversion (this is NBO -> NBO)
memcpy(m_addr.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr));
m_addr.sin6_port = other.sin_port;
m_empty = false;
return *this;
}
SockAddr::SockAddr(const sockaddr_in6& addr)
{
*this = addr;
}
SockAddr&
SockAddr::operator=(const sockaddr_in6& other)
{
init();
memcpy(&m_addr, &other, sizeof(sockaddr_in6));
m_empty = false;
return *this;
}
SockAddr::operator const sockaddr*() const
{
throw std::runtime_error("FIXME");
return (sockaddr*)&m_addr;
}
void
@ -131,9 +188,6 @@ namespace llarp
if (isEmpty())
return "";
if (m_addr.sin6_family != AF_INET)
throw std::runtime_error("Only IPv4 supported");
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
// ensure SIIT
@ -168,14 +222,12 @@ namespace llarp
void
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
m_addr.sin6_family = AF_INET;
m_addr.sin6_family = AF_INET6;
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
// SIIT (represent IPv4 with IPv6)
ip6[10] = 0xff;
ip6[11] = 0xff;
applySIITBytes();
ip6[12] = a;
ip6[13] = b;

@ -18,10 +18,20 @@ namespace llarp
SockAddr(const SockAddr&);
SockAddr&
operator=(const SockAddr&) const;
operator=(const SockAddr&);
SockAddr(const sockaddr& addr);
SockAddr&
operator=(const sockaddr& addr);
SockAddr(const sockaddr_in& addr);
SockAddr&
operator=(const sockaddr_in& addr);
SockAddr(const sockaddr_in6& addr);
SockAddr&
operator=(const sockaddr_in6& addr);
operator const sockaddr*() const;
void
@ -52,6 +62,9 @@ namespace llarp
void
init();
void
applySIITBytes();
};
std::ostream&

@ -1,24 +1,11 @@
#include <util/mem.hpp>
#include <net/sock_addr.hpp>
#include <net/ip_address.hpp>
#include <net/net_if.hpp>
#include <util/logging/logger.hpp>
#include <catch2/catch.hpp>
TEST_CASE("SockAddr from sockaddr", "[SockAddr]")
{
sockaddr sa;
// check that this compiles (taking sockaddr by ref)
CHECK_NOTHROW(llarp::SockAddr(sa));
sockaddr* saptr = &sa;
// check that this compiles (taking sockaddr by ref from cast from ptr)
// this was giving odd compilation errors from within net/net.cpp
llarp::SockAddr addr(*saptr);
llarp::IpAddress ip(addr);
}
#include <arpa/inet.h>
TEST_CASE("SockAddr from IPv4", "[SockAddr]")
{
@ -79,3 +66,35 @@ TEST_CASE("SockAddr fromString", "[SockAddr]")
CHECK_THROWS_WITH(llarp::SockAddr("1.2.3.4:1a"), "1.2.3.4:1a contains junk after port");
}
TEST_CASE("SockAddr from sockaddr_in", "[SockAddr]")
{
sockaddr_in sin4;
llarp::Zero(&sin4, sizeof(sockaddr_in));
sin4.sin_family = AF_INET;
sin4.sin_addr.s_addr = inet_addr("127.0.0.1");
sin4.sin_port = htons(1234);
llarp::SockAddr addr(sin4);
CHECK(addr.toString() == "127.0.0.1:1234");
}
TEST_CASE("SockAddr from sockaddr_in6", "[SockAddr]")
{
sockaddr_in6 sin6;
llarp::Zero(&sin6, sizeof(sockaddr_in6));
sin6.sin6_family = AF_INET6;
inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6.sin6_addr);
sin6.sin6_port = htons(53);
llarp::SockAddr addr(sin6);
char buf[128];
inet_ntop(AF_INET6, &(sin6.sin6_addr), buf, INET6_ADDRSTRLEN);
llarp::LogWarn("Addr: ", buf);
CHECK(addr.toString() == "127.0.0.1:53");
}

Loading…
Cancel
Save