From a3772dc1fa4019abe6acdcd5b61b39912eba1054 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 21 Nov 2022 18:08:06 -0600 Subject: [PATCH] refactor: aggregate dh in peer io (#4218) --- libtransmission/announcer.cc | 3 ++- libtransmission/crypto-utils.cc | 4 ++-- libtransmission/peer-io.h | 22 ++++++---------------- libtransmission/peer-mse.cc | 23 ++++++++++------------- libtransmission/peer-mse.h | 24 +++++++++++++++++------- libtransmission/port-forwarding-upnp.cc | 2 +- libtransmission/tr-arc4.h | 9 ++++++++- libtransmission/watchdir-inotify.cc | 2 +- 8 files changed, 47 insertions(+), 42 deletions(-) diff --git a/libtransmission/announcer.cc b/libtransmission/announcer.cc index 67f4c047f..f36bc2519 100644 --- a/libtransmission/announcer.cc +++ b/libtransmission/announcer.cc @@ -54,7 +54,6 @@ static auto constexpr DefaultAnnounceMinIntervalSec = int{ 60 * 2 }; static auto constexpr Numwant = int{ 80 }; /* how often to announce & scrape */ -static auto constexpr UpkeepInterval = 500ms; static auto constexpr MaxAnnouncesPerUpkeep = int{ 20 }; static auto constexpr MaxScrapesPerUpkeep = int{ 20 }; @@ -234,6 +233,8 @@ private: std::unique_ptr const upkeep_timer_; std::set stops_; + + static auto constexpr UpkeepInterval = 500ms; }; std::unique_ptr tr_announcer::create(tr_session* session, tr_announcer_udp& announcer_udp) diff --git a/libtransmission/crypto-utils.cc b/libtransmission/crypto-utils.cc index 210eefbd3..79e68e937 100644 --- a/libtransmission/crypto-utils.cc +++ b/libtransmission/crypto-utils.cc @@ -223,7 +223,7 @@ std::string tr_sha1_to_string(tr_sha1_digest_t const& digest) using namespace hex_impl; auto str = std::string(std::size(digest) * 2, '?'); - tr_binary_to_hex(std::data(digest), std::data(str), std::size(digest)); + tr_binary_to_hex(digest.data(), str.data(), std::size(digest)); return str; } @@ -232,7 +232,7 @@ std::string tr_sha256_to_string(tr_sha256_digest_t const& digest) using namespace hex_impl; auto str = std::string(std::size(digest) * 2, '?'); - tr_binary_to_hex(std::data(digest), std::data(str), std::size(digest)); + tr_binary_to_hex(digest.data(), str.data(), std::size(digest)); return str; } diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index 674dc1fb1..13c5ba270 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -262,27 +262,27 @@ public: void decryptInit(bool is_incoming, DH const& dh, tr_sha1_digest_t const& info_hash) { - filter().decryptInit(is_incoming, dh, info_hash); + filter_.decryptInit(is_incoming, dh, info_hash); } void decrypt(size_t buflen, void* buf) { - filter().decrypt(buflen, buf); + filter_.decrypt(buflen, buf); } void encryptInit(bool is_incoming, DH const& dh, tr_sha1_digest_t const& info_hash) { - filter().encryptInit(is_incoming, dh, info_hash); + filter_.encryptInit(is_incoming, dh, info_hash); } void encrypt(size_t buflen, void* buf) { - filter().encrypt(buflen, buf); + filter_.encrypt(buflen, buf); } [[nodiscard]] bool isEncrypted() const noexcept { - return filter_.get() != nullptr; + return filter_.is_active(); } static void utpInit(struct_utp_context* ctx); @@ -323,19 +323,9 @@ private: { } - Filter& filter() - { - if (!filter_) - { - filter_ = std::make_unique(); - } - - return *filter_; - } - tr_bandwidth bandwidth_; - std::unique_ptr filter_; + Filter filter_; tr_sha1_digest_t torrent_hash_; diff --git a/libtransmission/peer-mse.cc b/libtransmission/peer-mse.cc index b3bf3596f..4d34d66aa 100644 --- a/libtransmission/peer-mse.cc +++ b/libtransmission/peer-mse.cc @@ -54,8 +54,8 @@ auto export_bits(UIntWide i) } // NOLINTBEGIN(readability-identifier-naming) -auto WIDE_INTEGER_CONSTEXPR const G = wi::key_t{ "2" }; -auto WIDE_INTEGER_CONSTEXPR const P = wi::key_t{ +auto WIDE_INTEGER_CONSTEXPR const generator = wi::key_t{ "2" }; +auto WIDE_INTEGER_CONSTEXPR const prime = wi::key_t{ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563" }; // NOLINTEND(readability-identifier-naming) @@ -77,15 +77,10 @@ namespace tr_message_stream_encryption [[nodiscard]] auto generatePublicKey(DH::private_key_bigend_t const& private_key) noexcept { auto const private_key_wi = wi::import_bits(private_key); - auto const public_key_wi = math::wide_integer::powm(wi::G, private_key_wi, wi::P); + auto const public_key_wi = math::wide_integer::powm(wi::generator, private_key_wi, wi::prime); return wi::export_bits(public_key_wi); } -DH::DH(private_key_bigend_t const& private_key) noexcept - : private_key_{ private_key } -{ -} - DH::key_bigend_t DH::publicKey() noexcept { if (public_key_ == key_bigend_t{}) @@ -101,7 +96,7 @@ void DH::setPeerPublicKey(key_bigend_t const& peer_public_key) auto const secret = math::wide_integer::powm( wi::import_bits(peer_public_key), wi::import_bits(private_key_), - wi::P); + wi::prime); secret_ = wi::export_bits(secret); } @@ -111,16 +106,18 @@ void Filter::decryptInit(bool is_incoming, DH const& dh, tr_sha1_digest_t const& { auto const key = is_incoming ? "keyA"sv : "keyB"sv; auto const buf = tr_sha1::digest(key, dh.secret(), info_hash); - dec_key_ = std::make_unique(std::data(buf), std::size(buf)); - dec_key_->discard(1024); + dec_active_ = true; + dec_key_.init(std::data(buf), std::size(buf)); + dec_key_.discard(1024); } void Filter::encryptInit(bool is_incoming, DH const& dh, tr_sha1_digest_t const& info_hash) { auto const key = is_incoming ? "keyB"sv : "keyA"sv; auto const buf = tr_sha1::digest(key, dh.secret(), info_hash); - enc_key_ = std::make_unique(std::data(buf), std::size(buf)); - enc_key_->discard(1024); + enc_active_ = true; + enc_key_.init(std::data(buf), std::size(buf)); + enc_key_.discard(1024); } } // namespace tr_message_stream_encryption diff --git a/libtransmission/peer-mse.h b/libtransmission/peer-mse.h index 802d2df28..ad115b3ee 100644 --- a/libtransmission/peer-mse.h +++ b/libtransmission/peer-mse.h @@ -49,7 +49,10 @@ public: // By default, a private key is randomly generated. // Providing a predefined one is useful for reproducible unit tests. - DH(private_key_bigend_t const& private_key = randomPrivateKey()) noexcept; + constexpr DH(private_key_bigend_t const& private_key = randomPrivateKey()) noexcept + : private_key_{ private_key } + { + } // Returns our own public key to be shared with a peer. [[nodiscard]] key_bigend_t publicKey() noexcept; @@ -80,9 +83,9 @@ public: void decrypt(size_t buf_len, void* buf) { - if (dec_key_) + if (dec_active_) { - dec_key_->process(buf, buf, buf_len); + dec_key_.process(buf, buf, buf_len); } } @@ -90,15 +93,22 @@ public: void encrypt(size_t buf_len, void* buf) { - if (enc_key_) + if (enc_active_) { - enc_key_->process(buf, buf, buf_len); + enc_key_.process(buf, buf, buf_len); } } + [[nodiscard]] constexpr auto is_active() const noexcept + { + return dec_active_ || enc_active_; + } + private: - std::unique_ptr dec_key_; - std::unique_ptr enc_key_; + tr_arc4 dec_key_ = {}; + tr_arc4 enc_key_ = {}; + bool dec_active_ = false; + bool enc_active_ = false; }; } // namespace tr_message_stream_encryption diff --git a/libtransmission/port-forwarding-upnp.cc b/libtransmission/port-forwarding-upnp.cc index e5a4fff64..f58621868 100644 --- a/libtransmission/port-forwarding-upnp.cc +++ b/libtransmission/port-forwarding-upnp.cc @@ -288,7 +288,7 @@ tr_port_forwarding_state tr_upnpPulse(tr_upnp* handle, tr_port port, bool is_ena UPNP_IGD_VALID_CONNECTED) { tr_logAddInfo(fmt::format(_("Found Internet Gateway Device '{url}'"), fmt::arg("url", handle->urls.controlURL))); - tr_logAddInfo(fmt::format(_("Local Address is '{address}'"), fmt::arg("address", std::data(handle->lanaddr)))); + tr_logAddInfo(fmt::format(_("Local Address is '{address}'"), fmt::arg("address", handle->lanaddr.data()))); handle->state = UpnpState::Idle; handle->hasDiscovered = true; handle->lanaddr = std::data(lanaddr); diff --git a/libtransmission/tr-arc4.h b/libtransmission/tr-arc4.h index bcb140216..d7ea9221c 100644 --- a/libtransmission/tr-arc4.h +++ b/libtransmission/tr-arc4.h @@ -26,7 +26,14 @@ class tr_arc4 { public: + constexpr tr_arc4() = default; + constexpr tr_arc4(void const* key, size_t key_length) + { + init(key, key_length); + } + + constexpr void init(void const* key, size_t key_length) { for (size_t i = 0; i < 256; ++i) { @@ -74,7 +81,7 @@ private: return s_[static_cast(s_[i_] + s_[j_])]; } + std::array s_ = {}; uint8_t i_ = 0; uint8_t j_ = 0; - std::array s_ = {}; }; diff --git a/libtransmission/watchdir-inotify.cc b/libtransmission/watchdir-inotify.cc index b77e12e68..9c5b71eac 100644 --- a/libtransmission/watchdir-inotify.cc +++ b/libtransmission/watchdir-inotify.cc @@ -153,7 +153,7 @@ private: // consume entire name into buffer name.resize(ev.len); - nread = bufferevent_read(event, std::data(name), ev.len); + nread = bufferevent_read(event, name.data(), ev.len); if (nread == static_cast(-1)) { auto const error_code = errno;