From 85e8799fe0b14918472bd481c185e8430bd477a8 Mon Sep 17 00:00:00 2001 From: Jari Sundell Date: Tue, 11 Feb 2025 08:15:17 +0100 Subject: [PATCH] Added TrackerController to TrackerManager. --- src/download/download_main.cc | 57 ++++++----- src/download/download_main.h | 28 ++--- src/download/download_wrapper.cc | 38 ++++--- src/manager.cc | 94 ++++++++--------- src/manager.h | 58 ++++++----- src/torrent/Makefile.am | 14 +-- src/torrent/common.h | 39 +------ src/torrent/download.cc | 129 +++++++++--------------- src/torrent/download.h | 42 +------- src/torrent/download_info.h | 42 +------- src/torrent/hash_string.h | 45 ++------- src/torrent/tracker/tracker_manager.cc | 33 +++--- src/torrent/tracker/tracker_manager.h | 47 ++------- src/torrent/tracker/tracker_wrappers.cc | 111 ++++++++++++++++++++ src/torrent/tracker/tracker_wrappers.h | 119 ++++++++++++++++++++++ src/torrent/tracker_list.cc | 6 +- src/tracker/tracker_http.cc | 18 ++-- 17 files changed, 483 insertions(+), 437 deletions(-) create mode 100644 src/torrent/tracker/tracker_wrappers.cc create mode 100644 src/torrent/tracker/tracker_wrappers.h diff --git a/src/download/download_main.cc b/src/download/download_main.cc index 1369ceb0a..c885bb74f 100644 --- a/src/download/download_main.cc +++ b/src/download/download_main.cc @@ -1,9 +1,16 @@ #include "config.h" +#include "download/download_main.h" + +#include #include #include #include "data/chunk_list.h" +#include "download/available_list.h" +#include "download/chunk_selector.h" +#include "download/chunk_statistics.h" +#include "download/download_wrapper.h" #include "protocol/extensions.h" #include "protocol/handshake_manager.h" #include "protocol/initial_seed.h" @@ -21,14 +28,9 @@ #include "torrent/peer/peer_info.h" #include "torrent/tracker_controller.h" #include "torrent/tracker_list.h" +#include "torrent/tracker/tracker_manager.h" #include "torrent/utils/log.h" -#include "available_list.h" -#include "chunk_selector.h" -#include "chunk_statistics.h" -#include "download_main.h" -#include "download_wrapper.h" - #define LT_LOG_THIS(log_level, log_fmt, ...) \ lt_log_print_info(LOG_TORRENT_##log_level, m_ptr->info(), "download", log_fmt, __VA_ARGS__); @@ -40,13 +42,13 @@ DownloadInfo::DownloadInfo() : m_upRate(60), m_downRate(60), m_skipRate(60), - + m_uploadedBaseline(0), m_completedBaseline(0), m_sizePex(0), m_maxSizePex(8), m_metadataSize(0), - + m_creationDate(0), m_loadDate(rak::timer::current_seconds()), @@ -56,6 +58,7 @@ DownloadInfo::DownloadInfo() : DownloadMain::DownloadMain() : m_info(new DownloadInfo), + m_tracker_list(new TrackerList), m_choke_group(NULL), m_chunkList(new ChunkList), @@ -66,14 +69,7 @@ DownloadMain::DownloadMain() : m_uploadThrottle(NULL), m_downloadThrottle(NULL) { - m_tracker_list = new TrackerList(); - m_tracker_controller = new TrackerController(m_tracker_list); - - m_tracker_list->slot_success() = std::bind(&TrackerController::receive_success, m_tracker_controller, std::placeholders::_1, std::placeholders::_2); - m_tracker_list->slot_failure() = std::bind(&TrackerController::receive_failure, m_tracker_controller, std::placeholders::_1, std::placeholders::_2); - m_tracker_list->slot_scrape_success() = std::bind(&TrackerController::receive_scrape, m_tracker_controller, std::placeholders::_1); - m_tracker_list->slot_tracker_enabled() = std::bind(&TrackerController::receive_tracker_enabled, m_tracker_controller, std::placeholders::_1); - m_tracker_list->slot_tracker_disabled() = std::bind(&TrackerController::receive_tracker_disabled, m_tracker_controller, std::placeholders::_1); + // Only set trivial values here, the rest is done in DownloadWrapper. m_connectionList = new ConnectionList(this); @@ -94,17 +90,10 @@ DownloadMain::DownloadMain() : } DownloadMain::~DownloadMain() { - if (m_taskTrackerRequest.is_queued()) - throw internal_error("DownloadMain::~DownloadMain(): m_taskTrackerRequest is queued."); - - // Check if needed. - m_connectionList->clear(); - m_tracker_list->clear(); + assert(!m_taskTrackerRequest.is_queued() && "DownloadMain::~DownloadMain(): m_taskTrackerRequest is queued."); - if (m_info->size_pex() != 0) - throw internal_error("DownloadMain::~DownloadMain(): m_info->size_pex() != 0."); + assert(m_info->size_pex() == 0 && "DownloadMain::~DownloadMain(): m_info->size_pex() != 0."); - delete m_tracker_controller; delete m_tracker_list; delete m_connectionList; @@ -117,6 +106,20 @@ DownloadMain::~DownloadMain() { m_ut_pex_initial.clear(); } +void +DownloadMain::post_initialize() { + auto tracker_controller = new TrackerController(m_tracker_list); + + m_tracker_list->slot_success() = std::bind(&TrackerController::receive_success, tracker_controller, std::placeholders::_1, std::placeholders::_2); + m_tracker_list->slot_failure() = std::bind(&TrackerController::receive_failure, tracker_controller, std::placeholders::_1, std::placeholders::_2); + m_tracker_list->slot_scrape_success() = std::bind(&TrackerController::receive_scrape, tracker_controller, std::placeholders::_1); + m_tracker_list->slot_tracker_enabled() = std::bind(&TrackerController::receive_tracker_enabled, tracker_controller, std::placeholders::_1); + m_tracker_list->slot_tracker_disabled() = std::bind(&TrackerController::receive_tracker_disabled, tracker_controller, std::placeholders::_1); + + // TODO: Move tracker list to manager, and add the proper barrier for slots. + m_tracker_controller = manager->tracker_manager()->add_controller(info(), tracker_controller); +} + std::pair DownloadMain::throttles(const sockaddr* sa) { ThrottlePair pair = ThrottlePair(NULL, NULL); @@ -321,11 +324,11 @@ DownloadMain::receive_tracker_request() { if ((info()->is_pex_enabled() && info()->size_pex()) > 0 || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) { - m_tracker_controller->stop_requesting(); + m_tracker_controller.stop_requesting(); return; } - m_tracker_controller->start_requesting(); + m_tracker_controller.start_requesting(); } bool diff --git a/src/download/download_main.h b/src/download/download_main.h index 351bea53c..5e6bee886 100644 --- a/src/download/download_main.h +++ b/src/download/download_main.h @@ -14,6 +14,7 @@ #include "torrent/download/group_entry.h" #include "torrent/data/file_list.h" #include "torrent/peer/peer_list.h" +#include "torrent/tracker/tracker_wrappers.h" namespace torrent { @@ -25,8 +26,6 @@ class choke_group; class ConnectionList; class DownloadWrapper; class HandshakeManager; -class TrackerController; -class TrackerList; class DownloadInfo; class ThrottleList; class InitialSeeding; @@ -39,18 +38,23 @@ class DownloadMain { DownloadMain(); ~DownloadMain(); + DownloadMain(const DownloadMain&) = delete; + void operator = (const DownloadMain&) = delete; + + void post_initialize(); + void open(int flags); void close(); void start(); void stop(); - class choke_group* choke_group() { return m_choke_group; } - const class choke_group* c_choke_group() const { return m_choke_group; } - void set_choke_group(class choke_group* grp) { m_choke_group = grp; } + class choke_group* choke_group() { return m_choke_group; } + const class choke_group* c_choke_group() const { return m_choke_group; } + void set_choke_group(class choke_group* grp) { m_choke_group = grp; } - TrackerController* tracker_controller() { return m_tracker_controller; } - TrackerList* tracker_list() { return m_tracker_list; } + TrackerControllerWrapper tracker_controller() { return m_tracker_controller; } + TrackerList* tracker_list() { return m_tracker_list; } DownloadInfo* info() { return m_info; } @@ -84,7 +88,7 @@ class DownloadMain { DataBuffer get_ut_pex(bool initial) { return (initial ? m_ut_pex_initial : m_ut_pex_delta).clone(); } - bool want_pex_msg() { return m_info->is_pex_active() && m_peerList.available_list()->want_more(); }; + bool want_pex_msg() { return m_info->is_pex_active() && m_peerList.available_list()->want_more(); }; void set_metadata_size(size_t s); @@ -125,17 +129,13 @@ class DownloadMain { rak::priority_item& delay_disconnect_peers() { return m_delayDisconnectPeers; } private: - // Disable copy ctor and assignment. - DownloadMain(const DownloadMain&); - void operator = (const DownloadMain&); - void setup_start(); void setup_stop(); DownloadInfo* m_info; - TrackerController* m_tracker_controller; - TrackerList* m_tracker_list; + TrackerControllerWrapper m_tracker_controller; + TrackerList* m_tracker_list; class choke_group* m_choke_group; diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc index a3530306b..9459b1ff0 100644 --- a/src/download/download_wrapper.cc +++ b/src/download/download_wrapper.cc @@ -1,5 +1,7 @@ #include "config.h" +#include "download/download_wrapper.h" + #include #include #include @@ -7,6 +9,8 @@ #include "data/chunk_list.h" #include "data/hash_queue.h" #include "data/hash_torrent.h" +#include "download/available_list.h" +#include "download/chunk_selector.h" #include "protocol/handshake_manager.h" #include "protocol/peer_connection_base.h" #include "torrent/exceptions.h" @@ -19,14 +23,10 @@ #include "torrent/peer/connection_list.h" #include "torrent/tracker_controller.h" #include "torrent/tracker_list.h" +#include "torrent/tracker/tracker_manager.h" #include "torrent/utils/log.h" #include "utils/functional.h" -#include "available_list.h" -#include "chunk_selector.h" - -#include "download_wrapper.h" - #define LT_LOG_THIS(log_fmt, ...) \ lt_log_print_info(LOG_TORRENT_INFO, this->info(), "download", log_fmt, __VA_ARGS__); #define LT_LOG_STORAGE_ERRORS(log_fmt, ...) \ @@ -47,8 +47,6 @@ DownloadWrapper::DownloadWrapper() : m_main->peer_list()->set_info(info()); m_main->tracker_list()->set_info(info()); - m_main->tracker_controller()->slot_success() = std::bind(&DownloadWrapper::receive_tracker_success, this, std::placeholders::_1); - m_main->tracker_controller()->slot_failure() = std::bind(&DownloadWrapper::receive_tracker_failed, this, std::placeholders::_1); m_main->chunk_list()->slot_storage_error() = std::bind(&DownloadWrapper::receive_storage_error, this, std::placeholders::_1); } @@ -62,7 +60,15 @@ DownloadWrapper::~DownloadWrapper() { // If the client wants to do a quick cleanup after calling close, it // will need to manually cancel the tracker requests. - m_main->tracker_controller()->close(); + m_main->tracker_controller().close(); + + // Check if needed. + m_main->connection_list()->clear(); + m_main->tracker_list()->clear(); + + // TODO: Check first, and return if zero. Need to make the below shared ptrs. + if (info()->hash() != HashString::new_zero()) + manager->tracker_manager()->remove_controller(m_main->tracker_controller()); delete m_hashChecker; delete m_bencode; @@ -92,6 +98,11 @@ DownloadWrapper::initialize(const std::string& hash, const std::string& id) { // Connect various signals and slots. m_hashChecker->slot_check_chunk() = std::bind(&DownloadWrapper::check_chunk_hash, this, std::placeholders::_1); m_hashChecker->delay_checked().slot() = std::bind(&DownloadWrapper::receive_initial_hash, this); + + m_main->post_initialize(); + + m_main->tracker_controller().set_slots([this](auto l) { return receive_tracker_success(l); }, + [this](auto& m) { return receive_tracker_failed(m); }); } void @@ -119,7 +130,7 @@ DownloadWrapper::close() { bool DownloadWrapper::is_stopped() const { - return !m_main->tracker_controller()->is_active() && !m_main->tracker_list()->has_active(); + return !m_main->tracker_controller().is_active() && !m_main->tracker_list()->has_active(); } void @@ -144,7 +155,7 @@ DownloadWrapper::receive_initial_hash() { if (data()->slot_initial_hash()) data()->slot_initial_hash()(); -} +} void DownloadWrapper::receive_hash_done(ChunkHandle handle, const char* hash) { @@ -155,7 +166,6 @@ DownloadWrapper::receive_hash_done(ChunkHandle handle, const char* hash) { throw internal_error("DownloadWrapper::receive_hash_done(...) called but the download is not open."); if (m_hashChecker->is_checking()) { - if (hash == NULL) { m_hashChecker->receive_chunk_cleared(handle.index()); @@ -195,7 +205,7 @@ DownloadWrapper::receive_hash_done(ChunkHandle handle, const char* hash) { priority_queue_erase(&taskScheduler, &m_main->delay_partially_restarted()); priority_queue_update(&taskScheduler, &m_main->delay_partially_done(), cachedTime); } - + if (!m_main->have_queue()->empty() && m_main->have_queue()->front().first >= cachedTime) m_main->have_queue()->emplace_front(m_main->have_queue()->front().first + 1, handle.index()); else @@ -225,8 +235,8 @@ DownloadWrapper::receive_storage_error(const std::string& str) { m_main->stop(); close(); - m_main->tracker_controller()->disable(); - m_main->tracker_controller()->close(); + m_main->tracker_controller().disable(); + m_main->tracker_controller().close(); LT_LOG_STORAGE_ERRORS("%s", str.c_str()); } diff --git a/src/manager.cc b/src/manager.cc index c6ff405c7..e8ea04a7d 100644 --- a/src/manager.cc +++ b/src/manager.cc @@ -21,6 +21,7 @@ #include "torrent/download/resource_manager.h" #include "torrent/peer/client_list.h" #include "torrent/throttle.h" +#include "torrent/tracker/tracker_manager.h" #include "manager.h" @@ -29,61 +30,50 @@ namespace torrent { Manager* manager = NULL; Manager::Manager() : - m_downloadManager(new DownloadManager), - m_fileManager(new FileManager), - m_handshakeManager(new HandshakeManager), - m_resourceManager(new ResourceManager), + m_chunk_manager(new ChunkManager), + m_connection_manager(new ConnectionManager), + m_dht_manager(new DhtManager), + m_download_manager(new DownloadManager), + m_file_manager(new FileManager), + m_handshake_manager(new HandshakeManager), + m_resource_manager(new ResourceManager), + m_tracker_manager(new TrackerManager), - m_chunkManager(new ChunkManager), - m_clientList(new ClientList), - m_connectionManager(new ConnectionManager), - m_dhtManager(new DhtManager), + m_client_list(new ClientList), m_uploadThrottle(Throttle::create_throttle()), m_downloadThrottle(Throttle::create_throttle()), m_ticks(0) { - m_hashQueue = new HashQueue(&m_main_thread_disk); - m_hashQueue->slot_has_work() = - std::bind(&thread_base::send_event_signal, - &m_main_thread_main, - m_main_thread_main.signal_bitfield()->add_signal(std::bind(&HashQueue::work, m_hashQueue)), - std::placeholders::_1); + m_hash_queue = std::make_unique(&m_main_thread_disk); + + auto hash_work_signal = m_main_thread_main.signal_bitfield()->add_signal([hash_queue = m_hash_queue.get()]() { + return hash_queue->work(); + }); + + m_hash_queue->slot_has_work() = [hash_work_signal, thread = &m_main_thread_main](bool is_done) { + thread->send_event_signal(hash_work_signal, is_done); + }; m_taskTick.slot() = std::bind(&Manager::receive_tick, this); priority_queue_insert(&taskScheduler, &m_taskTick, cachedTime.round_seconds()); - m_handshakeManager->slot_download_id() = - std::bind(&DownloadManager::find_main, m_downloadManager, std::placeholders::_1); - m_handshakeManager->slot_download_obfuscated() = - std::bind(&DownloadManager::find_main_obfuscated, m_downloadManager, std::placeholders::_1); - m_connectionManager->listen()->slot_accepted() = - std::bind(&HandshakeManager::add_incoming, m_handshakeManager, std::placeholders::_1, std::placeholders::_2); + m_handshake_manager->slot_download_id() = [this](auto hash) { return m_download_manager->find_main(hash); }; + m_handshake_manager->slot_download_obfuscated() = [this](auto hash) { return m_download_manager->find_main_obfuscated(hash); }; + m_connection_manager->listen()->slot_accepted() = [this](auto fd, auto sa) { return m_handshake_manager->add_incoming(fd, sa); }; - m_resourceManager->push_group("default"); - m_resourceManager->group_back()->up_queue()->set_heuristics(choke_queue::HEURISTICS_UPLOAD_LEECH); - m_resourceManager->group_back()->down_queue()->set_heuristics(choke_queue::HEURISTICS_DOWNLOAD_LEECH); + m_resource_manager->push_group("default"); + m_resource_manager->group_back()->up_queue()->set_heuristics(choke_queue::HEURISTICS_UPLOAD_LEECH); + m_resource_manager->group_back()->down_queue()->set_heuristics(choke_queue::HEURISTICS_DOWNLOAD_LEECH); } Manager::~Manager() { priority_queue_erase(&taskScheduler, &m_taskTick); - m_handshakeManager->clear(); - m_downloadManager->clear(); - - delete m_downloadManager; - delete m_fileManager; - delete m_handshakeManager; - delete m_hashQueue; - - delete m_resourceManager; - delete m_dhtManager; - delete m_connectionManager; - delete m_chunkManager; - - delete m_clientList; + m_handshake_manager->clear(); + m_download_manager->clear(); Throttle::destroy_throttle(m_uploadThrottle); Throttle::destroy_throttle(m_downloadThrottle); @@ -94,20 +84,20 @@ Manager::~Manager() { void Manager::initialize_download(DownloadWrapper* d) { d->main()->slot_count_handshakes([this](DownloadMain* download) { - return m_handshakeManager->size_info(download); + return m_handshake_manager->size_info(download); }); d->main()->slot_start_handshake([this](const rak::socket_address& sa, DownloadMain* download) { - return m_handshakeManager->add_outgoing(sa, download); + return m_handshake_manager->add_outgoing(sa, download); }); d->main()->slot_stop_handshakes([this](DownloadMain* download) { - return m_handshakeManager->erase_download(download); + return m_handshake_manager->erase_download(download); }); // TODO: The resource manager doesn't need to know about this // download until we start/stop the torrent. - m_downloadManager->insert(d); - m_resourceManager->insert(d->main(), 1); - m_chunkManager->insert(d->main()->chunk_list()); + m_download_manager->insert(d); + m_resource_manager->insert(d->main(), 1); + m_chunk_manager->insert(d->main()->chunk_list()); d->main()->chunk_list()->set_chunk_size(d->main()->file_list()->chunk_size()); @@ -120,10 +110,10 @@ Manager::cleanup_download(DownloadWrapper* d) { d->main()->stop(); d->close(); - m_resourceManager->erase(d->main()); - m_chunkManager->erase(d->main()->chunk_list()); + m_resource_manager->erase(d->main()); + m_chunk_manager->erase(d->main()->chunk_list()); - m_downloadManager->erase(d); + m_download_manager->erase(d); } void @@ -133,17 +123,17 @@ Manager::receive_tick() { if (m_ticks % 2 == 0) instrumentation_tick(); - m_resourceManager->receive_tick(); - m_chunkManager->periodic_sync(); + m_resource_manager->receive_tick(); + m_chunk_manager->periodic_sync(); // To ensure the downloads get equal chance over time at using // various limited resources, like sockets for handshakes, cycle the // group in reverse order. - if (!m_downloadManager->empty()) { - auto split = m_downloadManager->end() - m_ticks % m_downloadManager->size() - 1; + if (!m_download_manager->empty()) { + auto split = m_download_manager->end() - m_ticks % m_download_manager->size() - 1; - std::for_each(split, m_downloadManager->end(), [this](auto wrapper) { return wrapper->receive_tick(m_ticks); }); - std::for_each(m_downloadManager->begin(), split, [this](auto wrapper) { return wrapper->receive_tick(m_ticks); }); + std::for_each(split, m_download_manager->end(), [this](auto wrapper) { return wrapper->receive_tick(m_ticks); }); + std::for_each(m_download_manager->begin(), split, [this](auto wrapper) { return wrapper->receive_tick(m_ticks); }); } // If you change the interval, make sure the keepalives gets diff --git a/src/manager.h b/src/manager.h index 6f40f9f21..35e3d2dfe 100644 --- a/src/manager.h +++ b/src/manager.h @@ -2,6 +2,7 @@ #define LIBTORRENT_MANAGER_H #include +#include #include #include @@ -11,20 +12,19 @@ namespace torrent { -class Poll; - -class HashQueue; -class HandshakeManager; +class ChunkManager; +class ConnectionManager; +class DhtManager; class DownloadManager; class DownloadWrapper; -class DownloadMain; class FileManager; -class ResourceManager; +class HashQueue; +class HandshakeManager; class PeerInfo; -class ChunkManager; -class ConnectionManager; +class Poll; +class ResourceManager; +class TrackerManager; class Throttle; -class DhtManager; typedef std::list EncodingList; @@ -33,16 +33,17 @@ class Manager { Manager(); ~Manager(); - DownloadManager* download_manager() { return m_downloadManager; } - FileManager* file_manager() { return m_fileManager; } - HandshakeManager* handshake_manager() { return m_handshakeManager; } - HashQueue* hash_queue() { return m_hashQueue; } - ResourceManager* resource_manager() { return m_resourceManager; } + ChunkManager* chunk_manager() { return m_chunk_manager.get(); } + ConnectionManager* connection_manager() { return m_connection_manager.get(); } + DhtManager* dht_manager() { return m_dht_manager.get(); } + DownloadManager* download_manager() { return m_download_manager.get(); } + FileManager* file_manager() { return m_file_manager.get(); } + HandshakeManager* handshake_manager() { return m_handshake_manager.get(); } + ResourceManager* resource_manager() { return m_resource_manager.get(); } + TrackerManager* tracker_manager() { return m_tracker_manager.get(); } - ChunkManager* chunk_manager() { return m_chunkManager; } - ClientList* client_list() { return m_clientList; } - ConnectionManager* connection_manager() { return m_connectionManager; } - DhtManager* dht_manager() { return m_dhtManager; } + ClientList* client_list() { return m_client_list.get(); } + HashQueue* hash_queue() { return m_hash_queue.get(); } Poll* poll() { return m_main_thread_main.poll(); } @@ -60,16 +61,17 @@ class Manager { void receive_tick(); private: - DownloadManager* m_downloadManager; - FileManager* m_fileManager; - HandshakeManager* m_handshakeManager; - HashQueue* m_hashQueue; - ResourceManager* m_resourceManager; - - ChunkManager* m_chunkManager; - ClientList* m_clientList; - ConnectionManager* m_connectionManager; - DhtManager* m_dhtManager; + std::unique_ptr m_chunk_manager; + std::unique_ptr m_connection_manager; + std::unique_ptr m_dht_manager; + std::unique_ptr m_download_manager; + std::unique_ptr m_file_manager; + std::unique_ptr m_handshake_manager; + std::unique_ptr m_resource_manager; + std::unique_ptr m_tracker_manager; + + std::unique_ptr m_client_list; + std::unique_ptr m_hash_queue; thread_main m_main_thread_main; thread_disk m_main_thread_disk; diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am index ca9cab94f..2bc034d83 100644 --- a/src/torrent/Makefile.am +++ b/src/torrent/Makefile.am @@ -66,6 +66,8 @@ libtorrent_torrent_la_SOURCES = \ tracker/tracker_manager.cc \ tracker/tracker_manager.h \ tracker/tracker_state.h \ + tracker/tracker_wrappers.cc \ + tracker/tracker_wrappers.h \ \ utils/directory_events.cc \ utils/directory_events.h \ @@ -186,6 +188,12 @@ libtorrent_torrent_peer_include_HEADERS = \ peer/peer_info.h \ peer/peer_list.h +libtorrent_torrent_tracker_includedir = $(includedir)/torrent/tracker +libtorrent_torrent_tracker_include_HEADERS = \ + tracker/tracker_manager.h \ + tracker/tracker_state.h \ + tracker/tracker_wrappers.h + libtorrent_torrent_utils_includedir = $(includedir)/torrent/utils libtorrent_torrent_utils_include_HEADERS = \ utils/directory_events.h \ @@ -200,12 +208,6 @@ libtorrent_torrent_utils_include_HEADERS = \ utils/thread_interrupt.h \ utils/uri_parser.h -libtorrent_torrent_tracker_includedir = $(includedir)/torrent/tracker -libtorrent_torrent_tracker_include_HEADERS = \ - tracker/tracker_manager.h \ - tracker/tracker_state.h - - libtorrent_torrent_includedir = $(includedir)/torrent libtorrent_torrent_include_HEADERS = \ bitfield.h \ diff --git a/src/torrent/common.h b/src/torrent/common.h index 42cc3246a..6a280e9b9 100644 --- a/src/torrent/common.h +++ b/src/torrent/common.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_COMMON_H #define LIBTORRENT_COMMON_H @@ -74,6 +38,7 @@ class ConnectionManager; class DhtManager; class DhtRouter; class Download; +class DownloadInfo; class DownloadMain; class DownloadWrapper; class FileList; @@ -98,7 +63,9 @@ class Rate; class SocketSet; class Throttle; class Tracker; +class TrackerController; class TrackerList; +class TrackerManager; class TransferList; // This should only need to be set when compiling libtorrent. diff --git a/src/torrent/download.cc b/src/torrent/download.cc index 2f49bf8f0..6db25aa38 100644 --- a/src/torrent/download.cc +++ b/src/torrent/download.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -55,7 +19,6 @@ #include "torrent/download_info.h" #include "torrent/data/file.h" #include "torrent/peer/connection_list.h" -#include "torrent/tracker_controller.h" #include "torrent/tracker_list.h" #include "torrent/utils/log.h" @@ -149,12 +112,16 @@ Download::start(int flags) { file_list()->open(flags & ~FileList::open_no_create); if (m_ptr->connection_type() == CONNECTION_INITIAL_SEED) { - if (!m_ptr->main()->start_initial_seeding()) + if (!m_ptr->main()->start_initial_seeding()) set_connection_type(CONNECTION_SEED); } m_ptr->main()->start(); - m_ptr->main()->tracker_controller()->enable((flags & start_skip_tracker) ? TrackerController::enable_dont_reset_stats : 0); + + if ((flags & start_skip_tracker)) + m_ptr->main()->tracker_controller().enable_dont_reset_stats(); + else + m_ptr->main()->tracker_controller().enable(); // Reset the uploaded/download baseline when we restart the download // so that broken trackers get the right uploaded ratio. @@ -168,7 +135,7 @@ Download::start(int flags) { } if (!(flags & start_skip_tracker)) - m_ptr->main()->tracker_controller()->send_start_event(); + m_ptr->main()->tracker_controller().send_start_event(); } void @@ -181,9 +148,9 @@ Download::stop(int flags) { m_ptr->main()->stop(); if (!(flags & stop_skip_tracker)) - m_ptr->main()->tracker_controller()->send_stop_event(); + m_ptr->main()->tracker_controller().send_stop_event(); - m_ptr->main()->tracker_controller()->disable(); + m_ptr->main()->tracker_controller().disable(); } bool @@ -203,7 +170,7 @@ Download::hash_check(bool tryQuick) { if (bitfield->empty()) { // The bitfield still hasn't been allocated, so no resume data was - // given. + // given. bitfield->allocate(); bitfield->unset_all(); @@ -262,16 +229,16 @@ Download::file_list() const { return m_ptr->main()->file_list(); } -TrackerController* -Download::tracker_controller() const { - return m_ptr->main()->tracker_controller(); -} - TrackerList* Download::tracker_list() const { return m_ptr->main()->tracker_list(); } +TrackerControllerWrapper +Download::tracker_controller() { + return m_ptr->main()->tracker_controller(); +} + PeerList* Download::peer_list() { return m_ptr->main()->peer_list(); @@ -300,7 +267,7 @@ Download::connection_list() const { uint64_t Download::bytes_done() const { uint64_t a = 0; - + Delegator* d = m_ptr->main()->delegator(); for (auto itr1 : *d->transfer_list()) @@ -311,7 +278,7 @@ Download::bytes_done() const { return a + m_ptr->main()->file_list()->completed_bytes(); } -uint32_t +uint32_t Download::chunks_hashed() const { return m_ptr->hash_checker()->position(); } @@ -346,7 +313,7 @@ Download::set_bitfield(bool allSet) { bitfield->set_all(); else bitfield->unset_all(); - + m_ptr->data()->update_wanted_chunks(); m_ptr->hash_checker()->hashing_ranges().clear(); } @@ -364,7 +331,7 @@ Download::set_bitfield(uint8_t* first, uint8_t* last) { bitfield->allocate(); std::memcpy(bitfield->begin(), first, bitfield->size_bytes()); bitfield->update(); - + m_ptr->data()->update_wanted_chunks(); m_ptr->hash_checker()->hashing_ranges().clear(); } @@ -380,13 +347,13 @@ Download::update_range(int flags, uint32_t first, uint32_t last) { if (flags & update_range_recheck) m_ptr->hash_checker()->hashing_ranges().insert(first, last); - + if (flags & (update_range_clear | update_range_recheck)) { m_ptr->data()->mutable_completed_bitfield()->unset_range(first, last); m_ptr->data()->update_wanted_chunks(); } } - + void Download::sync_chunks() { m_ptr->main()->chunk_list()->sync_chunks(ChunkList::sync_all | ChunkList::sync_force); @@ -475,60 +442,60 @@ Download::set_download_throttle(Throttle* t) { m_ptr->main()->set_download_throttle(t->throttle_list()); } - + void Download::send_completed() { - m_ptr->main()->tracker_controller()->send_completed_event(); + m_ptr->main()->tracker_controller().send_completed_event(); } void Download::manual_request(bool force) { - m_ptr->main()->tracker_controller()->manual_request(force); + m_ptr->main()->tracker_controller().manual_request(force); } void Download::manual_cancel() { - m_ptr->main()->tracker_controller()->close(); + m_ptr->main()->tracker_controller().close(); } // DEPRECATE void Download::set_uploads_max(uint32_t v) { - if (v > (1 << 16)) - throw input_error("Max uploads must be between 0 and 2^16."); - - // For the moment, treat 0 as unlimited. - m_ptr->main()->up_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v); + if (v > (1 << 16)) + throw input_error("Max uploads must be between 0 and 2^16."); + + // For the moment, treat 0 as unlimited. + m_ptr->main()->up_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v); m_ptr->main()->choke_group()->up_queue()->balance_entry(m_ptr->main()->up_group_entry()); } void Download::set_uploads_min(uint32_t v) { - if (v > (1 << 16)) - throw input_error("Min uploads must be between 0 and 2^16."); - - // For the moment, treat 0 as unlimited. - m_ptr->main()->up_group_entry()->set_min_slots(v); + if (v > (1 << 16)) + throw input_error("Min uploads must be between 0 and 2^16."); + + // For the moment, treat 0 as unlimited. + m_ptr->main()->up_group_entry()->set_min_slots(v); m_ptr->main()->choke_group()->up_queue()->balance_entry(m_ptr->main()->up_group_entry()); } void Download::set_downloads_max(uint32_t v) { - if (v > (1 << 16)) - throw input_error("Max downloads must be between 0 and 2^16."); - - // For the moment, treat 0 as unlimited. - m_ptr->main()->down_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v); + if (v > (1 << 16)) + throw input_error("Max downloads must be between 0 and 2^16."); + + // For the moment, treat 0 as unlimited. + m_ptr->main()->down_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v); m_ptr->main()->choke_group()->down_queue()->balance_entry(m_ptr->main()->down_group_entry()); } void Download::set_downloads_min(uint32_t v) { - if (v > (1 << 16)) - throw input_error("Min downloads must be between 0 and 2^16."); - - // For the moment, treat 0 as unlimited. - m_ptr->main()->down_group_entry()->set_min_slots(v); + if (v > (1 << 16)) + throw input_error("Min downloads must be between 0 and 2^16."); + + // For the moment, treat 0 as unlimited. + m_ptr->main()->down_group_entry()->set_min_slots(v); m_ptr->main()->choke_group()->down_queue()->balance_entry(m_ptr->main()->down_group_entry()); } @@ -572,7 +539,7 @@ void Download::set_upload_choke_heuristic(HeuristicType t) { if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE) throw input_error("Invalid heuristics value."); - + m_ptr->main()->choke_group()->up_queue()->set_heuristics((choke_queue::heuristics_enum)t); } @@ -585,8 +552,8 @@ void Download::set_download_choke_heuristic(HeuristicType t) { if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE) throw input_error("Invalid heuristics value."); - - m_ptr->main()->choke_group()->down_queue()->set_heuristics((choke_queue::heuristics_enum)t); + + m_ptr->main()->choke_group()->down_queue()->set_heuristics((choke_queue::heuristics_enum)t); } void diff --git a/src/torrent/download.h b/src/torrent/download.h index 4968c2de2..51ef4a0b3 100644 --- a/src/torrent/download.h +++ b/src/torrent/download.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_DOWNLOAD_H #define LIBTORRENT_DOWNLOAD_H @@ -43,6 +7,7 @@ #include #include +#include namespace torrent { @@ -50,7 +15,6 @@ class ConnectionList; class DownloadInfo; class DownloadMain; class download_data; -class TrackerController; // Download is safe to copy and destory as it is just a pointer to an // internal class. @@ -102,8 +66,8 @@ class LIBTORRENT_EXPORT Download { Object* bencode(); const Object* bencode() const; - TrackerController* tracker_controller() const; - TrackerList* tracker_list() const; + TrackerList* tracker_list() const; + TrackerControllerWrapper tracker_controller(); FileList* file_list() const; PeerList* peer_list(); diff --git a/src/torrent/download_info.h b/src/torrent/download_info.h index 2c4dbaf2d..ffa2827f7 100644 --- a/src/torrent/download_info.h +++ b/src/torrent/download_info.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_DOWNLOAD_INFO_H #define LIBTORRENT_DOWNLOAD_INFO_H @@ -173,9 +137,9 @@ class LIBTORRENT_EXPORT DownloadInfo { private: std::string m_name; - HashString m_hash; - HashString m_hashObfuscated; - HashString m_localId; + HashString m_hash{HashString::new_zero()}; + HashString m_hashObfuscated{HashString::new_zero()}; + HashString m_localId{HashString::new_zero()}; mutable int m_flags; diff --git a/src/torrent/hash_string.h b/src/torrent/hash_string.h index e6158f527..e5b7f726f 100644 --- a/src/torrent/hash_string.h +++ b/src/torrent/hash_string.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - // A fixed with char array used to store 20 byte with hashes. This // should really be replaced with std::array<20>. @@ -92,6 +56,8 @@ class LIBTORRENT_EXPORT HashString { bool equal_to(const char* hash) const { return std::memcmp(m_data, hash, size()) == 0; } bool not_equal_to(const char* hash) const { return std::memcmp(m_data, hash, size()) != 0; } + static HashString new_zero(); + // It is the users responsibility to ensure src.length() >= // size_data. static const HashString* cast_from(const char* src) { return (const HashString*)src; } @@ -111,6 +77,13 @@ std::string hash_string_to_html_str(const HashString& hash) LIBTORRENT_EXPORT; inline const char* hash_string_to_hex_first(const HashString& hash, char* first) { hash_string_to_hex(hash, first); return first; } +inline HashString +HashString::new_zero() { + HashString hash; + hash.clear(); + return hash; +} + inline bool operator == (const HashString& one, const HashString& two) { return std::memcmp(one.begin(), two.begin(), HashString::size_data) == 0; diff --git a/src/torrent/tracker/tracker_manager.cc b/src/torrent/tracker/tracker_manager.cc index fda010f0e..2a28dc5ab 100644 --- a/src/torrent/tracker/tracker_manager.cc +++ b/src/torrent/tracker/tracker_manager.cc @@ -5,38 +5,43 @@ #include "torrent/exceptions.h" #include "torrent/download_info.h" #include "torrent/tracker.h" +#include "torrent/tracker_controller.h" #include "torrent/utils/log.h" // TODO: Remove old logging categories. -#define LT_LOG_TRACKER_EVENTS(log_level, log_fmt, ...) \ - lt_log_print(LOG_TRACKER_EVENTS, "tracker_manager", log_fmt, __VA_ARGS__); +#define LT_LOG_TRACKER_EVENTS(log_fmt, ...) \ + lt_log_print_subsystem(LOG_TRACKER_EVENTS, "tracker_manager", log_fmt, __VA_ARGS__); namespace torrent { -// While we pass DownloadInfo to add() method, we don't own it so we must copy any data we need. -TrackerWrapper TrackerManager::add(DownloadInfo* download_info, Tracker* tracker_worker) { +TrackerControllerWrapper +TrackerManager::add_controller(DownloadInfo* download_info, TrackerController* controller) { + if (download_info->hash() == HashString::new_zero()) + throw internal_error("TrackerManager::add(...) invalid info_hash."); + std::lock_guard guard(m_lock); - auto tracker = TrackerWrapper(download_info->hash(), std::shared_ptr(tracker_worker)); - auto result = base_type::insert(tracker); + auto wrapper = TrackerControllerWrapper(download_info->hash(), std::shared_ptr(controller)); + auto result = m_controllers.insert(wrapper); if (!result.second) - throw internal_error("TrackerManager::add(...) tracker already exists."); + throw internal_error("TrackerManager::add_controller(...) controller already exists."); - LT_LOG_TRACKER_EVENTS("added tracker: info_hash:%s url:%s", tracker.info_hash().c_str(), tracker.get()->url().c_str()); + LT_LOG_TRACKER_EVENTS("added controller: info_hash:%s", hash_string_to_hex_str(download_info->hash()).c_str()); - return tracker; + return wrapper; } -void TrackerManager::remove(TrackerWrapper tracker) { +void +TrackerManager::remove_controller(TrackerControllerWrapper controller) { std::lock_guard guard(m_lock); - // We assume there are other references to the tracker, so gracefully close it. - - base_type::erase(tracker); + // We assume there are other references to the controller, so gracefully close it. + if (m_controllers.erase(controller) != 1) + throw internal_error("TrackerManager::remove_controller(...) controller not found or has multiple references."); - LT_LOG_TRACKER_EVENTS("removed tracker: info_hash:%s url:%s", tracker.info_hash().c_str(), tracker.get()->url().c_str()); + LT_LOG_TRACKER_EVENTS("removed controller: info_hash:%s", hash_string_to_hex_str(controller.info_hash()).c_str()); } } // namespace torrent diff --git a/src/torrent/tracker/tracker_manager.h b/src/torrent/tracker/tracker_manager.h index 833610af1..23f6626f8 100644 --- a/src/torrent/tracker/tracker_manager.h +++ b/src/torrent/tracker/tracker_manager.h @@ -9,53 +9,20 @@ #include #include #include +#include namespace torrent { -class DownloadInfo; -class TrackerManager; +// TODO: Don't export, this should be in src/tracker? -// TODO: This should be renamed to Tracker later. -class LIBTORRENT_EXPORT TrackerWrapper { +class LIBTORRENT_EXPORT TrackerManager { public: - TrackerWrapper(const HashString& info_hash, std::shared_ptr&& tracker); - - bool operator<(const TrackerWrapper& rhs) const; - -protected: - friend class TrackerManager; - - Tracker* get() { return m_tracker.get(); } - const Tracker* get() const { return m_tracker.get(); } - std::shared_ptr& get_shared() { return m_tracker; } - - const HashString& info_hash() const { return m_info_hash; } - -private: - std::shared_ptr m_tracker; - HashString m_info_hash; -}; - -inline -TrackerWrapper::TrackerWrapper(const HashString& info_hash, std::shared_ptr&& tracker) : - m_tracker(tracker), - m_info_hash(info_hash) { -} - -inline bool -TrackerWrapper::operator<(const TrackerWrapper& rhs) const { - return this->get() < rhs.get(); -} - -class LIBTORRENT_EXPORT TrackerManager : private std::set { -public: - typedef std::set base_type; - - TrackerWrapper add(DownloadInfo* download_info, Tracker* tracker_worker); - void remove(TrackerWrapper tracker); + TrackerControllerWrapper add_controller(DownloadInfo* download_info, TrackerController* controller); + void remove_controller(TrackerControllerWrapper controller); private: - std::mutex m_lock; + std::mutex m_lock; + std::set m_controllers; }; } diff --git a/src/torrent/tracker/tracker_wrappers.cc b/src/torrent/tracker/tracker_wrappers.cc new file mode 100644 index 000000000..27ca8bc3e --- /dev/null +++ b/src/torrent/tracker/tracker_wrappers.cc @@ -0,0 +1,111 @@ +#include "config.h" + +#include "torrent/tracker/tracker_wrappers.h" + +#include "torrent/tracker_controller.h" +#include "torrent/utils/log.h" + +// TODO: Remove old logging categories. + +// #define LT_LOG_TRACKER_EVENTS(log_fmt, ...) \ +// lt_log_print(LOG_TRACKER_EVENTS, "tracker_manager", log_fmt, __VA_ARGS__); + +namespace torrent { + +bool +TrackerControllerWrapper::is_active() const { + return m_ptr->is_active(); +} + +bool +TrackerControllerWrapper::is_requesting() const { + return m_ptr->is_requesting(); +} + +bool +TrackerControllerWrapper::is_failure_mode() const { + return m_ptr->is_failure_mode(); +} + +bool +TrackerControllerWrapper::is_promiscuous_mode() const { + return m_ptr->is_promiscuous_mode(); +} + +uint32_t +TrackerControllerWrapper::seconds_to_next_timeout() const { + return m_ptr->seconds_to_next_timeout(); +} + +uint32_t +TrackerControllerWrapper::seconds_to_next_scrape() const { + return m_ptr->seconds_to_next_scrape(); +} + +void +TrackerControllerWrapper::enable() { + m_ptr->enable(); +} + +void +TrackerControllerWrapper::enable_dont_reset_stats() { + m_ptr->enable(TrackerController::enable_dont_reset_stats); +} + +void +TrackerControllerWrapper::disable() { + m_ptr->disable(); +} + +void +TrackerControllerWrapper::close() { + m_ptr->close(); +} + +void +TrackerControllerWrapper::send_start_event() { + m_ptr->send_start_event(); +} + +void +TrackerControllerWrapper::send_stop_event() { + m_ptr->send_stop_event(); +} + +void +TrackerControllerWrapper::send_completed_event() { + m_ptr->send_completed_event(); +} + +void +TrackerControllerWrapper::send_update_event() { + m_ptr->send_update_event(); +} + +void +TrackerControllerWrapper::start_requesting() { + m_ptr->start_requesting(); +} + +void +TrackerControllerWrapper::stop_requesting() { + m_ptr->stop_requesting(); +} + +void +TrackerControllerWrapper::manual_request(bool request_now) { + m_ptr->manual_request(request_now); +} + +void +TrackerControllerWrapper::scrape_request(uint32_t seconds_to_request) { + m_ptr->scrape_request(seconds_to_request); +} + +void +TrackerControllerWrapper::set_slots(slot_address_list success, slot_string failure) { + m_ptr->slot_success() = success; + m_ptr->slot_failure() = failure; +} + +} // namespace torrent diff --git a/src/torrent/tracker/tracker_wrappers.h b/src/torrent/tracker/tracker_wrappers.h new file mode 100644 index 000000000..f5bd692bc --- /dev/null +++ b/src/torrent/tracker/tracker_wrappers.h @@ -0,0 +1,119 @@ +// Temporary classes for thread-safe tracker related classes. +// +// These will be renamed after movimg the old torrent/tracker_* classes to src/tracker. + +#ifndef LIBTORRENT_TRACKER_TRACKER_WRAPPER_H +#define LIBTORRENT_TRACKER_TRACKER_WRAPPER_H + +#include +#include +#include +#include + +namespace torrent { + +class AddressList; + +// TODO: This should be renamed to Tracker later. +class LIBTORRENT_EXPORT TrackerWrapper { +public: + typedef std::shared_ptr ptr_type; + + TrackerWrapper(const HashString& info_hash, std::shared_ptr&& tracker); + + const HashString& info_hash() const { return m_info_hash; } + + bool operator<(const TrackerWrapper& rhs) const; + +protected: + friend class TrackerManager; + + Tracker* get() { return m_ptr.get(); } + const Tracker* get() const { return m_ptr.get(); } + ptr_type& get_shared() { return m_ptr; } + +private: + ptr_type m_ptr; + HashString m_info_hash; +}; + +inline +TrackerWrapper::TrackerWrapper(const HashString& info_hash, std::shared_ptr&& tracker) : + m_ptr(tracker), + m_info_hash(info_hash) { +} + +inline bool +TrackerWrapper::operator<(const TrackerWrapper& rhs) const { + return this->get() < rhs.get(); +} + +class LIBTORRENT_EXPORT TrackerControllerWrapper { +public: + typedef std::shared_ptr ptr_type; + typedef std::function slot_string; + typedef std::function slot_address_list; + + TrackerControllerWrapper() = default; + TrackerControllerWrapper(const HashString& info_hash, std::shared_ptr&& controller); + + const HashString& info_hash() const { return m_info_hash; } + + bool is_active() const; + bool is_requesting() const; + bool is_failure_mode() const; + bool is_promiscuous_mode() const; + + uint32_t seconds_to_next_timeout() const; + uint32_t seconds_to_next_scrape() const; + + void manual_request(bool request_now); + void scrape_request(uint32_t seconds_to_request); + + bool operator<(const TrackerControllerWrapper& rhs) const; + +protected: + friend class Download; + friend class DownloadMain; + friend class DownloadWrapper; + friend class TrackerManager; + + TrackerController* get() { return m_ptr.get(); } + const TrackerController* get() const { return m_ptr.get(); } + ptr_type& get_shared() { return m_ptr; } + + void enable(); + void enable_dont_reset_stats(); + void disable(); + + void close(); + + void send_start_event(); + void send_stop_event(); + void send_completed_event(); + void send_update_event(); + + void start_requesting(); + void stop_requesting(); + + void set_slots(slot_address_list success, slot_string failure); + +private: + ptr_type m_ptr; + HashString m_info_hash; +}; + +inline +TrackerControllerWrapper::TrackerControllerWrapper(const HashString& info_hash, std::shared_ptr&& controller) : + m_ptr(controller), + m_info_hash(info_hash) { +} + +inline bool +TrackerControllerWrapper::operator<(const TrackerControllerWrapper& rhs) const { + return this->get() < rhs.get(); +} + +} // namespace torrent + +#endif // LIBTORRENT_TRACKER_TRACKER_WRAPPER_H diff --git a/src/torrent/tracker_list.cc b/src/torrent/tracker_list.cc index dd1db3007..42a695c73 100644 --- a/src/torrent/tracker_list.cc +++ b/src/torrent/tracker_list.cc @@ -129,7 +129,7 @@ TrackerList::send_scrape(Tracker* tracker) { tracker->send_scrape(); tracker->inc_request_counter(); - LT_LOG_TRACKER(INFO, "sending 'scrape' (group:%u url:%s)", + LT_LOG_TRACKER(INFO, "sending scrape (group:%u url:%s)", tracker->group(), tracker->url().c_str()); } @@ -322,7 +322,7 @@ TrackerList::receive_failed(Tracker* tracker, const std::string& msg) { if (itr == end() || tracker->is_busy()) throw internal_error("TrackerList::receive_failed(...) called but the iterator is invalid."); - LT_LOG_TRACKER(INFO, "failed to connect to tracker (url:%s msg:%s)", tracker->url().c_str(), msg.c_str()); + LT_LOG_TRACKER(INFO, "failed to send request to tracker (url:%s msg:%s)", tracker->url().c_str(), msg.c_str()); auto tracker_state = tracker->state(); @@ -359,7 +359,7 @@ TrackerList::receive_scrape_failed(Tracker* tracker, const std::string& msg) { if (itr == end() || tracker->is_busy()) throw internal_error("TrackerList::receive_failed(...) called but the iterator is invalid."); - LT_LOG_TRACKER(INFO, "failed to scrape tracker (url:%s msg:%s)", tracker->url().c_str(), msg.c_str()); + LT_LOG_TRACKER(INFO, "failed to send scrape to tracker (url:%s msg:%s)", tracker->url().c_str(), msg.c_str()); if (m_slot_scrape_failed) m_slot_scrape_failed(tracker, msg); diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc index f54175ad7..9f553c278 100644 --- a/src/tracker/tracker_http.cc +++ b/src/tracker/tracker_http.cc @@ -2,6 +2,8 @@ #define __STDC_FORMAT_MACROS +#include "tracker/tracker_http.h" + #include #include #include @@ -18,11 +20,11 @@ #include "torrent/utils/log.h" #include "torrent/utils/option_strings.h" -#include "tracker_http.h" - #include "globals.h" #include "manager.h" +// TODO: Update this to use the new logging system, dump the full request url. + #define LT_LOG_TRACKER(log_level, log_fmt, ...) \ lt_log_print_info(LOG_TRACKER_##log_level, m_parent->info(), "tracker", "[%u] " log_fmt, group(), __VA_ARGS__); @@ -305,6 +307,9 @@ TrackerHttp::receive_failed(std::string msg) { void TrackerHttp::process_failure(const Object& object) { + if (object.has_key_string("tracker id")) + update_tracker_id(object.get_key_string("tracker id")); + auto tracker_state = state(); if (object.has_key_value("interval")) @@ -313,9 +318,6 @@ TrackerHttp::process_failure(const Object& object) { if (object.has_key_value("min interval")) tracker_state.set_min_interval(object.get_key_value("min interval")); - if (object.has_key_string("tracker id")) - update_tracker_id(object.get_key_string("tracker id")); - if (object.has_key_value("complete") && object.has_key_value("incomplete")) { tracker_state.m_scrape_complete = std::max(object.get_key_value("complete"), 0); tracker_state.m_scrape_incomplete = std::max(object.get_key_value("incomplete"), 0); @@ -330,6 +332,9 @@ TrackerHttp::process_failure(const Object& object) { void TrackerHttp::process_success(const Object& object) { + if (object.has_key_string("tracker id")) + update_tracker_id(object.get_key_string("tracker id")); + auto tracker_state = state(); if (object.has_key_value("interval")) @@ -342,9 +347,6 @@ TrackerHttp::process_success(const Object& object) { else tracker_state.set_min_interval(default_min_interval); - if (object.has_key_string("tracker id")) - update_tracker_id(object.get_key_string("tracker id")); - if (object.has_key_value("complete") && object.has_key_value("incomplete")) { tracker_state.m_scrape_complete = std::max(object.get_key_value("complete"), 0); tracker_state.m_scrape_incomplete = std::max(object.get_key_value("incomplete"), 0);