From 416d470d07744592f186b65de7074f94edf39824 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 16 Sep 2020 12:25:06 -0400 Subject: Kernel: Plumb packet receive timestamp from NetworkAdapter to Socket::recvfrom Since the receiving socket isn't yet known at packet receive time, keep timestamps for all packets. This is useful for keeping statistics about in-kernel queue latencies in the future, and it can be used to implement SO_TIMESTAMP. --- Kernel/Net/IPv4Socket.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'Kernel/Net/IPv4Socket.cpp') diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index c64c036c4d..2ff4b60001 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -280,7 +280,7 @@ KResultOr IPv4Socket::receive_byte_buffered(FileDescription& description return nreceived; } -KResultOr IPv4Socket::receive_packet_buffered(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace addr, Userspace addr_length) +KResultOr IPv4Socket::receive_packet_buffered(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace addr, Userspace addr_length, timeval& packet_timestamp) { Locker locker(lock()); ReceivedPacket packet; @@ -330,6 +330,8 @@ KResultOr IPv4Socket::receive_packet_buffered(FileDescription& descripti ASSERT(packet.data.has_value()); auto& ipv4_packet = *(const IPv4Packet*)(packet.data.value().data()); + packet_timestamp = packet.timestamp; + if (addr) { #ifdef IPV4_SOCKET_DEBUG dbg() << "Incoming packet is from: " << packet.peer_address << ":" << packet.peer_port; @@ -359,7 +361,7 @@ KResultOr IPv4Socket::receive_packet_buffered(FileDescription& descripti return protocol_receive(packet.data.value(), buffer, buffer_length, flags); } -KResultOr IPv4Socket::recvfrom(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace user_addr, Userspace user_addr_length) +KResultOr IPv4Socket::recvfrom(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace user_addr, Userspace user_addr_length, timeval& packet_timestamp) { if (user_addr_length) { socklen_t addr_length; @@ -377,14 +379,14 @@ KResultOr IPv4Socket::recvfrom(FileDescription& description, UserOrKerne if (buffer_mode() == BufferMode::Bytes) nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length); else - nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length); + nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length, packet_timestamp); if (!nreceived.is_error()) Thread::current()->did_ipv4_socket_read(nreceived.value()); return nreceived; } -bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, KBuffer&& packet) +bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, KBuffer&& packet, const timeval& packet_timestamp) { LOCKER(lock()); @@ -413,7 +415,7 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, dbg() << "IPv4Socket(" << this << "): did_receive refusing packet since queue is full."; return false; } - m_receive_queue.append({ source_address, source_port, move(packet) }); + m_receive_queue.append({ source_address, source_port, packet_timestamp, move(packet) }); m_can_read = true; } m_bytes_received += packet_size; -- cgit v1.2.3