mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 15:27:57 +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/kademlia/find_data.hpp"
|
||||||
#include "libtorrent/rsa.hpp"
|
#include "libtorrent/rsa.hpp"
|
||||||
|
|
||||||
|
#include "../../src/twister.h"
|
||||||
|
|
||||||
namespace libtorrent { namespace dht
|
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)
|
else if (strcmp(query, "getData") == 0)
|
||||||
{
|
{
|
||||||
key_desc_t msg_desc[] = {
|
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},
|
{"r", lazy_entry::string_t, 0, 0},
|
||||||
{"t", 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
|
// attempt to parse the message
|
||||||
lazy_entry const* msg_keys[5];
|
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
|
// "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");
|
incoming_error(e, "target dict size != 3");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// target id is hash of bencoded dict "target"
|
// target id is hash of bencoded dict "target"
|
||||||
std::pair<char const*, int> buf = msg_keys[1]->data_section();
|
std::pair<char const*, int> targetbuf = msg_keys[mk_target]->data_section();
|
||||||
sha1_hash target(std::string(buf.first,buf.second));
|
sha1_hash target = hasher(targetbuf.first,targetbuf.second).final();
|
||||||
|
|
||||||
bool justtoken = false;
|
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"
|
fprintf(stderr, "GET target: %s = {%s,%s,%s}\n"
|
||||||
, to_hex(target.to_string()).c_str()
|
, 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;
|
nodes_t n;
|
||||||
// always return nodes as well as peers
|
// 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());
|
return (pubkeyRec.GetID() == pubkey.GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getBestHeight()
|
||||||
|
{
|
||||||
|
return nBestHeight;
|
||||||
|
}
|
||||||
|
@ -17,5 +17,6 @@ void stopSessionTorrent();
|
|||||||
std::string createSignature(std::string &strMessage, std::string &strUsername);
|
std::string createSignature(std::string &strMessage, std::string &strUsername);
|
||||||
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
|
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
|
||||||
|
|
||||||
|
int getBestHeight();
|
||||||
|
|
||||||
#endif // TWISTER_H
|
#endif // TWISTER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user