From 80f01dbfd9b8423e2fb1e05e92b5358e969af065 Mon Sep 17 00:00:00 2001 From: stickz Date: Fri, 19 Jul 2024 19:24:51 -0400 Subject: [PATCH] libtorrent: Add m_tracker_udp_list (#39) We can't send UDP tracker object references through std:bind() because it copies them, resulting in memory address errors. So we need to store them higher up in the connection manager, where they are always valid. --- libtorrent/src/torrent/connection_manager.cc | 6 +++--- libtorrent/src/torrent/connection_manager.h | 9 ++++++++- libtorrent/src/tracker/tracker_udp.cc | 7 ++++++- libtorrent/src/tracker/tracker_udp.h | 4 ++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/libtorrent/src/torrent/connection_manager.cc b/libtorrent/src/torrent/connection_manager.cc index 1b9ba531..82d88308 100644 --- a/libtorrent/src/torrent/connection_manager.cc +++ b/libtorrent/src/torrent/connection_manager.cc @@ -79,9 +79,9 @@ class UdnsAsyncResolver : public AsyncResolver { }; void -ConnectionManager::start_udp_announce(TrackerUdp *tracker, const sockaddr* sa, int err) { - if (tracker != NULL) { - tracker->start_announce(sa, err); +ConnectionManager::start_udp_announce(uint64_t idx, const sockaddr* sa, int err) { + if (m_tracker_udp_list[idx] != NULL) { + m_tracker_udp_list[idx]->start_announce(sa, err); } } diff --git a/libtorrent/src/torrent/connection_manager.h b/libtorrent/src/torrent/connection_manager.h index b7a06dc2..ee64b29b 100644 --- a/libtorrent/src/torrent/connection_manager.h +++ b/libtorrent/src/torrent/connection_manager.h @@ -187,7 +187,10 @@ class LIBTORRENT_EXPORT ConnectionManager { void cancel_async_resolve(void *query); #ifdef USE_UDNS - void start_udp_announce(TrackerUdp *tracker, const sockaddr* sa, int err); + void start_udp_announce(uint64_t idx, const sockaddr* sa, int err); + void null_udp_tracker(uint64_t idx) { m_tracker_udp_list[idx] = NULL; } + void add_udp_tracker(TrackerUdp* tracker) { m_tracker_udp_list.push_back(tracker); } + uint64_t get_udp_tracker_count() { return m_tracker_udp_list.size(); } #endif // Legacy synchronous resolver interface. @@ -227,6 +230,10 @@ class LIBTORRENT_EXPORT ConnectionManager { slot_resolver_type m_slot_resolver; slot_throttle_type m_slot_address_throttle; +#ifdef USE_UDNS + std::vector m_tracker_udp_list; +#endif + std::unique_ptr m_async_resolver; }; diff --git a/libtorrent/src/tracker/tracker_udp.cc b/libtorrent/src/tracker/tracker_udp.cc index 2e8f6152..5d611522 100644 --- a/libtorrent/src/tracker/tracker_udp.cc +++ b/libtorrent/src/tracker/tracker_udp.cc @@ -77,7 +77,9 @@ TrackerUdp::TrackerUdp(TrackerList* parent, rak::udp_tracker_info& info, int fla m_taskTimeout.slot() = std::bind(&TrackerUdp::receive_timeout, this); #ifdef USE_UDNS - m_resolver_callback = std::bind(&ConnectionManager::start_udp_announce, manager->connection_manager(), this, std::placeholders::_1, std::placeholders::_2); + manager->connection_manager()->add_udp_tracker(this); + m_vec_idx = manager->connection_manager()->get_udp_tracker_count() - 1; + m_resolver_callback = std::bind(&ConnectionManager::start_udp_announce, manager->connection_manager(), m_vec_idx, std::placeholders::_1, std::placeholders::_2); #else m_resolver_callback = std::bind(&TrackerUdp::start_announce, this, std::placeholders::_1, std::placeholders::_2); #endif @@ -86,6 +88,9 @@ TrackerUdp::TrackerUdp(TrackerList* parent, rak::udp_tracker_info& info, int fla } TrackerUdp::~TrackerUdp() { +#ifdef USE_UDNS + manager->connection_manager()->null_udp_tracker(m_vec_idx); +#endif close_directly(); } diff --git a/libtorrent/src/tracker/tracker_udp.h b/libtorrent/src/tracker/tracker_udp.h index 697f4493..6adc00ab 100644 --- a/libtorrent/src/tracker/tracker_udp.h +++ b/libtorrent/src/tracker/tracker_udp.h @@ -105,6 +105,10 @@ class TrackerUdp : public SocketDatagram, public Tracker { uint32_t m_action; uint64_t m_connectionId; uint32_t m_transactionId; + +#ifdef USE_UDNS + uint64_t m_vec_idx; +#endif ReadBuffer* m_readBuffer; WriteBuffer* m_writeBuffer;