LibCore: Move Stream-based sockets into the Core namespace

This commit is contained in:
Tim Schumacher 2023-02-08 23:05:44 +01:00 committed by Linus Groh
parent d43a7eae54
commit a96339b72b
Notes: sideshowbarker 2024-07-17 07:25:39 +09:00
123 changed files with 1157 additions and 1100 deletions

View file

@ -94,7 +94,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto webcontent_socket = TRY(Core::take_over_socket_from_system_server("WebContent"sv));
auto webcontent_client = TRY(WebContent::ConnectionFromClient::try_create(move(webcontent_socket)));
webcontent_client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(webcontent_fd_passing_socket)));
webcontent_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(webcontent_fd_passing_socket)));
QSocketNotifier webcontent_notifier(QSocketNotifier::Type::Read);
proxy_socket_through_notifier(*webcontent_client, webcontent_notifier);

View file

@ -600,11 +600,11 @@ void WebContentView::create_client()
MUST(Core::System::close(wc_fd_passing_fd));
MUST(Core::System::close(wc_fd));
auto socket = MUST(Core::Stream::LocalSocket::adopt_fd(ui_fd));
auto socket = MUST(Core::LocalSocket::adopt_fd(ui_fd));
MUST(socket->set_blocking(true));
auto new_client = MUST(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(std::move(socket), *this)));
new_client->set_fd_passing_socket(MUST(Core::Stream::LocalSocket::adopt_fd(ui_fd_passing_fd)));
new_client->set_fd_passing_socket(MUST(Core::LocalSocket::adopt_fd(ui_fd_passing_fd)));
m_web_content_notifier.setSocket(new_client->socket().fd().value());
m_web_content_notifier.setEnabled(true);

View file

@ -125,7 +125,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return;
}
auto maybe_buffered_socket = Core::Stream::BufferedTCPSocket::create(maybe_client_socket.release_value());
auto maybe_buffered_socket = Core::BufferedTCPSocket::create(maybe_client_socket.release_value());
if (maybe_buffered_socket.is_error()) {
warnln("Could not obtain a buffered socket for the client: {}", maybe_buffered_socket.error());
return;

View file

@ -338,7 +338,7 @@ public:)~~~");
static i32 static_message_id() { return (int)MessageID::@message.pascal_name@; }
virtual const char* message_name() const override { return "@endpoint.name@::@message.pascal_name@"; }
static ErrorOr<NonnullOwnPtr<@message.pascal_name@>> decode(AK::Stream& stream, Core::Stream::LocalSocket& socket)
static ErrorOr<NonnullOwnPtr<@message.pascal_name@>> decode(AK::Stream& stream, Core::LocalSocket& socket)
{
IPC::Decoder decoder { stream, socket };)~~~");
@ -584,7 +584,7 @@ public:
static u32 static_magic() { return @endpoint.magic@; }
static ErrorOr<NonnullOwnPtr<IPC::Message>> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Core::Stream::LocalSocket& socket)
static ErrorOr<NonnullOwnPtr<IPC::Message>> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Core::LocalSocket& socket)
{
FixedMemoryStream stream { buffer };
auto message_endpoint_magic = TRY(stream.read_value<u32>());)~~~");

View file

@ -9,6 +9,7 @@
#include <AK/String.h>
#include <LibCore/EventLoop.h>
#include <LibCore/LocalServer.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
#include <LibCore/TCPServer.h>
#include <LibCore/Timer.h>
@ -151,11 +152,11 @@ TEST_CASE(file_truncate)
TEST_CASE(should_error_when_connection_fails)
{
// NOTE: This is required here because Core::Stream::TCPSocket requires
// NOTE: This is required here because Core::TCPSocket requires
// Core::EventLoop through Core::Notifier.
Core::EventLoop event_loop;
auto maybe_tcp_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 1234 });
auto maybe_tcp_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 1234 });
EXPECT(maybe_tcp_socket.is_error());
EXPECT(maybe_tcp_socket.error().is_syscall());
EXPECT(maybe_tcp_socket.error().code() == ECONNREFUSED);
@ -175,7 +176,7 @@ TEST_CASE(tcp_socket_read)
EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
EXPECT(!tcp_server->set_blocking(true).is_error());
auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -211,7 +212,7 @@ TEST_CASE(tcp_socket_write)
EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
EXPECT(!tcp_server->set_blocking(true).is_error());
auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -244,7 +245,7 @@ TEST_CASE(tcp_socket_eof)
EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
EXPECT(!tcp_server->set_blocking(true).is_error());
auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -279,7 +280,7 @@ TEST_CASE(udp_socket_read_write)
auto udp_server = Core::UDPServer::construct();
EXPECT(udp_server->bind({ 127, 0, 0, 1 }, 9090));
auto maybe_client_socket = Core::Stream::UDPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
auto maybe_client_socket = Core::UDPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -328,7 +329,7 @@ TEST_CASE(local_socket_read)
auto local_server = Core::LocalServer::construct();
EXPECT(local_server->listen("/tmp/test-socket"));
local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
local_server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> server_socket) {
EXPECT(!server_socket->write(sent_data.bytes()).is_error());
event_loop.quit(0);
@ -343,7 +344,7 @@ TEST_CASE(local_socket_read)
[](auto&) {
Core::EventLoop event_loop;
auto maybe_client_socket = Core::Stream::LocalSocket::connect("/tmp/test-socket");
auto maybe_client_socket = Core::LocalSocket::connect("/tmp/test-socket");
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -377,7 +378,7 @@ TEST_CASE(local_socket_write)
auto local_server = Core::LocalServer::construct();
EXPECT(local_server->listen("/tmp/test-socket"));
local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
local_server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> server_socket) {
// NOTE: For some reason LocalServer gives us a nonblocking socket..?
MUST(server_socket->set_blocking(true));
@ -400,7 +401,7 @@ TEST_CASE(local_socket_write)
// NOTE: Same reason as in the local_socket_read test.
auto background_action = Threading::BackgroundAction<int>::construct(
[](auto&) {
auto maybe_client_socket = Core::Stream::LocalSocket::connect("/tmp/test-socket");
auto maybe_client_socket = Core::LocalSocket::connect("/tmp/test-socket");
EXPECT(!maybe_client_socket.is_error());
auto client_socket = maybe_client_socket.release_value();
@ -566,9 +567,9 @@ TEST_CASE(buffered_tcp_socket_read)
EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
EXPECT(!tcp_server->set_blocking(true).is_error());
auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
EXPECT(!maybe_client_socket.is_error());
auto maybe_buffered_socket = Core::Stream::BufferedTCPSocket::create(maybe_client_socket.release_value());
auto maybe_buffered_socket = Core::BufferedTCPSocket::create(maybe_client_socket.release_value());
EXPECT(!maybe_buffered_socket.is_error());
auto client_socket = maybe_buffered_socket.release_value();

View file

@ -31,7 +31,7 @@ class ConnectionToServer
friend class ConnectionToServerWrapper;
public:
ConnectionToServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket, DeprecatedString const& project_path)
ConnectionToServer(NonnullOwnPtr<Core::LocalSocket> socket, DeprecatedString const& project_path)
: IPC::ConnectionToServer<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket))
{
m_project_path = project_path;

View file

@ -12,22 +12,22 @@
#include <DevTools/HackStudio/LanguageServers/LanguageServerEndpoint.h>
#include <LibIPC/ConnectionToServer.h>
#define LANGUAGE_CLIENT(language_name_, socket_name) \
namespace language_name_ { \
class ConnectionToServer final : public HackStudio::ConnectionToServer { \
IPC_CLIENT_CONNECTION(ConnectionToServer, "/tmp/session/%sid/portal/language/" socket_name) \
public: \
static char const* language_name() \
{ \
return #language_name_; \
} \
\
private: \
ConnectionToServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket, DeprecatedString const& project_path) \
: HackStudio::ConnectionToServer(move(socket), project_path) \
{ \
} \
}; \
#define LANGUAGE_CLIENT(language_name_, socket_name) \
namespace language_name_ { \
class ConnectionToServer final : public HackStudio::ConnectionToServer { \
IPC_CLIENT_CONNECTION(ConnectionToServer, "/tmp/session/%sid/portal/language/" socket_name) \
public: \
static char const* language_name() \
{ \
return #language_name_; \
} \
\
private: \
ConnectionToServer(NonnullOwnPtr<Core::LocalSocket> socket, DeprecatedString const& project_path) \
: HackStudio::ConnectionToServer(move(socket), project_path) \
{ \
} \
}; \
}
namespace LanguageClients {

View file

@ -14,7 +14,7 @@ namespace LanguageServers {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket), 1)
{
s_connections.set(1, *this);

View file

@ -21,7 +21,7 @@ namespace LanguageServers {
class ConnectionFromClient : public IPC::ConnectionFromClient<LanguageClientEndpoint, LanguageServerEndpoint> {
public:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
~ConnectionFromClient() override = default;
virtual void die() override;

View file

@ -15,7 +15,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient
C_OBJECT(ConnectionFromClient);
private:
ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: LanguageServers::ConnectionFromClient(move(socket))
{
m_autocomplete_engine = adopt_own(*new CodeComprehension::Cpp::CppComprehensionEngine(m_filedb));

View file

@ -16,7 +16,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient
C_OBJECT(ConnectionFromClient);
private:
ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: LanguageServers::ConnectionFromClient(move(socket))
{
m_autocomplete_engine = make<CodeComprehension::Shell::ShellComprehensionEngine>(m_filedb);

View file

@ -21,7 +21,7 @@ public:
virtual ~InspectorServerClient() override = default;
private:
InspectorServerClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
InspectorServerClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<InspectorClientEndpoint, InspectorServerEndpoint>(*this, move(socket))
{
}

View file

@ -20,7 +20,7 @@
namespace Audio {
ConnectionToServer::ConnectionToServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToServer::ConnectionToServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<AudioClientEndpoint, AudioServerEndpoint>(*this, move(socket))
, m_buffer(make<AudioQueue>(MUST(AudioQueue::create())))
, m_user_queue(make<UserSampleQueue>())

View file

@ -62,7 +62,7 @@ public:
Function<void(double volume)> on_client_volume_change;
private:
ConnectionToServer(NonnullOwnPtr<Core::Stream::LocalSocket>);
ConnectionToServer(NonnullOwnPtr<Core::LocalSocket>);
virtual void main_mix_muted_state_changed(bool) override;
virtual void main_mix_volume_changed(double) override;

View file

@ -15,7 +15,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient
C_OBJECT(ConnectionFromClient);
private:
ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: LanguageServers::ConnectionFromClient(move(socket))
{
m_autocomplete_engine = make<CodeComprehension::Cpp::CppComprehensionEngine>(m_filedb);

View file

@ -16,7 +16,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient
C_OBJECT(ConnectionFromClient);
private:
ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: LanguageServers::ConnectionFromClient(move(socket))
{
m_autocomplete_engine = make<CodeComprehension::Shell::ShellComprehensionEngine>(m_filedb);

View file

@ -42,7 +42,7 @@ public:
static Client& the();
private:
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
explicit Client(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(socket))
{
}

View file

@ -22,6 +22,7 @@ set(SOURCES
Property.cpp
SecretString.cpp
SessionManagement.cpp
Socket.cpp
SOCKSProxyClient.cpp
StandardPaths.cpp
Stream.cpp

View file

@ -23,6 +23,7 @@
#include <LibCore/Notifier.h>
#include <LibCore/Object.h>
#include <LibCore/SessionManagement.h>
#include <LibCore/Socket.h>
#include <LibThreading/Mutex.h>
#include <LibThreading/MutexProtected.h>
#include <errno.h>
@ -156,7 +157,7 @@ pid_t EventLoop::s_pid;
class InspectorServerConnection : public Object {
C_OBJECT(InspectorServerConnection)
private:
explicit InspectorServerConnection(NonnullOwnPtr<Stream::LocalSocket> socket)
explicit InspectorServerConnection(NonnullOwnPtr<LocalSocket> socket)
: m_socket(move(socket))
, m_client_id(s_id_allocator.with_locked([](auto& allocator) {
return allocator->allocate();
@ -305,7 +306,7 @@ public:
}
private:
NonnullOwnPtr<Stream::LocalSocket> m_socket;
NonnullOwnPtr<LocalSocket> m_socket;
WeakPtr<Object> m_inspected_object;
int m_client_id { -1 };
};
@ -370,7 +371,7 @@ bool connect_to_inspector_server()
return false;
}
auto inspector_server_path = maybe_path.value();
auto maybe_socket = Stream::LocalSocket::connect(inspector_server_path, Stream::PreventSIGPIPE::Yes);
auto maybe_socket = LocalSocket::connect(inspector_server_path, Socket::PreventSIGPIPE::Yes);
if (maybe_socket.is_error()) {
dbgln("connect_to_inspector_server: Failed to connect: {}", maybe_socket.error());
return false;

View file

@ -10,6 +10,7 @@ namespace Core {
class AnonymousBuffer;
class ArgsParser;
class BufferedSocketBase;
class ChildEvent;
class ConfigFile;
class CustomEvent;
@ -22,6 +23,7 @@ class Event;
class EventLoop;
class IODevice;
class LocalServer;
class LocalSocket;
class MimeData;
class NetworkJob;
class NetworkResponse;
@ -29,18 +31,19 @@ class Notifier;
class Object;
class ObjectClassRegistration;
class ProcessStatisticsReader;
class Socket;
class SocketAddress;
class TCPServer;
class TCPSocket;
class Timer;
class TimerEvent;
class UDPServer;
class UDPSocket;
enum class TimerShouldFireWhenNotVisible;
namespace Stream {
class File;
class Socket;
class BufferedSocketBase;
}
}

View file

@ -7,6 +7,7 @@
#include <LibCore/LocalServer.h>
#include <LibCore/Notifier.h>
#include <LibCore/SessionManagement.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
#include <LibCore/System.h>
#include <LibCore/SystemServerTakeover.h>
@ -113,7 +114,7 @@ bool LocalServer::listen(DeprecatedString const& address)
return true;
}
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> LocalServer::accept()
ErrorOr<NonnullOwnPtr<LocalSocket>> LocalServer::accept()
{
VERIFY(m_listening);
sockaddr_un un;
@ -133,7 +134,7 @@ ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> LocalServer::accept()
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
#endif
return Stream::LocalSocket::adopt_fd(accepted_fd, Stream::PreventSIGPIPE::Yes);
return LocalSocket::adopt_fd(accepted_fd, Socket::PreventSIGPIPE::Yes);
}
}

View file

@ -21,9 +21,9 @@ public:
bool is_listening() const { return m_listening; }
bool listen(DeprecatedString const& address);
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> accept();
ErrorOr<NonnullOwnPtr<LocalSocket>> accept();
Function<void(NonnullOwnPtr<Stream::LocalSocket>)> on_accept;
Function<void(NonnullOwnPtr<LocalSocket>)> on_accept;
Function<void(Error)> on_accept_error;
private:

View file

@ -16,7 +16,7 @@ NetworkJob::NetworkJob(AK::Stream& output_stream)
{
}
void NetworkJob::start(Core::Stream::Socket&)
void NetworkJob::start(Core::Socket&)
{
}

View file

@ -41,7 +41,7 @@ public:
DetachFromSocket,
CloseSocket,
};
virtual void start(Core::Stream::Socket&) = 0;
virtual void start(Core::Socket&) = 0;
virtual void shutdown(ShutdownMode) = 0;
virtual void fail(Error error) { did_fail(error); }

View file

@ -95,7 +95,7 @@ StringView reply_response_name(Reply reply)
VERIFY_NOT_REACHED();
}
ErrorOr<void> send_version_identifier_and_method_selection_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::Version version, Method method)
ErrorOr<void> send_version_identifier_and_method_selection_message(Core::Socket& socket, Core::SOCKSProxyClient::Version version, Method method)
{
Socks5VersionIdentifierAndMethodSelectionMessage message {
.version_identifier = to_underlying(version),
@ -120,7 +120,7 @@ ErrorOr<void> send_version_identifier_and_method_selection_message(Core::Stream:
return {};
}
ErrorOr<Reply> send_connect_request_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::Version version, Core::SOCKSProxyClient::HostOrIPV4 target, int port, Core::SOCKSProxyClient::Command command)
ErrorOr<Reply> send_connect_request_message(Core::Socket& socket, Core::SOCKSProxyClient::Version version, Core::SOCKSProxyClient::HostOrIPV4 target, int port, Core::SOCKSProxyClient::Command command)
{
AllocatingMemoryStream stream;
@ -216,7 +216,7 @@ ErrorOr<Reply> send_connect_request_message(Core::Stream::Socket& socket, Core::
return Reply(response_header.status);
}
ErrorOr<u8> send_username_password_authentication_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::UsernamePasswordAuthenticationData const& auth_data)
ErrorOr<u8> send_username_password_authentication_message(Core::Socket& socket, Core::SOCKSProxyClient::UsernamePasswordAuthenticationData const& auth_data)
{
AllocatingMemoryStream stream;
@ -314,10 +314,10 @@ ErrorOr<NonnullOwnPtr<SOCKSProxyClient>> SOCKSProxyClient::connect(HostOrIPV4 co
{
auto underlying = TRY(server.visit(
[&](u32 ipv4) {
return Core::Stream::TCPSocket::connect({ IPv4Address(ipv4), static_cast<u16>(server_port) });
return Core::TCPSocket::connect({ IPv4Address(ipv4), static_cast<u16>(server_port) });
},
[&](DeprecatedString const& hostname) {
return Core::Stream::TCPSocket::connect(hostname, static_cast<u16>(server_port));
return Core::TCPSocket::connect(hostname, static_cast<u16>(server_port));
}));
auto socket = TRY(connect(*underlying, version, target, target_port, auth_data, command));

View file

@ -8,10 +8,11 @@
#include <AK/OwnPtr.h>
#include <LibCore/Proxy.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
namespace Core {
class SOCKSProxyClient final : public Stream::Socket {
class SOCKSProxyClient final : public Socket {
public:
enum class Version : u8 {
V4 = 0x04,

View file

@ -0,0 +1,410 @@
/*
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCore/Socket.h>
#include <LibCore/System.h>
namespace Core {
ErrorOr<int> Socket::create_fd(SocketDomain domain, SocketType type)
{
int socket_domain;
switch (domain) {
case SocketDomain::Inet:
socket_domain = AF_INET;
break;
case SocketDomain::Local:
socket_domain = AF_LOCAL;
break;
default:
VERIFY_NOT_REACHED();
}
int socket_type;
switch (type) {
case SocketType::Stream:
socket_type = SOCK_STREAM;
break;
case SocketType::Datagram:
socket_type = SOCK_DGRAM;
break;
default:
VERIFY_NOT_REACHED();
}
// Let's have a safe default of CLOEXEC. :^)
#ifdef SOCK_CLOEXEC
return System::socket(socket_domain, socket_type | SOCK_CLOEXEC, 0);
#else
auto fd = TRY(System::socket(socket_domain, socket_type, 0));
TRY(System::fcntl(fd, F_SETFD, FD_CLOEXEC));
return fd;
#endif
}
ErrorOr<IPv4Address> Socket::resolve_host(DeprecatedString const& host, SocketType type)
{
int socket_type;
switch (type) {
case SocketType::Stream:
socket_type = SOCK_STREAM;
break;
case SocketType::Datagram:
socket_type = SOCK_DGRAM;
break;
default:
VERIFY_NOT_REACHED();
}
struct addrinfo hints = {};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = socket_type;
hints.ai_flags = 0;
hints.ai_protocol = 0;
auto const results = TRY(Core::System::getaddrinfo(host.characters(), nullptr, hints));
for (auto const& result : results.addresses()) {
if (result.ai_family == AF_INET) {
auto* socket_address = bit_cast<struct sockaddr_in*>(result.ai_addr);
NetworkOrdered<u32> const network_ordered_address { socket_address->sin_addr.s_addr };
return IPv4Address { network_ordered_address };
}
}
return Error::from_string_literal("Could not resolve to IPv4 address");
}
ErrorOr<void> Socket::connect_local(int fd, DeprecatedString const& path)
{
auto address = SocketAddress::local(path);
auto maybe_sockaddr = address.to_sockaddr_un();
if (!maybe_sockaddr.has_value()) {
dbgln("Core::Socket::connect_local: Could not obtain a sockaddr_un");
return Error::from_errno(EINVAL);
}
auto addr = maybe_sockaddr.release_value();
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
}
ErrorOr<void> Socket::connect_inet(int fd, SocketAddress const& address)
{
auto addr = address.to_sockaddr_in();
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
}
ErrorOr<Bytes> PosixSocketHelper::read(Bytes buffer, int flags)
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
ssize_t nread = TRY(System::recv(m_fd, buffer.data(), buffer.size(), flags));
m_last_read_was_eof = nread == 0;
// If a socket read is EOF, then no more data can be read from it because
// the protocol has disconnected. In this case, we can just disable the
// notifier if we have one.
if (m_last_read_was_eof && m_notifier)
m_notifier->set_enabled(false);
return buffer.trim(nread);
}
ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer, int flags)
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
return TRY(System::send(m_fd, buffer.data(), buffer.size(), flags));
}
void PosixSocketHelper::close()
{
if (!is_open()) {
return;
}
if (m_notifier)
m_notifier->set_enabled(false);
ErrorOr<void> result;
do {
result = System::close(m_fd);
} while (result.is_error() && result.error().code() == EINTR);
VERIFY(!result.is_error());
m_fd = -1;
}
ErrorOr<bool> PosixSocketHelper::can_read_without_blocking(int timeout) const
{
struct pollfd the_fd = { .fd = m_fd, .events = POLLIN, .revents = 0 };
ErrorOr<int> result { 0 };
do {
result = Core::System::poll({ &the_fd, 1 }, timeout);
} while (result.is_error() && result.error().code() == EINTR);
if (result.is_error())
return result.release_error();
return (the_fd.revents & POLLIN) > 0;
}
ErrorOr<void> PosixSocketHelper::set_blocking(bool enabled)
{
int value = enabled ? 0 : 1;
return System::ioctl(m_fd, FIONBIO, &value);
}
ErrorOr<void> PosixSocketHelper::set_close_on_exec(bool enabled)
{
int flags = TRY(System::fcntl(m_fd, F_GETFD));
if (enabled)
flags |= FD_CLOEXEC;
else
flags &= ~FD_CLOEXEC;
TRY(System::fcntl(m_fd, F_SETFD, flags));
return {};
}
ErrorOr<void> PosixSocketHelper::set_receive_timeout(Time timeout)
{
auto timeout_spec = timeout.to_timespec();
return System::setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout_spec, sizeof(timeout_spec));
}
void PosixSocketHelper::setup_notifier()
{
if (!m_notifier)
m_notifier = Core::Notifier::construct(m_fd, Core::Notifier::Read);
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::connect(DeprecatedString const& host, u16 port)
{
auto ip_address = TRY(resolve_host(host, SocketType::Stream));
return connect(SocketAddress { ip_address, port });
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::connect(SocketAddress const& address)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) TCPSocket()));
auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Stream));
socket->m_helper.set_fd(fd);
TRY(connect_inet(fd, address));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::adopt_fd(int fd)
{
if (fd < 0) {
return Error::from_errno(EBADF);
}
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) TCPSocket()));
socket->m_helper.set_fd(fd);
socket->setup_notifier();
return socket;
}
ErrorOr<size_t> PosixSocketHelper::pending_bytes() const
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
int value;
TRY(System::ioctl(m_fd, FIONREAD, &value));
return static_cast<size_t>(value);
}
ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(DeprecatedString const& host, u16 port, Optional<Time> timeout)
{
auto ip_address = TRY(resolve_host(host, SocketType::Datagram));
return connect(SocketAddress { ip_address, port }, timeout);
}
ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(SocketAddress const& address, Optional<Time> timeout)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) UDPSocket()));
auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Datagram));
socket->m_helper.set_fd(fd);
if (timeout.has_value()) {
TRY(socket->m_helper.set_receive_timeout(timeout.value()));
}
TRY(connect_inet(fd, address));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<LocalSocket>> LocalSocket::connect(DeprecatedString const& path, PreventSIGPIPE prevent_sigpipe)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LocalSocket(prevent_sigpipe)));
auto fd = TRY(create_fd(SocketDomain::Local, SocketType::Stream));
socket->m_helper.set_fd(fd);
TRY(connect_local(fd, path));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<LocalSocket>> LocalSocket::adopt_fd(int fd, PreventSIGPIPE prevent_sigpipe)
{
if (fd < 0) {
return Error::from_errno(EBADF);
}
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LocalSocket(prevent_sigpipe)));
socket->m_helper.set_fd(fd);
socket->setup_notifier();
return socket;
}
ErrorOr<int> LocalSocket::receive_fd(int flags)
{
#if defined(AK_OS_SERENITY)
return Core::System::recvfd(m_helper.fd(), flags);
#elif defined(AK_OS_LINUX) || defined(AK_OS_MACOS) || defined(AK_OS_FREEBSD) || defined(AK_OS_OPENBSD)
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof(int))];
} cmsgu {};
char c = 0;
struct iovec iov {
.iov_base = &c,
.iov_len = 1,
};
struct msghdr msg = {};
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
TRY(Core::System::recvmsg(m_helper.fd(), &msg, 0));
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg || cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
return Error::from_string_literal("Malformed message when receiving file descriptor");
VERIFY(cmsg->cmsg_level == SOL_SOCKET);
VERIFY(cmsg->cmsg_type == SCM_RIGHTS);
int fd = *((int*)CMSG_DATA(cmsg));
if (flags & O_CLOEXEC) {
auto fd_flags = TRY(Core::System::fcntl(fd, F_GETFD));
TRY(Core::System::fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC));
}
return fd;
#else
(void)flags;
return Error::from_string_literal("File descriptor passing not supported on this platform");
#endif
}
ErrorOr<void> LocalSocket::send_fd(int fd)
{
#if defined(AK_OS_SERENITY)
return Core::System::sendfd(m_helper.fd(), fd);
#elif defined(AK_OS_LINUX) || defined(AK_OS_MACOS) || defined(AK_OS_FREEBSD) || defined(AK_OS_OPENBSD)
char c = 'F';
struct iovec iov {
.iov_base = &c,
.iov_len = sizeof(c)
};
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof(int))];
} cmsgu {};
struct msghdr msg = {};
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*((int*)CMSG_DATA(cmsg)) = fd;
TRY(Core::System::sendmsg(m_helper.fd(), &msg, 0));
return {};
#else
(void)fd;
return Error::from_string_literal("File descriptor passing not supported on this platform");
#endif
}
ErrorOr<pid_t> LocalSocket::peer_pid() const
{
#ifdef AK_OS_MACOS
pid_t pid;
socklen_t pid_size = sizeof(pid);
#elif defined(AK_OS_FREEBSD)
struct xucred creds = {};
socklen_t creds_size = sizeof(creds);
#elif defined(AK_OS_OPENBSD)
struct sockpeercred creds = {};
socklen_t creds_size = sizeof(creds);
#else
struct ucred creds = {};
socklen_t creds_size = sizeof(creds);
#endif
#ifdef AK_OS_MACOS
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERPID, &pid, &pid_size));
return pid;
#elif defined(AK_OS_FREEBSD)
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERCRED, &creds, &creds_size));
return creds.cr_pid;
#else
TRY(System::getsockopt(m_helper.fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size));
return creds.pid;
#endif
}
ErrorOr<Bytes> LocalSocket::read_without_waiting(Bytes buffer)
{
return m_helper.read(buffer, MSG_DONTWAIT);
}
Optional<int> LocalSocket::fd() const
{
if (!is_open())
return {};
return m_helper.fd();
}
ErrorOr<int> LocalSocket::release_fd()
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
auto fd = m_helper.fd();
m_helper.set_fd(-1);
return fd;
}
}

View file

@ -0,0 +1,508 @@
/*
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
* Copyright (c) 2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/BufferedStream.h>
#include <AK/Function.h>
#include <AK/Stream.h>
#include <AK/Time.h>
#include <LibCore/Notifier.h>
#include <LibCore/SocketAddress.h>
namespace Core {
/// The Socket class is the base class for all concrete BSD-style socket
/// classes. Sockets are non-seekable streams which can be read byte-wise.
class Socket : public AK::Stream {
public:
Socket(Socket&&) = default;
Socket& operator=(Socket&&) = default;
/// Checks how many bytes of data are currently available to read on the
/// socket. For datagram-based socket, this is the size of the first
/// datagram that can be read. Returns either the amount of bytes, or an
/// errno in the case of failure.
virtual ErrorOr<size_t> pending_bytes() const = 0;
/// Returns whether there's any data that can be immediately read, or an
/// errno on failure.
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const = 0;
// Sets the blocking mode of the socket. If blocking mode is disabled, reads
// will fail with EAGAIN when there's no data available to read, and writes
// will fail with EAGAIN when the data cannot be written without blocking
// (due to the send buffer being full, for example).
virtual ErrorOr<void> set_blocking(bool enabled) = 0;
// Sets the close-on-exec mode of the socket. If close-on-exec mode is
// enabled, then the socket will be automatically closed by the kernel when
// an exec call happens.
virtual ErrorOr<void> set_close_on_exec(bool enabled) = 0;
/// Disables any listening mechanisms that this socket uses.
/// Can be called with 'false' when `on_ready_to_read` notifications are no longer needed.
/// Conversely, set_notifications_enabled(true) will re-enable notifications.
virtual void set_notifications_enabled(bool) { }
Function<void()> on_ready_to_read;
enum class PreventSIGPIPE {
No,
Yes,
};
protected:
enum class SocketDomain {
Local,
Inet,
};
enum class SocketType {
Stream,
Datagram,
};
Socket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: m_prevent_sigpipe(prevent_sigpipe == PreventSIGPIPE::Yes)
{
}
static ErrorOr<int> create_fd(SocketDomain, SocketType);
// FIXME: This will need to be updated when IPv6 socket arrives. Perhaps a
// base class for all address types is appropriate.
static ErrorOr<IPv4Address> resolve_host(DeprecatedString const&, SocketType);
static ErrorOr<void> connect_local(int fd, DeprecatedString const& path);
static ErrorOr<void> connect_inet(int fd, SocketAddress const&);
int default_flags() const
{
int flags = 0;
if (m_prevent_sigpipe)
flags |= MSG_NOSIGNAL;
return flags;
}
private:
bool m_prevent_sigpipe { false };
};
/// A reusable socket maintains state about being connected in addition to
/// normal Socket capabilities, and can be reconnected once disconnected.
class ReusableSocket : public Socket {
public:
/// Returns whether the socket is currently connected.
virtual bool is_connected() = 0;
/// Reconnects the socket to the given host and port. Returns EALREADY if
/// is_connected() is true.
virtual ErrorOr<void> reconnect(DeprecatedString const& host, u16 port) = 0;
/// Connects the socket to the given socket address (IP address + port).
/// Returns EALREADY is_connected() is true.
virtual ErrorOr<void> reconnect(SocketAddress const&) = 0;
};
class PosixSocketHelper {
AK_MAKE_NONCOPYABLE(PosixSocketHelper);
public:
template<typename T>
PosixSocketHelper(Badge<T>)
requires(IsBaseOf<Socket, T>)
{
}
PosixSocketHelper(PosixSocketHelper&& other)
{
operator=(move(other));
}
PosixSocketHelper& operator=(PosixSocketHelper&& other)
{
m_fd = exchange(other.m_fd, -1);
m_last_read_was_eof = exchange(other.m_last_read_was_eof, false);
m_notifier = move(other.m_notifier);
return *this;
}
int fd() const { return m_fd; }
void set_fd(int fd) { m_fd = fd; }
ErrorOr<Bytes> read(Bytes, int flags);
ErrorOr<size_t> write(ReadonlyBytes, int flags);
bool is_eof() const { return !is_open() || m_last_read_was_eof; }
bool is_open() const { return m_fd != -1; }
void close();
ErrorOr<size_t> pending_bytes() const;
ErrorOr<bool> can_read_without_blocking(int timeout) const;
ErrorOr<void> set_blocking(bool enabled);
ErrorOr<void> set_close_on_exec(bool enabled);
ErrorOr<void> set_receive_timeout(Time timeout);
void setup_notifier();
RefPtr<Core::Notifier> notifier() { return m_notifier; }
private:
int m_fd { -1 };
bool m_last_read_was_eof { false };
RefPtr<Core::Notifier> m_notifier;
};
class TCPSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<TCPSocket>> connect(DeprecatedString const& host, u16 port);
static ErrorOr<NonnullOwnPtr<TCPSocket>> connect(SocketAddress const& address);
static ErrorOr<NonnullOwnPtr<TCPSocket>> adopt_fd(int fd);
TCPSocket(TCPSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
TCPSocket& operator=(TCPSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer, default_flags()); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); };
virtual void close() override { m_helper.close(); };
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual ~TCPSocket() override { close(); }
private:
TCPSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<TCPSocket> {} };
};
class UDPSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(DeprecatedString const& host, u16 port, Optional<Time> timeout = {});
static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(SocketAddress const& address, Optional<Time> timeout = {});
UDPSocket(UDPSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
UDPSocket& operator=(UDPSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override
{
auto pending_bytes = TRY(this->pending_bytes());
if (pending_bytes > buffer.size()) {
// With UDP datagrams, reading a datagram into a buffer that's
// smaller than the datagram's size will cause the rest of the
// datagram to be discarded. That's not very nice, so let's bail
// early, telling the caller that he should allocate a bigger
// buffer.
return Error::from_errno(EMSGSIZE);
}
return m_helper.read(buffer, default_flags());
}
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); }
virtual void close() override { m_helper.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual ~UDPSocket() override { close(); }
private:
UDPSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<UDPSocket> {} };
};
class LocalSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<LocalSocket>> connect(DeprecatedString const& path, PreventSIGPIPE = PreventSIGPIPE::No);
static ErrorOr<NonnullOwnPtr<LocalSocket>> adopt_fd(int fd, PreventSIGPIPE = PreventSIGPIPE::No);
LocalSocket(LocalSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
LocalSocket& operator=(LocalSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer, default_flags()); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); }
virtual void close() override { m_helper.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<int> receive_fd(int flags);
ErrorOr<void> send_fd(int fd);
ErrorOr<pid_t> peer_pid() const;
ErrorOr<Bytes> read_without_waiting(Bytes buffer);
/// Release the fd associated with this LocalSocket. After the fd is
/// released, the socket will be considered "closed" and all operations done
/// on it will fail with ENOTCONN. Fails with ENOTCONN if the socket is
/// already closed.
ErrorOr<int> release_fd();
Optional<int> fd() const;
RefPtr<Core::Notifier> notifier() { return m_helper.notifier(); }
virtual ~LocalSocket() { close(); }
private:
LocalSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<LocalSocket> {} };
};
template<typename T>
concept SocketLike = IsBaseOf<Socket, T>;
class BufferedSocketBase : public Socket {
public:
virtual ErrorOr<StringView> read_line(Bytes buffer) = 0;
virtual ErrorOr<Bytes> read_until(Bytes buffer, StringView candidate) = 0;
virtual ErrorOr<bool> can_read_line() = 0;
virtual size_t buffer_size() const = 0;
};
template<SocketLike T>
class BufferedSocket final : public BufferedSocketBase {
friend BufferedHelper<T>;
public:
static ErrorOr<NonnullOwnPtr<BufferedSocket<T>>> create(NonnullOwnPtr<T> stream, size_t buffer_size = 16384)
{
return BufferedHelper<T>::template create_buffered<BufferedSocket>(move(stream), buffer_size);
}
BufferedSocket(BufferedSocket&& other)
: BufferedSocketBase(static_cast<BufferedSocketBase&&>(other))
, m_helper(move(other.m_helper))
{
setup_notifier();
}
BufferedSocket& operator=(BufferedSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.stream().write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.stream().is_open(); }
virtual void close() override { m_helper.stream().close(); }
virtual ErrorOr<size_t> pending_bytes() const override
{
return TRY(m_helper.stream().pending_bytes()) + m_helper.buffered_data_size();
}
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.buffered_data_size() > 0 || TRY(m_helper.stream().can_read_without_blocking(timeout)); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_helper.stream().set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.stream().set_close_on_exec(enabled); }
virtual void set_notifications_enabled(bool enabled) override { m_helper.stream().set_notifications_enabled(enabled); }
virtual ErrorOr<StringView> read_line(Bytes buffer) override { return m_helper.read_line(move(buffer)); }
virtual ErrorOr<Bytes> read_until(Bytes buffer, StringView candidate) override { return m_helper.read_until(move(buffer), move(candidate)); }
template<size_t N>
ErrorOr<Bytes> read_until_any_of(Bytes buffer, Array<StringView, N> candidates) { return m_helper.read_until_any_of(move(buffer), move(candidates)); }
virtual ErrorOr<bool> can_read_line() override { return m_helper.can_read_line(); }
virtual size_t buffer_size() const override { return m_helper.buffer_size(); }
virtual ~BufferedSocket() override = default;
private:
BufferedSocket(NonnullOwnPtr<T> stream, CircularBuffer buffer)
: m_helper(Badge<BufferedSocket<T>> {}, move(stream), move(buffer))
{
setup_notifier();
}
void setup_notifier()
{
m_helper.stream().on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
BufferedHelper<T> m_helper;
};
using BufferedTCPSocket = BufferedSocket<TCPSocket>;
using BufferedUDPSocket = BufferedSocket<UDPSocket>;
using BufferedLocalSocket = BufferedSocket<LocalSocket>;
/// A BasicReusableSocket allows one to use one of the base Core::Stream classes
/// as a ReusableSocket. It does not preserve any connection state or options,
/// and instead just recreates the stream when reconnecting.
template<SocketLike T>
class BasicReusableSocket final : public ReusableSocket {
public:
static ErrorOr<NonnullOwnPtr<BasicReusableSocket<T>>> connect(DeprecatedString const& host, u16 port)
{
return make<BasicReusableSocket<T>>(TRY(T::connect(host, port)));
}
static ErrorOr<NonnullOwnPtr<BasicReusableSocket<T>>> connect(SocketAddress const& address)
{
return make<BasicReusableSocket<T>>(TRY(T::connect(address)));
}
virtual bool is_connected() override
{
return m_socket.is_open();
}
virtual ErrorOr<void> reconnect(DeprecatedString const& host, u16 port) override
{
if (is_connected())
return Error::from_errno(EALREADY);
m_socket = TRY(T::connect(host, port));
return {};
}
virtual ErrorOr<void> reconnect(SocketAddress const& address) override
{
if (is_connected())
return Error::from_errno(EALREADY);
m_socket = TRY(T::connect(address));
return {};
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_socket.read(move(buffer)); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_socket.write(buffer); }
virtual bool is_eof() const override { return m_socket.is_eof(); }
virtual bool is_open() const override { return m_socket.is_open(); }
virtual void close() override { m_socket.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_socket.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_socket.can_read_without_blocking(timeout); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_socket.set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_socket.set_close_on_exec(enabled); }
private:
BasicReusableSocket(NonnullOwnPtr<T> socket)
: m_socket(move(socket))
{
}
NonnullOwnPtr<T> m_socket;
};
using ReusableTCPSocket = BasicReusableSocket<TCPSocket>;
using ReusableUDPSocket = BasicReusableSocket<UDPSocket>;
}

View file

@ -192,401 +192,4 @@ ErrorOr<void> File::truncate(size_t length)
return System::ftruncate(m_fd, length);
}
ErrorOr<int> Socket::create_fd(SocketDomain domain, SocketType type)
{
int socket_domain;
switch (domain) {
case SocketDomain::Inet:
socket_domain = AF_INET;
break;
case SocketDomain::Local:
socket_domain = AF_LOCAL;
break;
default:
VERIFY_NOT_REACHED();
}
int socket_type;
switch (type) {
case SocketType::Stream:
socket_type = SOCK_STREAM;
break;
case SocketType::Datagram:
socket_type = SOCK_DGRAM;
break;
default:
VERIFY_NOT_REACHED();
}
// Let's have a safe default of CLOEXEC. :^)
#ifdef SOCK_CLOEXEC
return System::socket(socket_domain, socket_type | SOCK_CLOEXEC, 0);
#else
auto fd = TRY(System::socket(socket_domain, socket_type, 0));
TRY(System::fcntl(fd, F_SETFD, FD_CLOEXEC));
return fd;
#endif
}
ErrorOr<IPv4Address> Socket::resolve_host(DeprecatedString const& host, SocketType type)
{
int socket_type;
switch (type) {
case SocketType::Stream:
socket_type = SOCK_STREAM;
break;
case SocketType::Datagram:
socket_type = SOCK_DGRAM;
break;
default:
VERIFY_NOT_REACHED();
}
struct addrinfo hints = {};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = socket_type;
hints.ai_flags = 0;
hints.ai_protocol = 0;
auto const results = TRY(Core::System::getaddrinfo(host.characters(), nullptr, hints));
for (auto const& result : results.addresses()) {
if (result.ai_family == AF_INET) {
auto* socket_address = bit_cast<struct sockaddr_in*>(result.ai_addr);
NetworkOrdered<u32> const network_ordered_address { socket_address->sin_addr.s_addr };
return IPv4Address { network_ordered_address };
}
}
return Error::from_string_literal("Could not resolve to IPv4 address");
}
ErrorOr<void> Socket::connect_local(int fd, DeprecatedString const& path)
{
auto address = SocketAddress::local(path);
auto maybe_sockaddr = address.to_sockaddr_un();
if (!maybe_sockaddr.has_value()) {
dbgln("Core::Stream::Socket::connect_local: Could not obtain a sockaddr_un");
return Error::from_errno(EINVAL);
}
auto addr = maybe_sockaddr.release_value();
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
}
ErrorOr<void> Socket::connect_inet(int fd, SocketAddress const& address)
{
auto addr = address.to_sockaddr_in();
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
}
ErrorOr<Bytes> PosixSocketHelper::read(Bytes buffer, int flags)
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
ssize_t nread = TRY(System::recv(m_fd, buffer.data(), buffer.size(), flags));
m_last_read_was_eof = nread == 0;
// If a socket read is EOF, then no more data can be read from it because
// the protocol has disconnected. In this case, we can just disable the
// notifier if we have one.
if (m_last_read_was_eof && m_notifier)
m_notifier->set_enabled(false);
return buffer.trim(nread);
}
ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer, int flags)
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
return TRY(System::send(m_fd, buffer.data(), buffer.size(), flags));
}
void PosixSocketHelper::close()
{
if (!is_open()) {
return;
}
if (m_notifier)
m_notifier->set_enabled(false);
ErrorOr<void> result;
do {
result = System::close(m_fd);
} while (result.is_error() && result.error().code() == EINTR);
VERIFY(!result.is_error());
m_fd = -1;
}
ErrorOr<bool> PosixSocketHelper::can_read_without_blocking(int timeout) const
{
struct pollfd the_fd = { .fd = m_fd, .events = POLLIN, .revents = 0 };
ErrorOr<int> result { 0 };
do {
result = Core::System::poll({ &the_fd, 1 }, timeout);
} while (result.is_error() && result.error().code() == EINTR);
if (result.is_error())
return result.release_error();
return (the_fd.revents & POLLIN) > 0;
}
ErrorOr<void> PosixSocketHelper::set_blocking(bool enabled)
{
int value = enabled ? 0 : 1;
return System::ioctl(m_fd, FIONBIO, &value);
}
ErrorOr<void> PosixSocketHelper::set_close_on_exec(bool enabled)
{
int flags = TRY(System::fcntl(m_fd, F_GETFD));
if (enabled)
flags |= FD_CLOEXEC;
else
flags &= ~FD_CLOEXEC;
TRY(System::fcntl(m_fd, F_SETFD, flags));
return {};
}
ErrorOr<void> PosixSocketHelper::set_receive_timeout(Time timeout)
{
auto timeout_spec = timeout.to_timespec();
return System::setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout_spec, sizeof(timeout_spec));
}
void PosixSocketHelper::setup_notifier()
{
if (!m_notifier)
m_notifier = Core::Notifier::construct(m_fd, Core::Notifier::Read);
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::connect(DeprecatedString const& host, u16 port)
{
auto ip_address = TRY(resolve_host(host, SocketType::Stream));
return connect(SocketAddress { ip_address, port });
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::connect(SocketAddress const& address)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) TCPSocket()));
auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Stream));
socket->m_helper.set_fd(fd);
TRY(connect_inet(fd, address));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPSocket::adopt_fd(int fd)
{
if (fd < 0) {
return Error::from_errno(EBADF);
}
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) TCPSocket()));
socket->m_helper.set_fd(fd);
socket->setup_notifier();
return socket;
}
ErrorOr<size_t> PosixSocketHelper::pending_bytes() const
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
int value;
TRY(System::ioctl(m_fd, FIONREAD, &value));
return static_cast<size_t>(value);
}
ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(DeprecatedString const& host, u16 port, Optional<Time> timeout)
{
auto ip_address = TRY(resolve_host(host, SocketType::Datagram));
return connect(SocketAddress { ip_address, port }, timeout);
}
ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(SocketAddress const& address, Optional<Time> timeout)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) UDPSocket()));
auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Datagram));
socket->m_helper.set_fd(fd);
if (timeout.has_value()) {
TRY(socket->m_helper.set_receive_timeout(timeout.value()));
}
TRY(connect_inet(fd, address));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<LocalSocket>> LocalSocket::connect(DeprecatedString const& path, PreventSIGPIPE prevent_sigpipe)
{
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LocalSocket(prevent_sigpipe)));
auto fd = TRY(create_fd(SocketDomain::Local, SocketType::Stream));
socket->m_helper.set_fd(fd);
TRY(connect_local(fd, path));
socket->setup_notifier();
return socket;
}
ErrorOr<NonnullOwnPtr<LocalSocket>> LocalSocket::adopt_fd(int fd, PreventSIGPIPE prevent_sigpipe)
{
if (fd < 0) {
return Error::from_errno(EBADF);
}
auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) LocalSocket(prevent_sigpipe)));
socket->m_helper.set_fd(fd);
socket->setup_notifier();
return socket;
}
ErrorOr<int> LocalSocket::receive_fd(int flags)
{
#if defined(AK_OS_SERENITY)
return Core::System::recvfd(m_helper.fd(), flags);
#elif defined(AK_OS_LINUX) || defined(AK_OS_MACOS) || defined(AK_OS_FREEBSD) || defined(AK_OS_OPENBSD)
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof(int))];
} cmsgu {};
char c = 0;
struct iovec iov {
.iov_base = &c,
.iov_len = 1,
};
struct msghdr msg = {};
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
TRY(Core::System::recvmsg(m_helper.fd(), &msg, 0));
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg || cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
return Error::from_string_literal("Malformed message when receiving file descriptor");
VERIFY(cmsg->cmsg_level == SOL_SOCKET);
VERIFY(cmsg->cmsg_type == SCM_RIGHTS);
int fd = *((int*)CMSG_DATA(cmsg));
if (flags & O_CLOEXEC) {
auto fd_flags = TRY(Core::System::fcntl(fd, F_GETFD));
TRY(Core::System::fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC));
}
return fd;
#else
(void)flags;
return Error::from_string_literal("File descriptor passing not supported on this platform");
#endif
}
ErrorOr<void> LocalSocket::send_fd(int fd)
{
#if defined(AK_OS_SERENITY)
return Core::System::sendfd(m_helper.fd(), fd);
#elif defined(AK_OS_LINUX) || defined(AK_OS_MACOS) || defined(AK_OS_FREEBSD) || defined(AK_OS_OPENBSD)
char c = 'F';
struct iovec iov {
.iov_base = &c,
.iov_len = sizeof(c)
};
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof(int))];
} cmsgu {};
struct msghdr msg = {};
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*((int*)CMSG_DATA(cmsg)) = fd;
TRY(Core::System::sendmsg(m_helper.fd(), &msg, 0));
return {};
#else
(void)fd;
return Error::from_string_literal("File descriptor passing not supported on this platform");
#endif
}
ErrorOr<pid_t> LocalSocket::peer_pid() const
{
#ifdef AK_OS_MACOS
pid_t pid;
socklen_t pid_size = sizeof(pid);
#elif defined(AK_OS_FREEBSD)
struct xucred creds = {};
socklen_t creds_size = sizeof(creds);
#elif defined(AK_OS_OPENBSD)
struct sockpeercred creds = {};
socklen_t creds_size = sizeof(creds);
#else
struct ucred creds = {};
socklen_t creds_size = sizeof(creds);
#endif
#ifdef AK_OS_MACOS
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERPID, &pid, &pid_size));
return pid;
#elif defined(AK_OS_FREEBSD)
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERCRED, &creds, &creds_size));
return creds.cr_pid;
#else
TRY(System::getsockopt(m_helper.fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size));
return creds.pid;
#endif
}
ErrorOr<Bytes> LocalSocket::read_without_waiting(Bytes buffer)
{
return m_helper.read(buffer, MSG_DONTWAIT);
}
Optional<int> LocalSocket::fd() const
{
if (!is_open())
return {};
return m_helper.fd();
}
ErrorOr<int> LocalSocket::release_fd()
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
}
auto fd = m_helper.fd();
m_helper.set_fd(-1);
return fd;
}
}

View file

@ -28,93 +28,6 @@
namespace Core::Stream {
enum class PreventSIGPIPE {
No,
Yes,
};
/// The Socket class is the base class for all concrete BSD-style socket
/// classes. Sockets are non-seekable streams which can be read byte-wise.
class Socket : public AK::Stream {
public:
Socket(Socket&&) = default;
Socket& operator=(Socket&&) = default;
/// Checks how many bytes of data are currently available to read on the
/// socket. For datagram-based socket, this is the size of the first
/// datagram that can be read. Returns either the amount of bytes, or an
/// errno in the case of failure.
virtual ErrorOr<size_t> pending_bytes() const = 0;
/// Returns whether there's any data that can be immediately read, or an
/// errno on failure.
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const = 0;
// Sets the blocking mode of the socket. If blocking mode is disabled, reads
// will fail with EAGAIN when there's no data available to read, and writes
// will fail with EAGAIN when the data cannot be written without blocking
// (due to the send buffer being full, for example).
virtual ErrorOr<void> set_blocking(bool enabled) = 0;
// Sets the close-on-exec mode of the socket. If close-on-exec mode is
// enabled, then the socket will be automatically closed by the kernel when
// an exec call happens.
virtual ErrorOr<void> set_close_on_exec(bool enabled) = 0;
/// Disables any listening mechanisms that this socket uses.
/// Can be called with 'false' when `on_ready_to_read` notifications are no longer needed.
/// Conversely, set_notifications_enabled(true) will re-enable notifications.
virtual void set_notifications_enabled(bool) { }
Function<void()> on_ready_to_read;
protected:
enum class SocketDomain {
Local,
Inet,
};
enum class SocketType {
Stream,
Datagram,
};
Socket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: m_prevent_sigpipe(prevent_sigpipe == PreventSIGPIPE::Yes)
{
}
static ErrorOr<int> create_fd(SocketDomain, SocketType);
// FIXME: This will need to be updated when IPv6 socket arrives. Perhaps a
// base class for all address types is appropriate.
static ErrorOr<IPv4Address> resolve_host(DeprecatedString const&, SocketType);
static ErrorOr<void> connect_local(int fd, DeprecatedString const& path);
static ErrorOr<void> connect_inet(int fd, SocketAddress const&);
int default_flags() const
{
int flags = 0;
if (m_prevent_sigpipe)
flags |= MSG_NOSIGNAL;
return flags;
}
private:
bool m_prevent_sigpipe { false };
};
/// A reusable socket maintains state about being connected in addition to
/// normal Socket capabilities, and can be reconnected once disconnected.
class ReusableSocket : public Socket {
public:
/// Returns whether the socket is currently connected.
virtual bool is_connected() = 0;
/// Reconnects the socket to the given host and port. Returns EALREADY if
/// is_connected() is true.
virtual ErrorOr<void> reconnect(DeprecatedString const& host, u16 port) = 0;
/// Connects the socket to the given socket address (IP address + port).
/// Returns EALREADY is_connected() is true.
virtual ErrorOr<void> reconnect(SocketAddress const&) = 0;
};
// Concrete classes.
enum class OpenMode : unsigned {
@ -204,407 +117,6 @@ private:
ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes };
};
class PosixSocketHelper {
AK_MAKE_NONCOPYABLE(PosixSocketHelper);
public:
template<typename T>
PosixSocketHelper(Badge<T>)
requires(IsBaseOf<Socket, T>)
{
}
PosixSocketHelper(PosixSocketHelper&& other)
{
operator=(move(other));
}
PosixSocketHelper& operator=(PosixSocketHelper&& other)
{
m_fd = exchange(other.m_fd, -1);
m_last_read_was_eof = exchange(other.m_last_read_was_eof, false);
m_notifier = move(other.m_notifier);
return *this;
}
int fd() const { return m_fd; }
void set_fd(int fd) { m_fd = fd; }
ErrorOr<Bytes> read(Bytes, int flags);
ErrorOr<size_t> write(ReadonlyBytes, int flags);
bool is_eof() const { return !is_open() || m_last_read_was_eof; }
bool is_open() const { return m_fd != -1; }
void close();
ErrorOr<size_t> pending_bytes() const;
ErrorOr<bool> can_read_without_blocking(int timeout) const;
ErrorOr<void> set_blocking(bool enabled);
ErrorOr<void> set_close_on_exec(bool enabled);
ErrorOr<void> set_receive_timeout(Time timeout);
void setup_notifier();
RefPtr<Core::Notifier> notifier() { return m_notifier; }
private:
int m_fd { -1 };
bool m_last_read_was_eof { false };
RefPtr<Core::Notifier> m_notifier;
};
class TCPSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<TCPSocket>> connect(DeprecatedString const& host, u16 port);
static ErrorOr<NonnullOwnPtr<TCPSocket>> connect(SocketAddress const& address);
static ErrorOr<NonnullOwnPtr<TCPSocket>> adopt_fd(int fd);
TCPSocket(TCPSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
TCPSocket& operator=(TCPSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer, default_flags()); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); };
virtual void close() override { m_helper.close(); };
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual ~TCPSocket() override { close(); }
private:
TCPSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<TCPSocket> {} };
};
class UDPSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(DeprecatedString const& host, u16 port, Optional<Time> timeout = {});
static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(SocketAddress const& address, Optional<Time> timeout = {});
UDPSocket(UDPSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
UDPSocket& operator=(UDPSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override
{
auto pending_bytes = TRY(this->pending_bytes());
if (pending_bytes > buffer.size()) {
// With UDP datagrams, reading a datagram into a buffer that's
// smaller than the datagram's size will cause the rest of the
// datagram to be discarded. That's not very nice, so let's bail
// early, telling the caller that he should allocate a bigger
// buffer.
return Error::from_errno(EMSGSIZE);
}
return m_helper.read(buffer, default_flags());
}
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); }
virtual void close() override { m_helper.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual ~UDPSocket() override { close(); }
private:
UDPSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<UDPSocket> {} };
};
class LocalSocket final : public Socket {
public:
static ErrorOr<NonnullOwnPtr<LocalSocket>> connect(DeprecatedString const& path, PreventSIGPIPE = PreventSIGPIPE::No);
static ErrorOr<NonnullOwnPtr<LocalSocket>> adopt_fd(int fd, PreventSIGPIPE = PreventSIGPIPE::No);
LocalSocket(LocalSocket&& other)
: Socket(static_cast<Socket&&>(other))
, m_helper(move(other.m_helper))
{
if (is_open())
setup_notifier();
}
LocalSocket& operator=(LocalSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
if (is_open())
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer, default_flags()); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer, default_flags()); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); }
virtual void close() override { m_helper.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_helper.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.can_read_without_blocking(timeout); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_helper.set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.set_close_on_exec(enabled); }
virtual void set_notifications_enabled(bool enabled) override
{
if (auto notifier = m_helper.notifier())
notifier->set_enabled(enabled);
}
ErrorOr<int> receive_fd(int flags);
ErrorOr<void> send_fd(int fd);
ErrorOr<pid_t> peer_pid() const;
ErrorOr<Bytes> read_without_waiting(Bytes buffer);
/// Release the fd associated with this LocalSocket. After the fd is
/// released, the socket will be considered "closed" and all operations done
/// on it will fail with ENOTCONN. Fails with ENOTCONN if the socket is
/// already closed.
ErrorOr<int> release_fd();
Optional<int> fd() const;
RefPtr<Core::Notifier> notifier() { return m_helper.notifier(); }
virtual ~LocalSocket() { close(); }
private:
LocalSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::No)
: Socket(prevent_sigpipe)
{
}
void setup_notifier()
{
VERIFY(is_open());
m_helper.setup_notifier();
m_helper.notifier()->on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
PosixSocketHelper m_helper { Badge<LocalSocket> {} };
};
template<typename T>
concept SocketLike = IsBaseOf<Socket, T>;
class BufferedSocketBase : public Socket {
public:
virtual ErrorOr<StringView> read_line(Bytes buffer) = 0;
virtual ErrorOr<Bytes> read_until(Bytes buffer, StringView candidate) = 0;
virtual ErrorOr<bool> can_read_line() = 0;
virtual size_t buffer_size() const = 0;
};
template<SocketLike T>
class BufferedSocket final : public BufferedSocketBase {
friend BufferedHelper<T>;
public:
static ErrorOr<NonnullOwnPtr<BufferedSocket<T>>> create(NonnullOwnPtr<T> stream, size_t buffer_size = 16384)
{
return BufferedHelper<T>::template create_buffered<BufferedSocket>(move(stream), buffer_size);
}
BufferedSocket(BufferedSocket&& other)
: BufferedSocketBase(static_cast<BufferedSocketBase&&>(other))
, m_helper(move(other.m_helper))
{
setup_notifier();
}
BufferedSocket& operator=(BufferedSocket&& other)
{
Socket::operator=(static_cast<Socket&&>(other));
m_helper = move(other.m_helper);
setup_notifier();
return *this;
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.stream().write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.stream().is_open(); }
virtual void close() override { m_helper.stream().close(); }
virtual ErrorOr<size_t> pending_bytes() const override
{
return TRY(m_helper.stream().pending_bytes()) + m_helper.buffered_data_size();
}
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_helper.buffered_data_size() > 0 || TRY(m_helper.stream().can_read_without_blocking(timeout)); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_helper.stream().set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_helper.stream().set_close_on_exec(enabled); }
virtual void set_notifications_enabled(bool enabled) override { m_helper.stream().set_notifications_enabled(enabled); }
virtual ErrorOr<StringView> read_line(Bytes buffer) override { return m_helper.read_line(move(buffer)); }
virtual ErrorOr<Bytes> read_until(Bytes buffer, StringView candidate) override { return m_helper.read_until(move(buffer), move(candidate)); }
template<size_t N>
ErrorOr<Bytes> read_until_any_of(Bytes buffer, Array<StringView, N> candidates) { return m_helper.read_until_any_of(move(buffer), move(candidates)); }
virtual ErrorOr<bool> can_read_line() override { return m_helper.can_read_line(); }
virtual size_t buffer_size() const override { return m_helper.buffer_size(); }
virtual ~BufferedSocket() override = default;
private:
BufferedSocket(NonnullOwnPtr<T> stream, CircularBuffer buffer)
: m_helper(Badge<BufferedSocket<T>> {}, move(stream), move(buffer))
{
setup_notifier();
}
void setup_notifier()
{
m_helper.stream().on_ready_to_read = [this] {
if (on_ready_to_read)
on_ready_to_read();
};
}
BufferedHelper<T> m_helper;
};
using BufferedFile = BufferedSeekable<File>;
using BufferedTCPSocket = BufferedSocket<TCPSocket>;
using BufferedUDPSocket = BufferedSocket<UDPSocket>;
using BufferedLocalSocket = BufferedSocket<LocalSocket>;
/// A BasicReusableSocket allows one to use one of the base Core::Stream classes
/// as a ReusableSocket. It does not preserve any connection state or options,
/// and instead just recreates the stream when reconnecting.
template<SocketLike T>
class BasicReusableSocket final : public ReusableSocket {
public:
static ErrorOr<NonnullOwnPtr<BasicReusableSocket<T>>> connect(DeprecatedString const& host, u16 port)
{
return make<BasicReusableSocket<T>>(TRY(T::connect(host, port)));
}
static ErrorOr<NonnullOwnPtr<BasicReusableSocket<T>>> connect(SocketAddress const& address)
{
return make<BasicReusableSocket<T>>(TRY(T::connect(address)));
}
virtual bool is_connected() override
{
return m_socket.is_open();
}
virtual ErrorOr<void> reconnect(DeprecatedString const& host, u16 port) override
{
if (is_connected())
return Error::from_errno(EALREADY);
m_socket = TRY(T::connect(host, port));
return {};
}
virtual ErrorOr<void> reconnect(SocketAddress const& address) override
{
if (is_connected())
return Error::from_errno(EALREADY);
m_socket = TRY(T::connect(address));
return {};
}
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_socket.read(move(buffer)); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_socket.write(buffer); }
virtual bool is_eof() const override { return m_socket.is_eof(); }
virtual bool is_open() const override { return m_socket.is_open(); }
virtual void close() override { m_socket.close(); }
virtual ErrorOr<size_t> pending_bytes() const override { return m_socket.pending_bytes(); }
virtual ErrorOr<bool> can_read_without_blocking(int timeout = 0) const override { return m_socket.can_read_without_blocking(timeout); }
virtual ErrorOr<void> set_blocking(bool enabled) override { return m_socket.set_blocking(enabled); }
virtual ErrorOr<void> set_close_on_exec(bool enabled) override { return m_socket.set_close_on_exec(enabled); }
private:
BasicReusableSocket(NonnullOwnPtr<T> socket)
: m_socket(move(socket))
{
}
NonnullOwnPtr<T> m_socket;
};
using ReusableTCPSocket = BasicReusableSocket<TCPSocket>;
using ReusableUDPSocket = BasicReusableSocket<UDPSocket>;
}

View file

@ -5,6 +5,7 @@
*/
#include "SystemServerTakeover.h"
#include <LibCore/Socket.h>
#include <LibCore/System.h>
namespace Core {
@ -34,7 +35,7 @@ static void parse_sockets_from_system_server()
unsetenv(socket_takeover);
}
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_socket_from_system_server(DeprecatedString const& socket_path)
ErrorOr<NonnullOwnPtr<Core::LocalSocket>> take_over_socket_from_system_server(DeprecatedString const& socket_path)
{
if (!s_overtaken_sockets_parsed)
parse_sockets_from_system_server();
@ -57,7 +58,7 @@ ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_socket_from_system_s
if (!S_ISSOCK(stat.st_mode))
return Error::from_string_literal("The fd we got from SystemServer is not a socket");
auto socket = TRY(Core::Stream::LocalSocket::adopt_fd(fd));
auto socket = TRY(Core::LocalSocket::adopt_fd(fd));
// It had to be !CLOEXEC for obvious reasons, but we
// don't need it to be !CLOEXEC anymore, so set the
// CLOEXEC flag now.

View file

@ -10,6 +10,6 @@
namespace Core {
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_socket_from_system_server(DeprecatedString const& socket_path = {});
ErrorOr<NonnullOwnPtr<Core::LocalSocket>> take_over_socket_from_system_server(DeprecatedString const& socket_path = {});
}

View file

@ -8,6 +8,7 @@
#include <AK/IPv4Address.h>
#include <AK/Types.h>
#include <LibCore/Notifier.h>
#include <LibCore/Socket.h>
#include <LibCore/System.h>
#include <LibCore/TCPServer.h>
@ -74,7 +75,7 @@ ErrorOr<void> TCPServer::set_blocking(bool blocking)
return {};
}
ErrorOr<NonnullOwnPtr<Stream::TCPSocket>> TCPServer::accept()
ErrorOr<NonnullOwnPtr<TCPSocket>> TCPServer::accept()
{
VERIFY(m_listening);
sockaddr_in in;
@ -85,7 +86,7 @@ ErrorOr<NonnullOwnPtr<Stream::TCPSocket>> TCPServer::accept()
int accepted_fd = TRY(Core::System::accept(m_fd, (sockaddr*)&in, &in_size));
#endif
auto socket = TRY(Stream::TCPSocket::adopt_fd(accepted_fd));
auto socket = TRY(TCPSocket::adopt_fd(accepted_fd));
#ifdef AK_OS_MACOS
// FIXME: Ideally, we should let the caller decide whether it wants the

View file

@ -29,7 +29,7 @@ public:
ErrorOr<void> listen(IPv4Address const& address, u16 port, AllowAddressReuse = AllowAddressReuse::No);
ErrorOr<void> set_blocking(bool blocking);
ErrorOr<NonnullOwnPtr<Stream::TCPSocket>> accept();
ErrorOr<NonnullOwnPtr<TCPSocket>> accept();
Optional<IPv4Address> local_address() const;
Optional<u16> local_port() const;

View file

@ -37,7 +37,7 @@ class ConnectionToLaunchServer final
, public LaunchClientEndpoint {
IPC_CLIENT_CONNECTION(ConnectionToLaunchServer, "/tmp/session/%sid/portal/launch"sv)
private:
ConnectionToLaunchServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToLaunchServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(socket))
{
}

View file

@ -62,7 +62,7 @@ protected:
void die() override;
private:
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
explicit Client(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket))
{
}

View file

@ -19,7 +19,7 @@ class ConnectionToClipboardServer final
IPC_CLIENT_CONNECTION(ConnectionToClipboardServer, "/tmp/session/%sid/portal/clipboard"sv)
private:
ConnectionToClipboardServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToClipboardServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket))
{
}

View file

@ -22,7 +22,7 @@ public:
static ConnectionToWindowManagerServer& the();
private:
ConnectionToWindowManagerServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToWindowManagerServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, move(socket))
{
}

View file

@ -42,7 +42,7 @@ static void set_system_theme_from_anonymous_buffer(Core::AnonymousBuffer buffer)
Application::the()->set_system_palette(buffer);
}
ConnectionToWindowServer::ConnectionToWindowServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToWindowServer::ConnectionToWindowServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<WindowClientEndpoint, WindowServerEndpoint>(*this, move(socket))
{
// NOTE: WindowServer automatically sends a "fast_greet" message to us when we connect.

View file

@ -22,7 +22,7 @@ public:
i32 expose_client_id() { return m_client_id; }
private:
ConnectionToWindowServer(NonnullOwnPtr<Core::Stream::LocalSocket>);
ConnectionToWindowServer(NonnullOwnPtr<Core::LocalSocket>);
virtual void fast_greet(Vector<Gfx::IntRect> const&, u32, u32, u32, Core::AnonymousBuffer const&, DeprecatedString const&, DeprecatedString const&, DeprecatedString const&, Vector<bool> const&, i32) override;
virtual void paint(i32, Gfx::IntSize, Vector<Gfx::IntRect> const&) override;

View file

@ -26,7 +26,7 @@ public:
}
private:
explicit ConnectionToNotificationServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket, Notification* notification)
explicit ConnectionToNotificationServer(NonnullOwnPtr<Core::LocalSocket> socket, Notification* notification)
: IPC::ConnectionToServer<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(socket))
, m_notification(notification)
{

View file

@ -21,10 +21,10 @@ Job::Job(GeminiRequest const& request, AK::Stream& output_stream)
{
}
void Job::start(Core::Stream::Socket& socket)
void Job::start(Core::Socket& socket)
{
VERIFY(!m_socket);
m_socket = verify_cast<Core::Stream::BufferedSocketBase>(&socket);
m_socket = verify_cast<Core::BufferedSocketBase>(&socket);
on_socket_connected();
}

View file

@ -8,6 +8,7 @@
#include <AK/Optional.h>
#include <LibCore/NetworkJob.h>
#include <LibCore/Socket.h>
#include <LibGemini/GeminiRequest.h>
#include <LibGemini/GeminiResponse.h>
@ -20,14 +21,14 @@ public:
explicit Job(GeminiRequest const&, AK::Stream&);
virtual ~Job() override = default;
virtual void start(Core::Stream::Socket&) override;
virtual void start(Core::Socket&) override;
virtual void shutdown(ShutdownMode) override;
GeminiResponse* response() { return static_cast<GeminiResponse*>(Core::NetworkJob::response()); }
GeminiResponse const* response() const { return static_cast<GeminiResponse const*>(Core::NetworkJob::response()); }
const URL& url() const { return m_request.url(); }
Core::Stream::Socket const* socket() const { return m_socket; }
Core::Socket const* socket() const { return m_socket; }
ErrorOr<size_t> response_length() const;
@ -56,7 +57,7 @@ protected:
Vector<ByteBuffer, 2> m_received_buffers;
size_t m_received_size { 0 };
size_t m_buffered_size { 0 };
Core::Stream::BufferedSocketBase* m_socket { nullptr };
Core::BufferedSocketBase* m_socket { nullptr };
};
}

View file

@ -92,10 +92,10 @@ Job::Job(HttpRequest&& request, AK::Stream& output_stream)
{
}
void Job::start(Core::Stream::Socket& socket)
void Job::start(Core::Socket& socket)
{
VERIFY(!m_socket);
m_socket = static_cast<Core::Stream::BufferedSocketBase*>(&socket);
m_socket = static_cast<Core::BufferedSocketBase*>(&socket);
dbgln_if(HTTPJOB_DEBUG, "Reusing previous connection for {}", url());
deferred_invoke([this] {
dbgln_if(HTTPJOB_DEBUG, "HttpJob: on_connected callback");

View file

@ -10,6 +10,7 @@
#include <AK/NonnullOwnPtrVector.h>
#include <AK/Optional.h>
#include <LibCore/NetworkJob.h>
#include <LibCore/Socket.h>
#include <LibHTTP/HttpRequest.h>
#include <LibHTTP/HttpResponse.h>
@ -22,10 +23,10 @@ public:
explicit Job(HttpRequest&&, AK::Stream&);
virtual ~Job() override = default;
virtual void start(Core::Stream::Socket&) override;
virtual void start(Core::Socket&) override;
virtual void shutdown(ShutdownMode) override;
Core::Stream::Socket const* socket() const { return m_socket; }
Core::Socket const* socket() const { return m_socket; }
URL url() const { return m_request.url(); }
HttpResponse* response() { return static_cast<HttpResponse*>(Core::NetworkJob::response()); }
@ -50,7 +51,7 @@ protected:
HttpRequest m_request;
State m_state { State::InStatus };
Core::Stream::BufferedSocketBase* m_socket { nullptr };
Core::BufferedSocketBase* m_socket { nullptr };
bool m_legacy_connection { false };
int m_code { -1 };
HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> m_headers;

View file

@ -10,7 +10,7 @@
namespace IMAP {
Client::Client(StringView host, u16 port, NonnullOwnPtr<Core::Stream::Socket> socket)
Client::Client(StringView host, u16 port, NonnullOwnPtr<Core::Socket> socket)
: m_host(host)
, m_port(port)
, m_socket(move(socket))
@ -49,7 +49,7 @@ ErrorOr<NonnullOwnPtr<Client>> Client::connect_tls(StringView host, u16 port)
ErrorOr<NonnullOwnPtr<Client>> Client::connect_plaintext(StringView host, u16 port)
{
auto socket = TRY(Core::Stream::TCPSocket::connect(host, port));
auto socket = TRY(Core::TCPSocket::connect(host, port));
dbgln("Connected to {}:{}", host, port);
return adopt_nonnull_own_or_enomem(new (nothrow) Client(host, port, move(socket)));
}

View file

@ -60,7 +60,7 @@ public:
Function<void(ResponseData&&)> unrequested_response_callback;
private:
Client(StringView host, u16 port, NonnullOwnPtr<Core::Stream::Socket>);
Client(StringView host, u16 port, NonnullOwnPtr<Core::Socket>);
void setup_callbacks();
ErrorOr<void> on_ready_to_receive();
@ -71,7 +71,7 @@ private:
StringView m_host;
u16 m_port;
NonnullOwnPtr<Core::Stream::Socket> m_socket;
NonnullOwnPtr<Core::Socket> m_socket;
RefPtr<Promise<Empty>> m_connect_pending {};
int m_current_command = 1;

View file

@ -21,7 +21,7 @@ struct CoreEventLoopDeferredInvoker final : public DeferredInvoker {
}
};
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, u32 local_endpoint_magic)
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::LocalSocket> socket, u32 local_endpoint_magic)
: m_local_stub(local_stub)
, m_socket(move(socket))
, m_local_endpoint_magic(local_endpoint_magic)
@ -35,12 +35,12 @@ void ConnectionBase::set_deferred_invoker(NonnullOwnPtr<DeferredInvoker> deferre
m_deferred_invoker = move(deferred_invoker);
}
void ConnectionBase::set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
void ConnectionBase::set_fd_passing_socket(NonnullOwnPtr<Core::LocalSocket> socket)
{
m_fd_passing_socket = move(socket);
}
Core::Stream::LocalSocket& ConnectionBase::fd_passing_socket()
Core::LocalSocket& ConnectionBase::fd_passing_socket()
{
if (m_fd_passing_socket)
return *m_fd_passing_socket;

View file

@ -13,6 +13,7 @@
#include <LibCore/Event.h>
#include <LibCore/EventLoop.h>
#include <LibCore/Notifier.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
#include <LibCore/Timer.h>
#include <LibIPC/Forward.h>
@ -39,7 +40,7 @@ class ConnectionBase : public Core::Object {
public:
virtual ~ConnectionBase() override = default;
void set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket>);
void set_fd_passing_socket(NonnullOwnPtr<Core::LocalSocket>);
void set_deferred_invoker(NonnullOwnPtr<DeferredInvoker>);
DeferredInvoker& deferred_invoker() { return *m_deferred_invoker; }
@ -49,11 +50,11 @@ public:
void shutdown();
virtual void die() { }
Core::Stream::LocalSocket& socket() { return *m_socket; }
Core::Stream::LocalSocket& fd_passing_socket();
Core::LocalSocket& socket() { return *m_socket; }
Core::LocalSocket& fd_passing_socket();
protected:
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::LocalSocket>, u32 local_endpoint_magic);
virtual void may_have_become_unresponsive() { }
virtual void did_become_responsive() { }
@ -70,8 +71,8 @@ protected:
IPC::Stub& m_local_stub;
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
OwnPtr<Core::Stream::LocalSocket> m_fd_passing_socket;
NonnullOwnPtr<Core::LocalSocket> m_socket;
OwnPtr<Core::LocalSocket> m_fd_passing_socket;
RefPtr<Core::Timer> m_responsiveness_timer;
@ -86,7 +87,7 @@ protected:
template<typename LocalEndpoint, typename PeerEndpoint>
class Connection : public ConnectionBase {
public:
Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::LocalSocket> socket)
: ConnectionBase(local_stub, move(socket), LocalEndpoint::static_magic())
{
m_socket->on_ready_to_read = [this] {

View file

@ -26,7 +26,7 @@ public:
using ServerStub = typename ServerEndpoint::Stub;
using IPCProxy = typename ClientEndpoint::template Proxy<ServerEndpoint>;
ConnectionFromClient(ServerStub& stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
ConnectionFromClient(ServerStub& stub, NonnullOwnPtr<Core::LocalSocket> socket, int client_id)
: IPC::Connection<ServerEndpoint, ClientEndpoint>(stub, move(socket))
, ClientEndpoint::template Proxy<ServerEndpoint>(*this, {})
, m_client_id(client_id)

View file

@ -19,7 +19,7 @@ public:
static ErrorOr<NonnullRefPtr<klass>> try_create(Args&&... args) \
{ \
auto parsed_socket_path = TRY(Core::SessionManagement::parse_path_with_sid(socket_path)); \
auto socket = TRY(Core::Stream::LocalSocket::connect(move(parsed_socket_path))); \
auto socket = TRY(Core::LocalSocket::connect(move(parsed_socket_path))); \
/* We want to rate-limit our clients */ \
TRY(socket->set_blocking(true)); \
\
@ -34,7 +34,7 @@ public:
using ClientStub = typename ClientEndpoint::Stub;
using IPCProxy = typename ServerEndpoint::template Proxy<ClientEndpoint>;
ConnectionToServer(ClientStub& local_endpoint, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToServer(ClientStub& local_endpoint, NonnullOwnPtr<Core::LocalSocket> socket)
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, move(socket))
, ServerEndpoint::template Proxy<ClientEndpoint>(*this, {})
{

View file

@ -10,6 +10,7 @@
#include <LibCore/AnonymousBuffer.h>
#include <LibCore/DateTime.h>
#include <LibCore/Proxy.h>
#include <LibCore/Socket.h>
#include <LibIPC/Decoder.h>
#include <LibIPC/Dictionary.h>
#include <LibIPC/File.h>

View file

@ -32,7 +32,7 @@ inline ErrorOr<T> decode(Decoder&)
class Decoder {
public:
Decoder(AK::Stream& stream, Core::Stream::LocalSocket& socket)
Decoder(AK::Stream& stream, Core::LocalSocket& socket)
: m_stream(stream)
, m_socket(socket)
{
@ -56,11 +56,11 @@ public:
ErrorOr<size_t> decode_size();
Core::Stream::LocalSocket& socket() { return m_socket; }
Core::LocalSocket& socket() { return m_socket; }
private:
AK::Stream& m_stream;
Core::Stream::LocalSocket& m_socket;
Core::LocalSocket& m_socket;
};
template<Arithmetic T>

View file

@ -9,7 +9,7 @@
namespace ImageDecoderClient {
Client::Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
Client::Client(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket))
{
}

View file

@ -35,7 +35,7 @@ public:
Function<void()> on_death;
private:
Client(NonnullOwnPtr<Core::Stream::LocalSocket>);
Client(NonnullOwnPtr<Core::LocalSocket>);
virtual void die() override;
};

View file

@ -9,7 +9,7 @@
namespace Protocol {
RequestClient::RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
RequestClient::RequestClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket))
{
}

View file

@ -30,7 +30,7 @@ public:
bool set_certificate(Badge<Request>, Request&, DeprecatedString, DeprecatedString);
private:
RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
RequestClient(NonnullOwnPtr<Core::LocalSocket>);
virtual void request_progress(i32, Optional<u32> const&, u32) override;
virtual void request_finished(i32, bool, u32) override;

View file

@ -9,7 +9,7 @@
namespace Protocol {
WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket))
{
}

View file

@ -30,7 +30,7 @@ public:
bool set_certificate(Badge<WebSocket>, WebSocket&, DeprecatedString, DeprecatedString);
private:
WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
WebSocketClient(NonnullOwnPtr<Core::LocalSocket>);
virtual void connected(i32) override;
virtual void received(i32, bool, ByteBuffer const&) override;

View file

@ -146,7 +146,7 @@ ErrorOr<NonnullRefPtr<SQLClient>> SQLClient::launch_server_and_create_client(Vec
if (TRY(should_launch_server(pid_path)))
TRY(launch_server(socket_path, pid_path, move(candidate_server_paths)));
auto socket = TRY(Core::Stream::LocalSocket::connect(move(socket_path)));
auto socket = TRY(Core::LocalSocket::connect(move(socket_path)));
TRY(socket->set_blocking(true));
return adopt_nonnull_ref_or_enomem(new (nothrow) SQLClient(move(socket)));

View file

@ -66,7 +66,7 @@ public:
Function<void(ExecutionComplete)> on_results_exhausted;
private:
explicit SQLClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
explicit SQLClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket))
{
}

View file

@ -75,7 +75,7 @@ ErrorOr<size_t> TLSv12::write(ReadonlyBytes bytes)
ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, u16 port, Options options)
{
Core::EventLoop loop;
OwnPtr<Core::Stream::Socket> tcp_socket = TRY(Core::Stream::TCPSocket::connect(host, port));
OwnPtr<Core::Socket> tcp_socket = TRY(Core::TCPSocket::connect(host, port));
TRY(tcp_socket->set_blocking(false));
auto tls_socket = make<TLSv12>(move(tcp_socket), move(options));
tls_socket->set_sni(host);
@ -94,7 +94,7 @@ ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, u16
return AK::Error::from_string_view(alert_name(static_cast<AlertDescription>(256 - result)));
}
ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, Core::Stream::Socket& underlying_stream, Options options)
ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, Core::Socket& underlying_stream, Options options)
{
TRY(underlying_stream.set_blocking(false));
auto tls_socket = make<TLSv12>(&underlying_stream, move(options));

View file

@ -10,6 +10,7 @@
#include <AK/IPv4Address.h>
#include <AK/WeakPtr.h>
#include <LibCore/Notifier.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
#include <LibCore/Timer.h>
#include <LibCrypto/Authentication/HMAC.h>
@ -344,15 +345,15 @@ struct Context {
OwnPtr<Crypto::Curves::EllipticCurve> server_key_exchange_curve;
};
class TLSv12 final : public Core::Stream::Socket {
class TLSv12 final : public Core::Socket {
private:
Core::Stream::Socket& underlying_stream()
Core::Socket& underlying_stream()
{
return *m_stream.visit([&](auto& stream) -> Core::Stream::Socket* { return stream; });
return *m_stream.visit([&](auto& stream) -> Core::Socket* { return stream; });
}
Core::Stream::Socket const& underlying_stream() const
Core::Socket const& underlying_stream() const
{
return *m_stream.visit([&](auto& stream) -> Core::Stream::Socket const* { return stream; });
return *m_stream.visit([&](auto& stream) -> Core::Socket const* { return stream; });
}
public:
@ -384,9 +385,9 @@ public:
virtual void set_notifications_enabled(bool enabled) override { underlying_stream().set_notifications_enabled(enabled); }
static ErrorOr<NonnullOwnPtr<TLSv12>> connect(DeprecatedString const& host, u16 port, Options = {});
static ErrorOr<NonnullOwnPtr<TLSv12>> connect(DeprecatedString const& host, Core::Stream::Socket& underlying_stream, Options = {});
static ErrorOr<NonnullOwnPtr<TLSv12>> connect(DeprecatedString const& host, Core::Socket& underlying_stream, Options = {});
using StreamVariantType = Variant<OwnPtr<Core::Stream::Socket>, Core::Stream::Socket*>;
using StreamVariantType = Variant<OwnPtr<Core::Socket>, Core::Socket*>;
explicit TLSv12(StreamVariantType, Options);
bool is_established() const { return m_context.connection_status == ConnectionStatus::Established; }

View file

@ -170,7 +170,7 @@ static JsonValue make_success_response(JsonValue value)
return result;
}
Client::Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket> socket, Core::Object* parent)
Client::Client(NonnullOwnPtr<Core::BufferedTCPSocket> socket, Core::Object* parent)
: Core::Object(parent)
, m_socket(move(socket))
{

View file

@ -13,6 +13,7 @@
#include <AK/NonnullOwnPtrVector.h>
#include <AK/Variant.h>
#include <LibCore/Object.h>
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
#include <LibHTTP/Forward.h>
#include <LibHTTP/HttpRequest.h>
@ -103,7 +104,7 @@ public:
virtual Response print_page(Parameters parameters, JsonValue payload) = 0;
protected:
Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket>, Core::Object* parent);
Client(NonnullOwnPtr<Core::BufferedTCPSocket>, Core::Object* parent);
private:
using WrappedError = Variant<AK::Error, WebDriver::Error>;
@ -116,7 +117,7 @@ private:
ErrorOr<void, WrappedError> send_error_response(Error const& error);
void log_response(unsigned code);
NonnullOwnPtr<Core::Stream::BufferedTCPSocket> m_socket;
NonnullOwnPtr<Core::BufferedTCPSocket> m_socket;
Optional<HTTP::HttpRequest> m_request;
};

View file

@ -7,6 +7,7 @@
*/
#include <LibCore/EventLoop.h>
#include <LibCore/Socket.h>
#include <LibWebSocket/Impl/WebSocketImplSerenity.h>
namespace WebSocket {
@ -40,18 +41,18 @@ void WebSocketImplSerenity::connect(ConnectionInfo const& connection_info)
VERIFY(on_connected);
VERIFY(on_connection_error);
VERIFY(on_ready_to_read);
auto socket_result = [&]() -> ErrorOr<NonnullOwnPtr<Core::Stream::BufferedSocketBase>> {
auto socket_result = [&]() -> ErrorOr<NonnullOwnPtr<Core::BufferedSocketBase>> {
if (connection_info.is_secure()) {
TLS::Options options;
options.set_alert_handler([this](auto) {
on_connection_error();
});
return TRY(Core::Stream::BufferedSocket<TLS::TLSv12>::create(
return TRY(Core::BufferedSocket<TLS::TLSv12>::create(
TRY(TLS::TLSv12::connect(connection_info.url().host(), connection_info.url().port_or_default(), move(options)))));
}
return TRY(Core::Stream::BufferedTCPSocket::create(
TRY(Core::Stream::TCPSocket::connect(connection_info.url().host(), connection_info.url().port_or_default()))));
return TRY(Core::BufferedTCPSocket::create(
TRY(Core::TCPSocket::connect(connection_info.url().host(), connection_info.url().port_or_default()))));
}();
if (socket_result.is_error()) {

View file

@ -26,7 +26,7 @@ public:
virtual void discard_connection() override;
private:
OwnPtr<Core::Stream::BufferedSocketBase> m_socket;
OwnPtr<Core::BufferedSocketBase> m_socket;
};
}

View file

@ -11,7 +11,7 @@
namespace WebView {
WebContentClient::WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, ViewImplementation& view)
WebContentClient::WebContentClient(NonnullOwnPtr<Core::LocalSocket> socket, ViewImplementation& view)
: IPC::ConnectionToServer<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(socket))
, m_view(view)
{

View file

@ -21,7 +21,7 @@ class WebContentClient final
IPC_CLIENT_CONNECTION(WebContentClient, "/tmp/session/%sid/portal/webcontent"sv);
public:
WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket>, ViewImplementation&);
WebContentClient(NonnullOwnPtr<Core::LocalSocket>, ViewImplementation&);
Function<void()> on_web_content_process_crash;

View file

@ -22,7 +22,7 @@ void ConnectionFromClient::for_each(Function<void(ConnectionFromClient&)> callba
callback(connection);
}
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id, Mixer& mixer)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id, Mixer& mixer)
: IPC::ConnectionFromClient<AudioClientEndpoint, AudioServerEndpoint>(*this, move(client_socket), client_id)
, m_mixer(mixer)
{

View file

@ -32,7 +32,7 @@ public:
static void for_each(Function<void(ConnectionFromClient&)>);
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id, Mixer& mixer);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id, Mixer& mixer);
virtual Messages::AudioServer::GetMainMixVolumeResponse get_main_mix_volume() override;
virtual void set_main_mix_volume(double) override;

View file

@ -25,7 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
auto server = TRY(Core::LocalServer::try_create());
TRY(server->take_over_from_system_server());
server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> client_socket) {
server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> client_socket) {
static int s_next_client_id = 0;
int client_id = ++s_next_client_id;
(void)IPC::new_client_connection<AudioServer::ConnectionFromClient>(move(client_socket), client_id, *mixer);

View file

@ -19,7 +19,7 @@ void ConnectionFromClient::for_each_client(Function<void(ConnectionFromClient&)>
}
}
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket, int client_id)
: IPC::ConnectionFromClient<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket), client_id)
{
s_connections.set(client_id, *this);

View file

@ -27,7 +27,7 @@ public:
void notify_about_clipboard_change();
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual Messages::ClipboardServer::GetClipboardDataResponse get_clipboard_data() override;
virtual void set_clipboard_data(Core::AnonymousBuffer const&, DeprecatedString const&, IPC::Dictionary const&) override;

View file

@ -74,7 +74,7 @@ static Core::ConfigFile& ensure_domain_config(DeprecatedString const& domain)
return *config;
}
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id)
: IPC::ConnectionFromClient<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(client_socket), client_id)
, m_sync_timer(Core::Timer::create_single_shot(s_disk_sync_delay_ms, [this]() { sync_dirty_domains_to_disk(); }).release_value_but_fixme_should_propagate_errors())
{

View file

@ -23,7 +23,7 @@ public:
bool is_monitoring_domain(DeprecatedString const& domain) const { return m_monitored_domains.contains(domain); }
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual void pledge_domains(Vector<DeprecatedString> const&) override;
virtual void monitor_domain(DeprecatedString const&) override;

View file

@ -6,8 +6,9 @@
#include "Client.h"
#include <LibCore/EventLoop.h>
#include <LibCore/Socket.h>
Client::Client(int id, NonnullOwnPtr<Core::Stream::TCPSocket> socket)
Client::Client(int id, NonnullOwnPtr<Core::TCPSocket> socket)
: m_id(id)
, m_socket(move(socket))
{

View file

@ -6,11 +6,12 @@
#pragma once
#include <LibCore/Socket.h>
#include <LibCore/Stream.h>
class Client : public RefCounted<Client> {
public:
static NonnullRefPtr<Client> create(int id, NonnullOwnPtr<Core::Stream::TCPSocket> socket)
static NonnullRefPtr<Client> create(int id, NonnullOwnPtr<Core::TCPSocket> socket)
{
return adopt_ref(*new Client(id, move(socket)));
}
@ -18,12 +19,12 @@ public:
Function<void()> on_exit;
protected:
Client(int id, NonnullOwnPtr<Core::Stream::TCPSocket> socket);
Client(int id, NonnullOwnPtr<Core::TCPSocket> socket);
ErrorOr<void> drain_socket();
void quit();
private:
int m_id { 0 };
NonnullOwnPtr<Core::Stream::TCPSocket> m_socket;
NonnullOwnPtr<Core::TCPSocket> m_socket;
};

View file

@ -16,7 +16,7 @@ namespace FileSystemAccessServer {
static HashMap<int, NonnullRefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket), 1)
{
s_connections.set(1, *this);

View file

@ -25,7 +25,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
virtual void request_file_read_only_approved(i32, i32, i32, DeprecatedString const&) override;
virtual void request_file(i32, i32, i32, DeprecatedString const&, Core::Stream::OpenMode) override;

View file

@ -12,7 +12,7 @@
namespace ImageDecoder {
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket), 1)
{
}

View file

@ -24,7 +24,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer const&, Optional<DeprecatedString> const& mime_type) override;
};

View file

@ -12,7 +12,7 @@ namespace InspectorServer {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket, int client_id)
: IPC::ConnectionFromClient<InspectorClientEndpoint, InspectorServerEndpoint>(*this, move(socket), client_id)
{
s_connections.set(client_id, *this);

View file

@ -23,7 +23,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual Messages::InspectorServer::GetAllObjectsResponse get_all_objects(pid_t) override;
virtual Messages::InspectorServer::SetInspectedObjectResponse set_inspected_object(pid_t, u64 object_id) override;

View file

@ -7,6 +7,7 @@
#include "InspectableProcess.h"
#include <AK/JsonObject.h>
#include <LibCore/EventLoop.h>
#include <LibCore/Socket.h>
namespace InspectorServer {
@ -17,7 +18,7 @@ InspectableProcess* InspectableProcess::from_pid(pid_t pid)
return g_processes.get(pid).value_or(nullptr);
}
InspectableProcess::InspectableProcess(pid_t pid, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
InspectableProcess::InspectableProcess(pid_t pid, NonnullOwnPtr<Core::LocalSocket> socket)
: m_pid(pid)
, m_socket(move(socket))
{

View file

@ -12,7 +12,7 @@ namespace InspectorServer {
class InspectableProcess {
public:
InspectableProcess(pid_t, NonnullOwnPtr<Core::Stream::LocalSocket>);
InspectableProcess(pid_t, NonnullOwnPtr<Core::LocalSocket>);
~InspectableProcess() = default;
void send_request(JsonObject const& request);
@ -22,7 +22,7 @@ public:
private:
pid_t m_pid { 0 };
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
NonnullOwnPtr<Core::LocalSocket> m_socket;
};
extern HashMap<pid_t, NonnullOwnPtr<InspectorServer::InspectableProcess>> g_processes;

View file

@ -13,7 +13,7 @@
namespace LaunchServer {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id)
: IPC::ConnectionFromClient<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(client_socket), client_id)
{
s_connections.set(client_id, *this);

View file

@ -20,7 +20,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual Messages::LaunchServer::OpenUrlResponse open_url(URL const&, DeprecatedString const&) override;
virtual Messages::LaunchServer::GetHandlersForUrlResponse get_handlers_for_url(URL const&) override;

View file

@ -15,7 +15,7 @@ using namespace DNS;
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket, int client_id)
: IPC::ConnectionFromClient<LookupClientEndpoint, LookupServerEndpoint>(*this, move(socket), client_id)
{
s_connections.set(client_id, *this);

View file

@ -23,7 +23,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual Messages::LookupServer::LookupNameResponse lookup_name(DeprecatedString const&) override;
virtual Messages::LookupServer::LookupAddressResponse lookup_address(DeprecatedString const&) override;

View file

@ -237,7 +237,7 @@ ErrorOr<Vector<Answer>> LookupServer::lookup(Name const& name, DeprecatedString
auto buffer = TRY(request.to_byte_buffer());
auto udp_socket = TRY(Core::Stream::UDPSocket::connect(nameserver, 53, Time::from_seconds(1)));
auto udp_socket = TRY(Core::UDPSocket::connect(nameserver, 53, Time::from_seconds(1)));
TRY(udp_socket->set_blocking(true));
TRY(udp_socket->write(buffer));

View file

@ -13,7 +13,7 @@ namespace NotificationServer {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id)
: IPC::ConnectionFromClient<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(client_socket), client_id)
{
s_connections.set(client_id, *this);

View file

@ -21,7 +21,7 @@ public:
virtual void die() override;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual void show_notification(DeprecatedString const&, DeprecatedString const&, Gfx::ShareableBitmap const&) override;
virtual void close_notification() override;

View file

@ -11,10 +11,10 @@
namespace RequestServer::ConnectionCache {
HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<Core::Stream::TCPSocket, Core::Stream::Socket>>>> g_tcp_connection_cache {};
HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<Core::TCPSocket, Core::Socket>>>> g_tcp_connection_cache {};
HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<TLS::TLSv12>>>> g_tls_connection_cache {};
void request_did_finish(URL const& url, Core::Stream::Socket const* socket)
void request_did_finish(URL const& url, Core::Socket const* socket)
{
if (!socket) {
dbgln("Request with a null socket finished for URL {}", url);
@ -71,9 +71,9 @@ void request_did_finish(URL const& url, Core::Stream::Socket const* socket)
}
};
if (is<Core::Stream::BufferedSocket<TLS::TLSv12>>(socket))
if (is<Core::BufferedSocket<TLS::TLSv12>>(socket))
fire_off_next_job(g_tls_connection_cache);
else if (is<Core::Stream::BufferedSocket<Core::Stream::Socket>>(socket))
else if (is<Core::BufferedSocket<Core::Socket>>(socket))
fire_off_next_job(g_tcp_connection_cache);
else
dbgln("Unknown socket {} finished for URL {}", socket, url);

View file

@ -44,7 +44,7 @@ struct Proxy {
if constexpr (requires { SocketType::connect(declval<DeprecatedString>(), *proxy_client_storage, forward<Args>(args)...); }) {
proxy_client_storage = TRY(Core::SOCKSProxyClient::connect(data.host_ipv4, data.port, Core::SOCKSProxyClient::Version::V5, url.host(), url.port_or_default()));
return TRY(SocketType::connect(url.host(), *proxy_client_storage, forward<Args>(args)...));
} else if constexpr (IsSame<SocketType, Core::Stream::TCPSocket>) {
} else if constexpr (IsSame<SocketType, Core::TCPSocket>) {
return TRY(Core::SOCKSProxyClient::connect(data.host_ipv4, data.port, Core::SOCKSProxyClient::Version::V5, url.host(), url.port_or_default()));
} else {
return Error::from_string_literal("SOCKS5 not supported for this socket type");
@ -57,7 +57,7 @@ struct Proxy {
template<typename Socket, typename SocketStorageType = Socket>
struct Connection {
struct JobData {
Function<void(Core::Stream::Socket&)> start {};
Function<void(Core::Socket&)> start {};
Function<void(Core::NetworkJob::Error)> fail {};
Function<Vector<TLS::Certificate>()> provide_client_certificates {};
@ -91,7 +91,7 @@ struct Connection {
using SocketType = Socket;
using StorageType = SocketStorageType;
NonnullOwnPtr<Core::Stream::BufferedSocket<SocketStorageType>> socket;
NonnullOwnPtr<Core::BufferedSocket<SocketStorageType>> socket;
QueueType request_queue;
NonnullRefPtr<Core::Timer> removal_timer;
bool has_started { false };
@ -121,10 +121,10 @@ struct AK::Traits<RequestServer::ConnectionCache::ConnectionKey> : public AK::Ge
namespace RequestServer::ConnectionCache {
extern HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<Core::Stream::TCPSocket, Core::Stream::Socket>>>> g_tcp_connection_cache;
extern HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<Core::TCPSocket, Core::Socket>>>> g_tcp_connection_cache;
extern HashMap<ConnectionKey, NonnullOwnPtr<NonnullOwnPtrVector<Connection<TLS::TLSv12>>>> g_tls_connection_cache;
void request_did_finish(URL const&, Core::Stream::Socket const*);
void request_did_finish(URL const&, Core::Socket const*);
void dump_jobs();
constexpr static size_t MaxConcurrentConnectionsPerURL = 4;
@ -139,7 +139,7 @@ ErrorOr<void> recreate_socket_if_needed(T& connection, URL const& url)
if (!connection.socket->is_open() || connection.socket->is_eof()) {
// Create another socket for the connection.
auto set_socket = [&](auto socket) -> ErrorOr<void> {
connection.socket = TRY(Core::Stream::BufferedSocket<SocketStorageType>::create(move(socket)));
connection.socket = TRY(Core::BufferedSocket<SocketStorageType>::create(move(socket)));
return {};
};
@ -192,7 +192,7 @@ decltype(auto) get_or_create_connection(auto& cache, URL const& url, auto& job,
});
return ReturnType { nullptr };
}
auto socket_result = Core::Stream::BufferedSocket<typename ConnectionType::StorageType>::create(connection_result.release_value());
auto socket_result = Core::BufferedSocket<typename ConnectionType::StorageType>::create(connection_result.release_value());
if (socket_result.is_error()) {
dbgln("ConnectionCache: Failed to make a buffered socket for {}: {}", url, socket_result.error());
Core::deferred_invoke([&job] {

View file

@ -17,7 +17,7 @@ namespace RequestServer {
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionFromClient<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), 1)
{
s_connections.set(1, *this);
@ -123,7 +123,7 @@ struct Job {
return *s_jobs.find(url)->value;
}
void start(Core::Stream::Socket& socket)
void start(Core::Socket& socket)
{
auto is_connected = socket.is_open();
VERIFY(is_connected);

View file

@ -29,7 +29,7 @@ public:
void did_request_certificates(Badge<Request>, Request&);
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(DeprecatedString const&) override;
virtual Messages::RequestServer::StartRequestResponse start_request(DeprecatedString const&, URL const&, IPC::Dictionary const&, ByteBuffer const&, Core::ProxyData const&) override;

View file

@ -28,7 +28,7 @@ void ConnectionFromClient::set_database_path(DeprecatedString database_path)
m_database_path = move(database_path);
}
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket, int client_id)
: IPC::ConnectionFromClient<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket), client_id)
, m_database_path(DeprecatedString::formatted("{}/sql", Core::StandardPaths::data_directory()))
{

View file

@ -32,7 +32,7 @@ public:
Function<void()> on_disconnect;
private:
explicit ConnectionFromClient(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id);
virtual Messages::SQLServer::ConnectResponse connect(DeprecatedString const&) override;
virtual Messages::SQLServer::PrepareStatementResponse prepare_statement(SQL::ConnectionID, DeprecatedString const&) override;

View file

@ -23,7 +23,7 @@ public:
void set_bitmap(Gfx::Bitmap const& bitmap);
private:
ConnectionToClipboardServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
ConnectionToClipboardServer(NonnullOwnPtr<Core::LocalSocket> socket)
: IPC::ConnectionToServer<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket))
{
}

Some files were not shown because too many files have changed in this diff Show more