Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 13 additions & 5 deletions libtransmission/announcer-udp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ struct tau_scrape_request

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
Expand All @@ -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);
Expand Down Expand Up @@ -585,9 +595,7 @@ class tr_announcer_udp_impl final : public tr_announcer_udp
}

// 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);
}

Expand Down
4 changes: 2 additions & 2 deletions libtransmission/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
37 changes: 25 additions & 12 deletions libtransmission/tr-buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,35 +160,32 @@ class BufferWriter

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)
Expand All @@ -197,6 +194,22 @@ class BufferWriter
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);
Expand Down