mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 20:46:11 +02:00
BUG/MINOR: quic: Stop removing ACK ranges when building packets
Since this commit:
BUG/MINOR: quic: Possible wrapped values used as ACK tree purging limit.
There are more chances that ack ranges may be removed from their trees when
building a packet. It is preferable to impose a limit to these trees. This
will be the subject of the a next commit to come.
For now on, it is sufficient to stop deleting ack range from their trees.
Remove quic_ack_frm_reduce_sz() and quic_rm_last_ack_ranges() which were
there to do that.
Make qc_frm_len() support ACK frames and calls it to ensure an ACK frame
may be added to a packet before building it.
Must be backported to 2.6 and 2.7.
This commit is contained in:
parent
8cd620b46f
commit
4b2627beae
@ -48,6 +48,27 @@ static inline size_t qc_frm_len(struct quic_frame *frm)
|
||||
size_t len = 0;
|
||||
|
||||
switch (frm->type) {
|
||||
case QUIC_FT_ACK: {
|
||||
struct quic_tx_ack *tx_ack = &frm->tx_ack;
|
||||
struct eb64_node *ar, *prev_ar;
|
||||
struct quic_arng_node *ar_node, *prev_ar_node;
|
||||
|
||||
ar = eb64_last(&tx_ack->arngs->root);
|
||||
ar_node = eb64_entry(ar, struct quic_arng_node, first);
|
||||
len += 1 + quic_int_getsize(ar_node->last);
|
||||
len += quic_int_getsize(tx_ack->ack_delay);
|
||||
len += quic_int_getsize(tx_ack->arngs->sz - 1);
|
||||
len += quic_int_getsize(ar_node->last - ar_node->first.key);
|
||||
|
||||
while ((prev_ar = eb64_prev(ar))) {
|
||||
prev_ar_node = eb64_entry(prev_ar, struct quic_arng_node, first);
|
||||
len += quic_int_getsize(ar_node->first.key - prev_ar_node->last - 2);
|
||||
len += quic_int_getsize(prev_ar_node->last - prev_ar_node->first.key);
|
||||
ar = prev_ar;
|
||||
ar_node = eb64_entry(ar, struct quic_arng_node, first);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUIC_FT_RESET_STREAM: {
|
||||
struct quic_reset_stream *f = &frm->reset_stream;
|
||||
len += 1 + quic_int_getsize(f->id) +
|
||||
|
||||
@ -4206,46 +4206,6 @@ static inline size_t sack_gap(struct quic_arng_node *p,
|
||||
return p->first.key - q->last - 2;
|
||||
}
|
||||
|
||||
|
||||
/* Remove the last elements of <ack_ranges> list of ack range updating its
|
||||
* encoded size until it goes below <limit>.
|
||||
* Returns 1 if succeeded, 0 if not (no more element to remove).
|
||||
*/
|
||||
static int quic_rm_last_ack_ranges(struct quic_conn *qc,
|
||||
struct quic_arngs *arngs, size_t limit)
|
||||
{
|
||||
int ret = 0;
|
||||
struct eb64_node *last, *prev;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
|
||||
|
||||
last = eb64_last(&arngs->root);
|
||||
while (last && arngs->enc_sz > limit) {
|
||||
struct quic_arng_node *last_node, *prev_node;
|
||||
|
||||
prev = eb64_prev(last);
|
||||
if (!prev) {
|
||||
TRACE_DEVEL("<last> not found", QUIC_EV_CONN_TXPKT, qc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
last_node = eb64_entry(last, struct quic_arng_node, first);
|
||||
prev_node = eb64_entry(prev, struct quic_arng_node, first);
|
||||
arngs->enc_sz -= quic_int_getsize(last_node->last - last_node->first.key);
|
||||
arngs->enc_sz -= quic_int_getsize(sack_gap(prev_node, last_node));
|
||||
arngs->enc_sz -= quic_decint_size_diff(arngs->sz);
|
||||
--arngs->sz;
|
||||
eb64_delete(last);
|
||||
pool_free(pool_head_quic_arng, last);
|
||||
last = prev;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
out:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the encoded size of <arngs> QUIC ack ranges. */
|
||||
static void quic_arngs_set_enc_sz(struct quic_conn *qc, struct quic_arngs *arngs)
|
||||
{
|
||||
@ -7407,33 +7367,6 @@ static int quic_apply_header_protection(struct quic_conn *qc, unsigned char *buf
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reduce the encoded size of <ack_frm> ACK frame removing the last
|
||||
* ACK ranges if needed to a value below <limit> in bytes.
|
||||
* Return 1 if succeeded, 0 if not.
|
||||
*/
|
||||
static int quic_ack_frm_reduce_sz(struct quic_conn *qc,
|
||||
struct quic_frame *ack_frm, size_t limit)
|
||||
{
|
||||
size_t room, ack_delay_sz;
|
||||
int ret = 0;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
|
||||
|
||||
ack_delay_sz = quic_int_getsize(ack_frm->tx_ack.ack_delay);
|
||||
if (limit <= ack_delay_sz - 1)
|
||||
goto leave;
|
||||
|
||||
/* A frame is made of 1 byte for the frame type. */
|
||||
room = limit - ack_delay_sz - 1;
|
||||
if (!quic_rm_last_ack_ranges(qc, ack_frm->tx_ack.arngs, room))
|
||||
goto leave;
|
||||
|
||||
ret = 1 + ack_delay_sz + ack_frm->tx_ack.arngs->enc_sz;
|
||||
leave:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Prepare into <outlist> as most as possible ack-eliciting frame from their
|
||||
* <inlist> prebuilt frames for <qel> encryption level to be encoded in a buffer
|
||||
* with <room> as available room, and <*len> the packet Length field initialized
|
||||
@ -7853,8 +7786,8 @@ static int qc_do_build_pkt(unsigned char *pos, const unsigned char *end,
|
||||
if (end - pos <= 1 + *pn_len)
|
||||
goto no_room;
|
||||
|
||||
ack_frm_len = quic_ack_frm_reduce_sz(qc, &ack_frm, end - 1 - *pn_len - pos);
|
||||
if (!ack_frm_len)
|
||||
ack_frm_len = qc_frm_len(&ack_frm);
|
||||
if (ack_frm_len > end - 1 - *pn_len - pos)
|
||||
goto no_room;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user