mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-11 03:31:36 +00:00
MINOR: h3: extend function for QUIC varint encoding
Slighty adjust b_quic_enc_int(). This function is used to encode an integer as a QUIC varint in a struct buffer. A new parameter is added to the function API to specify the width of the encoded integer. By default, 0 should be use to ensure that the minimum space is used. Other valid values are 1, 2, 4 or 8. An error is reported if the width is not large enough. This new parameter will be useful when buffer space is reserved prior to encode an unknown integer value. The maximum size of 8 bytes will be reserved and some data can be put after. When finally encoding the integer, the width can be requested to be 8 bytes. With this new parameter, a small refactoring of the function has been conducted to remove some useless internal variables. This should be backported up to 2.7. It will be mostly useful to implement H3 trailers encoding.
This commit is contained in:
parent
8ad2669175
commit
7d78eff889
@ -198,39 +198,44 @@ static inline int quic_enc_int(unsigned char **buf, const unsigned char *end, ui
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Encode a QUIC variable-length integer <val> into <b> buffer.
|
||||
* Returns 1 if succeeded (there was enough room in buf), 0 if not.
|
||||
/* Encode a QUIC variable-length integer <val> into <b> buffer. <width> can be
|
||||
* set to specify the desired output width. By default use 0 for the minimal
|
||||
* integer size. Other valid values are 1, 2, 4 or 8.
|
||||
*
|
||||
* Returns 1 on success else 0.
|
||||
*/
|
||||
static inline int b_quic_enc_int(struct buffer *b, uint64_t val)
|
||||
static inline int b_quic_enc_int(struct buffer *b, uint64_t val, int width)
|
||||
{
|
||||
unsigned int shift;
|
||||
unsigned char size_bits, *tail, *pos, *wrap;
|
||||
size_t save_len, len;
|
||||
size_t data = b_data(b);
|
||||
size_t size = b_size(b);
|
||||
char *pos;
|
||||
int save_width, len;
|
||||
|
||||
if (data == size)
|
||||
return 0;
|
||||
/* width can only by 0, 1, 2, 4 or 8 */
|
||||
BUG_ON(width && (width > 8 || atleast2(width)));
|
||||
|
||||
save_len = len = quic_int_getsize(val);
|
||||
len = quic_int_getsize(val);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
shift = (len - 1) * 8;
|
||||
/* set the bits of byte#0 which gives the length of the encoded integer */
|
||||
size_bits = quic_log2(len) << QUIC_VARINT_BYTE_0_SHIFT;
|
||||
pos = tail = (unsigned char *)b_tail(b);
|
||||
wrap = (unsigned char *)b_wrap(b);
|
||||
while (len--) {
|
||||
*pos++ = val >> shift;
|
||||
shift -= 8;
|
||||
if (pos == wrap)
|
||||
pos -= size;
|
||||
if (++data == size && len)
|
||||
return 0;
|
||||
/* Check that buffer room is sufficient and width big enough if set. */
|
||||
if (b_room(b) < len || (width && width < len))
|
||||
return 0;
|
||||
|
||||
if (!width)
|
||||
width = len;
|
||||
save_width = width;
|
||||
|
||||
pos = b_tail(b);
|
||||
while (width--) {
|
||||
/* Encode the shifted integer or 0 if width bigger than integer length. */
|
||||
*pos++ = width >= len ? 0 : val >> (width * 8);
|
||||
|
||||
if (pos == b_wrap(b))
|
||||
pos = b_orig(b);
|
||||
}
|
||||
*tail |= size_bits;
|
||||
b_add(b, save_len);
|
||||
|
||||
/* set the bits of byte#0 which gives the length of the encoded integer */
|
||||
*b_tail(b) |= quic_log2(save_width) << QUIC_VARINT_BYTE_0_SHIFT;
|
||||
b_add(b, save_width);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
28
src/h3.c
28
src/h3.c
@ -1042,17 +1042,17 @@ static int h3_control_send(struct qcs *qcs, void *ctx)
|
||||
quic_int_getsize(h3_settings_max_field_section_size);
|
||||
}
|
||||
|
||||
b_quic_enc_int(&pos, H3_UNI_S_T_CTRL);
|
||||
b_quic_enc_int(&pos, H3_UNI_S_T_CTRL, 0);
|
||||
/* Build a SETTINGS frame */
|
||||
b_quic_enc_int(&pos, H3_FT_SETTINGS);
|
||||
b_quic_enc_int(&pos, frm_len);
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY);
|
||||
b_quic_enc_int(&pos, h3_settings_qpack_max_table_capacity);
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_QPACK_BLOCKED_STREAMS);
|
||||
b_quic_enc_int(&pos, h3_settings_qpack_blocked_streams);
|
||||
b_quic_enc_int(&pos, H3_FT_SETTINGS, 0);
|
||||
b_quic_enc_int(&pos, frm_len, 0);
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY, 0);
|
||||
b_quic_enc_int(&pos, h3_settings_qpack_max_table_capacity, 0);
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_QPACK_BLOCKED_STREAMS, 0);
|
||||
b_quic_enc_int(&pos, h3_settings_qpack_blocked_streams, 0);
|
||||
if (h3_settings_max_field_section_size) {
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_MAX_FIELD_SECTION_SIZE);
|
||||
b_quic_enc_int(&pos, h3_settings_max_field_section_size);
|
||||
b_quic_enc_int(&pos, H3_SETTINGS_MAX_FIELD_SECTION_SIZE, 0);
|
||||
b_quic_enc_int(&pos, h3_settings_max_field_section_size, 0);
|
||||
}
|
||||
|
||||
res = mux_get_buf(qcs);
|
||||
@ -1177,7 +1177,7 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
frame_length_size = quic_int_getsize(b_data(&headers_buf));
|
||||
res->head += 4 - frame_length_size;
|
||||
b_putchr(res, 0x01); /* h3 HEADERS frame type */
|
||||
if (!b_quic_enc_int(res, b_data(&headers_buf)))
|
||||
if (!b_quic_enc_int(res, b_data(&headers_buf), 0))
|
||||
ABORT_NOW();
|
||||
b_add(res, b_data(&headers_buf));
|
||||
|
||||
@ -1252,7 +1252,7 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx, size_t count)
|
||||
BUG_ON(fsize <= 0);
|
||||
|
||||
b_putchr(&outbuf, 0x00); /* h3 frame type = DATA */
|
||||
b_quic_enc_int(&outbuf, fsize); /* h3 frame length */
|
||||
b_quic_enc_int(&outbuf, fsize, 0); /* h3 frame length */
|
||||
|
||||
b_putblk(&outbuf, htx_get_blk_ptr(htx, blk), fsize);
|
||||
total += fsize;
|
||||
@ -1407,9 +1407,9 @@ static int h3_send_goaway(struct h3c *h3c)
|
||||
|
||||
pos = b_make((char *)data, sizeof(data), 0, 0);
|
||||
|
||||
b_quic_enc_int(&pos, H3_FT_GOAWAY);
|
||||
b_quic_enc_int(&pos, frm_len);
|
||||
b_quic_enc_int(&pos, h3c->id_goaway);
|
||||
b_quic_enc_int(&pos, H3_FT_GOAWAY, 0);
|
||||
b_quic_enc_int(&pos, frm_len, 0);
|
||||
b_quic_enc_int(&pos, h3c->id_goaway, 0);
|
||||
|
||||
res = mux_get_buf(qcs);
|
||||
if (!res || b_room(res) < b_data(&pos)) {
|
||||
|
Loading…
Reference in New Issue
Block a user