diff --git a/libtorrent/include/libtorrent/kademlia/dht_get.hpp b/libtorrent/include/libtorrent/kademlia/dht_get.hpp index 770f98a0..0e88d89a 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_get.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_get.hpp @@ -71,7 +71,7 @@ public: { m_write_tokens[n] = write_token; } dht_get(node_impl& node - , std::string &targetUser, std::string &targetResource, bool multi + , std::string const &targetUser, std::string const &targetResource, bool multi , data_callback const& dcallback , nodes_callback const& ncallback , bool justToken); diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index 8d9faccf..9d2af75d 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -245,6 +245,11 @@ public: void announce(sha1_hash const& info_hash, int listen_port, bool seed , boost::function const&)> f); + void putData(std::string const &username, std::string const &resource, bool multi, + entry const &value, std::string const &sig_user, + int timeutc, int seq, + boost::function f); + bool verify_token(std::string const& token, char const* info_hash , udp::endpoint const& addr); diff --git a/libtorrent/src/kademlia/dht_get.cpp b/libtorrent/src/kademlia/dht_get.cpp index 1ed1b5e0..7cdbebc7 100644 --- a/libtorrent/src/kademlia/dht_get.cpp +++ b/libtorrent/src/kademlia/dht_get.cpp @@ -178,8 +178,8 @@ static void add_entry_fun(void* userdata, node_entry const& e) dht_get::dht_get( node_impl& node - , std::string &targetUser - , std::string &targetResource + , std::string const &targetUser + , std::string const &targetResource , bool multi , data_callback const& dcallback , nodes_callback const& ncallback diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 60becfe9..c41f7340 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/kademlia/refresh.hpp" #include "libtorrent/kademlia/find_data.hpp" +#include "libtorrent/kademlia/dht_get.hpp" #include "libtorrent/rsa.hpp" #include "../../src/twister.h" @@ -297,6 +298,63 @@ namespace node.m_rpc.invoke(e, i->first.ep(), o); } } + + void putData_fun(std::vector > const& v, + node_impl& node, + std::string const &username, std::string const &resource, bool multi, + entry const &value, std::string const &sig_user, + int timeutc, int seq) + { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "sending putData [ username: " << username + << " res: " << resource + << " nodes: " << v.size() << " ]" ; +#endif + + // create a dummy traversal_algorithm + boost::intrusive_ptr algo( + new traversal_algorithm(node, (node_id::min)())); + + // store on the first k nodes + for (std::vector >::const_iterator i = v.begin() + , end(v.end()); i != end; ++i) + { +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << " putData-distance: " << (160 - distance_exp(ih, i->first.id)); +#endif + + void* ptr = node.m_rpc.allocate_observer(); + if (ptr == 0) return; + observer_ptr o(new (ptr) announce_observer(algo, i->first.ep(), i->first.id)); +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + o->m_in_constructor = false; +#endif + entry e; + e["z"] = "q"; + e["q"] = "putData"; + entry& a = e["x"]; + a["token"] = i->second; + + entry& p = a["p"]; + entry& target = p["target"]; + target["n"] = username; + target["r"] = resource; + target["t"] = (multi) ? "m" : "s"; + if (seq >= 0 && !multi) p["seq"] = seq; + p["v"] = value; + p["time"] = timeutc; + p["height"] = getBestHeight()-1; // be conservative + + std::vector pbuf; + bencode(std::back_inserter(pbuf), p); + std::string sig_p = createSignature(std::string(pbuf.data(),pbuf.size()), sig_user); + + a["sig_p"] = sig_p; + a["sig_user"] = sig_user; + + node.m_rpc.invoke(e, i->first.ep(), o); + } + } } void node_impl::add_router_node(udp::endpoint router) @@ -343,6 +401,23 @@ void node_impl::announce(sha1_hash const& info_hash, int listen_port, bool seed ta->start(); } +void node_impl::putData(std::string const &username, std::string const &resource, bool multi, + entry const &value, std::string const &sig_user, + int timeutc, int seq, + boost::function f) +{ +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(node) << "putData [ username: " << info_hash << " res: " << resource << " ]" ; +#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 dht_get(*this, username, resource, multi, f, + boost::bind(&putData_fun, _1, boost::ref(*this), + username, resource, multi, + value, sig_user, timeutc, seq), true)); + ta->start(); +} + void node_impl::tick() { node_id target;