]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] introduce separation between contimeout, and tarpit + queue
authorWilly Tarreau <w@1wt.eu>
Sun, 2 Dec 2007 23:36:16 +0000 (00:36 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Dec 2007 23:36:16 +0000 (00:36 +0100)
Now the connect timeout, tarpit timeout and queue timeout are
distinct. In order to retain compatibility with older versions,
if either queue or tarpit is left unset both in the proxy and
in the default proxy, then it is inherited from the connect
timeout as before.

include/types/proxy.h
src/backend.c
src/cfgparse.c
src/proto_http.c

index 61247e644f1e5e990fd578b7f3ff370f9ba7d8f4..ae6e337d50b33e4ee5c3c2e9ee05012dd2648fd4 100644 (file)
@@ -173,6 +173,10 @@ struct proxy {
        struct timeval srvtimeout;              /* server I/O timeout (in milliseconds) */
        struct timeval contimeout;              /* connect timeout (in milliseconds) */
        struct timeval appsession_timeout;
+       struct {
+               struct timeval queue;           /* queue timeout, defaults to contimeout if unspecified */
+               struct timeval tarpit;          /* tarpit timeout, defaults to contimeout if unspecified */
+       } timeout;
        char *id;                               /* proxy id */
        struct list pendconns;                  /* pending connections with no server assigned yet */
        int nbpend, nbpend_max;                 /* number of pending connections with no server assigned yet */
index 1eed377e9aff5f3b6740f05def14b4d357cf1909..57b421cf0b4c37bcaf89169f69c925573bd5d716 100644 (file)
@@ -1460,8 +1460,8 @@ int srv_redispatch_connect(struct session *t)
                return 1;
 
        case SRV_STATUS_QUEUED:
-               /* FIXME-20060503 : we should use the queue timeout instead */
-               if (!tv_add_ifset(&t->req->cex, &now, &t->be->contimeout))
+               /* note: we use the connect expiration date for the queue. */
+               if (!tv_add_ifset(&t->req->cex, &now, &t->be->timeout.queue))
                        tv_eternity(&t->req->cex);
                t->srv_state = SV_STIDLE;
                /* do nothing else and do not wake any other session up */
index 4ebb9ff178de3b24c18a3134e253c3639f9bc5c3..91b9f3ccd05d3879d0d7fc4edf08eae0eecb39e0 100644 (file)
@@ -502,6 +502,8 @@ static void init_default_instance()
        tv_eternity(&defproxy.contimeout);
        tv_eternity(&defproxy.srvtimeout);
        tv_eternity(&defproxy.appsession_timeout);
+       tv_eternity(&defproxy.timeout.queue);
+       tv_eternity(&defproxy.timeout.tarpit);
 }
 
 /*
@@ -582,6 +584,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                tv_eternity(&curproxy->srvtimeout);
                tv_eternity(&curproxy->contimeout);
                tv_eternity(&curproxy->appsession_timeout);
+               tv_eternity(&curproxy->timeout.queue);
+               tv_eternity(&curproxy->timeout.tarpit);
 
                curproxy->last_change = now.tv_sec;
                curproxy->id = strdup(args[1]);
@@ -640,6 +644,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
 
                if (curproxy->cap & PR_CAP_FE) {
                        curproxy->clitimeout = defproxy.clitimeout;
+                       curproxy->timeout.tarpit = defproxy.timeout.tarpit;
                        curproxy->uri_auth  = defproxy.uri_auth;
                        curproxy->mon_net = defproxy.mon_net;
                        curproxy->mon_mask = defproxy.mon_mask;
@@ -653,6 +658,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
                if (curproxy->cap & PR_CAP_BE) {
                        curproxy->contimeout = defproxy.contimeout;
                        curproxy->srvtimeout = defproxy.srvtimeout;
+                       curproxy->timeout.queue = defproxy.timeout.queue;
                        curproxy->source_addr = defproxy.source_addr;
                }
 
@@ -2738,6 +2744,39 @@ int readcfgfile(const char *file)
                                file, proxy_type_str(curproxy), curproxy->id);
                }
 
+               /* Historically, the tarpit and queue timeouts were inherited from contimeout.
+                * We must still support older configurations, so let's find out whether those
+                * parameters have been set or must be copied from contimeouts.
+                */
+               if (curproxy != &defproxy) {
+                       if ((curproxy->cap & PR_CAP_FE) &&
+                           (!tv_isset(&curproxy->timeout.tarpit) ||
+                            __tv_iseq(&curproxy->timeout.tarpit, &defproxy.timeout.tarpit))) {
+                               /* tarpit timeout not set. We search in the following order:
+                                * default.tarpit, curr.connect, default.connect.
+                                */
+                               if (tv_isset(&defproxy.timeout.tarpit))
+                                       curproxy->timeout.tarpit = defproxy.timeout.tarpit;
+                               else if (tv_isset(&curproxy->contimeout))
+                                       curproxy->timeout.tarpit = curproxy->contimeout;
+                               else if (tv_isset(&defproxy.contimeout))
+                                       curproxy->timeout.tarpit = defproxy.contimeout;
+                       }
+                       if ((curproxy->cap & PR_CAP_BE) &&
+                           (!tv_isset(&curproxy->timeout.queue) ||
+                            __tv_iseq(&curproxy->timeout.queue, &defproxy.timeout.queue))) {
+                               /* queue timeout not set. We search in the following order:
+                                * default.queue, curr.connect, default.connect.
+                                */
+                               if (tv_isset(&defproxy.timeout.queue))
+                                       curproxy->timeout.queue = defproxy.timeout.queue;
+                               else if (tv_isset(&curproxy->contimeout))
+                                       curproxy->timeout.queue = curproxy->contimeout;
+                               else if (tv_isset(&defproxy.contimeout))
+                                       curproxy->timeout.queue = defproxy.contimeout;
+                       }
+               }
+
                if (curproxy->options & PR_O_SSL3_CHK) {
                        curproxy->check_len = sizeof(sslv3_client_hello_pkt);
                        curproxy->check_req = (char *)malloc(sizeof(sslv3_client_hello_pkt));
index 370fded297c48355fde53e074f8b577cf8717b2a..55c67c1b8673cf951eb30882461f2f7cadf9f534 100644 (file)
@@ -2038,17 +2038,17 @@ int process_cli(struct session *t)
                        tv_eternity(&req->rex);
                }
 
-               /* When a connection is tarpitted, we use the queue timeout for the
-                * tarpit delay, which currently happens to be the server's connect
-                * timeout. If unset, then set it to zero because we really want it
-                * to expire at one moment.
+               /* When a connection is tarpitted, we use the tarpit timeout,
+                * which may be the same as the connect timeout if unspecified.
+                * If unset, then set it to zero because we really want it to
+                * eventually expire.
                 */
                if (txn->flags & TX_CLTARPIT) {
                        t->req->l = 0;
                        /* flush the request so that we can drop the connection early
                         * if the client closes first.
                         */
-                       if (!tv_add_ifset(&req->cex, &now, &t->be->contimeout))
+                       if (!tv_add_ifset(&req->cex, &now, &t->be->timeout.tarpit))
                                req->cex = now;
                }