summaryrefslogtreecommitdiff
path: root/Kernel/Net/TCPSocket.cpp
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-05-12 09:14:37 +0200
committerAndreas Kling <kling@serenityos.org>2021-05-12 13:47:07 +0200
commitaf59f64bc0ca4446deb3265a4b1a37be3fb5d2ab (patch)
tree67899ff190d3a8c6af58fda57244c68c2fc77f52 /Kernel/Net/TCPSocket.cpp
parentffc6b714b0876262d80fe7f48ba071ce33ff99fb (diff)
downloadserenity-af59f64bc0ca4446deb3265a4b1a37be3fb5d2ab.zip
Kernel: Coalesce TCP ACKs
Previously we'd send a TCP ACK for each TCP packet we received. This changes NetworkTask so that we send fewer TCP ACKs.
Diffstat (limited to 'Kernel/Net/TCPSocket.cpp')
-rw-r--r--Kernel/Net/TCPSocket.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp
index e72604fa23..c3176538c9 100644
--- a/Kernel/Net/TCPSocket.cpp
+++ b/Kernel/Net/TCPSocket.cpp
@@ -167,6 +167,13 @@ KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_
return data_length;
}
+KResult TCPSocket::send_ack(bool allow_duplicate)
+{
+ if (!allow_duplicate && m_last_ack_number_sent == m_ack_number)
+ return KSuccess;
+ return send_tcp_packet(TCPFlags::ACK);
+}
+
KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, size_t payload_size)
{
const bool has_mss_option = flags == TCPFlags::SYN;
@@ -183,8 +190,11 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload,
tcp_packet.set_data_offset(header_size / sizeof(u32));
tcp_packet.set_flags(flags);
- if (flags & TCPFlags::ACK)
+ if (flags & TCPFlags::ACK) {
+ m_last_ack_number_sent = m_ack_number;
+ m_last_ack_sent_time = kgettimeofday();
tcp_packet.set_ack_number(m_ack_number);
+ }
if (payload && !payload->read(tcp_packet.payload(), payload_size))
return EFAULT;
@@ -308,6 +318,22 @@ void TCPSocket::receive_tcp_packet(const TCPPacket& packet, u16 size)
m_bytes_in += packet.header_size() + size;
}
+bool TCPSocket::should_delay_next_ack() const
+{
+ // FIXME: We don't know the MSS here so make a reasonable guess.
+ const size_t mss = 1500;
+
+ // RFC 1122 says we should send an ACK for every two full-sized segments.
+ if (m_ack_number >= m_last_ack_number_sent + 2 * mss)
+ return false;
+
+ // RFC 1122 says we should not delay ACKs for more than 500 milliseconds.
+ if (kgettimeofday() >= m_last_ack_sent_time + Time::from_milliseconds(500))
+ return false;
+
+ return true;
+}
+
NetworkOrdered<u16> TCPSocket::compute_tcp_checksum(const IPv4Address& source, const IPv4Address& destination, const TCPPacket& packet, u16 payload_size)
{
struct [[gnu::packed]] PseudoHeader {