summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin <sw1tchbl4d3@sw1tchbl4d3.com>2021-04-28 23:22:55 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-29 08:09:53 +0200
commite6401d65bdcf44d9f23e6fcc67875b46aaf3acfb (patch)
tree974e43fba3dbec178fc98c34f49ebcaada5f1fec
parent2d098c88dc64cbf58e3eb09a39fb917e78360685 (diff)
downloadserenity-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.cpp25
-rw-r--r--Kernel/UnixTypes.h1
-rw-r--r--Userland/Libraries/LibC/sys/socket.h1
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;