output/httpd: bind_to_address support (including IPv6)
Added support for a new optional configuration setting for the httpd output named "bind_to_address". Setting it to a specific IP address (v4 or v6) will cause the httpd output to bind to that address exclusively. Supporting multiple addresses in parallel is future work. This implements the feature requests #2998 and #2646.
This commit is contained in:
parent
0c80bd5fc0
commit
9af9fd1400
1
NEWS
1
NEWS
|
@ -60,6 +60,7 @@ ver 0.16 (20??/??/??)
|
||||||
- httpd: bind port when output is enabled
|
- httpd: bind port when output is enabled
|
||||||
- httpd: added name/genre/website configuration
|
- httpd: added name/genre/website configuration
|
||||||
- httpd: implement "pause"
|
- httpd: implement "pause"
|
||||||
|
- httpd: bind_to_address support (including IPv6)
|
||||||
- oss: 24 bit support via OSS4
|
- oss: 24 bit support via OSS4
|
||||||
- win32: new output plugin for Windows Wave
|
- win32: new output plugin for Windows Wave
|
||||||
- wildcards allowed in audio_format configuration
|
- wildcards allowed in audio_format configuration
|
||||||
|
|
|
@ -260,6 +260,7 @@ input {
|
||||||
# name "My HTTP Stream"
|
# name "My HTTP Stream"
|
||||||
# encoder "vorbis" # optional, vorbis or lame
|
# encoder "vorbis" # optional, vorbis or lame
|
||||||
# port "8000"
|
# port "8000"
|
||||||
|
# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6
|
||||||
## quality "5.0" # do not define if bitrate is defined
|
## quality "5.0" # do not define if bitrate is defined
|
||||||
# bitrate "128" # do not define if quality is defined
|
# bitrate "128" # do not define if quality is defined
|
||||||
# format "44100:16:1"
|
# format "44100:16:1"
|
||||||
|
|
13
doc/user.xml
13
doc/user.xml
|
@ -914,8 +914,17 @@ cd mpd-version</programlisting>
|
||||||
<parameter>P</parameter>
|
<parameter>P</parameter>
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
Binds the HTTP server to the specified port (on all
|
Binds the HTTP server to the specified port.
|
||||||
interfaces).
|
</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<varname>bind_to_address</varname>
|
||||||
|
<parameter>ADDR</parameter>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Binds the HTTP server to the specified address (IPv4 or
|
||||||
|
IPv6). Multiple addresses in parallel are not supported.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
|
|
@ -71,8 +71,8 @@ httpd_output_bind(struct httpd_output *httpd, GError **error_r)
|
||||||
|
|
||||||
/* create and set up listener socket */
|
/* create and set up listener socket */
|
||||||
|
|
||||||
httpd->fd = socket_bind_listen(PF_INET, SOCK_STREAM, 0,
|
httpd->fd = socket_bind_listen(httpd->address.ss_family, SOCK_STREAM,
|
||||||
(struct sockaddr *)&httpd->address,
|
0, (struct sockaddr *)&httpd->address,
|
||||||
httpd->address_size,
|
httpd->address_size,
|
||||||
16, error_r);
|
16, error_r);
|
||||||
if (httpd->fd < 0)
|
if (httpd->fd < 0)
|
||||||
|
@ -103,16 +103,52 @@ httpd_output_unbind(struct httpd_output *httpd)
|
||||||
g_mutex_unlock(httpd->mutex);
|
g_mutex_unlock(httpd->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
httpd_output_parse_bind_to_address(struct httpd_output *httpd,
|
||||||
|
const char *bind_to_address,
|
||||||
|
guint port, GError **error)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *ai;
|
||||||
|
char service[20];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
#ifdef AI_ADDRCONFIG
|
||||||
|
hints.ai_flags |= AI_ADDRCONFIG;
|
||||||
|
#endif
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
g_snprintf(service, sizeof(service), "%u", port);
|
||||||
|
ret = getaddrinfo(bind_to_address, service, &hints, &ai);
|
||||||
|
if (ret != 0) {
|
||||||
|
g_set_error(error, httpd_output_quark(), ret,
|
||||||
|
"Failed to look up host \"%s\": %s",
|
||||||
|
bind_to_address, gai_strerror(ret));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ai);
|
||||||
|
|
||||||
|
/* Choose the first address, even if multiple are available. We do
|
||||||
|
* not support multiple addresses yet. */
|
||||||
|
memcpy(&httpd->address, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
httpd->address_size = ai->ai_addrlen;
|
||||||
|
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
||||||
const struct config_param *param,
|
const struct config_param *param,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct httpd_output *httpd = g_new(struct httpd_output, 1);
|
struct httpd_output *httpd = g_new(struct httpd_output, 1);
|
||||||
const char *encoder_name;
|
const char *encoder_name, *bind_to_address;
|
||||||
const struct encoder_plugin *encoder_plugin;
|
const struct encoder_plugin *encoder_plugin;
|
||||||
guint port;
|
guint port;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
|
|
||||||
/* read configuration */
|
/* read configuration */
|
||||||
httpd->name =
|
httpd->name =
|
||||||
|
@ -134,14 +170,18 @@ httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
||||||
|
|
||||||
httpd->clients_max = config_get_block_unsigned(param,"max_clients", 0);
|
httpd->clients_max = config_get_block_unsigned(param,"max_clients", 0);
|
||||||
|
|
||||||
/* initialize listen address */
|
/* set up bind_to_address */
|
||||||
|
bind_to_address =
|
||||||
sin = (struct sockaddr_in *)&httpd->address;
|
config_get_block_string(param, "bind_to_address",
|
||||||
memset(sin, 0, sizeof(sin));
|
#ifdef HAVE_IPV6
|
||||||
sin->sin_port = htons(port);
|
"::"
|
||||||
sin->sin_family = AF_INET;
|
#else
|
||||||
sin->sin_addr.s_addr = INADDR_ANY;
|
"0.0.0.0"
|
||||||
httpd->address_size = sizeof(*sin);
|
#endif
|
||||||
|
);
|
||||||
|
httpd_output_parse_bind_to_address(httpd, bind_to_address, port, error);
|
||||||
|
if (*error)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* initialize metadata */
|
/* initialize metadata */
|
||||||
httpd->metadata = NULL;
|
httpd->metadata = NULL;
|
||||||
|
|
Loading…
Reference in New Issue