diff options
Diffstat (limited to 'src/event/ServerSocket.cxx')
-rw-r--r-- | src/event/ServerSocket.cxx | 98 |
1 files changed, 53 insertions, 45 deletions
diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx index 313f0a6cf..f82c533c3 100644 --- a/src/event/ServerSocket.cxx +++ b/src/event/ServerSocket.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,10 +19,14 @@ #include "config.h" #include "ServerSocket.hxx" -#include "system/SocketUtil.hxx" -#include "system/SocketError.hxx" +#include "net/StaticSocketAddress.hxx" +#include "net/AllocatedSocketAddress.hxx" +#include "net/SocketAddress.hxx" +#include "net/SocketUtil.hxx" +#include "net/SocketError.hxx" +#include "net/Resolver.hxx" +#include "net/ToString.hxx" #include "event/SocketMonitor.hxx" -#include "system/Resolver.hxx" #include "system/fd_util.h" #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" @@ -52,39 +56,35 @@ #include <netdb.h> #endif -#define DEFAULT_PORT 6600 - class OneServerSocket final : private SocketMonitor { ServerSocket &parent; const unsigned serial; +#ifdef HAVE_UN AllocatedPath path; +#endif - size_t address_length; - struct sockaddr *address; + const AllocatedSocketAddress address; public: + template<typename A> OneServerSocket(EventLoop &_loop, ServerSocket &_parent, unsigned _serial, - const struct sockaddr *_address, - size_t _address_length) + A &&_address) :SocketMonitor(_loop), parent(_parent), serial(_serial), +#ifdef HAVE_UN path(AllocatedPath::Null()), - address_length(_address_length), - address((sockaddr *)xmemdup(_address, _address_length)) +#endif + address(std::forward<A>(_address)) { - assert(_address != nullptr); - assert(_address_length > 0); } OneServerSocket(const OneServerSocket &other) = delete; OneServerSocket &operator=(const OneServerSocket &other) = delete; ~OneServerSocket() { - free(address); - if (IsDefined()) Close(); } @@ -93,11 +93,13 @@ public: return serial; } +#ifdef HAVE_UN void SetPath(AllocatedPath &&_path) { assert(path.IsNull()); path = std::move(_path); } +#endif bool Open(Error &error); @@ -106,7 +108,7 @@ public: gcc_pure std::string ToString() const { - return sockaddr_to_string(address, address_length); + return ::ToString(address); } void SetFD(int _fd) { @@ -150,10 +152,10 @@ get_remote_uid(int fd) inline void OneServerSocket::Accept() { - struct sockaddr_storage peer_address; + StaticSocketAddress peer_address; size_t peer_address_length = sizeof(peer_address); int peer_fd = - accept_cloexec_nonblock(Get(), (struct sockaddr*)&peer_address, + accept_cloexec_nonblock(Get(), peer_address.GetAddress(), &peer_address_length); if (peer_fd < 0) { const SocketErrorMessage msg; @@ -162,6 +164,8 @@ OneServerSocket::Accept() return; } + peer_address.SetSize(peer_address_length); + if (socket_keepalive(peer_fd)) { const SocketErrorMessage msg; FormatError(server_socket_domain, @@ -169,9 +173,8 @@ OneServerSocket::Accept() (const char *)msg); } - parent.OnAccept(peer_fd, - (const sockaddr &)peer_address, - peer_address_length, get_remote_uid(peer_fd)); + parent.OnAccept(peer_fd, peer_address, + get_remote_uid(peer_fd)); } bool @@ -186,19 +189,21 @@ OneServerSocket::Open(Error &error) { assert(!IsDefined()); - int _fd = socket_bind_listen(address->sa_family, + int _fd = socket_bind_listen(address.GetFamily(), SOCK_STREAM, 0, - address, address_length, 5, + address, 5, error); if (_fd < 0) return false; +#ifdef HAVE_UN /* allow everybody to connect */ if (!path.IsNull()) chmod(path.c_str(), 0666); +#endif - /* register in the GLib main loop */ + /* register in the EventLoop */ SetFD(_fd); @@ -282,10 +287,19 @@ ServerSocket::Close() } OneServerSocket & -ServerSocket::AddAddress(const sockaddr &address, size_t address_length) +ServerSocket::AddAddress(SocketAddress address) { sockets.emplace_back(loop, *this, next_serial, - &address, address_length); + address); + + return sockets.back(); +} + +OneServerSocket & +ServerSocket::AddAddress(AllocatedSocketAddress &&address) +{ + sockets.emplace_back(loop, *this, next_serial, + std::move(address)); return sockets.back(); } @@ -295,17 +309,18 @@ ServerSocket::AddFD(int fd, Error &error) { assert(fd >= 0); - struct sockaddr_storage address; + StaticSocketAddress address; socklen_t address_length = sizeof(address); - if (getsockname(fd, (struct sockaddr *)&address, + if (getsockname(fd, address.GetAddress(), &address_length) < 0) { SetSocketError(error); error.AddPrefix("Failed to get socket address: "); return false; } - OneServerSocket &s = AddAddress((const sockaddr &)address, - address_length); + address.SetSize(address_length); + + OneServerSocket &s = AddAddress(address); s.SetFD(fd); return true; @@ -322,7 +337,7 @@ ServerSocket::AddPortIPv4(unsigned port) sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; - AddAddress((const sockaddr &)sin, sizeof(sin)); + AddAddress({(const sockaddr *)&sin, sizeof(sin)}); } #ifdef HAVE_IPV6 @@ -335,7 +350,7 @@ ServerSocket::AddPortIPv6(unsigned port) sin.sin6_port = htons(port); sin.sin6_family = AF_INET6; - AddAddress((const sockaddr &)sin, sizeof(sin)); + AddAddress({(const sockaddr *)&sin, sizeof(sin)}); } /** @@ -394,7 +409,7 @@ ServerSocket::AddHost(const char *hostname, unsigned port, Error &error) return false; for (const struct addrinfo *i = ai; i != nullptr; i = i->ai_next) - AddAddress(*i->ai_addr, i->ai_addrlen); + AddAddress(SocketAddress(i->ai_addr, i->ai_addrlen)); freeaddrinfo(ai); @@ -414,21 +429,14 @@ bool ServerSocket::AddPath(AllocatedPath &&path, Error &error) { #ifdef HAVE_UN - struct sockaddr_un s_un; - - const size_t path_length = path.length(); - if (path_length >= sizeof(s_un.sun_path)) { - error.Set(server_socket_domain, - "UNIX socket path is too long"); - return false; - } + (void)error; RemoveFile(path); - s_un.sun_family = AF_UNIX; - memcpy(s_un.sun_path, path.c_str(), path_length + 1); + AllocatedSocketAddress address; + address.SetLocal(path.c_str()); - OneServerSocket &s = AddAddress((const sockaddr &)s_un, sizeof(s_un)); + OneServerSocket &s = AddAddress(std::move(address)); s.SetPath(std::move(path)); return true; |