Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
aead2211
Commit
aead2211
authored
Oct 28, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event/ServerSocket: migrate from class Error to C++ exceptions
parent
16d1c9f5
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
154 additions
and
178 deletions
+154
-178
Listen.cxx
src/Listen.cxx
+30
-32
Listen.hxx
src/Listen.hxx
+2
-3
Main.cxx
src/Main.cxx
+1
-5
ServerSocket.cxx
src/event/ServerSocket.cxx
+40
-68
ServerSocket.hxx
src/event/ServerSocket.hxx
+17
-9
Resolver.cxx
src/net/Resolver.cxx
+4
-11
Resolver.hxx
src/net/Resolver.hxx
+4
-7
SocketError.hxx
src/net/SocketError.hxx
+19
-0
SocketUtil.cxx
src/net/SocketUtil.cxx
+9
-15
SocketUtil.hxx
src/net/SocketUtil.hxx
+4
-4
HttpdInternal.hxx
src/output/plugins/httpd/HttpdInternal.hxx
+1
-1
HttpdOutputPlugin.cxx
src/output/plugins/httpd/HttpdOutputPlugin.cxx
+16
-14
run_resolver.cxx
test/run_resolver.cxx
+7
-9
No files found.
src/Listen.cxx
View file @
aead2211
...
@@ -25,7 +25,8 @@
...
@@ -25,7 +25,8 @@
#include "config/ConfigOption.hxx"
#include "config/ConfigOption.hxx"
#include "net/SocketAddress.hxx"
#include "net/SocketAddress.hxx"
#include "event/ServerSocket.hxx"
#include "event/ServerSocket.hxx"
#include "util/Error.hxx"
#include "system/Error.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include "util/Domain.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/AllocatedPath.hxx"
#include "Log.hxx"
#include "Log.hxx"
...
@@ -58,50 +59,47 @@ private:
...
@@ -58,50 +59,47 @@ private:
static
ClientListener
*
listen_socket
;
static
ClientListener
*
listen_socket
;
int
listen_port
;
int
listen_port
;
static
bool
/**
* Throws #std::runtime_error on error.
*/
static
void
listen_add_config_param
(
unsigned
int
port
,
listen_add_config_param
(
unsigned
int
port
,
const
ConfigParam
*
param
,
const
ConfigParam
*
param
)
Error
&
error_r
)
{
{
assert
(
param
!=
nullptr
);
assert
(
param
!=
nullptr
);
if
(
0
==
strcmp
(
param
->
value
.
c_str
(),
"any"
))
{
if
(
0
==
strcmp
(
param
->
value
.
c_str
(),
"any"
))
{
return
listen_socket
->
AddPort
(
port
,
error_r
);
listen_socket
->
AddPort
(
port
);
}
else
if
(
param
->
value
[
0
]
==
'/'
||
param
->
value
[
0
]
==
'~'
)
{
}
else
if
(
param
->
value
[
0
]
==
'/'
||
param
->
value
[
0
]
==
'~'
)
{
auto
path
=
param
->
GetPath
(
error_r
);
listen_socket
->
AddPath
(
param
->
GetPath
());
return
!
path
.
IsNull
()
&&
listen_socket
->
AddPath
(
std
::
move
(
path
),
error_r
);
}
else
{
}
else
{
return
listen_socket
->
AddHost
(
param
->
value
.
c_str
(),
port
,
listen_socket
->
AddHost
(
param
->
value
.
c_str
(),
port
);
error_r
);
}
}
}
}
#ifdef ENABLE_SYSTEMD_DAEMON
#ifdef ENABLE_SYSTEMD_DAEMON
static
bool
static
bool
listen_systemd_activation
(
Error
&
error_r
)
listen_systemd_activation
()
{
{
int
n
=
sd_listen_fds
(
true
);
int
n
=
sd_listen_fds
(
true
);
if
(
n
<=
0
)
{
if
(
n
<=
0
)
{
if
(
n
<
0
)
if
(
n
<
0
)
FormatErrno
(
listen_domain
,
-
n
,
throw
MakeErrno
(
-
n
,
"sd_listen_fds() failed"
);
"sd_listen_fds() failed"
);
return
false
;
return
false
;
}
}
for
(
int
i
=
SD_LISTEN_FDS_START
,
end
=
SD_LISTEN_FDS_START
+
n
;
for
(
int
i
=
SD_LISTEN_FDS_START
,
end
=
SD_LISTEN_FDS_START
+
n
;
i
!=
end
;
++
i
)
i
!=
end
;
++
i
)
if
(
!
listen_socket
->
AddFD
(
i
,
error_r
))
listen_socket
->
AddFD
(
i
);
return
false
;
return
true
;
return
true
;
}
}
#endif
#endif
bool
void
listen_global_init
(
EventLoop
&
loop
,
Partition
&
partition
,
Error
&
error
)
listen_global_init
(
EventLoop
&
loop
,
Partition
&
partition
)
{
{
int
port
=
config_get_positive
(
ConfigOption
::
PORT
,
DEFAULT_PORT
);
int
port
=
config_get_positive
(
ConfigOption
::
PORT
,
DEFAULT_PORT
);
const
auto
*
param
=
config_get_param
(
ConfigOption
::
BIND_TO_ADDRESS
);
const
auto
*
param
=
config_get_param
(
ConfigOption
::
BIND_TO_ADDRESS
);
...
@@ -109,11 +107,8 @@ listen_global_init(EventLoop &loop, Partition &partition, Error &error)
...
@@ -109,11 +107,8 @@ listen_global_init(EventLoop &loop, Partition &partition, Error &error)
listen_socket
=
new
ClientListener
(
loop
,
partition
);
listen_socket
=
new
ClientListener
(
loop
,
partition
);
#ifdef ENABLE_SYSTEMD_DAEMON
#ifdef ENABLE_SYSTEMD_DAEMON
if
(
listen_systemd_activation
(
error
))
if
(
listen_systemd_activation
())
return
true
;
return
;
if
(
error
.
IsDefined
())
return
false
;
#endif
#endif
if
(
param
!=
nullptr
)
{
if
(
param
!=
nullptr
)
{
...
@@ -121,32 +116,35 @@ listen_global_init(EventLoop &loop, Partition &partition, Error &error)
...
@@ -121,32 +116,35 @@ listen_global_init(EventLoop &loop, Partition &partition, Error &error)
for all values */
for all values */
do
{
do
{
if
(
!
listen_add_config_param
(
port
,
param
,
error
))
{
try
{
listen_add_config_param
(
port
,
param
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
delete
listen_socket
;
delete
listen_socket
;
error
.
FormatPrefix
(
"Failed to listen on %s (line %i):
"
,
std
::
throw_with_nested
(
FormatRuntimeError
(
"Failed to listen on %s (line %i)
"
,
param
->
value
.
c_str
(),
param
->
value
.
c_str
(),
param
->
line
);
param
->
line
));
return
false
;
}
}
}
while
((
param
=
param
->
next
)
!=
nullptr
);
}
while
((
param
=
param
->
next
)
!=
nullptr
);
}
else
{
}
else
{
/* no "bind_to_address" configured, bind the
/* no "bind_to_address" configured, bind the
configured port on all interfaces */
configured port on all interfaces */
if
(
!
listen_socket
->
AddPort
(
port
,
error
))
{
try
{
listen_socket
->
AddPort
(
port
);
}
catch
(
const
std
::
runtime_error
&
e
)
{
delete
listen_socket
;
delete
listen_socket
;
error
.
FormatPrefix
(
"Failed to listen on *:%d: "
,
port
);
std
::
throw_with_nested
(
FormatRuntimeError
(
"Failed to listen on *:%d: "
,
port
));
return
false
;
}
}
}
}
if
(
!
listen_socket
->
Open
(
error
))
{
try
{
listen_socket
->
Open
();
}
catch
(
const
std
::
runtime_error
&
e
)
{
delete
listen_socket
;
delete
listen_socket
;
return
false
;
throw
;
}
}
listen_port
=
port
;
listen_port
=
port
;
return
true
;
}
}
void
listen_global_finish
(
void
)
void
listen_global_finish
(
void
)
...
...
src/Listen.hxx
View file @
aead2211
...
@@ -21,13 +21,12 @@
...
@@ -21,13 +21,12 @@
#define MPD_LISTEN_HXX
#define MPD_LISTEN_HXX
class
EventLoop
;
class
EventLoop
;
class
Error
;
struct
Partition
;
struct
Partition
;
extern
int
listen_port
;
extern
int
listen_port
;
bool
void
listen_global_init
(
EventLoop
&
loop
,
Partition
&
partition
,
Error
&
error
);
listen_global_init
(
EventLoop
&
loop
,
Partition
&
partition
);
void
void
listen_global_finish
();
listen_global_finish
();
...
...
src/Main.cxx
View file @
aead2211
...
@@ -465,11 +465,7 @@ try {
...
@@ -465,11 +465,7 @@ try {
initialize_decoder_and_player
();
initialize_decoder_and_player
();
if
(
!
listen_global_init
(
instance
->
event_loop
,
*
instance
->
partition
,
listen_global_init
(
instance
->
event_loop
,
*
instance
->
partition
);
error
))
{
LogError
(
error
);
return
EXIT_FAILURE
;
}
#ifdef ENABLE_DAEMON
#ifdef ENABLE_DAEMON
daemonize_set_user
();
daemonize_set_user
();
...
...
src/event/ServerSocket.cxx
View file @
aead2211
...
@@ -30,8 +30,9 @@
...
@@ -30,8 +30,9 @@
#include "system/fd_util.h"
#include "system/fd_util.h"
#include "fs/AllocatedPath.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/FileSystem.hxx"
#include "fs/FileSystem.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
#include "util/Domain.hxx"
#include "util/Domain.hxx"
#include "util/ScopeExit.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <string>
#include <string>
...
@@ -96,7 +97,7 @@ public:
...
@@ -96,7 +97,7 @@ public:
}
}
#endif
#endif
bool
Open
(
Error
&
error
);
void
Open
(
);
using
SocketMonitor
::
IsDefined
;
using
SocketMonitor
::
IsDefined
;
using
SocketMonitor
::
Close
;
using
SocketMonitor
::
Close
;
...
@@ -179,17 +180,14 @@ OneServerSocket::OnSocketReady(gcc_unused unsigned flags)
...
@@ -179,17 +180,14 @@ OneServerSocket::OnSocketReady(gcc_unused unsigned flags)
return
true
;
return
true
;
}
}
inline
bool
inline
void
OneServerSocket
::
Open
(
Error
&
error
)
OneServerSocket
::
Open
()
{
{
assert
(
!
IsDefined
());
assert
(
!
IsDefined
());
int
_fd
=
socket_bind_listen
(
address
.
GetFamily
(),
int
_fd
=
socket_bind_listen
(
address
.
GetFamily
(),
SOCK_STREAM
,
0
,
SOCK_STREAM
,
0
,
address
,
5
,
address
,
5
);
error
);
if
(
_fd
<
0
)
return
false
;
#ifdef HAVE_UN
#ifdef HAVE_UN
/* allow everybody to connect */
/* allow everybody to connect */
...
@@ -201,8 +199,6 @@ OneServerSocket::Open(Error &error)
...
@@ -201,8 +199,6 @@ OneServerSocket::Open(Error &error)
/* register in the EventLoop */
/* register in the EventLoop */
SetFD
(
_fd
);
SetFD
(
_fd
);
return
true
;
}
}
ServerSocket
::
ServerSocket
(
EventLoop
&
_loop
)
ServerSocket
::
ServerSocket
(
EventLoop
&
_loop
)
...
@@ -212,11 +208,11 @@ ServerSocket::ServerSocket(EventLoop &_loop)
...
@@ -212,11 +208,11 @@ ServerSocket::ServerSocket(EventLoop &_loop)
declaration */
declaration */
ServerSocket
::~
ServerSocket
()
{}
ServerSocket
::~
ServerSocket
()
{}
bool
void
ServerSocket
::
Open
(
Error
&
error
)
ServerSocket
::
Open
()
{
{
OneServerSocket
*
good
=
nullptr
,
*
bad
=
nullptr
;
OneServerSocket
*
good
=
nullptr
,
*
bad
=
nullptr
;
Erro
r
last_error
;
std
::
exception_pt
r
last_error
;
for
(
auto
&
i
:
sockets
)
{
for
(
auto
&
i
:
sockets
)
{
assert
(
i
.
GetSerial
()
>
0
);
assert
(
i
.
GetSerial
()
>
0
);
...
@@ -224,30 +220,32 @@ ServerSocket::Open(Error &error)
...
@@ -224,30 +220,32 @@ ServerSocket::Open(Error &error)
if
(
bad
!=
nullptr
&&
i
.
GetSerial
()
!=
bad
->
GetSerial
())
{
if
(
bad
!=
nullptr
&&
i
.
GetSerial
()
!=
bad
->
GetSerial
())
{
Close
();
Close
();
error
=
std
::
move
(
last_error
);
std
::
rethrow_exception
(
last_error
);
return
false
;
}
}
Error
error2
;
try
{
if
(
!
i
.
Open
(
error2
))
{
i
.
Open
();
}
catch
(
const
std
::
runtime_error
&
e
)
{
if
(
good
!=
nullptr
&&
good
->
GetSerial
()
==
i
.
GetSerial
())
{
if
(
good
!=
nullptr
&&
good
->
GetSerial
()
==
i
.
GetSerial
())
{
const
auto
address_string
=
i
.
ToString
();
const
auto
address_string
=
i
.
ToString
();
const
auto
good_string
=
good
->
ToString
();
const
auto
good_string
=
good
->
ToString
();
Format
Warning
(
server_socket_domain
,
Format
Error
(
e
,
"bind to '%s' failed: %s
"
"bind to '%s' failed
"
"(continuing anyway, because "
"(continuing anyway, because "
"binding to '%s' succeeded)"
,
"binding to '%s' succeeded)"
,
address_string
.
c_str
(),
address_string
.
c_str
(),
error2
.
GetMessage
(),
good_string
.
c_str
());
good_string
.
c_str
());
}
else
if
(
bad
==
nullptr
)
{
}
else
if
(
bad
==
nullptr
)
{
bad
=
&
i
;
bad
=
&
i
;
const
auto
address_string
=
i
.
ToString
();
const
auto
address_string
=
i
.
ToString
();
error2
.
FormatPrefix
(
"Failed to bind to '%s': "
,
address_string
.
c_str
());
last_error
=
std
::
move
(
error2
);
try
{
std
::
throw_with_nested
(
FormatRuntimeError
(
"Failed to bind to '%s'"
,
address_string
.
c_str
()));
}
catch
(...)
{
last_error
=
std
::
current_exception
();
}
}
}
continue
;
continue
;
...
@@ -260,17 +258,14 @@ ServerSocket::Open(Error &error)
...
@@ -260,17 +258,14 @@ ServerSocket::Open(Error &error)
if
(
bad
!=
nullptr
)
{
if
(
bad
!=
nullptr
)
{
bad
=
nullptr
;
bad
=
nullptr
;
last_error
.
Clear
()
;
last_error
=
nullptr
;
}
}
}
}
if
(
bad
!=
nullptr
)
{
if
(
bad
!=
nullptr
)
{
Close
();
Close
();
error
=
std
::
move
(
last_error
);
std
::
rethrow_exception
(
last_error
);
return
false
;
}
}
return
true
;
}
}
void
void
...
@@ -299,26 +294,21 @@ ServerSocket::AddAddress(AllocatedSocketAddress &&address)
...
@@ -299,26 +294,21 @@ ServerSocket::AddAddress(AllocatedSocketAddress &&address)
return
sockets
.
back
();
return
sockets
.
back
();
}
}
bool
void
ServerSocket
::
AddFD
(
int
fd
,
Error
&
error
)
ServerSocket
::
AddFD
(
int
fd
)
{
{
assert
(
fd
>=
0
);
assert
(
fd
>=
0
);
StaticSocketAddress
address
;
StaticSocketAddress
address
;
socklen_t
address_length
=
sizeof
(
address
);
socklen_t
address_length
=
sizeof
(
address
);
if
(
getsockname
(
fd
,
address
.
GetAddress
(),
if
(
getsockname
(
fd
,
address
.
GetAddress
(),
&
address_length
)
<
0
)
{
&
address_length
)
<
0
)
SetSocketError
(
error
);
throw
MakeSocketError
(
"Failed to get socket address"
);
error
.
AddPrefix
(
"Failed to get socket address: "
);
return
false
;
}
address
.
SetSize
(
address_length
);
address
.
SetSize
(
address_length
);
OneServerSocket
&
s
=
AddAddress
(
address
);
OneServerSocket
&
s
=
AddAddress
(
address
);
s
.
SetFD
(
fd
);
s
.
SetFD
(
fd
);
return
true
;
}
}
#ifdef HAVE_TCP
#ifdef HAVE_TCP
...
@@ -367,14 +357,12 @@ SupportsIPv6()
...
@@ -367,14 +357,12 @@ SupportsIPv6()
#endif
/* HAVE_TCP */
#endif
/* HAVE_TCP */
bool
void
ServerSocket
::
AddPort
(
unsigned
port
,
Error
&
error
)
ServerSocket
::
AddPort
(
unsigned
port
)
{
{
#ifdef HAVE_TCP
#ifdef HAVE_TCP
if
(
port
==
0
||
port
>
0xffff
)
{
if
(
port
==
0
||
port
>
0xffff
)
error
.
Set
(
server_socket_domain
,
"Invalid TCP port"
);
throw
std
::
runtime_error
(
"Invalid TCP port"
);
return
false
;
}
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
if
(
SupportsIPv6
())
if
(
SupportsIPv6
())
...
@@ -383,49 +371,37 @@ ServerSocket::AddPort(unsigned port, Error &error)
...
@@ -383,49 +371,37 @@ ServerSocket::AddPort(unsigned port, Error &error)
AddPortIPv4
(
port
);
AddPortIPv4
(
port
);
++
next_serial
;
++
next_serial
;
return
true
;
#else
/* HAVE_TCP */
#else
/* HAVE_TCP */
(
void
)
port
;
(
void
)
port
;
error
.
Set
(
server_socket_domain
,
"TCP support is disabled"
);
throw
std
::
runtime_error
(
"TCP support is disabled"
);
return
false
;
#endif
/* HAVE_TCP */
#endif
/* HAVE_TCP */
}
}
bool
void
ServerSocket
::
AddHost
(
const
char
*
hostname
,
unsigned
port
,
Error
&
error
)
ServerSocket
::
AddHost
(
const
char
*
hostname
,
unsigned
port
)
{
{
#ifdef HAVE_TCP
#ifdef HAVE_TCP
struct
addrinfo
*
ai
=
resolve_host_port
(
hostname
,
port
,
struct
addrinfo
*
ai
=
resolve_host_port
(
hostname
,
port
,
AI_PASSIVE
,
SOCK_STREAM
,
AI_PASSIVE
,
SOCK_STREAM
);
error
);
AtScopeExit
(
ai
)
{
freeaddrinfo
(
ai
);
};
if
(
ai
==
nullptr
)
return
false
;
for
(
const
struct
addrinfo
*
i
=
ai
;
i
!=
nullptr
;
i
=
i
->
ai_next
)
for
(
const
struct
addrinfo
*
i
=
ai
;
i
!=
nullptr
;
i
=
i
->
ai_next
)
AddAddress
(
SocketAddress
(
i
->
ai_addr
,
i
->
ai_addrlen
));
AddAddress
(
SocketAddress
(
i
->
ai_addr
,
i
->
ai_addrlen
));
freeaddrinfo
(
ai
);
++
next_serial
;
++
next_serial
;
return
true
;
#else
/* HAVE_TCP */
#else
/* HAVE_TCP */
(
void
)
hostname
;
(
void
)
hostname
;
(
void
)
port
;
(
void
)
port
;
error
.
Set
(
server_socket_domain
,
"TCP support is disabled"
);
throw
std
::
runtime_error
(
"TCP support is disabled"
);
return
false
;
#endif
/* HAVE_TCP */
#endif
/* HAVE_TCP */
}
}
bool
void
ServerSocket
::
AddPath
(
AllocatedPath
&&
path
,
Error
&
error
)
ServerSocket
::
AddPath
(
AllocatedPath
&&
path
)
{
{
#ifdef HAVE_UN
#ifdef HAVE_UN
(
void
)
error
;
unlink
(
path
.
c_str
());
unlink
(
path
.
c_str
());
AllocatedSocketAddress
address
;
AllocatedSocketAddress
address
;
...
@@ -433,14 +409,10 @@ ServerSocket::AddPath(AllocatedPath &&path, Error &error)
...
@@ -433,14 +409,10 @@ ServerSocket::AddPath(AllocatedPath &&path, Error &error)
OneServerSocket
&
s
=
AddAddress
(
std
::
move
(
address
));
OneServerSocket
&
s
=
AddAddress
(
std
::
move
(
address
));
s
.
SetPath
(
std
::
move
(
path
));
s
.
SetPath
(
std
::
move
(
path
));
return
true
;
#else
/* !HAVE_UN */
#else
/* !HAVE_UN */
(
void
)
path
;
(
void
)
path
;
error
.
Set
(
server_socket_domain
,
throw
std
::
runtime_error
(
"UNIX domain socket support is disabled"
);
"UNIX domain socket support is disabled"
);
return
false
;
#endif
/* !HAVE_UN */
#endif
/* !HAVE_UN */
}
}
src/event/ServerSocket.hxx
View file @
aead2211
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
class
SocketAddress
;
class
SocketAddress
;
class
AllocatedSocketAddress
;
class
AllocatedSocketAddress
;
class
EventLoop
;
class
EventLoop
;
class
Error
;
class
AllocatedPath
;
class
AllocatedPath
;
class
OneServerSocket
;
class
OneServerSocket
;
...
@@ -71,40 +70,49 @@ public:
...
@@ -71,40 +70,49 @@ public:
/**
/**
* Add a listener on a port on all interfaces.
* Add a listener on a port on all interfaces.
*
*
* Throws #std::runtime_error on error.
*
* @param port the TCP port
* @param port the TCP port
* @param error location to store the error occurring
* @param error location to store the error occurring
* @return true on success
*/
*/
bool
AddPort
(
unsigned
port
,
Error
&
error
);
void
AddPort
(
unsigned
port
);
/**
/**
* Resolves a host name, and adds listeners on all addresses in the
* Resolves a host name, and adds listeners on all addresses in the
* result set.
* result set.
*
*
* Throws #std::runtime_error on error.
*
* @param hostname the host name to be resolved
* @param hostname the host name to be resolved
* @param port the TCP port
* @param port the TCP port
* @param error location to store the error occurring
* @param error location to store the error occurring
* @return true on success
*/
*/
bool
AddHost
(
const
char
*
hostname
,
unsigned
port
,
Error
&
error
);
void
AddHost
(
const
char
*
hostname
,
unsigned
port
);
/**
/**
* Add a listener on a Unix domain socket.
* Add a listener on a Unix domain socket.
*
*
* Throws #std::runtime_error on error.
*
* @param path the absolute socket path
* @param path the absolute socket path
* @param error location to store the error occurring
* @param error location to store the error occurring
* @return true on success
*/
*/
bool
AddPath
(
AllocatedPath
&&
path
,
Error
&
error
);
void
AddPath
(
AllocatedPath
&&
path
);
/**
/**
* Add a socket descriptor that is accepting connections. After this
* Add a socket descriptor that is accepting connections. After this
* has been called, don't call server_socket_open(), because the
* has been called, don't call server_socket_open(), because the
* socket is already open.
* socket is already open.
*
* Throws #std::runtime_error on error.
*/
void
AddFD
(
int
fd
);
/**
* Throws #std::runtime_error on error.
*/
*/
bool
AddFD
(
int
fd
,
Error
&
error
);
void
Open
(
);
bool
Open
(
Error
&
error
);
void
Close
();
void
Close
();
protected
:
protected
:
...
...
src/net/Resolver.cxx
View file @
aead2211
...
@@ -19,8 +19,7 @@
...
@@ -19,8 +19,7 @@
#include "config.h"
#include "config.h"
#include "Resolver.hxx"
#include "Resolver.hxx"
#include "util/Error.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include <string>
#include <string>
...
@@ -35,12 +34,9 @@
...
@@ -35,12 +34,9 @@
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
const
Domain
resolver_domain
(
"resolver"
);
struct
addrinfo
*
struct
addrinfo
*
resolve_host_port
(
const
char
*
host_port
,
unsigned
default_port
,
resolve_host_port
(
const
char
*
host_port
,
unsigned
default_port
,
int
flags
,
int
socktype
,
int
flags
,
int
socktype
)
Error
&
error
)
{
{
std
::
string
p
(
host_port
);
std
::
string
p
(
host_port
);
const
char
*
host
=
p
.
c_str
(),
*
port
=
nullptr
;
const
char
*
host
=
p
.
c_str
(),
*
port
=
nullptr
;
...
@@ -87,12 +83,9 @@ resolve_host_port(const char *host_port, unsigned default_port,
...
@@ -87,12 +83,9 @@ resolve_host_port(const char *host_port, unsigned default_port,
struct
addrinfo
*
ai
;
struct
addrinfo
*
ai
;
int
ret
=
getaddrinfo
(
host
,
port
,
&
hints
,
&
ai
);
int
ret
=
getaddrinfo
(
host
,
port
,
&
hints
,
&
ai
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
error
.
Format
(
resolver_domain
,
ret
,
throw
FormatRuntimeError
(
"Failed to look up '%s': %s"
,
"Failed to look up '%s': %s"
,
host_port
,
gai_strerror
(
ret
));
host_port
,
gai_strerror
(
ret
));
return
nullptr
;
}
return
ai
;
return
ai
;
}
}
src/net/Resolver.hxx
View file @
aead2211
...
@@ -24,24 +24,21 @@
...
@@ -24,24 +24,21 @@
#include "Compiler.h"
#include "Compiler.h"
struct
addrinfo
;
struct
addrinfo
;
class
Error
;
class
Domain
;
extern
const
Domain
resolver_domain
;
/**
/**
* Resolve a specification in the form "host", "host:port",
* Resolve a specification in the form "host", "host:port",
* "[host]:port". This is a convenience wrapper for getaddrinfo().
* "[host]:port". This is a convenience wrapper for getaddrinfo().
*
*
* Throws #std::runtime_error on error.
*
* @param default_port a default port number that will be used if none
* @param default_port a default port number that will be used if none
* is given in the string (if applicable); pass 0 to go without a
* is given in the string (if applicable); pass 0 to go without a
* default
* default
* @return an #addrinfo linked list that must be freed with
* @return an #addrinfo linked list that must be freed with
* freeaddrinfo()
, or NULL on error
* freeaddrinfo()
*/
*/
addrinfo
*
addrinfo
*
resolve_host_port
(
const
char
*
host_port
,
unsigned
default_port
,
resolve_host_port
(
const
char
*
host_port
,
unsigned
default_port
,
int
flags
,
int
socktype
,
int
flags
,
int
socktype
);
Error
&
error
);
#endif
#endif
src/net/SocketError.hxx
View file @
aead2211
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#define MPD_SOCKET_ERROR_HXX
#define MPD_SOCKET_ERROR_HXX
#include "Compiler.h"
#include "Compiler.h"
#include "system/Error.hxx"
#include "util/Error.hxx" // IWYU pragma: export
#include "util/Error.hxx" // IWYU pragma: export
#ifdef WIN32
#ifdef WIN32
...
@@ -136,4 +137,22 @@ NewSocketError()
...
@@ -136,4 +137,22 @@ NewSocketError()
return
NewSocketError
(
GetSocketError
());
return
NewSocketError
(
GetSocketError
());
}
}
gcc_const
static
inline
std
::
system_error
MakeSocketError
(
socket_error_t
code
,
const
char
*
msg
)
{
#ifdef WIN32
return
MakeLastError
(
code
,
msg
);
#else
return
MakeErrno
(
code
,
msg
);
#endif
}
gcc_pure
static
inline
std
::
system_error
MakeSocketError
(
const
char
*
msg
)
{
return
MakeSocketError
(
GetSocketError
(),
msg
);
}
#endif
#endif
src/net/SocketUtil.cxx
View file @
aead2211
...
@@ -26,41 +26,35 @@
...
@@ -26,41 +26,35 @@
int
int
socket_bind_listen
(
int
domain
,
int
type
,
int
protocol
,
socket_bind_listen
(
int
domain
,
int
type
,
int
protocol
,
SocketAddress
address
,
SocketAddress
address
,
int
backlog
,
int
backlog
)
Error
&
error
)
{
{
int
fd
,
ret
;
int
fd
,
ret
;
const
int
reuse
=
1
;
const
int
reuse
=
1
;
fd
=
socket_cloexec_nonblock
(
domain
,
type
,
protocol
);
fd
=
socket_cloexec_nonblock
(
domain
,
type
,
protocol
);
if
(
fd
<
0
)
{
if
(
fd
<
0
)
SetSocketError
(
error
);
throw
MakeSocketError
(
"Failed to create socket"
);
error
.
AddPrefix
(
"Failed to create socket: "
);
return
-
1
;
}
ret
=
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
ret
=
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
const
char
*
)
&
reuse
,
sizeof
(
reuse
));
(
const
char
*
)
&
reuse
,
sizeof
(
reuse
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SetSocketError
(
error
);
auto
error
=
GetSocketError
();
error
.
AddPrefix
(
"setsockopt() failed: "
);
close_socket
(
fd
);
close_socket
(
fd
);
return
-
1
;
throw
MakeSocketError
(
error
,
"setsockopt() failed"
)
;
}
}
ret
=
bind
(
fd
,
address
.
GetAddress
(),
address
.
GetSize
());
ret
=
bind
(
fd
,
address
.
GetAddress
(),
address
.
GetSize
());
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SetSocketError
(
error
);
auto
error
=
GetSocketError
(
);
close_socket
(
fd
);
close_socket
(
fd
);
return
-
1
;
throw
MakeSocketError
(
error
,
"Failed to bind socket"
)
;
}
}
ret
=
listen
(
fd
,
backlog
);
ret
=
listen
(
fd
,
backlog
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SetSocketError
(
error
);
auto
error
=
GetSocketError
();
error
.
AddPrefix
(
"listen() failed: "
);
close_socket
(
fd
);
close_socket
(
fd
);
return
-
1
;
throw
MakeSocketError
(
error
,
"Failed to listen on socket"
)
;
}
}
#if defined(HAVE_STRUCT_UCRED) && defined(SO_PASSCRED)
#if defined(HAVE_STRUCT_UCRED) && defined(SO_PASSCRED)
...
...
src/net/SocketUtil.hxx
View file @
aead2211
...
@@ -27,12 +27,13 @@
...
@@ -27,12 +27,13 @@
#define MPD_SOCKET_UTIL_HXX
#define MPD_SOCKET_UTIL_HXX
class
SocketAddress
;
class
SocketAddress
;
class
Error
;
/**
/**
* Creates a socket listening on the specified address. This is a
* Creates a socket listening on the specified address. This is a
* shortcut for socket(), bind() and listen().
* shortcut for socket(), bind() and listen().
*
*
* Throws #std::system_error on error.
*
* @param domain the socket domain, e.g. PF_INET6
* @param domain the socket domain, e.g. PF_INET6
* @param type the socket type, e.g. SOCK_STREAM
* @param type the socket type, e.g. SOCK_STREAM
* @param protocol the protocol, usually 0 to let the kernel choose
* @param protocol the protocol, usually 0 to let the kernel choose
...
@@ -40,13 +41,12 @@ class Error;
...
@@ -40,13 +41,12 @@ class Error;
* @param backlog the backlog parameter for the listen() system call
* @param backlog the backlog parameter for the listen() system call
* @param error location to store the error occurring, or NULL to
* @param error location to store the error occurring, or NULL to
* ignore errors
* ignore errors
* @return the socket file descriptor
or -1 on error
* @return the socket file descriptor
*/
*/
int
int
socket_bind_listen
(
int
domain
,
int
type
,
int
protocol
,
socket_bind_listen
(
int
domain
,
int
type
,
int
protocol
,
SocketAddress
address
,
SocketAddress
address
,
int
backlog
,
int
backlog
);
Error
&
error
);
int
int
socket_keepalive
(
int
fd
);
socket_keepalive
(
int
fd
);
...
...
src/output/plugins/httpd/HttpdInternal.hxx
View file @
aead2211
...
@@ -177,7 +177,7 @@ public:
...
@@ -177,7 +177,7 @@ public:
return
&
base
;
return
&
base
;
}
}
bool
Bind
(
Error
&
error
);
void
Bind
(
);
void
Unbind
();
void
Unbind
();
/**
/**
...
...
src/output/plugins/httpd/HttpdOutputPlugin.cxx
View file @
aead2211
...
@@ -66,16 +66,14 @@ HttpdOutput::~HttpdOutput()
...
@@ -66,16 +66,14 @@ HttpdOutput::~HttpdOutput()
delete
prepared_encoder
;
delete
prepared_encoder
;
}
}
inline
bool
inline
void
HttpdOutput
::
Bind
(
Error
&
error
)
HttpdOutput
::
Bind
()
{
{
open
=
false
;
open
=
false
;
bool
result
=
false
;
BlockingCall
(
GetEventLoop
(),
[
this
](){
BlockingCall
(
GetEventLoop
(),
[
this
,
&
error
,
&
result
](){
ServerSocket
::
Open
();
result
=
ServerSocket
::
Open
(
error
);
});
});
return
result
;
}
}
inline
void
inline
void
...
@@ -112,12 +110,10 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error)
...
@@ -112,12 +110,10 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error)
/* set up bind_to_address */
/* set up bind_to_address */
const
char
*
bind_to_address
=
block
.
GetBlockValue
(
"bind_to_address"
);
const
char
*
bind_to_address
=
block
.
GetBlockValue
(
"bind_to_address"
);
bool
success
=
bind_to_address
!=
nullptr
&&
if
(
bind_to_address
!=
nullptr
&&
strcmp
(
bind_to_address
,
"any"
)
!=
0
)
strcmp
(
bind_to_address
,
"any"
)
!=
0
AddHost
(
bind_to_address
,
port
);
?
AddHost
(
bind_to_address
,
port
,
error
)
else
:
AddPort
(
port
,
error
);
AddPort
(
port
);
if
(
!
success
)
return
false
;
/* initialize encoder */
/* initialize encoder */
...
@@ -144,11 +140,16 @@ httpd_output_init(const ConfigBlock &block, Error &error)
...
@@ -144,11 +140,16 @@ httpd_output_init(const ConfigBlock &block, Error &error)
{
{
HttpdOutput
*
httpd
=
new
HttpdOutput
(
io_thread_get
());
HttpdOutput
*
httpd
=
new
HttpdOutput
(
io_thread_get
());
try
{
AudioOutput
*
result
=
httpd
->
InitAndConfigure
(
block
,
error
);
AudioOutput
*
result
=
httpd
->
InitAndConfigure
(
block
,
error
);
if
(
result
==
nullptr
)
if
(
result
==
nullptr
)
delete
httpd
;
delete
httpd
;
return
result
;
return
result
;
}
catch
(
const
std
::
runtime_error
&
e
)
{
delete
httpd
;
throw
;
}
}
}
static
void
static
void
...
@@ -271,11 +272,12 @@ HttpdOutput::ReadPage()
...
@@ -271,11 +272,12 @@ HttpdOutput::ReadPage()
}
}
static
bool
static
bool
httpd_output_enable
(
AudioOutput
*
ao
,
Error
&
error
)
httpd_output_enable
(
AudioOutput
*
ao
,
gcc_unused
Error
&
error
)
{
{
HttpdOutput
*
httpd
=
HttpdOutput
::
Cast
(
ao
);
HttpdOutput
*
httpd
=
HttpdOutput
::
Cast
(
ao
);
return
httpd
->
Bind
(
error
);
httpd
->
Bind
();
return
true
;
}
}
static
void
static
void
...
...
test/run_resolver.cxx
View file @
aead2211
...
@@ -21,9 +21,10 @@
...
@@ -21,9 +21,10 @@
#include "net/Resolver.hxx"
#include "net/Resolver.hxx"
#include "net/ToString.hxx"
#include "net/ToString.hxx"
#include "net/SocketAddress.hxx"
#include "net/SocketAddress.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <stdexcept>
#ifdef WIN32
#ifdef WIN32
#include <ws2tcpip.h>
#include <ws2tcpip.h>
#include <winsock.h>
#include <winsock.h>
...
@@ -36,20 +37,14 @@
...
@@ -36,20 +37,14 @@
#include <stdlib.h>
#include <stdlib.h>
int
main
(
int
argc
,
char
**
argv
)
int
main
(
int
argc
,
char
**
argv
)
{
try
{
if
(
argc
!=
2
)
{
if
(
argc
!=
2
)
{
fprintf
(
stderr
,
"Usage: run_resolver HOST
\n
"
);
fprintf
(
stderr
,
"Usage: run_resolver HOST
\n
"
);
return
EXIT_FAILURE
;
return
EXIT_FAILURE
;
}
}
Error
error
;
struct
addrinfo
*
ai
=
struct
addrinfo
*
ai
=
resolve_host_port
(
argv
[
1
],
80
,
AI_PASSIVE
,
SOCK_STREAM
,
resolve_host_port
(
argv
[
1
],
80
,
AI_PASSIVE
,
SOCK_STREAM
);
error
);
if
(
ai
==
NULL
)
{
LogError
(
error
);
return
EXIT_FAILURE
;
}
for
(
const
struct
addrinfo
*
i
=
ai
;
i
!=
NULL
;
i
=
i
->
ai_next
)
{
for
(
const
struct
addrinfo
*
i
=
ai
;
i
!=
NULL
;
i
=
i
->
ai_next
)
{
const
auto
s
=
ToString
({
i
->
ai_addr
,
i
->
ai_addrlen
});
const
auto
s
=
ToString
({
i
->
ai_addr
,
i
->
ai_addrlen
});
...
@@ -58,4 +53,7 @@ int main(int argc, char **argv)
...
@@ -58,4 +53,7 @@ int main(int argc, char **argv)
freeaddrinfo
(
ai
);
freeaddrinfo
(
ai
);
return
EXIT_SUCCESS
;
return
EXIT_SUCCESS
;
}
catch
(
const
std
::
runtime_error
&
e
)
{
LogError
(
e
);
return
EXIT_FAILURE
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment