From 1e4dac83952e1f707cdb837f647e6c80c3414154 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 28 Apr 2018 15:30:21 +0200 Subject: Add stop seeding function --- src/Database.cpp | 36 ++++++++++++++++++++++++++++++++---- src/DatabaseStorage.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Database.cpp b/src/Database.cpp index 6f864b4..7281025 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -140,6 +140,14 @@ namespace odhtdb void Database::seed(const DatabaseNode &nodeToSeed) { + if(seedInfoMap.find(*nodeToSeed.getRequestHash()) != seedInfoMap.end()) + { + Log::warn("You are already seeding node %s, ignoring...", nodeToSeed.getRequestHash()->toString().c_str()); + return; + } + + DatabaseSeedInfo newSeedInfo; + // TODO: Use cached files and seed those. If none exists, request new files to seed. // If nobody requests my cached files in a long time, request new files to seed and remove cached files // (only if there are plenty of other seeders for the cached files. This could also cause race issue @@ -150,7 +158,7 @@ namespace odhtdb Log::debug("Seeding key: %s", nodeToSeed.getRequestHash()->toString().c_str()); DhtKey dhtKey(*nodeToSeed.getRequestHash()); - node.listen(dhtKey.getNewDataListenerKey(), [this, nodeToSeed](const shared_ptr &value) + auto newDataListenerFuture = node.listen(dhtKey.getNewDataListenerKey(), [this, nodeToSeed](const shared_ptr &value) { Log::debug("Seed: New data listener received data..."); const Hash requestHash(value->data.data(), value->data.size()); @@ -160,12 +168,14 @@ namespace odhtdb else return listenAddData(value, requestHash, nodeToSeed.getRequestHash(), nodeToSeed.getNodeEncryptionKey()); }); + newSeedInfo.newDataListenerFuture = make_shared>(move(newDataListenerFuture)); u8 responseKey[OPENDHT_INFOHASH_LEN]; randombytes_buf(responseKey, OPENDHT_INFOHASH_LEN); + newSeedInfo.reponseKeyInfoHash = make_shared(responseKey, OPENDHT_INFOHASH_LEN); // TODO: If this response key is spammed, generate a new one. - node.listen(InfoHash(responseKey, OPENDHT_INFOHASH_LEN), [this, nodeToSeed](const shared_ptr &value) + auto responseKeyFuture = node.listen(*newSeedInfo.reponseKeyInfoHash, [this, nodeToSeed](const shared_ptr &value) { const Hash requestHash(value->data.data(), value->data.size()); if(requestHash == *nodeToSeed.getRequestHash()) @@ -173,10 +183,11 @@ namespace odhtdb else return listenAddData(value, requestHash, nodeToSeed.getRequestHash(), nodeToSeed.getNodeEncryptionKey()); }); + newSeedInfo.responseKeyFuture = make_shared>(move(responseKeyFuture)); // TODO: Before listening on this key, we should check how many remote peers are also providing this data. // This is to prevent too many peers from responding to a request to get old data. - node.listen(dhtKey.getRequestOldDataKey(), [this, nodeToSeed](const shared_ptr &value) + auto requestOldDataListenerFuture = node.listen(dhtKey.getRequestOldDataKey(), [this, nodeToSeed](const shared_ptr &value) { Log::debug("Request: Got request to send old data"); try @@ -220,6 +231,9 @@ namespace odhtdb } return true; }); + newSeedInfo.requestOldDataListenerFuture = make_shared>(move(requestOldDataListenerFuture)); + + seedInfoMap[*nodeToSeed.getRequestHash()] = newSeedInfo; sibs::SafeSerializer serializer; serializer.add((u64)0); // Timestamp in microseconds, fetch data newer than this. // TODO: Get timestamp from database storage @@ -233,6 +247,20 @@ namespace odhtdb //node.listen(CREATE_DATA_HASH, bind(&Database::listenCreateData, this, _1)); //node.listen(ADD_DATA_HASH, bind(&Database::listenAddData, this, _1)); } + + void Database::stopSeeding(const Hash &nodeHash) + { + auto seedInfoIt = seedInfoMap.find(nodeHash); + if(seedInfoIt != seedInfoMap.end()) + { + // TODO: Verify if doing get on listener future stalls program forever... Opendht documentation is not clear on this + DhtKey dhtKey(nodeHash); + node.cancelListen(dhtKey.getNewDataListenerKey(), seedInfoIt->second.newDataListenerFuture->get()); + node.cancelListen(dhtKey.getRequestOldDataKey(), seedInfoIt->second.requestOldDataListenerFuture->get()); + node.cancelListen(*seedInfoIt->second.reponseKeyInfoHash, seedInfoIt->second.responseKeyFuture->get()); + seedInfoMap.erase(seedInfoIt); + } + } unique_ptr Database::create(const string &ownerName, const string &nodeName) { @@ -286,7 +314,7 @@ namespace odhtdb } } - void Database::addData(const DatabaseNode &nodeInfo, LocalUser *userToPerformActionWith, DataView dataToAdd) + void Database::addData(const DatabaseNode &nodeInfo, const LocalUser *userToPerformActionWith, DataView dataToAdd) { if(!userToPerformActionWith->isAllowedToPerformAction(PermissionType::ADD_DATA)) { diff --git a/src/DatabaseStorage.cpp b/src/DatabaseStorage.cpp index 0e9fa32..384ef5f 100644 --- a/src/DatabaseStorage.cpp +++ b/src/DatabaseStorage.cpp @@ -692,6 +692,14 @@ namespace odhtdb return nullptr; } + const DataViewMap* DatabaseStorage::getNodeGroups(const Hash &nodeHash) + { + auto groupByIdMapIt = nodeGroupByIdMap.find(nodeHash); + if(groupByIdMapIt != nodeGroupByIdMap.end()) + return groupByIdMapIt->second; + return nullptr; + } + Group* DatabaseStorage::getGroupById(const Hash &nodeHash, uint8_t groupId[GROUP_ID_LENGTH]) const { auto groupByIdMapIt = nodeGroupByIdMap.find(nodeHash); @@ -704,6 +712,14 @@ namespace odhtdb return nullptr; } + const Signature::MapPublicKey* DatabaseStorage::getNodeUsers(const Hash &nodeHash) + { + auto publicKeyUserDataMapIt = nodePublicKeyUserDataMap.find(nodeHash); + if(publicKeyUserDataMapIt != nodePublicKeyUserDataMap.end()) + return publicKeyUserDataMapIt->second; + return nullptr; + } + User* DatabaseStorage::getUserByPublicKey(const Hash &nodeHash, const Signature::PublicKey &userPublicKey) const { auto publicKeyUserDataMapIt = nodePublicKeyUserDataMap.find(nodeHash); @@ -806,6 +822,14 @@ namespace odhtdb return localUsers; } + std::pair> DatabaseStorage::getNodeDecryptionKey(const Hash &nodeHash) + { + auto nodeDecryptionKeyIt = nodeDecryptionKeyMap.find(nodeHash); + if(nodeDecryptionKeyIt != nodeDecryptionKeyMap.end()) + return make_pair(true, nodeDecryptionKeyIt->second); + return make_pair(false, make_shared()); + } + void DatabaseStorage::setNodeDecryptionKey(const Hash &nodeHash, const DataView &decryptionKeyView) { bool nodeHasExistingEncryptionKey = nodeDecryptionKeyMap.find(nodeHash) != nodeDecryptionKeyMap.end(); -- cgit v1.2.3