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.
This commit is contained in:
Amaury Denoyelle 2023-10-04 15:46:06 +02:00
parent aaa326b571
commit 544e320f80

View File

@ -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 buffer htx_buf = BUF_NULL;
struct ist path; struct ist path;
char *ptr = b_head(b); char *ptr = b_head(b);
char *end = b_wrap(b);
size_t size = b_size(b);
size_t data = b_data(b); size_t data = b_data(b);
if (!data && fin) { /* hq-interop parser does not support buffer wrapping. */
struct buffer *appbuf; BUG_ON(b_data(b) != b_contig_data(b, 0));
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 is only done once full message is received. */
if (!fin)
return 0; return 0;
}
b_alloc(&htx_buf); b_alloc(&htx_buf);
htx = htx_from_buf(&htx_buf); htx = htx_from_buf(&htx_buf);
/* skip method */ /* skip method */
while (data && HTTP_IS_TOKEN(*ptr)) { while (data && HTTP_IS_TOKEN(*ptr)) {
if (++ptr == end) ptr++;
ptr -= size;
data--; data--;
} }
if (!data || !HTTP_IS_SPHT(*ptr)) { if (!data || !HTTP_IS_SPHT(*ptr)) {
fprintf(stderr, "truncated stream\n"); fprintf(stderr, "truncated stream\n");
return 0; return -1;
} }
if (++ptr == end) ptr++;
ptr -= size;
if (!--data) { if (!--data) {
fprintf(stderr, "truncated stream\n"); fprintf(stderr, "truncated stream\n");
return 0; return -1;
}
if (HTTP_IS_LWS(*ptr)) {
fprintf(stderr, "malformed stream\n");
return -1;
} }
/* extract path */ /* extract path */
BUG_ON(HTTP_IS_LWS(*ptr));
path.ptr = ptr; path.ptr = ptr;
while (data && !HTTP_IS_LWS(*ptr)) { while (data && !HTTP_IS_LWS(*ptr)) {
if (++ptr == end) ptr++;
ptr -= size;
data--; data--;
} }
if (!data) { if (!data) {
fprintf(stderr, "truncated stream\n"); fprintf(stderr, "truncated stream\n");
return 0; return -1;
} }
BUG_ON(!HTTP_IS_LWS(*ptr));
path.len = ptr - path.ptr; path.len = ptr - path.ptr;
sl = htx_add_stline(htx, HTX_BLK_REQ_SL, 0, ist("GET"), path, ist("HTTP/1.0")); 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); sl->info.req.meth = find_http_meth("GET", 3);
htx_add_endof(htx, HTX_BLK_EOH); htx_add_endof(htx, HTX_BLK_EOH);
htx->flags |= HTX_FL_EOM;
htx_to_buf(htx, &htx_buf); htx_to_buf(htx, &htx_buf);
if (!qcs_attach_sc(qcs, &htx_buf, fin)) 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); b_free(&htx_buf);
if (fin)
htx->flags |= HTX_FL_EOM;
return b_data(b); return b_data(b);
} }