+ 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;