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)
This commit is contained in:
Miguel Freitas 2013-08-09 21:34:00 -03:00
parent 6af8185112
commit 662c5fa833
8 changed files with 82 additions and 49 deletions

View File

@ -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<void(std::vector<tcp::endpoint> const&)> f);
void putData(std::string const &username, std::string const &resource, bool multi,

View File

@ -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<node_id, std::string> m_write_tokens;
std::string m_trackerName;
node_id const m_target;
bool m_done:1;
bool m_got_peers:1;

View File

@ -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<void(std::vector<tcp::endpoint> 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;

View File

@ -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<void(std::vector<tcp::endpoint> 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,

View File

@ -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);

View File

@ -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<void(std::vector<tcp::endpoint> 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<find_data> 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<find_data> 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<peer_entry>::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<peer_entry>::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<char const*, int> 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);
}
}
}

View File

@ -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)
{
}

View File

@ -2245,8 +2245,8 @@ namespace libtorrent
#endif
boost::weak_ptr<torrent> 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));
}