mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-21 03:00:35 +00:00
BUG/MINOR: quic: Frames leak during retransmissions
The frame which are retransmitted by qc_dgrams_retransmit() are duplicated from sent but not acknowledged packets and added to local frames lists. Some may not have been sent. If not replaced somewhere (linked to the connection) they are lost for ever (leak). We splice the list remaining contents to the packets number space frame list to avoid such a situation. Must be backported to 2.6.
This commit is contained in:
parent
a777ee36f6
commit
a1075209c7
@ -4084,15 +4084,24 @@ static void qc_dgrams_retransmit(struct quic_conn *qc)
|
||||
hqel->pktns->tx.pto_probe = 1;
|
||||
qc_send_hdshk_pkts(qc, 1, QUIC_TLS_ENC_LEVEL_INITIAL, &ifrms,
|
||||
QUIC_TLS_ENC_LEVEL_HANDSHAKE, &hfrms);
|
||||
/* Put back unsent frames in their packet number spaces */
|
||||
LIST_SPLICE(&iqel->pktns->tx.frms, &ifrms);
|
||||
LIST_SPLICE(&hqel->pktns->tx.frms, &hfrms);
|
||||
}
|
||||
}
|
||||
if (hqel->pktns->flags & QUIC_FL_PKTNS_PROBE_NEEDED) {
|
||||
/* This list has potentially been already used and spliced
|
||||
* to another one attached to the connection. We must reinitialize it.
|
||||
*/
|
||||
LIST_INIT(&hfrms);
|
||||
qc_prep_fast_retrans(qc, hqel, &hfrms, NULL);
|
||||
TRACE_DEVEL("Avail. ack eliciting frames", QUIC_EV_CONN_FRMLIST, qc, &hfrms);
|
||||
if (!LIST_ISEMPTY(&hfrms)) {
|
||||
hqel->pktns->tx.pto_probe = 1;
|
||||
qc_send_hdshk_pkts(qc, 1, QUIC_TLS_ENC_LEVEL_HANDSHAKE, &hfrms,
|
||||
QUIC_TLS_ENC_LEVEL_NONE, NULL);
|
||||
/* Put back unsent frames into their packet number spaces */
|
||||
LIST_SPLICE(&hqel->pktns->tx.frms, &hfrms);
|
||||
}
|
||||
TRACE_STATE("no more need to probe Handshake packet number space",
|
||||
QUIC_EV_CONN_TXPKT, qc);
|
||||
@ -4104,10 +4113,10 @@ static void qc_dgrams_retransmit(struct quic_conn *qc)
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
struct list frms1 = LIST_HEAD_INIT(frms1);
|
||||
struct list frms2 = LIST_HEAD_INIT(frms2);
|
||||
|
||||
if (hqel->pktns->flags & QUIC_FL_PKTNS_PROBE_NEEDED) {
|
||||
struct list frms1 = LIST_HEAD_INIT(frms1);
|
||||
|
||||
hqel->pktns->tx.pto_probe = 0;
|
||||
for (i = 0; i < QUIC_MAX_NB_PTO_DGRAMS; i++) {
|
||||
qc_prep_fast_retrans(qc, hqel, &frms1, NULL);
|
||||
@ -4116,6 +4125,8 @@ static void qc_dgrams_retransmit(struct quic_conn *qc)
|
||||
hqel->pktns->tx.pto_probe = 1;
|
||||
qc_send_hdshk_pkts(qc, 1, QUIC_TLS_ENC_LEVEL_HANDSHAKE, &frms1,
|
||||
QUIC_TLS_ENC_LEVEL_NONE, NULL);
|
||||
/* Put back unsent frames into their packet number spaces */
|
||||
LIST_SPLICE(&hqel->pktns->tx.frms, &frms1);
|
||||
}
|
||||
}
|
||||
TRACE_STATE("no more need to probe Handshake packet number space",
|
||||
@ -4123,6 +4134,9 @@ static void qc_dgrams_retransmit(struct quic_conn *qc)
|
||||
hqel->pktns->flags &= ~QUIC_FL_PKTNS_PROBE_NEEDED;
|
||||
}
|
||||
else if (aqel->pktns->flags & QUIC_FL_PKTNS_PROBE_NEEDED) {
|
||||
struct list frms2 = LIST_HEAD_INIT(frms2);
|
||||
struct list frms1 = LIST_HEAD_INIT(frms1);
|
||||
|
||||
aqel->pktns->tx.pto_probe = 0;
|
||||
qc_prep_fast_retrans(qc, aqel, &frms1, &frms2);
|
||||
TRACE_PROTO("Avail. ack eliciting frames", QUIC_EV_CONN_FRMLIST, qc, &frms1);
|
||||
@ -4130,10 +4144,14 @@ static void qc_dgrams_retransmit(struct quic_conn *qc)
|
||||
if (!LIST_ISEMPTY(&frms1)) {
|
||||
aqel->pktns->tx.pto_probe = 1;
|
||||
qc_send_app_probing(qc, &frms1);
|
||||
/* Put back unsent frames into their packet number spaces */
|
||||
LIST_SPLICE(&aqel->pktns->tx.frms, &frms1);
|
||||
}
|
||||
if (!LIST_ISEMPTY(&frms2)) {
|
||||
aqel->pktns->tx.pto_probe = 1;
|
||||
qc_send_app_probing(qc, &frms2);
|
||||
/* Put back unsent frames into their packet number spaces */
|
||||
LIST_SPLICE(&aqel->pktns->tx.frms, &frms2);
|
||||
}
|
||||
TRACE_STATE("no more need to probe 01RTT packet number space",
|
||||
QUIC_EV_CONN_TXPKT, qc);
|
||||
|
Loading…
Reference in New Issue
Block a user