2021-03-09 22:24:35 +00:00
|
|
|
#include "sock_addr.hpp"
|
|
|
|
#include "address_info.hpp"
|
|
|
|
#include "ip.hpp"
|
|
|
|
#include "net_bits.hpp"
|
|
|
|
#include <llarp/util/str.hpp>
|
|
|
|
#include <llarp/util/logging/logger.hpp>
|
|
|
|
#include <llarp/util/mem.hpp>
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
#include <charconv>
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2021-02-22 15:01:05 +00:00
|
|
|
bool
|
|
|
|
operator==(const in6_addr& lh, const in6_addr& rh)
|
|
|
|
{
|
|
|
|
return memcmp(&lh, &rh, sizeof(in6_addr)) == 0;
|
|
|
|
}
|
2020-05-08 17:23:21 +00:00
|
|
|
/// shared utility functions
|
|
|
|
///
|
|
|
|
|
|
|
|
void
|
|
|
|
SockAddr::init()
|
|
|
|
{
|
|
|
|
llarp::Zero(&m_addr, sizeof(m_addr));
|
2021-03-03 04:34:16 +00:00
|
|
|
m_addr.sin6_family = AF_INET6;
|
2020-10-27 21:34:09 +00:00
|
|
|
llarp::Zero(&m_addr4, sizeof(m_addr4));
|
2021-03-03 04:34:16 +00:00
|
|
|
m_addr4.sin_family = AF_INET;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 22:52:00 +00:00
|
|
|
void
|
2021-02-24 23:34:42 +00:00
|
|
|
SockAddr::applyIPv4MapBytes()
|
2020-05-08 22:52:00 +00:00
|
|
|
{
|
2021-02-24 23:34:42 +00:00
|
|
|
std::memcpy(m_addr.sin6_addr.s6_addr, ipv4_map_prefix.data(), ipv4_map_prefix.size());
|
2020-05-08 22:52:00 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 17:23:21 +00:00
|
|
|
SockAddr::SockAddr()
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
2021-03-09 16:02:41 +00:00
|
|
|
SockAddr::SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, huint16_t port)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
|
|
|
init();
|
|
|
|
setIPv4(a, b, c, d);
|
2021-03-09 16:02:41 +00:00
|
|
|
setPort(port);
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-09 16:02:41 +00:00
|
|
|
SockAddr::SockAddr(nuint32_t ip, nuint16_t port)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
2021-03-09 16:02:41 +00:00
|
|
|
init();
|
|
|
|
setIPv4(ip);
|
2020-05-08 17:23:21 +00:00
|
|
|
setPort(port);
|
|
|
|
}
|
2021-03-02 18:18:22 +00:00
|
|
|
|
2021-04-19 15:20:46 +00:00
|
|
|
SockAddr::SockAddr(huint32_t ip, huint16_t port) : SockAddr{ToNet(ip), ToNet(port)}
|
|
|
|
{}
|
|
|
|
|
2021-03-09 16:02:41 +00:00
|
|
|
SockAddr::SockAddr(huint128_t ip, huint16_t port)
|
2021-03-02 18:18:22 +00:00
|
|
|
{
|
|
|
|
init();
|
2021-03-09 16:02:41 +00:00
|
|
|
setIPv6(ip);
|
|
|
|
setPort(port);
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::SockAddr(nuint128_t ip, nuint16_t port)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
setIPv6(ip);
|
|
|
|
setPort(port);
|
2021-03-02 18:18:22 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 17:23:21 +00:00
|
|
|
SockAddr::SockAddr(std::string_view addr)
|
|
|
|
{
|
2020-05-08 20:33:44 +00:00
|
|
|
init();
|
|
|
|
fromString(addr);
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
2021-02-24 23:34:42 +00:00
|
|
|
SockAddr::SockAddr(std::string_view addr, uint16_t port)
|
|
|
|
{
|
|
|
|
init();
|
2021-03-09 16:02:41 +00:00
|
|
|
setPort(huint16_t{port});
|
2021-02-24 23:34:42 +00:00
|
|
|
fromString(addr, false);
|
|
|
|
}
|
2020-05-08 17:23:21 +00:00
|
|
|
|
2021-02-22 15:01:05 +00:00
|
|
|
SockAddr::SockAddr(const AddressInfo& info) : SockAddr{info.ip}
|
|
|
|
{
|
2021-03-09 16:02:41 +00:00
|
|
|
setPort(huint16_t{info.port});
|
2021-02-22 15:01:05 +00:00
|
|
|
}
|
|
|
|
|
2020-05-08 22:52:00 +00:00
|
|
|
SockAddr::SockAddr(const SockAddr& other)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
2020-05-08 22:52:00 +00:00
|
|
|
*this = other;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr&
|
2020-05-08 22:52:00 +00:00
|
|
|
SockAddr::operator=(const SockAddr& other)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
2020-05-08 22:52:00 +00:00
|
|
|
*this = other.m_addr;
|
|
|
|
return *this;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::SockAddr(const sockaddr& addr)
|
|
|
|
{
|
2020-05-08 22:52:00 +00:00
|
|
|
*this = addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr&
|
|
|
|
SockAddr::operator=(const sockaddr& other)
|
|
|
|
{
|
|
|
|
if (other.sa_family == AF_INET6)
|
2021-02-24 23:34:42 +00:00
|
|
|
*this = reinterpret_cast<const sockaddr_in6&>(other);
|
2020-05-08 22:52:00 +00:00
|
|
|
else if (other.sa_family == AF_INET)
|
2021-02-24 23:34:42 +00:00
|
|
|
*this = reinterpret_cast<const sockaddr_in&>(other);
|
2020-05-08 22:52:00 +00:00
|
|
|
else
|
|
|
|
throw std::invalid_argument("Invalid sockaddr (not AF_INET or AF_INET6)");
|
|
|
|
|
|
|
|
return *this;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr::SockAddr(const sockaddr_in& addr)
|
|
|
|
{
|
2020-05-08 22:52:00 +00:00
|
|
|
*this = addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr&
|
|
|
|
SockAddr::operator=(const sockaddr_in& other)
|
|
|
|
{
|
|
|
|
init();
|
2021-02-24 23:34:42 +00:00
|
|
|
applyIPv4MapBytes();
|
2020-05-08 22:52:00 +00:00
|
|
|
|
|
|
|
// 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;
|
2020-10-27 21:34:09 +00:00
|
|
|
m_addr4.sin_addr.s_addr = other.sin_addr.s_addr;
|
|
|
|
m_addr4.sin_port = other.sin_port;
|
2020-05-08 22:52:00 +00:00
|
|
|
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));
|
2021-02-24 23:34:42 +00:00
|
|
|
if (ipv6_is_mapped_ipv4(other.sin6_addr))
|
2021-03-09 16:02:41 +00:00
|
|
|
{
|
2020-10-27 21:34:09 +00:00
|
|
|
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]);
|
2021-03-09 16:02:41 +00:00
|
|
|
m_addr4.sin_port = m_addr.sin6_port;
|
|
|
|
}
|
2020-05-08 22:52:00 +00:00
|
|
|
m_empty = false;
|
|
|
|
|
|
|
|
return *this;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 16:14:07 +00:00
|
|
|
SockAddr::SockAddr(const in6_addr& addr)
|
|
|
|
{
|
|
|
|
*this = addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
SockAddr&
|
|
|
|
SockAddr::operator=(const in6_addr& other)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
|
|
|
|
memcpy(&m_addr.sin6_addr.s6_addr, &other.s6_addr, sizeof(m_addr.sin6_addr.s6_addr));
|
2021-02-24 23:34:42 +00:00
|
|
|
if (ipv6_is_mapped_ipv4(other))
|
2021-03-09 16:02:41 +00:00
|
|
|
{
|
2020-10-27 21:34:09 +00:00
|
|
|
setIPv4(other.s6_addr[12], other.s6_addr[13], other.s6_addr[14], other.s6_addr[15]);
|
2021-03-09 16:02:41 +00:00
|
|
|
m_addr4.sin_port = m_addr.sin6_port;
|
|
|
|
}
|
2020-05-11 16:14:07 +00:00
|
|
|
m_empty = false;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:23:21 +00:00
|
|
|
SockAddr::operator const sockaddr*() const
|
|
|
|
{
|
2021-03-23 19:19:39 +00:00
|
|
|
return isIPv4() ? reinterpret_cast<const sockaddr*>(&m_addr4)
|
|
|
|
: reinterpret_cast<const sockaddr*>(&m_addr);
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 21:34:09 +00:00
|
|
|
SockAddr::operator const sockaddr_in*() const
|
|
|
|
{
|
|
|
|
return &m_addr4;
|
|
|
|
}
|
|
|
|
|
2020-05-11 15:11:44 +00:00
|
|
|
SockAddr::operator const sockaddr_in6*() const
|
|
|
|
{
|
|
|
|
return &m_addr;
|
|
|
|
}
|
|
|
|
|
QUIC lokinet integration refactor
Refactors how quic packets get handled: the actual tunnels now live in
tunnel.hpp's TunnelManager which holds and manages all the quic<->tcp
tunnelling. service::Endpoint now holds a TunnelManager rather than a
quic::Server. We only need one quic server, but we need a separate quic
client instance per outgoing quic tunnel, and TunnelManager handles all
that glue now.
Adds QUIC packet handling to get to the right tunnel code. This
required multiplexing incoming quic packets, as follows:
Adds a very small quic tunnel packet header of 4 bytes:
[1, SPORT, ECN] for client->server packets, where SPORT is our
source "port" (really: just a uint16_t unique quic instance
identifier)
or
[2, DPORT, ECN] for server->client packets where the DPORT is the SPORT
from above.
(This also reworks ECN bits to get properly carried over lokinet.)
We don't need a destination/source port for the server-side because
there is only ever one quic server (and we know we're going to it when
the first byte of the header is 1).
Removes the config option for quic exposing ports; a full lokinet will
simply accept anything incoming on quic and tunnel it to the requested
port on the the local endpoint IP (this handler will come in a following
commit).
Replace ConvoTags with full addresses: we need to carry the port, as
well, which the ConvoTag can't give us, so change those to more general
SockAddrs from which we can extract both the ConvoTag *and* the port.
Add a pending connection queue along with new quic-side handlers to call
when a stream becomes available (TunnelManager uses this to wire up
pending incoming conns with quic streams as streams open up).
Completely get rid of tunnel_server/tunnel_client.cpp code; it is now
moved to tunnel.hpp.
Add listen()/forget() methods in TunnelManager for setting up quic
listening sockets (for liblokinet usage).
Add open()/close() methods in TunnelManager for spinning up new quic
clients for outgoing quic connections.
2021-03-23 19:26:32 +00:00
|
|
|
size_t
|
|
|
|
SockAddr::sockaddr_len() const
|
|
|
|
{
|
|
|
|
return isIPv6() ? sizeof(m_addr) : sizeof(m_addr4);
|
|
|
|
}
|
|
|
|
|
2020-05-11 17:55:36 +00:00
|
|
|
bool
|
|
|
|
SockAddr::operator<(const SockAddr& other) const
|
|
|
|
{
|
|
|
|
return (m_addr.sin6_addr.s6_addr < other.m_addr.sin6_addr.s6_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SockAddr::operator==(const SockAddr& other) const
|
|
|
|
{
|
2021-02-22 15:01:05 +00:00
|
|
|
return m_addr.sin6_addr == other.m_addr.sin6_addr
|
|
|
|
and m_addr.sin6_port == other.m_addr.sin6_port;
|
2020-05-11 17:55:36 +00:00
|
|
|
}
|
|
|
|
|
2021-02-16 15:59:18 +00:00
|
|
|
huint128_t
|
|
|
|
SockAddr::asIPv6() const
|
|
|
|
{
|
|
|
|
return net::In6ToHUInt(m_addr.sin6_addr);
|
|
|
|
}
|
|
|
|
|
2021-02-22 15:01:05 +00:00
|
|
|
huint32_t
|
|
|
|
SockAddr::asIPv4() const
|
|
|
|
{
|
|
|
|
const nuint32_t n{m_addr4.sin_addr.s_addr};
|
|
|
|
return ToHost(n);
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:23:21 +00:00
|
|
|
void
|
2021-02-24 23:34:42 +00:00
|
|
|
SockAddr::fromString(std::string_view str, bool allow_port)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
|
|
|
if (str.empty())
|
2020-05-11 15:11:44 +00:00
|
|
|
{
|
|
|
|
init();
|
|
|
|
m_empty = true;
|
|
|
|
return;
|
|
|
|
}
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
// NOTE: this potentially involves multiple memory allocations,
|
|
|
|
// reimplement without split() if it is performance bottleneck
|
|
|
|
auto splits = split(str, ':');
|
|
|
|
|
|
|
|
// TODO: having ":port" at the end makes this ambiguous with IPv6
|
|
|
|
// come up with a strategy for implementing
|
|
|
|
if (splits.size() > 2)
|
2021-02-16 15:59:18 +00:00
|
|
|
{
|
|
|
|
std::string data{str};
|
|
|
|
if (inet_pton(AF_INET6, data.c_str(), m_addr.sin6_addr.s6_addr) == -1)
|
|
|
|
throw std::runtime_error{"invalid ip6 address: " + data};
|
|
|
|
return;
|
|
|
|
}
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
// split() shouldn't return an empty list if str is empty (checked above)
|
|
|
|
assert(splits.size() > 0);
|
|
|
|
|
|
|
|
// splits[0] should be dot-separated IPv4
|
|
|
|
auto ipSplits = split(splits[0], '.');
|
|
|
|
if (ipSplits.size() != 4)
|
|
|
|
throw std::invalid_argument(stringify(str, " is not a valid IPv4 address"));
|
|
|
|
|
2021-02-24 23:34:42 +00:00
|
|
|
std::array<uint8_t, 4> ipBytes;
|
2020-05-08 17:23:21 +00:00
|
|
|
for (int i = 0; i < 4; ++i)
|
2021-02-24 23:34:42 +00:00
|
|
|
if (not parse_int(ipSplits[i], ipBytes[i]))
|
|
|
|
throw std::runtime_error(stringify(str, " contains invalid numeric value"));
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
// attempt port before setting IPv4 bytes
|
|
|
|
if (splits.size() == 2)
|
|
|
|
{
|
2021-02-24 23:34:42 +00:00
|
|
|
if (not allow_port)
|
|
|
|
throw std::runtime_error{stringify("invalid ip address (port not allowed here): ", str)};
|
|
|
|
uint16_t port;
|
|
|
|
if (not parse_int(splits[1], port))
|
|
|
|
throw std::runtime_error{stringify(splits[1], " is not a valid port")};
|
2020-05-08 17:23:21 +00:00
|
|
|
setPort(port);
|
|
|
|
}
|
|
|
|
|
|
|
|
setIPv4(ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
SockAddr::toString() const
|
|
|
|
{
|
|
|
|
// TODO: review
|
|
|
|
if (isEmpty())
|
|
|
|
return "";
|
|
|
|
|
2020-05-11 20:52:30 +00:00
|
|
|
std::string str;
|
2020-05-08 17:23:21 +00:00
|
|
|
|
2021-03-23 19:19:39 +00:00
|
|
|
if (isIPv4())
|
2020-05-11 20:52:30 +00:00
|
|
|
{
|
2021-02-24 23:34:42 +00:00
|
|
|
// handle IPv4 mapped addrs
|
2020-05-11 20:52:30 +00:00
|
|
|
constexpr auto MaxIPv4PlusPortStringSize = 22;
|
|
|
|
str.reserve(MaxIPv4PlusPortStringSize);
|
2020-10-27 21:34:09 +00:00
|
|
|
char buf[128] = {0x0};
|
|
|
|
inet_ntop(AF_INET, &m_addr4.sin_addr.s_addr, buf, sizeof(buf));
|
|
|
|
str.append(buf);
|
2020-05-11 20:52:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
constexpr auto MaxIPv6PlusPortStringSize = 128;
|
|
|
|
str.reserve(MaxIPv6PlusPortStringSize);
|
2020-05-08 17:23:21 +00:00
|
|
|
|
2020-05-11 20:52:30 +00:00
|
|
|
char buf[128] = {0x0};
|
|
|
|
inet_ntop(AF_INET6, &m_addr.sin6_addr.s6_addr, buf, sizeof(buf));
|
2020-05-08 17:23:21 +00:00
|
|
|
|
2020-05-11 20:52:30 +00:00
|
|
|
str.append("[");
|
|
|
|
str.append(buf);
|
|
|
|
str.append("]");
|
|
|
|
}
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
str.append(1, ':');
|
2020-05-08 20:33:44 +00:00
|
|
|
str.append(std::to_string(getPort()));
|
2020-05-08 17:23:21 +00:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SockAddr::isEmpty() const
|
|
|
|
{
|
|
|
|
return m_empty;
|
|
|
|
}
|
|
|
|
|
2021-03-23 19:19:39 +00:00
|
|
|
bool
|
|
|
|
SockAddr::isIPv4() const
|
|
|
|
{
|
|
|
|
return ipv6_is_mapped_ipv4(m_addr.sin6_addr);
|
|
|
|
}
|
|
|
|
bool
|
|
|
|
SockAddr::isIPv6() const
|
|
|
|
{
|
|
|
|
return not isIPv4();
|
|
|
|
}
|
|
|
|
|
2021-03-09 16:02:41 +00:00
|
|
|
nuint32_t
|
2021-03-02 18:18:22 +00:00
|
|
|
SockAddr::getIPv4() const
|
|
|
|
{
|
2021-03-09 16:02:41 +00:00
|
|
|
return {m_addr4.sin_addr.s_addr};
|
2021-03-02 18:18:22 +00:00
|
|
|
}
|
|
|
|
|
2021-04-28 18:41:14 +00:00
|
|
|
nuint128_t
|
|
|
|
SockAddr::getIPv6() const
|
|
|
|
{
|
|
|
|
nuint128_t a;
|
|
|
|
// Explicit cast to void* here to avoid non-trivial type copying warnings (technically this
|
|
|
|
// isn't trivial because of the zeroing default constructor, but it's trivial enough that this
|
|
|
|
// copy is safe).
|
|
|
|
std::memcpy(static_cast<void*>(&a), &m_addr.sin6_addr, 16);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2021-03-02 18:18:22 +00:00
|
|
|
void
|
2021-03-09 16:02:41 +00:00
|
|
|
SockAddr::setIPv4(nuint32_t ip)
|
2021-03-02 18:18:22 +00:00
|
|
|
{
|
|
|
|
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
|
|
|
|
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
|
|
|
|
|
|
|
|
applyIPv4MapBytes();
|
|
|
|
|
|
|
|
std::memcpy(ip6 + 12, &ip, 4);
|
2021-03-09 16:02:41 +00:00
|
|
|
m_addr4.sin_addr.s_addr = ip.n;
|
2021-03-02 18:18:22 +00:00
|
|
|
m_empty = false;
|
|
|
|
}
|
|
|
|
|
2021-03-09 16:02:41 +00:00
|
|
|
void
|
|
|
|
SockAddr::setIPv4(huint32_t ip)
|
|
|
|
{
|
|
|
|
setIPv4(ToNet(ip));
|
|
|
|
}
|
|
|
|
|
2020-05-08 17:23:21 +00:00
|
|
|
void
|
|
|
|
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
|
|
|
|
{
|
|
|
|
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
|
|
|
|
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
|
|
|
|
|
2021-02-24 23:34:42 +00:00
|
|
|
applyIPv4MapBytes();
|
2020-05-08 17:23:21 +00:00
|
|
|
|
|
|
|
ip6[12] = a;
|
|
|
|
ip6[13] = b;
|
|
|
|
ip6[14] = c;
|
|
|
|
ip6[15] = d;
|
2020-10-27 21:34:09 +00:00
|
|
|
const auto ip = ipaddr_ipv4_bits(a, b, c, d);
|
|
|
|
m_addr4.sin_addr.s_addr = htonl(ip.h);
|
2020-05-08 17:23:21 +00:00
|
|
|
m_empty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-03-09 16:02:41 +00:00
|
|
|
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));
|
2021-03-23 19:19:39 +00:00
|
|
|
if (isIPv4())
|
2021-03-09 16:02:41 +00:00
|
|
|
{
|
|
|
|
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)
|
2020-05-08 17:23:21 +00:00
|
|
|
{
|
2021-03-09 16:02:41 +00:00
|
|
|
setPort(ToNet(port));
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t
|
|
|
|
SockAddr::getPort() const
|
|
|
|
{
|
|
|
|
return ntohs(m_addr.sin6_port);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostream&
|
|
|
|
operator<<(std::ostream& out, const SockAddr& address)
|
|
|
|
{
|
2020-05-11 16:17:41 +00:00
|
|
|
out << address.toString();
|
|
|
|
return out;
|
2020-05-08 17:23:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace llarp
|