aboutsummaryrefslogtreecommitdiffstats
path: root/src/event/ServerSocket.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/ServerSocket.cxx')
-rw-r--r--src/event/ServerSocket.cxx98
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;