# HG changeset patch # User Trygve Vea <t...@redpill-linpro.com> # Date 1395999940 -3600 # Fri Mar 28 10:45:40 2014 +0100 # Node ID 16eacd8609c8362e9dd729c743ed7a869c2993fe # Parent 2411d4b5be2ca690a5a00a1d8ad96ff69a00317f Added nonlocal to the listen directive
The nonlocal option is used to set the needed socket options to be able to bind to an address not necessarily owned by the host. This patch currently implements this for Linux >= 2.4 IPv4/IPv6. The problem we solve by doing this, is in an environment where the following conditions are met: * HTTPS with multiple certificates, and a client base that are unable to use SNI - thus having the need to tie specific certificates to specific ip/ports. * Setting the ip_nonlocal_bind-sysctl is not an option (for example for Linux IPv6) * Used in a failover-setup, where the service IP-addresses are moved around by a daemon like linux-ha or keepalived. diff -r 2411d4b5be2c -r 16eacd8609c8 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 Fri Mar 28 10:45:40 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,35 @@ return NGX_ERROR; } + if (ls[i].nonlocal) { +#if (defined NGX_LINUX && defined IP_FREEBIND) + so_freebind = 1; + + 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); + } +#if (NGX_HAVE_INET6 && defined IP_TRANSPARENT) + so_transparent = 1; + + 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 + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "nonlocal requires Linux >= 2.4, ignored"); +#endif + } + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) if (ls[i].sockaddr->sa_family == AF_INET6) { diff -r 2411d4b5be2c -r 16eacd8609c8 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 Fri Mar 28 10:45:40 2014 +0100 @@ -66,6 +66,7 @@ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif + unsigned nonlocal:1; unsigned keepalive:2; #if (NGX_HAVE_DEFERRED_ACCEPT) diff -r 2411d4b5be2c -r 16eacd8609c8 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 Fri Mar 28 10:45:40 2014 +0100 @@ -1808,6 +1808,7 @@ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) ls->ipv6only = addr->opt.ipv6only; #endif + ls->nonlocal = addr->opt.nonlocal; #if (NGX_HAVE_SETFIB) ls->setfib = addr->opt.setfib; diff -r 2411d4b5be2c -r 16eacd8609c8 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 Fri Mar 28 10:45:40 2014 +0100 @@ -4283,6 +4283,11 @@ continue; } + if (ngx_strcmp(value[n].data, "nonlocal") == 0) { + lsopt.nonlocal = 1; + continue; + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[n]); return NGX_CONF_ERROR; diff -r 2411d4b5be2c -r 16eacd8609c8 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 Fri Mar 28 10:45:40 2014 +0100 @@ -81,6 +81,7 @@ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif + unsigned nonlocal:1; unsigned so_keepalive:2; unsigned proxy_protocol:1; diff -r 2411d4b5be2c -r 16eacd8609c8 src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Wed Mar 26 18:01:11 2014 +0400 +++ b/src/mail/ngx_mail.c Fri Mar 28 10:45:40 2014 +0100 @@ -327,6 +327,7 @@ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) addr->ipv6only = listen->ipv6only; #endif + addr->nonlocal = listen->nonlocal; return NGX_OK; } diff -r 2411d4b5be2c -r 16eacd8609c8 src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h Wed Mar 26 18:01:11 2014 +0400 +++ b/src/mail/ngx_mail.h Fri Mar 28 10:45:40 2014 +0100 @@ -41,6 +41,7 @@ #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:1; #endif + unsigned nonlocal:1; unsigned so_keepalive:2; #if (NGX_HAVE_KEEPALIVE_TUNABLE) int tcp_keepidle; diff -r 2411d4b5be2c -r 16eacd8609c8 src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c Wed Mar 26 18:01:11 2014 +0400 +++ b/src/mail/ngx_mail_core_module.c Fri Mar 28 10:45:40 2014 +0100 @@ -456,6 +456,11 @@ #endif } + if (ngx_strcmp(value[i].data, "nonlocal") == 0) { + ls->nonlocal = 1; + continue; + } + if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_MAIL_SSL) ls->ssl = 1; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel