diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/base.h | 2 | ||||
-rw-r--r-- | src/configfile.c | 5 | ||||
-rw-r--r-- | src/network.c | 13 |
4 files changed, 19 insertions, 2 deletions
@@ -32,6 +32,7 @@ NEWS * add libev fdevent handler: server.event-handler = "libev" * mod_proxy: return response as soon as it is available (fixes #2196) * don't overwrite global server.force-lowercase-filenames setting (fixes #2042) + * bind to IPV6-only if ipv6 address was specified (http://redmine.lighttpd.net/projects/lighttpd/wiki/IPv6-Config) - 1.4.26 - 2010-02-07 * Fix request parser to handle packets with splitted \r\n\r\n (fixes #2105) @@ -282,7 +282,7 @@ typedef struct { buffer *ssl_verifyclient_username; unsigned short ssl_verifyclient_export_cert; - unsigned short use_ipv6; + unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */ unsigned short defer_accept; unsigned short is_ssl; unsigned short allow_http11; diff --git a/src/configfile.c b/src/configfile.c index cecef076..0ee96b61 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -100,6 +100,9 @@ static int config_insert(server *srv) { { "ssl.verifyclient.depth", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 58 */ { "ssl.verifyclient.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 59 */ { "ssl.verifyclient.exportcert", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 60 */ + + { "server.set-v6only", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 61 */ + { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -170,6 +173,7 @@ static int config_insert(server *srv) { s->is_ssl = 0; s->ssl_use_sslv2 = 0; s->use_ipv6 = 0; + s->set_v6only = 1; s->defer_accept = 0; #ifdef HAVE_LSTAT s->follow_symlink = 1; @@ -194,6 +198,7 @@ static int config_insert(server *srv) { cv[7].destination = s->server_tag; cv[8].destination = &(s->use_ipv6); + cv[61].destination = &(s->set_v6only); cv[54].destination = &(s->defer_accept); diff --git a/src/network.c b/src/network.c index aa720703..43e0f330 100644 --- a/src/network.c +++ b/src/network.c @@ -225,7 +225,7 @@ static int network_server_init(server *srv, buffer *host_token, specific_config val = 1; if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { - log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno)); + log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(SO_REUSEADDR) failed:", strerror(errno)); goto error_free_socket; } @@ -236,10 +236,21 @@ static int network_server_init(server *srv, buffer *host_token, specific_config srv_socket->addr.ipv6.sin6_family = AF_INET6; if (host == NULL) { srv_socket->addr.ipv6.sin6_addr = in6addr_any; + log_error_write(srv, __FILE__, __LINE__, "s", "warning: please use server.use-ipv6 only for hostnames, not without server.bind / empty address; your config will break if the kernel default for IPV6_V6ONLY changes"); } else { struct addrinfo hints, *res; int r; + if (s->set_v6only) { + val = 1; + if (-1 == setsockopt(srv_socket->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(IPV6_V6ONLY) failed:", strerror(errno)); + goto error_free_socket; + } + } else { + log_error_write(srv, __FILE__, __LINE__, "s", "warning: server.set-v6only will be removed soon, update your config to have different sockets for ipv4 and ipv6"); + } + memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; |