[PATCH] Added nonlocal to the listen directive
Trygve Vea
tv at redpill-linpro.com
Fri Mar 28 09:45:53 UTC 2014
# HG changeset patch
# User Trygve Vea <tv at 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;
More information about the nginx-devel
mailing list