mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 02:42:44 +00:00 
			
		
		
		
	Kernel: Coalesce TCP ACKs
Previously we'd send a TCP ACK for each TCP packet we received. This changes NetworkTask so that we send fewer TCP ACKs.
This commit is contained in:
		
							parent
							
								
									ffc6b714b0
								
							
						
					
					
						commit
						af59f64bc0
					
				
					 3 changed files with 81 additions and 8 deletions
				
			
		|  | @ -167,6 +167,13 @@ KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_ | |||
|     return data_length; | ||||
| } | ||||
| 
 | ||||
| KResult TCPSocket::send_ack(bool allow_duplicate) | ||||
| { | ||||
|     if (!allow_duplicate && m_last_ack_number_sent == m_ack_number) | ||||
|         return KSuccess; | ||||
|     return send_tcp_packet(TCPFlags::ACK); | ||||
| } | ||||
| 
 | ||||
| KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, size_t payload_size) | ||||
| { | ||||
|     const bool has_mss_option = flags == TCPFlags::SYN; | ||||
|  | @ -183,8 +190,11 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, | |||
|     tcp_packet.set_data_offset(header_size / sizeof(u32)); | ||||
|     tcp_packet.set_flags(flags); | ||||
| 
 | ||||
|     if (flags & TCPFlags::ACK) | ||||
|     if (flags & TCPFlags::ACK) { | ||||
|         m_last_ack_number_sent = m_ack_number; | ||||
|         m_last_ack_sent_time = kgettimeofday(); | ||||
|         tcp_packet.set_ack_number(m_ack_number); | ||||
|     } | ||||
| 
 | ||||
|     if (payload && !payload->read(tcp_packet.payload(), payload_size)) | ||||
|         return EFAULT; | ||||
|  | @ -308,6 +318,22 @@ void TCPSocket::receive_tcp_packet(const TCPPacket& packet, u16 size) | |||
|     m_bytes_in += packet.header_size() + size; | ||||
| } | ||||
| 
 | ||||
| bool TCPSocket::should_delay_next_ack() const | ||||
| { | ||||
|     // FIXME: We don't know the MSS here so make a reasonable guess.
 | ||||
|     const size_t mss = 1500; | ||||
| 
 | ||||
|     // RFC 1122 says we should send an ACK for every two full-sized segments.
 | ||||
|     if (m_ack_number >= m_last_ack_number_sent + 2 * mss) | ||||
|         return false; | ||||
| 
 | ||||
|     // RFC 1122 says we should not delay ACKs for more than 500 milliseconds.
 | ||||
|     if (kgettimeofday() >= m_last_ack_sent_time + Time::from_milliseconds(500)) | ||||
|         return false; | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| NetworkOrdered<u16> TCPSocket::compute_tcp_checksum(const IPv4Address& source, const IPv4Address& destination, const TCPPacket& packet, u16 payload_size) | ||||
| { | ||||
|     struct [[gnu::packed]] PseudoHeader { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gunnar Beutner
						Gunnar Beutner