diff options
author | Christopher Faulet <cfaulet@haproxy.com> | 2020-10-05 17:50:58 +0200 |
---|---|---|
committer | Christopher Faulet <cfaulet@haproxy.com> | 2020-11-20 13:01:27 +0100 |
commit | 08dca01bb3baa85d060edf11acc49a98de278da1 (patch) | |
tree | 2595cbb4094ea96aacb64b04c690c461dc3a58c7 | |
parent | c3da9d43c5237d10d750e59360e0d992970b3e76 (diff) | |
download | haproxy-08dca01bb3baa85d060edf11acc49a98de278da1.tar.gz |
MINOR: mux-h1: Add a idle expiration date on the H1 connection
An idle expiration date is added on the H1 connection with the function to set
it depending on connection state. First, there is no idle timeout on backend
connections, For idle frontend connections, the http-request or keep-alive
timeout are used depending on which timeout is defined and if it is the first
request or not. For embryonic connections, the http-request is always used, if
defined. For attached or shutted down connections, no idle timeout is applied.
For now the idle expiration date is never set and the h1_set_idle_expiration
function remains unused.
-rw-r--r-- | src/mux_h1.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/src/mux_h1.c b/src/mux_h1.c index 15ba7e1a6..8c986a979 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -98,8 +98,9 @@ struct h1c { struct h1s *h1s; /* H1 stream descriptor */ struct task *task; /* timeout management task */ - int timeout; /* idle timeout duration in ticks */ - int shut_timeout; /* idle timeout duration in ticks after stream shutdown */ + int idle_exp; /* idle expriation date (http-keep-alive or http-request timeout) */ + int timeout; /* client/server timeout duration */ + int shut_timeout; /* client-fin/server-fin timeout duration */ }; /* H1 stream descriptor */ @@ -500,10 +501,46 @@ static void h1_refresh_timeout(struct h1c *h1c) TRACE_DEVEL("no connection timeout (alive back h1c or front h1c with a CS)", H1_EV_H1C_SEND|H1_EV_H1C_RECV, h1c->conn); } + /* Finally set the idle expiration date if shorter */ + h1c->task->expire = tick_first(h1c->task->expire, h1c->idle_exp); TRACE_DEVEL("new expiration date", H1_EV_H1C_SEND|H1_EV_H1C_RECV, h1c->conn, 0, 0, (size_t[]){h1c->task->expire}); task_queue(h1c->task); } } + +static __maybe_unused void h1_set_idle_expiration(struct h1c *h1c) +{ + if (h1c->flags & H1C_F_IS_BACK || !h1c->task) { + TRACE_DEVEL("no idle expiration (backend connection || no task)", H1_EV_H1C_RECV, h1c->conn); + h1c->idle_exp = TICK_ETERNITY; + return; + } + + if (h1c->flags & H1C_F_CS_IDLE) { + if (!tick_isset(h1c->idle_exp)) { + if ((h1c->flags & H1C_F_WAIT_NEXT_REQ) && /* Not the first request */ + !b_data(&h1c->ibuf) && /* No input data */ + tick_isset(h1c->px->timeout.httpka)) { /* K-A timeout set */ + h1c->idle_exp = tick_add_ifset(now_ms, h1c->px->timeout.httpka); + TRACE_DEVEL("set idle expiration (keep-alive timeout)", H1_EV_H1C_RECV, h1c->conn); + } + else { + h1c->idle_exp = tick_add_ifset(now_ms, h1c->px->timeout.httpreq); + TRACE_DEVEL("set idle expiration (http-request timeout)", H1_EV_H1C_RECV, h1c->conn); + } + } + } + else if (h1c->flags & H1C_F_CS_EMBRYIONIC) { + if (!tick_isset(h1c->idle_exp)) { + h1c->idle_exp = tick_add_ifset(now_ms, h1c->px->timeout.httpreq); + TRACE_DEVEL("set idle expiration (http-request timeout)", H1_EV_H1C_RECV, h1c->conn); + } + } + else { // CS_ATTACHED or SHUTDOWN + h1c->idle_exp = TICK_ETERNITY; + TRACE_DEVEL("unset idle expiration (attached || shutdown)", H1_EV_H1C_RECV, h1c->conn); + } +} /*****************************************************************/ /* functions below are dedicated to the mux setup and management */ /*****************************************************************/ @@ -724,6 +761,7 @@ static int h1_init(struct connection *conn, struct proxy *proxy, struct session h1c->wait_event.tasklet->process = h1_io_cb; h1c->wait_event.tasklet->context = h1c; h1c->wait_event.events = 0; + h1c->idle_exp = TICK_ETERNITY; if (conn_is_back(conn)) { h1c->flags |= (H1C_F_IS_BACK|H1C_F_DONT_READ); |