Skip to content

Commit

Permalink
Kernel: Add MSG_PEEK support for the IPv4Socket
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sw1tchbl4d3r authored and awesomekling committed Apr 29, 2021
1 parent 2d098c8 commit e6401d6
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
25 changes: 20 additions & 5 deletions Kernel/Net/IPv4Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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());
Expand All @@ -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: {}",
Expand Down Expand Up @@ -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: {}",
Expand Down
1 change: 1 addition & 0 deletions Kernel/UnixTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibC/sys/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit e6401d6

Please sign in to comment.