summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-08 13:09:37 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-08 13:09:37 +0100
commit48f13f2a813b90426662854c4eb993ebee223b0a (patch)
treebf57380eed54c6a57f011eeb1e6f17d558aed0d9
parent00d8ec3ead162c25ed1631734632b16475359dfd (diff)
downloadserenity-48f13f2a813b90426662854c4eb993ebee223b0a.zip
IPv4: Split IPv4Socket::recvfrom() into packet/byte buffered functions
This code was really hard to follow since it handles two separate modes of buffering the data.
-rw-r--r--Kernel/Net/IPv4Socket.cpp73
-rw-r--r--Kernel/Net/IPv4Socket.h3
2 files changed, 44 insertions, 32 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp
index 8ae6f9936c..b19aba3b8f 100644
--- a/Kernel/Net/IPv4Socket.cpp
+++ b/Kernel/Net/IPv4Socket.cpp
@@ -234,45 +234,37 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt
return nsent;
}
-ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
+ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*)
{
- if (addr_length && *addr_length < sizeof(sockaddr_in))
- return -EINVAL;
-
-#ifdef IPV4_SOCKET_DEBUG
- kprintf("recvfrom: type=%d, local_port=%u\n", type(), local_port());
-#endif
-
- if (buffer_mode() == BufferMode::Bytes) {
- if (m_receive_buffer.is_empty()) {
- if (protocol_is_disconnected()) {
- return 0;
- }
- if (!description.is_blocking()) {
- return -EAGAIN;
- }
+ if (m_receive_buffer.is_empty()) {
+ if (protocol_is_disconnected())
+ return 0;
+ if (!description.is_blocking())
+ return -EAGAIN;
- auto res = current->block<Thread::ReadBlocker>(description);
+ auto res = current->block<Thread::ReadBlocker>(description);
- LOCKER(lock());
- if (!m_can_read) {
- if (res != Thread::BlockResult::WokeNormally)
- return -EINTR;
+ LOCKER(lock());
+ if (!m_can_read) {
+ if (res != Thread::BlockResult::WokeNormally)
+ return -EINTR;
- // Unblocked due to timeout.
- return -EAGAIN;
- }
+ // Unblocked due to timeout.
+ return -EAGAIN;
}
+ }
- ASSERT(!m_receive_buffer.is_empty());
- int nreceived = m_receive_buffer.read((u8*)buffer, buffer_length);
- if (nreceived > 0)
- current->did_ipv4_socket_read((size_t)nreceived);
+ ASSERT(!m_receive_buffer.is_empty());
+ int nreceived = m_receive_buffer.read((u8*)buffer, buffer_length);
+ if (nreceived > 0)
+ current->did_ipv4_socket_read((size_t)nreceived);
- m_can_read = !m_receive_buffer.is_empty();
- return nreceived;
- }
+ m_can_read = !m_receive_buffer.is_empty();
+ return nreceived;
+}
+ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
+{
ReceivedPacket packet;
{
LOCKER(lock());
@@ -338,7 +330,24 @@ ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t
return ipv4_packet.payload_size();
}
- int nreceived = protocol_receive(packet.data.value(), buffer, buffer_length, flags);
+ return protocol_receive(packet.data.value(), buffer, buffer_length, flags);
+}
+
+ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
+{
+ if (addr_length && *addr_length < sizeof(sockaddr_in))
+ return -EINVAL;
+
+#ifdef IPV4_SOCKET_DEBUG
+ kprintf("recvfrom: type=%d, local_port=%u\n", type(), local_port());
+#endif
+
+ ssize_t nreceived = 0;
+ if (buffer_mode() == BufferMode::Bytes)
+ nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, addr, addr_length);
+ else
+ nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, addr, addr_length);
+
if (nreceived > 0)
current->did_ipv4_socket_read(nreceived);
return nreceived;
diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h
index fbdfa1b375..f00cc84cee 100644
--- a/Kernel/Net/IPv4Socket.h
+++ b/Kernel/Net/IPv4Socket.h
@@ -105,6 +105,9 @@ protected:
private:
virtual bool is_ipv4() const override { return true; }
+ ssize_t receive_byte_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
+ ssize_t receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
+
IPv4Address m_local_address;
IPv4Address m_peer_address;