Skip to content
Snippets Groups Projects
Commit e87e7462 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

dht: save values to the disk

Refs #56312

Change-Id: Ic07fc68b3130be181405c8971b4f66bb496abbc7
parent f39901da
No related branches found
No related tags found
No related merge requests found
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include <unistd.h> #include <unistd.h>
#include <pwd.h> #include <pwd.h>
#include <dirent.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
...@@ -89,18 +90,19 @@ DHTAccount::DHTAccount(const std::string& accountID, bool /* presenceEnabled */) ...@@ -89,18 +90,19 @@ DHTAccount::DHTAccount(const std::string& accountID, bool /* presenceEnabled */)
fileutils::check_dir(fileutils::get_cache_dir().c_str()); fileutils::check_dir(fileutils::get_cache_dir().c_str());
nodePath_ = fileutils::get_cache_dir()+DIR_SEPARATOR_STR+getAccountID(); nodePath_ = fileutils::get_cache_dir()+DIR_SEPARATOR_STR+getAccountID();
fileutils::check_dir(nodePath_.c_str()); fileutils::check_dir(nodePath_.c_str());
WARN("node cache path: %s", nodePath_.c_str());
if (privkeyPath_.empty()) { /* ~/.local/{appname} */
fileutils::check_dir(fileutils::get_data_dir().c_str()); fileutils::check_dir(fileutils::get_data_dir().c_str());
/* ~/.local/{appname}/{accountID} */
const auto idPath = fileutils::get_data_dir()+DIR_SEPARATOR_STR+getAccountID(); const auto idPath = fileutils::get_data_dir()+DIR_SEPARATOR_STR+getAccountID();
fileutils::check_dir(idPath.c_str()); fileutils::check_dir(idPath.c_str());
privkeyPath_ = idPath+DIR_SEPARATOR_STR+"id_rsa";
WARN("privkeyPath : %s", privkeyPath_.c_str()); privkeyPath_ = idPath + DIR_SEPARATOR_STR "id_rsa";
}
if (certPath_.empty()) {
certPath_ = privkeyPath_ + ".pub"; certPath_ = privkeyPath_ + ".pub";
WARN("certPath : %s", certPath_.c_str()); dataPath_ = idPath + DIR_SEPARATOR_STR "values";
} fileutils::check_dir(dataPath_.c_str());
int rc = gnutls_global_init(); int rc = gnutls_global_init();
if (rc != GNUTLS_E_SUCCESS) { if (rc != GNUTLS_E_SUCCESS) {
ERROR("Error initializing GnuTLS : %s", gnutls_strerror(rc)); ERROR("Error initializing GnuTLS : %s", gnutls_strerror(rc));
...@@ -469,10 +471,10 @@ void DHTAccount::doRegister() ...@@ -469,10 +471,10 @@ void DHTAccount::doRegister()
return; return;
} }
DEBUG("doRegister");
try { try {
if (dht_.isRunning()) { if (dht_.isRunning()) {
ERROR("DHT already running"); ERROR("DHT already running (stopping it first).");
dht_.join();
} }
dht_.run(dhtPort_, loadIdentity(), [=](dht::Dht::Status s4, dht::Dht::Status s6) { dht_.run(dhtPort_, loadIdentity(), [=](dht::Dht::Status s4, dht::Dht::Status s6) {
WARN("Dht status : %d %d", (int)s4, (int)s6); WARN("Dht status : %d %d", (int)s4, (int)s6);
...@@ -500,6 +502,9 @@ void DHTAccount::doRegister() ...@@ -500,6 +502,9 @@ void DHTAccount::doRegister()
break; break;
} }
}); });
dht_.importValues(loadValues());
dht_.put(dht_.getId(), dht::Value{dht::ServiceAnnouncement::TYPE.id, dht::ServiceAnnouncement(getTlsListenerPort())}, [](bool ok) { dht_.put(dht_.getId(), dht::Value{dht::ServiceAnnouncement::TYPE.id, dht::ServiceAnnouncement(getTlsListenerPort())}, [](bool ok) {
DEBUG("Peer announce callback ! %d", ok); DEBUG("Peer announce callback ! %d", ok);
}); });
...@@ -534,6 +539,7 @@ void DHTAccount::doUnregister(std::function<void(bool)> released_cb) ...@@ -534,6 +539,7 @@ void DHTAccount::doUnregister(std::function<void(bool)> released_cb)
{ {
Manager::instance().unregisterEventHandler((uintptr_t)this); Manager::instance().unregisterEventHandler((uintptr_t)this);
saveNodes(dht_.exportNodes()); saveNodes(dht_.exportNodes());
saveValues(dht_.exportValues());
dht_.join(); dht_.join();
tlsListener_.reset(); tlsListener_.reset();
setRegistrationState(RegistrationState::UNREGISTERED); setRegistrationState(RegistrationState::UNREGISTERED);
...@@ -557,6 +563,15 @@ void DHTAccount::saveNodes(const std::vector<dht::Dht::NodeExport>& nodes) const ...@@ -557,6 +563,15 @@ void DHTAccount::saveNodes(const std::vector<dht::Dht::NodeExport>& nodes) const
} }
} }
void DHTAccount::saveValues(const std::vector<dht::Dht::ValuesExport>& values) const
{
for (const auto& v : values) {
const std::string fname = dataPath_ + DIR_SEPARATOR_STR + v.first.toString();
std::ofstream file(fname, std::ios::trunc | std::ios::out | std::ios::binary);
file.write((const char*)v.second.data(), v.second.size());
}
}
std::vector<dht::Dht::NodeExport> std::vector<dht::Dht::NodeExport>
DHTAccount::loadNodes() const DHTAccount::loadNodes() const
{ {
...@@ -581,6 +596,35 @@ DHTAccount::loadNodes() const ...@@ -581,6 +596,35 @@ DHTAccount::loadNodes() const
} }
} }
std::vector<dht::Dht::ValuesExport>
DHTAccount::loadValues() const
{
struct dirent *entry;
DIR *dp = opendir(dataPath_.c_str());
if (!dp) {
ERROR("Could not load values from %s", dataPath_.c_str());
return {};
}
std::vector<dht::Dht::ValuesExport> values;
while ((entry = readdir(dp))) {
try {
const std::string fname {entry->d_name};
if (fname == "." || fname == "..")
continue;
std::ifstream ifs(dataPath_+DIR_SEPARATOR_STR+fname, std::ifstream::in | std::ifstream::binary);
std::istreambuf_iterator<char> begin(ifs), end;
values.push_back({{fname}, std::vector<uint8_t>{begin, end}});
} catch (const std::exception& e) {
ERROR("Error reading value: %s", e.what());
continue;
}
}
closedir(dp);
return values;
}
void DHTAccount::initTlsConfiguration() void DHTAccount::initTlsConfiguration()
{ {
// TLS listener is unique and should be only modified through IP2IP_PROFILE // TLS listener is unique and should be only modified through IP2IP_PROFILE
......
...@@ -54,6 +54,7 @@ namespace Conf { ...@@ -54,6 +54,7 @@ namespace Conf {
const char *const DHT_PORT_KEY = "dhtPort"; const char *const DHT_PORT_KEY = "dhtPort";
const char *const DHT_PRIVKEY_PATH_KEY = "dhtPrivkeyPath"; const char *const DHT_PRIVKEY_PATH_KEY = "dhtPrivkeyPath";
const char *const DHT_CERT_PATH_KEY = "dhtCertificatePath"; const char *const DHT_CERT_PATH_KEY = "dhtCertificatePath";
const char *const DHT_VALUES_PATH_KEY = "dhtValuesPath";
} }
namespace YAML { namespace YAML {
...@@ -280,9 +281,10 @@ class DHTAccount : public SIPAccountBase { ...@@ -280,9 +281,10 @@ class DHTAccount : public SIPAccountBase {
dht::DhtRunner dht_ {}; dht::DhtRunner dht_ {};
std::string nodePath_ {};
std::string privkeyPath_ {}; std::string privkeyPath_ {};
std::string certPath_ {}; std::string certPath_ {};
std::string nodePath_ {};
std::string dataPath_ {};
/** /**
* If identityPath_ is a valid private key file (PEM or DER), * If identityPath_ is a valid private key file (PEM or DER),
...@@ -290,10 +292,13 @@ class DHTAccount : public SIPAccountBase { ...@@ -290,10 +292,13 @@ class DHTAccount : public SIPAccountBase {
* Check if the given path contains a valid private key. * Check if the given path contains a valid private key.
* @return the key if a valid private key exists there, nullptr otherwise. * @return the key if a valid private key exists there, nullptr otherwise.
*/ */
dht::crypto::Identity loadIdentity() const;
void saveIdentity(const dht::crypto::Identity id) const; void saveIdentity(const dht::crypto::Identity id) const;
void saveNodes(const std::vector<dht::Dht::NodeExport>& nodes) const; void saveNodes(const std::vector<dht::Dht::NodeExport>&) const;
void saveValues(const std::vector<dht::Dht::ValuesExport>&) const;
dht::crypto::Identity loadIdentity() const;
std::vector<dht::Dht::NodeExport> loadNodes() const; std::vector<dht::Dht::NodeExport> loadNodes() const;
std::vector<dht::Dht::ValuesExport> loadValues() const;
/** /**
* Initializes tls settings from configuration file. * Initializes tls settings from configuration file.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment