perf: recycle DH MSE keys iff peer was unreachable (#4412)
This commit is contained in:
parent
edfce44d35
commit
d290ece0c8
|
@ -833,6 +833,8 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha
|
||||||
|
|
||||||
bool tr_handshake::fire_done(bool is_connected)
|
bool tr_handshake::fire_done(bool is_connected)
|
||||||
{
|
{
|
||||||
|
maybe_recycle_dh();
|
||||||
|
|
||||||
if (!on_done_)
|
if (!on_done_)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -910,7 +912,7 @@ uint32_t tr_handshake::crypto_provide() const noexcept
|
||||||
**/
|
**/
|
||||||
|
|
||||||
tr_handshake::tr_handshake(Mediator* mediator, std::shared_ptr<tr_peerIo> peer_io, tr_encryption_mode mode, DoneFunc on_done)
|
tr_handshake::tr_handshake(Mediator* mediator, std::shared_ptr<tr_peerIo> peer_io, tr_encryption_mode mode, DoneFunc on_done)
|
||||||
: dh_{ mediator->private_key() }
|
: dh_{ tr_handshake::get_dh(mediator) }
|
||||||
, on_done_{ std::move(on_done) }
|
, on_done_{ std::move(on_done) }
|
||||||
, peer_io_{ std::move(peer_io) }
|
, peer_io_{ std::move(peer_io) }
|
||||||
, timeout_timer_{ mediator->timer_maker().create([this]() { fire_done(false); }) }
|
, timeout_timer_{ mediator->timer_maker().create([this]() { fire_done(false); }) }
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <cstddef> // for std::byte, size_t
|
#include <cstddef> // for std::byte, size_t
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
@ -250,6 +251,53 @@ private:
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
static constexpr auto DhPoolMaxSize = size_t{ 32 };
|
||||||
|
static inline auto dh_pool_size_ = size_t{};
|
||||||
|
static inline auto dh_pool_ = std::array<tr_message_stream_encryption::DH, DhPoolMaxSize>{};
|
||||||
|
static inline auto dh_pool_mutex_ = std::mutex{};
|
||||||
|
|
||||||
|
[[nodiscard]] static DH get_dh(Mediator* mediator)
|
||||||
|
{
|
||||||
|
auto lock = std::unique_lock(dh_pool_mutex_);
|
||||||
|
|
||||||
|
if (dh_pool_size_ > 0U)
|
||||||
|
{
|
||||||
|
auto dh = DH{};
|
||||||
|
std::swap(dh, dh_pool_[dh_pool_size_ - 1U]);
|
||||||
|
--dh_pool_size_;
|
||||||
|
return dh;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DH{ mediator->private_key() };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_dh(DH&& dh)
|
||||||
|
{
|
||||||
|
auto lock = std::unique_lock(dh_pool_mutex_);
|
||||||
|
|
||||||
|
if (dh_pool_size_ < std::size(dh_pool_))
|
||||||
|
{
|
||||||
|
dh_pool_[dh_pool_size_] = std::move(dh);
|
||||||
|
++dh_pool_size_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void maybe_recycle_dh()
|
||||||
|
{
|
||||||
|
// keys are expensive to make, so recycle iff the peer was unreachable
|
||||||
|
|
||||||
|
if (have_read_anything_from_peer_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dh = DH{};
|
||||||
|
std::swap(dh_, dh);
|
||||||
|
add_dh(std::move(dh));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
DH dh_ = {};
|
DH dh_ = {};
|
||||||
|
|
||||||
DoneFunc on_done_;
|
DoneFunc on_done_;
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
[[nodiscard]] static private_key_bigend_t randomPrivateKey() noexcept;
|
[[nodiscard]] static private_key_bigend_t randomPrivateKey() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
private_key_bigend_t const private_key_;
|
private_key_bigend_t private_key_;
|
||||||
key_bigend_t public_key_ = {};
|
key_bigend_t public_key_ = {};
|
||||||
key_bigend_t secret_ = {};
|
key_bigend_t secret_ = {};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue