From 8ec7cff9931c77bce023195ebdc107d9aed761d0 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 26 Nov 2014 02:02:32 +0000 Subject: [PATCH] merged changes from RC_1_0 --- ChangeLog | 1 + src/broadcast_socket.cpp | 5 ++++- src/kademlia/node.cpp | 11 +++++++++++ src/kademlia/node_id.cpp | 4 +++- src/kademlia/routing_table.cpp | 20 ++++++++++++++++++++ test/test_dht.cpp | 2 ++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e650ee77..b00f331da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,6 +35,7 @@ 1.0.3 release + * fix if_nametoindex build error on windows * handle overlong utf-8 sequences * fix link order bug in makefile for python binding * fix bug in interest calculation, causing premature disconnects diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index 84e452b9b..e8cd79990 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -260,8 +260,11 @@ namespace libtorrent ec = error_code(); // if_nametoindex was introduced in vista + // and apparently msvc-9.0 doesn't support this, even though + // the _WIN32_WINNT version indicates vista+ #if TORRENT_USE_IPV6 \ - && (!defined TORRENT_WINDOWS || _WIN32_WINNT >= _WIN32_WINNT_VISTA) \ + && (!defined TORRENT_WINDOWS \ + || (_WIN32_WINNT >= _WIN32_WINNT_VISTA && _MSC_VER > 1500)) \ && !defined TORRENT_MINGW if (i->interface_address.is_v6() && diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 098b8bcaa..7fa904f7e 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -472,16 +472,27 @@ void node_impl::tick() node_entry const* ne = m_table.next_refresh(); if (ne == NULL) return; + // this shouldn't happen + TORRENT_ASSERT(m_id != ne->id); + if (ne->id == m_id) return; + int bucket = 159 - distance_exp(m_id, ne->id); + TORRENT_ASSERT(bucket < 160); send_single_refresh(ne->ep(), bucket, ne->id); } void node_impl::send_single_refresh(udp::endpoint const& ep, int bucket , node_id const& id) { + TORRENT_ASSERT(id != m_id); void* ptr = m_rpc.allocate_observer(); if (ptr == 0) return; + TORRENT_ASSERT(bucket >= 0); + + // sanity check + TORRENT_ASSERT(bucket <= 50); + // generate a random node_id within the given bucket // TODO: 2 it would be nice to have a bias towards node-id prefixes that // are missing in the bucket diff --git a/src/kademlia/node_id.cpp b/src/kademlia/node_id.cpp index 4041e806d..aa6d5393a 100644 --- a/src/kademlia/node_id.cpp +++ b/src/kademlia/node_id.cpp @@ -216,10 +216,12 @@ bool matching_prefix(node_entry const& n, int mask, int prefix, int bucket_index node_id generate_prefix_mask(int bits) { + TORRENT_ASSERT(bits >= 0); + TORRENT_ASSERT(bits <= 160); node_id mask(0); int b = 0; for (; b < bits - 7; b += 8) mask[b/8] |= 0xff; - mask[b/8] |= (0xff << (8 - (bits&7))) & 0xff; + if (bits < 160) mask[b/8] |= (0xff << (8 - (bits&7))) & 0xff; return mask; } diff --git a/src/kademlia/routing_table.cpp b/src/kademlia/routing_table.cpp index 3fe04a6d1..adcf8dbac 100644 --- a/src/kademlia/routing_table.cpp +++ b/src/kademlia/routing_table.cpp @@ -327,6 +327,10 @@ node_entry const* routing_table::next_refresh() for (bucket_t::iterator j = i->live_nodes.begin() , end(i->live_nodes.end()); j != end; ++j) { + // this shouldn't happen + TORRENT_ASSERT(m_id != j->id); + if (j->id == m_id) continue; + if (j->last_queried == min_time()) { bucket_idx = idx; @@ -456,6 +460,22 @@ bool routing_table::add_node(node_entry e) { split_bucket(); + // if this assert triggers a lot in the wild, we should probably + // harden our resistence towards this attack. Perhaps by never + // splitting a bucket (and discard nodes) if the two buckets above it + // are empty or close to empty + TORRENT_ASSERT(m_buckets.size() <= 50); + if (m_buckets.size() > 50) + { + // this is a sanity check. In the wild, we shouldn't see routing + // tables deeper than 26 or 27. If we get this deep, there might + // be a bug in the bucket splitting logic, or there may be someone + // playing a prank on us, spoofing node IDs. + s = add_node_impl(e); + if (s == node_added) return true; + return false; + } + // if the new bucket still has too many nodes in it, we need to keep // splitting if (m_buckets.back().live_nodes.size() > bucket_limit(m_buckets.size()-1)) diff --git a/test/test_dht.cpp b/test/test_dht.cpp index 1f9883f8b..520e7fffa 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -1147,10 +1147,12 @@ int test_main() // test node-id functions using namespace libtorrent::dht; + TEST_EQUAL(generate_prefix_mask(0), to_hash("0000000000000000000000000000000000000000")); TEST_EQUAL(generate_prefix_mask(1), to_hash("8000000000000000000000000000000000000000")); TEST_EQUAL(generate_prefix_mask(2), to_hash("c000000000000000000000000000000000000000")); TEST_EQUAL(generate_prefix_mask(11), to_hash("ffe0000000000000000000000000000000000000")); TEST_EQUAL(generate_prefix_mask(17), to_hash("ffff800000000000000000000000000000000000")); + TEST_EQUAL(generate_prefix_mask(160), to_hash("ffffffffffffffffffffffffffffffffffffffff")); // test kademlia functions