diff --git a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp index c032c19d1..6882d34bb 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp @@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "libtorrent/kademlia/node.hpp" #include "libtorrent/kademlia/node_id.hpp" @@ -125,6 +126,12 @@ namespace libtorrent { namespace dht dht_settings const& m_settings; int m_refresh_bucket; + // The mutex is used to abort the dht node + // it's only used to set m_abort to true + typedef boost::mutex mutex_t; + mutable mutex_t m_mutex; + bool m_abort; + // used to resolve hostnames for nodes udp::resolver m_host_resolver; diff --git a/libtorrent/include/libtorrent/kademlia/traversal_algorithm.hpp b/libtorrent/include/libtorrent/kademlia/traversal_algorithm.hpp index b333b385e..74d79edc9 100644 --- a/libtorrent/include/libtorrent/kademlia/traversal_algorithm.hpp +++ b/libtorrent/include/libtorrent/kademlia/traversal_algorithm.hpp @@ -84,12 +84,11 @@ protected: struct result { result(node_id const& id, udp::endpoint addr, unsigned char f = 0) - : id(id), addr(addr), flags(f) - {} + : id(id), addr(addr), flags(f) {} node_id id; udp::endpoint addr; - enum { queried = 1, initial = 2 }; + enum { queried = 1, initial = 2, no_id = 4 }; unsigned char flags; }; @@ -150,7 +149,7 @@ traversal_algorithm::traversal_algorithm( for (routing_table::router_iterator i = table.router_begin() , end(table.router_end()); i != end; ++i) { - add_entry(generate_id(), *i, result::initial); + add_entry(node_id(0), *i, result::initial); } } diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index b1884496b..e76c652cb 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -1594,11 +1594,6 @@ namespace libtorrent , boost::bind(&session_impl::free_disk_buffer , boost::ref(m_ses), _1)); -/* - buffer::interval i = allocate_send_buffer(r.length); - std::memcpy(i.begin, buffer, r.length); - t->filesystem().free_buffer(buffer); -*/ m_payloads.push_back(range(send_buffer_size() - r.length, r.length)); setup_send(); } diff --git a/libtorrent/src/kademlia/closest_nodes.cpp b/libtorrent/src/kademlia/closest_nodes.cpp index 7551e806f..a11fe2559 100644 --- a/libtorrent/src/kademlia/closest_nodes.cpp +++ b/libtorrent/src/kademlia/closest_nodes.cpp @@ -110,12 +110,13 @@ void closest_nodes::invoke(node_id const& id, udp::endpoint addr) void closest_nodes::done() { std::vector results; - int result_size = m_table.bucket_size(); - if (result_size > (int)m_results.size()) result_size = (int)m_results.size(); + int num_results = m_table.bucket_size(); for (std::vector::iterator i = m_results.begin() - , end(m_results.begin() + result_size); i != end; ++i) + , end(m_results.end()); i != end && num_results >= 0; ++i) { + if (i->flags & result::no_id) continue; results.push_back(node_entry(i->id, i->addr)); + --num_results; } m_done_callback(results); } diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index fe6a516ba..56bc765de 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -158,6 +158,7 @@ namespace libtorrent { namespace dht , m_refresh_timer(ios) , m_settings(settings) , m_refresh_bucket(160) + , m_abort(false) , m_host_resolver(ios) , m_refs(0) { @@ -220,6 +221,8 @@ namespace libtorrent { namespace dht void dht_tracker::stop() { + mutex_t::scoped_lock l(m_mutex); + m_abort = true; m_timer.cancel(); m_connection_timer.cancel(); m_refresh_timer.cancel(); @@ -237,7 +240,9 @@ namespace libtorrent { namespace dht void dht_tracker::connection_timeout(asio::error_code const& e) try { - if (e) return; + mutex_t::scoped_lock l(m_mutex); + if (e || m_abort) return; + if (!m_socket.is_open()) return; time_duration d = m_dht.connection_timeout(); m_connection_timer.expires_from_now(d); @@ -255,7 +260,9 @@ namespace libtorrent { namespace dht void dht_tracker::refresh_timeout(asio::error_code const& e) try { - if (e) return; + mutex_t::scoped_lock l(m_mutex); + if (e || m_abort) return; + if (!m_socket.is_open()) return; time_duration d = m_dht.refresh_timeout(); m_refresh_timer.expires_from_now(d); @@ -281,7 +288,9 @@ namespace libtorrent { namespace dht void dht_tracker::tick(asio::error_code const& e) try { - if (e) return; + mutex_t::scoped_lock l(m_mutex); + if (e || m_abort) return; + if (!m_socket.is_open()) return; m_timer.expires_from_now(minutes(tick_period)); m_timer.async_wait(m_strand.wrap(bind(&dht_tracker::tick, self(), _1))); diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index d4b343519..60dfa2d20 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -174,6 +174,12 @@ void node_impl::refresh(node_id const& id void node_impl::bootstrap(std::vector const& nodes , boost::function0 f) { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "bootrapping: " << nodes.size(); + for (std::vector::const_iterator i = nodes.begin() + , end(nodes.end()); i != end; ++i) + TORRENT_LOG(node) << " " << *i; +#endif std::vector start; start.reserve(nodes.size()); std::copy(nodes.begin(), nodes.end(), std::back_inserter(start)); @@ -254,6 +260,11 @@ namespace , int listen_port, sha1_hash const& ih , boost::function const&, sha1_hash const&)> f) { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "announce response [ ih: " << ih + << " p: " << listen_port + << " nodes: " << v.size() << " ]" ; +#endif bool nodes = false; // only store on the first k nodes for (std::vector::const_iterator i = v.begin() @@ -271,6 +282,9 @@ namespace void node_impl::add_router_node(udp::endpoint router) { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "adding router node: " << router; +#endif m_table.add_router_node(router); } @@ -288,6 +302,9 @@ void node_impl::add_node(udp::endpoint node) void node_impl::announce(sha1_hash const& info_hash, int listen_port , boost::function const&, sha1_hash const&)> f) { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "announcing [ ih: " << info_hash << " p: " << listen_port << " ]" ; +#endif // search for nodes with ids close to id, and then invoke the // get_peers and then announce_peer rpc on them. closest_nodes::initiate(info_hash, m_settings.search_branching diff --git a/libtorrent/src/kademlia/routing_table.cpp b/libtorrent/src/kademlia/routing_table.cpp index c0ba68080..359577613 100644 --- a/libtorrent/src/kademlia/routing_table.cpp +++ b/libtorrent/src/kademlia/routing_table.cpp @@ -436,7 +436,8 @@ void routing_table::find_node(node_id const& target routing_table::iterator routing_table::begin() const { - return iterator(m_buckets.begin(), m_buckets.end()); + // +1 to avoid ourself + return iterator(m_buckets.begin() + 1, m_buckets.end()); } routing_table::iterator routing_table::end() const diff --git a/libtorrent/src/kademlia/traversal_algorithm.cpp b/libtorrent/src/kademlia/traversal_algorithm.cpp index b0d3c5e74..8849b155b 100644 --- a/libtorrent/src/kademlia/traversal_algorithm.cpp +++ b/libtorrent/src/kademlia/traversal_algorithm.cpp @@ -51,7 +51,12 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig { if (m_failed.find(addr) != m_failed.end()) return; - result const entry(id, addr, flags); + result entry(id, addr, flags); + if (entry.id.is_all_zeros()) + { + entry.id = generate_id(); + entry.flags |= result::no_id; + } std::vector::iterator i = std::lower_bound( m_results.begin() @@ -83,6 +88,7 @@ boost::pool<>& traversal_algorithm::allocator() const void traversal_algorithm::traverse(node_id const& id, udp::endpoint addr) { + TORRENT_ASSERT(!id.is_all_zeros()); add_entry(id, addr, 0); } @@ -100,6 +106,7 @@ void traversal_algorithm::failed(node_id const& id, bool prevent_request) { m_invoke_count--; + TORRENT_ASSERT(!id.is_all_zeros()); std::vector::iterator i = std::find_if( m_results.begin() , m_results.end() @@ -119,6 +126,10 @@ void traversal_algorithm::failed(node_id const& id, bool prevent_request) #ifdef TORRENT_DHT_VERBOSE_LOGGING TORRENT_LOG(traversal) << "failed: " << i->id << " " << i->addr; #endif + // don't tell the routing table about + // node ids that we just generated ourself + if ((i->flags & result::no_id) == 0) + m_table.node_failed(id); m_results.erase(i); } if (prevent_request) @@ -126,10 +137,6 @@ void traversal_algorithm::failed(node_id const& id, bool prevent_request) --m_branch_factor; if (m_branch_factor <= 0) m_branch_factor = 1; } - else - { - m_table.node_failed(id); - } add_requests(); if (m_invoke_count == 0) done(); } diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index dbc6f4e43..4cd0e4435 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -1434,10 +1434,8 @@ namespace libtorrent if (t->alerts().should_post(alert::fatal)) { - if (j.str != "write failed: No space left on device"){ - std::string err = "torrent paused: disk write error, " + j.str; - t->alerts().post_alert(file_error_alert(t->get_handle(), err)); - } + std::string err = "torrent paused: disk write error, " + j.str; + t->alerts().post_alert(file_error_alert(t->get_handle(), err)); } t->pause(); return; @@ -2402,6 +2400,7 @@ namespace libtorrent if (ret != r.length || m_torrent.expired()) { + if (j.buffer) m_ses.free_disk_buffer(j.buffer); boost::shared_ptr t = m_torrent.lock(); if (!t) { diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index af871d6bf..0a6b7176c 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -240,7 +240,7 @@ namespace detail if (m_ses.m_alerts.should_post(alert::info)) { m_ses.m_alerts.post_alert(torrent_checked_alert( - processing->torrent_ptr->get_handle() + t->torrent_ptr->get_handle() , "torrent finished checking")); } if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))