From 314578a54f87b217f517715cdb00e4c77c5b721d Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 27 Apr 2022 14:52:52 +0200 Subject: [PATCH] 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. --- src/h3.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/h3.c b/src/h3.c index e516a470c..459e360bf 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;