From 830a02c009749dc8ffab35782fc5d72d7441a563 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Mon, 5 Aug 2013 22:33:38 -0300 Subject: [PATCH] dht get/put kind of working. with json interface. amazing. --- libtorrent/src/kademlia/dht_get.cpp | 2 +- libtorrent/src/kademlia/node.cpp | 17 ++-- src/bitcoinrpc.cpp | 3 + src/bitcoinrpc.h | 2 + src/twister.cpp | 115 ++++++++++++++++++++++++++++ src/twister.h | 1 + 6 files changed, 133 insertions(+), 7 deletions(-) diff --git a/libtorrent/src/kademlia/dht_get.cpp b/libtorrent/src/kademlia/dht_get.cpp index 7cdbebc7..c3ce5269 100644 --- a/libtorrent/src/kademlia/dht_get.cpp +++ b/libtorrent/src/kademlia/dht_get.cpp @@ -125,7 +125,7 @@ void dht_get_observer::reply(msg const& m) values_list.push_back(entry()); values_list.back() = *e; } - + printf("dht_get::reply calling got_data with %d entries\n", values_list.size()); static_cast(m_algorithm.get())->got_data(values_list); } diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 1b71af87..07a6c78e 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -253,6 +253,11 @@ void node_impl::incoming(msg const& m) TORRENT_LOG(node) << "INCOMING ERROR: " << err->list_string_value_at(1); } #endif + lazy_entry const* err = m.message.dict_find_list("e"); + if (err && err->list_size() >= 2) + { + printf("INCOMING ERROR: %s\n", err->list_string_value_at(1).c_str()); + } break; } } @@ -1173,15 +1178,15 @@ void node_impl::incoming_request(msg const& m, entry& e) std::pair targetbuf = msg_keys[mk_target]->data_section(); sha1_hash target = hasher(targetbuf.first,targetbuf.second).final(); -#ifdef TORRENT_DHT_VERBOSE_LOGGING +//#ifdef TORRENT_DHT_VERBOSE_LOGGING std::string target_str(targetbuf.first,targetbuf.second); - fprintf(stderr, "PUT target: %s = {%s,%s,%s} = '%s'\n" + printf("PUT target: %s = {%s,%s,%s} = '%s'\n" , to_hex(target.to_string()).c_str() , msg_keys[mk_n]->string_value().c_str() , msg_keys[mk_r]->string_value().c_str() , msg_keys[mk_t]->string_value().c_str() , target_str.c_str()); -#endif +//#endif // verify the write-token. tokens are only valid to write to // specific target hashes. it must match the one we got a "get" for @@ -1306,15 +1311,15 @@ void node_impl::incoming_request(msg const& m, entry& e) bool justtoken = false; if (msg_keys[mk_justtoken] && msg_keys[mk_justtoken]->int_value() != 0) justtoken = true; -#ifdef TORRENT_DHT_VERBOSE_LOGGING +//#ifdef TORRENT_DHT_VERBOSE_LOGGING std::string target_str(targetbuf.first,targetbuf.second); - fprintf(stderr, "GET target: %s = {%s,%s,%s} = '%s'\n" + printf("GET target: %s = {%s,%s,%s} = '%s'\n" , to_hex(target.to_string()).c_str() , msg_keys[mk_n]->string_value().c_str() , msg_keys[mk_r]->string_value().c_str() , msg_keys[mk_t]->string_value().c_str() , target_str.c_str()); -#endif +//#endif reply["token"] = generate_token(m.addr, target.to_string().c_str()); nodes_t n; diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 5e464016..4d422572 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -235,6 +235,9 @@ static const CRPCCommand vRPCCommands[] = { "sendrawtransaction", &sendrawtransaction, false, false }, { "sendnewusertransaction", &sendnewusertransaction, false, false }, { "verifychain", &verifychain, true, false }, + // twister dht network + { "dhtput", &dhtput, false, false }, + { "dhtget", &dhtget, false, false }, }; CRPCTable::CRPCTable() diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 590a82d7..d0899245 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -193,5 +193,7 @@ extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp) extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value dhtput(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value dhtget(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/twister.cpp b/src/twister.cpp index 9ec246cb..a3b0b505 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -2,9 +2,15 @@ #include "main.h" #include "init.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; #include +#include + twister::twister() { } @@ -15,6 +21,7 @@ twister::twister() #include "libtorrent/entry.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/session.hpp" +#include "libtorrent/alert_types.hpp" #define TORRENT_DISABLE_GEO_IP #include "libtorrent/aux_/session_impl.hpp" @@ -181,12 +188,77 @@ void ThreadMaintainDHTNodes() } } +void ThreadSessionAlerts() +{ + while(!ses) { + MilliSleep(200); + } + while (ses) { + alert const* a = ses->wait_for_alert(seconds(10)); + if (a == 0) continue; + + std::deque alerts; + ses->pop_alerts(&alerts); + std::string now = time_now_string(); + for (std::deque::iterator i = alerts.begin() + , end(alerts.end()); i != end; ++i) + { + // make sure to delete each alert + std::auto_ptr a(*i); + + dht_reply_data_alert const* rd = alert_cast(*i); + if (rd) + { + for (entry::list_type::const_iterator j = rd->m_lst.begin() + , end(rd->m_lst.end()); j != end; ++j) { + if( j->type() == entry::dictionary_t ) { + entry const *p = j->find_key("p"); + //entry const *sig_p = j->find_key("sig_p"); // already verified in dht_get.cpp + entry const *sig_user = j->find_key("sig_user"); + if( p && sig_user ) { + printf("ThreadSessionAlerts: dht data reply with sig_user=%s\n", + sig_user->string().c_str()); + entry const *v = p->find_key("v"); + if( v ) { + if( v->type() == entry::string_t ) { + printf("ThreadSessionAlerts: dht data reply value '%s'\n", + v->string().c_str()); + } + } + } else { + printf("ThreadSessionAlerts: Error: p, sig_p or sig_user missing\n"); + } + } else { + printf("ThreadSessionAlerts: Error: non-dictionary returned by dht data reply\n"); + } + } + continue; + } + + /* + save_resume_data_alert const* rd = alert_cast(*i); + if (rd) { + if (!rd->resume_data) continue; + + torrent_handle h = rd->handle; + torrent_status st = h.status(torrent_handle::query_save_path); + std::vector out; + bencode(std::back_inserter(out), *rd->resume_data); + save_file(combine_path(st.save_path, combine_path(".resume", to_hex(st.info_hash.to_string()) + ".resume")), out); + } + */ + } + } +} + + void startSessionTorrent(boost::thread_group& threadGroup) { printf("startSessionTorrent (waiting for external IP)\n"); threadGroup.create_thread(boost::bind(&ThreadWaitExtIP)); threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes)); + threadGroup.create_thread(boost::bind(&ThreadSessionAlerts)); } void stopSessionTorrent() @@ -294,3 +366,46 @@ int getBestHeight() { return nBestHeight; } + +Value dhtput(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 6) + throw runtime_error( + "dhtput \n" + "Sign a message with the private key of an address"); + + EnsureWalletIsUnlocked(); + + string strUsername = params[0].get_str(); + string strResource = params[1].get_str(); + string strMulti = params[2].get_str(); + string strValue = params[3].get_str(); + string strSigUser = params[4].get_str(); + string strSeq = params[5].get_str(); + + bool multi = (strMulti == "m"); + entry value = entry::string_type(strValue); + int timeutc = time(NULL); + int seq = atoi(strSeq.c_str()); + + ses->dht_putData(strUsername, strResource, multi, value, strSigUser, timeutc, seq); + return Value(); +} + +Value dhtget(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "dhtget \n" + "Sign a message with the private key of an address"); + + string strUsername = params[0].get_str(); + string strResource = params[1].get_str(); + string strMulti = params[2].get_str(); + + bool multi = (strMulti == "m"); + + ses->dht_getData(strUsername, strResource, multi); + return Value(); +} + diff --git a/src/twister.h b/src/twister.h index 333076ad..54a00a9b 100644 --- a/src/twister.h +++ b/src/twister.h @@ -1,6 +1,7 @@ #ifndef TWISTER_H #define TWISTER_H +#include "util.h" #include #define LIBTORRENT_PORT_OFFSET 1000