/*
- * 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
BIO_free(h->bio2);
}
+static void demux_default_handler(QUIC_URXE *e, void *arg,
+ const QUIC_CONN_ID *dcid)
+{
+ struct helper *h = arg;
+
+ if (dcid == NULL || !ossl_quic_conn_id_eq(dcid, &dcid_1))
+ return;
+
+ ossl_qrx_inject_urxe(h->qrx, e);
+}
+
static int helper_init(struct helper *h)
{
int rc = 0;
if (!TEST_true(ossl_quic_stream_map_init(&h->qsm, NULL, NULL,
&h->max_streams_bidi_rxfc,
- &h->max_streams_uni_rxfc)))
+ &h->max_streams_uni_rxfc,
+ /*is_server=*/0)))
goto err;
h->have_qsm = 1;
fake_now, NULL)))
goto err;
+ ossl_quic_demux_set_default_handler(h->demux, demux_default_handler, h);
+
h->qrx_args.demux = h->demux;
h->qrx_args.short_conn_id_len = 8;
h->qrx_args.max_deferred = 32;
if (!TEST_ptr(h->qrx = ossl_qrx_new(&h->qrx_args)))
goto err;
- if (!TEST_true(ossl_qrx_add_dst_conn_id(h->qrx, &dcid_1)))
- goto err;
+ ossl_qrx_allow_1rtt_processing(h->qrx);
rc = 1;
err:
#define OPK_CONN_TXFC_BUMP 20 /* Bump connection TXFC CWM */
#define OPK_STREAM_TXFC_BUMP 21 /* Bump stream TXFC CWM */
#define OPK_HANDSHAKE_COMPLETE 22 /* Mark handshake as complete */
+#define OPK_NOP 23 /* No-op */
struct script_op {
uint32_t opcode;
#define OP_END \
{ OPK_END }
-#define OP_TXP_GENERATE(archetype) \
- { OPK_TXP_GENERATE, (archetype) },
-#define OP_TXP_GENERATE_NONE(archetype) \
- { OPK_TXP_GENERATE_NONE, (archetype) },
+#define OP_TXP_GENERATE() \
+ { OPK_TXP_GENERATE },
+#define OP_TXP_GENERATE_NONE() \
+ { OPK_TXP_GENERATE_NONE },
#define OP_RX_PKT() \
{ OPK_RX_PKT },
#define OP_RX_PKT_NONE() \
{ OPK_STREAM_TXFC_BUMP, (cwm), (id) },
#define OP_HANDSHAKE_COMPLETE() \
{ OPK_HANDSHAKE_COMPLETE },
+#define OP_NOP() \
+ { OPK_NOP },
static int schedule_handshake_done(struct helper *h)
{
/* 1. 1-RTT, Single Handshake Done Frame */
static const struct script_op script_1[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_handshake_done)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
/* Should not be long */
OP_EXPECT_DGRAM_LEN(21, 32)
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
/* 2. 1-RTT, Forced ACK-Eliciting Frame */
static const struct script_op script_2[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_ack_eliciting_app)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
/* Should not be long */
OP_EXPECT_DGRAM_LEN(21, 32)
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_PING)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_3[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_max_data)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
/* Should not be long */
OP_EXPECT_DGRAM_LEN(21, 40)
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_MAX_DATA)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
QUIC_CFQ_ITEM *cfq_item;
WPACKET wpkt;
BUF_MEM *buf_mem = NULL;
- char have_wpkt = 0;
size_t l = 0;
OSSL_QUIC_FRAME_NEW_CONN_ID ncid = {0};
- ncid.seq_num = 1234;
- ncid.retire_prior_to = 2345;
+ ncid.seq_num = 2345;
+ ncid.retire_prior_to = 1234;
ncid.conn_id = cid_1;
- memcpy(ncid.stateless_reset_token, reset_token_1, sizeof(reset_token_1));
+ memcpy(ncid.stateless_reset.token, reset_token_1, sizeof(reset_token_1));
if (!TEST_ptr(buf_mem = BUF_MEM_new()))
goto err;
if (!TEST_true(WPACKET_init(&wpkt, buf_mem)))
goto err;
- have_wpkt = 1;
- if (!TEST_true(ossl_quic_wire_encode_frame_new_conn_id(&wpkt, &ncid)))
+ if (!TEST_true(ossl_quic_wire_encode_frame_new_conn_id(&wpkt, &ncid))) {
+ WPACKET_cleanup(&wpkt);
goto err;
+ }
+
+ WPACKET_finish(&wpkt);
if (!TEST_true(WPACKET_get_total_written(&wpkt, &l)))
goto err;
if (!TEST_ptr(cfq_item = ossl_quic_cfq_add_frame(h->args.cfq, 1,
QUIC_PN_SPACE_APP,
- OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,
+ OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID, 0,
(unsigned char *)buf_mem->data, l,
free_buf_mem,
buf_mem)))
rc = 1;
err:
- if (have_wpkt)
- WPACKET_cleanup(&wpkt);
+ if (!rc)
+ BUF_MEM_free(buf_mem);
return rc;
}
static int check_cfq_new_conn_id(struct helper *h)
{
- if (!TEST_uint64_t_eq(h->frame.new_conn_id.seq_num, 1234)
- || !TEST_uint64_t_eq(h->frame.new_conn_id.retire_prior_to, 2345)
+ if (!TEST_uint64_t_eq(h->frame.new_conn_id.seq_num, 2345)
+ || !TEST_uint64_t_eq(h->frame.new_conn_id.retire_prior_to, 1234)
|| !TEST_mem_eq(&h->frame.new_conn_id.conn_id, sizeof(cid_1),
&cid_1, sizeof(cid_1))
- || !TEST_mem_eq(&h->frame.new_conn_id.stateless_reset_token,
+ || !TEST_mem_eq(&h->frame.new_conn_id.stateless_reset.token,
sizeof(reset_token_1),
reset_token_1,
sizeof(reset_token_1)))
static const struct script_op script_4[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_cfq_new_conn_id)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 128)
OP_NEXT_FRAME()
OP_CHECK(check_cfq_new_conn_id)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
QUIC_CFQ_ITEM *cfq_item;
WPACKET wpkt;
BUF_MEM *buf_mem = NULL;
- char have_wpkt = 0;
size_t l = 0;
if (!TEST_ptr(buf_mem = BUF_MEM_new()))
if (!TEST_true(WPACKET_init(&wpkt, buf_mem)))
goto err;
- have_wpkt = 1;
if (!TEST_true(ossl_quic_wire_encode_frame_new_token(&wpkt, token_1,
- sizeof(token_1))))
+ sizeof(token_1)))) {
+ WPACKET_cleanup(&wpkt);
goto err;
+ }
+
+ WPACKET_finish(&wpkt);
if (!TEST_true(WPACKET_get_total_written(&wpkt, &l)))
goto err;
if (!TEST_ptr(cfq_item = ossl_quic_cfq_add_frame(h->args.cfq, 1,
QUIC_PN_SPACE_APP,
- OSSL_QUIC_FRAME_TYPE_NEW_TOKEN,
+ OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, 0,
(unsigned char *)buf_mem->data, l,
free_buf_mem,
buf_mem)))
rc = 1;
err:
- if (have_wpkt)
- WPACKET_cleanup(&wpkt);
+ if (!rc)
+ BUF_MEM_free(buf_mem);
return rc;
}
static const struct script_op script_5[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_cfq_new_token)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_CHECK(check_cfq_new_token)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_6[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_ack)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
/* 7. 1-RTT, ACK, NEW_TOKEN */
static const struct script_op script_7[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(schedule_cfq_new_token)
OP_CHECK(schedule_ack)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
/* ACK must come before NEW_TOKEN */
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_8[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CRYPTO_SEND(QUIC_PN_SPACE_APP, crypto_1)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_CRYPTO)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_9[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
OP_HANDSHAKE_COMPLETE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_STREAM_NEW(42)
OP_STREAM_SEND(42, stream_9)
/* Still no output because of TXFC */
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
/* Now grant a TXFC budget */
OP_CONN_TXFC_BUMP(1000)
OP_STREAM_TXFC_BUMP(42, 1000)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_CHECK(check_stream_9)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_10[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
OP_HANDSHAKE_COMPLETE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_STREAM_NEW(42)
OP_STREAM_NEW(43)
OP_CONN_TXFC_BUMP(10000)
OP_STREAM_SEND(43, stream_10b)
/* First packet containing data from stream 42 */
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(1100, 1200)
OP_NEXT_FRAME()
OP_EXPECT_NO_FRAME()
/* Second packet containing data from stream 43 */
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(1100, 1200)
OP_NEXT_FRAME()
OP_EXPECT_NO_FRAME()
/* Third packet containing data from stream 42 */
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(200, 500)
OP_NEXT_FRAME()
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
/* 11. Initial, CRYPTO */
static const struct script_op script_11[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_INITIAL, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CRYPTO_SEND(QUIC_PN_SPACE_INITIAL, crypto_1)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(1200, 1200)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_CRYPTO)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_12[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
OP_HANDSHAKE_COMPLETE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_STREAM_NEW(42)
OP_STOP_SENDING(42, 4568)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 128)
OP_NEXT_FRAME()
OP_CHECK(check_stream_12)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
{
if (!TEST_uint64_t_eq(h->frame.reset_stream.stream_id, 42)
|| !TEST_uint64_t_eq(h->frame.reset_stream.app_error_code, 4568)
- || !TEST_uint64_t_eq(h->frame.reset_stream.final_size, 8))
+ || !TEST_uint64_t_eq(h->frame.reset_stream.final_size, 0))
return 0;
return 1;
static const struct script_op script_13[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
OP_HANDSHAKE_COMPLETE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_STREAM_NEW(42)
OP_CONN_TXFC_BUMP(8)
OP_STREAM_TXFC_BUMP(42, 8)
OP_STREAM_SEND(42, stream_13)
OP_RESET_STREAM(42, 4568)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 128)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
OP_CHECK(check_stream_13)
OP_NEXT_FRAME()
- OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_STREAM)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_14[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
OP_HANDSHAKE_COMPLETE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(gen_conn_close)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
static const struct script_op script_15[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_INITIAL, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(gen_probe_initial)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(1200, 1200)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_PING)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
static const struct script_op script_16[] = {
OP_DISCARD_EL(QUIC_ENC_LEVEL_INITIAL)
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_HANDSHAKE, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(gen_probe_handshake)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_PING)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_END
};
OP_DISCARD_EL(QUIC_ENC_LEVEL_INITIAL)
OP_DISCARD_EL(QUIC_ENC_LEVEL_HANDSHAKE)
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
OP_CHECK(gen_probe_1rtt)
- OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE()
OP_RX_PKT()
OP_EXPECT_DGRAM_LEN(21, 512)
OP_NEXT_FRAME()
OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_PING)
OP_EXPECT_NO_FRAME()
OP_RX_PKT_NONE()
- OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
+ OP_TXP_GENERATE_NONE()
+ OP_END
+};
+
+/* 18. Big Token Rejection */
+static const unsigned char big_token[1950];
+
+static int try_big_token(struct helper *h)
+{
+ size_t i;
+
+ /* Ensure big token is rejected */
+ if (!TEST_false(ossl_quic_tx_packetiser_set_initial_token(h->txp,
+ big_token,
+ sizeof(big_token),
+ NULL,
+ NULL)))
+ return 0;
+
+ /*
+ * Keep trying until we find an acceptable size, then make sure
+ * that works for generation
+ */
+ for (i = sizeof(big_token) - 1;; --i) {
+ if (!TEST_size_t_gt(i, 0))
+ return 0;
+
+ if (ossl_quic_tx_packetiser_set_initial_token(h->txp, big_token, i,
+ NULL, NULL))
+ break;
+ }
+
+ return 1;
+}
+
+static const struct script_op script_18[] = {
+ OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_INITIAL, QRL_SUITE_AES128GCM, secret_1)
+ OP_TXP_GENERATE_NONE()
+ OP_CHECK(try_big_token)
+ OP_TXP_GENERATE_NONE()
+ OP_CRYPTO_SEND(QUIC_PN_SPACE_INITIAL, crypto_1)
+ OP_TXP_GENERATE()
+ OP_RX_PKT()
+ OP_EXPECT_DGRAM_LEN(1200, 1200)
+ OP_NEXT_FRAME()
+ OP_EXPECT_FRAME(OSSL_QUIC_FRAME_TYPE_CRYPTO)
+ OP_EXPECT_NO_FRAME()
+ OP_RX_PKT_NONE()
+ OP_TXP_GENERATE_NONE()
OP_END
};
script_14,
script_15,
script_16,
- script_17
+ script_17,
+ script_18
};
static void skip_padding(struct helper *h)
{
uint64_t frame_type;
- if (!ossl_quic_wire_peek_frame_header(&h->pkt, &frame_type))
+ if (!ossl_quic_wire_peek_frame_header(&h->pkt, &frame_type, NULL))
return; /* EOF */
if (frame_type == OSSL_QUIC_FRAME_TYPE_PADDING)
ossl_quic_wire_decode_padding(&h->pkt);
}
-static int run_script(const struct script_op *script)
+static int run_script(int script_idx, const struct script_op *script)
{
- int testresult = 0, have_helper = 0, sent_ack_eliciting = 0;
+ int testresult = 0, have_helper = 0;
+ QUIC_TXP_STATUS status;
struct helper h;
const struct script_op *op;
+ size_t opn = 0;
if (!helper_init(&h))
goto err;
have_helper = 1;
- for (op = script; op->opcode != OPK_END; ++op) {
+ for (op = script, opn = 0; op->opcode != OPK_END; ++op, ++opn) {
switch (op->opcode) {
case OPK_TXP_GENERATE:
- if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0,
- &sent_ack_eliciting),
- TX_PACKETISER_RES_SENT_PKT))
+ if (!TEST_true(ossl_quic_tx_packetiser_generate(h.txp, &status))
+ && !TEST_size_t_gt(status.sent_pkt, 0))
goto err;
ossl_qtx_finish_dgram(h.args.qtx);
ossl_qtx_flush_net(h.args.qtx);
break;
case OPK_TXP_GENERATE_NONE:
- if (!TEST_int_eq(ossl_quic_tx_packetiser_generate(h.txp, (int)op->arg0,
- &sent_ack_eliciting),
- TX_PACKETISER_RES_NO_PKT))
+ if (!TEST_true(ossl_quic_tx_packetiser_generate(h.txp, &status))
+ && !TEST_size_t_eq(status.sent_pkt, 0))
goto err;
break;
break;
case OPK_NEXT_FRAME:
skip_padding(&h);
- if (!ossl_quic_wire_peek_frame_header(&h.pkt, &h.frame_type)) {
+ if (!ossl_quic_wire_peek_frame_header(&h.pkt, &h.frame_type, NULL)) {
h.frame_type = UINT64_MAX;
break;
}
goto err;
break;
case OSSL_QUIC_FRAME_TYPE_CRYPTO:
- if (!TEST_true(ossl_quic_wire_decode_frame_crypto(&h.pkt, &h.frame.crypto)))
+ if (!TEST_true(ossl_quic_wire_decode_frame_crypto(&h.pkt, 0, &h.frame.crypto)))
goto err;
break;
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN:
- if (!TEST_true(ossl_quic_wire_decode_frame_stream(&h.pkt, &h.frame.stream)))
+ if (!TEST_true(ossl_quic_wire_decode_frame_stream(&h.pkt, 0, &h.frame.stream)))
goto err;
break;
|| !TEST_true(ossl_quic_rxfc_init(&s->rxfc, &h.conn_rxfc,
1 * 1024 * 1024,
16 * 1024 * 1024,
- fake_now, NULL))) {
+ fake_now, NULL))
+ || !TEST_ptr(s->rstream = ossl_quic_rstream_new(&s->rxfc,
+ NULL, 1024))) {
ossl_quic_sstream_free(s->sstream);
ossl_quic_stream_map_release(h.args.qsm, s);
goto err;
case OPK_HANDSHAKE_COMPLETE:
ossl_quic_tx_packetiser_notify_handshake_complete(h.txp);
break;
+ case OPK_NOP:
+ break;
default:
TEST_error("bad opcode");
goto err;
testresult = 1;
err:
+ if (!testresult)
+ TEST_error("script %d failed at op %zu", script_idx + 1, opn + 1);
if (have_helper)
helper_cleanup(&h);
return testresult;
static int test_script(int idx)
{
- return run_script(scripts[idx]);
+ return run_script(idx, scripts[idx]);
+}
+
+/*
+ * Dynamic Script 1.
+ *
+ * This script exists to test the interactions between multiple packets (ELs) in
+ * the same datagram when there is a padding requirement (due to the datagram
+ * containing an Initial packet). There are boundary cases which are difficult
+ * to get right so it is important to test this entire space. Examples of such
+ * edge cases include:
+ *
+ * - If we are planning on generating both an Initial and Handshake packet in a
+ * datagram ordinarily we would plan on adding the padding frames to meet the
+ * mandatory minimum size to the last packet in the datagram (i.e., the
+ * Handshake packet). But if the amount of room remaining in a datagram is
+ * e.g. only 3 bytes after generating the Initial packet, this is not
+ * enough room for another packet and we have a problem as having finished
+ * the Initial packet we have no way to add the necessary padding.
+ *
+ * - If we do have room for another packet but it is not enough room to encode
+ * any desired frame.
+ *
+ * This test confirms we handle these cases correctly for multi-packet datagrams
+ * by placing two packets in a datagram and varying the size of the first
+ * datagram.
+ */
+static const unsigned char dyn_script_1_crypto_1a[1200];
+static const unsigned char dyn_script_1_crypto_1b[1];
+
+static int check_is_initial(struct helper *h)
+{
+ return h->qrx_pkt->hdr->type == QUIC_PKT_TYPE_INITIAL;
+}
+
+static int check_is_handshake(struct helper *h)
+{
+ return h->qrx_pkt->hdr->type == QUIC_PKT_TYPE_HANDSHAKE;
+}
+
+static struct script_op dyn_script_1[] = {
+ OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_INITIAL, QRL_SUITE_AES128GCM, secret_1)
+ OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_HANDSHAKE, QRL_SUITE_AES128GCM, secret_1)
+ OP_TXP_GENERATE_NONE()
+ OP_CRYPTO_SEND(QUIC_PN_SPACE_INITIAL, dyn_script_1_crypto_1a) /* [crypto_idx] */
+ OP_CRYPTO_SEND(QUIC_PN_SPACE_HANDSHAKE, dyn_script_1_crypto_1b)
+ OP_TXP_GENERATE()
+ OP_RX_PKT()
+ OP_EXPECT_DGRAM_LEN(1200, 1200)
+ OP_CHECK(check_is_initial)
+ OP_NOP() /* [pkt_idx] */
+ OP_NOP() /* [check_idx] */
+ OP_END
+};
+
+static const size_t dyn_script_1_crypto_idx = 3;
+static const size_t dyn_script_1_pkt_idx = 9;
+static const size_t dyn_script_1_check_idx = 10;
+static const size_t dyn_script_1_start_from = 1000;
+
+static int test_dyn_script_1(int idx)
+{
+ size_t target_size = dyn_script_1_start_from + (size_t)idx;
+ int expect_handshake_pkt_in_same_dgram = (target_size <= 1115);
+
+ dyn_script_1[dyn_script_1_crypto_idx].buf_len = target_size;
+
+ if (expect_handshake_pkt_in_same_dgram) {
+ dyn_script_1[dyn_script_1_pkt_idx].opcode = OPK_RX_PKT;
+ dyn_script_1[dyn_script_1_check_idx].opcode = OPK_CHECK;
+ dyn_script_1[dyn_script_1_check_idx].check_func = check_is_handshake;
+ } else {
+ dyn_script_1[dyn_script_1_pkt_idx].opcode = OPK_RX_PKT_NONE;
+ dyn_script_1[dyn_script_1_check_idx].opcode = OPK_NOP;
+ }
+
+ if (!run_script(idx, dyn_script_1)) {
+ TEST_error("failed dyn script 1 with target size %zu", target_size);
+ return 0;
+ }
+
+ return 1;
}
int setup_tests(void)
{
ADD_ALL_TESTS(test_script, OSSL_NELEM(scripts));
+ ADD_ALL_TESTS(test_dyn_script_1,
+ OSSL_NELEM(dyn_script_1_crypto_1a)
+ - dyn_script_1_start_from + 1);
return 1;
}