summaryrefslogtreecommitdiffstats
path: root/ssl/quic/quic_ackm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/quic/quic_ackm.c')
-rw-r--r--ssl/quic/quic_ackm.c70
1 files changed, 36 insertions, 34 deletions
diff --git a/ssl/quic/quic_ackm.c b/ssl/quic/quic_ackm.c
index 6061fb29f5..b798636571 100644
--- a/ssl/quic/quic_ackm.c
+++ b/ssl/quic/quic_ackm.c
@@ -911,7 +911,7 @@ static int ackm_set_loss_detection_timer(OSSL_ACKM *ackm)
static int ackm_in_persistent_congestion(OSSL_ACKM *ackm,
const OSSL_ACKM_TX_PKT *lpkt)
{
- /* Persistent congestion not currently implemented. */
+ /* TODO(QUIC): Persistent congestion not currently implemented. */
return 0;
}
@@ -922,6 +922,8 @@ static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space,
OSSL_RTT_INFO rtt;
QUIC_PN largest_pn_lost = 0;
uint64_t num_bytes = 0;
+ OSSL_CC_LOSS_INFO loss_info = {0};
+ uint32_t flags = 0;
for (p = lpkt; p != NULL; p = pnext) {
pnext = p->lnext;
@@ -938,41 +940,38 @@ static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space,
num_bytes += p->num_bytes;
}
+ if (!pseudo) {
+ /*
+ * If this is pseudo-loss (e.g. during connection retry) we do not
+ * inform the CC as it is not a real loss and not reflective of
+ * network conditions.
+ */
+ loss_info.tx_time = p->time;
+ loss_info.tx_size = p->num_bytes;
+
+ ackm->cc_method->on_data_lost(ackm->cc_data, &loss_info);
+ }
+
p->on_lost(p->cb_arg);
}
- if (pseudo)
- /*
- * If this is pseudo-loss (e.g. during connection retry) we do not
- * inform the CC as it is not a real loss and not reflective of network
- * conditions.
- */
- return;
-
/*
- * Only consider lost packets with regards to congestion after getting an
- * RTT sample.
+ * Persistent congestion can only be considered if we have gotten at least
+ * one RTT sample.
*/
ossl_statm_get_rtt_info(ackm->statm, &rtt);
+ if (!ossl_time_is_zero(ackm->first_rtt_sample)
+ && ackm_in_persistent_congestion(ackm, lpkt))
+ flags |= OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION;
- if (ossl_time_is_zero(ackm->first_rtt_sample))
- return;
-
- ackm->cc_method->on_data_lost(ackm->cc_data,
- largest_pn_lost,
- ackm->tx_history[pkt_space].highest_sent,
- num_bytes,
- ackm_in_persistent_congestion(ackm, lpkt));
+ ackm->cc_method->on_data_lost_finished(ackm->cc_data, flags);
}
static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt)
{
const OSSL_ACKM_TX_PKT *anext;
- OSSL_TIME now;
- uint64_t num_retransmittable_bytes = 0;
QUIC_PN last_pn_acked = 0;
-
- now = ackm->now(ackm->now_arg);
+ OSSL_CC_ACK_INFO ainfo = {0};
for (; apkt != NULL; apkt = anext) {
if (apkt->is_inflight) {
@@ -981,7 +980,6 @@ static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt)
ackm->ack_eliciting_bytes_in_flight[apkt->pkt_space]
-= apkt->num_bytes;
- num_retransmittable_bytes += apkt->num_bytes;
if (apkt->pkt_num > last_pn_acked)
last_pn_acked = apkt->pkt_num;
@@ -997,10 +995,11 @@ static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt)
anext = apkt->anext;
apkt->on_acked(apkt->cb_arg); /* may free apkt */
- }
- ackm->cc_method->on_data_acked(ackm->cc_data, now,
- last_pn_acked, num_retransmittable_bytes);
+ ainfo.tx_time = apkt->time;
+ ainfo.tx_size = apkt->num_bytes;
+ ackm->cc_method->on_data_acked(ackm->cc_data, &ainfo);
+ }
}
OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),
@@ -1096,16 +1095,12 @@ int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes)
return 1;
}
-static void ackm_on_congestion(OSSL_ACKM *ackm, OSSL_TIME send_time)
-{
- /* Not currently implemented. */
-}
-
static void ackm_process_ecn(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack,
int pkt_space)
{
struct tx_pkt_history_st *h;
OSSL_ACKM_TX_PKT *pkt;
+ OSSL_CC_ECN_INFO ecn_info = {0};
/*
* If the ECN-CE counter reported by the peer has increased, this could
@@ -1119,7 +1114,8 @@ static void ackm_process_ecn(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack,
if (pkt == NULL)
return;
- ackm_on_congestion(ackm, pkt->time);
+ ecn_info.largest_acked_time = pkt->time;
+ ackm->cc_method->on_ecn(ackm->cc_data, &ecn_info);
}
}
@@ -1182,7 +1178,13 @@ int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack,
ossl_time_subtract(now, na_pkts->time));
}
- /* Process ECN information if present. */
+ /*
+ * Process ECN information if present.
+ *
+ * We deliberately do most ECN processing in the ACKM rather than the
+ * congestion controller to avoid having to give the congestion controller
+ * access to ACKM internal state.
+ */
if (ack->ecn_present)
ackm_process_ecn(ackm, ack, pkt_space);