From: Amaury Denoyelle Date: Wed, 4 Oct 2023 13:46:06 +0000 (+0200) Subject: BUG/MINOR: hq-interop: simplify parser requirement X-Git-Tag: v2.9-dev7~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=544e320f8093f74403a7826770304c7f5705db9a;p=thirdparty%2Fhaproxy.git BUG/MINOR: hq-interop: simplify parser requirement hq-interop should be limited for QUIC testing. As such, its code should be kept plain simple and not implement too many things. This patch fixes issues which may cause rare QUIC interop failures : - remove some unneeded BUG_ON() as parser should not be too strict - remove support of partial message parsing - ensure buffer data does not wrap as it was not properly handled. In any case, this should never happen as only a single message will be stored for each qcs buffer. This should be backported up to 2.6. --- diff --git a/src/hq_interop.c b/src/hq_interop.c index a372d226ef..8126a93905 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -16,66 +16,52 @@ static ssize_t hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) struct buffer htx_buf = BUF_NULL; struct ist path; char *ptr = b_head(b); - char *end = b_wrap(b); - size_t size = b_size(b); size_t data = b_data(b); - if (!data && fin) { - struct buffer *appbuf; - struct htx *htx; - - /* FIN is notified with an empty STREAM frame. */ - BUG_ON(!qcs->sd); /* sd must already be attached here */ - - if (!(appbuf = qcs_get_buf(qcs, &qcs->rx.app_buf))) - return -1; - - htx = htx_from_buf(appbuf); - if (!htx_set_eom(htx)) - return -1; - htx_to_buf(htx, appbuf); + /* hq-interop parser does not support buffer wrapping. */ + BUG_ON(b_data(b) != b_contig_data(b, 0)); + /* hq-interop parser is only done once full message is received. */ + if (!fin) return 0; - } b_alloc(&htx_buf); htx = htx_from_buf(&htx_buf); /* skip method */ while (data && HTTP_IS_TOKEN(*ptr)) { - if (++ptr == end) - ptr -= size; + ptr++; data--; } if (!data || !HTTP_IS_SPHT(*ptr)) { fprintf(stderr, "truncated stream\n"); - return 0; + return -1; } - if (++ptr == end) - ptr -= size; - + ptr++; if (!--data) { fprintf(stderr, "truncated stream\n"); - return 0; + return -1; + } + + if (HTTP_IS_LWS(*ptr)) { + fprintf(stderr, "malformed stream\n"); + return -1; } /* extract path */ - BUG_ON(HTTP_IS_LWS(*ptr)); path.ptr = ptr; while (data && !HTTP_IS_LWS(*ptr)) { - if (++ptr == end) - ptr -= size; + ptr++; data--; } if (!data) { fprintf(stderr, "truncated stream\n"); - return 0; + return -1; } - BUG_ON(!HTTP_IS_LWS(*ptr)); path.len = ptr - path.ptr; sl = htx_add_stline(htx, HTX_BLK_REQ_SL, 0, ist("GET"), path, ist("HTTP/1.0")); @@ -86,6 +72,7 @@ static ssize_t hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) sl->info.req.meth = find_http_meth("GET", 3); htx_add_endof(htx, HTX_BLK_EOH); + htx->flags |= HTX_FL_EOM; htx_to_buf(htx, &htx_buf); if (!qcs_attach_sc(qcs, &htx_buf, fin)) @@ -93,9 +80,6 @@ static ssize_t hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin) b_free(&htx_buf); - if (fin) - htx->flags |= HTX_FL_EOM; - return b_data(b); }