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,
|
int handshake_completed,
|
||||||
unsigned int *pto);
|
unsigned int *pto);
|
||||||
|
|
||||||
|
void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
|
||||||
|
struct list *lost_pkts);
|
||||||
#endif /* USE_QUIC */
|
#endif /* USE_QUIC */
|
||||||
#endif /* _PROTO_QUIC_LOSS_H */
|
#endif /* _PROTO_QUIC_LOSS_H */
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <import/eb64tree.h>
|
||||||
|
|
||||||
#include <haproxy/quic_loss.h>
|
#include <haproxy/quic_loss.h>
|
||||||
|
|
||||||
#include <haproxy/ticks.h>
|
#include <haproxy/ticks.h>
|
||||||
@ -127,3 +129,61 @@ struct quic_pktns *quic_pto_pktns(struct quic_conn *qc,
|
|||||||
|
|
||||||
return pktns;
|
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
|
/* 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.
|
* 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
|
* 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