From 4b656c5600a28f05665e849715af3d08f29dff2f Mon Sep 17 00:00:00 2001 From: dec05eba <0xdec05eba@gmail.com> Date: Tue, 15 May 2018 06:06:02 +0200 Subject: Store known remote nodes and connect to them next time --- src/DatabaseStorage.cpp | 102 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 30 deletions(-) (limited to 'src/DatabaseStorage.cpp') diff --git a/src/DatabaseStorage.cpp b/src/DatabaseStorage.cpp index 129ba13..d5053c5 100644 --- a/src/DatabaseStorage.cpp +++ b/src/DatabaseStorage.cpp @@ -73,7 +73,8 @@ namespace odhtdb selectNodeAddUserDataStmt(nullptr), setNodeAddDataDecryptedStmt(nullptr), setNodeAddDataAdditionalDataStmt(nullptr), - metadataFilePath(storagePath / "metadata") + metadataFilePath(storagePath / "metadata"), + remoteNodesFilePath(storagePath / "remote_nodes") { try { @@ -142,48 +143,47 @@ namespace odhtdb sqlite_prepare_checked(sqliteDb, "UPDATE NodeAddData SET decrypted = ? WHERE id = ?", &setNodeAddDataDecryptedStmt); sqlite_prepare_checked(sqliteDb, "UPDATE NodeAddDataAdditional SET data = ? WHERE nodeAddDataId = ?", &setNodeAddDataAdditionalDataStmt); - bool metadataLoaded = false; try { loadMetadataFromFile(); - metadataLoaded = true; } catch(FileException &e) { - if(metadataLoaded) - { - string errMsg = "Failed to load storage, reason: "; - errMsg += e.what(); - throw DatabaseStorageCorrupt(errMsg); - } - else - { - Log::warn("Failed to load storage meta data, reason: %s. Ignoring... (new storage probably)", e.what()); - sibs::SafeSerializer metadataSerializer; - metadataSerializer.add(STORAGE_VERSION); - randombytes_buf(passwordSalt, PASSWORD_SALT_LEN); - metadataSerializer.add(passwordSalt, PASSWORD_SALT_LEN); - - //string passwordSaltStr((const char*)passwordSalt, PASSWORD_SALT_LEN); - identity = dht::crypto::generateIdentity(); - dht::Blob privateKeyData = identity.first->serialize(); - metadataSerializer.add((u16)privateKeyData.size()); - metadataSerializer.add(privateKeyData.data(), privateKeyData.size()); + Log::warn("Failed to load storage meta data, reason: %s. Ignoring... (new storage probably)", e.what()); + sibs::SafeSerializer metadataSerializer; + metadataSerializer.add(STORAGE_VERSION); + randombytes_buf(passwordSalt, PASSWORD_SALT_LEN); + metadataSerializer.add(passwordSalt, PASSWORD_SALT_LEN); + + identity = dht::crypto::generateIdentity(); + dht::Blob privateKeyData = identity.first->serialize(); + metadataSerializer.add((u16)privateKeyData.size()); + metadataSerializer.add(privateKeyData.data(), privateKeyData.size()); - dht::Blob certificateData; - identity.second->pack(certificateData); - metadataSerializer.add((u16)certificateData.size()); - metadataSerializer.add(certificateData.data(), certificateData.size()); - - fileAppend(metadataFilePath, { metadataSerializer.getBuffer().data(), metadataSerializer.getBuffer().size() }); - } + dht::Blob certificateData; + identity.second->pack(certificateData); + metadataSerializer.add((u16)certificateData.size()); + metadataSerializer.add(certificateData.data(), certificateData.size()); + + fileAppend(metadataFilePath, { metadataSerializer.getBuffer().data(), metadataSerializer.getBuffer().size() }); } catch(sibs::DeserializeException &e) { - string errMsg = "Failed to load storage, reason: "; + string errMsg = "Failed to load metadata, reason: "; errMsg += e.what(); throw DatabaseStorageCorrupt(errMsg); } + + try + { + loadRemoteNodesFromFile(); + } + catch(exception &e) + { + string errMsg = "Failed to load nodes, reason: "; + errMsg += e.what(); + Log::warn("%s", errMsg.c_str()); + } } void DatabaseStorage::cleanup() @@ -344,6 +344,23 @@ namespace odhtdb assert(deserializer.empty()); } + void DatabaseStorage::loadRemoteNodesFromFile() + { + OwnedMemory remoteNodesFileContent = fileGetContent(remoteNodesFilePath); + msgpack::unpacker pac; + pac.reserve_buffer(remoteNodesFileContent.size); + memcpy(pac.buffer(), remoteNodesFileContent.data, remoteNodesFileContent.size); + pac.buffer_consumed(remoteNodesFileContent.size); + + msgpack::object_handle oh; + while(pac.next(oh)) + { + auto importedNodes = oh.get().as>(); + remoteNodes.reserve(remoteNodes.size() + importedNodes.size()); + remoteNodes.insert(remoteNodes.end(), importedNodes.begin(), importedNodes.end()); + } + } + static void sqlite_step_throw_on_failure(sqlite3 *db, sqlite3_stmt *stmt, const char *description) { int rc = sqlite3_step(stmt); @@ -920,6 +937,31 @@ namespace odhtdb decryptNodeData(nodeHash, nodeDecryptionKeyResult.second); } + struct RemoteNodePacker + { + sibs::SafeSerializer serializer; + + RemoteNodePacker& write(const char *data, size_t size) + { + serializer.add((const u8*)data, size); + return *this; + } + }; + + const vector& DatabaseStorage::getRemoteNodes() const + { + return remoteNodes; + } + + void DatabaseStorage::setRemoteNodes(const std::vector &remoteNodes) + { + Log::debug("Storing %u remote nodes", remoteNodes.size()); + this->remoteNodes = remoteNodes; + RemoteNodePacker remoteNodePacker; + msgpack::pack(remoteNodePacker, remoteNodes); + fileOverwrite(remoteNodesFilePath, DataView(remoteNodePacker.serializer.getBuffer().data(), remoteNodePacker.serializer.getBuffer().size())); + } + bool DatabaseStorage::decryptNodeData(const Hash &nodeHash, const shared_ptr decryptionKey) { sqlite3_reset(selectNodeStmt); -- cgit v1.2.3