|
From 3dd981c016ac7ad636ee546c2b9b685f7e8500d4 Mon Sep 17 00:00:00 2001
|
|
From: Lukas Tribus <luky-37@hotmail.com>
|
|
Date: Mon, 12 Sep 2016 21:42:20 +0000
|
|
Subject: [PATCH 06/26] MEDIUM: make SO_REUSEPORT configurable
|
|
|
|
With Linux officially introducing SO_REUSEPORT support in 3.9 and
|
|
its mainstream adoption we have seen more people running into strange
|
|
SO_REUSEPORT related issues (a process management issue turning into
|
|
hard to diagnose problems because the kernel load-balances between the
|
|
new and an obsolete haproxy instance).
|
|
|
|
Also some people simply want the guarantee that the bind fails when
|
|
the old process is still bound.
|
|
|
|
This change makes SO_REUSEPORT configurable, introducing the command
|
|
line argument "-dR" and the noreuseport configuration directive.
|
|
|
|
A backport to 1.6 should be considered.
|
|
(cherry picked from commit a0bcbdcb04d52c3ca71045f90aac33d9dd7965bf)
|
|
---
|
|
doc/configuration.txt | 5 +++++
|
|
include/types/global.h | 1 +
|
|
src/cfgparse.c | 5 +++++
|
|
src/haproxy.c | 10 ++++++++++
|
|
src/proto_tcp.c | 6 +++---
|
|
5 files changed, 24 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
|
index d18c399..e725ce2 100644
|
|
--- a/doc/configuration.txt
|
|
+++ b/doc/configuration.txt
|
|
@@ -570,6 +570,7 @@ The following keywords are supported in the "global" section :
|
|
- nopoll
|
|
- nosplice
|
|
- nogetaddrinfo
|
|
+ - noreuseport
|
|
- spread-checks
|
|
- server-state-base
|
|
- server-state-file
|
|
@@ -1090,6 +1091,10 @@ nogetaddrinfo
|
|
Disables the use of getaddrinfo(3) for name resolving. It is equivalent to
|
|
the command line argument "-dG". Deprecated gethostbyname(3) will be used.
|
|
|
|
+noreuseport
|
|
+ Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the
|
|
+ command line argument "-dR".
|
|
+
|
|
spread-checks <0..50, in percent>
|
|
Sometimes it is desirable to avoid sending agent and health checks to
|
|
servers at exact intervals, for instance when many logical servers are
|
|
diff --git a/include/types/global.h b/include/types/global.h
|
|
index 61f0391..2e24d3f 100644
|
|
--- a/include/types/global.h
|
|
+++ b/include/types/global.h
|
|
@@ -63,6 +63,7 @@
|
|
/* platform-specific options */
|
|
#define GTUNE_USE_SPLICE (1<<4)
|
|
#define GTUNE_USE_GAI (1<<5)
|
|
+#define GTUNE_USE_REUSEPORT (1<<6)
|
|
|
|
/* Access level for a stats socket */
|
|
#define ACCESS_LVL_NONE 0
|
|
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
|
index 55086fd..f2a104d 100644
|
|
--- a/src/cfgparse.c
|
|
+++ b/src/cfgparse.c
|
|
@@ -662,6 +662,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
|
goto out;
|
|
global.tune.options &= ~GTUNE_USE_GAI;
|
|
}
|
|
+ else if (!strcmp(args[0], "noreuseport")) {
|
|
+ if (alertif_too_many_args(0, file, linenum, args, &err_code))
|
|
+ goto out;
|
|
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
|
|
+ }
|
|
else if (!strcmp(args[0], "quiet")) {
|
|
if (alertif_too_many_args(0, file, linenum, args, &err_code))
|
|
goto out;
|
|
diff --git a/src/haproxy.c b/src/haproxy.c
|
|
index 9f5878a..a657dc4 100644
|
|
--- a/src/haproxy.c
|
|
+++ b/src/haproxy.c
|
|
@@ -452,6 +452,9 @@ void usage(char *name)
|
|
#if defined(USE_GETADDRINFO)
|
|
" -dG disables getaddrinfo() usage\n"
|
|
#endif
|
|
+#if defined(SO_REUSEPORT)
|
|
+ " -dR disables SO_REUSEPORT usage\n"
|
|
+#endif
|
|
" -dV disables SSL verify on servers side\n"
|
|
" -sf/-st [pid ]* finishes/terminates old pids.\n"
|
|
"\n",
|
|
@@ -623,6 +626,9 @@ void init(int argc, char **argv)
|
|
#if defined(USE_GETADDRINFO)
|
|
global.tune.options |= GTUNE_USE_GAI;
|
|
#endif
|
|
+#if defined(SO_REUSEPORT)
|
|
+ global.tune.options |= GTUNE_USE_REUSEPORT;
|
|
+#endif
|
|
|
|
pid = getpid();
|
|
progname = *argv;
|
|
@@ -666,6 +672,10 @@ void init(int argc, char **argv)
|
|
else if (*flag == 'd' && flag[1] == 'G')
|
|
global.tune.options &= ~GTUNE_USE_GAI;
|
|
#endif
|
|
+#if defined(SO_REUSEPORT)
|
|
+ else if (*flag == 'd' && flag[1] == 'R')
|
|
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
|
|
+#endif
|
|
else if (*flag == 'd' && flag[1] == 'V')
|
|
global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
|
|
else if (*flag == 'V')
|
|
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
|
index 4f5d88d..0f20fde 100644
|
|
--- a/src/proto_tcp.c
|
|
+++ b/src/proto_tcp.c
|
|
@@ -824,10 +824,10 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
|
setsockopt(fd, SOL_SOCKET, SO_LINGER, &nolinger, sizeof(struct linger));
|
|
|
|
#ifdef SO_REUSEPORT
|
|
- /* OpenBSD supports this. As it's present in old libc versions of Linux,
|
|
- * it might return an error that we will silently ignore.
|
|
+ /* OpenBSD and Linux 3.9 support this. As it's present in old libc versions of
|
|
+ * Linux, it might return an error that we will silently ignore.
|
|
*/
|
|
- if (!ext)
|
|
+ if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT))
|
|
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
|
|
#endif
|
|
|
|
--
|
|
2.7.3
|
|
|