refactor: aggregate dh in peer io (#4218)

This commit is contained in:
Charles Kerr
2022-11-21 18:08:06 -06:00
committed by GitHub
parent d26db72d7e
commit a3772dc1fa
8 changed files with 47 additions and 42 deletions

View File

@@ -54,7 +54,6 @@ static auto constexpr DefaultAnnounceMinIntervalSec = int{ 60 * 2 };
static auto constexpr Numwant = int{ 80 }; static auto constexpr Numwant = int{ 80 };
/* how often to announce & scrape */ /* how often to announce & scrape */
static auto constexpr UpkeepInterval = 500ms;
static auto constexpr MaxAnnouncesPerUpkeep = int{ 20 }; static auto constexpr MaxAnnouncesPerUpkeep = int{ 20 };
static auto constexpr MaxScrapesPerUpkeep = int{ 20 }; static auto constexpr MaxScrapesPerUpkeep = int{ 20 };
@@ -234,6 +233,8 @@ private:
std::unique_ptr<libtransmission::Timer> const upkeep_timer_; std::unique_ptr<libtransmission::Timer> const upkeep_timer_;
std::set<tr_announce_request, StopsCompare> stops_; std::set<tr_announce_request, StopsCompare> stops_;
static auto constexpr UpkeepInterval = 500ms;
}; };
std::unique_ptr<tr_announcer> tr_announcer::create(tr_session* session, tr_announcer_udp& announcer_udp) std::unique_ptr<tr_announcer> tr_announcer::create(tr_session* session, tr_announcer_udp& announcer_udp)

View File

@@ -223,7 +223,7 @@ std::string tr_sha1_to_string(tr_sha1_digest_t const& digest)
using namespace hex_impl; using namespace hex_impl;
auto str = std::string(std::size(digest) * 2, '?'); 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; return str;
} }
@@ -232,7 +232,7 @@ std::string tr_sha256_to_string(tr_sha256_digest_t const& digest)
using namespace hex_impl; using namespace hex_impl;
auto str = std::string(std::size(digest) * 2, '?'); 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; return str;
} }

View File

@@ -262,27 +262,27 @@ public:
void decryptInit(bool is_incoming, DH const& dh, tr_sha1_digest_t const& info_hash) 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) 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) 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) void encrypt(size_t buflen, void* buf)
{ {
filter().encrypt(buflen, buf); filter_.encrypt(buflen, buf);
} }
[[nodiscard]] bool isEncrypted() const noexcept [[nodiscard]] bool isEncrypted() const noexcept
{ {
return filter_.get() != nullptr; return filter_.is_active();
} }
static void utpInit(struct_utp_context* ctx); static void utpInit(struct_utp_context* ctx);
@@ -323,19 +323,9 @@ private:
{ {
} }
Filter& filter()
{
if (!filter_)
{
filter_ = std::make_unique<Filter>();
}
return *filter_;
}
tr_bandwidth bandwidth_; tr_bandwidth bandwidth_;
std::unique_ptr<tr_message_stream_encryption::Filter> filter_; Filter filter_;
tr_sha1_digest_t torrent_hash_; tr_sha1_digest_t torrent_hash_;

View File

@@ -54,8 +54,8 @@ auto export_bits(UIntWide i)
} }
// NOLINTBEGIN(readability-identifier-naming) // NOLINTBEGIN(readability-identifier-naming)
auto WIDE_INTEGER_CONSTEXPR const G = wi::key_t{ "2" }; auto WIDE_INTEGER_CONSTEXPR const generator = wi::key_t{ "2" };
auto WIDE_INTEGER_CONSTEXPR const P = wi::key_t{ auto WIDE_INTEGER_CONSTEXPR const prime = wi::key_t{
"0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563" "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563"
}; };
// NOLINTEND(readability-identifier-naming) // 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 [[nodiscard]] auto generatePublicKey(DH::private_key_bigend_t const& private_key) noexcept
{ {
auto const private_key_wi = wi::import_bits<wi::private_key_t>(private_key); auto const private_key_wi = wi::import_bits<wi::private_key_t>(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); 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 DH::key_bigend_t DH::publicKey() noexcept
{ {
if (public_key_ == key_bigend_t{}) 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( auto const secret = math::wide_integer::powm(
wi::import_bits<wi::key_t>(peer_public_key), wi::import_bits<wi::key_t>(peer_public_key),
wi::import_bits<wi::private_key_t>(private_key_), wi::import_bits<wi::private_key_t>(private_key_),
wi::P); wi::prime);
secret_ = wi::export_bits(secret); 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 key = is_incoming ? "keyA"sv : "keyB"sv;
auto const buf = tr_sha1::digest(key, dh.secret(), info_hash); auto const buf = tr_sha1::digest(key, dh.secret(), info_hash);
dec_key_ = std::make_unique<tr_arc4>(std::data(buf), std::size(buf)); dec_active_ = true;
dec_key_->discard(1024); 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) 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 key = is_incoming ? "keyB"sv : "keyA"sv;
auto const buf = tr_sha1::digest(key, dh.secret(), info_hash); auto const buf = tr_sha1::digest(key, dh.secret(), info_hash);
enc_key_ = std::make_unique<tr_arc4>(std::data(buf), std::size(buf)); enc_active_ = true;
enc_key_->discard(1024); enc_key_.init(std::data(buf), std::size(buf));
enc_key_.discard(1024);
} }
} // namespace tr_message_stream_encryption } // namespace tr_message_stream_encryption

View File

@@ -49,7 +49,10 @@ public:
// By default, a private key is randomly generated. // By default, a private key is randomly generated.
// Providing a predefined one is useful for reproducible unit tests. // 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. // Returns our own public key to be shared with a peer.
[[nodiscard]] key_bigend_t publicKey() noexcept; [[nodiscard]] key_bigend_t publicKey() noexcept;
@@ -80,9 +83,9 @@ public:
void decrypt(size_t buf_len, void* buf) 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) 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: private:
std::unique_ptr<tr_arc4> dec_key_; tr_arc4 dec_key_ = {};
std::unique_ptr<tr_arc4> enc_key_; tr_arc4 enc_key_ = {};
bool dec_active_ = false;
bool enc_active_ = false;
}; };
} // namespace tr_message_stream_encryption } // namespace tr_message_stream_encryption

View File

@@ -288,7 +288,7 @@ tr_port_forwarding_state tr_upnpPulse(tr_upnp* handle, tr_port port, bool is_ena
UPNP_IGD_VALID_CONNECTED) UPNP_IGD_VALID_CONNECTED)
{ {
tr_logAddInfo(fmt::format(_("Found Internet Gateway Device '{url}'"), fmt::arg("url", handle->urls.controlURL))); 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->state = UpnpState::Idle;
handle->hasDiscovered = true; handle->hasDiscovered = true;
handle->lanaddr = std::data(lanaddr); handle->lanaddr = std::data(lanaddr);

View File

@@ -26,7 +26,14 @@
class tr_arc4 class tr_arc4
{ {
public: public:
constexpr tr_arc4() = default;
constexpr tr_arc4(void const* key, size_t key_length) 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) for (size_t i = 0; i < 256; ++i)
{ {
@@ -74,7 +81,7 @@ private:
return s_[static_cast<uint8_t>(s_[i_] + s_[j_])]; return s_[static_cast<uint8_t>(s_[i_] + s_[j_])];
} }
std::array<uint8_t, 256> s_ = {};
uint8_t i_ = 0; uint8_t i_ = 0;
uint8_t j_ = 0; uint8_t j_ = 0;
std::array<uint8_t, 256> s_ = {};
}; };

View File

@@ -153,7 +153,7 @@ private:
// consume entire name into buffer // consume entire name into buffer
name.resize(ev.len); 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<size_t>(-1)) if (nread == static_cast<size_t>(-1))
{ {
auto const error_code = errno; auto const error_code = errno;