void *now_arg,
OSSL_STATM *statm,
const OSSL_CC_METHOD *cc_method,
- OSSL_CC_DATA *cc_data);
+ OSSL_CC_DATA *cc_data, char is_server);
void ossl_ackm_free(OSSL_ACKM *ackm);
void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm,
/* Set to 1 when the handshake is confirmed. */
char handshake_confirmed;
+ /* Set to 1 when attached to server channel */
+ char is_server;
+
/* Set to 1 when the peer has completed address validation. */
char peer_completed_addr_validation;
}
for (i = QUIC_PN_SPACE_INITIAL; i < QUIC_PN_SPACE_NUM; ++i) {
- if (ackm->ack_eliciting_bytes_in_flight[i] == 0)
+ /*
+ * RFC 9002 section 5.2.2.1 keep probe timeout armed until
+ * handshake is confirmed (client sees HANDSHAKE_DONE message
+ * from server(.
+ */
+ if (ackm->ack_eliciting_bytes_in_flight[i] == 0 &&
+ (ackm->handshake_confirmed == 1 || ackm->is_server == 1))
continue;
if (i == QUIC_PN_SPACE_APP) {
}
}
- t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);
- if (ossl_time_compare(t, pto_timeout) < 0) {
- pto_timeout = t;
- pto_space = i;
+ /*
+ * Only re-arm timer if stack has sent at least one ACK eliciting frame.
+ * If stack has sent no ACK eliciting at given encryption level then
+ * particular timer is zero and we must not attempt to set it. Timer time
+ * runs since epoch (Jan 1 1970 and we must not set timer to past.
+ */
+ if (!ossl_time_is_zero(ackm->time_of_last_ack_eliciting_pkt[i])) {
+ t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);
+ if (ossl_time_compare(t, pto_timeout) < 0) {
+ pto_timeout = t;
+ pto_space = i;
+ }
}
}
void *now_arg,
OSSL_STATM *statm,
const OSSL_CC_METHOD *cc_method,
- OSSL_CC_DATA *cc_data)
+ OSSL_CC_DATA *cc_data,
+ char is_server)
{
OSSL_ACKM *ackm;
int i;
ackm->statm = statm;
ackm->cc_method = cc_method;
ackm->cc_data = cc_data;
+ ackm->is_server = is_server;
ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY);
ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY;
goto err;
if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm,
- ch->cc_method, ch->cc_data)) == NULL)
+ ch->cc_method, ch->cc_data,
+ ch->is_server)) == NULL)
goto err;
if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch,
/* Initialise ACK manager. */
h->ackm = ossl_ackm_new(fake_now, NULL, &h->statm,
- &ossl_cc_dummy_method, h->ccdata);
+ &ossl_cc_dummy_method, h->ccdata,
+ /* is_server */0);
if (!TEST_ptr(h->ackm))
goto err;
|| !TEST_ptr(info.ackm = ossl_ackm_new(fake_now, NULL,
&info.statm,
&ossl_cc_dummy_method,
- info.ccdata))
+ info.ccdata,
+ /* is_server */0))
|| !TEST_true(ossl_ackm_on_handshake_confirmed(info.ackm))
|| !TEST_ptr(info.cfq = ossl_quic_cfq_new())
|| !TEST_ptr(info.txpim = ossl_quic_txpim_new())