]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: session: add support for tunnel timeouts
authorWilly Tarreau <w@1wt.eu>
Sat, 12 May 2012 10:50:00 +0000 (12:50 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 12 May 2012 10:50:00 +0000 (12:50 +0200)
Tunnel timeouts are used when TCP connections are forwarded, or
when forwarding upgraded HTTP connections (WebSocket) as well as
CONNECT requests to proxies.

This timeout allows long-lived sessions to be supported without
having to set large timeouts to normal requests.

doc/configuration.txt
include/proto/proxy.h
include/types/proxy.h
src/cfgparse.c
src/proxy.c
src/session.c

index 9aa7e1c6d27b373aece27ef61b965d0b62a9b5a2..99e4f85848811e0a3ac69dd4fcfac8fcb838dec1 100644 (file)
@@ -1117,6 +1117,7 @@ timeout queue                             X          -         X         X
 timeout server                            X          -         X         X
 timeout srvtimeout          (deprecated)  X          -         X         X
 timeout tarpit                            X          X         X         X
+timeout tunnel                            X          -         X         X
 transparent                 (deprecated)  X          -         X         X
 unique-id-format                          X          X         X         -
 unique-id-header                          X          X         X         -
@@ -3551,7 +3552,7 @@ no option independant-streams
   data sent to the server. Doing so will typically break large HTTP posts from
   slow lines, so use it with caution.
 
-  See also : "timeout client" and "timeout server"
+  See also : "timeout client", "timeout server" and "timeout tunnel"
 
 
 option ldap-check
@@ -5014,7 +5015,8 @@ srvtimeout <timeout> (deprecated)
   This parameter is provided for compatibility but is currently deprecated.
   Please use "timeout server" instead.
 
-  See also : "timeout server", "timeout client" and "clitimeout".
+  See also : "timeout server", "timeout tunnel", "timeout client" and
+             "clitimeout".
 
 
 stats admin { if | unless } <cond>
@@ -6334,7 +6336,9 @@ timeout clitimeout <timeout> (deprecated)
   client timeout remains equal to the server timeout in order to avoid complex
   situations to debug. It is a good practice to cover one or several TCP packet
   losses by specifying timeouts that are slightly above multiples of 3 seconds
-  (eg: 4 or 5 seconds).
+  (eg: 4 or 5 seconds). If some long-lived sessions are mixed with short-lived
+  sessions (eg: WebSocket and HTTP), it's worth considering "timeout tunnel",
+  which overrides "timeout client" and "timeout server" for tunnels.
 
   This parameter is specific to frontends, but can be specified once for all in
   "defaults" sections. This is in fact one of the easiest solutions not to
@@ -6347,7 +6351,7 @@ timeout clitimeout <timeout> (deprecated)
   to use it to write new configurations. The form "timeout clitimeout" is
   provided only by backwards compatibility but its use is strongly discouraged.
 
-  See also : "clitimeout", "timeout server".
+  See also : "clitimeout", "timeout server", "timeout tunnel".
 
 
 timeout connect <timeout>
@@ -6508,7 +6512,10 @@ timeout srvtimeout <timeout> (deprecated)
   order to avoid complex situations to debug. Whatever the expected server
   response times, it is a good practice to cover at least one or several TCP
   packet losses by specifying timeouts that are slightly above multiples of 3
-  seconds (eg: 4 or 5 seconds minimum).
+  seconds (eg: 4 or 5 seconds minimum). If some long-lived sessions are mixed
+  with short-lived sessions (eg: WebSocket and HTTP), it's worth considering
+  "timeout tunnel", which overrides "timeout client" and "timeout server" for
+  tunnels.
 
   This parameter is specific to backends, but can be specified once for all in
   "defaults" sections. This is in fact one of the easiest solutions not to
@@ -6521,7 +6528,7 @@ timeout srvtimeout <timeout> (deprecated)
   to use it to write new configurations. The form "timeout srvtimeout" is
   provided only by backwards compatibility but its use is strongly discouraged.
 
-  See also : "srvtimeout", "timeout client".
+  See also : "srvtimeout", "timeout client" and "timeout tunnel".
 
 
 timeout tarpit <timeout>
@@ -6546,6 +6553,47 @@ timeout tarpit <timeout>
   See also : "timeout connect", "contimeout".
 
 
+timeout tunnel <timeout>
+  Set the maximum inactivity time on the client and server side for tunnels.
+  May be used in sections :   defaults | frontend | listen | backend
+                                 yes   |    no    |   yes  |   yes
+  Arguments :
+    <timeout> is the timeout value specified in milliseconds by default, but
+              can be in any other unit if the number is suffixed by the unit,
+              as explained at the top of this document.
+
+  The tunnel timeout applies when a bidirectionnal connection is established
+  between a client and a server, and the connection remains inactive in both
+  directions. This timeout supersedes both the client and server timeouts once
+  the connection becomes a tunnel. In TCP, this timeout is used as soon as no
+  analyser remains attached to either connection (eg: tcp content rules are
+  accepted). In HTTP, this timeout is used when a connection is upgraded (eg:
+  when switching to the WebSocket protocol, or forwarding a CONNECT request
+  to a proxy), or after the first response when no keepalive/close option is
+  specified.
+
+  The value is specified in milliseconds by default, but can be in any other
+  unit if the number is suffixed by the unit, as specified at the top of this
+  document. Whatever the expected normal idle time, it is a good practice to
+  cover at least one or several TCP packet losses by specifying timeouts that
+  are slightly above multiples of 3 seconds (eg: 4 or 5 seconds minimum).
+
+  This parameter is specific to backends, but can be specified once for all in
+  "defaults" sections. This is in fact one of the easiest solutions not to
+  forget about it.
+
+  Example :
+        defaults http
+            option http-server-close
+            timeout connect 5s
+            timeout client 30s
+            timeout client 30s
+            timeout server 30s
+            timeout tunnel  1h    # timeout to use with WebSocket and CONNECT
+
+  See also : "timeout client", "timeout server".
+
+
 transparent (deprecated)
   Enable client-side transparent proxying
   May be used in sections :   defaults | frontend | listen | backend
index b2e97fe7de88fdbc9d50c102025777ad003d2db6..d5fd3e01ace8b01492edda41a13475092c47634c 100644 (file)
@@ -69,6 +69,7 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
        proxy->timeout.appsession = TICK_ETERNITY;
        proxy->timeout.httpreq = TICK_ETERNITY;
        proxy->timeout.check = TICK_ETERNITY;
+       proxy->timeout.tunnel = TICK_ETERNITY;
 }
 
 /* increase the number of cumulated connections received on the designated frontend */
index 26af501544e200e965ad6aa962f7c2cc5e3258a7..a94eee7678da64ae2d518dfb675e6c3d66cd5ac4 100644 (file)
@@ -263,6 +263,7 @@ struct proxy {
                int httpreq;                    /* maximum time for complete HTTP request */
                int httpka;                     /* maximum time for a new HTTP request when using keep-alive */
                int check;                      /* maximum time for complete check */
+               int tunnel;                     /* I/O timeout to use in tunnel mode (in ticks) */
        } timeout;
        char *id, *desc;                        /* proxy id (name) and description */
        struct list pendconns;                  /* pending connections with no server assigned yet */
index 5d12056d05c1b3cf5f27c3d3794d8989066725e3..49d1dbe02190d5973e6f9bc7b65ad5a1b17f5978 100644 (file)
@@ -1547,6 +1547,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        curproxy->timeout.tarpit = defproxy.timeout.tarpit;
                        curproxy->timeout.httpreq = defproxy.timeout.httpreq;
                        curproxy->timeout.httpka = defproxy.timeout.httpka;
+                       curproxy->timeout.tunnel = defproxy.timeout.tunnel;
                        curproxy->source_addr = defproxy.source_addr;
                }
 
@@ -6127,7 +6128,8 @@ out_uri_auth_compat:
                if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
                    (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
                     ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
-                     (!curproxy->timeout.connect || !curproxy->timeout.server)))) {
+                     (!curproxy->timeout.connect ||
+                      (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
                        Warning("config : missing timeouts for %s '%s'.\n"
                                "   | While not properly invalid, you will certainly encounter various problems\n"
                                "   | with such a configuration. To fix this, please ensure that all following\n"
index 9ae9889814cd8a066fea6d764c6ee75099948b83..bc5779ff3f759f4bcbbcede9ae6f732b9c16446d 100644 (file)
@@ -183,10 +183,14 @@ static int proxy_parse_timeout(char **args, int section, struct proxy *proxy,
                tv = &proxy->timeout.queue;
                td = &defpx->timeout.queue;
                cap = PR_CAP_BE;
+       } else if (!strcmp(args[0], "tunnel")) {
+               tv = &proxy->timeout.tunnel;
+               td = &defpx->timeout.tunnel;
+               cap = PR_CAP_BE;
        } else {
                memprintf(err,
                          "'timeout' supports 'client', 'server', 'connect', 'check', "
-                         "'queue', 'http-keep-alive', 'http-request' or 'tarpit', (got '%s')",
+                         "'queue', 'http-keep-alive', 'http-request', 'tunnel' or 'tarpit', (got '%s')",
                          args[0]);
                return -1;
        }
index 088b43663102e23d75c9f1d2e4f5b1adb531e43f..ae20e5b38b16a6f3fc4d33739d87296b55b95104 100644 (file)
@@ -2001,6 +2001,16 @@ struct task *process_session(struct task *t)
                 */
                if (!(s->rep->flags & (BF_SHUTR|BF_SHUTW_NOW)))
                        buffer_forward(s->rep, BUF_INFINITE_FORWARD);
+
+               /* if we have no analyser anymore in any direction and have a
+                * tunnel timeout set, use it now.
+                */
+               if (!s->req->analysers && s->be->timeout.tunnel) {
+                       s->req->rto = s->req->wto = s->rep->rto = s->rep->wto =
+                               s->be->timeout.tunnel;
+                       s->req->rex = s->req->wex = s->rep->rex = s->rep->wex =
+                               tick_add(now_ms, s->be->timeout.tunnel);
+               }
        }
 
        /* check if it is wise to enable kernel splicing to forward response data */