From 8fa55e5a1cb9236105b3033eb4e94ddd62097978 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 26 Jul 2024 21:47:47 -0700 Subject: [PATCH] fix issue when closing a uTP connection with a close reason and picking up a nagle packet. This would corrupt the payload. --- ChangeLog | 1 + src/utp_stream.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00cd9f616b8..e3e73bba456 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2.0.11 not released + * fix uTP issue where closing the connection could corrupt the payload * apply DSCP/TOS to sockets before initiating the TCP connection * assume copy_file_range() exists on linux (unless old glibc) * fix issue where set_piece_deadline() did not correctly post read_piece_alert diff --git a/src/utp_stream.cpp b/src/utp_stream.cpp index 2adfe4c4451..26ca9f5f878 100644 --- a/src/utp_stream.cpp +++ b/src/utp_stream.cpp @@ -1503,7 +1503,7 @@ bool utp_socket_impl::send_pkt(int const flags) // for non MTU-probes, use the conservative packet size int const effective_mtu = mtu_probe ? m_mtu : m_mtu_floor; - auto const close_reason = static_cast(m_close_reason); + auto close_reason = static_cast(m_close_reason); int sack = 0; if (m_inbuf.size()) @@ -1605,7 +1605,7 @@ bool utp_socket_impl::send_pkt(int const flags) int const packet_size = header_size + payload_size; p->size = std::uint16_t(packet_size); - p->header_size = std::uint16_t(packet_size - payload_size); + p->header_size = std::uint16_t(header_size); p->num_transmissions = 0; #if TORRENT_USE_ASSERTS p->num_fast_resend = 0; @@ -1662,6 +1662,10 @@ bool utp_socket_impl::send_pkt(int const flags) else sack = 0; + // we should not add or update a close reason extension header on a + // nagle packet. It's a bit tricky to get all the cases right. + close_reason = 0; + std::int32_t const size_left = std::min({ p->allocated - p->size , m_write_buffer_size @@ -1708,6 +1712,7 @@ bool utp_socket_impl::send_pkt(int const flags) *ptr++ = utp_no_extension; *ptr++ = 4; aux::write_uint32(close_reason, ptr); + TORRENT_ASSERT(ptr <= p->buf + p->header_size); } if (m_bytes_in_flight > 0