From: Willy Tarreau Date: Thu, 31 Oct 2019 14:36:30 +0000 (+0100) Subject: BUG/MEDIUM: mux-h2: immediately remove a failed connection from the idle list X-Git-Tag: v2.1-dev4~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4481e26e5dd2bc04df494c3f176aa5ceea3d63d5;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-h2: immediately remove a failed connection from the idle list If a connection faces an error or a timeout, it must be removed from its idle list ASAP. We certainly don't want to risk sending new streams on it. This should be backported to 2.0 (replacing MT_LIST_DEL with LIST_DEL_LOCKED) and 1.9 (there's no lock there, the idle lists are per-thread and per-server however a LIST_DEL_INIT will be needed). --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 22bf42919b..c9b805bb3c 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3626,6 +3626,17 @@ static int h2_process(struct h2c *h2c) TRACE_DEVEL("leaving after releasing the connection", H2_EV_H2C_WAKE); return -1; } + + /* connections in error must be removed from the idle lists */ + HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]); + MT_LIST_DEL((struct mt_list *)&conn->list); + HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]); + } + else if (h2c->st0 == H2_CS_ERROR) { + /* connections in error must be removed from the idle lists */ + HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]); + MT_LIST_DEL((struct mt_list *)&conn->list); + HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]); } if (!b_data(&h2c->dbuf)) @@ -3733,6 +3744,11 @@ static struct task *h2_timeout_task(struct task *t, void *context, unsigned shor offer_buffers(NULL, tasks_run_queue); } + /* in any case this connection must not be considered idle anymore */ + HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]); + MT_LIST_DEL((struct mt_list *)&h2c->conn->list); + HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]); + /* either we can release everything now or it will be done later once * the last stream closes. */