diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc index 20e09ad62..f26c80f33 100644 --- a/libtransmission/announcer-udp.cc +++ b/libtransmission/announcer-udp.cc @@ -166,7 +166,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 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); @@ -588,9 +598,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->is_ipv4() ? addr->addr.addr4.s_addr : 0; - tracker->announces.emplace_back(announce_ip, request, std::move(on_response)); + tracker->announces.emplace_back(mediator_.announceIP(), request, std::move(on_response)); tracker->upkeep(false); } diff --git a/libtransmission/tr-buffer.h b/libtransmission/tr-buffer.h index cbb912ab9..ed0072cce 100644 --- a/libtransmission/tr-buffer.h +++ b/libtransmission/tr-buffer.h @@ -16,6 +16,7 @@ #include "error.h" #include "net.h" // tr_socket_t +#include "tr-assert.h" #include "utils-ev.h" #include "utils.h" // for tr_htonll(), tr_ntohll() @@ -355,6 +356,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; + } + } + void add_uint8(uint8_t uch) { add(&uch, 1);