fix: encode `ip` in network byte order for udp announce (#6126)

This commit is contained in:
Yat Ho 2023-10-18 22:46:57 +08:00 committed by GitHub
parent 0c3f65e1c6
commit c70c49e87b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 19 deletions

View File

@ -169,7 +169,10 @@ private:
struct tau_announce_request
{
tau_announce_request(uint32_t announce_ip, tr_announce_request const& in, tr_announce_response_func on_response)
tau_announce_request(
std::optional<tr_address> announce_ip,
tr_announce_request const& in,
tr_announce_response_func on_response)
: on_response_{ std::move(on_response) }
{
// https://www.bittorrent.org/beps/bep_0015.html sets key size at 32 bits
@ -187,7 +190,14 @@ struct tau_announce_request
buf.add_uint64(in.leftUntilComplete);
buf.add_uint64(in.up);
buf.add_uint32(get_tau_announce_event(in.event));
buf.add_uint32(announce_ip);
if (announce_ip && announce_ip->is_ipv4())
{
buf.add_address(*announce_ip);
}
else
{
buf.add_uint32(0U);
}
buf.add_uint32(in.key);
buf.add_uint32(in.numwant);
buf.add_port(in.port);
@ -585,9 +595,7 @@ public:
}
// Since size of IP field is only 4 bytes long, we can only announce IPv4 addresses
auto const addr = mediator_.announce_ip();
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->announces.emplace_back(mediator_.announce_ip(), request, std::move(on_response));
tracker->upkeep(false);
}

View File

@ -181,13 +181,13 @@ struct tr_address
template<typename OutputIt>
static OutputIt to_compact_ipv4(OutputIt out, in_addr const& addr4)
{
return std::copy_n(reinterpret_cast<std::byte const*>(&addr4), sizeof(addr4), out);
return std::copy_n(reinterpret_cast<std::byte const*>(&addr4.s_addr), sizeof(addr4.s_addr), out);
}
template<typename OutputIt>
static OutputIt to_compact_ipv6(OutputIt out, in6_addr const& addr6)
{
return std::copy_n(reinterpret_cast<std::byte const*>(&addr6), sizeof(addr6), out);
return std::copy_n(reinterpret_cast<std::byte const*>(&addr6.s6_addr), sizeof(addr6.s6_addr), out);
}
template<typename OutputIt>

View File

@ -160,35 +160,32 @@ public:
void add_uint16(uint16_t hs)
{
uint16_t const ns = htons(hs);
add(&ns, sizeof(ns));
add_uint16_n(htons(hs));
}
void add_hton16(uint16_t hs)
void add_uint16_n(uint16_t ns)
{
add_uint16(hs);
add(&ns, sizeof(ns));
}
void add_uint32(uint32_t hl)
{
uint32_t const nl = htonl(hl);
add(&nl, sizeof(nl));
add_uint32_n(htonl(hl));
}
void eadd_hton32(uint32_t hl)
void add_uint32_n(uint32_t nl)
{
add_uint32(hl);
add(&nl, sizeof(nl));
}
void add_uint64(uint64_t hll)
{
uint64_t const nll = tr_htonll(hll);
add(&nll, sizeof(nll));
add_uint64_n(tr_htonll(hll));
}
void add_hton64(uint64_t hll)
void add_uint64_n(uint64_t nll)
{
add_uint64(hll);
add(&nll, sizeof(nll));
}
void add_port(tr_port port)
@ -197,6 +194,22 @@ public:
add(&nport, sizeof(nport));
}
void add_address(tr_address const& addr)
{
switch (addr.type)
{
case TR_AF_INET:
add(&addr.addr.addr4.s_addr, sizeof(addr.addr.addr4.s_addr));
break;
case TR_AF_INET6:
add(&addr.addr.addr6.s6_addr, sizeof(addr.addr.addr6.s6_addr));
break;
default:
TR_ASSERT_MSG(false, "invalid type");
break;
}
}
size_t add_socket(tr_socket_t sockfd, size_t n_bytes, tr_error** error = nullptr)
{
auto const [buf, buflen] = reserve_space(n_bytes);