diff --git a/include/opendht/value.h b/include/opendht/value.h index 63795caf702033cccfd3a10c991fcc18cdb5ecb1..a4a3348a1c0b019bcccecb465e5295f5c2c55280 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -122,6 +122,8 @@ private: std::map<ValueType::Id, ValueType> types {}; }; +struct CryptoValueCache; + /** * A "value" is data potentially stored on the Dht, with some metadata. * @@ -588,6 +590,14 @@ struct OPENDHT_PUBLIC Value * Hold encrypted version of the data. */ Blob cypher {}; + +private: + friend class SecureDht; + /* Cache for crypto ops */ + bool signatureChecked {false}; + bool signatureValid {false}; + bool decrypted {false}; + Sp<Value> decryptedValue {}; }; using ValuesExport = std::pair<InfoHash, Blob>; diff --git a/src/securedht.cpp b/src/securedht.cpp index 4d173170e4e84b9c90817a894f0574fc64e7410f..a0d5a5a25da90e404eb1ac2ea1ac240dfbc36871 100644 --- a/src/securedht.cpp +++ b/src/securedht.cpp @@ -235,12 +235,17 @@ SecureDht::checkValue(const Sp<Value>& v) #endif return {}; } + if (v->decrypted) { + return v->decryptedValue; + } + v->decrypted = true; try { Value decrypted_val (decrypt(*v)); if (decrypted_val.recipient == getId()) { if (decrypted_val.owner) nodesPubKeys_[decrypted_val.owner->getId()] = decrypted_val.owner; - return std::make_shared<Value>(std::move(decrypted_val)); + v->decryptedValue = std::make_shared<Value>(std::move(decrypted_val)); + return v->decryptedValue; } // Ignore values belonging to other people } catch (const std::exception& e) { @@ -249,7 +254,12 @@ SecureDht::checkValue(const Sp<Value>& v) } // Check signed values else if (v->isSigned()) { + if (v->signatureChecked) { + return v->signatureValid ? v : Sp<Value>{}; + } + v->signatureChecked = true; if (v->owner and v->owner->checkSignature(v->getToSign(), v->signature)) { + v->signatureValid = true; nodesPubKeys_[v->owner->getId()] = v->owner; return v; } @@ -355,7 +365,7 @@ SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, void SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val, DoneCallback callback, bool permanent) { - findPublicKey(to, [=](const Sp<const crypto::PublicKey> pk) { + findPublicKey(to, [=](const Sp<const crypto::PublicKey>& pk) { if(!pk || !*pk) { if (callback) callback(false, {});