Kernel: Fix bugs in TCP state handling in FinWait1 & FinWait2

1. When receiving FIN while in FinWait1, we now reply with ACK
   in addition to the FinWait1->Closing transition.

2. When receiving FIN|ACK while in FinWait1, we now reply with
   ACK and transition from FinWait1->TimeWait.

3. When receiving FIN while in FinWait2, we now reply with ACK.
This commit is contained in:
Andreas Kling 2022-02-06 17:31:32 +01:00
parent 7247f0204d
commit 83523cabda

View file

@ -571,6 +571,12 @@ void handle_tcp(IPv4Packet const& ipv4_packet, Time const& packet_timestamp)
case TCPFlags::FIN:
socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
socket->set_state(TCPSocket::State::Closing);
(void)socket->send_ack(true);
return;
case TCPFlags::FIN | TCPFlags::ACK:
socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
socket->set_state(TCPSocket::State::TimeWait);
(void)socket->send_ack(true);
return;
default:
dbgln("handle_tcp: unexpected flags in FinWait1 state ({:x})", tcp_packet.flags());
@ -583,8 +589,10 @@ void handle_tcp(IPv4Packet const& ipv4_packet, Time const& packet_timestamp)
case TCPFlags::FIN:
socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
socket->set_state(TCPSocket::State::TimeWait);
(void)socket->send_ack(true);
return;
case TCPFlags::ACK | TCPFlags::RST:
// FIXME: Verify that this transition is legitimate.
socket->set_state(TCPSocket::State::Closed);
return;
default: