refactor: only need a single handshake mediator (#4322)

This commit is contained in:
Charles Kerr 2022-12-05 11:47:11 -06:00 committed by GitHub
parent 0e193a0cb3
commit 468310300c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 47 deletions

View File

@ -118,13 +118,10 @@ enum handshake_state_t
struct tr_handshake
{
tr_handshake(
std::unique_ptr<tr_handshake_mediator> mediator_in,
std::shared_ptr<tr_peerIo> io_in,
tr_encryption_mode encryption_mode_in)
: mediator{ std::move(mediator_in) }
tr_handshake(tr_handshake_mediator& mediator_in, std::shared_ptr<tr_peerIo> io_in, tr_encryption_mode encryption_mode_in)
: mediator{ mediator_in }
, io{ std::move(io_in) }
, dh{ mediator->privateKey() }
, dh{ mediator.privateKey() }
, encryption_mode{ encryption_mode_in }
{
}
@ -159,7 +156,7 @@ struct tr_handshake
return provide;
}
std::unique_ptr<tr_handshake_mediator> const mediator;
tr_handshake_mediator& mediator;
bool haveReadAnythingFromPeer = false;
bool haveSentBitTorrentHandshake = false;
@ -222,7 +219,7 @@ static bool buildHandshakeMessage(tr_handshake const* const handshake, uint8_t*
auto const& info_hash = handshake->io->torrentHash();
TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "buildHandshakeMessage requires an info_hash");
auto const info = handshake->mediator->torrentInfo(info_hash);
auto const info = handshake->mediator.torrentInfo(info_hash);
if (!info)
{
return false;
@ -238,7 +235,7 @@ static bool buildHandshakeMessage(tr_handshake const* const handshake, uint8_t*
/* Note that this doesn't depend on whether the torrent is private.
* We don't accept DHT peers for a private torrent,
* but we participate in the DHT regardless. */
if (handshake->mediator->allowsDHT())
if (handshake->mediator.allowsDHT())
{
HANDSHAKE_SET_DHT(walk);
}
@ -303,7 +300,7 @@ static ParseResult parseHandshake(tr_handshake* handshake, tr_peerIo* peer_io)
auto const peer_id_sv = std::string_view{ std::data(peer_id), std::size(peer_id) };
tr_logAddTraceHand(handshake, fmt::format("peer-id is '{}'", peer_id_sv));
if (auto const info = handshake->mediator->torrentInfo(info_hash); info && info->client_peer_id == peer_id)
if (auto const info = handshake->mediator.torrentInfo(info_hash); info && info->client_peer_id == peer_id)
{
tr_logAddTraceHand(handshake, "streuth! we've connected to ourselves.");
return ParseResult::PeerIsSelf;
@ -334,7 +331,7 @@ static void sendPublicKeyAndPad(tr_handshake* handshake)
auto const data = std::data(outbuf);
auto walk = data;
walk = std::copy(std::begin(public_key), std::end(public_key), walk);
walk += handshake->mediator->pad(walk, PadMax);
walk += handshake->mediator.pad(walk, PadMax);
handshake->io->writeBytes(data, walk - data, false);
}
@ -606,7 +603,7 @@ static ReadState readHandshake(tr_handshake* handshake, tr_peerIo* peer_io)
if (handshake->isIncoming())
{
if (!handshake->mediator->torrentInfo(hash))
if (!handshake->mediator.torrentInfo(hash))
{
tr_logAddTraceHand(handshake, "peer is trying to connect to us for a torrent we don't have.");
return tr_handshakeDone(handshake, false);
@ -663,7 +660,7 @@ static ReadState readPeerId(tr_handshake* handshake, tr_peerIo* peer_io)
// if we've somehow connected to ourselves, don't keep the connection
auto const info_hash = peer_io->torrentHash();
auto const info = handshake->mediator->torrentInfo(info_hash);
auto const info = handshake->mediator.torrentInfo(info_hash);
auto const connected_to_self = info && info->client_peer_id == peer_id;
return tr_handshakeDone(handshake, !connected_to_self);
@ -749,10 +746,10 @@ static ReadState readCryptoProvide(tr_handshake* handshake, tr_peerIo* peer_io)
obfuscated_hash[i] = req2[i] ^ req3[i];
}
if (auto const info = handshake->mediator->torrentInfoFromObfuscated(obfuscated_hash); info)
if (auto const info = handshake->mediator.torrentInfoFromObfuscated(obfuscated_hash); info)
{
bool const client_is_seed = info->is_done;
bool const peer_is_seed = handshake->mediator->isPeerKnownSeed(info->id, peer_io->address());
bool const peer_is_seed = handshake->mediator.isPeerKnownSeed(info->id, peer_io->address());
tr_logAddTraceHand(handshake, fmt::format("got INCOMING connection's encrypted handshake for torrent [{}]", info->id));
peer_io->setTorrentHash(info->info_hash);
@ -1056,15 +1053,15 @@ static void gotError(tr_peerIo* io, short what, void* vhandshake)
// the peer probably doesn't speak µTP.
auto const info_hash = io->torrentHash();
auto const info = handshake->mediator->torrentInfo(info_hash);
auto const info = handshake->mediator.torrentInfo(info_hash);
/* Don't mark a peer as non-µTP unless it's really a connect failure. */
if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && info)
{
handshake->mediator->setUTPFailed(info_hash, io->address());
handshake->mediator.setUTPFailed(info_hash, io->address());
}
if (handshake->mediator->allowsTCP() && handshake->io->reconnect() == 0)
if (handshake->mediator.allowsTCP() && handshake->io->reconnect() == 0)
{
auto msg = std::array<uint8_t, HandshakeSize>{};
buildHandshakeMessage(handshake, std::data(msg));
@ -1078,7 +1075,7 @@ static void gotError(tr_peerIo* io, short what, void* vhandshake)
* have encountered a peer that doesn't do encryption... reconnect and
* try a plaintext handshake */
if ((handshake->state == AWAITING_YB || handshake->state == AWAITING_VC) &&
handshake->encryption_mode != TR_ENCRYPTION_REQUIRED && handshake->mediator->allowsTCP() &&
handshake->encryption_mode != TR_ENCRYPTION_REQUIRED && handshake->mediator.allowsTCP() &&
handshake->io->reconnect() == 0)
{
auto msg = std::array<uint8_t, HandshakeSize>{};
@ -1102,16 +1099,16 @@ static void gotError(tr_peerIo* io, short what, void* vhandshake)
**/
tr_handshake* tr_handshakeNew(
std::unique_ptr<tr_handshake_mediator> mediator,
tr_handshake_mediator& mediator,
std::shared_ptr<tr_peerIo> io,
tr_encryption_mode encryption_mode,
tr_handshake_done_func done_func,
void* done_func_user_data)
{
auto* const handshake = new tr_handshake{ std::move(mediator), std::move(io), encryption_mode };
auto* const handshake = new tr_handshake{ mediator, std::move(io), encryption_mode };
handshake->done_func = done_func;
handshake->done_func_user_data = done_func_user_data;
handshake->timeout_timer = handshake->mediator->timerMaker().create([handshake]() { tr_handshakeAbort(handshake); });
handshake->timeout_timer = handshake->mediator.timerMaker().create([handshake]() { tr_handshakeAbort(handshake); });
handshake->timeout_timer->startSingleShot(HandshakeTimeoutSec);
handshake->io->setCallbacks(canRead, nullptr, gotError, handshake);

View File

@ -82,7 +82,7 @@ using tr_handshake_done_func = bool (*)(tr_handshake_result const& result);
/** @brief create a new handshake */
tr_handshake* tr_handshakeNew(
std::unique_ptr<tr_handshake_mediator> mediator,
tr_handshake_mediator& mediator,
std::shared_ptr<tr_peerIo> io,
tr_encryption_mode encryption_mode,
tr_handshake_done_func done_func,

View File

@ -561,6 +561,7 @@ struct tr_peerMgr
{
explicit tr_peerMgr(tr_session* session_in)
: session{ session_in }
, handshake_mediator_{ *session }
, bandwidth_timer_{ session->timerMaker().create([this]() { bandwidthPulse(); }) }
, rechoke_timer_{ session->timerMaker().create([this]() { rechokePulseMarshall(); }) }
, refill_upkeep_timer_{ session->timerMaker().create([this]() { refillUpkeep(); }) }
@ -600,6 +601,8 @@ struct tr_peerMgr
tr_session* const session;
Handshakes incoming_handshakes;
tr_handshake_mediator_impl handshake_mediator_;
private:
void rechokePulseMarshall()
{
@ -1243,7 +1246,7 @@ void tr_peerMgrAddIncoming(tr_peerMgr* manager, tr_address const& addr, tr_port
else /* we don't have a connection to them yet... */
{
auto* const handshake = tr_handshakeNew(
std::make_unique<tr_handshake_mediator_impl>(*session),
manager->handshake_mediator_,
tr_peerIo::newIncoming(session, &session->top_bandwidth_, &addr, port, socket),
session->encryptionMode(),
on_handshake_done,
@ -2808,7 +2811,7 @@ void initiateConnection(tr_peerMgr* mgr, tr_swarm* s, peer_atom& atom)
else
{
auto* const handshake = tr_handshakeNew(
std::make_unique<tr_handshake_mediator_impl>(*mgr->session),
mgr->handshake_mediator_,
std::move(io),
mgr->session->encryptionMode(),
on_handshake_done,

View File

@ -199,7 +199,7 @@ public:
}
static auto runHandshake(
std::unique_ptr<tr_handshake_mediator> mediator,
tr_handshake_mediator& mediator,
std::shared_ptr<tr_peerIo> io,
tr_encryption_mode encryption_mode = TR_CLEAR_PREFERRED)
{
@ -211,7 +211,7 @@ public:
return true;
};
tr_handshakeNew(std::move(mediator), std::move(io), encryption_mode, DoneCallback, &result);
tr_handshakeNew(mediator, std::move(io), encryption_mode, DoneCallback, &result);
waitFor([&result]() { return result.has_value(); }, MaxWaitMsec);
@ -222,8 +222,8 @@ public:
TEST_F(HandshakeTest, incomingPlaintext)
{
auto const peer_id = makeRandomPeerId();
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
auto mediator = MediatorMock{ session_ };
mediator.torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
// The simplest handshake there is. "The handshake starts with character
// nineteen (decimal) followed by the string 'BitTorrent protocol'.
@ -240,7 +240,7 @@ TEST_F(HandshakeTest, incomingPlaintext)
sendToClient(sock, TorrentWeAreSeeding.info_hash);
sendToClient(sock, peer_id);
auto const res = runHandshake(std::move(mediator), io);
auto const res = runHandshake(mediator, io);
// check the results
EXPECT_TRUE(res);
@ -258,8 +258,8 @@ TEST_F(HandshakeTest, incomingPlaintext)
// but this time we don't recognize the infohash sent by the peer.
TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash)
{
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
auto mediator = MediatorMock{ session_ };
mediator.torrents.emplace(TorrentWeAreSeeding.info_hash, TorrentWeAreSeeding);
auto [io, sock] = createIncomingIo(session_);
sendToClient(sock, PlaintextProtocolName);
@ -267,7 +267,7 @@ TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash)
sendToClient(sock, tr_sha1::digest("some other torrent unknown to us"sv));
sendToClient(sock, makeRandomPeerId());
auto const res = runHandshake(std::move(mediator), io);
auto const res = runHandshake(mediator, io);
// check the results
EXPECT_TRUE(res);
@ -283,8 +283,8 @@ TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash)
TEST_F(HandshakeTest, outgoingPlaintext)
{
auto const peer_id = makeRandomPeerId();
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->torrents.emplace(UbuntuTorrent.info_hash, TorrentWeAreSeeding);
auto mediator = MediatorMock{ session_ };
mediator.torrents.emplace(UbuntuTorrent.info_hash, TorrentWeAreSeeding);
auto [io, sock] = createOutgoingIo(session_, UbuntuTorrent.info_hash);
sendToClient(sock, PlaintextProtocolName);
@ -292,7 +292,7 @@ TEST_F(HandshakeTest, outgoingPlaintext)
sendToClient(sock, UbuntuTorrent.info_hash);
sendToClient(sock, peer_id);
auto const res = runHandshake(std::move(mediator), io);
auto const res = runHandshake(mediator, io);
// check the results
EXPECT_TRUE(res);
@ -311,9 +311,9 @@ TEST_F(HandshakeTest, incomingEncrypted)
{
static auto constexpr ExpectedPeerId = makePeerId("-TR300Z-w4bd4mkebkbi"sv);
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto mediator = MediatorMock{ session_ };
mediator.torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
mediator.setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto [io, sock] = createIncomingIo(session_);
@ -330,7 +330,7 @@ TEST_F(HandshakeTest, incomingEncrypted)
"VGwrTPstEPu3V5lmzjtMGVLaL5EErlpJ93Xrz+ea6EIQEUZA+D4jKaV/to9NVi"
"04/1W1A2PHgg+I9puac/i9BsFPcjdQeoVtU73lNCbTDQgTieyjDWmwo="sv);
auto const res = runHandshake(std::move(mediator), io);
auto const res = runHandshake(mediator, io);
// check the results
EXPECT_TRUE(res);
@ -349,8 +349,8 @@ TEST_F(HandshakeTest, incomingEncrypted)
// but this time we don't recognize the infohash sent by the peer.
TEST_F(HandshakeTest, incomingEncryptedUnknownInfoHash)
{
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto mediator = MediatorMock{ session_ };
mediator.setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto [io, sock] = createIncomingIo(session_);
@ -367,7 +367,7 @@ TEST_F(HandshakeTest, incomingEncryptedUnknownInfoHash)
"VGwrTPstEPu3V5lmzjtMGVLaL5EErlpJ93Xrz+ea6EIQEUZA+D4jKaV/to9NVi"
"04/1W1A2PHgg+I9puac/i9BsFPcjdQeoVtU73lNCbTDQgTieyjDWmwo="sv);
auto const res = runHandshake(std::move(mediator), io);
auto const res = runHandshake(mediator, io);
// check the results
EXPECT_TRUE(res);
@ -382,9 +382,9 @@ TEST_F(HandshakeTest, outgoingEncrypted)
{
static auto constexpr ExpectedPeerId = makePeerId("-qB4250-scysDI_JuVN3"sv);
auto mediator = std::make_unique<MediatorMock>(session_);
mediator->torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
mediator->setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto mediator = MediatorMock{ session_ };
mediator.torrents.emplace(UbuntuTorrent.info_hash, UbuntuTorrent);
mediator.setPrivateKeyFromBase64("0EYKCwBWQ4Dg9kX3c5xxjVtBDKw="sv);
auto [io, sock] = createOutgoingIo(session_, UbuntuTorrent.info_hash);
@ -406,7 +406,7 @@ TEST_F(HandshakeTest, outgoingEncrypted)
"3+o/RdiKQJAsGxMIU08scBc5VOmrAmjeYrLNpFnpXVuavH5if7490zMCu3DEn"
"G9hpbYbiX95T+EUcRbM6pSCvr3Twq1Q="sv);
auto const res = runHandshake(std::move(mediator), io, TR_ENCRYPTION_PREFERRED);
auto const res = runHandshake(mediator, io, TR_ENCRYPTION_PREFERRED);
// check the results
EXPECT_TRUE(res);