BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early.
In h1_release(), when we want to upgrade the mux to h2, make sure we set
h1c->ibuf to BUF_NULL before calling conn_upgrade_mux_fe().
If the upgrade is successful, the buffer will be provided to the new mux,
h1_release() will be called recursively, it will so try to free h1c->ibuf,
and freeing the buffer we just provided to the new mux would be unfortunate.
diff --git a/src/mux_h1.c b/src/mux_h1.c
index c9c8f84..84a4560 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -464,16 +464,18 @@
conn = h1c->conn;
if (conn && h1c->flags & H1C_F_UPG_H2C) {
+ struct buffer tmpbuf = h1c->ibuf;
h1c->flags &= ~H1C_F_UPG_H2C;
- if (conn_upgrade_mux_fe(conn, NULL, &h1c->ibuf, ist("h2"), PROTO_MODE_HTX) != -1) {
+ h1c->ibuf = BUF_NULL;
+ if (conn_upgrade_mux_fe(conn, NULL, &tmpbuf, ist("h2"), PROTO_MODE_HTX) != -1) {
/* connection successfully upgraded to H2, this
* mux was already released */
return;
}
+ h1c->ibuf = tmpbuf;
sess_log(conn->owner); /* Log if the upgrade failed */
}
-
if (!LIST_ISEMPTY(&h1c->buf_wait.list)) {
HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
LIST_DEL(&h1c->buf_wait.list);