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.
This commit is contained in:
Amaury Denoyelle 2022-02-23 10:54:42 +01:00
parent 897c861aea
commit 642ab06313
4 changed files with 36 additions and 16 deletions

View file

@ -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
* <data> 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 <buf> field.
* for RX pointer into the packet buffer.
*/
const unsigned char *data;
};

View file

@ -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;

View file

@ -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;

View file

@ -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 <dlen> 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;