summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/base.h2
-rw-r--r--src/configfile.c5
-rw-r--r--src/network.c13
4 files changed, 19 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index dfe2ebcc..a15163f1 100644
--- a/NEWS
+++ b/NEWS
@@ -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)
diff --git a/src/base.h b/src/base.h
index 4243bd20..8278c7e0 100644
--- a/src/base.h
+++ b/src/base.h
@@ -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;