From d098e49059f11f54f7b78838e8d839ee56b13bb1 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 22 Sep 2012 21:40:16 +0000 Subject: [PATCH] merged DHT feature from libtorrent_aio --- docs/manual.rst | 5 +++ include/libtorrent/kademlia/routing_table.hpp | 6 ++-- include/libtorrent/session_settings.hpp | 6 ++++ src/kademlia/routing_table.cpp | 33 +++++++++++++------ src/session_impl.cpp | 5 +++ 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/docs/manual.rst b/docs/manual.rst index ad6721e20..64ac5acd1 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -1407,6 +1407,7 @@ struct has the following members:: int max_torrents; bool restrict_routing_ips; bool restrict_search_ips; + bool extended_routing_table; }; ``max_peers_reply`` is the maximum number of peers the node will send in @@ -1439,6 +1440,10 @@ distance. with IPs with very close CIDR distance. This also defaults to true and helps mitigate certain attacks on the DHT. +``extended_routing_table`` makes the first buckets in the DHT routing +table fit 128, 64, 32 and 16 nodes respectively, as opposed to the +standard size of 8. All other buckets have size 8 still. + The ``dht_settings`` struct used to contain a ``service_port`` member to control which port the DHT would listen on and send messages from. This field is deprecated and ignored. libtorrent always tries to open the UDP socket on the same port diff --git a/include/libtorrent/kademlia/routing_table.hpp b/include/libtorrent/kademlia/routing_table.hpp index a0488e55a..62703abb2 100644 --- a/include/libtorrent/kademlia/routing_table.hpp +++ b/include/libtorrent/kademlia/routing_table.hpp @@ -129,12 +129,12 @@ public: void find_node(node_id const& id, std::vector& l , int options, int count = 0); - int bucket_size(int bucket) + int bucket_size(int bucket) const { int num_buckets = m_buckets.size(); if (num_buckets == 0) return 0; if (bucket < num_buckets) bucket = num_buckets - 1; - table_t::iterator i = m_buckets.begin(); + table_t::const_iterator i = m_buckets.begin(); std::advance(i, bucket); return (int)i->live_nodes.size(); } @@ -162,6 +162,8 @@ public: void touch_bucket(node_id const& target); + int bucket_limit(int bucket) const; + private: typedef std::list table_t; diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 68744c0dd..c26caae8e 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -950,6 +950,7 @@ namespace libtorrent , max_torrent_search_reply(20) , restrict_routing_ips(true) , restrict_search_ips(true) + , extended_routing_table(true) {} // the maximum number of peers to send in a @@ -991,6 +992,11 @@ namespace libtorrent // applies the same IP restrictions on nodes // received during a DHT search (traversal algorithm) bool restrict_search_ips; + + // if this is set, the first few buckets in the routing + // table are enlarged, to make room for more nodes in order + // to lower the look-up times + bool extended_routing_table; }; #endif diff --git a/src/kademlia/routing_table.cpp b/src/kademlia/routing_table.cpp index d29f5f632..5bebe652f 100644 --- a/src/kademlia/routing_table.cpp +++ b/src/kademlia/routing_table.cpp @@ -67,6 +67,16 @@ routing_table::routing_table(node_id const& id, int bucket_size { } +int routing_table::bucket_limit(int bucket) const +{ + if (!m_settings.extended_routing_table) return m_bucket_size; + + int size_exceptions[] = {16, 8, 4, 2}; + if (bucket < sizeof(size_exceptions)/sizeof(size_exceptions[0])) + return m_bucket_size * size_exceptions[bucket]; + return m_bucket_size; +} + void routing_table::status(session_status& s) const { boost::tie(s.dht_nodes, s.dht_node_cache) = size(); @@ -131,19 +141,20 @@ void routing_table::print_state(std::ostream& os) const os << "-"; os << "\n"; - for (int k = 0; k < m_bucket_size; ++k) + int max_size = bucket_limit(0); + for (int k = 0; k < max_size; ++k) { for (table_t::const_iterator i = m_buckets.begin(), end(m_buckets.end()); i != end; ++i) { - os << (int(i->live_nodes.size()) > (m_bucket_size - 1 - k) ? "|" : " "); + os << (int(i->live_nodes.size()) > (max_size - 1 - k) ? "|" : " "); } os << "\n"; } for (int i = 0; i < 160; ++i) os << "+"; os << "\n"; - for (int k = 0; k < m_bucket_size; ++k) + for (int k = 0; k < max_size; ++k) { for (table_t::const_iterator i = m_buckets.begin(), end(m_buckets.end()); i != end; ++i) @@ -403,6 +414,8 @@ bool routing_table::add_node(node_entry e) table_t::iterator i = find_bucket(e.id); bucket_t& b = i->live_nodes; bucket_t& rb = i->replacements; + int bucket_index = std::distance(m_buckets.begin(), i); + int bucket_size_limit = bucket_limit(bucket_index); bucket_t::iterator j; @@ -473,9 +486,9 @@ bool routing_table::add_node(node_entry e) } // if there's room in the main bucket, just insert it - if (int(b.size()) < m_bucket_size) + if (int(b.size()) < bucket_size_limit) { - if (b.empty()) b.reserve(m_bucket_size); + if (b.empty()) b.reserve(bucket_size_limit); b.push_back(e); m_ips.insert(e.addr.to_v4().to_bytes()); // TORRENT_LOG(table) << "inserting node: " << e.id << " " << e.addr; @@ -603,7 +616,7 @@ bool routing_table::add_node(node_entry e) // move any node whose (160 - distane_exp(m_id, id)) >= (i - m_buckets.begin()) // to the new bucket - int bucket_index = std::distance(m_buckets.begin(), i); + int new_bucket_size = bucket_limit(bucket_index + 1); for (bucket_t::iterator j = b.begin(); j != b.end();) { if (distance_exp(m_id, j->id) >= 159 - bucket_index) @@ -623,7 +636,7 @@ bool routing_table::add_node(node_entry e) { if (distance_exp(m_id, j->id) >= 159 - bucket_index) { - if (int(b.size()) >= m_bucket_size) + if (int(b.size()) >= bucket_size_limit) { ++j; continue; @@ -633,7 +646,7 @@ bool routing_table::add_node(node_entry e) else { // this entry belongs in the new bucket - if (int(new_bucket.size()) < m_bucket_size) + if (int(new_bucket.size()) < new_bucket_size) new_bucket.push_back(*j); else new_replacement_bucket.push_back(*j); @@ -645,7 +658,7 @@ bool routing_table::add_node(node_entry e) // now insert the new node in the appropriate bucket if (distance_exp(m_id, e.id) >= 159 - bucket_index) { - if (int(b.size()) < m_bucket_size) + if (int(b.size()) < bucket_size_limit) { b.push_back(e); added = true; @@ -658,7 +671,7 @@ bool routing_table::add_node(node_entry e) } else { - if (int(new_bucket.size()) < m_bucket_size) + if (int(new_bucket.size()) < new_bucket_size) { new_bucket.push_back(e); added = true; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index cdd088547..85dd1ab15 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -472,7 +472,12 @@ namespace aux { TORRENT_SETTING(integer, service_port) #endif TORRENT_SETTING(integer, max_fail_count) + TORRENT_SETTING(integer, max_torrents) + TORRENT_SETTING(integer, max_dht_items) TORRENT_SETTING(integer, max_torrent_search_reply) + TORRENT_SETTING(boolean, restrict_routing_ips) + TORRENT_SETTING(boolean, restrict_search_ips) + TORRENT_SETTING(boolean, extended_routing_table) }; #undef TORRENT_SETTING #endif