From 4633258fbe30187b8108859b86d74507c6243f18 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 15 Jul 2018 18:56:14 +0200 Subject: [PATCH] make the DHT announce flags a strong type --- CMakeLists.txt | 1 + include/libtorrent/Makefile.am | 1 + include/libtorrent/aux_/session_impl.hpp | 3 +- .../libtorrent/kademlia/announce_flags.hpp | 52 +++++++++++++++++++ include/libtorrent/kademlia/dht_tracker.hpp | 5 +- include/libtorrent/kademlia/node.hpp | 6 +-- include/libtorrent/session_handle.hpp | 3 +- src/kademlia/dht_tracker.cpp | 5 +- src/kademlia/node.cpp | 15 +++--- src/session_handle.cpp | 3 +- src/session_impl.cpp | 2 +- src/torrent.cpp | 6 +-- test/test_dht.cpp | 2 +- 13 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 include/libtorrent/kademlia/announce_flags.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ba25f21..62b84f732 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ set(libtorrent_include_files xml_parse) set(libtorrent_kademlia_include_files + announce_flags dht_observer dht_settings dht_state diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index f7dd2a967..3be632873 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -222,6 +222,7 @@ nobase_include_HEADERS = \ extensions/ut_metadata.hpp \ extensions/ut_pex.hpp \ \ + kademlia/announce_flags.hpp \ kademlia/dht_settings.hpp \ kademlia/dht_state.hpp \ kademlia/dht_storage.hpp \ diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 36b440ac2..95059ed31 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -76,6 +76,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/peer_class_type_filter.hpp" #include "libtorrent/kademlia/dht_observer.hpp" #include "libtorrent/kademlia/dht_state.hpp" +#include "libtorrent/kademlia/announce_flags.hpp" #include "libtorrent/resolver.hpp" #include "libtorrent/invariant_check.hpp" #include "libtorrent/extensions.hpp" @@ -418,7 +419,7 @@ namespace aux { , std::string salt = std::string()); void dht_get_peers(sha1_hash const& info_hash); - void dht_announce(sha1_hash const& info_hash, int port = 0, int flags = 0); + void dht_announce(sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {}); void dht_live_nodes(sha1_hash const& nid); void dht_sample_infohashes(udp::endpoint const& ep, sha1_hash const& target); diff --git a/include/libtorrent/kademlia/announce_flags.hpp b/include/libtorrent/kademlia/announce_flags.hpp new file mode 100644 index 000000000..dc7df5ac6 --- /dev/null +++ b/include/libtorrent/kademlia/announce_flags.hpp @@ -0,0 +1,52 @@ +/* + +Copyright (c) 2018, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef ANNOUNCE_FLAGS_HPP +#define ANNOUNCE_FLAGS_HPP + +#include "libtorrent/flags.hpp" + +namespace libtorrent { namespace dht { + +using announce_flags_t = flags::bitfield_flag; + +namespace announce { + +constexpr announce_flags_t seed = 0_bit; +constexpr announce_flags_t implied_port = 1_bit; +constexpr announce_flags_t ssl_torrent = 2_bit; + +} + +}} + +#endif diff --git a/include/libtorrent/kademlia/dht_tracker.hpp b/include/libtorrent/kademlia/dht_tracker.hpp index 953a1d58e..76c6a70b9 100644 --- a/include/libtorrent/kademlia/dht_tracker.hpp +++ b/include/libtorrent/kademlia/dht_tracker.hpp @@ -96,10 +96,9 @@ namespace libtorrent { namespace dht { dht_state state() const; - enum flags_t { flag_seed = 1, flag_implied_port = 2, flag_ssl_torrent = 4 }; void get_peers(sha1_hash const& ih , std::function const&)> f); - void announce(sha1_hash const& ih, int listen_port, int flags + void announce(sha1_hash const& ih, int listen_port, announce_flags_t flags , std::function const&)> f); void sample_infohashes(udp::endpoint const& ep, sha1_hash const& target @@ -156,6 +155,8 @@ namespace libtorrent { namespace dht { , dht_observer* observer, counters& cnt , get_foreign_node_t get_foreign_node , dht_storage_interface& storage); + tracker_node(tracker_node const&) = delete; + tracker_node(tracker_node&&) = default; node dht; deadline_timer connection_timer; diff --git a/include/libtorrent/kademlia/node.hpp b/include/libtorrent/kademlia/node.hpp index 4bd60e24e..189879acc 100644 --- a/include/libtorrent/kademlia/node.hpp +++ b/include/libtorrent/kademlia/node.hpp @@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include // for udp::endpoint @@ -132,12 +133,11 @@ public: int data_size() const { return int(m_storage.num_torrents()); } #endif - enum flags_t { flag_seed = 1, flag_implied_port = 2, flag_ssl_torrent = 4 }; void get_peers(sha1_hash const& info_hash , std::function const&)> dcallback , std::function> const&)> ncallback - , bool noseeds); - void announce(sha1_hash const& info_hash, int listen_port, int flags + , announce_flags_t flags); + void announce(sha1_hash const& info_hash, int listen_port, announce_flags_t flags , std::function const&)> f); void direct_request(udp::endpoint const& ep, entry& e diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index fb737de14..348708398 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/kademlia/dht_storage.hpp" #include "libtorrent/kademlia/dht_settings.hpp" +#include "libtorrent/kademlia/announce_flags.hpp" #if TORRENT_ABI_VERSION == 1 #include "libtorrent/session_settings.hpp" @@ -435,7 +436,7 @@ namespace libtorrent { , std::string salt = std::string()); void dht_get_peers(sha1_hash const& info_hash); - void dht_announce(sha1_hash const& info_hash, int port = 0, int flags = 0); + void dht_announce(sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {}); // Retrieve all the live DHT (identified by ``nid``) nodes. All the // nodes id and endpoint will be returned in the list of nodes in the diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp index 97ebfbd7e..ca1a9313d 100644 --- a/src/kademlia/dht_tracker.cpp +++ b/src/kademlia/dht_tracker.cpp @@ -321,10 +321,11 @@ namespace libtorrent { namespace dht { , std::function const&)> f) { for (auto& n : m_nodes) - n.second.dht.get_peers(ih, f, {}, false); + n.second.dht.get_peers(ih, f, {}, {}); } - void dht_tracker::announce(sha1_hash const& ih, int listen_port, int flags + void dht_tracker::announce(sha1_hash const& ih, int listen_port + , announce_flags_t const flags , std::function const&)> f) { for (auto& n : m_nodes) diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index e1b708970..8c5090310 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -361,7 +361,7 @@ void node::incoming(aux::listen_socket_handle const& s, msg const& m) namespace { void announce_fun(std::vector> const& v - , node& node, int const listen_port, sha1_hash const& ih, int const flags) + , node& node, int const listen_port, sha1_hash const& ih, announce_flags_t const flags) { #ifndef TORRENT_DISABLE_LOGGING auto logger = node.observer(); @@ -398,8 +398,8 @@ namespace { a["info_hash"] = ih; a["port"] = listen_port; a["token"] = p.second; - a["seed"] = (flags & node::flag_seed) ? 1 : 0; - if (flags & node::flag_implied_port) a["implied_port"] = 1; + a["seed"] = (flags & announce::seed) ? 1 : 0; + if (flags & announce::implied_port) a["implied_port"] = 1; node.stats_counters().inc_stats_counter(counters::dht_announce_peer_out); node.m_rpc.invoke(e, p.first.ep(), o); } @@ -429,10 +429,11 @@ void node::add_node(udp::endpoint const& node) void node::get_peers(sha1_hash const& info_hash , std::function const&)> dcallback , std::function> const&)> ncallback - , bool noseeds) + , announce_flags_t const flags) { // search for nodes with ids close to id or with peers // for info-hash id. then send announce_peer to them. + bool const noseeds = bool(flags & announce::seed); auto ta = m_settings.privacy_lookups ? std::make_shared(*this, info_hash, dcallback, ncallback, noseeds) @@ -441,7 +442,7 @@ void node::get_peers(sha1_hash const& info_hash ta->start(); } -void node::announce(sha1_hash const& info_hash, int listen_port, int const flags +void node::announce(sha1_hash const& info_hash, int listen_port, announce_flags_t const flags , std::function const&)> f) { #ifndef TORRENT_DISABLE_LOGGING @@ -455,13 +456,13 @@ void node::announce(sha1_hash const& info_hash, int listen_port, int const flags if (listen_port == 0) { listen_port = m_observer->get_listen_port( - flags & node::flag_ssl_torrent ? aux::transport::ssl : aux::transport::plaintext + flags & announce::ssl_torrent ? aux::transport::ssl : aux::transport::plaintext , m_sock); } get_peers(info_hash, std::move(f) , std::bind(&announce_fun, _1, std::ref(*this) - , listen_port, info_hash, flags), flags & node::flag_seed); + , listen_port, info_hash, flags), flags); } void node::direct_request(udp::endpoint const& ep, entry& e diff --git a/src/session_handle.cpp b/src/session_handle.cpp index bd87aa21f..0a364d90a 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -644,7 +644,8 @@ namespace { #endif } - void session_handle::dht_announce(sha1_hash const& info_hash, int port, int flags) + void session_handle::dht_announce(sha1_hash const& info_hash, int port + , dht::announce_flags_t const flags) { #ifndef TORRENT_DISABLE_DHT async_call(&session_impl::dht_announce, info_hash, port, flags); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 3bf3c5677..d4759904d 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -6034,7 +6034,7 @@ namespace aux { m_dht->get_peers(info_hash, std::bind(&on_dht_get_peers, std::ref(m_alerts), info_hash, _1)); } - void session_impl::dht_announce(sha1_hash const& info_hash, int port, int flags) + void session_impl::dht_announce(sha1_hash const& info_hash, int port, dht::announce_flags_t const flags) { if (!m_dht) return; m_dht->announce(info_hash, port, flags, std::bind(&on_dht_get_peers, std::ref(m_alerts), info_hash, _1)); diff --git a/src/torrent.cpp b/src/torrent.cpp index 26886a1bf..5f34e71af 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2592,7 +2592,7 @@ bool is_downloading_state(int const st) #endif // if we're a seed, we tell the DHT for better scrape stats - int flags = is_seed() ? dht::dht_tracker::flag_seed : 0; + dht::announce_flags_t flags = is_seed() ? dht::announce::seed : dht::announce_flags_t{}; // If this is an SSL torrent the announce needs to specify an SSL // listen port. DHT nodes only operate on non-SSL ports so SSL @@ -2603,11 +2603,11 @@ bool is_downloading_state(int const st) // likely more accurate when behind a NAT if (is_ssl_torrent()) { - flags |= dht::dht_tracker::flag_ssl_torrent; + flags |= dht::announce::ssl_torrent; } else if (settings().get_bool(settings_pack::enable_incoming_utp)) { - flags |= dht::dht_tracker::flag_implied_port; + flags |= dht::announce::implied_port; } std::weak_ptr self(shared_from_this()); diff --git a/test/test_dht.cpp b/test/test_dht.cpp index 0448c8c98..2177299a7 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -2107,7 +2107,7 @@ void test_get_peers(address(&rand_addr)()) dht::node_id const initial_node_id = to_hash("1111111111222222222233333333334444444444"); t.dht_node.m_table.add_node(node_entry{initial_node_id, initial_node, 10, true}); - t.dht_node.announce(target, 1234, false, get_peers_cb); + t.dht_node.announce(target, 1234, {}, get_peers_cb); TEST_EQUAL(g_sent_packets.size(), 1); if (g_sent_packets.empty()) return;