[httpd/mpd] Make sure daemons listen on both ipv4 and ipv6 if enabled

Before setting ipv6 = enabled on FreeBSD would make the daemon not listen on ipv4
This commit is contained in:
ejurgensen 2017-09-07 21:44:12 +02:00
parent c45a85d143
commit c27448418c
2 changed files with 68 additions and 43 deletions

View File

@ -1515,14 +1515,19 @@ httpd_init(void)
} }
} }
if (!v6enabled)
{
ret = evhttp_bind_socket(evhttpd, "0.0.0.0", httpd_port); ret = evhttp_bind_socket(evhttpd, "0.0.0.0", httpd_port);
if (ret < 0) if (ret < 0)
{
if (!v6enabled)
{ {
DPRINTF(E_FATAL, L_HTTPD, "Could not bind to port %d (forked-daapd already running?)\n", httpd_port); DPRINTF(E_FATAL, L_HTTPD, "Could not bind to port %d (forked-daapd already running?)\n", httpd_port);
goto bind_fail; goto bind_fail;
} }
#ifndef __linux__
// Linux will listen on both ipv6 and ipv4, but FreeBSD won't
DPRINTF(E_LOG, L_HTTPD, "Could not bind to port %d with IPv4, listening on IPv6 only\n", httpd_port);
#endif
} }
evhttp_set_gencb(evhttpd, httpd_gen_cb, NULL); evhttp_set_gencb(evhttpd, httpd_gen_cb, NULL);

View File

@ -68,7 +68,8 @@ static struct commands_base *cmdbase;
static struct evhttp *evhttpd; static struct evhttp *evhttpd;
struct evconnlistener *listener; struct evconnlistener *mpd_listener6;
struct evconnlistener *mpd_listener;
// Virtual path to the default playlist directory // Virtual path to the default playlist directory
static char *default_pl_dir; static char *default_pl_dir;
@ -4859,7 +4860,6 @@ int mpd_init(void)
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
unsigned short port; unsigned short port;
unsigned short http_port; unsigned short http_port;
const char *http_addr;
int v6enabled; int v6enabled;
const char *pl_dir; const char *pl_dir;
int ret; int ret;
@ -4891,7 +4891,7 @@ int mpd_init(void)
sin6.sin6_port = htons(port); sin6.sin6_port = htons(port);
saddr = (struct sockaddr *)&sin6; saddr = (struct sockaddr *)&sin6;
listener = evconnlistener_new_bind( mpd_listener6 = evconnlistener_new_bind(
evbase_mpd, evbase_mpd,
mpd_accept_conn_cb, mpd_accept_conn_cb,
NULL, NULL,
@ -4900,15 +4900,15 @@ int mpd_init(void)
saddr, saddr,
saddr_length); saddr_length);
if (!listener) if (!mpd_listener6)
{ {
DPRINTF(E_LOG, L_MPD, "Could not bind to port %d, falling back to IPv4\n", port); DPRINTF(E_LOG, L_MPD, "Could not bind to port %d, falling back to IPv4\n", port);
v6enabled = 0; v6enabled = 0;
} }
else
evconnlistener_set_error_cb(mpd_listener6, mpd_accept_error_cb);
} }
if (!v6enabled)
{
saddr_length = sizeof(struct sockaddr_in); saddr_length = sizeof(struct sockaddr_in);
memset(&sin, 0, saddr_length); memset(&sin, 0, saddr_length);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
@ -4916,7 +4916,7 @@ int mpd_init(void)
sin.sin_port = htons(port); sin.sin_port = htons(port);
saddr = (struct sockaddr *)&sin; saddr = (struct sockaddr *)&sin;
listener = evconnlistener_new_bind( mpd_listener = evconnlistener_new_bind(
evbase_mpd, evbase_mpd,
mpd_accept_conn_cb, mpd_accept_conn_cb,
NULL, NULL,
@ -4925,15 +4925,21 @@ int mpd_init(void)
saddr, saddr,
saddr_length); saddr_length);
if (!listener) if (!mpd_listener)
{
if (!v6enabled)
{ {
DPRINTF(E_LOG, L_MPD, "Could not create connection listener for mpd clients on port %d\n", port); DPRINTF(E_LOG, L_MPD, "Could not create connection listener for mpd clients on port %d\n", port);
goto connew_fail; goto connew_fail;
} }
}
evconnlistener_set_error_cb(listener, mpd_accept_error_cb); #ifndef __linux__
// Linux will listen on both ipv6 and ipv4, but FreeBSD won't
DPRINTF(E_LOG, L_MPD, "Could not bind to port %d with IPv4, listening on IPv6 only\n", port);
#endif
}
else
evconnlistener_set_error_cb(mpd_listener, mpd_accept_error_cb);
http_port = cfg_getint(cfg_getsec(cfg, "mpd"), "http_port"); http_port = cfg_getint(cfg_getsec(cfg, "mpd"), "http_port");
if (http_port > 0) if (http_port > 0)
@ -4949,17 +4955,29 @@ int mpd_init(void)
evhttp_set_gencb(evhttpd, artwork_cb, NULL); evhttp_set_gencb(evhttpd, artwork_cb, NULL);
if (v6enabled) if (v6enabled)
http_addr = "::"; {
else ret = evhttp_bind_socket(evhttpd, "::", http_port);
http_addr = "0.0.0.0";
ret = evhttp_bind_socket(evhttpd, http_addr, http_port);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_FATAL, L_MPD, "Could not bind HTTP artwork server at %s:%d\n", http_addr, http_port); DPRINTF(E_LOG, L_MPD, "Could not bind HTTP artwork server to port %d with IPv6, falling back to IPv4\n", http_port);
v6enabled = 0;
}
}
ret = evhttp_bind_socket(evhttpd, "0.0.0.0", http_port);
if (ret < 0)
{
if (!v6enabled)
{
DPRINTF(E_LOG, L_MPD, "Could not bind HTTP artwork server to port %d with IPv4\n", http_port);
goto bind_fail; goto bind_fail;
} }
#ifndef __linux__
// Linux will listen on both ipv6 and ipv4, but FreeBSD won't
DPRINTF(E_LOG, L_MPD, "Could not bind HTTP artwork server to port %d with IPv4, listening on IPv6 only\n", http_port);
#endif
}
} }
allow_modifying_stored_playlists = cfg_getbool(cfg_getsec(cfg, "mpd"), "allow_modifying_stored_playlists"); allow_modifying_stored_playlists = cfg_getbool(cfg_getsec(cfg, "mpd"), "allow_modifying_stored_playlists");
@ -4994,7 +5012,8 @@ int mpd_init(void)
if (http_port > 0) if (http_port > 0)
evhttp_free(evhttpd); evhttp_free(evhttpd);
evhttp_fail: evhttp_fail:
evconnlistener_free(listener); evconnlistener_free(mpd_listener);
evconnlistener_free(mpd_listener6);
connew_fail: connew_fail:
commands_base_free(cmdbase); commands_base_free(cmdbase);
event_base_free(evbase_mpd); event_base_free(evbase_mpd);
@ -5041,7 +5060,8 @@ void mpd_deinit(void)
if (http_port > 0) if (http_port > 0)
evhttp_free(evhttpd); evhttp_free(evhttpd);
evconnlistener_free(listener); evconnlistener_free(mpd_listener);
evconnlistener_free(mpd_listener6);
// Free event base (should free events too) // Free event base (should free events too)
event_base_free(evbase_mpd); event_base_free(evbase_mpd);