mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 07:17:53 +00:00
draft for dht putdata
This commit is contained in:
parent
8b6edd3c79
commit
8b3368da1f
@ -53,6 +53,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/kademlia/find_data.hpp"
|
||||
#include "libtorrent/rsa.hpp"
|
||||
|
||||
#include "../../src/twister.h"
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
||||
@ -1033,6 +1035,148 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(query, "putData") == 0)
|
||||
{
|
||||
const static key_desc_t msg_desc[] = {
|
||||
{"token", lazy_entry::string_t, 0, 0},
|
||||
{"sig_p", lazy_entry::string_t, 0, 0},
|
||||
{"sig_user", lazy_entry::string_t, 0, 0},
|
||||
{"p", lazy_entry::dict_t, 0, key_desc_t::parse_children},
|
||||
{"v", lazy_entry::none_t, 0, 0},
|
||||
{"seq", lazy_entry::int_t, 0, key_desc_t::optional},
|
||||
{"time", lazy_entry::int_t, 0, 0},
|
||||
{"height", lazy_entry::int_t, 0, 0},
|
||||
{"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},
|
||||
};
|
||||
enum {mk_token=0, mk_sig_p, mk_sig_user, mk_p, mk_v,
|
||||
mk_seq, mk_time, mk_height, mk_target, mk_n,
|
||||
mk_r, mk_t};
|
||||
|
||||
// attempt to parse the message
|
||||
lazy_entry const* msg_keys[12];
|
||||
if (!verify_message(arg_ent, msg_desc, msg_keys, 12, error_string, sizeof(error_string)))
|
||||
{
|
||||
incoming_error(e, error_string);
|
||||
return;
|
||||
}
|
||||
|
||||
// is this a multi-item?
|
||||
bool multi = (msg_keys[mk_t]->string_value() == "m");
|
||||
|
||||
// pointer and length to the whole entry
|
||||
std::pair<char const*, int> buf = msg_keys[mk_p]->data_section();
|
||||
if (buf.second > 767 || buf.second <= 0)
|
||||
{
|
||||
incoming_error(e, "message too big");
|
||||
return;
|
||||
}
|
||||
|
||||
// "target" must be a dict of 3 entries
|
||||
if (msg_keys[mk_target]->dict_size() != 3) {
|
||||
incoming_error(e, "target dict size != 3");
|
||||
return;
|
||||
}
|
||||
|
||||
// target id is hash of bencoded dict "target"
|
||||
std::pair<char const*, int> targetbuf = msg_keys[1]->data_section();
|
||||
sha1_hash target = hasher(targetbuf.first,targetbuf.second).final();
|
||||
|
||||
fprintf(stderr, "PUT target: %s = {%s,%s,%s}\n"
|
||||
, to_hex(target.to_string()).c_str()
|
||||
, msg_keys[mk_n], msg_keys[mk_r], msg_keys[mk_t]);
|
||||
|
||||
// verify the write-token. tokens are only valid to write to
|
||||
// specific target hashes. it must match the one we got a "get" for
|
||||
if (!verify_token(msg_keys[mk_token]->string_value(), (char const*)&target[0], m.addr))
|
||||
{
|
||||
incoming_error(e, "invalid token");
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<char const*, int> bufp = msg_keys[mk_p]->data_section();
|
||||
std::string str_p(bufp.first,bufp.second);
|
||||
if (!verifySignature(str_p,
|
||||
msg_keys[mk_sig_user]->string_value(),
|
||||
msg_keys[mk_sig_p]->string_value())) {
|
||||
incoming_error(e, "invalid signature");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!multi && msg_keys[mk_sig_user]->string_value() !=
|
||||
msg_keys[mk_n]->string_value() ) {
|
||||
incoming_error(e, "only owner is allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!multi || !msg_keys[mk_seq] || msg_keys[mk_seq]->int_value() <= 0) {
|
||||
incoming_error(e, "seq is required");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_keys[mk_height]->int_value() > getBestHeight() ) {
|
||||
incoming_error(e, "future messages not allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
dht_storage_table_t::iterator i = m_storage_table.find(target);
|
||||
if (i == m_storage_table.end()) {
|
||||
// make sure we don't add too many items
|
||||
if (int(m_storage_table.size()) >= m_settings.max_dht_items)
|
||||
{
|
||||
// erase one? preferably a multi
|
||||
}
|
||||
|
||||
dht_storage_item item;
|
||||
item.p = str_p;
|
||||
item.sig_p = msg_keys[mk_sig_p]->string_value();
|
||||
item.sig_user = msg_keys[mk_sig_user]->string_value();
|
||||
|
||||
dht_storage_list_t to_add;
|
||||
to_add.push_back(item);
|
||||
|
||||
boost::tie(i, boost::tuples::ignore) = m_storage_table.insert(
|
||||
std::make_pair(target, to_add));
|
||||
} else {
|
||||
dht_storage_list_t & lsto = i->second;
|
||||
|
||||
// if not multi, seq must increase
|
||||
if(!multi) {
|
||||
dht_storage_item &item = lsto[0];
|
||||
// FIXME: Implement
|
||||
// if( msg_keys[mk_seq]->int_value() > lsto[0].p.seq ) etc
|
||||
if( msg_keys[mk_seq]->int_value() ) {
|
||||
item.p = str_p;
|
||||
item.sig_p = msg_keys[mk_sig_p]->string_value();
|
||||
item.sig_user = msg_keys[mk_sig_user]->string_value();
|
||||
} else {
|
||||
incoming_error(e, "old sequence number");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dht_storage_list_t::iterator j = lsto.begin(), end(lsto.end());
|
||||
for (; j != end; ++j)
|
||||
{
|
||||
// compare p contents before adding to the list
|
||||
if( j->p == str_p ) break;
|
||||
}
|
||||
if(j == end) {
|
||||
// new entry
|
||||
dht_storage_item item;
|
||||
item.p = str_p;
|
||||
item.sig_p = msg_keys[mk_sig_p]->string_value();
|
||||
item.sig_user = msg_keys[mk_sig_user]->string_value();
|
||||
lsto.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_table.node_seen(id, m.addr, 0xffff);
|
||||
|
||||
//f->last_seen = time_now();
|
||||
}
|
||||
else if (strcmp(query, "getData") == 0)
|
||||
{
|
||||
key_desc_t msg_desc[] = {
|
||||
@ -1042,6 +1186,7 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
||||
{"r", lazy_entry::string_t, 0, 0},
|
||||
{"t", lazy_entry::string_t, 0, 0},
|
||||
};
|
||||
enum {mk_justtoken=0, mk_target, mk_n, mk_r, mk_t};
|
||||
|
||||
// attempt to parse the message
|
||||
lazy_entry const* msg_keys[5];
|
||||
@ -1052,23 +1197,23 @@ void node_impl::incoming_request(msg const& m, entry& e)
|
||||
}
|
||||
|
||||
// "target" must be a dict of 3 entries
|
||||
if (msg_keys[1]->dict_size() != 3) {
|
||||
if (msg_keys[mk_target]->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));
|
||||
std::pair<char const*, int> targetbuf = msg_keys[mk_target]->data_section();
|
||||
sha1_hash target = hasher(targetbuf.first,targetbuf.second).final();
|
||||
|
||||
bool justtoken = false;
|
||||
if (msg_keys[0] && msg_keys[0]->int_value() != 0) justtoken = true;
|
||||
if (msg_keys[mk_justtoken] && msg_keys[mk_justtoken]->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]);
|
||||
, msg_keys[mk_n], msg_keys[mk_r], msg_keys[mk_t]);
|
||||
|
||||
reply["token"] = generate_token(m.addr, msg_keys[0]->string_ptr());
|
||||
reply["token"] = generate_token(m.addr, target.to_string().c_str());
|
||||
|
||||
nodes_t n;
|
||||
// always return nodes as well as peers
|
||||
|
@ -267,3 +267,8 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna
|
||||
|
||||
return (pubkeyRec.GetID() == pubkey.GetID());
|
||||
}
|
||||
|
||||
int getBestHeight()
|
||||
{
|
||||
return nBestHeight;
|
||||
}
|
||||
|
@ -17,5 +17,6 @@ void stopSessionTorrent();
|
||||
std::string createSignature(std::string &strMessage, std::string &strUsername);
|
||||
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
|
||||
|
||||
int getBestHeight();
|
||||
|
||||
#endif // TWISTER_H
|
||||
|
Loading…
Reference in New Issue
Block a user