[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);
if (ret < 0)
{ {
ret = evhttp_bind_socket(evhttpd, "0.0.0.0", httpd_port); if (!v6enabled)
if (ret < 0)
{ {
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);

100
src/mpd.c
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,40 +4900,46 @@ 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);
memset(&sin, 0, saddr_length);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0);
sin.sin_port = htons(port);
saddr = (struct sockaddr *)&sin;
mpd_listener = evconnlistener_new_bind(
evbase_mpd,
mpd_accept_conn_cb,
NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
-1,
saddr,
saddr_length);
if (!mpd_listener)
{ {
saddr_length = sizeof(struct sockaddr_in); if (!v6enabled)
memset(&sin, 0, saddr_length); {
sin.sin_family = AF_INET; DPRINTF(E_LOG, L_MPD, "Could not create connection listener for mpd clients on port %d\n", port);
sin.sin_addr.s_addr = htonl(0); goto connew_fail;
sin.sin_port = htons(port); }
saddr = (struct sockaddr *)&sin;
listener = evconnlistener_new_bind( #ifndef __linux__
evbase_mpd, // Linux will listen on both ipv6 and ipv4, but FreeBSD won't
mpd_accept_conn_cb, DPRINTF(E_LOG, L_MPD, "Could not bind to port %d with IPv4, listening on IPv6 only\n", port);
NULL, #endif
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
-1,
saddr,
saddr_length);
if (!listener)
{
DPRINTF(E_LOG, L_MPD, "Could not create connection listener for mpd clients on port %d\n", port);
goto connew_fail;
}
} }
else
evconnlistener_set_error_cb(listener, mpd_accept_error_cb); 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,16 +4955,28 @@ 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"; if (ret < 0)
{
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, http_addr, http_port); ret = evhttp_bind_socket(evhttpd, "0.0.0.0", 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); 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
} }
} }
@ -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);