diff --git a/libtorrent/include/libtorrent/kademlia/dht_get.hpp b/libtorrent/include/libtorrent/kademlia/dht_get.hpp index 0e88d89a..6bac7357 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_get.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_get.hpp @@ -64,7 +64,7 @@ public: typedef boost::function data_callback; // callback to receive all write tokens - typedef boost::function > const&, bool)> nodes_callback; + typedef boost::function > const&, bool, node_id)> nodes_callback; void got_data(entry::list_type const& values_list); void got_write_token(node_id const& n, std::string const& write_token) diff --git a/libtorrent/src/kademlia/dht_get.cpp b/libtorrent/src/kademlia/dht_get.cpp index c3ce5269..9f55a807 100644 --- a/libtorrent/src/kademlia/dht_get.cpp +++ b/libtorrent/src/kademlia/dht_get.cpp @@ -269,7 +269,7 @@ void dht_get::done() results.push_back(std::make_pair(node_entry(o->id(), o->target_ep()), j->second)); --num_results; } - m_nodes_callback(results, m_got_data); + m_nodes_callback(results, m_got_data, target()); traversal_algorithm::done(); } diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 8ef5490a..de8235a0 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -367,10 +367,22 @@ namespace } void getDataDone_fun(std::vector > const& node_results, - bool got_data, node_impl& node, + bool got_data, node_id target, node_impl& node, boost::function fdone) { bool is_neighbor = false; + + // check distance between target, nodes and our own id + // n is sorted from closer(begin) to more distant (back) + if( node_results.size() < node.m_table.bucket_size() ) { + is_neighbor = true; + } else { + node_id dFarther = distance(node_results.back().first.id, target); + node_id dOwn = distance(node.nid(), target); + if( dOwn < dFarther ) + is_neighbor = true; + } + fdone(is_neighbor, got_data); } } @@ -449,7 +461,7 @@ void node_impl::getData(std::string const &username, std::string const &resource // for info-hash id. callback is used to return data. boost::intrusive_ptr ta(new dht_get(*this, username, resource, multi, fdata, - boost::bind(&getDataDone_fun, _1, _2, boost::ref(*this), fdone), false)); + boost::bind(&getDataDone_fun, _1, _2, _3, boost::ref(*this), fdone), false)); ta->start(); } diff --git a/src/twister.cpp b/src/twister.cpp index 1cf540e8..9bfd2176 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -31,7 +31,7 @@ static session *ses = NULL; static CCriticalSection cs_dhtgetMap; static map m_dhtgetMap; - +static map m_specialResources; uint256 dhtTargetHash(std::string const &username, std::string const &resource, std::string const &type) { @@ -281,17 +281,21 @@ void ThreadSessionAlerts() r && r->type() == entry::string_t && t && t->type() == entry::string_t) { - // now we do our own search to make sure we are really close to this target - uint256 th = dhtTargetHash(n->string(), r->string(), t->string()); + // if this is a special resource then start another dhtget to make + // sure we are really its neighbor. don't do it needless. + if( m_specialResources.count(r->string()) ) { + // now we do our own search to make sure we are really close to this target + uint256 th = dhtTargetHash(n->string(), r->string(), t->string()); - if( !neighborCheck.count(th) ) { - printf("possiblyNeighbor of [%s,%s,%s]\n", - n->string().c_str(), - r->string().c_str(), - t->string().c_str()); + if( !neighborCheck.count(th) ) { + printf("possiblyNeighbor of [%s,%s,%s] - starting a new dhtget to be sure\n", + n->string().c_str(), + r->string().c_str(), + t->string().c_str()); - neighborCheck[th] = gd->m_target; - ses->dht_getData(n->string(), r->string(), t->string() == "m"); + neighborCheck[th] = gd->m_target; + ses->dht_getData(n->string(), r->string(), t->string() == "m"); + } } } @@ -318,6 +322,10 @@ void ThreadSessionAlerts() } } + if( dd->m_is_neighbor && m_specialResources.count(dd->m_resource) ) { + // Do something! + printf("Neighbor of special resource - do something!\n"); + } continue; } @@ -342,6 +350,8 @@ void startSessionTorrent(boost::thread_group& threadGroup) { printf("startSessionTorrent (waiting for external IP)\n"); + m_specialResources["tracker"] = true; + threadGroup.create_thread(boost::bind(&ThreadWaitExtIP)); threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes)); threadGroup.create_thread(boost::bind(&ThreadSessionAlerts));