Kernel: Trigger TCP fast retransmission when we encounter lost packets

When we receive a TCP packet with a sequence number that is not what
we expected we have lost one or more packets. We can signal this to
the sender by sending a TCP ACK with the previous ack number so that
they can resend the missing TCP fragments.
This commit is contained in:
Gunnar Beutner 2021-05-12 08:13:53 +02:00 committed by Andreas Kling
parent 7272127927
commit ffc6b714b0
Notes: sideshowbarker 2024-07-18 18:17:58 +09:00
2 changed files with 14 additions and 0 deletions

View file

@ -533,9 +533,16 @@ void handle_tcp(const IPv4Packet& ipv4_packet, const Time& packet_timestamp)
if (tcp_packet.sequence_number() != socket->ack_number()) {
dbgln_if(TCP_DEBUG, "Discarding out of order packet: seq {} vs. ack {}", tcp_packet.sequence_number(), socket->ack_number());
if (socket->duplicate_acks() < TCPSocket::maximum_duplicate_acks) {
dbgln_if(TCP_DEBUG, "Sending ACK with same ack number to trigger fast retransmission");
socket->set_duplicate_acks(socket->duplicate_acks() + 1);
unused_rc = socket->send_tcp_packet(TCPFlags::ACK);
}
return;
}
socket->set_duplicate_acks(0);
if (tcp_packet.has_fin()) {
if (payload_size != 0)
socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), { &ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size() }, packet_timestamp);

View file

@ -128,6 +128,11 @@ public:
u32 packets_out() const { return m_packets_out; }
u32 bytes_out() const { return m_bytes_out; }
// FIXME: Make this configurable?
static constexpr u32 maximum_duplicate_acks = 5;
void set_duplicate_acks(u32 acks) { m_duplicate_acks = acks; }
u32 duplicate_acks() const { return m_duplicate_acks; }
KResult send_tcp_packet(u16 flags, const UserOrKernelBuffer* = nullptr, size_t = 0);
void send_outgoing_packets(RoutingDecision&);
void receive_tcp_packet(const TCPPacket&, u16 size);
@ -187,6 +192,8 @@ private:
Lock m_not_acked_lock { "TCPSocket unacked packets" };
SinglyLinkedList<OutgoingPacket> m_not_acked;
u32 m_duplicate_acks { 0 };
};
}