Kernel: Add unhandled cases for the FinWait2 state

According to RFC 9293 Section 3.6.1. Half-Closed Connections, we should
still accept incoming packets in the FinWait2 state. Additionally, we
didn't handle the FIN+ACK case. We should handle this the same we
handle the FIN flag. The ACK is only added to signify successful
reception of the last packet.
This commit is contained in:
jared 2023-12-28 12:23:43 -05:00 committed by Andrew Kaster
parent 9d3604215d
commit 7244369aff
Notes: sideshowbarker 2024-07-17 01:04:03 +09:00

View file

@ -603,6 +603,7 @@ void handle_tcp(IPv4Packet const& ipv4_packet, UnixDateTime const& packet_timest
}
case TCPSocket::State::FinWait2:
switch (tcp_packet.flags()) {
case TCPFlags::FIN | TCPFlags::ACK: // Fallthrough
case TCPFlags::FIN:
socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
socket->set_state(TCPSocket::State::TimeWait);
@ -612,6 +613,18 @@ void handle_tcp(IPv4Packet const& ipv4_packet, UnixDateTime const& packet_timest
// FIXME: Verify that this transition is legitimate.
socket->set_state(TCPSocket::State::Closed);
return;
case TCPFlags::ACK:
socket->set_duplicate_acks(0);
if (payload_size) {
if (socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), { &ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size() }, packet_timestamp)) {
socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
dbgln_if(TCP_DEBUG, "Got packet with ack_no={}, seq_no={}, payload_size={}, acking it with new ack_no={}, seq_no={}",
tcp_packet.ack_number(), tcp_packet.sequence_number(), payload_size, socket->ack_number(), socket->sequence_number());
send_delayed_tcp_ack(*socket);
}
}
return;
default:
dbgln("handle_tcp: unexpected flags in FinWait2 state ({:x})", tcp_packet.flags());
(void)socket->send_tcp_packet(TCPFlags::RST);