[haproxy/f21] Add tcp-ut bind option to set TCP_USER_TIMEOUT (#1190783)
rohara
rohara at fedoraproject.org
Tue Feb 10 16:37:31 UTC 2015
commit 9ccca381484fd0abacc980e4361849577fe8cbdc
Author: Ryan O'Hara <rohara at redhat.com>
Date: Tue Feb 10 10:29:03 2015 -0600
Add tcp-ut bind option to set TCP_USER_TIMEOUT (#1190783)
haproxy-pattern-delete-acl-map.patch | 38 ++++++++++
haproxy-pattern-oom-error.patch | 30 ++++++++
haproxy-tcp-user-timeout.patch | 131 ++++++++++++++++++++++++++++++++++
haproxy.spec | 11 +++-
4 files changed, 209 insertions(+), 1 deletions(-)
---
diff --git a/haproxy-pattern-delete-acl-map.patch b/haproxy-pattern-delete-acl-map.patch
new file mode 100644
index 0000000..e301d2d
--- /dev/null
+++ b/haproxy-pattern-delete-acl-map.patch
@@ -0,0 +1,38 @@
+From 623401b983185c1e0f6507e96557de3bc46fd41b Mon Sep 17 00:00:00 2001
+From: Thierry FOURNIER <tfournier at 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
+
diff --git a/haproxy-pattern-oom-error.patch b/haproxy-pattern-oom-error.patch
new file mode 100644
index 0000000..0651702
--- /dev/null
+++ b/haproxy-pattern-oom-error.patch
@@ -0,0 +1,30 @@
+From e338a8741983acc9a4501a03ecd593d89e6fade3 Mon Sep 17 00:00:00 2001
+From: Thierry FOURNIER <tfournier at 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
+
diff --git a/haproxy-tcp-user-timeout.patch b/haproxy-tcp-user-timeout.patch
new file mode 100644
index 0000000..24fa77d
--- /dev/null
+++ b/haproxy-tcp-user-timeout.patch
@@ -0,0 +1,131 @@
+From 285871db151bd030d6247e8ee12b415a75c1566e Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w at 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
+
diff --git a/haproxy.spec b/haproxy.spec
index e00af00..c7e9718 100644
--- a/haproxy.spec
+++ b/haproxy.spec
@@ -8,7 +8,7 @@
Name: haproxy
Version: 1.5.11
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: HAProxy reverse proxy for high availability environments
Group: System Environment/Daemons
@@ -23,6 +23,9 @@ Source4: halog.1
Patch0: halog-unused-variables.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: zlib-devel
@@ -52,6 +55,9 @@ availability environments. Indeed, it can:
%setup -q
%patch0 -p0
%patch1 -p0
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
%build
regparm_opts=
@@ -135,6 +141,9 @@ exit 0
%attr(-,%{haproxy_user},%{haproxy_group}) %dir %{haproxy_home}
%changelog
+* Tue Feb 10 2015 Ryan O'Hara <rohara at 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 at redhat.com> - 1.5.11-1
- Update to 1.5.11 (#1188029)
More information about the scm-commits
mailing list