refactor: only need a single handshake mediator (#4322)
This commit is contained in:
parent
0e193a0cb3
commit
468310300c
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue