You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.7 KiB

  1. From 3dd981c016ac7ad636ee546c2b9b685f7e8500d4 Mon Sep 17 00:00:00 2001
  2. From: Lukas Tribus <luky-37@hotmail.com>
  3. Date: Mon, 12 Sep 2016 21:42:20 +0000
  4. Subject: [PATCH 06/26] MEDIUM: make SO_REUSEPORT configurable
  5. With Linux officially introducing SO_REUSEPORT support in 3.9 and
  6. its mainstream adoption we have seen more people running into strange
  7. SO_REUSEPORT related issues (a process management issue turning into
  8. hard to diagnose problems because the kernel load-balances between the
  9. new and an obsolete haproxy instance).
  10. Also some people simply want the guarantee that the bind fails when
  11. the old process is still bound.
  12. This change makes SO_REUSEPORT configurable, introducing the command
  13. line argument "-dR" and the noreuseport configuration directive.
  14. A backport to 1.6 should be considered.
  15. (cherry picked from commit a0bcbdcb04d52c3ca71045f90aac33d9dd7965bf)
  16. ---
  17. doc/configuration.txt | 5 +++++
  18. include/types/global.h | 1 +
  19. src/cfgparse.c | 5 +++++
  20. src/haproxy.c | 10 ++++++++++
  21. src/proto_tcp.c | 6 +++---
  22. 5 files changed, 24 insertions(+), 3 deletions(-)
  23. diff --git a/doc/configuration.txt b/doc/configuration.txt
  24. index d18c399..e725ce2 100644
  25. --- a/doc/configuration.txt
  26. +++ b/doc/configuration.txt
  27. @@ -570,6 +570,7 @@ The following keywords are supported in the "global" section :
  28. - nopoll
  29. - nosplice
  30. - nogetaddrinfo
  31. + - noreuseport
  32. - spread-checks
  33. - server-state-base
  34. - server-state-file
  35. @@ -1090,6 +1091,10 @@ nogetaddrinfo
  36. Disables the use of getaddrinfo(3) for name resolving. It is equivalent to
  37. the command line argument "-dG". Deprecated gethostbyname(3) will be used.
  38. +noreuseport
  39. + Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the
  40. + command line argument "-dR".
  41. +
  42. spread-checks <0..50, in percent>
  43. Sometimes it is desirable to avoid sending agent and health checks to
  44. servers at exact intervals, for instance when many logical servers are
  45. diff --git a/include/types/global.h b/include/types/global.h
  46. index 61f0391..2e24d3f 100644
  47. --- a/include/types/global.h
  48. +++ b/include/types/global.h
  49. @@ -63,6 +63,7 @@
  50. /* platform-specific options */
  51. #define GTUNE_USE_SPLICE (1<<4)
  52. #define GTUNE_USE_GAI (1<<5)
  53. +#define GTUNE_USE_REUSEPORT (1<<6)
  54. /* Access level for a stats socket */
  55. #define ACCESS_LVL_NONE 0
  56. diff --git a/src/cfgparse.c b/src/cfgparse.c
  57. index 55086fd..f2a104d 100644
  58. --- a/src/cfgparse.c
  59. +++ b/src/cfgparse.c
  60. @@ -662,6 +662,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
  61. goto out;
  62. global.tune.options &= ~GTUNE_USE_GAI;
  63. }
  64. + else if (!strcmp(args[0], "noreuseport")) {
  65. + if (alertif_too_many_args(0, file, linenum, args, &err_code))
  66. + goto out;
  67. + global.tune.options &= ~GTUNE_USE_REUSEPORT;
  68. + }
  69. else if (!strcmp(args[0], "quiet")) {
  70. if (alertif_too_many_args(0, file, linenum, args, &err_code))
  71. goto out;
  72. diff --git a/src/haproxy.c b/src/haproxy.c
  73. index 9f5878a..a657dc4 100644
  74. --- a/src/haproxy.c
  75. +++ b/src/haproxy.c
  76. @@ -452,6 +452,9 @@ void usage(char *name)
  77. #if defined(USE_GETADDRINFO)
  78. " -dG disables getaddrinfo() usage\n"
  79. #endif
  80. +#if defined(SO_REUSEPORT)
  81. + " -dR disables SO_REUSEPORT usage\n"
  82. +#endif
  83. " -dV disables SSL verify on servers side\n"
  84. " -sf/-st [pid ]* finishes/terminates old pids.\n"
  85. "\n",
  86. @@ -623,6 +626,9 @@ void init(int argc, char **argv)
  87. #if defined(USE_GETADDRINFO)
  88. global.tune.options |= GTUNE_USE_GAI;
  89. #endif
  90. +#if defined(SO_REUSEPORT)
  91. + global.tune.options |= GTUNE_USE_REUSEPORT;
  92. +#endif
  93. pid = getpid();
  94. progname = *argv;
  95. @@ -666,6 +672,10 @@ void init(int argc, char **argv)
  96. else if (*flag == 'd' && flag[1] == 'G')
  97. global.tune.options &= ~GTUNE_USE_GAI;
  98. #endif
  99. +#if defined(SO_REUSEPORT)
  100. + else if (*flag == 'd' && flag[1] == 'R')
  101. + global.tune.options &= ~GTUNE_USE_REUSEPORT;
  102. +#endif
  103. else if (*flag == 'd' && flag[1] == 'V')
  104. global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
  105. else if (*flag == 'V')
  106. diff --git a/src/proto_tcp.c b/src/proto_tcp.c
  107. index 4f5d88d..0f20fde 100644
  108. --- a/src/proto_tcp.c
  109. +++ b/src/proto_tcp.c
  110. @@ -824,10 +824,10 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
  111. setsockopt(fd, SOL_SOCKET, SO_LINGER, &nolinger, sizeof(struct linger));
  112. #ifdef SO_REUSEPORT
  113. - /* OpenBSD supports this. As it's present in old libc versions of Linux,
  114. - * it might return an error that we will silently ignore.
  115. + /* OpenBSD and Linux 3.9 support this. As it's present in old libc versions of
  116. + * Linux, it might return an error that we will silently ignore.
  117. */
  118. - if (!ext)
  119. + if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT))
  120. setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
  121. #endif
  122. --
  123. 2.7.3