mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 04:21:51 +00:00
dht: save id, port when saving state
This commit is contained in:
1 parent
7d3781acc8
commit
15eb221cd1
3 files changed
+68
-28
No files matched your search
@@ -389,7 +389,7 @@ public:
|
||||
* @param threaded: If false, loop() must be called periodically. Otherwise a thread is launched.
|
||||
* @param cb: Optional callback to receive general state information.
|
||||
*/
|
||||
void run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context = {});
|
||||
void run(SockAddr& local4, SockAddr& local6, const Config& config, Context&& context = {});
|
||||
|
||||
/**
|
||||
* Same as @run(sockaddr_in, sockaddr_in6, Identity, bool, StatusCallback), but with string IP addresses and service (port).
|
||||
|
||||
+32
-24
@@ -1785,13 +1785,13 @@ Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, cons
|
||||
secret = std::uniform_int_distribution<uint64_t>{}(rd);
|
||||
rotateSecrets();
|
||||
|
||||
if (not persistPath.empty())
|
||||
loadState(persistPath);
|
||||
|
||||
expire();
|
||||
|
||||
if (logger_)
|
||||
logger_->d("DHT node initialised with ID %s", myid.toString().c_str());
|
||||
|
||||
if (not persistPath.empty())
|
||||
loadState(persistPath);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2070,13 +2070,13 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
{
|
||||
const auto& now = scheduler.time();
|
||||
|
||||
for (const auto& node : import) {
|
||||
if (node.second.empty())
|
||||
for (const auto& value : import) {
|
||||
if (value.second.empty())
|
||||
continue;
|
||||
|
||||
try {
|
||||
msgpack::unpacked msg;
|
||||
msgpack::unpack(msg, (const char*)node.second.data(), node.second.size());
|
||||
msgpack::unpack(msg, (const char*)value.second.data(), value.second.size());
|
||||
auto valarr = msg.get();
|
||||
if (valarr.type != msgpack::type::ARRAY)
|
||||
throw msgpack::type_error();
|
||||
@@ -2091,15 +2091,15 @@ Dht::importValues(const std::vector<ValuesExport>& import)
|
||||
tmp_val.msgpack_unpack(valel.via.array.ptr[1]);
|
||||
} catch (const std::exception&) {
|
||||
if (logger_)
|
||||
logger_->e(node.first, "Error reading value at %s", node.first.toString().c_str());
|
||||
logger_->e(value.first, "Error reading value at %s", value.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
val_time = std::min(val_time, now);
|
||||
storageStore(node.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
storageStore(value.first, std::make_shared<Value>(std::move(tmp_val)), val_time);
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
if (logger_)
|
||||
logger_->e(node.first, "Error reading values at %s", node.first.toString().c_str());
|
||||
logger_->e(value.first, "Error reading values at %s", value.first.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2504,12 +2504,24 @@ Dht::onAnnounceDone(const Sp<Node>& node, net::RequestAnswer& answer, Sp<Search>
|
||||
}
|
||||
|
||||
|
||||
struct DhtState {
|
||||
unsigned v {1};
|
||||
InfoHash id;
|
||||
std::vector<NodeExport> nodes;
|
||||
std::vector<ValuesExport> values;
|
||||
|
||||
MSGPACK_DEFINE_MAP(v, id, nodes, values)
|
||||
};
|
||||
|
||||
void
|
||||
Dht::saveState(const std::string& path) const
|
||||
{
|
||||
DhtState state;
|
||||
state.id = myid;
|
||||
state.nodes = exportNodes();
|
||||
state.values = exportValues();
|
||||
std::ofstream file(path);
|
||||
msgpack::pack(file, exportNodes());
|
||||
msgpack::pack(file, exportValues());
|
||||
msgpack::pack(file, state);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2535,19 +2547,15 @@ Dht::loadState(const std::string& path)
|
||||
// Import nodes
|
||||
msgpack::object_handle oh;
|
||||
if (pac.next(oh)) {
|
||||
{
|
||||
auto imported_nodes = oh.get().as<std::vector<NodeExport>>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu nodes", imported_nodes.size());
|
||||
for (const auto& node : imported_nodes)
|
||||
insertNode(node);
|
||||
}
|
||||
if (pac.next(oh)) {
|
||||
auto imported_values = oh.get().as<std::vector<ValuesExport>>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu values", imported_values.size());
|
||||
importValues(imported_values);
|
||||
}
|
||||
auto state = oh.get().as<DhtState>();
|
||||
if (logger_)
|
||||
logger_->d("Importing %zu nodes", state.nodes.size());
|
||||
myid = state.id;
|
||||
std::vector<Sp<Node>> tmpNodes;
|
||||
tmpNodes.reserve(state.nodes.size());
|
||||
for (const auto& node : state.nodes)
|
||||
tmpNodes.emplace_back(network_engine.insertNode(node.id, SockAddr(node.ss, node.sslen)));
|
||||
importValues(state.values);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
if (logger_)
|
||||
|
||||
+35
-3
@@ -32,6 +32,8 @@
|
||||
#include "dht_proxy_client.h"
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace dht {
|
||||
|
||||
constexpr std::chrono::seconds DhtRunner::BOOTSTRAP_PERIOD;
|
||||
@@ -90,16 +92,46 @@ DhtRunner::run(const char* ip4, const char* ip6, const char* service, const Conf
|
||||
{
|
||||
auto res4 = SockAddr::resolve(ip4, service);
|
||||
auto res6 = SockAddr::resolve(ip6, service);
|
||||
run(res4.empty() ? SockAddr() : res4.front(),
|
||||
res6.empty() ? SockAddr() : res6.front(), config, std::move(context));
|
||||
if (res4.empty())
|
||||
res4.emplace_back();
|
||||
if (res6.empty())
|
||||
res6.emplace_back();
|
||||
run(res4.front(), res6.front(), config, std::move(context));
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunner::run(const SockAddr& local4, const SockAddr& local6, const Config& config, Context&& context)
|
||||
DhtRunner::run(SockAddr& local4, SockAddr& local6, const Config& config, Context&& context)
|
||||
{
|
||||
if (running == State::Idle) {
|
||||
auto state_path = config.dht_config.node_config.persist_path;
|
||||
if (not state_path.empty()) {
|
||||
state_path += "_port.txt";
|
||||
std::ifstream inConfig(state_path);
|
||||
if (inConfig.is_open()) {
|
||||
in_port_t port;
|
||||
if (inConfig >> port) {
|
||||
if (context.logger)
|
||||
context.logger->d("[runner %p] Using IPv4 port %hu from saved configuration", this, port);
|
||||
if (local4.getPort() == 0)
|
||||
local4.setPort(port);
|
||||
}
|
||||
if (inConfig >> port) {
|
||||
if (context.logger)
|
||||
context.logger->d("[runner %p] Using IPv6 port %hu from saved configuration", this, port);
|
||||
if (local6.getPort() == 0)
|
||||
local6.setPort(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not context.sock)
|
||||
context.sock.reset(new net::UdpSocket(local4, local6, context.logger));
|
||||
|
||||
if (not state_path.empty()) {
|
||||
std::ofstream outConfig(state_path);
|
||||
outConfig << context.sock->getBoundRef(AF_INET).getPort() << std::endl;
|
||||
outConfig << context.sock->getBoundRef(AF_INET6).getPort() << std::endl;
|
||||
}
|
||||
run(config, std::move(context));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user