diff options
author | Andreas Kling <kling@serenityos.org> | 2020-02-08 13:09:37 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-08 13:09:37 +0100 |
commit | 48f13f2a813b90426662854c4eb993ebee223b0a (patch) | |
tree | bf57380eed54c6a57f011eeb1e6f17d558aed0d9 | |
parent | 00d8ec3ead162c25ed1631734632b16475359dfd (diff) | |
download | serenity-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.cpp | 73 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 3 |
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; |