mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
BUG/MEDIUM: proxy: Make sure to destroy the stream on upgrade from TCP to H2
In stream_set_backend(), if we have a TCP stream, and we want to upgrade it to H2 instead of attempting ot reuse the stream, just destroy the conn_stream, make sure we don't log anything about the stream, and pretend we failed setting the backend, so that the stream will get destroyed. New streams will then be created by the mux, as if the connection just happened. This fixes a crash when upgrading from TCP to H2, as the H2 mux totally ignored the conn_stream provided by the upgrade, as reported in github issue #196. This should be backported to 2.0.
This commit is contained in:
parent
1d4a0f8810
commit
4c18f94c11
@ -56,7 +56,7 @@
|
||||
#define SF_CURR_SESS 0x00000040 /* a connection is currently being counted on the server */
|
||||
/* unused: 0x00000080 */
|
||||
#define SF_REDISP 0x00000100 /* set if this stream was redispatched from one server to another */
|
||||
/* unused: 0x00000200 */
|
||||
#define SF_IGNORE 0x00000200 /* The stream lead to a mux upgrade, and should be ignored */
|
||||
#define SF_REDIRECTABLE 0x00000400 /* set if this stream is redirectable (GET or HEAD) */
|
||||
#define SF_HTX 0x00000800 /* set if this stream is an htx stream */
|
||||
|
||||
|
15
src/proxy.c
15
src/proxy.c
@ -1457,7 +1457,20 @@ int stream_set_backend(struct stream *s, struct proxy *be)
|
||||
&s->si[0].wait_event);
|
||||
if (conn_upgrade_mux_fe(conn, cs, &s->req.buf, ist(""), PROTO_MODE_HTTP) == -1)
|
||||
return 0;
|
||||
s->flags |= SF_HTX;
|
||||
if (!strcmp(conn->mux->name, "H2")) {
|
||||
/* For HTTP/2, destroy the conn_stream,
|
||||
* disable logging, and pretend that we
|
||||
* failed, to that the stream is
|
||||
* silently destroyed. The new mux
|
||||
* will create new streams.
|
||||
*/
|
||||
cs_destroy(cs);
|
||||
si_detach_endpoint(&s->si[0]);
|
||||
s->logs.logwait = 0;
|
||||
s->logs.level = 0;
|
||||
s->flags |= SF_IGNORE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2611,7 +2611,7 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
|
||||
}
|
||||
|
||||
if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO))) {
|
||||
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED))
|
||||
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
|
||||
stream_process_counters(s);
|
||||
|
||||
si_update_both(si_f, si_b);
|
||||
@ -2679,7 +2679,8 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
|
||||
}
|
||||
|
||||
s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
|
||||
stream_process_counters(s);
|
||||
if (!(s->flags & SF_IGNORE))
|
||||
stream_process_counters(s);
|
||||
|
||||
if (s->txn && s->txn->status) {
|
||||
int n;
|
||||
|
Loading…
Reference in New Issue
Block a user