refactor: tr_address cleanup (#4338)

* refactor: move tr_tracker_http_announce() helper funcs into their own namespace

* refactor: move tr_globalIPv6() helper funcs into their own namespace

* refactor: move tr_address_is_valid_for_peers() helper funcs into their own namespace

* refactor: make tr_address_compare() a private method

* refactor: rename tr_address::isIPv4() to is_ipv4()

* refactor: use snake_case for tr_address methods

* refactor: make tr_address_is_valid_for_peers() a member function
This commit is contained in:
Charles Kerr 2022-12-08 20:27:52 -06:00 committed by GitHub
parent 26a8c17187
commit 0a69685a4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 337 additions and 316 deletions

View File

@ -52,84 +52,6 @@ using namespace std::literals;
return req.partial_seed && (req.event != TR_ANNOUNCE_EVENT_STOPPED) ? "paused"sv : tr_announce_event_get_string(req.event);
}
static void announce_url_new(tr_urlbuf& url, tr_session const* session, tr_announce_request const& req)
{
url.clear();
auto out = std::back_inserter(url);
auto escaped_info_hash = tr_urlbuf{};
tr_urlPercentEncode(std::back_inserter(escaped_info_hash), req.info_hash);
fmt::format_to(
out,
"{url}"
"{sep}info_hash={info_hash}"
"&peer_id={peer_id}"
"&port={port}"
"&uploaded={uploaded}"
"&downloaded={downloaded}"
"&left={left}"
"&numwant={numwant}"
"&key={key}"
"&compact=1"
"&supportcrypto=1",
fmt::arg("url", req.announce_url),
fmt::arg("sep", tr_strvContains(req.announce_url.sv(), '?') ? '&' : '?'),
fmt::arg("info_hash", std::data(escaped_info_hash)),
fmt::arg("peer_id", std::string_view{ std::data(req.peer_id), std::size(req.peer_id) }),
fmt::arg("port", req.port.host()),
fmt::arg("uploaded", req.up),
fmt::arg("downloaded", req.down),
fmt::arg("left", req.leftUntilComplete),
fmt::arg("numwant", req.numwant),
fmt::arg("key", req.key));
if (session->encryptionMode() == TR_ENCRYPTION_REQUIRED)
{
fmt::format_to(out, "&requirecrypto=1");
}
if (req.corrupt != 0)
{
fmt::format_to(out, "&corrupt={}", req.corrupt);
}
if (auto const str = get_event_string(req); !std::empty(str))
{
fmt::format_to(out, "&event={}", str);
}
if (!std::empty(req.tracker_id))
{
fmt::format_to(out, "&trackerid={}", req.tracker_id);
}
}
static std::string format_ipv4_url_arg(tr_address const& ipv4_address)
{
auto readable = std::array<char, INET_ADDRSTRLEN>{};
evutil_inet_ntop(AF_INET, &ipv4_address.addr, readable.data(), readable.size());
return "&ipv4="s + readable.data();
}
static std::string format_ipv6_url_arg(in6_addr const addr)
{
auto readable = std::array<char, INET6_ADDRSTRLEN>{};
evutil_inet_ntop(AF_INET6, &addr, std::data(readable), std::size(readable));
auto arg = "&ipv6="s;
tr_urlPercentEncode(std::back_inserter(arg), readable.data());
return arg;
}
static std::string format_ip_arg(std::string_view ip)
{
auto arg = std::string{ "&ip="sv };
arg += ip;
return arg;
}
static void verboseLog(std::string_view description, tr_direction direction, std::string_view message)
{
auto& out = std::cerr;
@ -190,7 +112,7 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
{
BasicHandler::EndDict(context);
if (tr_address_is_valid_for_peers(&pex_.addr, pex_.port))
if (pex_.is_valid_for_peers())
{
response_.pex.push_back(pex_);
pex_ = {};
@ -249,15 +171,15 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
}
else if (key == "peers"sv)
{
response_.pex = tr_pex::fromCompact4(std::data(value), std::size(value), nullptr, 0);
response_.pex = tr_pex::from_compact_ipv4(std::data(value), std::size(value), nullptr, 0);
}
else if (key == "peers6"sv)
{
response_.pex6 = tr_pex::fromCompact6(std::data(value), std::size(value), nullptr, 0);
response_.pex6 = tr_pex::from_compact_ipv6(std::data(value), std::size(value), nullptr, 0);
}
else if (key == "ip")
{
if (auto const addr = tr_address::fromString(value); addr)
if (auto const addr = tr_address::from_string(value); addr)
{
pex_.addr = *addr;
}
@ -268,7 +190,7 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
}
else if (key == "external ip"sv && std::size(value) == 4)
{
auto const [addr, out] = tr_address::fromCompact4(reinterpret_cast<std::byte const*>(std::data(value)));
auto const [addr, out] = tr_address::from_compact_ipv4(reinterpret_cast<std::byte const*>(std::data(value)));
response_.external_ip = addr;
}
else
@ -403,11 +325,96 @@ static void onAnnounceDone(tr_web::FetchResponse const& web_response)
}
}
namespace tr_tracker_announce_helpers
{
void announce_url_new(tr_urlbuf& url, tr_session const* session, tr_announce_request const& req)
{
url.clear();
auto out = std::back_inserter(url);
auto escaped_info_hash = tr_urlbuf{};
tr_urlPercentEncode(std::back_inserter(escaped_info_hash), req.info_hash);
fmt::format_to(
out,
"{url}"
"{sep}info_hash={info_hash}"
"&peer_id={peer_id}"
"&port={port}"
"&uploaded={uploaded}"
"&downloaded={downloaded}"
"&left={left}"
"&numwant={numwant}"
"&key={key}"
"&compact=1"
"&supportcrypto=1",
fmt::arg("url", req.announce_url),
fmt::arg("sep", tr_strvContains(req.announce_url.sv(), '?') ? '&' : '?'),
fmt::arg("info_hash", std::data(escaped_info_hash)),
fmt::arg("peer_id", std::string_view{ std::data(req.peer_id), std::size(req.peer_id) }),
fmt::arg("port", req.port.host()),
fmt::arg("uploaded", req.up),
fmt::arg("downloaded", req.down),
fmt::arg("left", req.leftUntilComplete),
fmt::arg("numwant", req.numwant),
fmt::arg("key", req.key));
if (session->encryptionMode() == TR_ENCRYPTION_REQUIRED)
{
fmt::format_to(out, "&requirecrypto=1");
}
if (req.corrupt != 0)
{
fmt::format_to(out, "&corrupt={}", req.corrupt);
}
if (auto const str = get_event_string(req); !std::empty(str))
{
fmt::format_to(out, "&event={}", str);
}
if (!std::empty(req.tracker_id))
{
fmt::format_to(out, "&trackerid={}", req.tracker_id);
}
}
[[nodiscard]] std::string format_ipv4_url_arg(tr_address const& addr)
{
auto buf = std::array<char, TR_ADDRSTRLEN>{};
auto display_name = addr.display_name(std::data(buf), std::size(buf));
return fmt::format("&ipv4={:s}", display_name);
}
[[nodiscard]] std::string format_ipv6_url_arg(in6_addr const addr)
{
auto readable = std::array<char, INET6_ADDRSTRLEN>{};
evutil_inet_ntop(AF_INET6, &addr, std::data(readable), std::size(readable));
auto arg = "&ipv6="s;
tr_urlPercentEncode(std::back_inserter(arg), readable.data());
return arg;
}
[[nodiscard]] std::string format_ip_arg(std::string_view ip)
{
auto arg = std::string{ "&ip="sv };
arg += ip;
return arg;
}
} // namespace tr_tracker_announce_helpers
void tr_tracker_http_announce(
tr_session const* session,
tr_announce_request const& request,
tr_announce_response_func on_response)
{
using namespace tr_tracker_announce_helpers;
auto* const d = new http_announce_data{ request.info_hash, std::move(on_response), request.log_name };
/* There are two alternative techniques for announcing both IPv4 and

View File

@ -227,7 +227,7 @@ struct tau_announce_request
response.seeders = buf.toUint32();
auto const contiguous = std::vector<std::byte>{ std::begin(buf), std::end(buf) };
response.pex = tr_pex::fromCompact4(std::data(contiguous), std::size(contiguous), nullptr, 0);
response.pex = tr_pex::from_compact_ipv4(std::data(contiguous), std::size(contiguous), nullptr, 0);
requestFinished();
}
else
@ -591,7 +591,7 @@ public:
// Since size of IP field is only 4 bytes long, we can only announce IPv4 addresses
auto const addr = mediator_.announceIP();
uint32_t const announce_ip = addr && addr->isIPv4() ? addr->addr.addr4.s_addr : 0;
uint32_t const announce_ip = addr && addr->is_ipv4() ? addr->addr.addr4.s_addr : 0;
tracker->announces.emplace_back(announce_ip, request, std::move(on_response));
tracker->upkeep(false);
}

View File

@ -94,7 +94,7 @@ std::optional<address_range_t> parsePeerGuardianLine(std::string_view line)
}
auto addrpair = address_range_t{};
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
if (auto const addr = tr_address::from_string(line.substr(0, pos)); addr)
{
addrpair.first = *addr;
}
@ -106,7 +106,7 @@ std::optional<address_range_t> parsePeerGuardianLine(std::string_view line)
line = line.substr(pos + 1);
// parse the trailing 'y.y.y.y'
if (auto const addr = tr_address::fromString(line); addr)
if (auto const addr = tr_address::from_string(line); addr)
{
addrpair.second = *addr;
}
@ -133,7 +133,7 @@ std::optional<address_range_t> parseEmuleLine(std::string_view line)
auto addrpair = address_range_t{};
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
if (auto const addr = tr_address::from_string(line.substr(0, pos)); addr)
{
addrpair.first = *addr;
}
@ -149,7 +149,7 @@ std::optional<address_range_t> parseEmuleLine(std::string_view line)
return {};
}
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
if (auto const addr = tr_address::from_string(line.substr(0, pos)); addr)
{
addrpair.second = *addr;
}
@ -174,7 +174,7 @@ std::optional<address_range_t> parseCidrLine(std::string_view line)
return {};
}
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr && addr->isIPv4())
if (auto const addr = tr_address::from_string(line.substr(0, pos)); addr && addr->is_ipv4())
{
addrpair.first = *addr;
}
@ -439,7 +439,7 @@ std::vector<Blocklist> Blocklist::loadBlocklists(std::string_view const blocklis
bool Blocklist::contains(tr_address const& addr) const
{
TR_ASSERT(tr_address_is_valid(&addr));
TR_ASSERT(addr.is_valid());
if (!is_enabled_)
{

View File

@ -58,30 +58,11 @@ std::string tr_net_strerror(int err)
#endif
}
/*
* Compare two tr_address structures.
* Returns:
* <0 if a < b
* >0 if a > b
* 0 if a == b
*/
int tr_address_compare(tr_address const* a, tr_address const* b) noexcept
{
// IPv6 addresses are always "greater than" IPv4
if (a->type != b->type)
{
return a->isIPv4() ? 1 : -1;
}
return a->isIPv4() ? memcmp(&a->addr.addr4, &b->addr.addr4, sizeof(a->addr.addr4)) :
memcmp(&a->addr.addr6.s6_addr, &b->addr.addr6.s6_addr, sizeof(a->addr.addr6.s6_addr));
}
/***********************************************************************
* TCP sockets
**********************************************************************/
[[nodiscard]] std::optional<tr_tos_t> tr_tos_t::fromString(std::string_view name)
[[nodiscard]] std::optional<tr_tos_t> tr_tos_t::from_string(std::string_view name)
{
auto const needle = tr_strlower(tr_strvStrip(name));
@ -159,55 +140,6 @@ void tr_netSetCongestionControl([[maybe_unused]] tr_socket_t s, [[maybe_unused]]
#endif
}
std::optional<std::pair<tr_address, tr_port>> tr_address::fromSockaddr(struct sockaddr const* from)
{
if (from == nullptr)
{
return {};
}
if (from->sa_family == AF_INET)
{
auto const* const sin = reinterpret_cast<struct sockaddr_in const*>(from);
auto addr = tr_address{};
addr.type = TR_AF_INET;
addr.addr.addr4 = sin->sin_addr;
return std::make_pair(addr, tr_port::fromNetwork(sin->sin_port));
}
if (from->sa_family == AF_INET6)
{
auto const* const sin6 = reinterpret_cast<struct sockaddr_in6 const*>(from);
auto addr = tr_address{};
addr.type = TR_AF_INET6;
addr.addr.addr6 = sin6->sin6_addr;
return std::make_pair(addr, tr_port::fromNetwork(sin6->sin6_port));
}
return {};
}
std::pair<sockaddr_storage, socklen_t> tr_address::toSockaddr(tr_port port) const noexcept
{
auto ss = sockaddr_storage{};
if (isIPv4())
{
auto* const ss4 = reinterpret_cast<sockaddr_in*>(&ss);
ss4->sin_addr = addr.addr4;
ss4->sin_family = AF_INET;
ss4->sin_port = port.network();
return { ss, sizeof(sockaddr_in) };
}
auto* const ss6 = reinterpret_cast<sockaddr_in6*>(&ss);
ss6->sin6_addr = addr.addr6;
ss6->sin6_family = AF_INET6;
ss6->sin6_flowinfo = 0;
ss6->sin6_port = port.network();
return { ss, sizeof(sockaddr_in6) };
}
static tr_socket_t createSocket(tr_session* session, int domain, int type)
{
TR_ASSERT(session != nullptr);
@ -258,14 +190,14 @@ static tr_socket_t createSocket(tr_session* session, int domain, int type)
tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const& addr, tr_port port, bool client_is_seed)
{
TR_ASSERT(tr_address_is_valid(&addr));
TR_ASSERT(addr.is_valid());
if (!session->allowsTCP())
{
return {};
}
if (!tr_address_is_valid_for_peers(&addr, port))
if (!addr.is_valid_for_peers(port))
{
return {};
}
@ -288,11 +220,11 @@ tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const& addr,
}
}
auto const [sock, addrlen] = addr.toSockaddr(port);
auto const [sock, addrlen] = addr.to_sockaddr(port);
// set source address
auto const [source_addr, is_default_addr] = session->publicAddress(addr.type);
auto const [source_sock, sourcelen] = source_addr.toSockaddr({});
auto const [source_sock, sourcelen] = source_addr.to_sockaddr({});
if (bind(s, reinterpret_cast<sockaddr const*>(&source_sock), sourcelen) == -1)
{
@ -313,7 +245,7 @@ tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const& addr,
#endif
sockerrno != EINPROGRESS)
{
if (auto const tmperrno = sockerrno; (tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr.isIPv4())
if (auto const tmperrno = sockerrno; (tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr.is_ipv4())
{
tr_logAddWarn(fmt::format(
_("Couldn't connect socket {socket} to {address}:{port}: {error} ({error_code})"),
@ -340,9 +272,9 @@ tr_peer_socket tr_netOpenPeerUTPSocket(tr_session* session, tr_address const& ad
{
auto ret = tr_peer_socket{};
if (session->utp_context != nullptr && tr_address_is_valid_for_peers(&addr, port))
if (session->utp_context != nullptr && addr.is_valid_for_peers(port))
{
auto const [ss, sslen] = addr.toSockaddr(port);
auto const [ss, sslen] = addr.to_sockaddr(port);
if (auto* const sock = utp_create_socket(session->utp_context); sock != nullptr)
{
@ -362,7 +294,7 @@ tr_peer_socket tr_netOpenPeerUTPSocket(tr_session* session, tr_address const& ad
static tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool suppress_msgs, int* err_out)
{
TR_ASSERT(tr_address_is_valid(&addr));
TR_ASSERT(addr.is_valid());
static auto constexpr Domains = std::array<int, NUM_TR_AF_INET_TYPES>{ AF_INET, AF_INET6 };
@ -386,7 +318,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool
#ifdef IPV6_V6ONLY
if (addr.isIPv6() &&
if (addr.is_ipv6() &&
(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char const*>(&optval), sizeof(optval)) == -1) &&
(sockerrno != ENOPROTOOPT)) // if the kernel doesn't support it, ignore it
{
@ -397,7 +329,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool
#endif
auto const [sock, addrlen] = addr.toSockaddr(port);
auto const [sock, addrlen] = addr.to_sockaddr(port);
if (bind(fd, (struct sockaddr*)&sock, addrlen) == -1)
{
@ -465,7 +397,7 @@ bool tr_net_hasIPv6(tr_port port)
if (!already_done)
{
int err = 0;
auto const fd = tr_netBindTCPImpl(tr_address::AnyIPv4(), port, true, &err);
auto const fd = tr_netBindTCPImpl(tr_address::any_ipv4(), port, true, &err);
if (fd != TR_BAD_SOCKET || err != EAFNOSUPPORT) /* we support ipv6 */
{
@ -499,7 +431,7 @@ std::optional<std::tuple<tr_address, tr_port, tr_socket_t>> tr_netAccept(tr_sess
// get the address and port,
// make the socket unblocking,
// and confirm we don't have too many peers
auto const addrport = tr_address::fromSockaddr(reinterpret_cast<struct sockaddr*>(&sock));
auto const addrport = tr_address::from_sockaddr(reinterpret_cast<struct sockaddr*>(&sock));
if (!addrport || evutil_make_socket_nonblocking(sockfd) == -1 || !session->incPeerCount())
{
tr_netCloseSocket(sockfd);
@ -520,17 +452,18 @@ void tr_netClose(tr_session* session, tr_socket_t sockfd)
session->decPeerCount();
}
/*
get_source_address() and global_unicast_address() were written by
Juliusz Chroboczek, and are covered under the same license as dht.c.
Please feel free to copy them into your software if it can help
unbreaking the double-stack Internet. */
// code in global_ipv6_herlpers is written by Juliusz Chroboczek
// and is covered under the same license as dht.cc.
// Please feel free to copy them into your software if it can help
// unbreaking the double-stack Internet.
namespace global_ipv6_helpers
{
/* Get the source address used for a given destination address. Since
there is no official interface to get this information, we create
a connected UDP socket (connected UDP... hmm...) and check its source
address. */
static int get_source_address(struct sockaddr const* dst, socklen_t dst_len, struct sockaddr* src, socklen_t* src_len)
[[nodiscard]] int get_source_address(struct sockaddr const* dst, socklen_t dst_len, struct sockaddr* src, socklen_t* src_len)
{
tr_socket_t const s = socket(dst->sa_family, SOCK_DGRAM, 0);
if (s == TR_BAD_SOCKET)
@ -552,7 +485,7 @@ static int get_source_address(struct sockaddr const* dst, socklen_t dst_len, str
}
/* We all hate NATs. */
static int global_unicast_address(struct sockaddr_storage* ss)
[[nodiscard]] int global_unicast_address(struct sockaddr_storage* ss)
{
if (ss->ss_family == AF_INET)
{
@ -578,7 +511,7 @@ static int global_unicast_address(struct sockaddr_storage* ss)
return -1;
}
static int tr_globalAddress(int af, void* addr, int* addr_len)
[[nodiscard]] int global_address(int af, void* addr, int* addr_len)
{
auto ss = sockaddr_storage{};
socklen_t sslen = sizeof(ss);
@ -650,9 +583,13 @@ static int tr_globalAddress(int af, void* addr, int* addr_len)
}
}
} // namespace global_ipv6_helpers
/* Return our global IPv6 address, with caching. */
std::optional<in6_addr> tr_globalIPv6(tr_session const* session)
{
using namespace global_ipv6_helpers;
static auto ipv6 = in6_addr{};
static time_t last_time = 0;
static bool have_ipv6 = false;
@ -661,7 +598,7 @@ std::optional<in6_addr> tr_globalIPv6(tr_session const* session)
if (auto const now = tr_time(); last_time < now - 1800)
{
int addrlen = sizeof(ipv6);
int const rc = tr_globalAddress(AF_INET6, &ipv6, &addrlen);
int const rc = global_address(AF_INET6, &ipv6, &addrlen);
have_ipv6 = rc >= 0 && addrlen == sizeof(ipv6);
last_time = now;
}
@ -695,35 +632,36 @@ std::optional<in6_addr> tr_globalIPv6(tr_session const* session)
****
***/
static bool isIPv4MappedAddress(tr_address const* addr)
namespace is_valid_for_peers_helpers
{
return addr->isIPv6() && IN6_IS_ADDR_V4MAPPED(&addr->addr.addr6);
[[nodiscard]] constexpr auto is_ipv4_mapped_address(tr_address const* addr)
{
return addr->is_ipv6() && IN6_IS_ADDR_V4MAPPED(&addr->addr.addr6);
}
static bool isIPv6LinkLocalAddress(tr_address const* addr)
[[nodiscard]] constexpr auto is_ipv6_link_local_address(tr_address const* addr)
{
return addr->isIPv6() && IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6);
return addr->is_ipv6() && IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6);
}
/* isMartianAddr was written by Juliusz Chroboczek,
and is covered under the same license as third-party/dht/dht.c. */
static bool isMartianAddr(struct tr_address const* a)
[[nodiscard]] auto is_martian_addr(tr_address const& addr)
{
TR_ASSERT(tr_address_is_valid(a));
static auto constexpr Zeroes = std::array<unsigned char, 16>{};
switch (a->type)
switch (addr.type)
{
case TR_AF_INET:
{
auto const* const address = (unsigned char const*)&a->addr.addr4;
auto const* const address = (unsigned char const*)&addr.addr.addr4;
return address[0] == 0 || address[0] == 127 || (address[0] & 0xE0) == 0xE0;
}
case TR_AF_INET6:
{
auto const* const address = (unsigned char const*)&a->addr.addr6;
auto const* const address = (unsigned char const*)&addr.addr.addr6;
return address[0] == 0xFF ||
(memcmp(address, std::data(Zeroes), 15) == 0 && (address[15] == 0 || address[15] == 1));
}
@ -733,10 +671,14 @@ static bool isMartianAddr(struct tr_address const* a)
}
}
bool tr_address_is_valid_for_peers(tr_address const* addr, tr_port port)
} // namespace is_valid_for_peers_helpers
bool tr_address::is_valid_for_peers(tr_port port) const noexcept
{
return !std::empty(port) && tr_address_is_valid(addr) && !isIPv6LinkLocalAddress(addr) && !isIPv4MappedAddress(addr) &&
!isMartianAddr(addr);
using namespace is_valid_for_peers_helpers;
return is_valid() && !std::empty(port) && !is_ipv6_link_local_address(this) && !is_ipv4_mapped_address(this) &&
!is_martian_addr(*this);
}
/// tr_port
@ -755,7 +697,7 @@ std::pair<tr_port, std::byte const*> tr_port::fromCompact(std::byte const* compa
/// tr_address
std::optional<tr_address> tr_address::fromString(std::string_view address_sv)
std::optional<tr_address> tr_address::from_string(std::string_view address_sv)
{
auto const address_sz = tr_strbuf<char, TR_ADDRSTRLEN>{ address_sv };
@ -780,7 +722,7 @@ std::string_view tr_address::display_name(char* out, size_t outlen, tr_port port
{
if (std::empty(port))
{
return isIPv4() ? evutil_inet_ntop(AF_INET, &addr, out, outlen) : evutil_inet_ntop(AF_INET6, &addr, out, outlen);
return is_ipv4() ? evutil_inet_ntop(AF_INET, &addr, out, outlen) : evutil_inet_ntop(AF_INET6, &addr, out, outlen);
}
auto buf = std::array<char, INET6_ADDRSTRLEN>{};
@ -807,7 +749,7 @@ template char* tr_address::display_name<char*>(char*, tr_port) const;
return buf;
}
std::pair<tr_address, std::byte const*> tr_address::fromCompact4(std::byte const* compact) noexcept
std::pair<tr_address, std::byte const*> tr_address::from_compact_ipv4(std::byte const* compact) noexcept
{
static auto constexpr Addr4Len = size_t{ 4 };
@ -820,7 +762,7 @@ std::pair<tr_address, std::byte const*> tr_address::fromCompact4(std::byte const
return std::make_pair(address, compact);
}
std::pair<tr_address, std::byte const*> tr_address::fromCompact6(std::byte const* compact) noexcept
std::pair<tr_address, std::byte const*> tr_address::from_compact_ipv6(std::byte const* compact) noexcept
{
static auto constexpr Addr6Len = size_t{ 16 };
@ -832,6 +774,67 @@ std::pair<tr_address, std::byte const*> tr_address::fromCompact6(std::byte const
return std::make_pair(address, compact);
}
std::optional<std::pair<tr_address, tr_port>> tr_address::from_sockaddr(struct sockaddr const* from)
{
if (from == nullptr)
{
return {};
}
if (from->sa_family == AF_INET)
{
auto const* const sin = reinterpret_cast<struct sockaddr_in const*>(from);
auto addr = tr_address{};
addr.type = TR_AF_INET;
addr.addr.addr4 = sin->sin_addr;
return std::make_pair(addr, tr_port::fromNetwork(sin->sin_port));
}
if (from->sa_family == AF_INET6)
{
auto const* const sin6 = reinterpret_cast<struct sockaddr_in6 const*>(from);
auto addr = tr_address{};
addr.type = TR_AF_INET6;
addr.addr.addr6 = sin6->sin6_addr;
return std::make_pair(addr, tr_port::fromNetwork(sin6->sin6_port));
}
return {};
}
std::pair<sockaddr_storage, socklen_t> tr_address::to_sockaddr(tr_port port) const noexcept
{
auto ss = sockaddr_storage{};
if (is_ipv4())
{
auto* const ss4 = reinterpret_cast<sockaddr_in*>(&ss);
ss4->sin_addr = addr.addr4;
ss4->sin_family = AF_INET;
ss4->sin_port = port.network();
return { ss, sizeof(sockaddr_in) };
}
auto* const ss6 = reinterpret_cast<sockaddr_in6*>(&ss);
ss6->sin6_addr = addr.addr6;
ss6->sin6_family = AF_INET6;
ss6->sin6_flowinfo = 0;
ss6->sin6_port = port.network();
return { ss, sizeof(sockaddr_in6) };
}
static int tr_address_compare(tr_address const* a, tr_address const* b) noexcept // <=>
{
// IPv6 addresses are always "greater than" IPv4
if (a->type != b->type)
{
return a->is_ipv4() ? 1 : -1;
}
return a->is_ipv4() ? memcmp(&a->addr.addr4, &b->addr.addr4, sizeof(a->addr.addr4)) :
memcmp(&a->addr.addr6.s6_addr, &b->addr.addr6.s6_addr, sizeof(a->addr.addr6.s6_addr));
}
int tr_address::compare(tr_address const& that) const noexcept // <=>
{
return tr_address_compare(this, &that);

View File

@ -73,8 +73,6 @@ enum tr_address_type
struct tr_address;
[[nodiscard]] int tr_address_compare(tr_address const* a, tr_address const* b) noexcept;
/**
* Literally just a port number.
*
@ -153,10 +151,10 @@ private:
struct tr_address
{
[[nodiscard]] static std::optional<tr_address> fromString(std::string_view address_sv);
[[nodiscard]] static std::optional<std::pair<tr_address, tr_port>> fromSockaddr(struct sockaddr const*);
[[nodiscard]] static std::pair<tr_address, std::byte const*> fromCompact4(std::byte const* compact) noexcept;
[[nodiscard]] static std::pair<tr_address, std::byte const*> fromCompact6(std::byte const* compact) noexcept;
[[nodiscard]] static std::optional<tr_address> from_string(std::string_view address_sv);
[[nodiscard]] static std::optional<std::pair<tr_address, tr_port>> from_sockaddr(struct sockaddr const*);
[[nodiscard]] static std::pair<tr_address, std::byte const*> from_compact_ipv4(std::byte const* compact) noexcept;
[[nodiscard]] static std::pair<tr_address, std::byte const*> from_compact_ipv6(std::byte const* compact) noexcept;
// write the text form of the address, e.g. inet_ntop()
template<typename OutputIt>
@ -165,7 +163,7 @@ struct tr_address
[[nodiscard]] std::string display_name(tr_port port = {}) const;
template<typename OutputIt>
static OutputIt toCompact4(OutputIt out, in_addr const* addr4, tr_port port)
static OutputIt to_compact_ipv4(OutputIt out, in_addr const* addr4, tr_port port)
{
auto const nport = port.network();
out = std::copy_n(reinterpret_cast<std::byte const*>(addr4), sizeof(*addr4), out);
@ -174,13 +172,13 @@ struct tr_address
}
template<typename OutputIt>
static OutputIt toCompact4(OutputIt out, sockaddr_in const* sa4)
static OutputIt to_compact_ipv4(OutputIt out, sockaddr_in const* sa4)
{
return toCompact4(out, &sa4->sin_addr, tr_port::fromNetwork(sa4->sin_port));
return to_compact_ipv4(out, &sa4->sin_addr, tr_port::fromNetwork(sa4->sin_port));
}
template<typename OutputIt>
static OutputIt toCompact6(OutputIt out, in6_addr const* addr6, tr_port port)
static OutputIt to_compact_ipv6(OutputIt out, in6_addr const* addr6, tr_port port)
{
auto const nport = port.network();
out = std::copy_n(reinterpret_cast<std::byte const*>(addr6), sizeof(*addr6), out);
@ -189,42 +187,42 @@ struct tr_address
}
template<typename OutputIt>
static OutputIt toCompact6(OutputIt out, sockaddr_in6 const* sa6)
static OutputIt to_compact_ipv6(OutputIt out, sockaddr_in6 const* sa6)
{
return toCompact6(out, &sa6->sin6_addr, tr_port::fromNetwork(sa6->sin6_port));
return to_compact_ipv6(out, &sa6->sin6_addr, tr_port::fromNetwork(sa6->sin6_port));
}
template<typename OutputIt>
OutputIt toCompact4(OutputIt out, tr_port port) const
OutputIt to_compact_ipv4(OutputIt out, tr_port port) const
{
return toCompact4(out, &this->addr.addr4, port);
return to_compact_ipv4(out, &this->addr.addr4, port);
}
template<typename OutputIt>
OutputIt toCompact6(OutputIt out, tr_port port) const
OutputIt to_compact_ipv6(OutputIt out, tr_port port) const
{
return toCompact6(out, &this->addr.addr6, port);
return to_compact_ipv6(out, &this->addr.addr6, port);
}
template<typename OutputIt>
static OutputIt toCompact(OutputIt out, sockaddr const* saddr)
static OutputIt to_compact(OutputIt out, sockaddr const* saddr)
{
return saddr->sa_family == AF_INET ? toCompact4(out, reinterpret_cast<sockaddr_in const*>(saddr)) :
toCompact6(out, reinterpret_cast<sockaddr_in6 const*>(saddr));
return saddr->sa_family == AF_INET ? to_compact_ipv4(out, reinterpret_cast<sockaddr_in const*>(saddr)) :
to_compact_ipv6(out, reinterpret_cast<sockaddr_in6 const*>(saddr));
}
template<typename OutputIt>
static OutputIt toCompact(OutputIt out, struct sockaddr_storage* ss)
static OutputIt to_compact(OutputIt out, struct sockaddr_storage* ss)
{
return toCompact(out, reinterpret_cast<struct sockaddr*>(ss));
return to_compact(out, reinterpret_cast<struct sockaddr*>(ss));
}
[[nodiscard]] constexpr auto isIPv4() const noexcept
[[nodiscard]] constexpr auto is_ipv4() const noexcept
{
return type == TR_AF_INET;
}
[[nodiscard]] constexpr auto isIPv6() const noexcept
[[nodiscard]] constexpr auto is_ipv6() const noexcept
{
return type == TR_AF_INET6;
}
@ -255,7 +253,7 @@ struct tr_address
//
[[nodiscard]] std::pair<sockaddr_storage, socklen_t> toSockaddr(tr_port port) const noexcept;
[[nodiscard]] std::pair<sockaddr_storage, socklen_t> to_sockaddr(tr_port port) const noexcept;
tr_address_type type;
union
@ -264,24 +262,24 @@ struct tr_address
struct in_addr addr4;
} addr;
[[nodiscard]] static auto constexpr AnyIPv4() noexcept
[[nodiscard]] static auto constexpr any_ipv4() noexcept
{
return tr_address{ TR_AF_INET, { { { { INADDR_ANY } } } } };
}
[[nodiscard]] static auto constexpr AnyIPv6() noexcept
[[nodiscard]] static auto constexpr any_ipv6() noexcept
{
return tr_address{ TR_AF_INET6, { IN6ADDR_ANY_INIT } };
}
[[nodiscard]] constexpr auto is_valid() const noexcept
{
return type == TR_AF_INET || type == TR_AF_INET6;
}
[[nodiscard]] bool is_valid_for_peers(tr_port port) const noexcept;
};
bool tr_address_is_valid_for_peers(tr_address const* addr, tr_port port);
constexpr bool tr_address_is_valid(tr_address const* a)
{
return a != nullptr && (a->type == TR_AF_INET || a->type == TR_AF_INET6);
}
/***********************************************************************
* Sockets
**********************************************************************/
@ -305,7 +303,7 @@ bool tr_net_hasIPv6(tr_port);
/// TOS / DSCP
/**
* A toString() / fromString() convenience wrapper around the TOS int value
* A toString() / from_string() convenience wrapper around the TOS int value
*/
class tr_tos_t
{
@ -322,7 +320,7 @@ public:
return value_;
}
[[nodiscard]] static std::optional<tr_tos_t> fromString(std::string_view);
[[nodiscard]] static std::optional<tr_tos_t> from_string(std::string_view);
[[nodiscard]] std::string toString() const;

View File

@ -533,7 +533,7 @@ std::shared_ptr<tr_peerIo> tr_peerIo::newOutgoing(
bool utp)
{
TR_ASSERT(session != nullptr);
TR_ASSERT(tr_address_is_valid(&addr));
TR_ASSERT(addr.is_valid());
TR_ASSERT(utp || session->allowsTCP());
auto socket = tr_peer_socket{};

View File

@ -317,5 +317,5 @@ private:
constexpr bool tr_isPeerIo(tr_peerIo const* io)
{
return io != nullptr && tr_address_is_valid(&io->address());
return io != nullptr && io->address().is_valid();
}

View File

@ -164,7 +164,7 @@ struct peer_atom
#ifdef TR_ENABLE_ASSERTS
[[nodiscard]] bool isValid() const noexcept
{
return fromFirst < TR_PEER_FROM__MAX && fromBest < TR_PEER_FROM__MAX && tr_address_is_valid(&addr);
return fromFirst < TR_PEER_FROM__MAX && fromBest < TR_PEER_FROM__MAX && addr.is_valid();
}
#endif
@ -1086,7 +1086,7 @@ static struct peer_atom* ensureAtomExists(
uint8_t const flags,
uint8_t const from)
{
TR_ASSERT(tr_address_is_valid(&addr));
TR_ASSERT(addr.is_valid());
TR_ASSERT(from < TR_PEER_FROM__MAX);
struct peer_atom* a = getExistingAtom(s, addr);
@ -1285,7 +1285,7 @@ size_t tr_peerMgrAddPex(tr_torrent* tor, uint8_t from, tr_pex const* pex, size_t
for (tr_pex const* const end = pex + n_pex; pex != end; ++pex)
{
if (tr_isPex(pex) && /* safeguard against corrupt data */
!s->manager->session->addressIsBlocked(pex->addr) && tr_address_is_valid_for_peers(&pex->addr, pex->port))
!s->manager->session->addressIsBlocked(pex->addr) && pex->is_valid_for_peers())
{
ensureAtomExists(s, pex->addr, pex->port, pex->flags, from);
++n_used;
@ -1295,7 +1295,11 @@ size_t tr_peerMgrAddPex(tr_torrent* tor, uint8_t from, tr_pex const* pex, size_t
return n_used;
}
std::vector<tr_pex> tr_pex::fromCompact4(void const* compact, size_t compact_len, uint8_t const* added_f, size_t added_f_len)
std::vector<tr_pex> tr_pex::from_compact_ipv4(
void const* compact,
size_t compact_len,
uint8_t const* added_f,
size_t added_f_len)
{
size_t const n = compact_len / 6;
auto const* walk = static_cast<std::byte const*>(compact);
@ -1303,7 +1307,7 @@ std::vector<tr_pex> tr_pex::fromCompact4(void const* compact, size_t compact_len
for (size_t i = 0; i < n; ++i)
{
std::tie(pex[i].addr, walk) = tr_address::fromCompact4(walk);
std::tie(pex[i].addr, walk) = tr_address::from_compact_ipv4(walk);
std::tie(pex[i].port, walk) = tr_port::fromCompact(walk);
if (added_f != nullptr && n == added_f_len)
@ -1315,7 +1319,11 @@ std::vector<tr_pex> tr_pex::fromCompact4(void const* compact, size_t compact_len
return pex;
}
std::vector<tr_pex> tr_pex::fromCompact6(void const* compact, size_t compact_len, uint8_t const* added_f, size_t added_f_len)
std::vector<tr_pex> tr_pex::from_compact_ipv6(
void const* compact,
size_t compact_len,
uint8_t const* added_f,
size_t added_f_len)
{
size_t const n = compact_len / 18;
auto const* walk = static_cast<std::byte const*>(compact);
@ -1323,7 +1331,7 @@ std::vector<tr_pex> tr_pex::fromCompact6(void const* compact, size_t compact_len
for (size_t i = 0; i < n; ++i)
{
std::tie(pex[i].addr, walk) = tr_address::fromCompact6(walk);
std::tie(pex[i].addr, walk) = tr_address::from_compact_ipv6(walk);
std::tie(pex[i].port, walk) = tr_port::fromCompact(walk);
if (added_f != nullptr && n == added_f_len)
@ -1479,7 +1487,7 @@ std::vector<tr_pex> tr_peerMgrGetPeers(tr_torrent const* tor, uint8_t address_ty
if (atom->addr.type == address_type)
{
TR_ASSERT(tr_address_is_valid(&atom->addr));
TR_ASSERT(atom->addr.is_valid());
pex.emplace_back(atom->addr, atom->port, atom->flags);
}
}

View File

@ -65,44 +65,44 @@ struct tr_pex
}
template<typename OutputIt>
OutputIt toCompact4(OutputIt out) const
OutputIt to_compact_ipv4(OutputIt out) const
{
return this->addr.toCompact4(out, this->port);
return this->addr.to_compact_ipv4(out, this->port);
}
template<typename OutputIt>
OutputIt toCompact6(OutputIt out) const
OutputIt to_compact_ipv6(OutputIt out) const
{
return this->addr.toCompact6(out, this->port);
return this->addr.to_compact_ipv6(out, this->port);
}
template<typename OutputIt>
static OutputIt toCompact4(OutputIt out, tr_pex const* pex, size_t n_pex)
static OutputIt to_compact_ipv4(OutputIt out, tr_pex const* pex, size_t n_pex)
{
for (size_t i = 0; i < n_pex; ++i)
{
out = pex[i].toCompact4(out);
out = pex[i].to_compact_ipv4(out);
}
return out;
}
template<typename OutputIt>
static OutputIt toCompact6(OutputIt out, tr_pex const* pex, size_t n_pex)
static OutputIt to_compact_ipv6(OutputIt out, tr_pex const* pex, size_t n_pex)
{
for (size_t i = 0; i < n_pex; ++i)
{
out = pex[i].toCompact6(out);
out = pex[i].to_compact_ipv6(out);
}
return out;
}
[[nodiscard]] static std::vector<tr_pex> fromCompact4(
[[nodiscard]] static std::vector<tr_pex> from_compact_ipv4(
void const* compact,
size_t compact_len,
uint8_t const* added_f,
size_t added_f_len);
[[nodiscard]] static std::vector<tr_pex> fromCompact6(
[[nodiscard]] static std::vector<tr_pex> from_compact_ipv6(
void const* compact,
size_t compact_len,
uint8_t const* added_f,
@ -144,6 +144,11 @@ struct tr_pex
return compare(that) < 0;
}
[[nodiscard]] bool is_valid_for_peers() const noexcept
{
return addr.is_valid_for_peers(port);
}
tr_address addr = {};
tr_port port = {}; /* this field is in network byte order */
uint8_t flags = 0;
@ -151,7 +156,7 @@ struct tr_pex
constexpr bool tr_isPex(tr_pex const* pex)
{
return pex && tr_address_is_valid(&pex->addr);
return pex != nullptr && pex->addr.is_valid();
}
[[nodiscard]] tr_peerMgr* tr_peerMgrNew(tr_session* session);

View File

@ -284,7 +284,7 @@ public:
if (session->allowsDHT() && io->supportsDHT())
{
// only send PORT over IPv6 iff IPv6 DHT is running (BEP-32).
if (io->address().isIPv4() || tr_globalIPv6(nullptr).has_value())
if (io->address().is_ipv4() || tr_globalIPv6(nullptr).has_value())
{
protocolSendPort(this, session->udpPort());
}
@ -1180,7 +1180,7 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen)
added_f = nullptr;
}
auto pex = tr_pex::fromCompact4(added, added_len, added_f, added_f_len);
auto pex = tr_pex::from_compact_ipv4(added, added_len, added_f, added_f_len);
pex.resize(std::min(MaxPexPeerCount, std::size(pex)));
tr_peerMgrAddPex(tor, TR_PEER_FROM_PEX, std::data(pex), std::size(pex));
}
@ -1195,7 +1195,7 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen)
added_f = nullptr;
}
auto pex = tr_pex::fromCompact6(added, added_len, added_f, added_f_len);
auto pex = tr_pex::from_compact_ipv6(added, added_len, added_f, added_f_len);
pex.resize(std::min(MaxPexPeerCount, std::size(pex)));
tr_peerMgrAddPex(tor, TR_PEER_FROM_PEX, std::data(pex), std::size(pex));
}
@ -2264,7 +2264,7 @@ void tr_peerMsgsImpl::sendPex()
{
// "added"
tmpbuf.clear();
tr_pex::toCompact4(std::back_inserter(tmpbuf), std::data(added), std::size(added));
tr_pex::to_compact_ipv4(std::back_inserter(tmpbuf), std::data(added), std::size(added));
TR_ASSERT(std::size(tmpbuf) == std::size(added) * 6);
tr_variantDictAddRaw(&val, TR_KEY_added, std::data(tmpbuf), std::size(tmpbuf));
@ -2286,7 +2286,7 @@ void tr_peerMsgsImpl::sendPex()
{
// "dropped"
tmpbuf.clear();
tr_pex::toCompact4(std::back_inserter(tmpbuf), std::data(dropped), std::size(dropped));
tr_pex::to_compact_ipv4(std::back_inserter(tmpbuf), std::data(dropped), std::size(dropped));
TR_ASSERT(std::size(tmpbuf) == std::size(dropped) * 6);
tr_variantDictAddRaw(&val, TR_KEY_dropped, std::data(tmpbuf), std::size(tmpbuf));
}
@ -2294,7 +2294,7 @@ void tr_peerMsgsImpl::sendPex()
if (!std::empty(added6))
{
tmpbuf.clear();
tr_pex::toCompact6(std::back_inserter(tmpbuf), std::data(added6), std::size(added6));
tr_pex::to_compact_ipv6(std::back_inserter(tmpbuf), std::data(added6), std::size(added6));
TR_ASSERT(std::size(tmpbuf) == std::size(added6) * 18);
tr_variantDictAddRaw(&val, TR_KEY_added6, std::data(tmpbuf), std::size(tmpbuf));
@ -2316,7 +2316,7 @@ void tr_peerMsgsImpl::sendPex()
{
// "dropped6"
tmpbuf.clear();
tr_pex::toCompact6(std::back_inserter(tmpbuf), std::data(dropped6), std::size(dropped6));
tr_pex::to_compact_ipv6(std::back_inserter(tmpbuf), std::data(dropped6), std::size(dropped6));
TR_ASSERT(std::size(tmpbuf) == std::size(dropped6) * 18);
tr_variantDictAddRaw(&val, TR_KEY_dropped6, std::data(tmpbuf), std::size(tmpbuf));
}

View File

@ -337,15 +337,15 @@ tr_session::PublicAddressResult tr_session::publicAddress(tr_address_type type)
{
if (type == TR_AF_INET)
{
static auto constexpr DefaultAddr = tr_address::AnyIPv4();
auto addr = tr_address::fromString(settings_.bind_address_ipv4).value_or(DefaultAddr);
static auto constexpr DefaultAddr = tr_address::any_ipv4();
auto addr = tr_address::from_string(settings_.bind_address_ipv4).value_or(DefaultAddr);
return { addr, addr == DefaultAddr };
}
if (type == TR_AF_INET6)
{
static auto constexpr DefaultAddr = tr_address::AnyIPv6();
auto addr = tr_address::fromString(settings_.bind_address_ipv6).value_or(DefaultAddr);
static auto constexpr DefaultAddr = tr_address::any_ipv6();
auto addr = tr_address::from_string(settings_.bind_address_ipv6).value_or(DefaultAddr);
return { addr, addr == DefaultAddr };
}

View File

@ -146,7 +146,7 @@ private:
return {};
}
return tr_address::fromString(session_.announceIP());
return tr_address::from_string(session_.announceIP());
}
private:

View File

@ -180,7 +180,7 @@ public:
void addNode(tr_address const& addr, tr_port port) override
{
if (addr.isIPv4())
if (addr.is_ipv4())
{
auto sin = sockaddr_in{};
sin.sin_family = AF_INET;
@ -188,7 +188,7 @@ public:
sin.sin_port = port.network();
mediator_.api().ping_node((struct sockaddr*)&sin, sizeof(sin));
}
else if (addr.isIPv6())
else if (addr.is_ipv6())
{
auto sin6 = sockaddr_in6{};
sin6.sin6_family = AF_INET6;
@ -388,12 +388,12 @@ private:
if (event == DHT_EVENT_VALUES)
{
auto const pex = tr_pex::fromCompact4(data, data_len, nullptr, 0);
auto const pex = tr_pex::from_compact_ipv4(data, data_len, nullptr, 0);
self->mediator_.addPex(hash, std::data(pex), std::size(pex));
}
else if (event == DHT_EVENT_VALUES6)
{
auto const pex = tr_pex::fromCompact6(data, data_len, nullptr, 0);
auto const pex = tr_pex::from_compact_ipv6(data, data_len, nullptr, 0);
self->mediator_.addPex(hash, std::data(pex), std::size(pex));
}
}
@ -480,7 +480,7 @@ private:
{
auto addr = tr_address{};
auto port = tr_port{};
std::tie(addr, walk) = tr_address::fromCompact4(walk);
std::tie(addr, walk) = tr_address::from_compact_ipv4(walk);
std::tie(port, walk) = tr_port::fromCompact(walk);
nodes.emplace_back(addr, port);
}
@ -494,7 +494,7 @@ private:
{
auto addr = tr_address{};
auto port = tr_port{};
std::tie(addr, walk) = tr_address::fromCompact6(walk);
std::tie(addr, walk) = tr_address::from_compact_ipv6(walk);
std::tie(port, walk) = tr_port::fromCompact(walk);
nodes.emplace_back(addr, port);
}
@ -564,7 +564,7 @@ private:
for (auto* infop = info; infop != nullptr; infop = infop->ai_next)
{
if (auto addrport = tr_address::fromSockaddr(infop->ai_addr); addrport)
if (auto addrport = tr_address::from_sockaddr(infop->ai_addr); addrport)
{
nodes.emplace_back(addrport->first, addrport->second);
}

View File

@ -90,7 +90,7 @@ static void utp_on_accept(tr_session* const session, UTPSocket* const utp_sock)
utp_getpeername(utp_sock, from, &fromlen);
if (auto addrport = tr_address::fromSockaddr(reinterpret_cast<struct sockaddr*>(&from_storage)); addrport)
if (auto addrport = tr_address::from_sockaddr(reinterpret_cast<struct sockaddr*>(&from_storage)); addrport)
{
auto const& [addr, port] = *addrport;
session->addIncoming(tr_peer_socket{ addr, port, utp_sock });

View File

@ -303,7 +303,7 @@ std::optional<tr_tos_t> VariantConverter::load<tr_tos_t>(tr_variant* src)
{
if (auto val = std::string_view{}; tr_variantGetStrView(src, &val))
{
return tr_tos_t::fromString(val);
return tr_tos_t::from_string(val);
}
if (auto val = int64_t{}; tr_variantGetInt(src, &val))

View File

@ -34,7 +34,7 @@ using namespace std::literals;
bool tr_addressIsIP(char const* address)
{
return address != nullptr && tr_address::fromString(address).has_value();
return address != nullptr && tr_address::from_string(address).has_value();
}
char const* tr_webGetResponseStr(long code)
@ -249,7 +249,7 @@ std::string_view getSiteName(std::string_view host)
}
// is it an IP?
if (auto const addr = tr_address::fromString(host); addr)
if (auto const addr = tr_address::from_string(host); addr)
{
return host;
}

View File

@ -44,7 +44,7 @@ TEST_F(AnnouncerTest, parseHttpAnnounceResponseNoPeers)
EXPECT_EQ(3, response.seeders);
EXPECT_EQ(0, response.leechers);
EXPECT_EQ(2, response.downloads);
EXPECT_EQ(*tr_address::fromString("1.2.3.4"), response.external_ip);
EXPECT_EQ(*tr_address::from_string("1.2.3.4"), response.external_ip);
EXPECT_EQ(0U, std::size(response.pex));
EXPECT_EQ(0U, std::size(response.pex6));
EXPECT_EQ(""sv, response.errmsg);

View File

@ -47,7 +47,7 @@ protected:
void sendto(void const* buf, size_t buflen, sockaddr const* sa, socklen_t salen) override
{
auto target = tr_address::fromSockaddr(sa);
auto target = tr_address::from_sockaddr(sa);
ASSERT_TRUE(target);
sent_.emplace_back(static_cast<char const*>(buf), buflen, sa, salen);
}
@ -567,9 +567,9 @@ TEST_F(AnnouncerUdpTest, canAnnounce)
static auto constexpr Leechers = uint32_t{ 10 };
static auto constexpr Seeders = uint32_t{ 20 };
auto const addresses = std::array<std::pair<tr_address, tr_port>, 3>{
std::make_pair(tr_address::fromString("10.10.10.5").value_or(tr_address{}), tr_port::fromHost(128)),
std::make_pair(tr_address::fromString("192.168.1.2").value_or(tr_address{}), tr_port::fromHost(2021)),
std::make_pair(tr_address::fromString("192.168.1.3").value_or(tr_address{}), tr_port::fromHost(2022)),
std::make_pair(tr_address::from_string("10.10.10.5").value_or(tr_address{}), tr_port::fromHost(128)),
std::make_pair(tr_address::from_string("192.168.1.2").value_or(tr_address{}), tr_port::fromHost(2021)),
std::make_pair(tr_address::from_string("192.168.1.3").value_or(tr_address{}), tr_port::fromHost(2022)),
};
auto request = tr_announce_request{};

View File

@ -42,7 +42,7 @@ protected:
bool addressIsBlocked(char const* address_str)
{
auto const addr = tr_address::fromString(address_str);
auto const addr = tr_address::from_string(address_str);
return !addr || session_->addressIsBlocked(*addr);
}
};

View File

@ -56,19 +56,19 @@ protected:
std::array<char, IdLength> const id_ = tr_rand_obj<std::array<char, IdLength>>();
std::vector<std::pair<tr_address, tr_port>> ipv4_nodes_ = {
std::make_pair(*tr_address::fromString("10.10.10.1"), tr_port::fromHost(128)),
std::make_pair(*tr_address::fromString("10.10.10.2"), tr_port::fromHost(129)),
std::make_pair(*tr_address::fromString("10.10.10.3"), tr_port::fromHost(130)),
std::make_pair(*tr_address::fromString("10.10.10.4"), tr_port::fromHost(131)),
std::make_pair(*tr_address::fromString("10.10.10.5"), tr_port::fromHost(132))
std::make_pair(*tr_address::from_string("10.10.10.1"), tr_port::fromHost(128)),
std::make_pair(*tr_address::from_string("10.10.10.2"), tr_port::fromHost(129)),
std::make_pair(*tr_address::from_string("10.10.10.3"), tr_port::fromHost(130)),
std::make_pair(*tr_address::from_string("10.10.10.4"), tr_port::fromHost(131)),
std::make_pair(*tr_address::from_string("10.10.10.5"), tr_port::fromHost(132))
};
std::vector<std::pair<tr_address, tr_port>> ipv6_nodes_ = {
std::make_pair(*tr_address::fromString("1002:1035:4527:3546:7854:1237:3247:3217"), tr_port::fromHost(6881)),
std::make_pair(*tr_address::fromString("1002:1035:4527:3546:7854:1237:3247:3218"), tr_port::fromHost(6882)),
std::make_pair(*tr_address::fromString("1002:1035:4527:3546:7854:1237:3247:3219"), tr_port::fromHost(6883)),
std::make_pair(*tr_address::fromString("1002:1035:4527:3546:7854:1237:3247:3220"), tr_port::fromHost(6884)),
std::make_pair(*tr_address::fromString("1002:1035:4527:3546:7854:1237:3247:3221"), tr_port::fromHost(6885))
std::make_pair(*tr_address::from_string("1002:1035:4527:3546:7854:1237:3247:3217"), tr_port::fromHost(6881)),
std::make_pair(*tr_address::from_string("1002:1035:4527:3546:7854:1237:3247:3218"), tr_port::fromHost(6882)),
std::make_pair(*tr_address::from_string("1002:1035:4527:3546:7854:1237:3247:3219"), tr_port::fromHost(6883)),
std::make_pair(*tr_address::from_string("1002:1035:4527:3546:7854:1237:3247:3220"), tr_port::fromHost(6884)),
std::make_pair(*tr_address::from_string("1002:1035:4527:3546:7854:1237:3247:3221"), tr_port::fromHost(6885))
};
[[nodiscard]] auto nodesString() const
@ -102,13 +102,13 @@ protected:
auto compact = std::vector<std::byte>{};
for (auto const& [addr, port] : ipv4_nodes_)
{
addr.toCompact4(std::back_inserter(compact), port);
addr.to_compact_ipv4(std::back_inserter(compact), port);
}
tr_variantDictAddRaw(&dict, TR_KEY_nodes, std::data(compact), std::size(compact));
compact.clear();
for (auto const& [addr, port] : ipv6_nodes_)
{
addr.toCompact6(std::back_inserter(compact), port);
addr.to_compact_ipv6(std::back_inserter(compact), port);
}
tr_variantDictAddRaw(&dict, TR_KEY_nodes6, std::data(compact), std::size(compact));
tr_variantToFile(&dict, TR_VARIANT_FMT_BENC, dat_file);
@ -165,7 +165,7 @@ protected:
int ping_node(struct sockaddr const* sa, int /*salen*/) override
{
auto addrport = tr_address::fromSockaddr(sa);
auto addrport = tr_address::from_sockaddr(sa);
auto const [addr, port] = *addrport;
pinged_.push_back(Pinged{ addr, port, tr_time() });
return 0;
@ -373,7 +373,7 @@ protected:
return {};
}
auto opt = tr_address::fromSockaddr(info->ai_addr);
auto opt = tr_address::from_sockaddr(info->ai_addr);
freeaddrinfo(info);
if (opt)
{
@ -584,7 +584,7 @@ TEST_F(DhtTest, pingsAddedNodes)
EXPECT_EQ(0U, std::size(mediator.mock_dht_.pinged_));
auto const addr = *tr_address::fromString("10.10.10.1");
auto const addr = *tr_address::from_string("10.10.10.1");
auto constexpr Port = tr_port::fromHost(128);
dht->addNode(addr, Port);

View File

@ -143,7 +143,7 @@ public:
static auto constexpr ReservedBytesNoExtensions = std::array<uint8_t, 8>{ 0, 0, 0, 0, 0, 0, 0, 0 };
static auto constexpr PlaintextProtocolName = "\023BitTorrent protocol"sv;
tr_address const DefaultPeerAddr = *tr_address::fromString("127.0.0.1"sv);
tr_address const DefaultPeerAddr = *tr_address::from_string("127.0.0.1"sv);
tr_port const DefaultPeerPort = tr_port::fromHost(8080);
tr_handshake_mediator::torrent_info const TorrentWeAreSeeding{ tr_sha1::digest("abcde"sv),
tr_peerIdInit(),

View File

@ -18,15 +18,15 @@ TEST_F(NetTest, conversionsIPv4)
auto constexpr Port = tr_port::fromHost(80);
auto constexpr AddrStr = "127.0.0.1"sv;
auto addr = tr_address::fromString(AddrStr);
auto addr = tr_address::from_string(AddrStr);
EXPECT_TRUE(addr);
EXPECT_EQ(AddrStr, addr->display_name());
auto [ss, sslen] = addr->toSockaddr(Port);
auto [ss, sslen] = addr->to_sockaddr(Port);
EXPECT_EQ(AF_INET, ss.ss_family);
EXPECT_EQ(Port.network(), reinterpret_cast<sockaddr_in const*>(&ss)->sin_port);
auto addrport = tr_address::fromSockaddr(reinterpret_cast<sockaddr const*>(&ss));
auto addrport = tr_address::from_sockaddr(reinterpret_cast<sockaddr const*>(&ss));
EXPECT_TRUE(addrport);
EXPECT_EQ(addr, addrport->first);
EXPECT_EQ(Port, addrport->second);
@ -34,8 +34,8 @@ TEST_F(NetTest, conversionsIPv4)
TEST_F(NetTest, trAddress)
{
EXPECT_EQ("0.0.0.0", tr_address::AnyIPv4().display_name());
EXPECT_EQ("::", tr_address::AnyIPv6().display_name());
EXPECT_EQ("0.0.0.0", tr_address::any_ipv4().display_name());
EXPECT_EQ("::", tr_address::any_ipv6().display_name());
}
TEST_F(NetTest, compact4)
@ -51,7 +51,7 @@ TEST_F(NetTest, compact4)
auto in = std::data(Compact4);
auto addr = tr_address{};
auto port = tr_port{};
std::tie(addr, in) = tr_address::fromCompact4(in);
std::tie(addr, in) = tr_address::from_compact_ipv4(in);
std::tie(port, in) = tr_port::fromCompact(in);
EXPECT_EQ(std::data(Compact4) + std::size(Compact4), in);
EXPECT_EQ(ExpectedReadable, addr.display_name());
@ -60,23 +60,23 @@ TEST_F(NetTest, compact4)
// ...serialize it back again
auto compact4 = std::array<std::byte, 6>{};
auto out = std::data(compact4);
out = addr.toCompact4(out, port);
out = addr.to_compact_ipv4(out, port);
EXPECT_EQ(std::size(Compact4), static_cast<size_t>(out - std::data(compact4)));
EXPECT_EQ(Compact4, compact4);
/// sockaddr --> compact
auto [ss, sslen] = addr.toSockaddr(port);
auto [ss, sslen] = addr.to_sockaddr(port);
std::fill(std::begin(compact4), std::end(compact4), std::byte{});
out = std::data(compact4);
out = tr_address::toCompact(out, &ss);
out = tr_address::to_compact(out, &ss);
EXPECT_EQ(out, std::data(compact4) + std::size(compact4));
EXPECT_EQ(Compact4, compact4);
/// compact <--> tr_pex
// extract them into a tr_pex struct...
auto const pex = tr_pex::fromCompact4(std::data(compact4), std::size(compact4), nullptr, 0U);
auto const pex = tr_pex::from_compact_ipv4(std::data(compact4), std::size(compact4), nullptr, 0U);
ASSERT_EQ(1U, std::size(pex));
EXPECT_EQ(addr, pex.front().addr);
EXPECT_EQ(port, pex.front().port);
@ -84,7 +84,7 @@ TEST_F(NetTest, compact4)
// ...serialize that back again too
std::fill(std::begin(compact4), std::end(compact4), std::byte{});
out = std::data(compact4);
out = tr_pex::toCompact4(out, std::data(pex), std::size(pex));
out = tr_pex::to_compact_ipv4(out, std::data(pex), std::size(pex));
EXPECT_EQ(std::data(compact4) + std::size(compact4), out);
EXPECT_EQ(Compact4, compact4);
}
@ -105,7 +105,7 @@ TEST_F(NetTest, compact6)
auto in = std::data(Compact6);
auto addr = tr_address{};
auto port = tr_port{};
std::tie(addr, in) = tr_address::fromCompact6(in);
std::tie(addr, in) = tr_address::from_compact_ipv6(in);
std::tie(port, in) = tr_port::fromCompact(in);
EXPECT_EQ(std::data(Compact6) + std::size(Compact6), in);
EXPECT_EQ(ExpectedReadable, addr.display_name());
@ -114,23 +114,23 @@ TEST_F(NetTest, compact6)
// ...serialize it back again
auto compact6 = std::array<std::byte, 18>{};
auto out = std::data(compact6);
out = addr.toCompact6(out, port);
out = addr.to_compact_ipv6(out, port);
EXPECT_EQ(std::size(Compact6), static_cast<size_t>(out - std::data(compact6)));
EXPECT_EQ(Compact6, compact6);
/// sockaddr --> compact
auto [ss, sslen] = addr.toSockaddr(port);
auto [ss, sslen] = addr.to_sockaddr(port);
std::fill(std::begin(compact6), std::end(compact6), std::byte{});
out = std::data(compact6);
out = tr_address::toCompact(out, &ss);
out = tr_address::to_compact(out, &ss);
EXPECT_EQ(out, std::data(compact6) + std::size(compact6));
EXPECT_EQ(Compact6, compact6);
/// compact <--> tr_pex
// extract them into a tr_pex struct...
auto const pex = tr_pex::fromCompact6(std::data(compact6), std::size(compact6), nullptr, 0U);
auto const pex = tr_pex::from_compact_ipv6(std::data(compact6), std::size(compact6), nullptr, 0U);
ASSERT_EQ(1U, std::size(pex));
EXPECT_EQ(addr, pex.front().addr);
EXPECT_EQ(port, pex.front().port);
@ -138,7 +138,7 @@ TEST_F(NetTest, compact6)
// ...serialize that back again too
std::fill(std::begin(compact6), std::end(compact6), std::byte{});
out = std::data(compact6);
out = tr_pex::toCompact6(out, std::data(pex), std::size(pex));
out = tr_pex::to_compact_ipv6(out, std::data(pex), std::size(pex));
EXPECT_EQ(std::data(compact6) + std::size(compact6), out);
EXPECT_EQ(Compact6, compact6);
}