Add tcp-ut bind option to set TCP_USER_TIMEOUT (#1190783)

This commit is contained in:
Ryan O'Hara 2015-02-10 10:29:03 -06:00
parent 728e5a0dd1
commit 0d702190a7
4 changed files with 209 additions and 1 deletions

View File

@ -0,0 +1,38 @@
From 623401b983185c1e0f6507e96557de3bc46fd41b Mon Sep 17 00:00:00 2001
From: Thierry FOURNIER <tfournier@exceliance.fr>
Date: Fri, 6 Feb 2015 17:53:54 +0100
Subject: [PATCH 2/3] BUG/MEDIUM: pattern: some entries are not deleted with
case insensitive match
ACL or map entries are not deleted with the command "del acl" or "del map"
if the case insentive flag is set.
This is because the the case insensitive string are stored in a list and the
default delete function associated with string looks in a tree. I add a check
of the case insensitive flag and execute the delete function for lists if it
is set.
This patch must be backported in 1.5 version.
(cherry picked from commit 73bc285be194f443dc7eab9c949e87e1dbe8f70c)
---
src/pattern.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/pattern.c b/src/pattern.c
index a6fc52d..b19ffe2 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -1308,6 +1308,10 @@ void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref)
struct ebmb_node *node, *next_node;
struct pattern_tree *elt;
+ /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
+ if (expr->mflags & PAT_MF_IGNORE_CASE)
+ return pat_del_list_ptr(expr, ref);
+
/* browse each node of the tree. */
for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL;
node;
--
1.9.3

View File

@ -0,0 +1,30 @@
From e338a8741983acc9a4501a03ecd593d89e6fade3 Mon Sep 17 00:00:00 2001
From: Thierry FOURNIER <tfournier@exceliance.fr>
Date: Fri, 6 Feb 2015 17:50:55 +0100
Subject: [PATCH 1/3] BUG/MINOR: pattern: error message missing
This patch must be backported in 1.5 version.
(cherry picked from commit 8aa8384e22dd0b66ded00c70a9c6034278b4bb69)
---
src/pattern.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/pattern.c b/src/pattern.c
index 208e33a..a6fc52d 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -989,8 +989,10 @@ int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
/* allocate pattern */
patl = calloc(1, sizeof(*patl));
- if (!patl)
+ if (!patl) {
+ memprintf(err, "out of memory while indexing pattern");
return 0;
+ }
/* duplicate pattern */
memcpy(&patl->pat, pat, sizeof(*pat));
--
1.9.3

View File

@ -0,0 +1,131 @@
From 285871db151bd030d6247e8ee12b415a75c1566e Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 4 Feb 2015 00:45:58 +0100
Subject: [PATCH 3/3] MEDIUM: tcp: implement tcp-ut bind option to set
TCP_USER_TIMEOUT
On Linux since 2.6.37, it's possible to set the socket timeout for
pending outgoing data, with an accuracy of 1 millisecond. This is
pretty handy to deal with dead connections to clients and or servers.
For now we only implement it on the frontend side (bind line) so
that when a client disappears from the net, we're able to quickly
get rid of its connection and possibly release a server connection.
This can be useful with long-lived connections where an application
level timeout is not suited because long pauses are expected (remote
terminals, connection pools, etc).
Thanks to Thijs Houtenbos and John Eckersberg for the suggestion.
---
doc/configuration.txt | 13 +++++++++++++
include/types/listener.h | 1 +
src/proto_tcp.c | 42 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 3ae6624..634f71a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8585,6 +8585,19 @@ strict-sni
a certificate. The default certificate is not used.
See the "crt" option for more information.
+tcp-ut <delay>
+ Sets the TCP User Timeout for all incoming connections instanciated from this
+ listening socket. This option is available on Linux since version 2.6.37. It
+ allows haproxy to configure a timeout for sockets which contain data not
+ receiving an acknoledgement for the configured delay. This is especially
+ useful on long-lived connections experiencing long idle periods such as
+ remote terminals or database connection pools, where the client and server
+ timeouts must remain high to allow a long period of idle, but where it is
+ important to detect that the client has disappeared in order to release all
+ resources associated with its connection (and the server's session). The
+ argument is a delay expressed in milliseconds by default. This only works
+ for regular TCP connections, and is ignored for other protocols.
+
tfo
Is an optional keyword which is supported only on Linux kernels >= 3.7. It
enables TCP Fast Open on the listening socket, which means that clients which
diff --git a/include/types/listener.h b/include/types/listener.h
index 83b63af..2d71df6 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -175,6 +175,7 @@ struct listener {
struct list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */
unsigned int analysers; /* bitmap of required protocol analysers */
int maxseg; /* for TCP, advertised MSS */
+ int tcp_ut; /* for TCP, user timeout */
char *interface; /* interface name or NULL */
struct list by_fe; /* chaining in frontend's list of listeners */
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index cfa62f7..e98a9fb 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -838,6 +838,15 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
}
}
#endif
+#if defined(TCP_USER_TIMEOUT)
+ if (listener->tcp_ut) {
+ if (setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT,
+ &listener->tcp_ut, sizeof(listener->tcp_ut)) == -1) {
+ msg = "cannot set TCP User Timeout";
+ err |= ERR_WARN;
+ }
+ }
+#endif
#if defined(TCP_DEFER_ACCEPT)
if (listener->options & LI_O_DEF_ACCEPT) {
/* defer accept by up to one second */
@@ -1986,8 +1995,36 @@ static int bind_parse_mss(char **args, int cur_arg, struct proxy *px, struct bin
}
#endif
+#ifdef TCP_USER_TIMEOUT
+/* parse the "tcp-ut" bind keyword */
+static int bind_parse_tcp_ut(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ const char *ptr = NULL;
+ struct listener *l;
+ unsigned int timeout;
+
+ if (!*args[cur_arg + 1]) {
+ memprintf(err, "'%s' : missing TCP User Timeout value", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ ptr = parse_time_err(args[cur_arg + 1], &timeout, TIME_UNIT_MS);
+ if (ptr) {
+ memprintf(err, "'%s' : expects a positive delay in milliseconds", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ list_for_each_entry(l, &conf->listeners, by_bind) {
+ if (l->addr.ss_family == AF_INET || l->addr.ss_family == AF_INET6)
+ l->tcp_ut = timeout;
+ }
+
+ return 0;
+}
+#endif
+
#ifdef SO_BINDTODEVICE
-/* parse the "mss" bind keyword */
+/* parse the "interface" bind keyword */
static int bind_parse_interface(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
@@ -2056,6 +2093,9 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
#ifdef TCP_MAXSEG
{ "mss", bind_parse_mss, 1 }, /* set MSS of listening socket */
#endif
+#ifdef TCP_USER_TIMEOUT
+ { "tcp-ut", bind_parse_tcp_ut, 1 }, /* set User Timeout on listening socket */
+#endif
#ifdef TCP_FASTOPEN
{ "tfo", bind_parse_tfo, 0 }, /* enable TCP_FASTOPEN of listening socket */
#endif
--
1.9.3

View File

@ -8,7 +8,7 @@
Name: haproxy Name: haproxy
Version: 1.5.11 Version: 1.5.11
Release: 1%{?dist} Release: 2%{?dist}
Summary: HAProxy reverse proxy for high availability environments Summary: HAProxy reverse proxy for high availability environments
Group: System Environment/Daemons Group: System Environment/Daemons
@ -23,6 +23,9 @@ Source4: halog.1
Patch0: halog-unused-variables.patch Patch0: halog-unused-variables.patch
Patch1: iprange-return-type.patch Patch1: iprange-return-type.patch
Patch2: haproxy-pattern-oom-error.patch
Patch3: haproxy-pattern-delete-acl-map.patch
Patch4: haproxy-tcp-user-timeout.patch
BuildRequires: pcre-devel BuildRequires: pcre-devel
BuildRequires: zlib-devel BuildRequires: zlib-devel
@ -52,6 +55,9 @@ availability environments. Indeed, it can:
%setup -q %setup -q
%patch0 -p0 %patch0 -p0
%patch1 -p0 %patch1 -p0
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build %build
regparm_opts= regparm_opts=
@ -135,6 +141,9 @@ exit 0
%attr(-,%{haproxy_user},%{haproxy_group}) %dir %{haproxy_home} %attr(-,%{haproxy_user},%{haproxy_group}) %dir %{haproxy_home}
%changelog %changelog
* Tue Feb 10 2015 Ryan O'Hara <rohara@redhat.com> - 1.5.11-2
- Add tcp-ut bind option to set TCP_USER_TIMEOUT (#1190783)
* Sun Feb 01 2015 Ryan O'Hara <rohara@redhat.com> - 1.5.11-1 * Sun Feb 01 2015 Ryan O'Hara <rohara@redhat.com> - 1.5.11-1
- Update to 1.5.11 (#1188029) - Update to 1.5.11 (#1188029)