MINOR: quic: moving code for QUIC loss detection
qc_qc_packet_loss_lookup() is definitively a QUIC loss detection function.
This commit is contained in:
parent
88e5741c53
commit
1601395063
@ -81,5 +81,7 @@ struct quic_pktns *quic_pto_pktns(struct quic_conn *qc,
|
||||
int handshake_completed,
|
||||
unsigned int *pto);
|
||||
|
||||
void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
|
||||
struct list *lost_pkts);
|
||||
#endif /* USE_QUIC */
|
||||
#endif /* _PROTO_QUIC_LOSS_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <import/eb64tree.h>
|
||||
|
||||
#include <haproxy/quic_loss.h>
|
||||
|
||||
#include <haproxy/ticks.h>
|
||||
@ -127,3 +129,61 @@ struct quic_pktns *quic_pto_pktns(struct quic_conn *qc,
|
||||
|
||||
return pktns;
|
||||
}
|
||||
|
||||
/* Look for packet loss from sent packets for <qel> encryption level of a
|
||||
* connection with <ctx> as I/O handler context. If remove is true, remove them from
|
||||
* their tree if deemed as lost or set the <loss_time> value the packet number
|
||||
* space if any not deemed lost.
|
||||
* Should be called after having received an ACK frame with newly acknowledged
|
||||
* packets or when the the loss detection timer has expired.
|
||||
* Always succeeds.
|
||||
*/
|
||||
void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
|
||||
struct list *lost_pkts)
|
||||
{
|
||||
struct eb_root *pkts;
|
||||
struct eb64_node *node;
|
||||
struct quic_loss *ql;
|
||||
unsigned int loss_delay;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_PKTLOSS, qc, pktns);
|
||||
pkts = &pktns->tx.pkts;
|
||||
pktns->tx.loss_time = TICK_ETERNITY;
|
||||
if (eb_is_empty(pkts))
|
||||
goto out;
|
||||
|
||||
ql = &qc->path->loss;
|
||||
loss_delay = QUIC_MAX(ql->latest_rtt, ql->srtt >> 3);
|
||||
loss_delay = QUIC_MAX(loss_delay, MS_TO_TICKS(QUIC_TIMER_GRANULARITY));
|
||||
|
||||
node = eb64_first(pkts);
|
||||
while (node) {
|
||||
struct quic_tx_packet *pkt;
|
||||
int64_t largest_acked_pn;
|
||||
unsigned int loss_time_limit, time_sent;
|
||||
|
||||
pkt = eb64_entry(&node->node, struct quic_tx_packet, pn_node);
|
||||
largest_acked_pn = pktns->rx.largest_acked_pn;
|
||||
node = eb64_next(node);
|
||||
if ((int64_t)pkt->pn_node.key > largest_acked_pn)
|
||||
break;
|
||||
|
||||
time_sent = pkt->time_sent;
|
||||
loss_time_limit = tick_add(time_sent, loss_delay);
|
||||
if (tick_is_le(time_sent, now_ms) ||
|
||||
(int64_t)largest_acked_pn >= pkt->pn_node.key + QUIC_LOSS_PACKET_THRESHOLD) {
|
||||
eb64_delete(&pkt->pn_node);
|
||||
LIST_APPEND(lost_pkts, &pkt->list);
|
||||
}
|
||||
else {
|
||||
if (tick_isset(pktns->tx.loss_time))
|
||||
pktns->tx.loss_time = tick_first(pktns->tx.loss_time, loss_time_limit);
|
||||
else
|
||||
pktns->tx.loss_time = loss_time_limit;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_PKTLOSS, qc, pktns, lost_pkts);
|
||||
}
|
||||
|
||||
|
@ -1906,64 +1906,6 @@ static inline void qc_release_lost_pkts(struct quic_conn *qc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for packet loss from sent packets for <qel> encryption level of a
|
||||
* connection with <ctx> as I/O handler context. If remove is true, remove them from
|
||||
* their tree if deemed as lost or set the <loss_time> value the packet number
|
||||
* space if any not deemed lost.
|
||||
* Should be called after having received an ACK frame with newly acknowledged
|
||||
* packets or when the the loss detection timer has expired.
|
||||
* Always succeeds.
|
||||
*/
|
||||
static void qc_packet_loss_lookup(struct quic_pktns *pktns,
|
||||
struct quic_conn *qc,
|
||||
struct list *lost_pkts)
|
||||
{
|
||||
struct eb_root *pkts;
|
||||
struct eb64_node *node;
|
||||
struct quic_loss *ql;
|
||||
unsigned int loss_delay;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_PKTLOSS, qc, pktns);
|
||||
pkts = &pktns->tx.pkts;
|
||||
pktns->tx.loss_time = TICK_ETERNITY;
|
||||
if (eb_is_empty(pkts))
|
||||
goto out;
|
||||
|
||||
ql = &qc->path->loss;
|
||||
loss_delay = QUIC_MAX(ql->latest_rtt, ql->srtt >> 3);
|
||||
loss_delay = QUIC_MAX(loss_delay, MS_TO_TICKS(QUIC_TIMER_GRANULARITY));
|
||||
|
||||
node = eb64_first(pkts);
|
||||
while (node) {
|
||||
struct quic_tx_packet *pkt;
|
||||
int64_t largest_acked_pn;
|
||||
unsigned int loss_time_limit, time_sent;
|
||||
|
||||
pkt = eb64_entry(&node->node, struct quic_tx_packet, pn_node);
|
||||
largest_acked_pn = pktns->rx.largest_acked_pn;
|
||||
node = eb64_next(node);
|
||||
if ((int64_t)pkt->pn_node.key > largest_acked_pn)
|
||||
break;
|
||||
|
||||
time_sent = pkt->time_sent;
|
||||
loss_time_limit = tick_add(time_sent, loss_delay);
|
||||
if (tick_is_le(time_sent, now_ms) ||
|
||||
(int64_t)largest_acked_pn >= pkt->pn_node.key + QUIC_LOSS_PACKET_THRESHOLD) {
|
||||
eb64_delete(&pkt->pn_node);
|
||||
LIST_APPEND(lost_pkts, &pkt->list);
|
||||
}
|
||||
else {
|
||||
if (tick_isset(pktns->tx.loss_time))
|
||||
pktns->tx.loss_time = tick_first(pktns->tx.loss_time, loss_time_limit);
|
||||
else
|
||||
pktns->tx.loss_time = loss_time_limit;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_PKTLOSS, qc, pktns, lost_pkts);
|
||||
}
|
||||
|
||||
/* Parse ACK frame into <frm> from a buffer at <buf> address with <end> being at
|
||||
* one byte past the end of this buffer. Also update <rtt_sample> if needed, i.e.
|
||||
* if the largest acked packet was newly acked and if there was at least one newly
|
||||
|
Loading…
x
Reference in New Issue
Block a user