From 12e534c8c6cd8a79bd447ad41cef73324d5080ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Thu, 17 Aug 2023 19:53:49 +0200 Subject: [PATCH] =?UTF-8?q?Kernel:=20Implement=20Nagle=E2=80=99s=20Algorit?= =?UTF-8?q?hm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an initial implementation, about as basic as intended by the RFC, and not configurable from userspace at the moment. It should reduce the amount of low-sized packets sent, reducing overhead and thereby network traffic. --- Kernel/Net/TCPSocket.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index c6cd0c5b3e..e9224f497a 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -210,6 +210,18 @@ ErrorOr TCPSocket::protocol_send(UserOrKernelBuffer const& data, size_t if (routing_decision.is_zero()) return set_so_error(EHOSTUNREACH); size_t mss = routing_decision.adapter->mtu() - sizeof(IPv4Packet) - sizeof(TCPPacket); + + // RFC 896 (Nagle’s algorithm): https://www.ietf.org/rfc/rfc0896 + // "The solution is to inhibit the sending of new TCP segments when + // new outgoing data arrives from the user if any previously + // transmitted data on the connection remains unacknowledged. This + // inhibition is to be unconditional; no timers, tests for size of + // data received, or other conditions are required." + // FIXME: Make this configurable via TCP_NODELAY. + auto has_unacked_data = m_unacked_packets.with_shared([&](auto const& packets) { return packets.size > 0; }); + if (has_unacked_data && data_length < mss) + return 0; + data_length = min(data_length, mss); TRY(send_tcp_packet(TCPFlags::PSH | TCPFlags::ACK, &data, data_length, &routing_decision)); return data_length;