# HG changeset patch # User Trygve Vea <trygve....@redpill-linpro.com> # Date 1395933815 -3600 # Thu Mar 27 16:23:35 2014 +0100 # Node ID 13e6a37c2f57443b0d5dd0abce8d9d4ab00e31e3 # Parent 2411d4b5be2ca690a5a00a1d8ad96ff69a00317f Added so_freebind and so_transparent to the listen directive
This solves a Linux/IPv6-specific problem. To be able to listen to an IPv6 address that is not yet available on the host, one need to use the IP_FREEBIND and IP_TRANSPARENT socket options. The use case in question is for a failover setup with several service- addresses in a IPv6-only environment. IPv4 has a sysctl available (ip_nonlocal_bind), which is not available for IPv6 - thus making these patches necessary. diff -r 2411d4b5be2c -r 13e6a37c2f57 src/core/ngx_connection.c --- a/src/core/ngx_connection.c Wed Mar 26 18:01:11 2014 +0400 +++ b/src/core/ngx_connection.c Thu Mar 27 16:23:35 2014 +0100 @@ -305,6 +305,14 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) { int reuseaddr; +#ifdef NGX_LINUX +#ifdef IP_FREEBIND + int so_freebind; +#endif +#ifdef IP_TRANSPARENT + int so_transparent; +#endif +#endif ngx_uint_t i, tries, failed; ngx_err_t err; ngx_log_t *log; @@ -370,6 +378,37 @@ return NGX_ERROR; } +#ifdef NGX_LINUX +#ifdef IP_FREEBIND + if (ls[i].so_freebind) { + so_freebind = (ls[i].so_freebind == 1) ? 1 : 0; + + if (setsockopt(s, SOL_IP, IP_FREEBIND, + (const void *) &so_freebind, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(IP_FREEBIND, %d) %V failed", + so_freebind, &ls[i].addr_text); + } + } +#endif +#ifdef IP_TRANSPARENT + if (ls[i].so_transparent) { + so_transparent = (ls[i].so_transparent == 1) ? 1 : 0; + + if (setsockopt(s, SOL_IP, IP_TRANSPARENT, + (const void *) &so_transparent, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(IP_TRANSPARENT, %d) %V failed", + so_transparent, &ls[i].addr_text); + } + } +#endif +#endif + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) if (ls[i].sockaddr->sa_family == AF_INET6) { diff -r 2411d4b5be2c -r 13e6a37c2f57 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Wed Mar 26 18:01:11 2014 +0400 +++ b/src/core/ngx_connection.h Thu Mar 27 16:23:35 2014 +0100 @@ -67,6 +67,14 @@ unsigned ipv6only:1; #endif unsigned keepalive:2; +#ifdef NGX_LINUX +#ifdef IP_FREEBIND + unsigned so_freebind:1; +#endif +#ifdef IP_TRANSPARENT + unsigned so_transparent:1; +#endif +#endif #if (NGX_HAVE_DEFERRED_ACCEPT) unsigned deferred_accept:1; diff -r 2411d4b5be2c -r 13e6a37c2f57 src/http/ngx_http.c --- a/src/http/ngx_http.c Wed Mar 26 18:01:11 2014 +0400 +++ b/src/http/ngx_http.c Thu Mar 27 16:23:35 2014 +0100 @@ -1791,6 +1791,14 @@ ls->sndbuf = addr->opt.sndbuf; ls->keepalive = addr->opt.so_keepalive; +#ifdef NGX_LINUX +#ifdef IP_FREEBIND + ls->so_freebind = addr->opt.so_freebind; +#endif +#ifdef IP_TRANSPARENT + ls->so_transparent = addr->opt.so_transparent; +#endif +#endif #if (NGX_HAVE_KEEPALIVE_TUNABLE) ls->keepidle = addr->opt.tcp_keepidle; ls->keepintvl = addr->opt.tcp_keepintvl; diff -r 2411d4b5be2c -r 13e6a37c2f57 src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c Wed Mar 26 18:01:11 2014 +0400 +++ b/src/http/ngx_http_core_module.c Thu Mar 27 16:23:35 2014 +0100 @@ -4283,6 +4283,30 @@ continue; } + if (ngx_strcmp(value[n].data, "so_freebind") == 0) { +#ifdef NGX_LINUX + lsopt.so_freebind = 1; + continue; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"so_freebind\" parameter requires " + "nginx to be built for Linux"); + return NGX_CONF_ERROR; +#endif + } + + if (ngx_strcmp(value[n].data, "so_transparent") == 0) { +#ifdef NGX_LINUX + lsopt.so_transparent = 1; + continue; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"so_transparent\" parameter requires " + "nginx to be built for linux"); + return NGX_CONF_ERROR; +#endif + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[n]); return NGX_CONF_ERROR; diff -r 2411d4b5be2c -r 13e6a37c2f57 src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h Wed Mar 26 18:01:11 2014 +0400 +++ b/src/http/ngx_http_core_module.h Thu Mar 27 16:23:35 2014 +0100 @@ -82,6 +82,14 @@ unsigned ipv6only:1; #endif unsigned so_keepalive:2; +#ifdef NGX_LINUX +#ifdef IP_FREEBIND + unsigned so_freebind:1; +#endif +#ifdef IP_TRANSPARENT + unsigned so_transparent:1; +#endif +#endif unsigned proxy_protocol:1; int backlog; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel