From 662c5fa83315b92e99bc5e97c0d192ce27812c61 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Fri, 9 Aug 2013 21:34:00 -0300 Subject: [PATCH] big announce / getPeers change 1) getPeers is obsolete, peers are obtained from getData with r="tracker", t="m" 2) announce api of node.cpp is used to update our own memory table (of the tracker) 3) announce api of node.cpp only do getDate/announce to the network if peer is the local one 4) announcement rpc (to the network) might be removed in future (not sure) --- .../libtorrent/kademlia/dht_tracker.hpp | 3 +- .../include/libtorrent/kademlia/find_data.hpp | 3 +- .../include/libtorrent/kademlia/node.hpp | 6 +- libtorrent/src/kademlia/dht_tracker.cpp | 5 +- libtorrent/src/kademlia/find_data.cpp | 8 +- libtorrent/src/kademlia/node.cpp | 100 +++++++++++------- libtorrent/src/kademlia/refresh.cpp | 2 +- libtorrent/src/torrent.cpp | 4 +- 8 files changed, 82 insertions(+), 49 deletions(-) diff --git a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp index 5bce8841..b63e47d8 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp @@ -90,7 +90,8 @@ namespace libtorrent { namespace dht entry state() const; - void announce(sha1_hash const& ih, int listen_port, bool seed + void announce(std::string const& trackerName, sha1_hash const& ih + , address addr, int listen_port, bool seed, bool myself , boost::function const&)> f); void putData(std::string const &username, std::string const &resource, bool multi, diff --git a/libtorrent/include/libtorrent/kademlia/find_data.hpp b/libtorrent/include/libtorrent/kademlia/find_data.hpp index d78abf21..e58278e7 100644 --- a/libtorrent/include/libtorrent/kademlia/find_data.hpp +++ b/libtorrent/include/libtorrent/kademlia/find_data.hpp @@ -69,7 +69,7 @@ public: void got_write_token(node_id const& n, std::string const& write_token) { m_write_tokens[n] = write_token; } - find_data(node_impl& node, node_id target + find_data(node_impl& node, const std::string &trackerName, node_id target , data_callback const& dcallback , nodes_callback const& ncallback , bool noseeds); @@ -89,6 +89,7 @@ private: data_callback m_data_callback; nodes_callback m_nodes_callback; std::map m_write_tokens; + std::string m_trackerName; node_id const m_target; bool m_done:1; bool m_got_peers:1; diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index cc9cd09c..fbf712f5 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -210,7 +210,8 @@ public: { m_table.print_state(os); } #endif - void announce(sha1_hash const& info_hash, int listen_port, bool seed + void announce(std::string const& trackerName, sha1_hash const& info_hash + , address addr, int listen_port, bool seed, bool myself , boost::function const&)> f); void putData(std::string const &username, std::string const &resource, bool multi, @@ -263,8 +264,7 @@ protected: void lookup_peers(sha1_hash const& info_hash, int prefix, entry& reply , bool noseed, bool scrape) const; - bool lookup_torrents(sha1_hash const& target, entry& reply - , char* tags) const; + void add_peer(std::string const& name, sha1_hash const& info_hash, address addr, int port, bool seed); dht_settings const& m_settings; diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index ee1e7e36..9fa21b3d 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -416,10 +416,11 @@ namespace libtorrent { namespace dht #endif } - void dht_tracker::announce(sha1_hash const& ih, int listen_port, bool seed + void dht_tracker::announce(std::string const& trackerName, sha1_hash const& ih + , address addr, int listen_port, bool seed, bool myself , boost::function const&)> f) { - m_dht.announce(ih, listen_port, seed, f); + m_dht.announce(trackerName, ih, addr, listen_port, seed, myself, f); } void dht_tracker::putData(std::string const &username, std::string const &resource, bool multi, diff --git a/libtorrent/src/kademlia/find_data.cpp b/libtorrent/src/kademlia/find_data.cpp index c4e6b21c..1ef1f05b 100644 --- a/libtorrent/src/kademlia/find_data.cpp +++ b/libtorrent/src/kademlia/find_data.cpp @@ -171,6 +171,7 @@ static void add_entry_fun(void* userdata, node_entry const& e) find_data::find_data( node_impl& node + , std::string const& trackerName , node_id target , data_callback const& dcallback , nodes_callback const& ncallback @@ -178,6 +179,7 @@ find_data::find_data( : traversal_algorithm(node, target) , m_data_callback(dcallback) , m_nodes_callback(ncallback) + , m_trackerName(trackerName) , m_target(target) , m_done(false) , m_got_peers(false) @@ -206,8 +208,12 @@ bool find_data::invoke(observer_ptr o) entry e; e["z"] = "q"; - e["q"] = "getPeers"; + e["q"] = "getData"; // "getPeers" entry& a = e["x"]; + entry& target = a["target"]; + target["n"] = m_trackerName; + target["r"] = "tracker"; + target["t"] = "m"; a["infoHash"] = m_target.to_string(); if (m_noseeds) a["noseed"] = 1; return m_node.m_rpc.invoke(e, o->target_ep(), o); diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 51417ec5..c567387c 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -417,18 +417,23 @@ void node_impl::add_node(udp::endpoint node) m_rpc.invoke(e, node, o); } -void node_impl::announce(sha1_hash const& info_hash, int listen_port, bool seed +void node_impl::announce(std::string const& trackerName, sha1_hash const& info_hash, address addr, int listen_port, bool seed, bool myself , boost::function 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 or with peers - // for info-hash id. then send announce_peer to them. - boost::intrusive_ptr ta(new find_data(*this, info_hash, f - , boost::bind(&announce_fun, _1, boost::ref(*this) - , listen_port, info_hash, seed), seed)); - ta->start(); + add_peer( trackerName, info_hash, addr, listen_port, seed ); + + // do not announce other peers, just add them to our local m_map. + if( myself ) { + // search for nodes with ids close to id or with peers + // for info-hash id. then send announce_peer to them. + boost::intrusive_ptr ta(new find_data(*this, trackerName, info_hash, f + , boost::bind(&announce_fun, _1, boost::ref(*this) + , listen_port, info_hash, seed), seed)); + ta->start(); + } } void node_impl::putData(std::string const &username, std::string const &resource, bool multi, @@ -592,6 +597,27 @@ 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) +{ + torrent_entry& v = m_map[info_hash]; + + // the peer announces a torrent name, and we don't have a name + // for this torrent. Store it. + if (name.size() && v.name.empty()) + { + v.name = name; + if (v.name.size() > 50) v.name.resize(50); + } + + peer_entry peer; + peer.addr = tcp::endpoint(addr, port); + peer.added = time_now(); + peer.seed = seed; + std::set::iterator i = v.peers.find(peer); + if (i != v.peers.end()) v.peers.erase(i++); + v.peers.insert(i, peer); +} + namespace { void write_nodes_entry(entry& r, nodes_t const& nodes) @@ -774,6 +800,7 @@ void node_impl::incoming_request(msg const& m, entry& e) // we already have 't' and 'id' in the response // no more left to add } + /* else if (strcmp(query, "getPeers") == 0) { key_desc_t msg_desc[] = { @@ -813,7 +840,7 @@ void node_impl::incoming_request(msg const& m, entry& e) TORRENT_LOG(node) << " values: " << reply["values"].list().size(); } #endif - } + }*/ else if (strcmp(query, "findNode") == 0) { key_desc_t msg_desc[] = { @@ -909,24 +936,10 @@ void node_impl::incoming_request(msg const& m, entry& e) } m_map.erase(candidate); } - torrent_entry& v = m_map[info_hash]; - // the peer announces a torrent name, and we don't have a name - // for this torrent. Store it. - if (msg_keys[3] && v.name.empty()) - { - std::string name = msg_keys[3]->string_value(); - if (name.size() > 50) name.resize(50); - v.name = name; - } + 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()); - peer_entry peer; - peer.addr = tcp::endpoint(m.addr.address(), port); - peer.added = time_now(); - peer.seed = msg_keys[4] && msg_keys[4]->int_value(); - std::set::iterator i = v.peers.find(peer); - if (i != v.peers.end()) v.peers.erase(i++); - v.peers.insert(i, peer); #ifdef TORRENT_DHT_VERBOSE_LOGGING ++g_announces; #endif @@ -1135,6 +1148,12 @@ void node_impl::incoming_request(msg const& m, entry& e) return; } + if (msg_keys[mk_t]->string_value() != "s" && + msg_keys[mk_t]->string_value() != "m") { + incoming_error(e, "invalid target.t value"); + return; + } + // target id is hash of bencoded dict "target" std::pair targetbuf = msg_keys[mk_target]->data_section(); sha1_hash target = hasher(targetbuf.first,targetbuf.second).final(); @@ -1159,22 +1178,27 @@ void node_impl::incoming_request(msg const& m, entry& e) write_nodes_entry(reply, n); bool hasData = false; - dht_storage_table_t::iterator i = m_storage_table.find(target); - if (i != m_storage_table.end()) - { - hasData = true; - reply["values"] = entry::list_type(); - entry::list_type &values = reply["values"].list(); - dht_storage_list_t const& lsto = i->second; - for (dht_storage_list_t::const_iterator j = lsto.begin() - , end(lsto.end()); j != end && !justtoken; ++j) + if( msg_keys[mk_r]->string_value() == "tracker" ) { + lookup_peers(target, 20, reply, false, false); + } else { + dht_storage_table_t::iterator i = m_storage_table.find(target); + if (i != m_storage_table.end()) { - entry::dictionary_type v; - v["p"] = bdecode(j->p.begin(), j->p.end()); - v["sig_p"] = j->sig_p; - v["sig_user"] = j->sig_user; - values.push_back(v); + hasData = true; + reply["values"] = entry::list_type(); + entry::list_type &values = reply["values"].list(); + + dht_storage_list_t const& lsto = i->second; + for (dht_storage_list_t::const_iterator j = lsto.begin() + , end(lsto.end()); j != end && !justtoken; ++j) + { + entry::dictionary_type v; + v["p"] = bdecode(j->p.begin(), j->p.end()); + v["sig_p"] = j->sig_p; + v["sig_user"] = j->sig_user; + values.push_back(v); + } } } diff --git a/libtorrent/src/kademlia/refresh.cpp b/libtorrent/src/kademlia/refresh.cpp index fb7faae6..722cb757 100644 --- a/libtorrent/src/kademlia/refresh.cpp +++ b/libtorrent/src/kademlia/refresh.cpp @@ -49,7 +49,7 @@ refresh::refresh( node_impl& node , node_id target , done_callback const& callback) - : find_data(node, target, find_data::data_callback(), callback, false) + : find_data(node, std::string(), target, find_data::data_callback(), callback, false) { } diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 4defa372..500319cc 100644 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -2245,8 +2245,8 @@ namespace libtorrent #endif boost::weak_ptr self(shared_from_this()); - m_ses.m_dht->announce(m_torrent_file->info_hash() - , port, is_seed() + m_ses.m_dht->announce(m_torrent_file->name(), m_torrent_file->info_hash() + , m_ses.external_address().external_address(address_v4()), port, is_seed(), true , boost::bind(&torrent::on_dht_announce_response_disp, self, _1)); }