BUG/MEDIUM: h2: check that the connection is still valid at the end of init()
Since commit 7505f94f9 ("MEDIUM: h2: Don't use a wake() method anymore."),
the H2 mux's init() calls h2_process(). But this last one may detect an
early error and call h2_release(), destroying the connection, and return
-1. At this point we're screwed because the caller will still dereference
the connection for various things ranging from the configuration of the
proxy protocol header to the retries. We could simply return -1 here upon
failure but that's not enough since the stream layer really needs to keep
its connection structure allocated (to clean it up in session_kill_embryonic
or for example because it holds the destination address to reconnect to
when the connection goes to the backend). Thus the correct solution here is
to only schedule a wakeup of the I/O callback so that the init succeeds,
and that the connection is only handled later.
No backport is needed, this is 1.9-specific.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index b02f4c3..62eb909 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -381,6 +381,7 @@
h2c->wait_list.task->process = h2_io_cb;
h2c->wait_list.task->context = h2c;
h2c->wait_list.wait_reason = 0;
+ LIST_INIT(&h2c->wait_list.list);
h2c->ddht = hpack_dht_alloc(h2_settings_header_table_size);
if (!h2c->ddht)
@@ -414,12 +415,10 @@
if (t)
task_queue(t);
- conn_xprt_want_recv(conn);
- LIST_INIT(&h2c->wait_list.list);
- /* Try to read, if nothing is available yet we'll just subscribe */
- if (h2_recv(h2c))
- h2_process(h2c);
+ /* prepare to read something */
+ conn_xprt_want_recv(conn);
+ tasklet_wakeup(h2c->wait_list.task);
return 0;
fail:
if (t)