diff --git a/libtorrent/include/libtorrent/kademlia/dht_get.hpp b/libtorrent/include/libtorrent/kademlia/dht_get.hpp index 6bac7357..0be2f554 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_get.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_get.hpp @@ -98,6 +98,8 @@ private: bool m_done:1; bool m_got_data:1; bool m_justToken:1; + + friend class dht_get_observer; }; class dht_get_observer : public observer diff --git a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp index ee8408ca..af580286 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp @@ -93,7 +93,7 @@ namespace libtorrent { namespace dht entry state() const; void announce(std::string const& trackerName, sha1_hash const& ih - , address addr, int listen_port, bool seed, bool myself + , address addr, int listen_port, bool seed, bool myself, int list_peers , boost::function const&)> f); void putData(std::string const &username, std::string const &resource, bool multi, diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index cb1fe9c4..231c8c3f 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -112,6 +112,7 @@ struct torrent_entry { std::string name; std::set peers; + int list_peers; // number of known peers (copied from torrent status) }; struct dht_storage_item @@ -215,7 +216,7 @@ public: #endif void announce(std::string const& trackerName, sha1_hash const& info_hash - , address addr, int listen_port, bool seed, bool myself + , address addr, int listen_port, bool seed, bool myself, int list_peers , boost::function const&)> f); void putData(std::string const &username, std::string const &resource, bool multi, @@ -268,7 +269,7 @@ protected: void lookup_peers(sha1_hash const& info_hash, int prefix, entry& reply , bool noseed, bool scrape) const; - void add_peer(std::string const& name, sha1_hash const& info_hash, address addr, int port, bool seed); + void add_peer(std::string const& name, sha1_hash const& info_hash, address addr, int port, bool seed, int list_peers); dht_settings const& m_settings; diff --git a/libtorrent/src/kademlia/dht_get.cpp b/libtorrent/src/kademlia/dht_get.cpp index 307fa6bd..d3b6224e 100644 --- a/libtorrent/src/kademlia/dht_get.cpp +++ b/libtorrent/src/kademlia/dht_get.cpp @@ -125,8 +125,34 @@ void dht_get_observer::reply(msg const& m) values_list.push_back(entry()); values_list.back() = *e; } - //printf("dht_get::reply from %s:%d with %d entries\n", m.addr.address().to_string().c_str(), m.addr.port(), values_list.size()); + //printf("dht_get::reply from %s:%d with %d entries\n", m.addr.address().to_string().c_str(), m.addr.port(), values_list.size()); static_cast(m_algorithm.get())->got_data(values_list); + } else { + // special case for trackers (non-signed content) + // pretend it is a normal dht resource to the caller + dht_get *dget( static_cast(m_algorithm.get()) ); + if( dget->m_targetResource == "tracker" && dget->m_multi ) { + int followers = r->dict_find_int_value("followers"); + if( followers ) { + entry::dictionary_type v; + v["followers"] = followers; + + entry::dictionary_type target; + target["n"] = dget->m_targetUser; + target["r"] = dget->m_targetResource; + target["t"] = dget->m_multi ? "m" : "s"; + + entry::dictionary_type p; + p["target"] = target; + p["v"] = v; + + entry::dictionary_type e; + e["p"] = p; + entry::list_type values_list; + values_list.push_back(e); + dget->got_data(values_list); + } + } } // look for nodes diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index 24459306..f6f451c0 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -427,10 +427,10 @@ namespace libtorrent { namespace dht } void dht_tracker::announce(std::string const& trackerName, sha1_hash const& ih - , address addr, int listen_port, bool seed, bool myself + , address addr, int listen_port, bool seed, bool myself, int list_peers , boost::function const&)> f) { - m_dht.announce(trackerName, ih, addr, listen_port, seed, myself, f); + m_dht.announce(trackerName, ih, addr, listen_port, seed, myself, list_peers, f); } void dht_tracker::putData(std::string const &username, std::string const &resource, bool multi, diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index f6fe01e7..26c07ae9 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -400,7 +400,7 @@ void node_impl::add_node(udp::endpoint node) m_rpc.invoke(e, node, o); } -void node_impl::announce(std::string const& trackerName, sha1_hash const& info_hash, address addr, int listen_port, bool seed, bool myself +void node_impl::announce(std::string const& trackerName, sha1_hash const& info_hash, address addr, int listen_port, bool seed, bool myself, int list_peers , boost::function const&)> f) { #ifdef TORRENT_DHT_VERBOSE_LOGGING @@ -410,7 +410,7 @@ void node_impl::announce(std::string const& trackerName, sha1_hash const& info_h // [MF] is_unspecified() is not always available. never mind. //if( !addr.is_unspecified() ) { - add_peer( trackerName, info_hash, addr, listen_port, seed ); + add_peer( trackerName, info_hash, addr, listen_port, seed, list_peers ); //} // do not announce other peers, just add them to our local m_map. @@ -762,6 +762,7 @@ void node_impl::lookup_peers(sha1_hash const& info_hash, int prefix, entry& repl torrent_entry const& v = i->second; if (!v.name.empty()) reply["n"] = v.name; + reply["followers"] = v.list_peers; if (scrape) { @@ -803,7 +804,7 @@ void node_impl::lookup_peers(sha1_hash const& info_hash, int prefix, entry& repl return; } -void node_impl::add_peer(std::string const &name, sha1_hash const& info_hash, address addr, int port, bool seed) +void node_impl::add_peer(std::string const &name, sha1_hash const& info_hash, address addr, int port, bool seed, int list_peers) { torrent_entry& v = m_map[info_hash]; @@ -814,6 +815,7 @@ void node_impl::add_peer(std::string const &name, sha1_hash const& info_hash, ad v.name = name; if (v.name.size() > 50) v.name.resize(50); } + if (list_peers) v.list_peers = list_peers; peer_entry peer; peer.addr = tcp::endpoint(addr, port); @@ -1144,7 +1146,7 @@ void node_impl::incoming_request(msg const& m, entry& e) } add_peer( msg_keys[3] ? msg_keys[3]->string_value() : std::string(), info_hash, - m.addr.address(), port, msg_keys[4] && msg_keys[4]->int_value()); + m.addr.address(), port, msg_keys[4] && msg_keys[4]->int_value(), 0); #ifdef TORRENT_DHT_VERBOSE_LOGGING ++g_announces; diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 71597a6c..ac76de61 100644 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -2073,7 +2073,7 @@ namespace libtorrent p->last_connected && (m_ses.session_time() - p->last_connected) < (4*3600); if( p->connectable && ( p->connection || connect_recently) ) { m_ses.m_dht->announce(name(), m_torrent_file->info_hash() - , p->address(), p->port, p->seed, false + , p->address(), p->port, p->seed, false, m_policy.num_peers() , boost::bind(&nop)); } } @@ -2086,8 +2086,8 @@ namespace libtorrent #endif boost::weak_ptr self(shared_from_this()); - m_ses.m_dht->announce(name(), m_torrent_file->info_hash() - , m_ses.external_address().external_address(address_v4()), port, is_seed(), true + m_ses.m_dht->announce(name(), m_torrent_file->info_hash() + , m_ses.external_address().external_address(address_v4()), port, is_seed(), true, m_policy.num_peers() , boost::bind(&torrent::on_dht_announce_response_disp, self, _1)); }