From 1fa3126ec4eb172fb64bad7fee95920073b020ba Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 3 Dec 2007 00:36:16 +0100 Subject: [PATCH] [MEDIUM] introduce separation between contimeout, and tarpit + queue 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 | 4 ++++ src/backend.c | 4 ++-- src/cfgparse.c | 39 +++++++++++++++++++++++++++++++++++++++ src/proto_http.c | 10 +++++----- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/types/proxy.h b/include/types/proxy.h index 61247e644f..ae6e337d50 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -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 */ diff --git a/src/backend.c b/src/backend.c index 1eed377e9a..57b421cf0b 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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 */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 4ebb9ff178..91b9f3ccd0 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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)); diff --git a/src/proto_http.c b/src/proto_http.c index 370fded297..55c67c1b86 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; } -- 2.39.5