diff options
author | Andreas Kling <kling@serenityos.org> | 2021-09-07 15:36:39 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-07 15:36:39 +0200 |
commit | b300f9aa2fd11796e63b5029008b33a1ae735928 (patch) | |
tree | 31d96f52a7733dc7de131eea9b096c58a411523f /Kernel/Net | |
parent | 250b52d6e5ef4b57048ef7f52a02ebb2fb87780b (diff) | |
download | serenity-b300f9aa2fd11796e63b5029008b33a1ae735928.zip |
Kernel: Convert KBuffer::copy() => KBuffer::try_copy()
This was a weird KBuffer API that assumed failure was impossible.
This patch converts it to a modern KResultOr<NonnullOwnPtr<KBuffer>> API
and updates the two clients to the new style.
Diffstat (limited to 'Kernel/Net')
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 52 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 2 |
2 files changed, 32 insertions, 22 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index efec7e4ae5..bf155ed6f1 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -284,7 +284,8 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descrip KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Time& packet_timestamp) { MutexLocker locker(mutex()); - ReceivedPacket packet; + ReceivedPacket taken_packet; + ReceivedPacket* packet { nullptr }; { if (m_receive_queue.is_empty()) { // FIXME: Shouldn't this return ENOTCONN instead of EOF? @@ -296,20 +297,22 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr } if (!m_receive_queue.is_empty()) { - if (flags & MSG_PEEK) - packet = m_receive_queue.first(); - else - packet = m_receive_queue.take_first(); + if (flags & MSG_PEEK) { + packet = &m_receive_queue.first(); + } else { + taken_packet = m_receive_queue.take_first(); + packet = &taken_packet; + } set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}", this, - packet.data.value().size(), + packet->data->size(), m_receive_queue.size()); } } - if (!packet.data.has_value()) { + if (!packet->data) { if (protocol_is_disconnected()) { dbgln("IPv4Socket({}) is protocol-disconnected, returning 0 in recvfrom!", this); return 0; @@ -330,28 +333,30 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr VERIFY(m_can_read); VERIFY(!m_receive_queue.is_empty()); - if (flags & MSG_PEEK) - packet = m_receive_queue.first(); - else - packet = m_receive_queue.take_first(); + if (flags & MSG_PEEK) { + packet = &m_receive_queue.first(); + } else { + taken_packet = m_receive_queue.take_first(); + packet = &taken_packet; + } set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}", this, - packet.data.value().size(), + packet->data->size(), m_receive_queue.size()); } - VERIFY(packet.data.has_value()); + VERIFY(packet->data); - packet_timestamp = packet.timestamp; + packet_timestamp = packet->timestamp; if (addr) { - dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet.peer_address, packet.peer_port); + dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet->peer_address, packet->peer_port); sockaddr_in out_addr {}; - memcpy(&out_addr.sin_addr, &packet.peer_address, sizeof(IPv4Address)); - out_addr.sin_port = htons(packet.peer_port); + memcpy(&out_addr.sin_addr, &packet->peer_address, sizeof(IPv4Address)); + out_addr.sin_port = htons(packet->peer_port); out_addr.sin_family = AF_INET; Userspace<sockaddr_in*> dest_addr = addr.ptr(); SOCKET_TRY(copy_to_user(dest_addr, &out_addr)); @@ -362,12 +367,12 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr } if (type() == SOCK_RAW) { - size_t bytes_written = min(packet.data.value().size(), buffer_length); - SOCKET_TRY(buffer.write(packet.data.value().data(), bytes_written)); + size_t bytes_written = min(packet->data->size(), buffer_length); + SOCKET_TRY(buffer.write(packet->data->data(), bytes_written)); return bytes_written; } - return protocol_receive(ReadonlyBytes { packet.data.value().data(), packet.data.value().size() }, buffer, buffer_length, flags); + return protocol_receive(ReadonlyBytes { packet->data->data(), packet->data->size() }, buffer, buffer_length, flags); } KResultOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Time& packet_timestamp) @@ -421,7 +426,12 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this); return false; } - m_receive_queue.append({ source_address, source_port, packet_timestamp, KBuffer::copy(packet.data(), packet.size()) }); + auto data_or_error = KBuffer::try_copy(packet.data(), packet.size()); + if (data_or_error.is_error()) { + dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet."); + return false; + } + m_receive_queue.append({ source_address, source_port, packet_timestamp, data_or_error.release_value() }); set_can_read(true); } m_bytes_received += packet_size; diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index 3ec3521acc..d416305601 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -110,7 +110,7 @@ private: IPv4Address peer_address; u16 peer_port; Time timestamp; - Optional<KBuffer> data; + OwnPtr<KBuffer> data; }; SinglyLinkedListWithCount<ReceivedPacket> m_receive_queue; |