From 9a5bcc6db0c58459b63d25fede1945b7ebef67a8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 10 Aug 2017 19:13:18 +0200 Subject: [PATCH] net/ServerSocket: pass UniqueSocketDescriptor&& to OnAccept() --- src/Listen.cxx | 5 +++-- src/client/Client.hxx | 5 +++-- src/client/ClientNew.cxx | 16 ++++++++-------- src/event/ServerSocket.cxx | 4 ++-- src/event/ServerSocket.hxx | 4 +++- src/output/plugins/httpd/HttpdClient.cxx | 5 +++-- src/output/plugins/httpd/HttpdClient.hxx | 4 +++- src/output/plugins/httpd/HttpdInternal.hxx | 5 +++-- src/output/plugins/httpd/HttpdOutputPlugin.cxx | 15 +++++++-------- 9 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/Listen.cxx b/src/Listen.cxx index ab08050db..3faccc954 100644 --- a/src/Listen.cxx +++ b/src/Listen.cxx @@ -50,9 +50,10 @@ public: :ServerSocket(_loop), partition(_partition) {} private: - void OnAccept(int fd, SocketAddress address, int uid) override { + void OnAccept(UniqueSocketDescriptor &&fd, + SocketAddress address, int uid) override { client_new(GetEventLoop(), partition, - SocketDescriptor(fd), address, uid); + std::move(fd), address, uid); } }; diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 1b7bcab50..6c895006c 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -38,6 +38,7 @@ #include class SocketAddress; +class UniqueSocketDescriptor; class EventLoop; class Path; struct Instance; @@ -94,7 +95,7 @@ public: std::list messages; Client(EventLoop &loop, Partition &partition, - SocketDescriptor fd, int uid, int num); + UniqueSocketDescriptor &&fd, int uid, int num); ~Client() { if (FullyBufferedSocket::IsDefined()) @@ -236,7 +237,7 @@ client_manager_init(); void client_new(EventLoop &loop, Partition &partition, - SocketDescriptor fd, SocketAddress address, int uid); + UniqueSocketDescriptor &&fd, SocketAddress address, int uid); /** * Write a printf-like formatted string to the client. diff --git a/src/client/ClientNew.cxx b/src/client/ClientNew.cxx index 6099acf4a..0b95b79b7 100644 --- a/src/client/ClientNew.cxx +++ b/src/client/ClientNew.cxx @@ -23,6 +23,7 @@ #include "Partition.hxx" #include "Instance.hxx" #include "system/fd_util.h" +#include "net/UniqueSocketDescriptor.hxx" #include "net/SocketAddress.hxx" #include "net/ToString.hxx" #include "Permission.hxx" @@ -42,8 +43,9 @@ static const char GREETING[] = "OK MPD " PROTOCOL_VERSION "\n"; Client::Client(EventLoop &_loop, Partition &_partition, - SocketDescriptor _fd, int _uid, int _num) - :FullyBufferedSocket(_fd, _loop, 16384, client_max_output_buffer_size), + UniqueSocketDescriptor &&_fd, int _uid, int _num) + :FullyBufferedSocket(_fd.Release(), _loop, + 16384, client_max_output_buffer_size), TimeoutMonitor(_loop), partition(&_partition), permission(getDefaultPermissions()), @@ -57,7 +59,7 @@ Client::Client(EventLoop &_loop, Partition &_partition, void client_new(EventLoop &loop, Partition &partition, - SocketDescriptor fd, SocketAddress address, int uid) + UniqueSocketDescriptor &&fd, SocketAddress address, int uid) { static unsigned int next_client_num; const auto remote = ToString(address); @@ -80,7 +82,6 @@ client_new(EventLoop &loop, Partition &partition, "libwrap refused connection (libwrap=%s) from %s", progname, remote.c_str()); - fd.Close(); return; } } @@ -89,15 +90,14 @@ client_new(EventLoop &loop, Partition &partition, ClientList &client_list = *partition.instance.client_list; if (client_list.IsFull()) { LogWarning(client_domain, "Max connections reached"); - fd.Close(); return; } - Client *client = new Client(loop, partition, fd, uid, - next_client_num++); - (void)fd.Write(GREETING, sizeof(GREETING) - 1); + Client *client = new Client(loop, partition, std::move(fd), uid, + next_client_num++); + client_list.Add(*client); FormatInfo(client_domain, "[%u] opened from %s", diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx index 3d3716f10..85cf93dbe 100644 --- a/src/event/ServerSocket.cxx +++ b/src/event/ServerSocket.cxx @@ -150,7 +150,7 @@ inline void OneServerSocket::Accept() noexcept { StaticSocketAddress peer_address; - auto peer_fd = Get().AcceptNonBlock(peer_address); + UniqueSocketDescriptor peer_fd(Get().AcceptNonBlock(peer_address)); if (!peer_fd.IsDefined()) { const SocketErrorMessage msg; FormatError(server_socket_domain, @@ -165,7 +165,7 @@ OneServerSocket::Accept() noexcept (const char *)msg); } - parent.OnAccept(peer_fd.Get(), peer_address, + parent.OnAccept(std::move(peer_fd), peer_address, get_remote_uid(peer_fd.Get())); } diff --git a/src/event/ServerSocket.hxx b/src/event/ServerSocket.hxx index 875bdd3bb..9e44143e3 100644 --- a/src/event/ServerSocket.hxx +++ b/src/event/ServerSocket.hxx @@ -24,6 +24,7 @@ class SocketAddress; class AllocatedSocketAddress; +class UniqueSocketDescriptor; class EventLoop; class AllocatedPath; class OneServerSocket; @@ -116,7 +117,8 @@ public: void Close(); protected: - virtual void OnAccept(int fd, SocketAddress address, int uid) = 0; + virtual void OnAccept(UniqueSocketDescriptor &&fd, + SocketAddress address, int uid) = 0; }; #endif diff --git a/src/output/plugins/httpd/HttpdClient.cxx b/src/output/plugins/httpd/HttpdClient.cxx index d37ce5ff4..c62cd17e1 100644 --- a/src/output/plugins/httpd/HttpdClient.cxx +++ b/src/output/plugins/httpd/HttpdClient.cxx @@ -25,6 +25,7 @@ #include "Page.hxx" #include "IcyMetaDataServer.hxx" #include "net/SocketError.hxx" +#include "net/UniqueSocketDescriptor.hxx" #include "Log.hxx" #include @@ -185,10 +186,10 @@ HttpdClient::SendResponse() return true; } -HttpdClient::HttpdClient(HttpdOutput &_httpd, SocketDescriptor _fd, +HttpdClient::HttpdClient(HttpdOutput &_httpd, UniqueSocketDescriptor &&_fd, EventLoop &_loop, bool _metadata_supported) - :BufferedSocket(_fd, _loop), + :BufferedSocket(_fd.Release(), _loop), httpd(_httpd), state(REQUEST), queue_size(0), diff --git a/src/output/plugins/httpd/HttpdClient.hxx b/src/output/plugins/httpd/HttpdClient.hxx index b4da2cd4c..128e17eeb 100644 --- a/src/output/plugins/httpd/HttpdClient.hxx +++ b/src/output/plugins/httpd/HttpdClient.hxx @@ -32,6 +32,7 @@ #include +class UniqueSocketDescriptor; class HttpdOutput; class HttpdClient final @@ -131,7 +132,8 @@ public: * @param httpd the HTTP output device * @param _fd the socket file descriptor */ - HttpdClient(HttpdOutput &httpd, SocketDescriptor _fd, EventLoop &_loop, + HttpdClient(HttpdOutput &httpd, UniqueSocketDescriptor &&_fd, + EventLoop &_loop, bool _metadata_supported); /** diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx index 3dd7d1d0c..f7df99c57 100644 --- a/src/output/plugins/httpd/HttpdInternal.hxx +++ b/src/output/plugins/httpd/HttpdInternal.hxx @@ -206,7 +206,7 @@ public: return HasClients(); } - void AddClient(SocketDescriptor fd); + void AddClient(UniqueSocketDescriptor &&fd); /** * Removes a client from the httpd_output.clients linked list. @@ -257,7 +257,8 @@ public: private: virtual void RunDeferred() override; - void OnAccept(int fd, SocketAddress address, int uid) override; + void OnAccept(UniqueSocketDescriptor &&fd, + SocketAddress address, int uid) override; }; extern const class Domain httpd_output_domain; diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx index 216061e53..2f876de62 100644 --- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx +++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx @@ -25,6 +25,7 @@ #include "encoder/EncoderInterface.hxx" #include "encoder/EncoderPlugin.hxx" #include "encoder/EncoderList.hxx" +#include "net/UniqueSocketDescriptor.hxx" #include "net/SocketAddress.hxx" #include "net/ToString.hxx" #include "Page.hxx" @@ -118,9 +119,9 @@ HttpdOutput::Unbind() * HttpdOutput.clients linked list. */ inline void -HttpdOutput::AddClient(SocketDescriptor fd) +HttpdOutput::AddClient(UniqueSocketDescriptor &&fd) { - auto *client = new HttpdClient(*this, fd, GetEventLoop(), + auto *client = new HttpdClient(*this, std::move(fd), GetEventLoop(), !encoder->ImplementsTag()); clients.push_front(*client); @@ -151,7 +152,8 @@ HttpdOutput::RunDeferred() } void -HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid) +HttpdOutput::OnAccept(UniqueSocketDescriptor &&fd, + SocketAddress address, gcc_unused int uid) { /* the listener socket has become readable - a client has connected */ @@ -163,7 +165,7 @@ HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid) const char *progname = "mpd"; struct request_info req; - request_init(&req, RQ_FILE, fd, RQ_DAEMON, progname, 0); + request_init(&req, RQ_FILE, fd.Get(), RQ_DAEMON, progname, 0); fromhost(&req); @@ -172,7 +174,6 @@ HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid) FormatWarning(httpd_output_domain, "libwrap refused connection (libwrap=%s) from %s", progname, hostaddr.c_str()); - close_socket(fd); return; } } @@ -184,9 +185,7 @@ HttpdOutput::OnAccept(int fd, SocketAddress address, gcc_unused int uid) /* can we allow additional client */ if (open && (clients_max == 0 || clients.size() < clients_max)) - AddClient(SocketDescriptor(fd)); - else - close_socket(fd); + AddClient(std::move(fd)); } PagePtr