diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index 0a68d2ed28..9cce282d08 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -94,7 +94,7 @@ ErrorOr 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); diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 690b1c0d72..e35b7c8310 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -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); diff --git a/Ladybird/WebDriver/main.cpp b/Ladybird/WebDriver/main.cpp index 03f11e418b..7c668af984 100644 --- a/Ladybird/WebDriver/main.cpp +++ b/Ladybird/WebDriver/main.cpp @@ -125,7 +125,7 @@ ErrorOr 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; diff --git a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp index 9d58aa0ff3..2a106802a3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp @@ -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> decode(AK::Stream& stream, Core::Stream::LocalSocket& socket) + static ErrorOr> 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> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Core::Stream::LocalSocket& socket) + static ErrorOr> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Core::LocalSocket& socket) { FixedMemoryStream stream { buffer }; auto message_endpoint_magic = TRY(stream.read_value());)~~~"); diff --git a/Tests/LibCore/TestLibCoreStream.cpp b/Tests/LibCore/TestLibCoreStream.cpp index fe448f2698..895b77434f 100644 --- a/Tests/LibCore/TestLibCoreStream.cpp +++ b/Tests/LibCore/TestLibCoreStream.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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 server_socket) { + local_server->on_accept = [&](NonnullOwnPtr 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 server_socket) { + local_server->on_accept = [&](NonnullOwnPtr 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::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(); diff --git a/Userland/DevTools/HackStudio/LanguageClient.h b/Userland/DevTools/HackStudio/LanguageClient.h index 7d1e45101f..e918bd4351 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.h +++ b/Userland/DevTools/HackStudio/LanguageClient.h @@ -31,7 +31,7 @@ class ConnectionToServer friend class ConnectionToServerWrapper; public: - ConnectionToServer(NonnullOwnPtr socket, DeprecatedString const& project_path) + ConnectionToServer(NonnullOwnPtr socket, DeprecatedString const& project_path) : IPC::ConnectionToServer(*this, move(socket)) { m_project_path = project_path; diff --git a/Userland/DevTools/HackStudio/LanguageClients/ConnectionsToServer.h b/Userland/DevTools/HackStudio/LanguageClients/ConnectionsToServer.h index f79ec41484..3433516914 100644 --- a/Userland/DevTools/HackStudio/LanguageClients/ConnectionsToServer.h +++ b/Userland/DevTools/HackStudio/LanguageClients/ConnectionsToServer.h @@ -12,22 +12,22 @@ #include #include -#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 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 socket, DeprecatedString const& project_path) \ + : HackStudio::ConnectionToServer(move(socket), project_path) \ + { \ + } \ + }; \ } namespace LanguageClients { diff --git a/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.cpp b/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.cpp index 500b3be695..fa3d664e27 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.cpp @@ -14,7 +14,7 @@ namespace LanguageServers { static HashMap> s_connections; -ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr socket) +ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr socket) : IPC::ConnectionFromClient(*this, move(socket), 1) { s_connections.set(1, *this); diff --git a/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.h b/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.h index 17facfe8f9..59affb06c2 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.h +++ b/Userland/DevTools/HackStudio/LanguageServers/ConnectionFromClient.h @@ -21,7 +21,7 @@ namespace LanguageServers { class ConnectionFromClient : public IPC::ConnectionFromClient { public: - explicit ConnectionFromClient(NonnullOwnPtr); + explicit ConnectionFromClient(NonnullOwnPtr); ~ConnectionFromClient() override = default; virtual void die() override; diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ConnectionFromClient.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ConnectionFromClient.h index 17fa4b45ea..360788c91a 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ConnectionFromClient.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ConnectionFromClient.h @@ -15,7 +15,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient C_OBJECT(ConnectionFromClient); private: - ConnectionFromClient(NonnullOwnPtr socket) + ConnectionFromClient(NonnullOwnPtr socket) : LanguageServers::ConnectionFromClient(move(socket)) { m_autocomplete_engine = adopt_own(*new CodeComprehension::Cpp::CppComprehensionEngine(m_filedb)); diff --git a/Userland/DevTools/HackStudio/LanguageServers/Shell/ConnectionFromClient.h b/Userland/DevTools/HackStudio/LanguageServers/Shell/ConnectionFromClient.h index 6471b3c659..44a0f1a30c 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Shell/ConnectionFromClient.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Shell/ConnectionFromClient.h @@ -16,7 +16,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient C_OBJECT(ConnectionFromClient); private: - ConnectionFromClient(NonnullOwnPtr socket) + ConnectionFromClient(NonnullOwnPtr socket) : LanguageServers::ConnectionFromClient(move(socket)) { m_autocomplete_engine = make(m_filedb); diff --git a/Userland/DevTools/Inspector/InspectorServerClient.h b/Userland/DevTools/Inspector/InspectorServerClient.h index a67148117a..d03ab0a2c2 100644 --- a/Userland/DevTools/Inspector/InspectorServerClient.h +++ b/Userland/DevTools/Inspector/InspectorServerClient.h @@ -21,7 +21,7 @@ public: virtual ~InspectorServerClient() override = default; private: - InspectorServerClient(NonnullOwnPtr socket) + InspectorServerClient(NonnullOwnPtr socket) : IPC::ConnectionToServer(*this, move(socket)) { } diff --git a/Userland/Libraries/LibAudio/ConnectionToServer.cpp b/Userland/Libraries/LibAudio/ConnectionToServer.cpp index 795a4a0211..ab46dd8a20 100644 --- a/Userland/Libraries/LibAudio/ConnectionToServer.cpp +++ b/Userland/Libraries/LibAudio/ConnectionToServer.cpp @@ -20,7 +20,7 @@ namespace Audio { -ConnectionToServer::ConnectionToServer(NonnullOwnPtr socket) +ConnectionToServer::ConnectionToServer(NonnullOwnPtr socket) : IPC::ConnectionToServer(*this, move(socket)) , m_buffer(make(MUST(AudioQueue::create()))) , m_user_queue(make()) diff --git a/Userland/Libraries/LibAudio/ConnectionToServer.h b/Userland/Libraries/LibAudio/ConnectionToServer.h index c98ecb973e..7bab23c407 100644 --- a/Userland/Libraries/LibAudio/ConnectionToServer.h +++ b/Userland/Libraries/LibAudio/ConnectionToServer.h @@ -62,7 +62,7 @@ public: Function on_client_volume_change; private: - ConnectionToServer(NonnullOwnPtr); + ConnectionToServer(NonnullOwnPtr); virtual void main_mix_muted_state_changed(bool) override; virtual void main_mix_volume_changed(double) override; diff --git a/Userland/Libraries/LibCodeComprehension/Cpp/ConnectionFromClient.h b/Userland/Libraries/LibCodeComprehension/Cpp/ConnectionFromClient.h index f609a7f270..2b8428eab5 100644 --- a/Userland/Libraries/LibCodeComprehension/Cpp/ConnectionFromClient.h +++ b/Userland/Libraries/LibCodeComprehension/Cpp/ConnectionFromClient.h @@ -15,7 +15,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient C_OBJECT(ConnectionFromClient); private: - ConnectionFromClient(NonnullOwnPtr socket) + ConnectionFromClient(NonnullOwnPtr socket) : LanguageServers::ConnectionFromClient(move(socket)) { m_autocomplete_engine = make(m_filedb); diff --git a/Userland/Libraries/LibCodeComprehension/Shell/ConnectionFromClient.h b/Userland/Libraries/LibCodeComprehension/Shell/ConnectionFromClient.h index 960f088b44..e461bc51ea 100644 --- a/Userland/Libraries/LibCodeComprehension/Shell/ConnectionFromClient.h +++ b/Userland/Libraries/LibCodeComprehension/Shell/ConnectionFromClient.h @@ -16,7 +16,7 @@ class ConnectionFromClient final : public LanguageServers::ConnectionFromClient C_OBJECT(ConnectionFromClient); private: - ConnectionFromClient(NonnullOwnPtr socket) + ConnectionFromClient(NonnullOwnPtr socket) : LanguageServers::ConnectionFromClient(move(socket)) { m_autocomplete_engine = make(m_filedb); diff --git a/Userland/Libraries/LibConfig/Client.h b/Userland/Libraries/LibConfig/Client.h index 3c711fc97f..00b3a8353a 100644 --- a/Userland/Libraries/LibConfig/Client.h +++ b/Userland/Libraries/LibConfig/Client.h @@ -42,7 +42,7 @@ public: static Client& the(); private: - explicit Client(NonnullOwnPtr socket) + explicit Client(NonnullOwnPtr socket) : IPC::ConnectionToServer(*this, move(socket)) { } diff --git a/Userland/Libraries/LibCore/CMakeLists.txt b/Userland/Libraries/LibCore/CMakeLists.txt index 7d32e1b1a1..1c0e3577f5 100644 --- a/Userland/Libraries/LibCore/CMakeLists.txt +++ b/Userland/Libraries/LibCore/CMakeLists.txt @@ -22,6 +22,7 @@ set(SOURCES Property.cpp SecretString.cpp SessionManagement.cpp + Socket.cpp SOCKSProxyClient.cpp StandardPaths.cpp Stream.cpp diff --git a/Userland/Libraries/LibCore/EventLoop.cpp b/Userland/Libraries/LibCore/EventLoop.cpp index 9fbcc76dc5..23c8866413 100644 --- a/Userland/Libraries/LibCore/EventLoop.cpp +++ b/Userland/Libraries/LibCore/EventLoop.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -156,7 +157,7 @@ pid_t EventLoop::s_pid; class InspectorServerConnection : public Object { C_OBJECT(InspectorServerConnection) private: - explicit InspectorServerConnection(NonnullOwnPtr socket) + explicit InspectorServerConnection(NonnullOwnPtr 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 m_socket; + NonnullOwnPtr m_socket; WeakPtr 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; diff --git a/Userland/Libraries/LibCore/Forward.h b/Userland/Libraries/LibCore/Forward.h index db97705312..dff8a2aad3 100644 --- a/Userland/Libraries/LibCore/Forward.h +++ b/Userland/Libraries/LibCore/Forward.h @@ -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; } } diff --git a/Userland/Libraries/LibCore/LocalServer.cpp b/Userland/Libraries/LibCore/LocalServer.cpp index 05aab22951..c15576b25c 100644 --- a/Userland/Libraries/LibCore/LocalServer.cpp +++ b/Userland/Libraries/LibCore/LocalServer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -113,7 +114,7 @@ bool LocalServer::listen(DeprecatedString const& address) return true; } -ErrorOr> LocalServer::accept() +ErrorOr> LocalServer::accept() { VERIFY(m_listening); sockaddr_un un; @@ -133,7 +134,7 @@ ErrorOr> 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); } } diff --git a/Userland/Libraries/LibCore/LocalServer.h b/Userland/Libraries/LibCore/LocalServer.h index c93a049f90..f5ed840cca 100644 --- a/Userland/Libraries/LibCore/LocalServer.h +++ b/Userland/Libraries/LibCore/LocalServer.h @@ -21,9 +21,9 @@ public: bool is_listening() const { return m_listening; } bool listen(DeprecatedString const& address); - ErrorOr> accept(); + ErrorOr> accept(); - Function)> on_accept; + Function)> on_accept; Function on_accept_error; private: diff --git a/Userland/Libraries/LibCore/NetworkJob.cpp b/Userland/Libraries/LibCore/NetworkJob.cpp index 3169c0b846..d83814f503 100644 --- a/Userland/Libraries/LibCore/NetworkJob.cpp +++ b/Userland/Libraries/LibCore/NetworkJob.cpp @@ -16,7 +16,7 @@ NetworkJob::NetworkJob(AK::Stream& output_stream) { } -void NetworkJob::start(Core::Stream::Socket&) +void NetworkJob::start(Core::Socket&) { } diff --git a/Userland/Libraries/LibCore/NetworkJob.h b/Userland/Libraries/LibCore/NetworkJob.h index 7d561bea20..ae19ea7a09 100644 --- a/Userland/Libraries/LibCore/NetworkJob.h +++ b/Userland/Libraries/LibCore/NetworkJob.h @@ -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); } diff --git a/Userland/Libraries/LibCore/SOCKSProxyClient.cpp b/Userland/Libraries/LibCore/SOCKSProxyClient.cpp index f658e5e274..61f3cfaa6c 100644 --- a/Userland/Libraries/LibCore/SOCKSProxyClient.cpp +++ b/Userland/Libraries/LibCore/SOCKSProxyClient.cpp @@ -95,7 +95,7 @@ StringView reply_response_name(Reply reply) VERIFY_NOT_REACHED(); } -ErrorOr send_version_identifier_and_method_selection_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::Version version, Method method) +ErrorOr 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 send_version_identifier_and_method_selection_message(Core::Stream: return {}; } -ErrorOr send_connect_request_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::Version version, Core::SOCKSProxyClient::HostOrIPV4 target, int port, Core::SOCKSProxyClient::Command command) +ErrorOr 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 send_connect_request_message(Core::Stream::Socket& socket, Core:: return Reply(response_header.status); } -ErrorOr send_username_password_authentication_message(Core::Stream::Socket& socket, Core::SOCKSProxyClient::UsernamePasswordAuthenticationData const& auth_data) +ErrorOr send_username_password_authentication_message(Core::Socket& socket, Core::SOCKSProxyClient::UsernamePasswordAuthenticationData const& auth_data) { AllocatingMemoryStream stream; @@ -314,10 +314,10 @@ ErrorOr> SOCKSProxyClient::connect(HostOrIPV4 co { auto underlying = TRY(server.visit( [&](u32 ipv4) { - return Core::Stream::TCPSocket::connect({ IPv4Address(ipv4), static_cast(server_port) }); + return Core::TCPSocket::connect({ IPv4Address(ipv4), static_cast(server_port) }); }, [&](DeprecatedString const& hostname) { - return Core::Stream::TCPSocket::connect(hostname, static_cast(server_port)); + return Core::TCPSocket::connect(hostname, static_cast(server_port)); })); auto socket = TRY(connect(*underlying, version, target, target_port, auth_data, command)); diff --git a/Userland/Libraries/LibCore/SOCKSProxyClient.h b/Userland/Libraries/LibCore/SOCKSProxyClient.h index e2efe52448..e63991cb65 100644 --- a/Userland/Libraries/LibCore/SOCKSProxyClient.h +++ b/Userland/Libraries/LibCore/SOCKSProxyClient.h @@ -8,10 +8,11 @@ #include #include +#include #include namespace Core { -class SOCKSProxyClient final : public Stream::Socket { +class SOCKSProxyClient final : public Socket { public: enum class Version : u8 { V4 = 0x04, diff --git a/Userland/Libraries/LibCore/Socket.cpp b/Userland/Libraries/LibCore/Socket.cpp new file mode 100644 index 0000000000..4e3808c191 --- /dev/null +++ b/Userland/Libraries/LibCore/Socket.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, sin-ack + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Core { + +ErrorOr 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 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(result.ai_addr); + NetworkOrdered 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 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(&addr), sizeof(addr)); +} + +ErrorOr Socket::connect_inet(int fd, SocketAddress const& address) +{ + auto addr = address.to_sockaddr_in(); + return System::connect(fd, bit_cast(&addr), sizeof(addr)); +} + +ErrorOr 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 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 result; + do { + result = System::close(m_fd); + } while (result.is_error() && result.error().code() == EINTR); + + VERIFY(!result.is_error()); + m_fd = -1; +} + +ErrorOr PosixSocketHelper::can_read_without_blocking(int timeout) const +{ + struct pollfd the_fd = { .fd = m_fd, .events = POLLIN, .revents = 0 }; + + ErrorOr 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 PosixSocketHelper::set_blocking(bool enabled) +{ + int value = enabled ? 0 : 1; + return System::ioctl(m_fd, FIONBIO, &value); +} + +ErrorOr 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 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> TCPSocket::connect(DeprecatedString const& host, u16 port) +{ + auto ip_address = TRY(resolve_host(host, SocketType::Stream)); + return connect(SocketAddress { ip_address, port }); +} + +ErrorOr> 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> 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 PosixSocketHelper::pending_bytes() const +{ + if (!is_open()) { + return Error::from_errno(ENOTCONN); + } + + int value; + TRY(System::ioctl(m_fd, FIONREAD, &value)); + return static_cast(value); +} + +ErrorOr> UDPSocket::connect(DeprecatedString const& host, u16 port, Optional