From: Amaury Denoyelle Date: Wed, 27 Apr 2022 12:52:52 +0000 (+0200) Subject: MINOR: h3: change frame demuxing API X-Git-Tag: v2.6-dev8~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=314578a54f87b217f517715cdb00e4c77c5b721d;p=thirdparty%2Fhaproxy.git MINOR: h3: change frame demuxing API Edit the functions used for HEADERS and DATA parsing. They now return the number of bytes handled. This change will help to demux H3 frames bigger than the buffer. --- diff --git a/src/h3.c b/src/h3.c index e516a470c6..459e360bff 100644 --- a/src/h3.c +++ b/src/h3.c @@ -95,7 +95,7 @@ static inline size_t h3_decode_frm_header(uint64_t *ftype, uint64_t *flen, * in a local HTX buffer and transfer to the conn-stream layer. must be * set if this is the last data to transfer from this stream. * - * Returns 0 on success else non-zero. + * Returns the number of bytes handled or a negative error code. */ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, char fin) @@ -115,7 +115,7 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, /* TODO support buffer wrapping */ BUG_ON(b_contig_data(buf, 0) != b_data(buf)); if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0) - return 1; + return -1; qc_get_buf(qcs, &htx_buf); BUG_ON(!b_size(&htx_buf)); @@ -147,7 +147,7 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, meth, path, ist("HTTP/3.0")); if (!sl) - return 1; + return -1; if (fin) sl->flags |= HTX_SL_F_BODYLESS; @@ -178,7 +178,7 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, cs = qc_attach_cs(qcs, &htx_buf); if (!cs) - return 1; + return -1; /* buffer is transferred to conn_stream and set to NULL * except on stream creation error. @@ -186,14 +186,14 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, b_free(&htx_buf); offer_buffers(NULL, 1); - return 0; + return len; } /* Copy from buffer a H3 DATA frame of length in QUIC stream * HTX buffer. must be set if this is the last data to transfer from this * stream. * - * Returns 0 on success else non-zero + * Returns the number of bytes handled or a negative error code. */ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, char fin) @@ -229,7 +229,7 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, htx->flags |= HTX_FL_EOM; htx_to_buf(htx, appbuf); - return 0; + return htx_sent; } /* Decode remotely initiated bidi-stream. must be set to indicate @@ -239,7 +239,7 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len, static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx) { struct buffer *rxbuf = &qcs->rx.buf; - int ret; + ssize_t ret; h3_debug_printf(stderr, "%s: STREAM ID: %lu\n", __func__, qcs->id); if (!b_data(rxbuf)) @@ -272,23 +272,29 @@ static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx) case H3_FT_DATA: ret = h3_data_to_htx(qcs, rxbuf, flen, last_stream_frame); /* TODO handle error reporting. Stream closure required. */ - if (ret) { ABORT_NOW(); } + if (ret < 0) { ABORT_NOW(); } break; case H3_FT_HEADERS: ret = h3_headers_to_htx(qcs, rxbuf, flen, last_stream_frame); /* TODO handle error reporting. Stream closure required. */ - if (ret) { ABORT_NOW(); } + if (ret < 0) { ABORT_NOW(); } break; case H3_FT_PUSH_PROMISE: /* Not supported */ + ret = MIN(b_data(rxbuf), flen); break; default: /* draft-ietf-quic-http34 9. Extensions to HTTP/3 * unknown frame types MUST be ignored */ h3_debug_printf(stderr, "ignore unknown frame type 0x%lx\n", ftype); + ret = MIN(b_data(rxbuf), flen); } - b_del(rxbuf, flen); + + if (!ret) + break; + + b_del(rxbuf, ret); } return 0;