mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-05 11:39:33 +00:00
MINOR: h2: make use of client-fin timeout after GOAWAY
At the moment, the "client" timeout is used on an HTTP/2 connection once it's idle with no active stream. With this patch, this timeout is replaced by client-fin once a GOAWAY frame is sent. This closely matches what is done on HTTP/1 since the principle is the same, as it indicates a willing ness to quickly close a connection on which we don't expect to see anything anymore.
This commit is contained in:
parent
a76e4c2183
commit
599391a7c2
@ -9826,7 +9826,9 @@ timeout client-fin <timeout>
|
||||
FIN_WAIT state for too long when clients do not disconnect cleanly. This
|
||||
problem is particularly common long connections such as RDP or WebSocket.
|
||||
Note that this timeout can override "timeout tunnel" when a connection shuts
|
||||
down in one direction.
|
||||
down in one direction. It is applied to idle HTTP/2 connections once a GOAWAY
|
||||
frame was sent, often indicating an expectation that the connection quickly
|
||||
ends.
|
||||
|
||||
This parameter is specific to frontends, but can be specified once for all in
|
||||
"defaults" sections. By default it is not set, so half-closed connections
|
||||
|
11
src/mux_h2.c
11
src/mux_h2.c
@ -104,6 +104,7 @@ struct h2c {
|
||||
int32_t mfs; /* mux's max frame size */
|
||||
|
||||
int timeout; /* idle timeout duration in ticks */
|
||||
int shut_timeout; /* idle timeout duration in ticks after GOAWAY was sent */
|
||||
struct task *task; /* timeout management task */
|
||||
struct eb_root streams_by_id; /* all active streams by their ID */
|
||||
struct list send_list; /* list of blocked streams requesting to send */
|
||||
@ -332,7 +333,10 @@ static int h2c_frt_init(struct connection *conn)
|
||||
goto fail;
|
||||
|
||||
|
||||
h2c->timeout = sess->fe->timeout.client;
|
||||
h2c->shut_timeout = h2c->timeout = sess->fe->timeout.client;
|
||||
if (tick_isset(sess->fe->timeout.clientfin))
|
||||
h2c->shut_timeout = sess->fe->timeout.clientfin;
|
||||
|
||||
h2c->task = NULL;
|
||||
if (tick_isset(h2c->timeout)) {
|
||||
t = task_new(tid_bit);
|
||||
@ -2143,7 +2147,7 @@ static int h2_wake(struct connection *conn)
|
||||
|
||||
if (h2c->task) {
|
||||
if (eb_is_empty(&h2c->streams_by_id)) {
|
||||
h2c->task->expire = tick_add(now_ms, h2c->timeout);
|
||||
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
task_queue(h2c->task);
|
||||
}
|
||||
else
|
||||
@ -2175,6 +2179,7 @@ static struct task *h2_timeout_task(struct task *t)
|
||||
}
|
||||
|
||||
/* try to send but no need to insist */
|
||||
h2c->last_sid = h2c->max_id;
|
||||
if (h2c_send_goaway_error(h2c, NULL) <= 0)
|
||||
h2c->flags |= H2_CF_GOAWAY_FAILED;
|
||||
|
||||
@ -2310,7 +2315,7 @@ static void h2_detach(struct conn_stream *cs)
|
||||
}
|
||||
else if (h2c->task) {
|
||||
if (eb_is_empty(&h2c->streams_by_id)) {
|
||||
h2c->task->expire = tick_add(now_ms, h2c->timeout);
|
||||
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
|
||||
task_queue(h2c->task);
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user