diff --git a/libtransmission/handshake.cc b/libtransmission/handshake.cc index 170db3473..a09a2f0fc 100644 --- a/libtransmission/handshake.cc +++ b/libtransmission/handshake.cc @@ -792,6 +792,7 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha handshake->have_sent_bittorrent_handshake_ = true; handshake->set_state(State::AwaitingHandshake); io->write_bytes(std::data(msg), std::size(msg), false); + return; } } @@ -807,12 +808,11 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha handshake->have_sent_bittorrent_handshake_ = true; handshake->set_state(State::AwaitingHandshake); io->write_bytes(std::data(msg), std::size(msg), false); + return; } - else - { - tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message, error.code)); - handshake->done(false); - } + + tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message, error.code)); + handshake->done(false); } bool tr_handshake::fire_done(bool is_connected) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 70ffd5bb0..9e631de80 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -130,15 +130,7 @@ std::shared_ptr tr_peerIo::new_outgoing( auto peer_io = tr_peerIo::create(session, parent, &info_hash, false, is_seed); - // try a TCP socket - if (auto sock = tr_netOpenPeerSocket(session, addr, port, is_seed); sock.is_valid()) - { - peer_io->set_socket(std::move(sock)); - return peer_io; - } - #ifdef WITH_UTP - // try a UTP socket if (utp) { auto* const sock = utp_create_socket(session->utp_context); @@ -153,6 +145,15 @@ std::shared_ptr tr_peerIo::new_outgoing( } #endif + if (!peer_io->socket_.is_valid()) + { + if (auto sock = tr_netOpenPeerSocket(session, addr, port, is_seed); sock.is_valid()) + { + peer_io->set_socket(std::move(sock)); + return peer_io; + } + } + return {}; } @@ -677,13 +678,28 @@ void tr_peerIo::on_utp_error(int errcode) { tr_logAddTraceIo(this, fmt::format("utp_on_error -- {}", utp_error_code_names[errcode])); - if (got_error_ != nullptr) + if (got_error_ == nullptr) { - tr_error* error = nullptr; - tr_error_set(&error, errcode, utp_error_code_names[errcode]); - call_error_callback(*error); - tr_error_clear(&error); + return; } + + tr_error* error = nullptr; + switch (errcode) + { + case UTP_ECONNREFUSED: + tr_error_set_from_errno(&error, ECONNREFUSED); + break; + case UTP_ECONNRESET: + tr_error_set_from_errno(&error, ECONNRESET); + break; + case UTP_ETIMEDOUT: + tr_error_set_from_errno(&error, ETIMEDOUT); + break; + default: + tr_error_set(&error, errcode, utp_error_code_names[errcode]); + } + call_error_callback(*error); + tr_error_clear(&error); } #endif /* #ifdef WITH_UTP */ diff --git a/libtransmission/tr-utp.cc b/libtransmission/tr-utp.cc index b26aa83fa..905c68e85 100644 --- a/libtransmission/tr-utp.cc +++ b/libtransmission/tr-utp.cc @@ -141,7 +141,7 @@ uint64 utp_callback(utp_callback_arguments* args) return 0; } -void reset_timer(tr_session* session) +void restart_timer(tr_session* session) { auto interval = std::chrono::milliseconds{}; auto const random_percent = tr_rand_int(1000U) / 1000.0; @@ -177,7 +177,7 @@ void timer_callback(void* vsession) utp_issue_deferred_acks(session->utp_context); utp_check_timeouts(session->utp_context); - reset_timer(session); + restart_timer(session); } } // namespace @@ -208,16 +208,12 @@ void tr_utpInit(tr_session* session) #endif session->utp_context = ctx; + session->utp_timer = session->timerMaker().create(timer_callback, session); + restart_timer(session); } bool tr_utpPacket(unsigned char const* buf, size_t buflen, struct sockaddr const* from, socklen_t fromlen, tr_session* ss) { - if (!ss->isClosing() && !ss->utp_timer) - { - ss->utp_timer = ss->timerMaker().create(timer_callback, ss); - reset_timer(ss); - } - auto const ret = utp_process_udp(ss->utp_context, buf, buflen, from, fromlen); /* utp_internal.cpp says "Should be called each time the UDP socket is drained" but it's tricky with libevent */