mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
LibCore: Move Stream-based sockets into the Core
namespace
This commit is contained in:
parent
d43a7eae54
commit
a96339b72b
Notes:
sideshowbarker
2024-07-17 07:25:39 +09:00
Author: https://github.com/timschumi Commit: https://github.com/SerenityOS/serenity/commit/a96339b72b Pull-request: https://github.com/SerenityOS/serenity/pull/17406 Reviewed-by: https://github.com/linusg
123 changed files with 1157 additions and 1100 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>());)~~~");
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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>())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ set(SOURCES
|
|||
Property.cpp
|
||||
SecretString.cpp
|
||||
SessionManagement.cpp
|
||||
Socket.cpp
|
||||
SOCKSProxyClient.cpp
|
||||
StandardPaths.cpp
|
||||
Stream.cpp
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -16,7 +16,7 @@ NetworkJob::NetworkJob(AK::Stream& output_stream)
|
|||
{
|
||||
}
|
||||
|
||||
void NetworkJob::start(Core::Stream::Socket&)
|
||||
void NetworkJob::start(Core::Socket&)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
410
Userland/Libraries/LibCore/Socket.cpp
Normal file
410
Userland/Libraries/LibCore/Socket.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
508
Userland/Libraries/LibCore/Socket.h
Normal file
508
Userland/Libraries/LibCore/Socket.h
Normal 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>;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 = {});
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, {})
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
Function<void()> on_death;
|
||||
|
||||
private:
|
||||
Client(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
Client(NonnullOwnPtr<Core::LocalSocket>);
|
||||
|
||||
virtual void die() override;
|
||||
};
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
virtual void discard_connection() override;
|
||||
|
||||
private:
|
||||
OwnPtr<Core::Stream::BufferedSocketBase> m_socket;
|
||||
OwnPtr<Core::BufferedSocketBase> m_socket;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue