merged DHT feature from libtorrent_aio

This commit is contained in:
Arvid Norberg 2012-09-22 21:40:16 +00:00
parent 055f8a0598
commit d098e49059
5 changed files with 43 additions and 12 deletions

View File

@ -1407,6 +1407,7 @@ struct has the following members::
int max_torrents; int max_torrents;
bool restrict_routing_ips; bool restrict_routing_ips;
bool restrict_search_ips; bool restrict_search_ips;
bool extended_routing_table;
}; };
``max_peers_reply`` is the maximum number of peers the node will send in ``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 with IPs with very close CIDR distance. This also defaults to true and helps
mitigate certain attacks on the DHT. 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 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 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 and ignored. libtorrent always tries to open the UDP socket on the same port

View File

@ -129,12 +129,12 @@ public:
void find_node(node_id const& id, std::vector<node_entry>& l void find_node(node_id const& id, std::vector<node_entry>& l
, int options, int count = 0); , int options, int count = 0);
int bucket_size(int bucket) int bucket_size(int bucket) const
{ {
int num_buckets = m_buckets.size(); int num_buckets = m_buckets.size();
if (num_buckets == 0) return 0; if (num_buckets == 0) return 0;
if (bucket < num_buckets) bucket = num_buckets - 1; 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); std::advance(i, bucket);
return (int)i->live_nodes.size(); return (int)i->live_nodes.size();
} }
@ -162,6 +162,8 @@ public:
void touch_bucket(node_id const& target); void touch_bucket(node_id const& target);
int bucket_limit(int bucket) const;
private: private:
typedef std::list<routing_table_node> table_t; typedef std::list<routing_table_node> table_t;

View File

@ -950,6 +950,7 @@ namespace libtorrent
, max_torrent_search_reply(20) , max_torrent_search_reply(20)
, restrict_routing_ips(true) , restrict_routing_ips(true)
, restrict_search_ips(true) , restrict_search_ips(true)
, extended_routing_table(true)
{} {}
// the maximum number of peers to send in a // the maximum number of peers to send in a
@ -991,6 +992,11 @@ namespace libtorrent
// applies the same IP restrictions on nodes // applies the same IP restrictions on nodes
// received during a DHT search (traversal algorithm) // received during a DHT search (traversal algorithm)
bool restrict_search_ips; 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 #endif

View File

@ -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 void routing_table::status(session_status& s) const
{ {
boost::tie(s.dht_nodes, s.dht_node_cache) = size(); 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 << "-";
os << "\n"; 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()); for (table_t::const_iterator i = m_buckets.begin(), end(m_buckets.end());
i != end; ++i) 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"; os << "\n";
} }
for (int i = 0; i < 160; ++i) os << "+"; for (int i = 0; i < 160; ++i) os << "+";
os << "\n"; 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()); for (table_t::const_iterator i = m_buckets.begin(), end(m_buckets.end());
i != end; ++i) i != end; ++i)
@ -403,6 +414,8 @@ bool routing_table::add_node(node_entry e)
table_t::iterator i = find_bucket(e.id); table_t::iterator i = find_bucket(e.id);
bucket_t& b = i->live_nodes; bucket_t& b = i->live_nodes;
bucket_t& rb = i->replacements; 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; 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 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); b.push_back(e);
m_ips.insert(e.addr.to_v4().to_bytes()); m_ips.insert(e.addr.to_v4().to_bytes());
// TORRENT_LOG(table) << "inserting node: " << e.id << " " << e.addr; // 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()) // move any node whose (160 - distane_exp(m_id, id)) >= (i - m_buckets.begin())
// to the new bucket // 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();) for (bucket_t::iterator j = b.begin(); j != b.end();)
{ {
if (distance_exp(m_id, j->id) >= 159 - bucket_index) 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 (distance_exp(m_id, j->id) >= 159 - bucket_index)
{ {
if (int(b.size()) >= m_bucket_size) if (int(b.size()) >= bucket_size_limit)
{ {
++j; ++j;
continue; continue;
@ -633,7 +646,7 @@ bool routing_table::add_node(node_entry e)
else else
{ {
// this entry belongs in the new bucket // 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); new_bucket.push_back(*j);
else else
new_replacement_bucket.push_back(*j); 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 // now insert the new node in the appropriate bucket
if (distance_exp(m_id, e.id) >= 159 - bucket_index) 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); b.push_back(e);
added = true; added = true;
@ -658,7 +671,7 @@ bool routing_table::add_node(node_entry e)
} }
else else
{ {
if (int(new_bucket.size()) < m_bucket_size) if (int(new_bucket.size()) < new_bucket_size)
{ {
new_bucket.push_back(e); new_bucket.push_back(e);
added = true; added = true;

View File

@ -472,7 +472,12 @@ namespace aux {
TORRENT_SETTING(integer, service_port) TORRENT_SETTING(integer, service_port)
#endif #endif
TORRENT_SETTING(integer, max_fail_count) 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(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 #undef TORRENT_SETTING
#endif #endif