From 198d35f9c69ec3e0cba4a30f9ebb736b26fcf95e Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Fri, 1 Apr 2022 17:56:58 +0200 Subject: [PATCH] MINOR: mux-quic: define is_active app-ops Add a new app layer operation is_active. This can be used by the MUX to check if the connection can be considered as active or not. This is used inside qcc_is_dead as a first check. For example on HTTP/3, if there is at least one bidir client stream opened the connection is active. This explicitly ignore the uni streams used for control and qpack as they can never be closed during the connection lifetime. --- include/haproxy/mux_quic-t.h | 1 + src/h3.c | 13 +++++++++++++ src/hq_interop.c | 9 +++++++++ src/mux_quic.c | 6 +++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index edc693026..2a1cd862d 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -117,6 +117,7 @@ struct qcc_app_ops { int (*decode_qcs)(struct qcs *qcs, int fin, void *ctx); size_t (*snd_buf)(struct conn_stream *cs, struct buffer *buf, size_t count, int flags); int (*finalize)(void *ctx); + int (*is_active)(const struct qcc *qcc, void *ctx); void (*release)(void *ctx); }; diff --git a/src/h3.c b/src/h3.c index 3cce59563..e39c54135 100644 --- a/src/h3.c +++ b/src/h3.c @@ -897,6 +897,18 @@ static void h3_release(void *ctx) pool_free(pool_head_h3, h3); } +/* Check if the H3 connection can still be considered as active. + * + * Return true if active else false. + */ +static int h3_is_active(const struct qcc *qcc, void *ctx) +{ + if (qcc->strms[QCS_CLT_BIDI].nb_streams) + return 1; + + return 0; +} + /* HTTP/3 application layer operations */ const struct qcc_app_ops h3_ops = { .init = h3_init, @@ -904,5 +916,6 @@ const struct qcc_app_ops h3_ops = { .decode_qcs = h3_decode_qcs, .snd_buf = h3_snd_buf, .finalize = h3_finalize, + .is_active = h3_is_active, .release = h3_release, }; diff --git a/src/hq_interop.c b/src/hq_interop.c index 79283736c..71419d1ea 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -166,7 +166,16 @@ static size_t hq_interop_snd_buf(struct conn_stream *cs, struct buffer *buf, return total; } +static int hq_is_active(const struct qcc *qcc, void *ctx) +{ + if (!eb_is_empty(&qcc->streams_by_id)) + return 1; + + return 0; +} + const struct qcc_app_ops hq_interop_ops = { .decode_qcs = hq_interop_decode_qcs, .snd_buf = hq_interop_snd_buf, + .is_active = hq_is_active, }; diff --git a/src/mux_quic.c b/src/mux_quic.c index ad1a69367..34e9291ae 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -462,7 +462,11 @@ static void qcs_destroy(struct qcs *qcs) static inline int qcc_is_dead(const struct qcc *qcc) { - if (!qcc->strms[QCS_CLT_BIDI].nb_streams && !qcc->task) + if (qcc->app_ops && qcc->app_ops->is_active && + qcc->app_ops->is_active(qcc, qcc->ctx)) + return 0; + + if (!qcc->task) return 1; return 0;