From 6384abeb2be8347e8840c1db78dd27bdb973a7f5 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Sun, 31 Mar 2024 04:26:55 +0800 Subject: [PATCH] fix: invalid socket address in `tr_peerIo::reconnect()` (#6750) * fix: don't discard socket if reconnect failed * fix: don't try to reconnect more than once --- libtransmission/handshake.cc | 23 +++++++++++++++++------ libtransmission/peer-io.cc | 6 +++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/libtransmission/handshake.cc b/libtransmission/handshake.cc index 82720697b..63297198e 100644 --- a/libtransmission/handshake.cc +++ b/libtransmission/handshake.cc @@ -626,6 +626,17 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha { auto* handshake = static_cast(vhandshake); + auto const retry = [&]() + { + handshake->send_handshake(io); + handshake->set_state(State::AwaitingHandshake); + }; + auto const fail = [&]() + { + tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message(), error.code())); + handshake->done(false); + }; + if (io->is_utp() && !io->is_incoming() && handshake->is_state(State::AwaitingYb)) { // the peer probably doesn't speak µTP. @@ -641,10 +652,12 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha if (handshake->mediator_->allows_tcp() && io->reconnect()) { - handshake->send_handshake(io); - handshake->set_state(State::AwaitingHandshake); + retry(); return; } + + fail(); + return; } /* if the error happened while we were sending a public key, we might @@ -654,13 +667,11 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha handshake->encryption_mode_ != TR_ENCRYPTION_REQUIRED && handshake->mediator_->allows_tcp() && io->reconnect()) { tr_logAddTraceHand(handshake, "handshake failed, trying plaintext..."); - handshake->send_handshake(io); - handshake->set_state(State::AwaitingHandshake); + retry(); return; } - tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message(), error.code())); - handshake->done(false); + fail(); } // --- diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 4ee09be6d..d57acb62e 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -245,12 +245,12 @@ bool tr_peerIo::reconnect() return false; } - socket_ = tr_netOpenPeerSocket(session_, socket_address(), is_seed()); - - if (!socket_.is_tcp()) + auto sock = tr_netOpenPeerSocket(session_, socket_address(), is_seed()); + if (!sock.is_tcp()) { return false; } + socket_ = std::move(sock); this->event_read_.reset(event_new(session_->event_base(), socket_.handle.tcp, EV_READ, event_read_cb, this)); this->event_write_.reset(event_new(session_->event_base(), socket_.handle.tcp, EV_WRITE, event_write_cb, this));