diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index 4ca06220..01434ef6 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -180,10 +180,12 @@ public: void tick(); bool refresh_storage(); + bool save_storage(entry &save) const; void refresh(node_id const& id, find_data::nodes_callback const& f); void bootstrap(std::vector const& nodes , find_data::nodes_callback const& f); void add_router_node(udp::endpoint router); + void load_storage(entry const* load); void unreachable(udp::endpoint const& ep); void incoming(msg const& m); @@ -288,7 +290,7 @@ public: private: table_t m_map; dht_storage_table_t m_storage_table; - + ptime m_last_tracker_tick; ptime m_last_storage_refresh; diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index 4c496b93..6724ab2b 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -241,6 +241,9 @@ namespace libtorrent { namespace dht TORRENT_LOG(dht_tracker) << "starting DHT tracker with node id: " << m_dht.nid(); #endif + if (state && state->type() == entry::dictionary_t) { + m_dht.load_storage(state->find_key("storage_table")); + } } dht_tracker::~dht_tracker() {} @@ -602,6 +605,12 @@ namespace libtorrent { namespace dht } if (!nodes.list().empty()) ret["nodes"] = nodes; + + // [MF] save stored keys + entry storate_entry(entry::dictionary_t); + if( m_dht.save_storage(storate_entry) ) { + ret["storage_table"] = storate_entry; + } } ret["node-id"] = m_dht.nid().to_string(); diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 86531fab..ff28959d 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -537,6 +537,70 @@ bool node_impl::refresh_storage() { return did_something; } +bool node_impl::save_storage(entry &save) const { + bool did_something = false; + + if( m_storage_table.size() == 0 ) + return did_something; + + printf("node dht: saving storage... (storage_table.size = %d)\n", m_storage_table.size()); + + for (dht_storage_table_t::const_iterator i = m_storage_table.begin(), + iend(m_storage_table.end()); i != iend; ++i ) + { + entry save_list(entry::list_t); + + dht_storage_list_t const& lsto = i->second; + // save only 's' items? for now save everything + /*if( lsto.size() == 1 )*/ { + for(dht_storage_list_t::const_iterator j = lsto.begin(), + jend(lsto.end()); j != jend; ++j ) { + + dht_storage_item const& item = *j; + + entry entry_item; + entry_item["p"] = item.p; + entry_item["sig_p"] = item.sig_p; + entry_item["sig_user"] = item.sig_user; + save_list.list().push_back(entry_item); + } + } + + if( save_list.list().size() ) { + save[i->first.to_string()] = save_list; + did_something = true; + } + } + return did_something; +} + +void node_impl::load_storage(entry const* e) { + if( !e || e->type() != entry::dictionary_t) + return; + + printf("node dht: loading storage... (%d node_id keys)\n", e->dict().size()); + + for (entry::dictionary_type::const_iterator i = e->dict().begin(); + i != e->dict().end(); ++i) { + + node_id target( i->first ); + dht_storage_list_t to_add; + if ( i->second.type() != entry::list_t ) + continue; + for (entry::list_type::const_iterator j = i->second.list().begin(); + j != i->second.list().end(); ++j) { + dht_storage_item item; + item.p = j->find_key("p")->string(); + item.sig_p = j->find_key("sig_p")->string(); + item.sig_user = j->find_key("sig_user")->string(); + to_add.push_back(item); + } + m_storage_table.insert(std::make_pair(target, to_add)); + } +} + + + time_duration node_impl::connection_timeout() { time_duration d = m_rpc.tick();