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->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)

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);
// 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> 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 */

View File

@ -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 */