/*
- * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
RX_OPK_CHECK_STATE, /* check is_desired/deadline */
RX_OPK_CHECK_ACKS, /* check ACK ranges */
RX_OPK_TX, /* TX packet */
- RX_OPK_RX_ACK /* RX ACK frame */
+ RX_OPK_RX_ACK, /* RX ACK frame */
+ RX_OPK_SKIP_IF_PN_SPACE /* skip for a given PN space */
};
struct rx_test_op {
0, 0, NULL, 0, 0 \
},
+#define RX_OP_SKIP_IF_PN_SPACE(pn_space) \
+ { \
+ RX_OPK_SKIP_IF_PN_SPACE, 0, (pn_space), 0, \
+ 0, 0, NULL, 0, 0 \
+ },
+
#define RX_OP_END \
{ RX_OPK_END }
RX_OP_END
};
-/* RX 2. Simple Test with ACK Not Yet Desired (Packet Threshold) */
+/* RX 2. Simple Test with ACK Not Yet Desired (Packet Threshold) (1-RTT) */
static const OSSL_QUIC_ACK_RANGE rx_ack_ranges_2a[] = {
{ 0, 0 }
};
};
static const struct rx_test_op rx_script_2[] = {
+ /*
+ * We skip this for INITIAL/HANDSHAKE and use a separate version
+ * (rx_script_4) for those spaces as those spaces should not delay ACK
+ * generation, so a different RX_OP_CHECK_STATE test is needed.
+ */
+ RX_OP_SKIP_IF_PN_SPACE(QUIC_PN_SPACE_INITIAL)
+ RX_OP_SKIP_IF_PN_SPACE(QUIC_PN_SPACE_HANDSHAKE)
+
RX_OP_CHECK_STATE (0, 0, 0) /* no threshold yet */
RX_OP_CHECK_PROC (0, 0, 3)
RX_OP_END
};
+/*
+ * RX 4. Simple Test with ACK Not Yet Desired (Packet Threshold)
+ * (Initial/Handshake)
+ */
+static const OSSL_QUIC_ACK_RANGE rx_ack_ranges_4a[] = {
+ { 0, 1 }
+};
+
+static const struct rx_test_op rx_script_4[] = {
+ /* The application PN space is tested in rx_script_2. */
+ RX_OP_SKIP_IF_PN_SPACE(QUIC_PN_SPACE_APP)
+
+ RX_OP_CHECK_STATE (0, 0, 0) /* no threshold yet */
+ RX_OP_CHECK_PROC (0, 0, 3)
+
+ /* First packet always generates an ACK so get it out of the way. */
+ RX_OP_PKT (0, 0, 1)
+ RX_OP_CHECK_UNPROC (0, 0, 1)
+ RX_OP_CHECK_PROC (0, 1, 1)
+ RX_OP_CHECK_STATE (0, 1, 0) /* first packet always causes ACK */
+ RX_OP_CHECK_ACKS (0, rx_ack_ranges_2a) /* clears packet counter */
+ RX_OP_CHECK_STATE (0, 0, 0) /* desired state should have been cleared */
+
+ /*
+ * Second packet should cause ACK-desired state because we are
+ * INITIAL/HANDSHAKE (RFC 9000 s. 13.2.1)
+ */
+ RX_OP_PKT (0, 1, 1) /* just one packet, threshold is 2 */
+ RX_OP_CHECK_UNPROC (0, 0, 2)
+ RX_OP_CHECK_PROC (0, 2, 1)
+ RX_OP_CHECK_STATE (0, 1, 1)
+ RX_OP_CHECK_ACKS (0, rx_ack_ranges_4a)
+ RX_OP_CHECK_STATE (0, 0, 0) /* desired state should have been cleared */
+
+ /* At this point we would generate e.g. a packet with an ACK. */
+ RX_OP_TX (0, 0, 1) /* ACKs all */
+ RX_OP_CHECK_ACKS (0, rx_ack_ranges_4a) /* not provably ACKed yet */
+ RX_OP_RX_ACK (0, 0, 1) /* TX'd packet is ACK'd */
+
+ RX_OP_CHECK_NO_ACKS (0) /* nothing more to ACK */
+ RX_OP_CHECK_UNPROC (0, 0, 2) /* still unprocessable */
+ RX_OP_CHECK_PROC (0, 2, 1) /* still processable */
+
+ RX_OP_END
+};
+
static const struct rx_test_op *const rx_test_scripts[] = {
rx_script_1,
rx_script_2,
- rx_script_3
+ rx_script_3,
+ rx_script_4
};
static void on_ack_deadline_callback(OSSL_TIME deadline,
struct pkt_info *pkts = NULL;
OSSL_ACKM_TX_PKT *txs = NULL, *tx;
OSSL_TIME ack_deadline[QUIC_PN_SPACE_NUM];
+ size_t opn = 0;
for (i = 0; i < QUIC_PN_SPACE_NUM; ++i)
ack_deadline[i] = ossl_time_infinite();
goto err;
/* Run script. */
- for (s = script; s->kind != RX_OPK_END; ++s) {
+ for (s = script; s->kind != RX_OPK_END; ++s, ++opn) {
fake_time = ossl_time_add(fake_time,
ossl_ticks2time(s->time_advance));
switch (s->kind) {
break;
+ case RX_OPK_SKIP_IF_PN_SPACE:
+ if (space == (int)s->pn) {
+ testresult = 1;
+ goto err;
+ }
+
+ break;
+
default:
goto err;
}
testresult = 1;
err:
+ if (!testresult)
+ TEST_error("error in ACKM RX script %d, op %zu", tidx + 1, opn + 1);
+
helper_destroy(&h);
OPENSSL_free(pkts);
OPENSSL_free(txs);