mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
refactor: aggregate dh in peer io (#4218)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_ = {};
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user