summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-02-06 17:31:32 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-06 22:13:13 +0100
commit83523cabda25b9a9e08d4c38811e60d9a2913919 (patch)
tree684a42b4eeb93321b1bcbef3292eb7b5c20592d9 /Kernel
parent7247f0204d7ac4612b058176d401364e73bb52c1 (diff)
downloadserenity-83523cabda25b9a9e08d4c38811e60d9a2913919.zip
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.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Net/NetworkTask.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp
index e1d973af20..c99d167f80 100644
--- a/Kernel/Net/NetworkTask.cpp
+++ b/Kernel/Net/NetworkTask.cpp
@@ -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: