diff options
author | Justin <sw1tchbl4d3@sw1tchbl4d3.com> | 2021-04-28 23:22:55 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-29 08:09:53 +0200 |
commit | e6401d65bdcf44d9f23e6fcc67875b46aaf3acfb (patch) | |
tree | 974e43fba3dbec178fc98c34f49ebcaada5f1fec | |
parent | 2d098c88dc64cbf58e3eb09a39fb917e78360685 (diff) | |
download | serenity-e6401d65bdcf44d9f23e6fcc67875b46aaf3acfb.zip |
Kernel: Add MSG_PEEK support for the IPv4Socket
This commit will add MSG_PEEK support, which allows a package to be
seen without taking it from the buffer, so that a subsequent recv()
without the MSG_PEEK flag can pick it up.
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 25 | ||||
-rw-r--r-- | Kernel/UnixTypes.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibC/sys/socket.h | 1 |
3 files changed, 22 insertions, 5 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index d202f7e1f6..0ffd786e48 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -217,7 +217,7 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer& return nsent_or_error; } -KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int, Userspace<sockaddr*>, Userspace<socklen_t*>) +KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>) { Locker locker(lock()); if (m_receive_buffer.is_empty()) { @@ -241,8 +241,14 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description } VERIFY(!m_receive_buffer.is_empty()); - int nreceived = m_receive_buffer.read(buffer, buffer_length); - if (nreceived > 0) + + int nreceived; + if (flags & MSG_PEEK) + nreceived = m_receive_buffer.peek(buffer, buffer_length); + else + nreceived = m_receive_buffer.read(buffer, buffer_length); + + if (nreceived > 0 && !(flags & MSG_PEEK)) Thread::current()->did_ipv4_socket_read((size_t)nreceived); set_can_read(!m_receive_buffer.is_empty()); @@ -264,7 +270,11 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti } if (!m_receive_queue.is_empty()) { - packet = m_receive_queue.take_first(); + if (flags & MSG_PEEK) + packet = m_receive_queue.first(); + else + packet = m_receive_queue.take_first(); + set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}", @@ -293,7 +303,12 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti } VERIFY(m_can_read); VERIFY(!m_receive_queue.is_empty()); - packet = m_receive_queue.take_first(); + + if (flags & MSG_PEEK) + packet = m_receive_queue.first(); + else + packet = m_receive_queue.take_first(); + set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}", diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h index 27a01e128f..b220b41343 100644 --- a/Kernel/UnixTypes.h +++ b/Kernel/UnixTypes.h @@ -496,6 +496,7 @@ struct pollfd { #define MSG_TRUNC 0x1 #define MSG_CTRUNC 0x2 +#define MSG_PEEK 0x4 #define MSG_DONTWAIT 0x40 #define SOL_SOCKET 1 diff --git a/Userland/Libraries/LibC/sys/socket.h b/Userland/Libraries/LibC/sys/socket.h index 8e34091063..44b673546d 100644 --- a/Userland/Libraries/LibC/sys/socket.h +++ b/Userland/Libraries/LibC/sys/socket.h @@ -46,6 +46,7 @@ __BEGIN_DECLS #define MSG_TRUNC 0x1 #define MSG_CTRUNC 0x2 +#define MSG_PEEK 0x4 #define MSG_DONTWAIT 0x40 typedef uint16_t sa_family_t; |