From: Amaury Denoyelle Date: Wed, 23 Feb 2022 09:54:42 +0000 (+0100) Subject: MINOR: quic: adjust buffer handling for STREAM transmission X-Git-Tag: v2.6-dev2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=642ab063132c414c41cc8061d87a653073720437;p=thirdparty%2Fhaproxy.git MINOR: quic: adjust buffer handling for STREAM transmission Simplify the data manipulation of STREAM frames on TX. Only stream data and len field are used to generate a valid STREAM frames from the buffer. Do not use the offset field, which required that a single buffer instance should be shared for every frames on a single stream. --- diff --git a/include/haproxy/quic_frame-t.h b/include/haproxy/quic_frame-t.h index 1d2d354210..057ad1563a 100644 --- a/include/haproxy/quic_frame-t.h +++ b/include/haproxy/quic_frame-t.h @@ -148,10 +148,23 @@ struct quic_new_token { struct quic_stream { uint64_t id; struct qcs *qcs; + + /* used only on TX when constructing frames. + * Data cleared when processing ACK related to this STREAM frame. + * + * A same buffer may be shared between several STREAM frames. The + * field of each quic_stream serves to differentiate the payload + * of each of these. + */ struct buffer *buf; + struct eb64_node offset; uint64_t len; int fin; + + /* for TX pointer into field. + * for RX pointer into the packet buffer. + */ const unsigned char *data; }; diff --git a/src/mux_quic.c b/src/mux_quic.c index e286d6a9aa..4be7d83d86 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -271,6 +271,7 @@ static int qcs_push_frame(struct qcs *qcs, struct buffer *payload, int fin, uint struct buffer *buf = &qcs->tx.xprt_buf; struct quic_enc_level *qel = &qcs->qcc->conn->qc->els[QUIC_TLS_ENC_LEVEL_APP]; int total = 0, to_xfer; + unsigned char *btail; fprintf(stderr, "%s\n", __func__); @@ -283,6 +284,8 @@ static int qcs_push_frame(struct qcs *qcs, struct buffer *payload, int fin, uint if (!frm) goto err; + /* store buffer end before transfering data for frm.stream.data */ + btail = (unsigned char *)b_tail(buf); total = b_force_xfer(buf, payload, to_xfer); /* FIN is positioned only when the buffer has been totally emptied. */ fin = fin && !b_data(payload); @@ -295,6 +298,7 @@ static int qcs_push_frame(struct qcs *qcs, struct buffer *payload, int fin, uint } frm->stream.qcs = (struct qcs *)qcs; frm->stream.buf = buf; + frm->stream.data = btail; frm->stream.id = qcs->by_id.key; if (total) { frm->type |= QUIC_STREAM_FRAME_TYPE_LEN_BIT; diff --git a/src/quic_frame.c b/src/quic_frame.c index 0adce4c1f7..c5adddc1bb 100644 --- a/src/quic_frame.c +++ b/src/quic_frame.c @@ -501,8 +501,7 @@ static int quic_build_stream_frame(unsigned char **buf, const unsigned char *end struct quic_frame *frm, struct quic_conn *conn) { struct quic_stream *stream = &frm->stream; - size_t offset, block1, block2; - struct buffer b; + const unsigned char *wrap; if (!quic_enc_int(buf, end, stream->id) || ((frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) && !quic_enc_int(buf, end, stream->offset.key)) || @@ -510,19 +509,19 @@ static int quic_build_stream_frame(unsigned char **buf, const unsigned char *end (!quic_enc_int(buf, end, stream->len) || end - *buf < stream->len))) return 0; - /* Buffer copy */ - b = *stream->buf; - offset = (frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) ? - stream->offset.key & (b_size(stream->buf) - 1): 0; - block1 = b_wrap(&b) - (b_orig(&b) + offset); - if (block1 > stream->len) - block1 = stream->len; - block2 = stream->len - block1; - memcpy(*buf, b_orig(&b) + offset, block1); - *buf += block1; - if (block2) { - memcpy(*buf, b_orig(&b), block2); - *buf += block2; + wrap = (const unsigned char *)b_wrap(stream->buf); + if (stream->data + stream->len > wrap) { + size_t to_copy = wrap - stream->data; + memcpy(*buf, stream->data, to_copy); + *buf += to_copy; + + to_copy = stream->len - to_copy; + memcpy(*buf, b_orig(stream->buf), to_copy); + *buf += to_copy; + } + else { + memcpy(*buf, stream->data, stream->len); + *buf += stream->len; } return 1; diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 52f843dd22..a6eda370b5 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -4775,6 +4775,7 @@ static inline int qc_build_frms(struct list *l, } else { struct quic_frame *new_cf; + struct buffer cf_buf; new_cf = pool_zalloc(pool_head_quic_frame); if (!new_cf) { @@ -4796,9 +4797,12 @@ static inline int qc_build_frms(struct list *l, LIST_APPEND(l, &new_cf->list); cf->type |= QUIC_STREAM_FRAME_TYPE_OFF_BIT; /* Consume bytes of the current frame. */ + cf_buf = b_make(b_orig(cf->stream.buf), + b_size(cf->stream.buf), + (char *)cf->stream.data - b_orig(cf->stream.buf), 0); cf->stream.len -= dlen; cf->stream.offset.key += dlen; - cf->stream.data += dlen; + cf->stream.data = (unsigned char *)b_peek(&cf_buf, dlen); } break;