mirror of
https://github.com/transmission/transmission
synced 2025-02-20 21:26:53 +00:00
refactor: add tr_address::toCompact() (#4014)
* refactor: add tr_address::toCompact() * test: use the theory.org compact ipv4/6 examples in NetTest.compact4, NetTest.compact6 * refactor: add tr_address::toCompact() * test: add toCompact, fromCompact tests * refactor: add compact <--> sockaddr_storage conversion
This commit is contained in:
parent
be4a44292e
commit
b32f3e0a24
13 changed files with 286 additions and 103 deletions
|
@ -249,11 +249,11 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
|
|||
}
|
||||
else if (key == "peers"sv)
|
||||
{
|
||||
response_.pex = tr_peerMgrCompactToPex(std::data(value), std::size(value), nullptr, 0);
|
||||
response_.pex = tr_pex::fromCompact4(std::data(value), std::size(value), nullptr, 0);
|
||||
}
|
||||
else if (key == "peers6"sv)
|
||||
{
|
||||
response_.pex6 = tr_peerMgrCompact6ToPex(std::data(value), std::size(value), nullptr, 0);
|
||||
response_.pex6 = tr_pex::fromCompact6(std::data(value), std::size(value), nullptr, 0);
|
||||
}
|
||||
else if (key == "ip")
|
||||
{
|
||||
|
@ -268,7 +268,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<uint8_t const*>(std::data(value)));
|
||||
auto const [addr, out] = tr_address::fromCompact4(reinterpret_cast<std::byte const*>(std::data(value)));
|
||||
response_.external_ip = addr;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "crypto-utils.h" /* tr_rand_buffer() */
|
||||
#include "log.h"
|
||||
#include "peer-io.h"
|
||||
#include "peer-mgr.h" /* tr_peerMgrCompactToPex() */
|
||||
#include "peer-mgr.h" // for tr_pex::fromCompact4()
|
||||
#include "session.h"
|
||||
#include "tr-assert.h"
|
||||
#include "tr-buffer.h"
|
||||
|
@ -228,7 +228,7 @@ struct tau_announce_request
|
|||
auto const compact_len = std::size(buf);
|
||||
auto contiguous = std::array<uint8_t, 576>{};
|
||||
buf.toBuf(std::data(contiguous), compact_len);
|
||||
response.pex = tr_peerMgrCompactToPex(std::data(contiguous), compact_len, nullptr, 0);
|
||||
response.pex = tr_pex::fromCompact4(std::data(contiguous), compact_len, nullptr, 0);
|
||||
requestFinished();
|
||||
}
|
||||
else
|
||||
|
@ -298,7 +298,7 @@ static tau_announce_request make_tau_announce_request(
|
|||
buf.addUint32(announce_ip);
|
||||
buf.addUint32(in.key);
|
||||
buf.addUint32(in.numwant);
|
||||
buf.addUint16(in.port.host());
|
||||
buf.addPort(in.port);
|
||||
|
||||
/* build the tau_announce_request */
|
||||
auto req = tau_announce_request();
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "announcer.h"
|
||||
#include "crypto-utils.h" /* tr_rand_int(), tr_rand_int_weak() */
|
||||
#include "log.h"
|
||||
#include "peer-mgr.h" /* tr_peerMgrCompactToPex() */
|
||||
#include "session.h"
|
||||
#include "timer.h"
|
||||
#include "torrent.h"
|
||||
|
|
|
@ -812,13 +812,13 @@ struct tr_peer_socket tr_peer_socket_utp_create(struct UTPSocket* const handle)
|
|||
|
||||
/// tr_port
|
||||
|
||||
std::pair<tr_port, uint8_t const*> tr_port::fromCompact(uint8_t const* compact) noexcept
|
||||
std::pair<tr_port, std::byte const*> tr_port::fromCompact(std::byte const* compact) noexcept
|
||||
{
|
||||
static auto constexpr PortLen = size_t{ 2 };
|
||||
|
||||
static_assert(PortLen == sizeof(uint16_t));
|
||||
auto nport = uint16_t{};
|
||||
std::copy_n(compact, PortLen, reinterpret_cast<uint8_t*>(&nport));
|
||||
std::copy_n(compact, PortLen, reinterpret_cast<std::byte*>(&nport));
|
||||
compact += PortLen;
|
||||
|
||||
return std::make_pair(tr_port::fromNetwork(nport), compact);
|
||||
|
@ -878,26 +878,26 @@ template char* tr_address::readable<char*>(char*, tr_port) const;
|
|||
return buf;
|
||||
}
|
||||
|
||||
std::pair<tr_address, uint8_t const*> tr_address::fromCompact4(uint8_t const* compact) noexcept
|
||||
std::pair<tr_address, std::byte const*> tr_address::fromCompact4(std::byte const* compact) noexcept
|
||||
{
|
||||
static auto constexpr Addr4Len = size_t{ 4 };
|
||||
|
||||
auto address = tr_address{};
|
||||
static_assert(sizeof(address.addr.addr4) == Addr4Len);
|
||||
address.type = TR_AF_INET;
|
||||
std::copy_n(compact, Addr4Len, reinterpret_cast<uint8_t*>(&address.addr));
|
||||
std::copy_n(compact, Addr4Len, reinterpret_cast<std::byte*>(&address.addr));
|
||||
compact += Addr4Len;
|
||||
|
||||
return std::make_pair(address, compact);
|
||||
}
|
||||
|
||||
std::pair<tr_address, uint8_t const*> tr_address::fromCompact6(uint8_t const* compact) noexcept
|
||||
std::pair<tr_address, std::byte const*> tr_address::fromCompact6(std::byte const* compact) noexcept
|
||||
{
|
||||
static auto constexpr Addr6Len = size_t{ 16 };
|
||||
|
||||
auto address = tr_address{};
|
||||
address.type = TR_AF_INET6;
|
||||
std::copy_n(compact, Addr6Len, reinterpret_cast<uint8_t*>(&address.addr.addr6.s6_addr));
|
||||
std::copy_n(compact, Addr6Len, reinterpret_cast<std::byte*>(&address.addr.addr6.s6_addr));
|
||||
compact += Addr6Len;
|
||||
|
||||
return std::make_pair(address, compact);
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include <algorithm> // for std::copy_n
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint8_t
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
hport_ = ntohs(nport);
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::pair<tr_port, uint8_t const*> fromCompact(uint8_t const* compact) noexcept;
|
||||
[[nodiscard]] static std::pair<tr_port, std::byte const*> fromCompact(std::byte const* compact) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr auto operator<(tr_port const& that) const noexcept
|
||||
{
|
||||
|
@ -154,8 +154,8 @@ 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, uint8_t const*> fromCompact4(uint8_t const* compact) noexcept;
|
||||
[[nodiscard]] static std::pair<tr_address, uint8_t const*> fromCompact6(uint8_t const* compact) noexcept;
|
||||
[[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;
|
||||
|
||||
// human-readable formatting
|
||||
template<typename OutputIt>
|
||||
|
@ -163,6 +163,61 @@ struct tr_address
|
|||
std::string_view readable(char* out, size_t outlen, tr_port port = {}) const;
|
||||
[[nodiscard]] std::string readable(tr_port port = {}) const;
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact4(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);
|
||||
out = std::copy_n(reinterpret_cast<std::byte const*>(&nport), sizeof(nport), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact4(OutputIt out, sockaddr_in const* sa4)
|
||||
{
|
||||
return toCompact4(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)
|
||||
{
|
||||
auto const nport = port.network();
|
||||
out = std::copy_n(reinterpret_cast<std::byte const*>(addr6), sizeof(*addr6), out);
|
||||
out = std::copy_n(reinterpret_cast<std::byte const*>(&nport), sizeof(nport), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact6(OutputIt out, sockaddr_in6 const* sa6)
|
||||
{
|
||||
return toCompact6(out, &sa6->sin6_addr, tr_port::fromNetwork(sa6->sin6_port));
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
OutputIt toCompact4(OutputIt out, tr_port port) const
|
||||
{
|
||||
return toCompact4(out, &this->addr.addr4, port);
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
OutputIt toCompact6(OutputIt out, tr_port port) const
|
||||
{
|
||||
return toCompact6(out, &this->addr.addr6, port);
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact(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));
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact(OutputIt out, struct sockaddr_storage* ss)
|
||||
{
|
||||
return toCompact(out, reinterpret_cast<struct sockaddr*>(ss));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto isIPv4() const noexcept
|
||||
{
|
||||
return type == TR_AF_INET;
|
||||
|
|
|
@ -1297,10 +1297,10 @@ size_t tr_peerMgrAddPex(tr_torrent* tor, uint8_t from, tr_pex const* pex, size_t
|
|||
return n_used;
|
||||
}
|
||||
|
||||
std::vector<tr_pex> tr_peerMgrCompactToPex(void const* compact, size_t compact_len, uint8_t const* added_f, size_t added_f_len)
|
||||
std::vector<tr_pex> tr_pex::fromCompact4(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<uint8_t const*>(compact);
|
||||
auto const* walk = static_cast<std::byte const*>(compact);
|
||||
auto pex = std::vector<tr_pex>(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
|
@ -1317,10 +1317,10 @@ std::vector<tr_pex> tr_peerMgrCompactToPex(void const* compact, size_t compact_l
|
|||
return pex;
|
||||
}
|
||||
|
||||
std::vector<tr_pex> tr_peerMgrCompact6ToPex(void const* compact, size_t compact_len, uint8_t const* added_f, size_t added_f_len)
|
||||
std::vector<tr_pex> tr_pex::fromCompact6(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<uint8_t const*>(compact);
|
||||
auto const* walk = static_cast<std::byte const*>(compact);
|
||||
auto pex = std::vector<tr_pex>(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
|
|
|
@ -64,6 +64,50 @@ struct tr_pex
|
|||
{
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
OutputIt toCompact4(OutputIt out) const
|
||||
{
|
||||
return this->addr.toCompact4(out, this->port);
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
OutputIt toCompact6(OutputIt out) const
|
||||
{
|
||||
return this->addr.toCompact6(out, this->port);
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact4(OutputIt out, tr_pex const* pex, size_t n_pex)
|
||||
{
|
||||
for (size_t i = 0; i < n_pex; ++i)
|
||||
{
|
||||
out = pex[i].toCompact4(out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename OutputIt>
|
||||
static OutputIt toCompact6(OutputIt out, tr_pex const* pex, size_t n_pex)
|
||||
{
|
||||
for (size_t i = 0; i < n_pex; ++i)
|
||||
{
|
||||
out = pex[i].toCompact6(out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<tr_pex> fromCompact4(
|
||||
void const* compact,
|
||||
size_t compact_len,
|
||||
uint8_t const* added_f,
|
||||
size_t added_f_len);
|
||||
|
||||
[[nodiscard]] static std::vector<tr_pex> fromCompact6(
|
||||
void const* compact,
|
||||
size_t compact_len,
|
||||
uint8_t const* added_f,
|
||||
size_t added_f_len);
|
||||
|
||||
template<typename OutputIt>
|
||||
[[nodiscard]] OutputIt readable(OutputIt out) const
|
||||
{
|
||||
|
@ -128,18 +172,6 @@ void tr_peerMgrClientSentRequests(tr_torrent* torrent, tr_peer* peer, tr_block_s
|
|||
|
||||
void tr_peerMgrAddIncoming(tr_peerMgr* manager, tr_address const& addr, tr_port port, struct tr_peer_socket const socket);
|
||||
|
||||
[[nodiscard]] std::vector<tr_pex> tr_peerMgrCompactToPex(
|
||||
void const* compact,
|
||||
size_t compact_len,
|
||||
uint8_t const* added_f,
|
||||
size_t added_f_len);
|
||||
|
||||
[[nodiscard]] std::vector<tr_pex> tr_peerMgrCompact6ToPex(
|
||||
void const* compact,
|
||||
size_t compact_len,
|
||||
uint8_t const* added_f,
|
||||
size_t added_f_len);
|
||||
|
||||
size_t tr_peerMgrAddPex(tr_torrent* tor, uint8_t from, tr_pex const* pex, size_t n_pex);
|
||||
|
||||
void tr_peerMgrSetSwarmIsAllSeeds(tr_torrent* tor);
|
||||
|
|
|
@ -806,7 +806,7 @@ static void protocolSendPort(tr_peerMsgsImpl* msgs, tr_port port)
|
|||
logtrace(msgs, fmt::format(FMT_STRING("sending Port {:d}"), port.host()));
|
||||
out.addUint32(3);
|
||||
out.addUint8(BtPeerMsgs::Port);
|
||||
out.addUint16(port.network());
|
||||
out.addPort(port);
|
||||
}
|
||||
|
||||
static void protocolSendHave(tr_peerMsgsImpl* msgs, tr_piece_index_t index)
|
||||
|
@ -1221,7 +1221,7 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen)
|
|||
added_f = nullptr;
|
||||
}
|
||||
|
||||
auto pex = tr_peerMgrCompactToPex(added, added_len, added_f, added_f_len);
|
||||
auto pex = tr_pex::fromCompact4(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));
|
||||
}
|
||||
|
@ -1236,7 +1236,7 @@ static void parseUtPex(tr_peerMsgsImpl* msgs, uint32_t msglen)
|
|||
added_f = nullptr;
|
||||
}
|
||||
|
||||
auto pex = tr_peerMgrCompact6ToPex(added, added_len, added_f, added_f_len);
|
||||
auto pex = tr_pex::fromCompact6(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));
|
||||
}
|
||||
|
@ -2288,33 +2288,25 @@ void tr_peerMsgsImpl::sendPex()
|
|||
auto val = tr_variant{};
|
||||
tr_variantInitDict(&val, 3); /* ipv6 support: left as 3: speed vs. likelihood? */
|
||||
|
||||
auto tmpbuf = std::vector<uint8_t>{};
|
||||
auto tmpbuf = std::vector<std::byte>{};
|
||||
tmpbuf.reserve(MaxPexAdded * 18);
|
||||
|
||||
if (!std::empty(added))
|
||||
{
|
||||
// "added"
|
||||
tmpbuf.resize(std::size(added) * 6U);
|
||||
auto* begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : added)
|
||||
{
|
||||
memcpy(walk, &p.addr.addr, 4U);
|
||||
walk += 4U;
|
||||
memcpy(walk, &p.port, 2U);
|
||||
walk += 2U;
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(added) * 6U);
|
||||
tr_variantDictAddRaw(&val, TR_KEY_added, begin, walk - begin);
|
||||
tmpbuf.clear();
|
||||
tr_pex::toCompact4(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));
|
||||
|
||||
// "added.f"
|
||||
// unset each holepunch flag because we don't support it.
|
||||
tmpbuf.resize(std::size(added));
|
||||
begin = std::data(tmpbuf);
|
||||
walk = begin;
|
||||
auto* begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : added)
|
||||
{
|
||||
*walk++ = p.flags & ~ADDED_F_HOLEPUNCH;
|
||||
*walk++ = std::byte{ p.flags } & ~std::byte{ ADDED_F_HOLEPUNCH };
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(added));
|
||||
|
@ -2324,46 +2316,27 @@ void tr_peerMsgsImpl::sendPex()
|
|||
if (!std::empty(dropped))
|
||||
{
|
||||
// "dropped"
|
||||
tmpbuf.resize(std::size(dropped) * 6U);
|
||||
auto* begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : dropped)
|
||||
{
|
||||
memcpy(walk, &p.addr.addr, 4U);
|
||||
walk += 4U;
|
||||
memcpy(walk, &p.port, 2U);
|
||||
walk += 2U;
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(dropped) * 6U);
|
||||
tr_variantDictAddRaw(&val, TR_KEY_dropped, begin, walk - begin);
|
||||
tmpbuf.clear();
|
||||
tr_pex::toCompact4(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));
|
||||
}
|
||||
|
||||
if (!std::empty(added6))
|
||||
{
|
||||
// "added6"
|
||||
tmpbuf.resize(std::size(added6) * 18U);
|
||||
auto* begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : added6)
|
||||
{
|
||||
memcpy(walk, &p.addr.addr.addr6.s6_addr, 16U);
|
||||
walk += 16U;
|
||||
memcpy(walk, &p.port, 2U);
|
||||
walk += 2U;
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(added6) * 18U);
|
||||
tr_variantDictAddRaw(&val, TR_KEY_added6, begin, walk - begin);
|
||||
tmpbuf.clear();
|
||||
tr_pex::toCompact6(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));
|
||||
|
||||
// "added6.f"
|
||||
// unset each holepunch flag because we don't support it.
|
||||
tmpbuf.resize(std::size(added6));
|
||||
begin = std::data(tmpbuf);
|
||||
walk = begin;
|
||||
auto* begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : added6)
|
||||
{
|
||||
*walk++ = p.flags & ~ADDED_F_HOLEPUNCH;
|
||||
*walk++ = std::byte{ p.flags } & ~std::byte{ ADDED_F_HOLEPUNCH };
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(added6));
|
||||
|
@ -2373,19 +2346,10 @@ void tr_peerMsgsImpl::sendPex()
|
|||
if (!std::empty(dropped6))
|
||||
{
|
||||
// "dropped6"
|
||||
tmpbuf.resize(std::size(dropped6) * 18U);
|
||||
auto* const begin = std::data(tmpbuf);
|
||||
auto* walk = begin;
|
||||
for (auto const& p : dropped6)
|
||||
{
|
||||
memcpy(walk, &p.addr.addr.addr6.s6_addr, 16U);
|
||||
walk += 16U;
|
||||
memcpy(walk, &p.port, 2U);
|
||||
walk += 2U;
|
||||
}
|
||||
|
||||
TR_ASSERT(static_cast<size_t>(walk - begin) == std::size(dropped6) * 18U);
|
||||
tr_variantDictAddRaw(&val, TR_KEY_dropped6, begin, walk - begin);
|
||||
tmpbuf.clear();
|
||||
tr_pex::toCompact6(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));
|
||||
}
|
||||
|
||||
/* write the pex message */
|
||||
|
|
|
@ -302,6 +302,12 @@ public:
|
|||
add(&ch, 1);
|
||||
}
|
||||
|
||||
void addPort(tr_port const& port)
|
||||
{
|
||||
auto nport = port.network();
|
||||
add(&nport, sizeof(nport));
|
||||
}
|
||||
|
||||
void addUint8(uint8_t uch)
|
||||
{
|
||||
add(&uch, 1);
|
||||
|
|
|
@ -342,7 +342,7 @@ static void bootstrapFromFile(std::string_view config_dir)
|
|||
}
|
||||
}
|
||||
|
||||
static void bootstrapStart(std::string_view config_dir, std::vector<uint8_t> nodes4, std::vector<uint8_t> nodes6)
|
||||
static void bootstrapStart(std::string_view config_dir, std::vector<std::byte> nodes4, std::vector<std::byte> nodes6)
|
||||
{
|
||||
if (!tr_dhtEnabled())
|
||||
{
|
||||
|
@ -452,8 +452,8 @@ int tr_dhtInit(tr_session* session, tr_socket_t udp4_socket, tr_socket_t udp6_so
|
|||
auto const ok = tr_variantFromFile(&benc, TR_VARIANT_PARSE_BENC, dat_file.sv());
|
||||
|
||||
bool have_id = false;
|
||||
auto nodes = std::vector<uint8_t>{};
|
||||
auto nodes6 = std::vector<uint8_t>{};
|
||||
auto nodes = std::vector<std::byte>{};
|
||||
auto nodes6 = std::vector<std::byte>{};
|
||||
|
||||
if (ok)
|
||||
{
|
||||
|
@ -465,7 +465,7 @@ int tr_dhtInit(tr_session* session, tr_socket_t udp4_socket, tr_socket_t udp6_so
|
|||
}
|
||||
|
||||
size_t raw_len = 0U;
|
||||
uint8_t const* raw = nullptr;
|
||||
std::byte const* raw = nullptr;
|
||||
|
||||
if (tr_variantDictFindRaw(&benc, TR_KEY_nodes, &raw, &raw_len) && raw_len % 6 == 0)
|
||||
{
|
||||
|
@ -643,8 +643,8 @@ static void callback(void* vsession, int event, unsigned char const* info_hash,
|
|||
{
|
||||
if (tor != nullptr && tor->allowsDht())
|
||||
{
|
||||
auto const pex = event == DHT_EVENT_VALUES ? tr_peerMgrCompactToPex(data, data_len, nullptr, 0) :
|
||||
tr_peerMgrCompact6ToPex(data, data_len, nullptr, 0);
|
||||
auto const pex = event == DHT_EVENT_VALUES ? tr_pex::fromCompact4(data, data_len, nullptr, 0) :
|
||||
tr_pex::fromCompact6(data, data_len, nullptr, 0);
|
||||
tr_peerMgrAddPex(tor, TR_PEER_FROM_DHT, std::data(pex), std::size(pex));
|
||||
tr_logAddDebugTor(
|
||||
tor,
|
||||
|
|
|
@ -246,6 +246,19 @@ bool tr_variantGetStrView(tr_variant const* v, std::string_view* setme)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_variantGetRaw(tr_variant const* v, std::byte const** setme_raw, size_t* setme_len)
|
||||
{
|
||||
bool const success = tr_variantIsString(v);
|
||||
|
||||
if (success)
|
||||
{
|
||||
*setme_raw = (std::byte const*)getStr(v);
|
||||
*setme_len = v->val.s.len;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool tr_variantGetRaw(tr_variant const* v, uint8_t const** setme_raw, size_t* setme_len)
|
||||
{
|
||||
bool const success = tr_variantIsString(v);
|
||||
|
@ -358,7 +371,13 @@ bool tr_variantDictFindDict(tr_variant* dict, tr_quark const key, tr_variant** s
|
|||
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, uint8_t const** setme_raw, size_t* setme_len)
|
||||
{
|
||||
tr_variant const* child = tr_variantDictFind(dict, key);
|
||||
auto const* child = tr_variantDictFind(dict, key);
|
||||
return tr_variantGetRaw(child, setme_raw, setme_len);
|
||||
}
|
||||
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, std::byte const** setme_raw, size_t* setme_len)
|
||||
{
|
||||
auto const* child = tr_variantDictFind(dict, key);
|
||||
return tr_variantGetRaw(child, setme_raw, setme_len);
|
||||
}
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ void tr_variantInitStrView(tr_variant* initme, std::string_view);
|
|||
void tr_variantInitQuark(tr_variant* initme, tr_quark const quark);
|
||||
void tr_variantInitRaw(tr_variant* initme, void const* raw, size_t raw_len);
|
||||
|
||||
bool tr_variantGetRaw(tr_variant const* variant, std::byte const** setme_raw, size_t* setme_len);
|
||||
bool tr_variantGetRaw(tr_variant const* variant, uint8_t const** setme_raw, size_t* setme_len);
|
||||
|
||||
/***
|
||||
|
@ -275,6 +276,7 @@ bool tr_variantDictFindReal(tr_variant* dict, tr_quark const key, double* setme)
|
|||
bool tr_variantDictFindBool(tr_variant* dict, tr_quark const key, bool* setme);
|
||||
bool tr_variantDictFindStrView(tr_variant* dict, tr_quark const key, std::string_view* setme);
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, uint8_t const** setme_raw, size_t* setme_len);
|
||||
bool tr_variantDictFindRaw(tr_variant* dict, tr_quark const key, std::byte const** setme_raw, size_t* setme_len);
|
||||
|
||||
/* this is only quasi-supported. don't rely on it too heavily outside of libT */
|
||||
void tr_variantMergeDicts(tr_variant* dict_target, tr_variant const* dict_source);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "transmission.h"
|
||||
|
||||
#include "net.h"
|
||||
#include "peer-mgr.h"
|
||||
|
||||
#include "test-fixtures.h"
|
||||
|
||||
|
@ -30,3 +31,108 @@ TEST_F(NetTest, conversionsIPv4)
|
|||
EXPECT_EQ(addr, addrport->first);
|
||||
EXPECT_EQ(Port, addrport->second);
|
||||
}
|
||||
|
||||
TEST_F(NetTest, compact4)
|
||||
{
|
||||
static auto constexpr ExpectedReadable = "10.10.10.5"sv;
|
||||
static auto constexpr ExpectedPort = tr_port::fromHost(128);
|
||||
static auto constexpr Compact4 = std::array<std::byte, 6>{ std::byte{ 0x0A }, std::byte{ 0x0A }, std::byte{ 0x0A },
|
||||
std::byte{ 0x05 }, std::byte{ 0x00 }, std::byte{ 0x80 } };
|
||||
|
||||
/// compact <--> tr_address, port
|
||||
|
||||
// extract the address and port from a compact stream...
|
||||
auto in = std::data(Compact4);
|
||||
auto addr = tr_address{};
|
||||
auto port = tr_port{};
|
||||
std::tie(addr, in) = tr_address::fromCompact4(in);
|
||||
std::tie(port, in) = tr_port::fromCompact(in);
|
||||
EXPECT_EQ(std::data(Compact4) + std::size(Compact4), in);
|
||||
EXPECT_EQ(ExpectedReadable, addr.readable());
|
||||
EXPECT_EQ(ExpectedPort, port);
|
||||
|
||||
// ...serialize it back again
|
||||
auto compact4 = std::array<std::byte, 6>{};
|
||||
auto out = std::data(compact4);
|
||||
out = addr.toCompact4(out, port);
|
||||
EXPECT_EQ(std::size(Compact4), out - std::data(compact4));
|
||||
EXPECT_EQ(Compact4, compact4);
|
||||
|
||||
/// sockaddr --> compact
|
||||
|
||||
auto [ss, sslen] = addr.toSockaddr(port);
|
||||
std::fill(std::begin(compact4), std::end(compact4), std::byte{});
|
||||
out = std::data(compact4);
|
||||
out = tr_address::toCompact(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);
|
||||
ASSERT_EQ(1U, std::size(pex));
|
||||
EXPECT_EQ(addr, pex.front().addr);
|
||||
EXPECT_EQ(port, pex.front().port);
|
||||
|
||||
// ...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));
|
||||
EXPECT_EQ(std::data(compact4) + std::size(compact4), out);
|
||||
EXPECT_EQ(Compact4, compact4);
|
||||
}
|
||||
|
||||
TEST_F(NetTest, compact6)
|
||||
{
|
||||
static auto constexpr ExpectedReadable = "1002:1035:4527:3546:7854:1237:3247:3217"sv;
|
||||
static auto constexpr ExpectedPort = tr_port::fromHost(6881);
|
||||
static auto constexpr Compact6 = std::array<std::byte, 18>{
|
||||
std::byte{ 0x10 }, std::byte{ 0x02 }, std::byte{ 0x10 }, std::byte{ 0x35 }, std::byte{ 0x45 }, std::byte{ 0x27 },
|
||||
std::byte{ 0x35 }, std::byte{ 0x46 }, std::byte{ 0x78 }, std::byte{ 0x54 }, std::byte{ 0x12 }, std::byte{ 0x37 },
|
||||
std::byte{ 0x32 }, std::byte{ 0x47 }, std::byte{ 0x32 }, std::byte{ 0x17 }, std::byte{ 0x1A }, std::byte{ 0xE1 }
|
||||
};
|
||||
|
||||
/// compact <--> tr_address, tr_port
|
||||
|
||||
// extract the address and port from a compact stream...
|
||||
auto in = std::data(Compact6);
|
||||
auto addr = tr_address{};
|
||||
auto port = tr_port{};
|
||||
std::tie(addr, in) = tr_address::fromCompact6(in);
|
||||
std::tie(port, in) = tr_port::fromCompact(in);
|
||||
EXPECT_EQ(std::data(Compact6) + std::size(Compact6), in);
|
||||
EXPECT_EQ(ExpectedReadable, addr.readable());
|
||||
EXPECT_EQ(ExpectedPort, port);
|
||||
|
||||
// ...serialize it back again
|
||||
auto compact6 = std::array<std::byte, 18>{};
|
||||
auto out = std::data(compact6);
|
||||
out = addr.toCompact6(out, port);
|
||||
EXPECT_EQ(std::size(Compact6), out - std::data(compact6));
|
||||
EXPECT_EQ(Compact6, compact6);
|
||||
|
||||
/// sockaddr --> compact
|
||||
|
||||
auto [ss, sslen] = addr.toSockaddr(port);
|
||||
std::fill(std::begin(compact6), std::end(compact6), std::byte{});
|
||||
out = std::data(compact6);
|
||||
out = tr_address::toCompact(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);
|
||||
ASSERT_EQ(1U, std::size(pex));
|
||||
EXPECT_EQ(addr, pex.front().addr);
|
||||
EXPECT_EQ(port, pex.front().port);
|
||||
|
||||
// ...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));
|
||||
EXPECT_EQ(std::data(compact6) + std::size(compact6), out);
|
||||
EXPECT_EQ(Compact6, compact6);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue