diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index 97b8b890..8d9faccf 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -140,6 +140,18 @@ struct dht_mutable_item : dht_immutable_item rsa_key key; }; +struct dht_storage_item +{ + dht_storage_item() : p(), sig_p(), sig_user() {} + std::string p; + std::string sig_p; + std::string sig_user; + // the last time we heard about this + //ptime last_seen; +}; + + + // internal inline bool operator<(rsa_key const& lhs, rsa_key const& rhs) { @@ -188,6 +200,8 @@ class TORRENT_EXTRA_EXPORT node_impl : boost::noncopyable typedef std::map table_t; typedef std::map dht_immutable_table_t; typedef std::map dht_mutable_table_t; +typedef std::vector dht_storage_list_t; +typedef std::map dht_storage_table_t; public: node_impl(alert_dispatcher* alert_disp, udp_socket_interface* sock @@ -298,6 +312,7 @@ private: table_t m_map; dht_immutable_table_t m_immutable_table; dht_mutable_table_t m_mutable_table; + dht_storage_table_t m_storage_table; ptime m_last_tracker_tick; diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index ab149019..933a134e 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -1033,6 +1033,66 @@ void node_impl::incoming_request(msg const& m, entry& e) } } } + else if (strcmp(query, "getData") == 0) + { + key_desc_t msg_desc[] = { + {"justtoken", lazy_entry::int_t, 0, key_desc_t::optional}, + {"target", lazy_entry::dict_t, 0, key_desc_t::parse_children}, + {"n", lazy_entry::string_t, 0, 0}, + {"r", lazy_entry::string_t, 0, 0}, + {"t", lazy_entry::string_t, 0, 0}, + }; + + // attempt to parse the message + lazy_entry const* msg_keys[5]; + if (!verify_message(arg_ent, msg_desc, msg_keys, 5, error_string, sizeof(error_string))) + { + incoming_error(e, error_string); + return; + } + + // "target" must be a dict of 3 entries + if (msg_keys[1]->dict_size() != 3) { + incoming_error(e, "target dict size != 3"); + return; + } + + // target id is hash of bencoded dict "target" + std::pair buf = msg_keys[1]->data_section(); + sha1_hash target(std::string(buf.first,buf.second)); + + bool justtoken = false; + if (msg_keys[0] && msg_keys[0]->int_value() != 0) justtoken = true; + + fprintf(stderr, "GET target: %s = {%s,%s,%s}\n" + , to_hex(target.to_string()).c_str() + , msg_keys[2], msg_keys[3], msg_keys[4]); + + reply["token"] = generate_token(m.addr, msg_keys[0]->string_ptr()); + + nodes_t n; + // always return nodes as well as peers + m_table.find_node(target, n, 0); + write_nodes_entry(reply, n); + + dht_storage_table_t::iterator i = m_storage_table.find(target); + if (i != m_storage_table.end()) + { + 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"] = bdecode(j->sig_p.begin(), j->sig_p.end()); + v["sig_user"] = bdecode(j->sig_user.begin(), j->sig_user.end()); + values.push_back(v); + } + } + } else { // if we don't recognize the message but there's a