mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 04:52:45 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									7272127927
								
							
						
					
					
						commit
						ffc6b714b0
					
				
					 2 changed files with 14 additions and 0 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -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 }; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gunnar Beutner
						Gunnar Beutner