2020-01-18 08:38:21 +00:00
/*
2021-03-12 10:59:41 +00:00
* Copyright ( c ) 2018 - 2021 , Andreas Kling < kling @ serenityos . org >
2020-01-18 08:38:21 +00:00
*
2021-04-22 08:24:48 +00:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-01-18 08:38:21 +00:00
*/
2021-01-25 15:07:10 +00:00
# include <Kernel/Debug.h>
2021-07-18 07:10:27 +00:00
# include <Kernel/Locking/Mutex.h>
2021-08-21 21:31:15 +00:00
# include <Kernel/Locking/MutexProtected.h>
2019-06-07 09:43:58 +00:00
# include <Kernel/Net/ARP.h>
# include <Kernel/Net/EtherType.h>
2019-04-02 17:54:38 +00:00
# include <Kernel/Net/EthernetFrameHeader.h>
# include <Kernel/Net/ICMP.h>
# include <Kernel/Net/IPv4.h>
# include <Kernel/Net/IPv4Socket.h>
2019-06-07 09:43:58 +00:00
# include <Kernel/Net/LoopbackAdapter.h>
2020-04-09 11:31:05 +00:00
# include <Kernel/Net/NetworkTask.h>
2021-06-04 04:43:16 +00:00
# include <Kernel/Net/NetworkingManagement.h>
2019-08-28 11:53:01 +00:00
# include <Kernel/Net/Routing.h>
2019-06-07 09:43:58 +00:00
# include <Kernel/Net/TCP.h>
2019-04-02 17:54:38 +00:00
# include <Kernel/Net/TCPSocket.h>
2019-06-07 09:43:58 +00:00
# include <Kernel/Net/UDP.h>
2019-04-02 17:54:38 +00:00
# include <Kernel/Net/UDPSocket.h>
2019-03-11 11:43:45 +00:00
# include <Kernel/Process.h>
2019-03-11 22:21:38 +00:00
2020-02-16 00:27:42 +00:00
namespace Kernel {
2021-08-01 17:54:42 +00:00
static void handle_arp ( EthernetFrameHeader const & , size_t frame_size ) ;
static void handle_ipv4 ( EthernetFrameHeader const & , size_t frame_size , Time const & packet_timestamp ) ;
static void handle_icmp ( EthernetFrameHeader const & , IPv4Packet const & , Time const & packet_timestamp ) ;
static void handle_udp ( IPv4Packet const & , Time const & packet_timestamp ) ;
static void handle_tcp ( IPv4Packet const & , Time const & packet_timestamp ) ;
2021-05-12 07:14:37 +00:00
static void send_delayed_tcp_ack ( RefPtr < TCPSocket > socket ) ;
2021-07-18 22:19:25 +00:00
static void send_tcp_rst ( IPv4Packet const & ipv4_packet , TCPPacket const & tcp_packet , RefPtr < NetworkAdapter > adapter ) ;
2021-05-13 05:45:14 +00:00
static void flush_delayed_tcp_acks ( ) ;
2021-05-13 08:49:10 +00:00
static void retransmit_tcp_packets ( ) ;
2019-03-11 11:43:45 +00:00
2021-04-30 17:18:23 +00:00
static Thread * network_task = nullptr ;
2021-05-12 07:14:37 +00:00
static HashTable < RefPtr < TCPSocket > > * delayed_ack_sockets ;
2021-04-30 17:18:23 +00:00
2020-11-17 03:51:34 +00:00
[[noreturn]] static void NetworkTask_main ( void * ) ;
2020-04-09 11:31:05 +00:00
void NetworkTask : : spawn ( )
{
2020-09-27 14:53:35 +00:00
RefPtr < Thread > thread ;
2021-09-07 10:53:28 +00:00
auto name = KString : : try_create ( " NetworkTask " ) ;
if ( name . is_error ( ) )
TODO ( ) ;
2021-12-03 10:23:09 +00:00
( void ) Process : : create_kernel_process ( thread , name . release_value ( ) , NetworkTask_main , nullptr ) ;
2021-04-30 17:18:23 +00:00
network_task = thread ;
}
bool NetworkTask : : is_current ( )
{
return Thread : : current ( ) = = network_task ;
2020-04-09 11:31:05 +00:00
}
2020-11-17 03:51:34 +00:00
void NetworkTask_main ( void * )
2019-03-11 11:43:45 +00:00
{
2021-05-12 07:14:37 +00:00
delayed_ack_sockets = new HashTable < RefPtr < TCPSocket > > ;
2019-12-01 15:47:49 +00:00
WaitQueue packet_wait_queue ;
2019-08-28 11:53:01 +00:00
int pending_packets = 0 ;
2021-06-04 04:43:16 +00:00
NetworkingManagement : : the ( ) . for_each ( [ & ] ( auto & adapter ) {
2021-04-03 01:42:32 +00:00
dmesgln ( " NetworkTask: {} network adapter found: hw={} " , adapter . class_name ( ) , adapter . mac_address ( ) . to_string ( ) ) ;
2021-09-07 10:14:00 +00:00
if ( adapter . class_name ( ) = = " LoopbackAdapter " sv ) {
2019-08-28 11:53:01 +00:00
adapter . set_ipv4_address ( { 127 , 0 , 0 , 1 } ) ;
adapter . set_ipv4_netmask ( { 255 , 0 , 0 , 0 } ) ;
}
2019-04-02 13:46:44 +00:00
2019-12-01 15:47:49 +00:00
adapter . on_receive = [ & ] ( ) {
2019-08-28 11:53:01 +00:00
pending_packets + + ;
2019-12-01 15:47:49 +00:00
packet_wait_queue . wake_all ( ) ;
2019-08-28 12:14:38 +00:00
} ;
2019-08-28 11:53:01 +00:00
} ) ;
2019-03-11 11:43:45 +00:00
2021-02-28 01:48:45 +00:00
auto dequeue_packet = [ & pending_packets ] ( u8 * buffer , size_t buffer_size , Time & packet_timestamp ) - > size_t {
2019-12-01 15:47:49 +00:00
if ( pending_packets = = 0 )
2019-12-14 10:07:37 +00:00
return 0 ;
size_t packet_size = 0 ;
2021-06-04 04:43:16 +00:00
NetworkingManagement : : the ( ) . for_each ( [ & ] ( auto & adapter ) {
2019-12-14 10:07:37 +00:00
if ( packet_size | | ! adapter . has_queued_packets ( ) )
2019-08-28 11:53:01 +00:00
return ;
2020-09-16 16:25:06 +00:00
packet_size = adapter . dequeue_packet ( buffer , buffer_size , packet_timestamp ) ;
2019-08-28 11:53:01 +00:00
pending_packets - - ;
2021-03-12 10:59:41 +00:00
dbgln_if ( NETWORK_TASK_DEBUG , " NetworkTask: Dequeued packet from {} ({} bytes) " , adapter . name ( ) , packet_size ) ;
2019-08-28 11:53:01 +00:00
} ) ;
2019-12-14 10:07:37 +00:00
return packet_size ;
2019-04-02 13:46:44 +00:00
} ;
AK: Rename KB, MB, GB to KiB, MiB, GiB
The SI prefixes "k", "M", "G" mean "10^3", "10^6", "10^9".
The IEC prefixes "Ki", "Mi", "Gi" mean "2^10", "2^20", "2^30".
Let's use the correct name, at least in code.
Only changes the name of the constants, no other behavior change.
2020-08-15 17:55:00 +00:00
size_t buffer_size = 64 * KiB ;
2021-09-05 23:36:14 +00:00
auto region_or_error = MM . allocate_kernel_region ( buffer_size , " Kernel Packet Buffer " , Memory : : Region : : Access : : ReadWrite ) ;
if ( region_or_error . is_error ( ) )
TODO ( ) ;
auto buffer_region = region_or_error . release_value ( ) ;
2019-12-27 23:07:56 +00:00
auto buffer = ( u8 * ) buffer_region - > vaddr ( ) . get ( ) ;
2021-02-28 01:48:45 +00:00
Time packet_timestamp ;
2019-12-27 23:07:56 +00:00
2019-03-11 11:43:45 +00:00
for ( ; ; ) {
2021-05-13 05:45:14 +00:00
flush_delayed_tcp_acks ( ) ;
2021-05-13 08:49:10 +00:00
retransmit_tcp_packets ( ) ;
2020-09-16 16:25:06 +00:00
size_t packet_size = dequeue_packet ( buffer , buffer_size , packet_timestamp ) ;
2019-12-14 10:07:37 +00:00
if ( ! packet_size ) {
2021-05-13 05:45:14 +00:00
auto timeout_time = Time : : from_milliseconds ( 500 ) ;
auto timeout = Thread : : BlockTimeout { false , & timeout_time } ;
[[maybe_unused]] auto result = packet_wait_queue . wait_on ( timeout , " NetworkTask " ) ;
2019-03-11 11:43:45 +00:00
continue ;
}
2019-12-14 10:07:37 +00:00
if ( packet_size < sizeof ( EthernetFrameHeader ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " NetworkTask: Packet is too small to be an Ethernet packet! ({}) " , packet_size ) ;
2019-03-11 11:43:45 +00:00
continue ;
}
2021-08-01 17:54:42 +00:00
auto & eth = * ( EthernetFrameHeader const * ) buffer ;
2021-03-12 10:59:41 +00:00
dbgln_if ( ETHERNET_DEBUG , " NetworkTask: From {} to {}, ether_type={:#04x}, packet_size={} " , eth . source ( ) . to_string ( ) , eth . destination ( ) . to_string ( ) , eth . ether_type ( ) , packet_size ) ;
2019-08-06 13:40:38 +00:00
2019-03-11 22:21:38 +00:00
switch ( eth . ether_type ( ) ) {
case EtherType : : ARP :
2019-12-14 10:07:37 +00:00
handle_arp ( eth , packet_size ) ;
2019-03-11 22:21:38 +00:00
break ;
case EtherType : : IPv4 :
2020-09-16 16:25:06 +00:00
handle_ipv4 ( eth , packet_size , packet_timestamp ) ;
2019-03-11 22:21:38 +00:00
break ;
2019-08-28 00:53:12 +00:00
case EtherType : : IPv6 :
// ignore
break ;
default :
2021-04-26 22:42:15 +00:00
dbgln_if ( ETHERNET_DEBUG , " NetworkTask: Unknown ethernet type {:#04x} " , eth . ether_type ( ) ) ;
2019-03-11 22:21:38 +00:00
}
2019-03-11 11:43:45 +00:00
}
}
2019-03-11 22:21:38 +00:00
2021-08-01 17:54:42 +00:00
void handle_arp ( EthernetFrameHeader const & eth , size_t frame_size )
2019-03-11 22:21:38 +00:00
{
2019-08-09 08:42:01 +00:00
constexpr size_t minimum_arp_frame_size = sizeof ( EthernetFrameHeader ) + sizeof ( ARPPacket ) ;
2019-03-11 22:21:38 +00:00
if ( frame_size < minimum_arp_frame_size ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_arp: Frame too small ({}, need {}) " , frame_size , minimum_arp_frame_size ) ;
2019-03-11 22:21:38 +00:00
return ;
}
2021-08-01 17:54:42 +00:00
auto & packet = * static_cast < ARPPacket const * > ( eth . payload ( ) ) ;
2019-03-11 23:01:07 +00:00
if ( packet . hardware_type ( ) ! = 1 | | packet . hardware_address_length ( ) ! = sizeof ( MACAddress ) ) {
2020-12-25 16:05:05 +00:00
dbgln ( " handle_arp: Hardware type not ethernet ({:#04x}, len={}) " , packet . hardware_type ( ) , packet . hardware_address_length ( ) ) ;
2019-03-11 22:21:38 +00:00
return ;
}
2019-03-11 23:01:07 +00:00
if ( packet . protocol_type ( ) ! = EtherType : : IPv4 | | packet . protocol_address_length ( ) ! = sizeof ( IPv4Address ) ) {
2020-12-25 16:05:05 +00:00
dbgln ( " handle_arp: Protocol type not IPv4 ({:#04x}, len={}) " , packet . protocol_type ( ) , packet . protocol_address_length ( ) ) ;
2019-03-11 22:21:38 +00:00
return ;
}
2021-03-12 10:59:41 +00:00
dbgln_if ( ARP_DEBUG , " handle_arp: operation={:#04x}, sender={}/{}, target={}/{} " ,
2020-12-25 16:05:05 +00:00
packet . operation ( ) ,
packet . sender_hardware_address ( ) . to_string ( ) ,
packet . sender_protocol_address ( ) . to_string ( ) ,
packet . target_hardware_address ( ) . to_string ( ) ,
packet . target_protocol_address ( ) . to_string ( ) ) ;
2019-03-11 22:21:38 +00:00
2019-09-08 07:26:21 +00:00
if ( ! packet . sender_hardware_address ( ) . is_zero ( ) & & ! packet . sender_protocol_address ( ) . is_zero ( ) ) {
// Someone has this IPv4 address. I guess we can try to remember that.
// FIXME: Protect against ARP spamming.
2022-03-12 18:56:23 +00:00
update_arp_table ( packet . sender_protocol_address ( ) , packet . sender_hardware_address ( ) , UpdateTable : : Set ) ;
2019-09-08 07:26:21 +00:00
}
2019-03-12 00:30:49 +00:00
if ( packet . operation ( ) = = ARPOperation : : Request ) {
2019-03-11 22:21:38 +00:00
// Who has this IP address?
2021-06-04 04:43:16 +00:00
if ( auto adapter = NetworkingManagement : : the ( ) . from_ipv4_address ( packet . target_protocol_address ( ) ) ) {
2019-03-11 22:21:38 +00:00
// We do!
2021-03-12 10:59:41 +00:00
dbgln ( " handle_arp: Responding to ARP request for my IPv4 address ({}) " , adapter - > ipv4_address ( ) ) ;
2019-03-11 22:21:38 +00:00
ARPPacket response ;
2019-03-12 00:30:49 +00:00
response . set_operation ( ARPOperation : : Response ) ;
2019-03-11 23:01:07 +00:00
response . set_target_hardware_address ( packet . sender_hardware_address ( ) ) ;
response . set_target_protocol_address ( packet . sender_protocol_address ( ) ) ;
2019-03-12 12:30:36 +00:00
response . set_sender_hardware_address ( adapter - > mac_address ( ) ) ;
response . set_sender_protocol_address ( adapter - > ipv4_address ( ) ) ;
2019-03-11 22:21:38 +00:00
2019-03-12 12:30:36 +00:00
adapter - > send ( packet . sender_hardware_address ( ) , response ) ;
2019-03-11 22:21:38 +00:00
}
2019-03-11 23:56:33 +00:00
return ;
}
2019-03-11 22:21:38 +00:00
}
2021-08-01 17:54:42 +00:00
void handle_ipv4 ( EthernetFrameHeader const & eth , size_t frame_size , Time const & packet_timestamp )
2019-03-11 22:21:38 +00:00
{
2019-08-09 08:42:01 +00:00
constexpr size_t minimum_ipv4_frame_size = sizeof ( EthernetFrameHeader ) + sizeof ( IPv4Packet ) ;
2019-03-12 03:11:20 +00:00
if ( frame_size < minimum_ipv4_frame_size ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_ipv4: Frame too small ({}, need {}) " , frame_size , minimum_ipv4_frame_size ) ;
2019-03-12 03:11:20 +00:00
return ;
}
2021-08-01 17:54:42 +00:00
auto & packet = * static_cast < IPv4Packet const * > ( eth . payload ( ) ) ;
2019-03-11 22:21:38 +00:00
2019-08-09 07:36:06 +00:00
if ( packet . length ( ) < sizeof ( IPv4Packet ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_ipv4: IPv4 packet too short ({}, need {}) " , packet . length ( ) , sizeof ( IPv4Packet ) ) ;
2019-08-09 07:36:06 +00:00
return ;
}
size_t actual_ipv4_packet_length = frame_size - sizeof ( EthernetFrameHeader ) ;
if ( packet . length ( ) > actual_ipv4_packet_length ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_ipv4: IPv4 packet claims to be longer than it is ({}, actually {}) " , packet . length ( ) , actual_ipv4_packet_length ) ;
2019-08-09 07:36:06 +00:00
return ;
}
2021-03-12 10:59:41 +00:00
dbgln_if ( IPV4_DEBUG , " handle_ipv4: source={}, destination={} " , packet . source ( ) , packet . destination ( ) ) ;
2019-03-12 03:11:20 +00:00
2021-06-04 04:43:16 +00:00
NetworkingManagement : : the ( ) . for_each ( [ & ] ( auto & adapter ) {
2021-04-30 20:07:41 +00:00
if ( adapter . link_up ( ) ) {
auto my_net = adapter . ipv4_address ( ) . to_u32 ( ) & adapter . ipv4_netmask ( ) . to_u32 ( ) ;
auto their_net = packet . source ( ) . to_u32 ( ) & adapter . ipv4_netmask ( ) . to_u32 ( ) ;
if ( my_net = = their_net )
2022-03-12 18:56:23 +00:00
update_arp_table ( packet . source ( ) , eth . source ( ) , UpdateTable : : Set ) ;
2021-04-30 20:07:41 +00:00
}
} ) ;
2019-03-12 11:43:30 +00:00
switch ( ( IPv4Protocol ) packet . protocol ( ) ) {
2019-03-12 03:11:20 +00:00
case IPv4Protocol : : ICMP :
2020-09-16 16:25:06 +00:00
return handle_icmp ( eth , packet , packet_timestamp ) ;
2019-03-13 13:22:27 +00:00
case IPv4Protocol : : UDP :
2020-09-16 16:25:06 +00:00
return handle_udp ( packet , packet_timestamp ) ;
2019-03-13 16:17:07 +00:00
case IPv4Protocol : : TCP :
2020-09-16 16:25:06 +00:00
return handle_tcp ( packet , packet_timestamp ) ;
2019-03-12 03:11:20 +00:00
default :
2021-04-26 22:42:15 +00:00
dbgln_if ( IPV4_DEBUG , " handle_ipv4: Unhandled protocol {:#02x} " , packet . protocol ( ) ) ;
2019-03-12 03:11:20 +00:00
break ;
}
}
2021-08-01 17:54:42 +00:00
void handle_icmp ( EthernetFrameHeader const & eth , IPv4Packet const & ipv4_packet , Time const & packet_timestamp )
2019-03-12 03:11:20 +00:00
{
2021-08-01 17:54:42 +00:00
auto & icmp_header = * static_cast < ICMPHeader const * > ( ipv4_packet . payload ( ) ) ;
2021-03-12 10:59:41 +00:00
dbgln_if ( ICMP_DEBUG , " handle_icmp: source={}, destination={}, type={:#02x}, code={:#02x} " , ipv4_packet . source ( ) . to_string ( ) , ipv4_packet . destination ( ) . to_string ( ) , icmp_header . type ( ) , icmp_header . code ( ) ) ;
2019-03-12 11:43:30 +00:00
2019-03-12 16:27:07 +00:00
{
2021-02-12 13:49:34 +00:00
NonnullRefPtrVector < IPv4Socket > icmp_sockets ;
2021-08-15 13:46:35 +00:00
IPv4Socket : : all_sockets ( ) . with_exclusive ( [ & ] ( auto & sockets ) {
for ( auto & socket : sockets ) {
if ( socket . protocol ( ) = = ( unsigned ) IPv4Protocol : : ICMP )
icmp_sockets . append ( socket ) ;
}
2021-07-18 09:59:25 +00:00
} ) ;
2021-02-12 13:49:34 +00:00
for ( auto & socket : icmp_sockets )
2021-05-11 17:47:40 +00:00
socket . did_receive ( ipv4_packet . source ( ) , 0 , { & ipv4_packet , sizeof ( IPv4Packet ) + ipv4_packet . payload_size ( ) } , packet_timestamp ) ;
2019-03-12 16:27:07 +00:00
}
2021-06-04 04:43:16 +00:00
auto adapter = NetworkingManagement : : the ( ) . from_ipv4_address ( ipv4_packet . destination ( ) ) ;
2019-03-12 12:30:36 +00:00
if ( ! adapter )
2019-03-12 11:43:30 +00:00
return ;
if ( icmp_header . type ( ) = = ICMPType : : EchoRequest ) {
2021-08-01 17:54:42 +00:00
auto & request = reinterpret_cast < ICMPEchoPacket const & > ( icmp_header ) ;
2021-03-12 10:59:41 +00:00
dbgln ( " handle_icmp: EchoRequest from {}: id={}, seq={} " , ipv4_packet . source ( ) , ( u16 ) request . identifier , ( u16 ) request . sequence_number ) ;
2019-03-12 11:43:30 +00:00
size_t icmp_packet_size = ipv4_packet . payload_size ( ) ;
2020-10-20 15:53:11 +00:00
if ( icmp_packet_size < sizeof ( ICMPEchoPacket ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_icmp: EchoRequest packet is too small, ignoring. " ) ;
2020-10-20 15:53:11 +00:00
return ;
}
2021-05-26 03:35:05 +00:00
auto ipv4_payload_offset = adapter - > ipv4_payload_offset ( ) ;
auto packet = adapter - > acquire_packet_buffer ( ipv4_payload_offset + icmp_packet_size ) ;
if ( ! packet ) {
dbgln ( " Could not allocate packet buffer while sending ICMP packet " ) ;
return ;
}
2021-10-27 20:20:24 +00:00
adapter - > fill_in_ipv4_header ( * packet , adapter - > ipv4_address ( ) , eth . source ( ) , ipv4_packet . source ( ) , IPv4Protocol : : ICMP , icmp_packet_size , 0 , 64 ) ;
2021-08-01 12:11:49 +00:00
memset ( packet - > buffer - > data ( ) + ipv4_payload_offset , 0 , sizeof ( ICMPEchoPacket ) ) ;
auto & response = * ( ICMPEchoPacket * ) ( packet - > buffer - > data ( ) + ipv4_payload_offset ) ;
2019-03-12 11:43:30 +00:00
response . header . set_type ( ICMPType : : EchoReply ) ;
response . header . set_code ( 0 ) ;
response . identifier = request . identifier ;
response . sequence_number = request . sequence_number ;
if ( size_t icmp_payload_size = icmp_packet_size - sizeof ( ICMPEchoPacket ) )
memcpy ( response . payload ( ) , request . payload ( ) , icmp_payload_size ) ;
response . header . set_checksum ( internet_checksum ( & response , icmp_packet_size ) ) ;
2019-09-19 19:40:06 +00:00
// FIXME: What is the right TTL value here? Is 64 ok? Should we use the same TTL as the echo request?
2021-08-01 12:11:49 +00:00
adapter - > send_packet ( packet - > bytes ( ) ) ;
2021-05-26 03:35:05 +00:00
adapter - > release_packet_buffer ( * packet ) ;
2019-03-12 03:11:20 +00:00
}
2019-03-11 22:21:38 +00:00
}
2019-03-13 13:22:27 +00:00
2021-08-01 17:54:42 +00:00
void handle_udp ( IPv4Packet const & ipv4_packet , Time const & packet_timestamp )
2019-03-13 13:22:27 +00:00
{
2019-08-09 08:42:01 +00:00
if ( ipv4_packet . payload_size ( ) < sizeof ( UDPPacket ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_udp: Packet too small ({}, need {}) " , ipv4_packet . payload_size ( ) , sizeof ( UDPPacket ) ) ;
2019-08-09 08:42:01 +00:00
return ;
}
2019-03-13 13:22:27 +00:00
2021-08-01 17:54:42 +00:00
auto & udp_packet = * static_cast < UDPPacket const * > ( ipv4_packet . payload ( ) ) ;
2021-03-12 10:59:41 +00:00
dbgln_if ( UDP_DEBUG , " handle_udp: source={}:{}, destination={}:{}, length={} " ,
ipv4_packet . source ( ) , udp_packet . source_port ( ) ,
ipv4_packet . destination ( ) , udp_packet . destination_port ( ) ,
udp_packet . length ( ) ) ;
2019-03-13 13:22:27 +00:00
2019-03-14 11:43:18 +00:00
auto socket = UDPSocket : : from_port ( udp_packet . destination_port ( ) ) ;
2019-03-14 08:19:24 +00:00
if ( ! socket ) {
2021-04-26 22:42:15 +00:00
dbgln_if ( UDP_DEBUG , " handle_udp: No local UDP socket for {}:{} " , ipv4_packet . destination ( ) , udp_packet . destination_port ( ) ) ;
2019-03-14 08:19:24 +00:00
return ;
2019-03-13 13:22:27 +00:00
}
2019-03-13 15:23:22 +00:00
2021-02-23 19:42:32 +00:00
VERIFY ( socket - > type ( ) = = SOCK_DGRAM ) ;
VERIFY ( socket - > local_port ( ) = = udp_packet . destination_port ( ) ) ;
2021-05-04 11:42:47 +00:00
auto & destination = ipv4_packet . destination ( ) ;
2021-06-04 04:43:16 +00:00
if ( destination = = IPv4Address ( 255 , 255 , 255 , 255 ) | | NetworkingManagement : : the ( ) . from_ipv4_address ( destination ) | | socket - > multicast_memberships ( ) . contains_slow ( destination ) )
2021-05-11 17:47:40 +00:00
socket - > did_receive ( ipv4_packet . source ( ) , udp_packet . source_port ( ) , { & ipv4_packet , sizeof ( IPv4Packet ) + ipv4_packet . payload_size ( ) } , packet_timestamp ) ;
2019-03-13 13:22:27 +00:00
}
2019-03-13 16:17:07 +00:00
2021-05-12 07:14:37 +00:00
void send_delayed_tcp_ack ( RefPtr < TCPSocket > socket )
{
2021-08-29 11:10:55 +00:00
VERIFY ( socket - > mutex ( ) . is_locked ( ) ) ;
2021-05-12 07:14:37 +00:00
if ( ! socket - > should_delay_next_ack ( ) ) {
[[maybe_unused]] auto result = socket - > send_ack ( ) ;
return ;
}
delayed_ack_sockets - > set ( move ( socket ) ) ;
}
2021-05-13 05:45:14 +00:00
void flush_delayed_tcp_acks ( )
2021-05-12 07:14:37 +00:00
{
Vector < RefPtr < TCPSocket > , 32 > remaining_sockets ;
for ( auto & socket : * delayed_ack_sockets ) {
2021-08-29 11:10:55 +00:00
MutexLocker locker ( socket - > mutex ( ) ) ;
2021-05-13 05:45:14 +00:00
if ( socket - > should_delay_next_ack ( ) ) {
2022-01-03 11:20:39 +00:00
MUST ( remaining_sockets . try_append ( socket ) ) ;
2021-05-12 07:14:37 +00:00
continue ;
}
[[maybe_unused]] auto result = socket - > send_ack ( ) ;
}
if ( remaining_sockets . size ( ) ! = delayed_ack_sockets - > size ( ) ) {
delayed_ack_sockets - > clear ( ) ;
if ( remaining_sockets . size ( ) > 0 )
dbgln ( " flush_delayed_tcp_acks: {} sockets remaining " , remaining_sockets . size ( ) ) ;
for ( auto & & socket : remaining_sockets )
delayed_ack_sockets - > set ( move ( socket ) ) ;
}
}
2021-07-18 22:19:25 +00:00
void send_tcp_rst ( IPv4Packet const & ipv4_packet , TCPPacket const & tcp_packet , RefPtr < NetworkAdapter > adapter )
{
auto routing_decision = route_to ( ipv4_packet . source ( ) , ipv4_packet . destination ( ) , adapter ) ;
if ( routing_decision . is_zero ( ) )
return ;
auto ipv4_payload_offset = routing_decision . adapter - > ipv4_payload_offset ( ) ;
const size_t options_size = 0 ;
const size_t tcp_header_size = sizeof ( TCPPacket ) + options_size ;
const size_t buffer_size = ipv4_payload_offset + tcp_header_size ;
auto packet = routing_decision . adapter - > acquire_packet_buffer ( buffer_size ) ;
if ( ! packet )
return ;
routing_decision . adapter - > fill_in_ipv4_header ( * packet , ipv4_packet . destination ( ) ,
routing_decision . next_hop , ipv4_packet . source ( ) , IPv4Protocol : : TCP ,
2021-10-27 20:20:24 +00:00
buffer_size - ipv4_payload_offset , 0 , 64 ) ;
2021-08-03 02:16:43 +00:00
auto & rst_packet = * ( TCPPacket * ) ( packet - > buffer - > data ( ) + ipv4_payload_offset ) ;
rst_packet = { } ;
2021-07-18 22:19:25 +00:00
rst_packet . set_source_port ( tcp_packet . destination_port ( ) ) ;
rst_packet . set_destination_port ( tcp_packet . source_port ( ) ) ;
rst_packet . set_window_size ( 0 ) ;
rst_packet . set_sequence_number ( 0 ) ;
rst_packet . set_ack_number ( tcp_packet . sequence_number ( ) + 1 ) ;
rst_packet . set_data_offset ( tcp_header_size / sizeof ( u32 ) ) ;
rst_packet . set_flags ( TCPFlags : : RST | TCPFlags : : ACK ) ;
rst_packet . set_checksum ( TCPSocket : : compute_tcp_checksum ( ipv4_packet . source ( ) , ipv4_packet . destination ( ) , rst_packet , 0 ) ) ;
2021-08-01 12:11:49 +00:00
routing_decision . adapter - > send_packet ( packet - > bytes ( ) ) ;
2021-07-18 22:19:25 +00:00
routing_decision . adapter - > release_packet_buffer ( * packet ) ;
}
2021-08-01 17:54:42 +00:00
void handle_tcp ( IPv4Packet const & ipv4_packet , Time const & packet_timestamp )
2019-03-13 16:17:07 +00:00
{
2019-08-09 08:42:01 +00:00
if ( ipv4_packet . payload_size ( ) < sizeof ( TCPPacket ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: IPv4 payload is too small to be a TCP packet ({}, need {}) " , ipv4_packet . payload_size ( ) , sizeof ( TCPPacket ) ) ;
2019-03-13 16:17:07 +00:00
return ;
}
2021-08-01 17:54:42 +00:00
auto & tcp_packet = * static_cast < TCPPacket const * > ( ipv4_packet . payload ( ) ) ;
2019-08-09 08:42:01 +00:00
size_t minimum_tcp_header_size = 5 * sizeof ( u32 ) ;
size_t maximum_tcp_header_size = 15 * sizeof ( u32 ) ;
if ( tcp_packet . header_size ( ) < minimum_tcp_header_size | | tcp_packet . header_size ( ) > maximum_tcp_header_size ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: TCP packet header has invalid size {} " , tcp_packet . header_size ( ) ) ;
2019-08-09 08:42:01 +00:00
}
if ( ipv4_packet . payload_size ( ) < tcp_packet . header_size ( ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: IPv4 payload is smaller than TCP header claims ({}, supposedly {}) " , ipv4_packet . payload_size ( ) , tcp_packet . header_size ( ) ) ;
2019-08-09 08:42:01 +00:00
return ;
}
2019-03-14 00:42:29 +00:00
size_t payload_size = ipv4_packet . payload_size ( ) - tcp_packet . header_size ( ) ;
2021-03-12 10:59:41 +00:00
dbgln_if ( TCP_DEBUG , " handle_tcp: source={}:{}, destination={}:{}, seq_no={}, ack_no={}, flags={:#04x} ({}{}{}{}), window_size={}, payload_size={} " ,
2020-12-25 16:05:05 +00:00
ipv4_packet . source ( ) . to_string ( ) ,
tcp_packet . source_port ( ) ,
ipv4_packet . destination ( ) . to_string ( ) ,
tcp_packet . destination_port ( ) ,
tcp_packet . sequence_number ( ) ,
tcp_packet . ack_number ( ) ,
tcp_packet . flags ( ) ,
tcp_packet . has_syn ( ) ? " SYN " : " " ,
tcp_packet . has_ack ( ) ? " ACK " : " " ,
tcp_packet . has_fin ( ) ? " FIN " : " " ,
tcp_packet . has_rst ( ) ? " RST " : " " ,
tcp_packet . window_size ( ) ,
payload_size ) ;
2019-03-13 16:17:07 +00:00
2021-06-04 04:43:16 +00:00
auto adapter = NetworkingManagement : : the ( ) . from_ipv4_address ( ipv4_packet . destination ( ) ) ;
2019-08-09 08:42:01 +00:00
if ( ! adapter ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: this packet is not for me, it's for {} " , ipv4_packet . destination ( ) ) ;
2019-08-09 08:42:01 +00:00
return ;
}
2019-08-06 13:40:38 +00:00
IPv4SocketTuple tuple ( ipv4_packet . destination ( ) , tcp_packet . destination_port ( ) , ipv4_packet . source ( ) , tcp_packet . source_port ( ) ) ;
2021-03-12 10:59:41 +00:00
dbgln_if ( TCP_DEBUG , " handle_tcp: looking for socket; tuple={} " , tuple . to_string ( ) ) ;
2019-08-09 02:35:56 +00:00
2019-08-06 13:40:38 +00:00
auto socket = TCPSocket : : from_tuple ( tuple ) ;
2021-08-18 08:30:10 +00:00
if ( ! socket ) {
if ( ! tcp_packet . has_rst ( ) ) {
dbgln ( " handle_tcp: No TCP socket for tuple {}. Sending RST. " , tuple . to_string ( ) ) ;
send_tcp_rst ( ipv4_packet , tcp_packet , adapter ) ;
}
2019-03-14 08:19:24 +00:00
return ;
2019-03-13 16:17:07 +00:00
}
2021-08-29 11:10:55 +00:00
MutexLocker locker ( socket - > mutex ( ) ) ;
2020-10-21 18:51:02 +00:00
2021-02-23 19:42:32 +00:00
VERIFY ( socket - > type ( ) = = SOCK_STREAM ) ;
VERIFY ( socket - > local_port ( ) = = tcp_packet . destination_port ( ) ) ;
2019-03-13 22:14:30 +00:00
2021-03-12 10:59:41 +00:00
dbgln_if ( TCP_DEBUG , " handle_tcp: got socket {}; state={} " , socket - > tuple ( ) . to_string ( ) , TCPSocket : : to_string ( socket - > state ( ) ) ) ;
2019-08-09 02:35:56 +00:00
2019-09-08 07:38:08 +00:00
socket - > receive_tcp_packet ( tcp_packet , ipv4_packet . payload_size ( ) ) ;
2019-08-08 02:32:35 +00:00
2019-08-06 13:40:38 +00:00
switch ( socket - > state ( ) ) {
case TCPSocket : : State : : Closed :
2022-03-17 14:28:56 +00:00
dbgln ( " handle_tcp: unexpected flags in Closed state ({:x}) " , tcp_packet . flags ( ) ) ;
2019-08-08 02:29:34 +00:00
// TODO: we may want to send an RST here, maybe as a configurable option
2019-03-14 14:23:32 +00:00
return ;
2019-08-06 13:40:38 +00:00
case TCPSocket : : State : : TimeWait :
2022-03-17 14:28:56 +00:00
dbgln ( " handle_tcp: unexpected flags in TimeWait state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
case TCPSocket : : State : : Listen :
switch ( tcp_packet . flags ( ) ) {
2019-08-09 02:48:28 +00:00
case TCPFlags : : SYN : {
2021-03-12 10:59:41 +00:00
dbgln_if ( TCP_DEBUG , " handle_tcp: incoming connection " ) ;
2019-08-09 02:48:28 +00:00
auto & local_address = ipv4_packet . destination ( ) ;
auto & peer_address = ipv4_packet . source ( ) ;
2021-09-07 12:44:29 +00:00
auto client_or_error = socket - > try_create_client ( local_address , tcp_packet . destination_port ( ) , peer_address , tcp_packet . source_port ( ) ) ;
if ( client_or_error . is_error ( ) ) {
dmesgln ( " handle_tcp: couldn't create client socket: {} " , client_or_error . error ( ) ) ;
2019-08-09 02:48:28 +00:00
return ;
}
2021-09-07 12:44:29 +00:00
auto client = client_or_error . release_value ( ) ;
2021-08-29 11:10:55 +00:00
MutexLocker locker ( client - > mutex ( ) ) ;
2021-03-12 10:59:41 +00:00
dbgln_if ( TCP_DEBUG , " handle_tcp: created new client socket with tuple {} " , client - > tuple ( ) . to_string ( ) ) ;
2019-08-09 02:48:28 +00:00
client - > set_sequence_number ( 1000 ) ;
client - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
2020-12-20 23:09:48 +00:00
[[maybe_unused]] auto rc2 = client - > send_tcp_packet ( TCPFlags : : SYN | TCPFlags : : ACK ) ;
2019-08-09 02:48:28 +00:00
client - > set_state ( TCPSocket : : State : : SynReceived ) ;
2019-08-06 13:40:38 +00:00
return ;
2019-08-09 02:48:28 +00:00
}
2019-08-06 13:40:38 +00:00
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in Listen state ({:x}) " , tcp_packet . flags ( ) ) ;
2020-12-20 23:09:48 +00:00
// socket->send_tcp_packet(TCPFlags::RST);
2019-08-06 13:40:38 +00:00
return ;
}
case TCPSocket : : State : : SynSent :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : SYN :
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
2022-02-07 00:12:14 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : SYN | TCPFlags : : ACK ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : SynReceived ) ;
return ;
2019-08-10 03:18:18 +00:00
case TCPFlags : : ACK | TCPFlags : : SYN :
2019-08-06 13:40:38 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_ack ( true ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Established ) ;
2019-08-10 03:17:00 +00:00
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
2019-08-06 13:40:38 +00:00
socket - > set_connected ( true ) ;
return ;
2019-08-10 03:18:18 +00:00
case TCPFlags : : ACK | TCPFlags : : FIN :
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
2021-05-12 07:14:37 +00:00
send_delayed_tcp_ack ( socket ) ;
2019-08-10 03:18:18 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
socket - > set_error ( TCPSocket : : Error : : FINDuringConnect ) ;
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
return ;
case TCPFlags : : ACK | TCPFlags : : RST :
socket - > set_state ( TCPSocket : : State : : Closed ) ;
socket - > set_error ( TCPSocket : : Error : : RSTDuringConnect ) ;
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
return ;
2019-08-06 13:40:38 +00:00
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in SynSent state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
2019-08-10 03:18:18 +00:00
socket - > set_error ( TCPSocket : : Error : : UnexpectedFlagsDuringConnect ) ;
2019-08-10 03:17:00 +00:00
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
2019-08-06 13:40:38 +00:00
return ;
}
case TCPSocket : : State : : SynReceived :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : ACK :
2019-09-08 07:02:40 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size ) ;
2019-09-08 09:37:05 +00:00
switch ( socket - > direction ( ) ) {
case TCPSocket : : Direction : : Incoming :
if ( ! socket - > has_originator ( ) ) {
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: connection doesn't have an originating socket; maybe it went away? " ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-09-08 09:37:05 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
socket - > set_state ( TCPSocket : : State : : Established ) ;
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
socket - > release_to_originator ( ) ;
return ;
case TCPSocket : : Direction : : Outgoing :
socket - > set_state ( TCPSocket : : State : : Established ) ;
socket - > set_setup_state ( Socket : : SetupState : : Completed ) ;
2019-08-09 02:48:28 +00:00
socket - > set_connected ( true ) ;
2019-09-08 09:37:05 +00:00
return ;
default :
2021-03-12 10:59:41 +00:00
dbgln ( " handle_tcp: got ACK in SynReceived state but direction is invalid ({}) " , TCPSocket : : to_string ( socket - > direction ( ) ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-09-08 09:37:05 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
2021-10-07 17:51:24 +00:00
VERIFY_NOT_REACHED ( ) ;
2019-09-08 09:37:05 +00:00
2021-05-27 22:00:58 +00:00
case TCPFlags : : SYN :
dbgln ( " handle_tcp: ignoring SYN for partially established connection " ) ;
2019-08-06 13:40:38 +00:00
return ;
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in SynReceived state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : CloseWait :
switch ( tcp_packet . flags ( ) ) {
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in CloseWait state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : LastAck :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : ACK :
2019-09-08 07:02:40 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in LastAck state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : FinWait1 :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : ACK :
2019-09-08 07:02:40 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : FinWait2 ) ;
return ;
case TCPFlags : : FIN :
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
socket - > set_state ( TCPSocket : : State : : Closing ) ;
2022-02-06 16:31:32 +00:00
( 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 ) ;
2019-08-06 13:40:38 +00:00
return ;
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in FinWait1 state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : FinWait2 :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : FIN :
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
socket - > set_state ( TCPSocket : : State : : TimeWait ) ;
2022-02-06 16:31:32 +00:00
( void ) socket - > send_ack ( true ) ;
2019-08-06 13:40:38 +00:00
return ;
2020-02-08 14:52:32 +00:00
case TCPFlags : : ACK | TCPFlags : : RST :
2022-02-06 16:31:32 +00:00
// FIXME: Verify that this transition is legitimate.
2020-02-08 14:52:32 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
2019-08-06 13:40:38 +00:00
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in FinWait2 state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : Closing :
switch ( tcp_packet . flags ( ) ) {
case TCPFlags : : ACK :
2019-09-08 07:02:40 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : TimeWait ) ;
return ;
default :
2021-05-15 06:01:07 +00:00
dbgln ( " handle_tcp: unexpected flags in Closing state ({:x}) " , tcp_packet . flags ( ) ) ;
2021-08-14 13:15:11 +00:00
( void ) socket - > send_tcp_packet ( TCPFlags : : RST ) ;
2019-08-06 13:40:38 +00:00
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
case TCPSocket : : State : : Established :
2021-04-30 20:08:40 +00:00
if ( tcp_packet . has_rst ( ) ) {
socket - > set_state ( TCPSocket : : State : : Closed ) ;
return ;
}
2021-05-11 20:18:19 +00:00
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 ( ) ) ;
2021-05-12 06:13:53 +00:00
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 ) ;
2021-05-12 07:14:37 +00:00
[[maybe_unused]] auto result = socket - > send_ack ( true ) ;
2021-05-12 06:13:53 +00:00
}
2021-05-11 20:18:19 +00:00
return ;
}
2021-05-12 06:13:53 +00:00
socket - > set_duplicate_acks ( 0 ) ;
2019-08-06 13:40:38 +00:00
if ( tcp_packet . has_fin ( ) ) {
if ( payload_size ! = 0 )
2021-05-11 17:47:40 +00:00
socket - > did_receive ( ipv4_packet . source ( ) , tcp_packet . source_port ( ) , { & ipv4_packet , sizeof ( IPv4Packet ) + ipv4_packet . payload_size ( ) } , packet_timestamp ) ;
2019-08-06 13:40:38 +00:00
socket - > set_ack_number ( tcp_packet . sequence_number ( ) + payload_size + 1 ) ;
2021-05-12 07:14:37 +00:00
send_delayed_tcp_ack ( socket ) ;
2020-02-08 14:52:32 +00:00
socket - > set_state ( TCPSocket : : State : : CloseWait ) ;
2019-08-06 13:40:38 +00:00
socket - > set_connected ( false ) ;
return ;
}
2020-02-08 13:09:02 +00:00
if ( payload_size ) {
2021-05-11 20:18:19 +00:00
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 ( ) ) ;
2021-05-12 07:14:37 +00:00
send_delayed_tcp_ack ( socket ) ;
2021-05-11 20:18:19 +00:00
}
2019-11-04 13:03:14 +00:00
}
2019-08-06 13:40:38 +00:00
}
2019-03-13 16:17:07 +00:00
}
2020-02-16 00:27:42 +00:00
2021-05-13 08:49:10 +00:00
void retransmit_tcp_packets ( )
{
// We must keep the sockets alive until after we've unlocked the hash table
// in case retransmit_packets() realizes that it wants to close the socket.
NonnullRefPtrVector < TCPSocket , 16 > sockets ;
2022-04-01 17:58:27 +00:00
TCPSocket : : sockets_for_retransmit ( ) . for_each_shared ( [ & ] ( auto const & socket ) {
2022-02-03 14:28:33 +00:00
// We ignore allocation failures above the first 16 guaranteed socket slots, as
// we will just retransmit their packets the next time around
( void ) sockets . try_append ( socket ) ;
2021-07-18 10:14:43 +00:00
} ) ;
2021-05-13 08:49:10 +00:00
for ( auto & socket : sockets ) {
2021-08-29 11:10:55 +00:00
MutexLocker socket_locker ( socket . mutex ( ) ) ;
2021-05-13 08:49:10 +00:00
socket . retransmit_packets ( ) ;
}
}
2020-02-16 00:27:42 +00:00
}