Browse Source

draft of dht get implementation (untested)

miguelfreitas
Miguel Freitas 12 years ago
parent
commit
8b6edd3c79
  1. 15
      libtorrent/include/libtorrent/kademlia/node.hpp
  2. 60
      libtorrent/src/kademlia/node.cpp

15
libtorrent/include/libtorrent/kademlia/node.hpp

@ -140,6 +140,18 @@ struct dht_mutable_item : dht_immutable_item
rsa_key key; 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 // internal
inline bool operator<(rsa_key const& lhs, rsa_key const& rhs) 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<node_id, torrent_entry> table_t; typedef std::map<node_id, torrent_entry> table_t;
typedef std::map<node_id, dht_immutable_item> dht_immutable_table_t; typedef std::map<node_id, dht_immutable_item> dht_immutable_table_t;
typedef std::map<node_id, dht_mutable_item> dht_mutable_table_t; typedef std::map<node_id, dht_mutable_item> dht_mutable_table_t;
typedef std::vector<dht_storage_item> dht_storage_list_t;
typedef std::map<node_id, dht_storage_list_t> dht_storage_table_t;
public: public:
node_impl(alert_dispatcher* alert_disp, udp_socket_interface* sock node_impl(alert_dispatcher* alert_disp, udp_socket_interface* sock
@ -298,6 +312,7 @@ private:
table_t m_map; table_t m_map;
dht_immutable_table_t m_immutable_table; dht_immutable_table_t m_immutable_table;
dht_mutable_table_t m_mutable_table; dht_mutable_table_t m_mutable_table;
dht_storage_table_t m_storage_table;
ptime m_last_tracker_tick; ptime m_last_tracker_tick;

60
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<char const*, int> 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 else
{ {
// if we don't recognize the message but there's a // if we don't recognize the message but there's a

Loading…
Cancel
Save