summaryrefslogtreecommitdiff
path: root/Kernel/Net
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/Net')
-rw-r--r--Kernel/Net/IPv4Socket.cpp54
-rw-r--r--Kernel/Net/LocalSocket.cpp55
-rw-r--r--Kernel/Net/Socket.cpp10
-rw-r--r--Kernel/Net/Socket.h9
-rw-r--r--Kernel/Net/TCPSocket.cpp26
-rw-r--r--Kernel/Net/UDPSocket.cpp12
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;
});