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 };
/* 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<libtransmission::Timer> const upkeep_timer_;
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)

View File

@@ -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;
}

View File

@@ -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<Filter>();
}
return *filter_;
}
tr_bandwidth bandwidth_;
std::unique_ptr<tr_message_stream_encryption::Filter> filter_;
Filter filter_;
tr_sha1_digest_t torrent_hash_;

View File

@@ -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<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);
}
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<wi::key_t>(peer_public_key),
wi::import_bits<wi::private_key_t>(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<tr_arc4>(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<tr_arc4>(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

View File

@@ -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<tr_arc4> dec_key_;
std::unique_ptr<tr_arc4> enc_key_;
tr_arc4 dec_key_ = {};
tr_arc4 enc_key_ = {};
bool dec_active_ = false;
bool enc_active_ = false;
};
} // 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)
{
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);

View File

@@ -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<uint8_t>(s_[i_] + s_[j_])];
}
std::array<uint8_t, 256> s_ = {};
uint8_t i_ = 0;
uint8_t j_ = 0;
std::array<uint8_t, 256> s_ = {};
};

View File

@@ -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<size_t>(-1))
{
auto const error_code = errno;