1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-24 08:43:27 +00:00

fix: try utp connection first; fix utp timeout issues. (#4897)

This commit is contained in:
Charles Kerr 2023-02-18 10:03:59 -06:00 committed by GitHub
parent adf5051d46
commit e29064023f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 26 deletions

View file

@ -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->have_sent_bittorrent_handshake_ = true;
handshake->set_state(State::AwaitingHandshake); handshake->set_state(State::AwaitingHandshake);
io->write_bytes(std::data(msg), std::size(msg), false); 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->have_sent_bittorrent_handshake_ = true;
handshake->set_state(State::AwaitingHandshake); handshake->set_state(State::AwaitingHandshake);
io->write_bytes(std::data(msg), std::size(msg), false); 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));
tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message, error.code)); handshake->done(false);
handshake->done(false);
}
} }
bool tr_handshake::fire_done(bool is_connected) bool tr_handshake::fire_done(bool is_connected)

View file

@ -130,15 +130,7 @@ std::shared_ptr<tr_peerIo> tr_peerIo::new_outgoing(
auto peer_io = tr_peerIo::create(session, parent, &info_hash, false, is_seed); 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 #ifdef WITH_UTP
// try a UTP socket
if (utp) if (utp)
{ {
auto* const sock = utp_create_socket(session->utp_context); auto* const sock = utp_create_socket(session->utp_context);
@ -153,6 +145,15 @@ std::shared_ptr<tr_peerIo> tr_peerIo::new_outgoing(
} }
#endif #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 {}; 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])); 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; return;
tr_error_set(&error, errcode, utp_error_code_names[errcode]);
call_error_callback(*error);
tr_error_clear(&error);
} }
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 */ #endif /* #ifdef WITH_UTP */

View file

@ -141,7 +141,7 @@ uint64 utp_callback(utp_callback_arguments* args)
return 0; return 0;
} }
void reset_timer(tr_session* session) void restart_timer(tr_session* session)
{ {
auto interval = std::chrono::milliseconds{}; auto interval = std::chrono::milliseconds{};
auto const random_percent = tr_rand_int(1000U) / 1000.0; 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_issue_deferred_acks(session->utp_context);
utp_check_timeouts(session->utp_context); utp_check_timeouts(session->utp_context);
reset_timer(session); restart_timer(session);
} }
} // namespace } // namespace
@ -208,16 +208,12 @@ void tr_utpInit(tr_session* session)
#endif #endif
session->utp_context = ctx; 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) 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); 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 */ /* utp_internal.cpp says "Should be called each time the UDP socket is drained" but it's tricky with libevent */