diff options
Diffstat (limited to 'Kernel/Net')
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 54 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 55 | ||||
-rw-r--r-- | Kernel/Net/Socket.cpp | 10 | ||||
-rw-r--r-- | Kernel/Net/Socket.h | 9 | ||||
-rw-r--r-- | Kernel/Net/TCPSocket.cpp | 26 | ||||
-rw-r--r-- | Kernel/Net/UDPSocket.cpp | 12 |
6 files changed, 88 insertions, 78 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 4ccabe7022..35ee2f9646 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -108,20 +108,20 @@ KResult IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t addr { VERIFY(setup_state() == SetupState::Unstarted); if (address_size != sizeof(sockaddr_in)) - return EINVAL; + return set_so_error(EINVAL); sockaddr_in address; if (!copy_from_user(&address, user_address, sizeof(sockaddr_in))) - return EFAULT; + return set_so_error(EFAULT); if (address.sin_family != AF_INET) - return EINVAL; + return set_so_error(EINVAL); auto requested_local_port = ntohs(address.sin_port); if (!Process::current()->is_superuser()) { if (requested_local_port > 0 && requested_local_port < 1024) { dbgln("UID {} attempted to bind {} to port {}", Process::current()->uid(), class_name(), requested_local_port); - return EACCES; + return set_so_error(EACCES); } } @@ -152,19 +152,19 @@ KResult IPv4Socket::listen(size_t backlog) KResult IPv4Socket::connect(FileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock should_block) { if (address_size != sizeof(sockaddr_in)) - return EINVAL; + return set_so_error(EINVAL); u16 sa_family_copy; auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr()); if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))) - return EFAULT; + return set_so_error(EFAULT); if (sa_family_copy != AF_INET) - return EINVAL; + return set_so_error(EINVAL); if (m_role == Role::Connected) - return EISCONN; + return set_so_error(EISCONN); sockaddr_in safe_address; if (!copy_from_user(&safe_address, (const sockaddr_in*)user_address, sizeof(sockaddr_in))) - return EFAULT; + return set_so_error(EFAULT); m_peer_address = IPv4Address((const u8*)&safe_address.sin_addr.s_addr); if (m_peer_address == IPv4Address { 0, 0, 0, 0 }) @@ -205,16 +205,16 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer& MutexLocker locker(lock()); if (addr && addr_length != sizeof(sockaddr_in)) - return EINVAL; + return set_so_error(EINVAL); if (addr) { sockaddr_in ia; if (!copy_from_user(&ia, Userspace<const sockaddr_in*>(addr.ptr()))) - return EFAULT; + return set_so_error(EFAULT); if (ia.sin_family != AF_INET) { dmesgln("sendto: Bad address family: {} is not AF_INET", ia.sin_family); - return EAFNOSUPPORT; + return set_so_error(EAFNOSUPPORT); } m_peer_address = IPv4Address((const u8*)&ia.sin_addr.s_addr); @@ -222,11 +222,11 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer& } if (!is_connected() && m_peer_address.is_zero()) - return EPIPE; + return set_so_error(EPIPE); auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface()); if (routing_decision.is_zero()) - return EHOSTUNREACH; + return set_so_error(EHOSTUNREACH); if (m_local_address.to_u32() == 0) m_local_address = routing_decision.adapter->ipv4_address(); @@ -241,12 +241,12 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer& data_length = min(data_length, routing_decision.adapter->mtu() - ipv4_payload_offset); auto packet = routing_decision.adapter->acquire_packet_buffer(ipv4_payload_offset + data_length); if (!packet) - return ENOMEM; + return set_so_error(ENOMEM); routing_decision.adapter->fill_in_ipv4_header(*packet, local_address(), routing_decision.next_hop, m_peer_address, (IPv4Protocol)protocol(), data_length, m_ttl); if (!data.read(packet->buffer->data() + ipv4_payload_offset, data_length)) { routing_decision.adapter->release_packet_buffer(*packet); - return EFAULT; + return set_so_error(EFAULT); } routing_decision.adapter->send_packet(packet->bytes()); routing_decision.adapter->release_packet_buffer(*packet); @@ -266,7 +266,7 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description if (protocol_is_disconnected()) return 0; if (!description.is_blocking()) - return EAGAIN; + return set_so_error(EAGAIN); locker.unlock(); auto unblocked_flags = BlockFlags::None; @@ -275,10 +275,10 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description if (!has_flag(unblocked_flags, BlockFlags::Read)) { if (res.was_interrupted()) - return EINTR; + return set_so_error(EINTR); // Unblocked due to timeout. - return EAGAIN; + return set_so_error(EAGAIN); } } @@ -306,7 +306,7 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti if (protocol_is_disconnected()) return 0; if (!description.is_blocking()) - return EAGAIN; + return set_so_error(EAGAIN); } if (!m_receive_queue.is_empty()) { @@ -336,10 +336,10 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti if (!has_flag(unblocked_flags, BlockFlags::Read)) { if (res.was_interrupted()) - return EINTR; + return set_so_error(EINTR); // Unblocked due to timeout. - return EAGAIN; + return set_so_error(EAGAIN); } VERIFY(m_can_read); VERIFY(!m_receive_queue.is_empty()); @@ -369,18 +369,18 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti out_addr.sin_family = AF_INET; Userspace<sockaddr_in*> dest_addr = addr.ptr(); if (!copy_to_user(dest_addr, &out_addr)) - return EFAULT; + return set_so_error(EFAULT); socklen_t out_length = sizeof(sockaddr_in); VERIFY(addr_length); if (!copy_to_user(addr_length, &out_length)) - return EFAULT; + return set_so_error(EFAULT); } if (type() == SOCK_RAW) { size_t bytes_written = min(packet.data.value().size(), buffer_length); if (!buffer.write(packet.data.value().data(), bytes_written)) - return EFAULT; + return set_so_error(EFAULT); return bytes_written; } @@ -392,9 +392,9 @@ KResultOr<size_t> IPv4Socket::recvfrom(FileDescription& description, UserOrKerne if (user_addr_length) { socklen_t addr_length; if (!copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr())) - return EFAULT; + return set_so_error(EFAULT); if (addr_length < sizeof(sockaddr_in)) - return EINVAL; + return set_so_error(EINVAL); } dbgln_if(IPV4_SOCKET_DEBUG, "recvfrom: type={}, local_port={}", type(), local_port()); diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 5e8dc330f5..8041c8d459 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -122,14 +122,14 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add { VERIFY(setup_state() == SetupState::Unstarted); if (address_size != sizeof(sockaddr_un)) - return EINVAL; + return set_so_error(EINVAL); sockaddr_un address; if (!copy_from_user(&address, user_address, sizeof(sockaddr_un))) - return EFAULT; + return set_so_error(EFAULT); if (address.sun_family != AF_LOCAL) - return EINVAL; + return set_so_error(EINVAL); auto path = String(address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path))); @@ -140,7 +140,7 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add auto result = VirtualFileSystem::the().open(path, O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current()->current_directory(), owner); if (result.is_error()) { if (result.error() == -EEXIST) - return EADDRINUSE; + return set_so_error(EADDRINUSE); return result.error(); } @@ -148,7 +148,7 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add VERIFY(file->inode()); if (!file->inode()->bind_socket(*this)) - return EADDRINUSE; + return set_so_error(EADDRINUSE); m_file = move(file); @@ -161,33 +161,33 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka { VERIFY(!m_bound); if (address_size != sizeof(sockaddr_un)) - return EINVAL; + return set_so_error(EINVAL); u16 sa_family_copy; auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr()); if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))) - return EFAULT; + return set_so_error(EFAULT); if (sa_family_copy != AF_LOCAL) - return EINVAL; + return set_so_error(EINVAL); if (is_connected()) - return EISCONN; + return set_so_error(EISCONN); const auto& local_address = *reinterpret_cast<const sockaddr_un*>(user_address); char safe_address[sizeof(local_address.sun_path) + 1] = { 0 }; if (!copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1)) - return EFAULT; + return set_so_error(EFAULT); safe_address[sizeof(safe_address) - 1] = '\0'; dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({})", this, safe_address); auto description_or_error = VirtualFileSystem::the().open(safe_address, O_RDWR, 0, Process::current()->current_directory()); if (description_or_error.is_error()) - return ECONNREFUSED; + return set_so_error(ECONNREFUSED); m_file = move(description_or_error.value()); VERIFY(m_file->inode()); if (!m_file->inode()->socket()) - return ECONNREFUSED; + return set_so_error(ECONNREFUSED); m_address.sun_family = sa_family_copy; memcpy(m_address.sun_path, safe_address, sizeof(m_address.sun_path)); @@ -210,14 +210,14 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None; if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted()) { set_connect_side_role(Role::None); - return EINTR; + return set_so_error(EINTR); } dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({}) status is {}", this, safe_address, to_string(setup_state())); if (!has_flag(unblock_flags, Thread::FileDescriptionBlocker::BlockFlags::Connect)) { set_connect_side_role(Role::None); - return ECONNREFUSED; + return set_so_error(ECONNREFUSED); } set_connect_side_role(Role::Connected); return KSuccess; @@ -227,7 +227,7 @@ KResult LocalSocket::listen(size_t backlog) { MutexLocker locker(lock()); if (type() != SOCK_STREAM) - return EOPNOTSUPP; + return set_so_error(EOPNOTSUPP); set_backlog(backlog); auto previous_role = m_role; m_role = Role::Listener; @@ -300,10 +300,10 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const UserOrKernelBuffer& data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t) { if (!has_attached_peer(description)) - return EPIPE; + return set_so_error(EPIPE); auto* socket_buffer = send_buffer_for(description); if (!socket_buffer) - return EINVAL; + return set_so_error(EINVAL); auto nwritten_or_error = socket_buffer->write(data, data_size); if (!nwritten_or_error.is_error() && nwritten_or_error.value() > 0) Thread::current()->did_unix_socket_write(nwritten_or_error.value()); @@ -334,17 +334,18 @@ KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKern { auto* socket_buffer = receive_buffer_for(description); if (!socket_buffer) - return EINVAL; + return set_so_error(EINVAL); if (!description.is_blocking()) { if (socket_buffer->is_empty()) { if (!has_attached_peer(description)) return 0; - return EAGAIN; + return set_so_error(EAGAIN); } } else if (!can_read(description, 0)) { auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None; - if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted()) - return EINTR; + if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted()) { + return set_so_error(EINTR); + } } if (!has_attached_peer(description) && socket_buffer->is_empty()) return 0; @@ -447,7 +448,7 @@ KResult LocalSocket::chown(FileDescription&, uid_t uid, gid_t gid) auto current_process = Process::current(); if (!current_process->is_superuser() && (current_process->euid() != uid || !current_process->in_group(gid))) - return EPERM; + return set_so_error(EPERM); m_prebind_uid = uid; m_prebind_gid = gid; @@ -479,13 +480,13 @@ KResult LocalSocket::sendfd(const FileDescription& socket_description, FileDescr MutexLocker locker(lock()); auto role = this->role(socket_description); if (role != Role::Connected && role != Role::Accepted) - return EINVAL; + return set_so_error(EINVAL); auto& queue = sendfd_queue_for(socket_description); // FIXME: Figure out how we should limit this properly. if (queue.size() > 128) - return EBUSY; + return set_so_error(EBUSY); if (!queue.try_append(move(passing_description))) - return ENOMEM; + return set_so_error(ENOMEM); return KSuccess; } @@ -494,11 +495,11 @@ KResultOr<NonnullRefPtr<FileDescription>> LocalSocket::recvfd(const FileDescript MutexLocker locker(lock()); auto role = this->role(socket_description); if (role != Role::Connected && role != Role::Accepted) - return EINVAL; + return set_so_error(EINVAL); auto& queue = recvfd_queue_for(socket_description); if (queue.is_empty()) { // FIXME: Figure out the perfect error code for this. - return EAGAIN; + return set_so_error(EAGAIN); } return queue.take_first(); } diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp index e7bc17a581..d7a69fa456 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -71,9 +71,9 @@ KResult Socket::queue_connection_from(NonnullRefPtr<Socket> peer) dbgln_if(SOCKET_DEBUG, "Socket({}) queueing connection", this); MutexLocker locker(m_lock); if (m_pending.size() >= m_backlog) - return ECONNREFUSED; + return set_so_error(ECONNREFUSED); if (!m_pending.try_append(peer)) - return ENOMEM; + return set_so_error(ENOMEM); evaluate_block_conditions(); return KSuccess; } @@ -235,7 +235,7 @@ KResultOr<size_t> Socket::read(FileDescription& description, u64, UserOrKernelBu KResultOr<size_t> Socket::write(FileDescription& description, u64, const UserOrKernelBuffer& data, size_t size) { if (is_shut_down_for_writing()) - return EPIPE; + return set_so_error(EPIPE); return sendto(description, data, size, 0, {}, 0); } @@ -243,9 +243,9 @@ KResult Socket::shutdown(int how) { MutexLocker locker(lock()); if (type() == SOCK_STREAM && !is_connected()) - return ENOTCONN; + return set_so_error(ENOTCONN); if (m_role == Role::Listener) - return ENOTCONN; + return set_so_error(ENOTCONN); if (!m_shut_down_for_writing && (how & SHUT_WR)) shut_down_for_writing(); if (!m_shut_down_for_reading && (how & SHUT_RD)) diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index 939ee41fb8..d175001a35 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -130,6 +130,13 @@ protected: Role m_role { Role::None }; + KResult so_error() const { return m_so_error; } + KResult set_so_error(KResult error) + { + m_so_error = error; + return error; + } + protected: ucred m_origin { 0, 0, 0 }; ucred m_acceptor { 0, 0, 0 }; @@ -154,6 +161,8 @@ private: Time m_send_timeout {}; int m_timestamp { 0 }; + KResult m_so_error { KSuccess }; + NonnullRefPtrVector<Socket> m_pending; }; diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index c03e631509..c1ea1abd8c 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -171,7 +171,7 @@ KResultOr<size_t> TCPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use dbgln_if(TCP_SOCKET_DEBUG, "payload_size {}, will it fit in {}?", payload_size, buffer_size); VERIFY(buffer_size >= payload_size); if (!buffer.write(tcp_packet.payload(), payload_size)) - return EFAULT; + return set_so_error(EFAULT); return payload_size; } @@ -179,7 +179,7 @@ KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_ { RoutingDecision routing_decision = route_to(peer_address(), local_address(), bound_interface()); if (routing_decision.is_zero()) - return EHOSTUNREACH; + return set_so_error(EHOSTUNREACH); size_t mss = routing_decision.adapter->mtu() - sizeof(IPv4Packet) - sizeof(TCPPacket); data_length = min(data_length, mss); int err = send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, &data, data_length, &routing_decision); @@ -199,7 +199,7 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, { RoutingDecision routing_decision = user_routing_decision ? *user_routing_decision : route_to(peer_address(), local_address(), bound_interface()); if (routing_decision.is_zero()) - return EHOSTUNREACH; + return set_so_error(EHOSTUNREACH); auto ipv4_payload_offset = routing_decision.adapter->ipv4_payload_offset(); @@ -209,7 +209,7 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, const size_t buffer_size = ipv4_payload_offset + tcp_header_size + payload_size; auto packet = routing_decision.adapter->acquire_packet_buffer(buffer_size); if (!packet) - return ENOMEM; + return set_so_error(ENOMEM); routing_decision.adapter->fill_in_ipv4_header(*packet, local_address(), routing_decision.next_hop, peer_address(), IPv4Protocol::TCP, buffer_size - ipv4_payload_offset, ttl()); @@ -231,7 +231,7 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, if (payload && !payload->read(tcp_packet.payload(), payload_size)) { routing_decision.adapter->release_packet_buffer(*packet); - return EFAULT; + return set_so_error(EFAULT); } if (flags & TCPFlags::SYN) { @@ -370,7 +370,7 @@ KResult TCPSocket::protocol_bind() if (has_specific_local_address() && !m_adapter) { m_adapter = NetworkingManagement::the().from_ipv4_address(local_address()); if (!m_adapter) - return EADDRNOTAVAIL; + return set_so_error(EADDRNOTAVAIL); } return KSuccess; @@ -386,7 +386,7 @@ KResult TCPSocket::protocol_listen(bool did_allocate_port) return true; }); if (!ok) - return EADDRINUSE; + return set_so_error(EADDRINUSE); } set_direction(Direction::Passive); @@ -401,7 +401,7 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh auto routing_decision = route_to(peer_address(), local_address()); if (routing_decision.is_zero()) - return EHOSTUNREACH; + return set_so_error(EHOSTUNREACH); if (!has_specific_local_address()) set_local_address(routing_decision.adapter->ipv4_address()); @@ -425,20 +425,20 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh locker.unlock(); auto unblock_flags = Thread::FileBlocker::BlockFlags::None; if (Thread::current()->block<Thread::ConnectBlocker>({}, description, unblock_flags).was_interrupted()) - return EINTR; + return set_so_error(EINTR); locker.lock(); VERIFY(setup_state() == SetupState::Completed); if (has_error()) { // TODO: check unblock_flags m_role = Role::None; if (error() == TCPSocket::Error::RetransmitTimeout) - return ETIMEDOUT; + return set_so_error(ETIMEDOUT); else - return ECONNREFUSED; + return set_so_error(ECONNREFUSED); } return KSuccess; } - return EINPROGRESS; + return set_so_error(EINPROGRESS); } KResultOr<u16> TCPSocket::protocol_allocate_local_port() @@ -464,7 +464,7 @@ KResultOr<u16> TCPSocket::protocol_allocate_local_port() if (port == first_scan_port) break; } - return EADDRINUSE; + return set_so_error(EADDRINUSE); }); } diff --git a/Kernel/Net/UDPSocket.cpp b/Kernel/Net/UDPSocket.cpp index fc6217ebf2..170663fc32 100644 --- a/Kernel/Net/UDPSocket.cpp +++ b/Kernel/Net/UDPSocket.cpp @@ -69,7 +69,7 @@ KResultOr<size_t> UDPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use VERIFY(udp_packet.length() >= sizeof(UDPPacket)); // FIXME: This should be rejected earlier. size_t read_size = min(buffer_size, udp_packet.length() - sizeof(UDPPacket)); if (!buffer.write(udp_packet.payload(), read_size)) - return EFAULT; + return set_so_error(EFAULT); return read_size; } @@ -77,20 +77,20 @@ KResultOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_ { auto routing_decision = route_to(peer_address(), local_address(), bound_interface()); if (routing_decision.is_zero()) - return EHOSTUNREACH; + return set_so_error(EHOSTUNREACH); auto ipv4_payload_offset = routing_decision.adapter->ipv4_payload_offset(); data_length = min(data_length, routing_decision.adapter->mtu() - ipv4_payload_offset - sizeof(UDPPacket)); const size_t udp_buffer_size = sizeof(UDPPacket) + data_length; auto packet = routing_decision.adapter->acquire_packet_buffer(ipv4_payload_offset + udp_buffer_size); if (!packet) - return ENOMEM; + return set_so_error(ENOMEM); memset(packet->buffer->data() + ipv4_payload_offset, 0, sizeof(UDPPacket)); auto& udp_packet = *reinterpret_cast<UDPPacket*>(packet->buffer->data() + ipv4_payload_offset); udp_packet.set_source_port(local_port()); udp_packet.set_destination_port(peer_port()); udp_packet.set_length(udp_buffer_size); if (!data.read(udp_packet.payload(), data_length)) - return EFAULT; + return set_so_error(EFAULT); routing_decision.adapter->fill_in_ipv4_header(*packet, local_address(), routing_decision.next_hop, peer_address(), IPv4Protocol::UDP, udp_buffer_size, ttl()); @@ -126,7 +126,7 @@ KResultOr<u16> UDPSocket::protocol_allocate_local_port() if (port == first_scan_port) break; } - return EADDRINUSE; + return set_so_error(EADDRINUSE); }); } @@ -134,7 +134,7 @@ KResult UDPSocket::protocol_bind() { return sockets_by_port().with_exclusive([&](auto& table) -> KResult { if (table.contains(local_port())) - return EADDRINUSE; + return set_so_error(EADDRINUSE); table.set(local_port(), this); return KSuccess; }); |