From: Olivier Houchard Date: Sat, 15 Dec 2018 15:05:40 +0000 (+0100) Subject: MEDIUM: mux: Destroy the stream before trying to add the conn to the idle list. X-Git-Tag: v1.9-dev11~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a7869022999c8b6bedd85cdbc846f8be811c8a2;p=thirdparty%2Fhaproxy.git MEDIUM: mux: Destroy the stream before trying to add the conn to the idle list. In the mux_h1 and mux_h2, move the test to see if we should add the connection in the idle list until after we destroyed the h1s/h2s, that way later we'll be able to check if the connection has no stream at all, and if it should be added to the server idling list. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 09c29c2f02..0a8f874ca0 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1917,6 +1917,8 @@ static void h1_detach(struct conn_stream *cs) { struct h1s *h1s = cs->ctx; struct h1c *h1c; + int has_keepalive; + int is_not_first; cs->ctx = NULL; if (!h1s) @@ -1925,7 +1927,11 @@ static void h1_detach(struct conn_stream *cs) h1c = h1s->h1c; h1s->cs = NULL; - if (conn_is_back(h1c->conn) && (h1s->flags & H1S_F_WANT_KAL) && + has_keepalive = h1s->flags & H1S_F_WANT_KAL; + is_not_first = h1s->flags & H1S_F_NOT_FIRST; + h1s_destroy(h1s); + + if (conn_is_back(h1c->conn) && has_keepalive && !(h1c->conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) { struct stream_interface *si = cs->data; struct stream *s = si_strm(si); @@ -1945,7 +1951,7 @@ static void h1_detach(struct conn_stream *cs) if (srv) { if (h1c->conn->flags & CO_FL_PRIVATE) LIST_ADD(&srv->priv_conns[tid], &h1c->conn->list); - else if (h1s->flags & H1S_F_NOT_FIRST) + else if (is_not_first) LIST_ADD(&srv->safe_conns[tid], &h1c->conn->list); else LIST_ADD(&srv->idle_conns[tid], &h1c->conn->list); @@ -1953,8 +1959,6 @@ static void h1_detach(struct conn_stream *cs) } } - h1s_destroy(h1s); - /* We don't want to close right now unless the connection is in error */ if ((h1c->flags & (H1C_F_CS_ERROR|H1C_F_CS_SHUTW)) || (h1c->conn->flags & CO_FL_ERROR) || !h1c->conn->owner) diff --git a/src/mux_h2.c b/src/mux_h2.c index a0357be4b7..c28b84484a 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -2809,34 +2809,6 @@ static void h2_detach(struct conn_stream *cs) return; h2c = h2s->h2c; - if (h2c->proxy->options2 & PR_O2_USE_HTX) { - struct stream_interface *si; - struct stream *s; - - si = cs->data; - s = si_strm(si); - if (!(h2c->conn->flags & - (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) { - if (!h2c->conn->owner) { - h2c->conn->owner = s->sess; - session_add_conn(s->sess, h2c->conn, s->target); - } - /* Never ever allow to reuse a connection from a non-reuse backend */ - if ((h2c->proxy->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR) - h2c->conn->flags |= CO_FL_PRIVATE; - if (LIST_ISEMPTY(&h2c->conn->list)) { - struct server *srv = objt_server(h2c->conn->target); - - if (srv) { - if (h2c->conn->flags & CO_FL_PRIVATE) - LIST_ADD(&srv->priv_conns[tid], &h2c->conn->list); - else - LIST_ADD(&srv->idle_conns[tid], &h2c->conn->list); - } - - } - } - } h2s->cs = NULL; h2c->nb_cs--; if (h2c->flags & H2_CF_DEM_TOOMANY && @@ -2866,6 +2838,36 @@ static void h2_detach(struct conn_stream *cs) h2s_destroy(h2s); + if (h2c->flags & H2_CF_IS_BACK && + (h2c->proxy->options2 & PR_O2_USE_HTX)) { + struct stream_interface *si; + struct stream *s; + + si = cs->data; + s = si_strm(si); + if (!(h2c->conn->flags & + (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) { + if (!h2c->conn->owner) { + h2c->conn->owner = s->sess; + session_add_conn(s->sess, h2c->conn, s->target); + } + /* Never ever allow to reuse a connection from a non-reuse backend */ + if ((h2c->proxy->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR) + h2c->conn->flags |= CO_FL_PRIVATE; + if (LIST_ISEMPTY(&h2c->conn->list)) { + struct server *srv = objt_server(h2c->conn->target); + + if (srv) { + if (h2c->conn->flags & CO_FL_PRIVATE) + LIST_ADD(&srv->priv_conns[tid], &h2c->conn->list); + else + LIST_ADD(&srv->idle_conns[tid], &h2c->conn->list); + } + + } + } + } + /* We don't want to close right now unless we're removing the * last stream, and either the connection is in error, or it * reached the ID already specified in a GOAWAY frame received