mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 00:47:45 +00:00
Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace! This was a slightly tedious refactoring that took a long time, so it's not unlikely that some bugs crept in. Nevertheless, it does pass basic functionality testing, and it's just real nice to finally see the same pattern in all contexts. :^)
This commit is contained in:
parent
7ee10c6926
commit
79fa9765ca
262 changed files with 2415 additions and 2600 deletions
|
@ -35,12 +35,12 @@ MutexProtected<IPv4Socket::List>& IPv4Socket::all_sockets()
|
|||
return *s_all_sockets;
|
||||
}
|
||||
|
||||
KResultOr<NonnullOwnPtr<DoubleBuffer>> IPv4Socket::try_create_receive_buffer()
|
||||
ErrorOr<NonnullOwnPtr<DoubleBuffer>> IPv4Socket::try_create_receive_buffer()
|
||||
{
|
||||
return DoubleBuffer::try_create(256 * KiB);
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol)
|
||||
ErrorOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol)
|
||||
{
|
||||
auto receive_buffer = TRY(IPv4Socket::try_create_receive_buffer());
|
||||
|
||||
|
@ -94,7 +94,7 @@ void IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size)
|
|||
*address_size = sizeof(sockaddr_in);
|
||||
}
|
||||
|
||||
KResult IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t address_size)
|
||||
ErrorOr<void> IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t address_size)
|
||||
{
|
||||
VERIFY(setup_state() == SetupState::Unstarted);
|
||||
if (address_size != sizeof(sockaddr_in))
|
||||
|
@ -122,12 +122,12 @@ KResult IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t addr
|
|||
return protocol_bind();
|
||||
}
|
||||
|
||||
KResult IPv4Socket::listen(size_t backlog)
|
||||
ErrorOr<void> IPv4Socket::listen(size_t backlog)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
auto result = allocate_local_port_if_needed();
|
||||
if (result.error_or_port.is_error() && result.error_or_port.error() != ENOPROTOOPT)
|
||||
return result.error_or_port.error();
|
||||
if (result.error_or_port.is_error() && result.error_or_port.error().code() != ENOPROTOOPT)
|
||||
return result.error_or_port.release_error();
|
||||
|
||||
set_backlog(backlog);
|
||||
set_role(Role::Listener);
|
||||
|
@ -138,7 +138,7 @@ KResult IPv4Socket::listen(size_t backlog)
|
|||
return protocol_listen(result.did_allocate);
|
||||
}
|
||||
|
||||
KResult IPv4Socket::connect(OpenFileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock should_block)
|
||||
ErrorOr<void> IPv4Socket::connect(OpenFileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock should_block)
|
||||
{
|
||||
if (address_size != sizeof(sockaddr_in))
|
||||
return set_so_error(EINVAL);
|
||||
|
@ -182,12 +182,12 @@ PortAllocationResult IPv4Socket::allocate_local_port_if_needed()
|
|||
return { m_local_port, false };
|
||||
auto port_or_error = protocol_allocate_local_port();
|
||||
if (port_or_error.is_error())
|
||||
return { port_or_error.error(), false };
|
||||
m_local_port = port_or_error.value();
|
||||
return { port_or_error.release_error(), false };
|
||||
m_local_port = port_or_error.release_value();
|
||||
return { m_local_port, true };
|
||||
}
|
||||
|
||||
KResultOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuffer& data, size_t data_length, [[maybe_unused]] int flags, Userspace<const sockaddr*> addr, socklen_t addr_length)
|
||||
ErrorOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuffer& data, size_t data_length, [[maybe_unused]] int flags, Userspace<const sockaddr*> addr, socklen_t addr_length)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
|
||||
|
@ -217,8 +217,8 @@ KResultOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuf
|
|||
if (m_local_address.to_u32() == 0)
|
||||
m_local_address = routing_decision.adapter->ipv4_address();
|
||||
|
||||
if (auto result = allocate_local_port_if_needed(); result.error_or_port.is_error() && result.error_or_port.error() != ENOPROTOOPT)
|
||||
return result.error_or_port.error();
|
||||
if (auto result = allocate_local_port_if_needed(); result.error_or_port.is_error() && result.error_or_port.error().code() != ENOPROTOOPT)
|
||||
return result.error_or_port.release_error();
|
||||
|
||||
dbgln_if(IPV4_SOCKET_DEBUG, "sendto: destination={}:{}", m_peer_address, m_peer_port);
|
||||
|
||||
|
@ -232,7 +232,7 @@ KResultOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuf
|
|||
m_peer_address, (IPv4Protocol)protocol(), data_length, m_type_of_service, m_ttl);
|
||||
if (auto result = data.read(packet->buffer->data() + ipv4_payload_offset, data_length); result.is_error()) {
|
||||
routing_decision.adapter->release_packet_buffer(*packet);
|
||||
return set_so_error(result);
|
||||
return set_so_error(result.release_error());
|
||||
}
|
||||
routing_decision.adapter->send_packet(packet->bytes());
|
||||
routing_decision.adapter->release_packet_buffer(*packet);
|
||||
|
@ -245,7 +245,7 @@ KResultOr<size_t> IPv4Socket::sendto(OpenFileDescription&, const UserOrKernelBuf
|
|||
return nsent_or_error;
|
||||
}
|
||||
|
||||
KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>)
|
||||
ErrorOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
|
||||
|
@ -271,7 +271,7 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descrip
|
|||
}
|
||||
}
|
||||
|
||||
KResultOr<size_t> nreceived_or_error { 0 };
|
||||
ErrorOr<size_t> nreceived_or_error { 0 };
|
||||
if (flags & MSG_PEEK)
|
||||
nreceived_or_error = m_receive_buffer->peek(buffer, buffer_length);
|
||||
else
|
||||
|
@ -284,7 +284,7 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descrip
|
|||
return nreceived_or_error;
|
||||
}
|
||||
|
||||
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)
|
||||
ErrorOr<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 taken_packet;
|
||||
|
@ -379,7 +379,7 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr
|
|||
return protocol_receive(packet->data->bytes(), 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)
|
||||
ErrorOr<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)
|
||||
{
|
||||
if (user_addr_length) {
|
||||
socklen_t addr_length;
|
||||
|
@ -390,7 +390,7 @@ KResultOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrK
|
|||
|
||||
dbgln_if(IPV4_SOCKET_DEBUG, "recvfrom: type={}, local_port={}", type(), local_port());
|
||||
|
||||
KResultOr<size_t> nreceived = 0;
|
||||
ErrorOr<size_t> nreceived = 0;
|
||||
if (buffer_mode() == BufferMode::Bytes)
|
||||
nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length);
|
||||
else
|
||||
|
@ -456,7 +456,7 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
|
|||
return true;
|
||||
}
|
||||
|
||||
KResultOr<NonnullOwnPtr<KString>> IPv4Socket::pseudo_path(const OpenFileDescription&) const
|
||||
ErrorOr<NonnullOwnPtr<KString>> IPv4Socket::pseudo_path(const OpenFileDescription&) const
|
||||
{
|
||||
if (m_role == Role::None)
|
||||
return KString::try_create("socket"sv);
|
||||
|
@ -488,7 +488,7 @@ KResultOr<NonnullOwnPtr<KString>> IPv4Socket::pseudo_path(const OpenFileDescript
|
|||
return KString::try_create(builder.to_string());
|
||||
}
|
||||
|
||||
KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
||||
ErrorOr<void> IPv4Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
||||
{
|
||||
if (level != IPPROTO_IP)
|
||||
return Socket::setsockopt(level, option, user_value, user_value_size);
|
||||
|
@ -502,7 +502,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
|
|||
if (value < 0 || value > 255)
|
||||
return EINVAL;
|
||||
m_ttl = value;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
case IP_TOS: {
|
||||
if (user_value_size < sizeof(int))
|
||||
|
@ -512,7 +512,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
|
|||
if (value < 0 || value > 255)
|
||||
return EINVAL;
|
||||
m_type_of_service = value;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
case IP_MULTICAST_LOOP: {
|
||||
if (user_value_size != 1)
|
||||
|
@ -522,7 +522,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
|
|||
if (value != 0 && value != 1)
|
||||
return EINVAL;
|
||||
m_multicast_loop = value;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
case IP_ADD_MEMBERSHIP: {
|
||||
if (user_value_size != sizeof(ip_mreq))
|
||||
|
@ -534,7 +534,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
|
|||
IPv4Address address { (const u8*)&mreq.imr_multiaddr.s_addr };
|
||||
if (!m_multicast_memberships.contains_slow(address))
|
||||
m_multicast_memberships.append(address);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
case IP_DROP_MEMBERSHIP: {
|
||||
if (user_value_size != sizeof(ip_mreq))
|
||||
|
@ -545,14 +545,14 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
|
|||
return ENOTSUP;
|
||||
IPv4Address address { (const u8*)&mreq.imr_multiaddr.s_addr };
|
||||
m_multicast_memberships.remove_first_matching([&address](auto& a) { return a == address; });
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
default:
|
||||
return ENOPROTOOPT;
|
||||
}
|
||||
}
|
||||
|
||||
KResult IPv4Socket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
ErrorOr<void> IPv4Socket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
{
|
||||
if (level != IPPROTO_IP)
|
||||
return Socket::getsockopt(description, level, option, value, value_size);
|
||||
|
@ -589,11 +589,11 @@ KResult IPv4Socket::getsockopt(OpenFileDescription& description, int level, int
|
|||
}
|
||||
}
|
||||
|
||||
KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||
ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||
{
|
||||
REQUIRE_PROMISE(inet);
|
||||
|
||||
auto ioctl_route = [request, arg]() -> KResult {
|
||||
auto ioctl_route = [request, arg]() -> ErrorOr<void> {
|
||||
auto user_route = static_ptr_cast<rtentry*>(arg);
|
||||
rtentry route;
|
||||
TRY(copy_from_user(&route, user_route));
|
||||
|
@ -614,17 +614,17 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
if ((route.rt_flags & (RTF_UP | RTF_GATEWAY)) != (RTF_UP | RTF_GATEWAY))
|
||||
return EINVAL; // FIXME: Find the correct value to return
|
||||
adapter->set_ipv4_gateway(IPv4Address(((sockaddr_in&)route.rt_gateway).sin_addr.s_addr));
|
||||
return KSuccess;
|
||||
return {};
|
||||
|
||||
case SIOCDELRT:
|
||||
// FIXME: Support gateway deletion
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
};
|
||||
|
||||
auto ioctl_arp = [request, arg]() -> KResult {
|
||||
auto ioctl_arp = [request, arg]() -> ErrorOr<void> {
|
||||
auto user_req = static_ptr_cast<arpreq*>(arg);
|
||||
arpreq arp_req;
|
||||
TRY(copy_from_user(&arp_req, user_req));
|
||||
|
@ -636,7 +636,7 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
if (arp_req.arp_pa.sa_family != AF_INET)
|
||||
return EAFNOSUPPORT;
|
||||
update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateArp::Set);
|
||||
return KSuccess;
|
||||
return {};
|
||||
|
||||
case SIOCDARP:
|
||||
if (!Process::current().is_superuser())
|
||||
|
@ -644,13 +644,13 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
if (arp_req.arp_pa.sa_family != AF_INET)
|
||||
return EAFNOSUPPORT;
|
||||
update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateArp::Delete);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
};
|
||||
|
||||
auto ioctl_interface = [request, arg]() -> KResult {
|
||||
auto ioctl_interface = [request, arg]() -> ErrorOr<void> {
|
||||
auto user_ifr = static_ptr_cast<ifreq*>(arg);
|
||||
ifreq ifr;
|
||||
TRY(copy_from_user(&ifr, user_ifr));
|
||||
|
@ -670,7 +670,7 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
if (ifr.ifr_addr.sa_family != AF_INET)
|
||||
return EAFNOSUPPORT;
|
||||
adapter->set_ipv4_address(IPv4Address(((sockaddr_in&)ifr.ifr_addr).sin_addr.s_addr));
|
||||
return KSuccess;
|
||||
return {};
|
||||
|
||||
case SIOCSIFNETMASK:
|
||||
if (!Process::current().is_superuser())
|
||||
|
@ -678,7 +678,7 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
if (ifr.ifr_addr.sa_family != AF_INET)
|
||||
return EAFNOSUPPORT;
|
||||
adapter->set_ipv4_netmask(IPv4Address(((sockaddr_in&)ifr.ifr_netmask).sin_addr.s_addr));
|
||||
return KSuccess;
|
||||
return {};
|
||||
|
||||
case SIOCGIFADDR: {
|
||||
auto ip4_addr = adapter->ipv4_address().to_u32();
|
||||
|
@ -770,10 +770,10 @@ KResult IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
KResult IPv4Socket::close()
|
||||
ErrorOr<void> IPv4Socket::close()
|
||||
{
|
||||
[[maybe_unused]] auto rc = shutdown(SHUT_RDWR);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
void IPv4Socket::shut_down_for_reading()
|
||||
|
|
|
@ -22,29 +22,29 @@ class TCPPacket;
|
|||
class TCPSocket;
|
||||
|
||||
struct PortAllocationResult {
|
||||
KResultOr<u16> error_or_port;
|
||||
ErrorOr<u16> error_or_port;
|
||||
bool did_allocate;
|
||||
};
|
||||
|
||||
class IPv4Socket : public Socket {
|
||||
public:
|
||||
static KResultOr<NonnullRefPtr<Socket>> create(int type, int protocol);
|
||||
static ErrorOr<NonnullRefPtr<Socket>> create(int type, int protocol);
|
||||
virtual ~IPv4Socket() override;
|
||||
|
||||
virtual KResult close() override;
|
||||
virtual KResult bind(Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual KResult connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock = ShouldBlock::Yes) override;
|
||||
virtual KResult listen(size_t) override;
|
||||
virtual ErrorOr<void> close() override;
|
||||
virtual ErrorOr<void> bind(Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual ErrorOr<void> connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock = ShouldBlock::Yes) override;
|
||||
virtual ErrorOr<void> listen(size_t) override;
|
||||
virtual void get_local_address(sockaddr*, socklen_t*) override;
|
||||
virtual void get_peer_address(sockaddr*, socklen_t*) override;
|
||||
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
||||
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
||||
virtual KResultOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual KResultOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override;
|
||||
virtual KResult setsockopt(int level, int option, Userspace<const void*>, socklen_t) override;
|
||||
virtual KResult getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
|
||||
virtual ErrorOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override;
|
||||
virtual ErrorOr<void> setsockopt(int level, int option, Userspace<const void*>, socklen_t) override;
|
||||
virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
|
||||
|
||||
virtual KResult ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override;
|
||||
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override;
|
||||
|
||||
bool did_receive(const IPv4Address& peer_address, u16 peer_port, ReadonlyBytes, const Time&);
|
||||
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
IPv4SocketTuple tuple() const { return IPv4SocketTuple(m_local_address, m_local_port, m_peer_address, m_peer_port); }
|
||||
|
||||
KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||
ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||
|
||||
u8 type_of_service() const { return m_type_of_service; }
|
||||
u8 ttl() const { return m_ttl; }
|
||||
|
@ -78,12 +78,12 @@ protected:
|
|||
|
||||
PortAllocationResult allocate_local_port_if_needed();
|
||||
|
||||
virtual KResult protocol_bind() { return KSuccess; }
|
||||
virtual KResult protocol_listen([[maybe_unused]] bool did_allocate_port) { return KSuccess; }
|
||||
virtual KResultOr<size_t> protocol_receive(ReadonlyBytes /* raw_ipv4_packet */, UserOrKernelBuffer&, size_t, int) { return ENOTIMPL; }
|
||||
virtual KResultOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) { return ENOTIMPL; }
|
||||
virtual KResult protocol_connect(OpenFileDescription&, ShouldBlock) { return KSuccess; }
|
||||
virtual KResultOr<u16> protocol_allocate_local_port() { return ENOPROTOOPT; }
|
||||
virtual ErrorOr<void> protocol_bind() { return {}; }
|
||||
virtual ErrorOr<void> protocol_listen([[maybe_unused]] bool did_allocate_port) { return {}; }
|
||||
virtual ErrorOr<size_t> protocol_receive(ReadonlyBytes /* raw_ipv4_packet */, UserOrKernelBuffer&, size_t, int) { return ENOTIMPL; }
|
||||
virtual ErrorOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) { return ENOTIMPL; }
|
||||
virtual ErrorOr<void> protocol_connect(OpenFileDescription&, ShouldBlock) { return {}; }
|
||||
virtual ErrorOr<u16> protocol_allocate_local_port() { return ENOPROTOOPT; }
|
||||
virtual bool protocol_is_disconnected() const { return false; }
|
||||
|
||||
virtual void shut_down_for_reading() override;
|
||||
|
@ -91,14 +91,14 @@ protected:
|
|||
void set_local_address(IPv4Address address) { m_local_address = address; }
|
||||
void set_peer_address(IPv4Address address) { m_peer_address = address; }
|
||||
|
||||
static KResultOr<NonnullOwnPtr<DoubleBuffer>> try_create_receive_buffer();
|
||||
static ErrorOr<NonnullOwnPtr<DoubleBuffer>> try_create_receive_buffer();
|
||||
void drop_receive_buffer();
|
||||
|
||||
private:
|
||||
virtual bool is_ipv4() const override { return true; }
|
||||
|
||||
KResultOr<size_t> receive_byte_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>);
|
||||
KResultOr<size_t> receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&);
|
||||
ErrorOr<size_t> receive_byte_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>);
|
||||
ErrorOr<size_t> receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&);
|
||||
|
||||
void set_can_read(bool);
|
||||
|
||||
|
|
|
@ -34,14 +34,14 @@ void LocalSocket::for_each(Function<void(const LocalSocket&)> callback)
|
|||
});
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<LocalSocket>> LocalSocket::try_create(int type)
|
||||
ErrorOr<NonnullRefPtr<LocalSocket>> LocalSocket::try_create(int type)
|
||||
{
|
||||
auto client_buffer = TRY(DoubleBuffer::try_create());
|
||||
auto server_buffer = TRY(DoubleBuffer::try_create());
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) LocalSocket(type, move(client_buffer), move(server_buffer)));
|
||||
}
|
||||
|
||||
KResultOr<SocketPair> LocalSocket::try_create_connected_pair(int type)
|
||||
ErrorOr<SocketPair> LocalSocket::try_create_connected_pair(int type)
|
||||
{
|
||||
auto socket = TRY(LocalSocket::try_create(type));
|
||||
auto description1 = TRY(OpenFileDescription::try_create(*socket));
|
||||
|
@ -106,7 +106,7 @@ void LocalSocket::get_peer_address(sockaddr* address, socklen_t* address_size)
|
|||
get_local_address(address, address_size);
|
||||
}
|
||||
|
||||
KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t address_size)
|
||||
ErrorOr<void> LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t address_size)
|
||||
{
|
||||
VERIFY(setup_state() == SetupState::Unstarted);
|
||||
if (address_size != sizeof(sockaddr_un))
|
||||
|
@ -125,9 +125,9 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
|
|||
UidAndGid owner { m_prebind_uid, m_prebind_gid };
|
||||
auto result = VirtualFileSystem::the().open(path->view(), O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current().current_directory(), owner);
|
||||
if (result.is_error()) {
|
||||
if (result.error() == EEXIST)
|
||||
if (result.error().code() == EEXIST)
|
||||
return set_so_error(EADDRINUSE);
|
||||
return result.error();
|
||||
return result.release_error();
|
||||
}
|
||||
|
||||
auto file = move(result.value());
|
||||
|
@ -141,10 +141,10 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
|
|||
|
||||
m_path = move(path);
|
||||
m_bound = true;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult LocalSocket::connect(OpenFileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock)
|
||||
ErrorOr<void> LocalSocket::connect(OpenFileDescription& description, Userspace<const sockaddr*> address, socklen_t address_size, ShouldBlock)
|
||||
{
|
||||
VERIFY(!m_bound);
|
||||
if (address_size != sizeof(sockaddr_un))
|
||||
|
@ -191,7 +191,7 @@ KResult LocalSocket::connect(OpenFileDescription& description, Userspace<const s
|
|||
|
||||
if (is_connected()) {
|
||||
set_connect_side_role(Role::Connected);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto unblock_flags = Thread::OpenFileDescriptionBlocker::BlockFlags::None;
|
||||
|
@ -207,10 +207,10 @@ KResult LocalSocket::connect(OpenFileDescription& description, Userspace<const s
|
|||
return set_so_error(ECONNREFUSED);
|
||||
}
|
||||
set_connect_side_role(Role::Connected);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult LocalSocket::listen(size_t backlog)
|
||||
ErrorOr<void> LocalSocket::listen(size_t backlog)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
if (type() != SOCK_STREAM)
|
||||
|
@ -222,10 +222,10 @@ KResult LocalSocket::listen(size_t backlog)
|
|||
|
||||
dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) listening with backlog={}", this, backlog);
|
||||
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult LocalSocket::attach(OpenFileDescription& description)
|
||||
ErrorOr<void> LocalSocket::attach(OpenFileDescription& description)
|
||||
{
|
||||
VERIFY(!m_accept_side_fd_open);
|
||||
if (m_connect_side_role == Role::None) {
|
||||
|
@ -237,7 +237,7 @@ KResult LocalSocket::attach(OpenFileDescription& description)
|
|||
}
|
||||
|
||||
evaluate_block_conditions();
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
void LocalSocket::detach(OpenFileDescription& description)
|
||||
|
@ -290,7 +290,7 @@ bool LocalSocket::can_write(const OpenFileDescription& description, size_t) cons
|
|||
return false;
|
||||
}
|
||||
|
||||
KResultOr<size_t> LocalSocket::sendto(OpenFileDescription& description, const UserOrKernelBuffer& data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t)
|
||||
ErrorOr<size_t> LocalSocket::sendto(OpenFileDescription& description, const UserOrKernelBuffer& data, size_t data_size, int, Userspace<const sockaddr*>, socklen_t)
|
||||
{
|
||||
if (!has_attached_peer(description))
|
||||
return set_so_error(EPIPE);
|
||||
|
@ -323,7 +323,7 @@ DoubleBuffer* LocalSocket::send_buffer_for(OpenFileDescription& description)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
KResultOr<size_t> LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&)
|
||||
ErrorOr<size_t> LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&)
|
||||
{
|
||||
auto* socket_buffer = receive_buffer_for(description);
|
||||
if (!socket_buffer)
|
||||
|
@ -355,7 +355,7 @@ StringView LocalSocket::socket_path() const
|
|||
return m_path->view();
|
||||
}
|
||||
|
||||
KResultOr<NonnullOwnPtr<KString>> LocalSocket::pseudo_path(const OpenFileDescription& description) const
|
||||
ErrorOr<NonnullOwnPtr<KString>> LocalSocket::pseudo_path(const OpenFileDescription& description) const
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.append("socket:");
|
||||
|
@ -381,7 +381,7 @@ KResultOr<NonnullOwnPtr<KString>> LocalSocket::pseudo_path(const OpenFileDescrip
|
|||
return KString::try_create(builder.to_string());
|
||||
}
|
||||
|
||||
KResult LocalSocket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
ErrorOr<void> LocalSocket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
{
|
||||
if (level != SOL_SOCKET)
|
||||
return Socket::getsockopt(description, level, option, value, value_size);
|
||||
|
@ -402,12 +402,12 @@ KResult LocalSocket::getsockopt(OpenFileDescription& description, int level, int
|
|||
TRY(copy_to_user(static_ptr_cast<ucred*>(value), &m_origin));
|
||||
size = sizeof(ucred);
|
||||
TRY(copy_to_user(value_size, &size));
|
||||
return KSuccess;
|
||||
return {};
|
||||
case Role::Connected:
|
||||
TRY(copy_to_user(static_ptr_cast<ucred*>(value), &m_acceptor));
|
||||
size = sizeof(ucred);
|
||||
TRY(copy_to_user(value_size, &size));
|
||||
return KSuccess;
|
||||
return {};
|
||||
case Role::Connecting:
|
||||
return ENOTCONN;
|
||||
default:
|
||||
|
@ -420,7 +420,7 @@ KResult LocalSocket::getsockopt(OpenFileDescription& description, int level, int
|
|||
}
|
||||
}
|
||||
|
||||
KResult LocalSocket::ioctl(OpenFileDescription& description, unsigned request, Userspace<void*> arg)
|
||||
ErrorOr<void> LocalSocket::ioctl(OpenFileDescription& description, unsigned request, Userspace<void*> arg)
|
||||
{
|
||||
switch (request) {
|
||||
case FIONREAD: {
|
||||
|
@ -432,17 +432,17 @@ KResult LocalSocket::ioctl(OpenFileDescription& description, unsigned request, U
|
|||
return ENOTTY;
|
||||
}
|
||||
|
||||
KResult LocalSocket::chmod(OpenFileDescription&, mode_t mode)
|
||||
ErrorOr<void> LocalSocket::chmod(OpenFileDescription&, mode_t mode)
|
||||
{
|
||||
auto inode = m_inode.strong_ref();
|
||||
if (inode)
|
||||
return inode->chmod(mode);
|
||||
|
||||
m_prebind_mode = mode & 0777;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult LocalSocket::chown(OpenFileDescription&, UserID uid, GroupID gid)
|
||||
ErrorOr<void> LocalSocket::chown(OpenFileDescription&, UserID uid, GroupID gid)
|
||||
{
|
||||
auto inode = m_inode.strong_ref();
|
||||
if (inode)
|
||||
|
@ -454,7 +454,7 @@ KResult LocalSocket::chown(OpenFileDescription&, UserID uid, GroupID gid)
|
|||
|
||||
m_prebind_uid = uid;
|
||||
m_prebind_gid = gid;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
NonnullRefPtrVector<OpenFileDescription>& LocalSocket::recvfd_queue_for(const OpenFileDescription& description)
|
||||
|
@ -477,7 +477,7 @@ NonnullRefPtrVector<OpenFileDescription>& LocalSocket::sendfd_queue_for(const Op
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
KResult LocalSocket::sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description)
|
||||
ErrorOr<void> LocalSocket::sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
auto role = this->role(socket_description);
|
||||
|
@ -489,10 +489,10 @@ KResult LocalSocket::sendfd(OpenFileDescription const& socket_description, Nonnu
|
|||
return set_so_error(EBUSY);
|
||||
if (!queue.try_append(move(passing_description)))
|
||||
return set_so_error(ENOMEM);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<OpenFileDescription>> LocalSocket::recvfd(const OpenFileDescription& socket_description)
|
||||
ErrorOr<NonnullRefPtr<OpenFileDescription>> LocalSocket::recvfd(const OpenFileDescription& socket_description)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
auto role = this->role(socket_description);
|
||||
|
@ -506,10 +506,10 @@ KResultOr<NonnullRefPtr<OpenFileDescription>> LocalSocket::recvfd(const OpenFile
|
|||
return queue.take_first();
|
||||
}
|
||||
|
||||
KResult LocalSocket::try_set_path(StringView path)
|
||||
ErrorOr<void> LocalSocket::try_set_path(StringView path)
|
||||
{
|
||||
m_path = TRY(KString::try_create(path));
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,34 +22,34 @@ struct SocketPair {
|
|||
class LocalSocket final : public Socket {
|
||||
|
||||
public:
|
||||
static KResultOr<NonnullRefPtr<LocalSocket>> try_create(int type);
|
||||
static KResultOr<SocketPair> try_create_connected_pair(int type);
|
||||
static ErrorOr<NonnullRefPtr<LocalSocket>> try_create(int type);
|
||||
static ErrorOr<SocketPair> try_create_connected_pair(int type);
|
||||
virtual ~LocalSocket() override;
|
||||
|
||||
KResult sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description);
|
||||
KResultOr<NonnullRefPtr<OpenFileDescription>> recvfd(const OpenFileDescription& socket_description);
|
||||
ErrorOr<void> sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description);
|
||||
ErrorOr<NonnullRefPtr<OpenFileDescription>> recvfd(const OpenFileDescription& socket_description);
|
||||
|
||||
static void for_each(Function<void(const LocalSocket&)>);
|
||||
|
||||
StringView socket_path() const;
|
||||
KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||
ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||
|
||||
// ^Socket
|
||||
virtual KResult bind(Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual KResult connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock = ShouldBlock::Yes) override;
|
||||
virtual KResult listen(size_t) override;
|
||||
virtual ErrorOr<void> bind(Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual ErrorOr<void> connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock = ShouldBlock::Yes) override;
|
||||
virtual ErrorOr<void> listen(size_t) override;
|
||||
virtual void get_local_address(sockaddr*, socklen_t*) override;
|
||||
virtual void get_peer_address(sockaddr*, socklen_t*) override;
|
||||
virtual KResult attach(OpenFileDescription&) override;
|
||||
virtual ErrorOr<void> attach(OpenFileDescription&) override;
|
||||
virtual void detach(OpenFileDescription&) override;
|
||||
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
||||
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
||||
virtual KResultOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual KResultOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override;
|
||||
virtual KResult getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
|
||||
virtual KResult ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override;
|
||||
virtual KResult chown(OpenFileDescription&, UserID, GroupID) override;
|
||||
virtual KResult chmod(OpenFileDescription&, mode_t) override;
|
||||
virtual ErrorOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
|
||||
virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override;
|
||||
virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
|
||||
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override;
|
||||
virtual ErrorOr<void> chown(OpenFileDescription&, UserID, GroupID) override;
|
||||
virtual ErrorOr<void> chmod(OpenFileDescription&, mode_t) override;
|
||||
|
||||
private:
|
||||
explicit LocalSocket(int type, NonnullOwnPtr<DoubleBuffer> client_buffer, NonnullOwnPtr<DoubleBuffer> server_buffer);
|
||||
|
@ -69,7 +69,7 @@ private:
|
|||
evaluate_block_conditions();
|
||||
}
|
||||
|
||||
KResult try_set_path(StringView);
|
||||
ErrorOr<void> try_set_path(StringView);
|
||||
|
||||
// The inode this socket is bound to.
|
||||
WeakPtr<Inode> m_inode;
|
||||
|
|
|
@ -74,7 +74,7 @@ RefPtr<NetworkAdapter> NetworkingManagement::lookup_by_name(const StringView& na
|
|||
return found_adapter;
|
||||
}
|
||||
|
||||
KResultOr<NonnullOwnPtr<KString>> NetworkingManagement::generate_interface_name_from_pci_address(PCI::DeviceIdentifier const& device_identifier)
|
||||
ErrorOr<NonnullOwnPtr<KString>> NetworkingManagement::generate_interface_name_from_pci_address(PCI::DeviceIdentifier const& device_identifier)
|
||||
{
|
||||
VERIFY(device_identifier.class_code().value() == 0x2);
|
||||
// Note: This stands for e - "Ethernet", p - "Port" as for PCI bus, "s" for slot as for PCI slot
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
static bool is_initialized();
|
||||
bool initialize();
|
||||
|
||||
static KResultOr<NonnullOwnPtr<KString>> generate_interface_name_from_pci_address(PCI::DeviceIdentifier const&);
|
||||
static ErrorOr<NonnullOwnPtr<KString>> generate_interface_name_from_pci_address(PCI::DeviceIdentifier const&);
|
||||
|
||||
NetworkingManagement();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
KResultOr<NonnullRefPtr<Socket>> Socket::create(int domain, int type, int protocol)
|
||||
ErrorOr<NonnullRefPtr<Socket>> Socket::create(int domain, int type, int protocol)
|
||||
{
|
||||
switch (domain) {
|
||||
case AF_LOCAL:
|
||||
|
@ -65,7 +65,7 @@ RefPtr<Socket> Socket::accept()
|
|||
return client;
|
||||
}
|
||||
|
||||
KResult Socket::queue_connection_from(NonnullRefPtr<Socket> peer)
|
||||
ErrorOr<void> Socket::queue_connection_from(NonnullRefPtr<Socket> peer)
|
||||
{
|
||||
dbgln_if(SOCKET_DEBUG, "Socket({}) queueing connection", this);
|
||||
MutexLocker locker(mutex());
|
||||
|
@ -74,10 +74,10 @@ KResult Socket::queue_connection_from(NonnullRefPtr<Socket> peer)
|
|||
if (!m_pending.try_append(peer))
|
||||
return set_so_error(ENOMEM);
|
||||
evaluate_block_conditions();
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
||||
ErrorOr<void> Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
||||
{
|
||||
if (level != SOL_SOCKET)
|
||||
return ENOPROTOOPT;
|
||||
|
@ -87,12 +87,12 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
|
|||
if (user_value_size != sizeof(timeval))
|
||||
return EINVAL;
|
||||
m_send_timeout = TRY(copy_time_from_user(static_ptr_cast<timeval const*>(user_value)));
|
||||
return KSuccess;
|
||||
return {};
|
||||
case SO_RCVTIMEO:
|
||||
if (user_value_size != sizeof(timeval))
|
||||
return EINVAL;
|
||||
m_receive_timeout = TRY(copy_time_from_user(static_ptr_cast<timeval const*>(user_value)));
|
||||
return KSuccess;
|
||||
return {};
|
||||
case SO_BINDTODEVICE: {
|
||||
if (user_value_size != IFNAMSIZ)
|
||||
return EINVAL;
|
||||
|
@ -102,11 +102,11 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
|
|||
if (!device)
|
||||
return ENODEV;
|
||||
m_bound_interface = move(device);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
case SO_KEEPALIVE:
|
||||
// FIXME: Obviously, this is not a real keepalive.
|
||||
return KSuccess;
|
||||
return {};
|
||||
case SO_TIMESTAMP:
|
||||
if (user_value_size != sizeof(int))
|
||||
return EINVAL;
|
||||
|
@ -120,14 +120,14 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
|
|||
m_timestamp = 0;
|
||||
return ENOTSUP;
|
||||
}
|
||||
return KSuccess;
|
||||
return {};
|
||||
default:
|
||||
dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option);
|
||||
return ENOPROTOOPT;
|
||||
}
|
||||
}
|
||||
|
||||
KResult Socket::getsockopt(OpenFileDescription&, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
ErrorOr<void> Socket::getsockopt(OpenFileDescription&, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||
{
|
||||
socklen_t size;
|
||||
TRY(copy_from_user(&size, value_size.unsafe_userspace_ptr()));
|
||||
|
@ -160,11 +160,16 @@ KResult Socket::getsockopt(OpenFileDescription&, int level, int option, Userspac
|
|||
case SO_ERROR: {
|
||||
if (size < sizeof(int))
|
||||
return EINVAL;
|
||||
int errno = so_error().error();
|
||||
int errno;
|
||||
if (so_error().is_error())
|
||||
errno = so_error().error().code();
|
||||
else
|
||||
errno = 0;
|
||||
TRY(copy_to_user(static_ptr_cast<int*>(value), &errno));
|
||||
size = sizeof(int);
|
||||
TRY(copy_to_user(value_size, &size));
|
||||
return set_so_error(KSuccess);
|
||||
clear_so_error();
|
||||
return {};
|
||||
}
|
||||
case SO_BINDTODEVICE:
|
||||
if (size < IFNAMSIZ)
|
||||
|
@ -200,7 +205,7 @@ KResult Socket::getsockopt(OpenFileDescription&, int level, int option, Userspac
|
|||
}
|
||||
}
|
||||
|
||||
KResultOr<size_t> Socket::read(OpenFileDescription& description, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||
ErrorOr<size_t> Socket::read(OpenFileDescription& description, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||
{
|
||||
if (is_shut_down_for_reading())
|
||||
return 0;
|
||||
|
@ -208,14 +213,14 @@ KResultOr<size_t> Socket::read(OpenFileDescription& description, u64, UserOrKern
|
|||
return recvfrom(description, buffer, size, 0, {}, 0, t);
|
||||
}
|
||||
|
||||
KResultOr<size_t> Socket::write(OpenFileDescription& description, u64, const UserOrKernelBuffer& data, size_t size)
|
||||
ErrorOr<size_t> Socket::write(OpenFileDescription& description, u64, const UserOrKernelBuffer& data, size_t size)
|
||||
{
|
||||
if (is_shut_down_for_writing())
|
||||
return set_so_error(EPIPE);
|
||||
return sendto(description, data, size, 0, {}, 0);
|
||||
}
|
||||
|
||||
KResult Socket::shutdown(int how)
|
||||
ErrorOr<void> Socket::shutdown(int how)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
if (type() == SOCK_STREAM && !is_connected())
|
||||
|
@ -228,14 +233,14 @@ KResult Socket::shutdown(int how)
|
|||
shut_down_for_reading();
|
||||
m_shut_down_for_reading |= (how & SHUT_RD) != 0;
|
||||
m_shut_down_for_writing |= (how & SHUT_WR) != 0;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult Socket::stat(::stat& st) const
|
||||
ErrorOr<void> Socket::stat(::stat& st) const
|
||||
{
|
||||
memset(&st, 0, sizeof(st));
|
||||
st.st_mode = S_IFSOCK;
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
void Socket::set_connected(bool connected)
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/Time.h>
|
||||
#include <Kernel/API/KResult.h>
|
||||
#include <Kernel/FileSystem/File.h>
|
||||
#include <Kernel/Locking/Mutex.h>
|
||||
#include <Kernel/Net/NetworkAdapter.h>
|
||||
|
@ -27,7 +27,7 @@ class OpenFileDescription;
|
|||
|
||||
class Socket : public File {
|
||||
public:
|
||||
static KResultOr<NonnullRefPtr<Socket>> create(int domain, int type, int protocol);
|
||||
static ErrorOr<NonnullRefPtr<Socket>> create(int domain, int type, int protocol);
|
||||
virtual ~Socket() override;
|
||||
|
||||
int domain() const { return m_domain; }
|
||||
|
@ -76,20 +76,20 @@ public:
|
|||
bool can_accept() const { return !m_pending.is_empty(); }
|
||||
RefPtr<Socket> accept();
|
||||
|
||||
KResult shutdown(int how);
|
||||
ErrorOr<void> shutdown(int how);
|
||||
|
||||
virtual KResult bind(Userspace<const sockaddr*>, socklen_t) = 0;
|
||||
virtual KResult connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock) = 0;
|
||||
virtual KResult listen(size_t) = 0;
|
||||
virtual ErrorOr<void> bind(Userspace<const sockaddr*>, socklen_t) = 0;
|
||||
virtual ErrorOr<void> connect(OpenFileDescription&, Userspace<const sockaddr*>, socklen_t, ShouldBlock) = 0;
|
||||
virtual ErrorOr<void> listen(size_t) = 0;
|
||||
virtual void get_local_address(sockaddr*, socklen_t*) = 0;
|
||||
virtual void get_peer_address(sockaddr*, socklen_t*) = 0;
|
||||
virtual bool is_local() const { return false; }
|
||||
virtual bool is_ipv4() const { return false; }
|
||||
virtual KResultOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int flags, Userspace<const sockaddr*>, socklen_t) = 0;
|
||||
virtual KResultOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) = 0;
|
||||
virtual ErrorOr<size_t> sendto(OpenFileDescription&, const UserOrKernelBuffer&, size_t, int flags, Userspace<const sockaddr*>, socklen_t) = 0;
|
||||
virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) = 0;
|
||||
|
||||
virtual KResult setsockopt(int level, int option, Userspace<const void*>, socklen_t);
|
||||
virtual KResult getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>);
|
||||
virtual ErrorOr<void> setsockopt(int level, int option, Userspace<const void*>, socklen_t);
|
||||
virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>);
|
||||
|
||||
ProcessID origin_pid() const { return m_origin.pid; }
|
||||
UserID origin_uid() const { return m_origin.uid; }
|
||||
|
@ -102,10 +102,10 @@ public:
|
|||
Mutex& mutex() { return m_mutex; }
|
||||
|
||||
// ^File
|
||||
virtual KResultOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final;
|
||||
virtual KResultOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final;
|
||||
virtual KResult stat(::stat&) const override;
|
||||
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override = 0;
|
||||
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final;
|
||||
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final;
|
||||
virtual ErrorOr<void> stat(::stat&) const override;
|
||||
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override = 0;
|
||||
|
||||
bool has_receive_timeout() const { return m_receive_timeout != Time::zero(); }
|
||||
const Time& receive_timeout() const { return m_receive_timeout; }
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
protected:
|
||||
Socket(int domain, int type, int protocol);
|
||||
|
||||
KResult queue_connection_from(NonnullRefPtr<Socket>);
|
||||
ErrorOr<void> queue_connection_from(NonnullRefPtr<Socket>);
|
||||
|
||||
size_t backlog() const { return m_backlog; }
|
||||
void set_backlog(size_t backlog) { m_backlog = backlog; }
|
||||
|
@ -130,13 +130,25 @@ protected:
|
|||
|
||||
Role m_role { Role::None };
|
||||
|
||||
KResult so_error() const { return m_so_error; }
|
||||
KResult set_so_error(KResult error)
|
||||
ErrorOr<void> so_error() const { return m_so_error; }
|
||||
|
||||
Error set_so_error(ErrnoCode error_code)
|
||||
{
|
||||
auto error = Error::from_errno(error_code);
|
||||
m_so_error = error;
|
||||
return error;
|
||||
}
|
||||
Error set_so_error(Error error)
|
||||
{
|
||||
m_so_error = error;
|
||||
return error;
|
||||
}
|
||||
|
||||
void clear_so_error()
|
||||
{
|
||||
m_so_error = {};
|
||||
}
|
||||
|
||||
void set_origin(Process const&);
|
||||
void set_acceptor(Process const&);
|
||||
|
||||
|
@ -166,7 +178,7 @@ private:
|
|||
Time m_send_timeout {};
|
||||
int m_timestamp { 0 };
|
||||
|
||||
KResult m_so_error { KSuccess };
|
||||
ErrorOr<void> m_so_error;
|
||||
|
||||
NonnullRefPtrVector<Socket> m_pending;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ void TCPSocket::set_state(State new_state)
|
|||
|
||||
if (new_state == State::Established && m_direction == Direction::Outgoing) {
|
||||
set_role(Role::Connected);
|
||||
[[maybe_unused]] auto rc = set_so_error(KSuccess);
|
||||
clear_so_error();
|
||||
}
|
||||
|
||||
if (new_state == State::TimeWait) {
|
||||
|
@ -97,10 +97,10 @@ RefPtr<TCPSocket> TCPSocket::from_tuple(const IPv4SocketTuple& tuple)
|
|||
return {};
|
||||
});
|
||||
}
|
||||
KResultOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create_client(const IPv4Address& new_local_address, u16 new_local_port, const IPv4Address& new_peer_address, u16 new_peer_port)
|
||||
ErrorOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create_client(const IPv4Address& new_local_address, u16 new_local_port, const IPv4Address& new_peer_address, u16 new_peer_port)
|
||||
{
|
||||
auto tuple = IPv4SocketTuple(new_local_address, new_local_port, new_peer_address, new_peer_port);
|
||||
return sockets_by_tuple().with_exclusive([&](auto& table) -> KResultOr<NonnullRefPtr<TCPSocket>> {
|
||||
return sockets_by_tuple().with_exclusive([&](auto& table) -> ErrorOr<NonnullRefPtr<TCPSocket>> {
|
||||
if (table.contains(tuple))
|
||||
return EEXIST;
|
||||
|
||||
|
@ -154,14 +154,14 @@ TCPSocket::~TCPSocket()
|
|||
dbgln_if(TCP_SOCKET_DEBUG, "~TCPSocket in state {}", to_string(state()));
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer)
|
||||
ErrorOr<NonnullRefPtr<TCPSocket>> TCPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer)
|
||||
{
|
||||
// Note: Scratch buffer is only used for SOCK_STREAM sockets.
|
||||
auto scratch_buffer = TRY(KBuffer::try_create_with_size(65536));
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) TCPSocket(protocol, move(receive_buffer), move(scratch_buffer)));
|
||||
}
|
||||
|
||||
KResultOr<size_t> TCPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, [[maybe_unused]] int flags)
|
||||
ErrorOr<size_t> TCPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, [[maybe_unused]] int flags)
|
||||
{
|
||||
auto& ipv4_packet = *reinterpret_cast<const IPv4Packet*>(raw_ipv4_packet.data());
|
||||
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
|
||||
|
@ -172,7 +172,7 @@ KResultOr<size_t> TCPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use
|
|||
return payload_size;
|
||||
}
|
||||
|
||||
KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_t data_length)
|
||||
ErrorOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_t data_length)
|
||||
{
|
||||
RoutingDecision routing_decision = route_to(peer_address(), local_address(), bound_interface());
|
||||
if (routing_decision.is_zero())
|
||||
|
@ -183,14 +183,14 @@ KResultOr<size_t> TCPSocket::protocol_send(const UserOrKernelBuffer& data, size_
|
|||
return data_length;
|
||||
}
|
||||
|
||||
KResult TCPSocket::send_ack(bool allow_duplicate)
|
||||
ErrorOr<void> TCPSocket::send_ack(bool allow_duplicate)
|
||||
{
|
||||
if (!allow_duplicate && m_last_ack_number_sent == m_ack_number)
|
||||
return KSuccess;
|
||||
return {};
|
||||
return send_tcp_packet(TCPFlags::ACK);
|
||||
}
|
||||
|
||||
KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, size_t payload_size, RoutingDecision* user_routing_decision)
|
||||
ErrorOr<void> TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload, size_t payload_size, RoutingDecision* user_routing_decision)
|
||||
{
|
||||
RoutingDecision routing_decision = user_routing_decision ? *user_routing_decision : route_to(peer_address(), local_address(), bound_interface());
|
||||
if (routing_decision.is_zero())
|
||||
|
@ -227,7 +227,7 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload,
|
|||
if (payload) {
|
||||
if (auto result = payload->read(tcp_packet.payload(), payload_size); result.is_error()) {
|
||||
routing_decision.adapter->release_packet_buffer(*packet);
|
||||
return set_so_error(result);
|
||||
return set_so_error(result.release_error());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ KResult TCPSocket::send_tcp_packet(u16 flags, const UserOrKernelBuffer* payload,
|
|||
routing_decision.adapter->release_packet_buffer(*packet);
|
||||
}
|
||||
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
void TCPSocket::receive_tcp_packet(const TCPPacket& packet, u16 size)
|
||||
|
@ -362,7 +362,7 @@ NetworkOrdered<u16> TCPSocket::compute_tcp_checksum(const IPv4Address& source, c
|
|||
return ~(checksum & 0xffff);
|
||||
}
|
||||
|
||||
KResult TCPSocket::protocol_bind()
|
||||
ErrorOr<void> TCPSocket::protocol_bind()
|
||||
{
|
||||
if (has_specific_local_address() && !m_adapter) {
|
||||
m_adapter = NetworkingManagement::the().from_ipv4_address(local_address());
|
||||
|
@ -370,10 +370,10 @@ KResult TCPSocket::protocol_bind()
|
|||
return set_so_error(EADDRNOTAVAIL);
|
||||
}
|
||||
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult TCPSocket::protocol_listen(bool did_allocate_port)
|
||||
ErrorOr<void> TCPSocket::protocol_listen(bool did_allocate_port)
|
||||
{
|
||||
if (!did_allocate_port) {
|
||||
bool ok = sockets_by_tuple().with_exclusive([&](auto& table) -> bool {
|
||||
|
@ -389,10 +389,10 @@ KResult TCPSocket::protocol_listen(bool did_allocate_port)
|
|||
set_direction(Direction::Passive);
|
||||
set_state(State::Listen);
|
||||
set_setup_state(SetupState::Completed);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResult TCPSocket::protocol_connect(OpenFileDescription& description, ShouldBlock should_block)
|
||||
ErrorOr<void> TCPSocket::protocol_connect(OpenFileDescription& description, ShouldBlock should_block)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
|
||||
|
@ -403,7 +403,7 @@ KResult TCPSocket::protocol_connect(OpenFileDescription& description, ShouldBloc
|
|||
set_local_address(routing_decision.adapter->ipv4_address());
|
||||
|
||||
if (auto result = allocate_local_port_if_needed(); result.error_or_port.is_error())
|
||||
return result.error_or_port.error();
|
||||
return result.error_or_port.release_error();
|
||||
|
||||
m_sequence_number = get_good_random<u32>();
|
||||
m_ack_number = 0;
|
||||
|
@ -430,20 +430,20 @@ KResult TCPSocket::protocol_connect(OpenFileDescription& description, ShouldBloc
|
|||
else
|
||||
return set_so_error(ECONNREFUSED);
|
||||
}
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
return set_so_error(EINPROGRESS);
|
||||
}
|
||||
|
||||
KResultOr<u16> TCPSocket::protocol_allocate_local_port()
|
||||
ErrorOr<u16> TCPSocket::protocol_allocate_local_port()
|
||||
{
|
||||
constexpr u16 first_ephemeral_port = 32768;
|
||||
constexpr u16 last_ephemeral_port = 60999;
|
||||
constexpr u16 ephemeral_port_range_size = last_ephemeral_port - first_ephemeral_port;
|
||||
u16 first_scan_port = first_ephemeral_port + get_good_random<u16>() % ephemeral_port_range_size;
|
||||
|
||||
return sockets_by_tuple().with_exclusive([&](auto& table) -> KResultOr<u16> {
|
||||
return sockets_by_tuple().with_exclusive([&](auto& table) -> ErrorOr<u16> {
|
||||
for (u16 port = first_scan_port;;) {
|
||||
IPv4SocketTuple proposed_tuple(local_address(), port, peer_address(), peer_port());
|
||||
|
||||
|
@ -490,7 +490,7 @@ void TCPSocket::shut_down_for_writing()
|
|||
}
|
||||
}
|
||||
|
||||
KResult TCPSocket::close()
|
||||
ErrorOr<void> TCPSocket::close()
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
auto result = IPv4Socket::close();
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/SinglyLinkedList.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <Kernel/API/KResult.h>
|
||||
#include <Kernel/Locking/MutexProtected.h>
|
||||
#include <Kernel/Net/IPv4Socket.h>
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace Kernel {
|
|||
class TCPSocket final : public IPv4Socket {
|
||||
public:
|
||||
static void for_each(Function<void(const TCPSocket&)>);
|
||||
static KResultOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
||||
static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
||||
virtual ~TCPSocket() override;
|
||||
|
||||
enum class Direction {
|
||||
|
@ -136,8 +136,8 @@ public:
|
|||
void set_duplicate_acks(u32 acks) { m_duplicate_acks = acks; }
|
||||
u32 duplicate_acks() const { return m_duplicate_acks; }
|
||||
|
||||
KResult send_ack(bool allow_duplicate = false);
|
||||
KResult send_tcp_packet(u16 flags, const UserOrKernelBuffer* = nullptr, size_t = 0, RoutingDecision* = nullptr);
|
||||
ErrorOr<void> send_ack(bool allow_duplicate = false);
|
||||
ErrorOr<void> send_tcp_packet(u16 flags, const UserOrKernelBuffer* = nullptr, size_t = 0, RoutingDecision* = nullptr);
|
||||
void receive_tcp_packet(const TCPPacket&, u16 size);
|
||||
|
||||
bool should_delay_next_ack() const;
|
||||
|
@ -147,7 +147,7 @@ public:
|
|||
|
||||
static MutexProtected<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>& closing_sockets();
|
||||
|
||||
KResultOr<NonnullRefPtr<TCPSocket>> try_create_client(IPv4Address const& local_address, u16 local_port, IPv4Address const& peer_address, u16 peer_port);
|
||||
ErrorOr<NonnullRefPtr<TCPSocket>> try_create_client(IPv4Address const& local_address, u16 local_port, IPv4Address const& peer_address, u16 peer_port);
|
||||
void set_originator(TCPSocket& originator) { m_originator = originator; }
|
||||
bool has_originator() { return !!m_originator; }
|
||||
void release_to_originator();
|
||||
|
@ -155,7 +155,7 @@ public:
|
|||
|
||||
void retransmit_packets();
|
||||
|
||||
virtual KResult close() override;
|
||||
virtual ErrorOr<void> close() override;
|
||||
|
||||
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
||||
|
||||
|
@ -170,13 +170,13 @@ private:
|
|||
|
||||
virtual void shut_down_for_writing() override;
|
||||
|
||||
virtual KResultOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
|
||||
virtual KResultOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) override;
|
||||
virtual KResult protocol_connect(OpenFileDescription&, ShouldBlock) override;
|
||||
virtual KResultOr<u16> protocol_allocate_local_port() override;
|
||||
virtual ErrorOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
|
||||
virtual ErrorOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) override;
|
||||
virtual ErrorOr<void> protocol_connect(OpenFileDescription&, ShouldBlock) override;
|
||||
virtual ErrorOr<u16> protocol_allocate_local_port() override;
|
||||
virtual bool protocol_is_disconnected() const override;
|
||||
virtual KResult protocol_bind() override;
|
||||
virtual KResult protocol_listen(bool did_allocate_port) override;
|
||||
virtual ErrorOr<void> protocol_bind() override;
|
||||
virtual ErrorOr<void> protocol_listen(bool did_allocate_port) override;
|
||||
|
||||
void enqueue_for_retransmit();
|
||||
void dequeue_for_retransmit();
|
||||
|
|
|
@ -54,12 +54,12 @@ UDPSocket::~UDPSocket()
|
|||
});
|
||||
}
|
||||
|
||||
KResultOr<NonnullRefPtr<UDPSocket>> UDPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer)
|
||||
ErrorOr<NonnullRefPtr<UDPSocket>> UDPSocket::try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer)
|
||||
{
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) UDPSocket(protocol, move(receive_buffer)));
|
||||
}
|
||||
|
||||
KResultOr<size_t> UDPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, [[maybe_unused]] int flags)
|
||||
ErrorOr<size_t> UDPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, [[maybe_unused]] int flags)
|
||||
{
|
||||
auto& ipv4_packet = *(const IPv4Packet*)(raw_ipv4_packet.data());
|
||||
auto& udp_packet = *static_cast<const UDPPacket*>(ipv4_packet.payload());
|
||||
|
@ -69,7 +69,7 @@ KResultOr<size_t> UDPSocket::protocol_receive(ReadonlyBytes raw_ipv4_packet, Use
|
|||
return read_size;
|
||||
}
|
||||
|
||||
KResultOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_t data_length)
|
||||
ErrorOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_t data_length)
|
||||
{
|
||||
auto routing_decision = route_to(peer_address(), local_address(), bound_interface());
|
||||
if (routing_decision.is_zero())
|
||||
|
@ -92,21 +92,21 @@ KResultOr<size_t> UDPSocket::protocol_send(const UserOrKernelBuffer& data, size_
|
|||
return data_length;
|
||||
}
|
||||
|
||||
KResult UDPSocket::protocol_connect(OpenFileDescription&, ShouldBlock)
|
||||
ErrorOr<void> UDPSocket::protocol_connect(OpenFileDescription&, ShouldBlock)
|
||||
{
|
||||
set_role(Role::Connected);
|
||||
set_connected(true);
|
||||
return KSuccess;
|
||||
return {};
|
||||
}
|
||||
|
||||
KResultOr<u16> UDPSocket::protocol_allocate_local_port()
|
||||
ErrorOr<u16> UDPSocket::protocol_allocate_local_port()
|
||||
{
|
||||
constexpr u16 first_ephemeral_port = 32768;
|
||||
constexpr u16 last_ephemeral_port = 60999;
|
||||
constexpr u16 ephemeral_port_range_size = last_ephemeral_port - first_ephemeral_port;
|
||||
u16 first_scan_port = first_ephemeral_port + get_good_random<u16>() % ephemeral_port_range_size;
|
||||
|
||||
return sockets_by_port().with_exclusive([&](auto& table) -> KResultOr<u16> {
|
||||
return sockets_by_port().with_exclusive([&](auto& table) -> ErrorOr<u16> {
|
||||
for (u16 port = first_scan_port;;) {
|
||||
auto it = table.find(port);
|
||||
if (it == table.end()) {
|
||||
|
@ -124,13 +124,13 @@ KResultOr<u16> UDPSocket::protocol_allocate_local_port()
|
|||
});
|
||||
}
|
||||
|
||||
KResult UDPSocket::protocol_bind()
|
||||
ErrorOr<void> UDPSocket::protocol_bind()
|
||||
{
|
||||
return sockets_by_port().with_exclusive([&](auto& table) -> KResult {
|
||||
return sockets_by_port().with_exclusive([&](auto& table) -> ErrorOr<void> {
|
||||
if (table.contains(local_port()))
|
||||
return set_so_error(EADDRINUSE);
|
||||
table.set(local_port(), this);
|
||||
return KSuccess;
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/API/KResult.h>
|
||||
#include <AK/Error.h>
|
||||
#include <Kernel/Locking/MutexProtected.h>
|
||||
#include <Kernel/Net/IPv4Socket.h>
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace Kernel {
|
|||
|
||||
class UDPSocket final : public IPv4Socket {
|
||||
public:
|
||||
static KResultOr<NonnullRefPtr<UDPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
||||
static ErrorOr<NonnullRefPtr<UDPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
|
||||
virtual ~UDPSocket() override;
|
||||
|
||||
static SocketHandle<UDPSocket> from_port(u16);
|
||||
|
@ -25,11 +25,11 @@ private:
|
|||
virtual StringView class_name() const override { return "UDPSocket"sv; }
|
||||
static MutexProtected<HashMap<u16, UDPSocket*>>& sockets_by_port();
|
||||
|
||||
virtual KResultOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
|
||||
virtual KResultOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) override;
|
||||
virtual KResult protocol_connect(OpenFileDescription&, ShouldBlock) override;
|
||||
virtual KResultOr<u16> protocol_allocate_local_port() override;
|
||||
virtual KResult protocol_bind() override;
|
||||
virtual ErrorOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
|
||||
virtual ErrorOr<size_t> protocol_send(const UserOrKernelBuffer&, size_t) override;
|
||||
virtual ErrorOr<void> protocol_connect(OpenFileDescription&, ShouldBlock) override;
|
||||
virtual ErrorOr<u16> protocol_allocate_local_port() override;
|
||||
virtual ErrorOr<void> protocol_bind() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue