allow DHT bootstrap to use nodes of both IP protocols
This commit is contained in:
parent
9efb72197c
commit
014a07a5c8
|
@ -69,6 +69,14 @@ namespace libtorrent { namespace dht
|
|||
c.inc_stats_counter(counters::dht_allocated_observers, allocated_observers);
|
||||
}
|
||||
|
||||
std::vector<udp::endpoint> concat(std::vector<udp::endpoint> const& v1
|
||||
, std::vector<udp::endpoint> const& v2)
|
||||
{
|
||||
std::vector<udp::endpoint> r = v1;
|
||||
r.insert(r.end(), v2.begin(), v2.end());
|
||||
return r;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// class that puts the networking and the kademlia node in a single
|
||||
|
@ -155,9 +163,10 @@ namespace libtorrent { namespace dht
|
|||
m_refresh_timer.expires_from_now(seconds(5), ec);
|
||||
m_refresh_timer.async_wait(std::bind(&dht_tracker::refresh_timeout, self(), _1));
|
||||
|
||||
m_dht.bootstrap(m_state.nodes, f);
|
||||
// bootstrap with mix of IP protocols via want/nodes/nodes6
|
||||
m_dht.bootstrap(concat(m_state.nodes, m_state.nodes6), f);
|
||||
#if TORRENT_USE_IPV6
|
||||
m_dht6.bootstrap(m_state.nodes6, f);
|
||||
m_dht6.bootstrap(concat(m_state.nodes6, m_state.nodes), f);
|
||||
#endif
|
||||
m_state.clear();
|
||||
}
|
||||
|
|
|
@ -220,7 +220,10 @@ void node::bootstrap(std::vector<udp::endpoint> const& nodes
|
|||
|
||||
for (auto const& n : nodes)
|
||||
{
|
||||
if (n.protocol() != protocol()) continue;
|
||||
#if !TORRENT_USE_IPV6
|
||||
if (n.protocol() == udp::v6()) continue;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
++count;
|
||||
#endif
|
||||
|
|
|
@ -198,7 +198,7 @@ std::int64_t routing_table::num_global_nodes() const
|
|||
int deepest_size = 0;
|
||||
for (auto const& i : m_buckets)
|
||||
{
|
||||
deepest_size = int(i.live_nodes.size()); // + i.replacements.size();
|
||||
deepest_size = i.live_nodes.end_index(); // + i.replacements.size();
|
||||
if (deepest_size < m_bucket_size) break;
|
||||
// this bucket is full
|
||||
++deepest_bucket;
|
||||
|
|
|
@ -510,7 +510,7 @@ void traversal_algorithm::add_router_entries()
|
|||
|
||||
void traversal_algorithm::init()
|
||||
{
|
||||
m_branch_factor = std::int16_t(m_node.branch_factor());
|
||||
m_branch_factor = aux::numeric_cast<std::int16_t>(m_node.branch_factor());
|
||||
m_node.add_traversal_algorithm(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ TORRENT_TEST(alerts_types)
|
|||
TEST_EQUAL(name::alert_type, seq); \
|
||||
TEST_EQUAL(name::static_category, cat);
|
||||
|
||||
TEST_ALERT_TYPE(dht_bootstrap_alert, 62, 0, alert::dht_notification);
|
||||
TEST_ALERT_TYPE(session_stats_alert, 70, 1, alert::stats_notification);
|
||||
TEST_ALERT_TYPE(dht_get_peers_reply_alert, 87, 0, alert::dht_operation_notification);
|
||||
TEST_ALERT_TYPE(session_error_alert, 90, 0, alert::error_notification);
|
||||
|
|
|
@ -1824,6 +1824,75 @@ TORRENT_TEST(bootstrap_v6)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
void test_bootstrap_want(address(&rand_addr)())
|
||||
{
|
||||
dht_test_setup t(udp::endpoint(rand_addr(), 20));
|
||||
bdecode_node response;
|
||||
bool ret;
|
||||
|
||||
dht::key_desc_t const find_node_desc[] = {
|
||||
{"y", bdecode_node::string_t, 1, 0},
|
||||
{"t", bdecode_node::string_t, 2, 0},
|
||||
{"q", bdecode_node::string_t, 9, 0},
|
||||
{"a", bdecode_node::dict_t, 0, key_desc_t::parse_children},
|
||||
{"id", bdecode_node::string_t, 20, 0},
|
||||
{"target", bdecode_node::string_t, 20, key_desc_t::optional},
|
||||
{"info_hash", bdecode_node::string_t, 20, key_desc_t::optional},
|
||||
{"want", bdecode_node::list_t, 0, key_desc_t::last_child},
|
||||
};
|
||||
|
||||
bdecode_node find_node_keys[8];
|
||||
|
||||
g_sent_packets.clear();
|
||||
|
||||
std::vector<udp::endpoint> nodesv;
|
||||
if (t.source.address().is_v4())
|
||||
nodesv.push_back(rand_udp_ep(rand_v6));
|
||||
else
|
||||
nodesv.push_back(rand_udp_ep(rand_v4));
|
||||
|
||||
t.dht_node.bootstrap(nodesv, std::bind(&nop_node));
|
||||
|
||||
TEST_EQUAL(g_sent_packets.size(), 1);
|
||||
TEST_EQUAL(g_sent_packets.front().first, nodesv[0]);
|
||||
|
||||
lazy_from_entry(g_sent_packets.front().second, response);
|
||||
ret = verify_message(response, find_node_desc, find_node_keys, t.error_string);
|
||||
if (ret)
|
||||
{
|
||||
TEST_EQUAL(find_node_keys[0].string_value(), "q");
|
||||
TEST_CHECK(find_node_keys[2].string_value() == "find_node"
|
||||
|| find_node_keys[2].string_value() == "get_peers");
|
||||
|
||||
TEST_EQUAL(find_node_keys[7].list_size(), 1);
|
||||
if (t.source.address().is_v4())
|
||||
{
|
||||
TEST_EQUAL(find_node_keys[7].list_string_value_at(0), "n4");
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EQUAL(find_node_keys[7].list_string_value_at(0), "n6");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::printf(" invalid find_node request: %s\n", print_entry(response).c_str());
|
||||
TEST_ERROR(t.error_string);
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_TEST(bootstrap_want_v4)
|
||||
{
|
||||
test_bootstrap_want(rand_v4);
|
||||
}
|
||||
|
||||
TORRENT_TEST(bootstrap_want_v6)
|
||||
{
|
||||
test_bootstrap_want(rand_v6);
|
||||
}
|
||||
#endif
|
||||
|
||||
// test that the node ignores a nodes entry which is too short
|
||||
void test_short_nodes(address(&rand_addr)())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue