diff --git a/configure.cpp b/configure.cpp index 44f0d37..fda107d 100644 --- a/configure.cpp +++ b/configure.cpp @@ -250,6 +250,10 @@ bool CConfigure::ReadData(const std::string &path) { data.interlinkpath.assign(value); } + else if (0 == key.compare("DHTStatePath")) + { + data.dhtstatepath.assign(value); + } else if (0 == key.compare("Port")) { data.port = std::stoul(value); @@ -455,8 +459,8 @@ bool CConfigure::ReadData(const std::string &path) if (data.bootstrap.empty()) { - std::cerr << "ERROR - no Bootstrap" << std::endl; - rval = true; + std::cerr << "WARNING - no Bootstrap specified" << std::endl; + //rval = true; } else { @@ -533,6 +537,16 @@ bool CConfigure::ReadData(const std::string &path) std::cout << "InterlinkPath='" << data.interlinkpath << "'" << std::endl; } + if (data.dhtstatepath.empty()) + { + std::cerr << "WARNING - no DHT network state path specified" << std::endl; + //rval = true; + } + else + { + std::cout << "DHTStatePath='" << data.bootstrap << "'" << std::endl; + } + if (49000U < data.port || data.port < 4096U) { std::cerr << "ERROR - Port is out of range" << std::endl; diff --git a/configure.h b/configure.h index 28d9195..57a1ed7 100644 --- a/configure.h +++ b/configure.h @@ -29,6 +29,7 @@ using CFGDATA = struct CFGData_struct { std::string ipv4extaddr, ipv6extaddr; std::string url, emailaddr, bootstrap; std::string sponsor, country; + std::string dhtstatepath; #endif std::string pidpath, xmlpath, whitepath, blackpath, interlinkpath; unsigned long port; @@ -56,6 +57,7 @@ class CConfigure const std::string &GetBootstrap() const { return data.bootstrap; } const std::string &GetSponsor() const { return data.sponsor; } const std::string &GetCountry() const { return data.country; } + const std::string &GetDHTStatePath() const { return data.dhtstatepath; } #endif const std::string &GetXmlPath() const { return data.xmlpath; } const std::string &GetPidPath() const { return data.pidpath; } diff --git a/example.cfg b/example.cfg index c30ed27..60ce731 100644 --- a/example.cfg +++ b/example.cfg @@ -47,6 +47,7 @@ XmlPath = /var/log/mrefd.xml WhitelistPath = /usr/local/etc/mrefd.whitelist BlacklistPath = /usr/local/etc/mrefd.blacklist InterlinkPath = /usr/local/etc/mrefd.interlink +DHTStatePath = /usr/local/etc/mrefd.dht-save.bin # If you want to allow multiple clients connecting from the same IP at # the same time, set MultiClient to "true". diff --git a/reflector.cpp b/reflector.cpp index 42cd723..cb99ec1 100644 --- a/reflector.cpp +++ b/reflector.cpp @@ -89,7 +89,40 @@ bool CReflector::Start(const char *cfgfilename) // start the dht instance refhash = dht::InfoHash::get(g_CFG.GetCallsign()); node.run(17171, dht::crypto::generateIdentity(g_CFG.GetCallsign()), true); - node.bootstrap(g_CFG.GetBootstrap(), "17171"); + std::ifstream myfile; + const auto path = g_CFG.GetDHTStatePath(); + if (path.size() > 0) + myfile.open(path, std::ios::binary|std::ios::ate); + if (myfile.is_open()) + { + msgpack::unpacker pac; + auto size = myfile.tellg(); + myfile.seekg (0, std::ios::beg); + pac.reserve_buffer(size); + myfile.read (pac.buffer(), size); + pac.buffer_consumed(size); + // Import nodes + msgpack::object_handle oh; + while (pac.next(oh)) { + auto imported_nodes = oh.get().as>(); + std::cout << "Importing " << imported_nodes.size() << " ham-dht nodes from " << path << std::endl; + node.bootstrap(imported_nodes); + } + myfile.close(); + } + else + { + const auto bsnode = g_CFG.GetBootstrap(); + if (bsnode.size()) + { + std::cout << "Bootstrapping from " << bsnode << std::endl; + node.bootstrap(bsnode, "17171"); + } + else + { + std::cout << "WARNING: The DHT is not bootstrapping from any node!" << std::endl; + } + } #endif // create protocols @@ -144,6 +177,28 @@ void CReflector::Stop(void) g_GateKeeper.Close(); #ifndef NO_DHT + // save the state of the DHT network + const auto path = g_CFG.GetDHTStatePath(); + if (path.size() > 0) + { + auto exnodes = node.exportNodes(); + if (exnodes.size()) + { + // Export nodes to binary file + std::ofstream myfile(path, std::ios::binary | std::ios::trunc); + if (myfile.is_open()) + { + std::cout << "Saving " << exnodes.size() << " nodes to " << path << std::endl; + msgpack::pack(myfile, exnodes); + myfile.close(); + } + else + std::cerr << "Trouble opening " << path << std::endl; + } + else + std::cout << "There are no DHT network nodes to save!" << std::endl; + } + // kill the DHT node.cancelPut(refhash, toUType(EMrefdValueID::Config)); node.cancelPut(refhash, toUType(EMrefdValueID::Peers)); diff --git a/version.cpp b/version.cpp index bc93780..186843e 100644 --- a/version.cpp +++ b/version.cpp @@ -25,7 +25,7 @@ #include "version.h" -CVersion g_Version(0, 11, 3); // the global object +CVersion g_Version(0, 11, 4); // the global object CVersion::CVersion(uint8_t maj, uint8_t min, uint8_t rev) : version(0x10000*maj + 0x100*min + rev) {}