# ifndef OPENSSL_NO_QUIC
-typedef void (*ossl_msg_cb)(int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl, void *arg);
-
/*
* QUIC Record Layer - RX
* ======================
/* Maximum datagram payload length (MDPL) for TX purposes. */
size_t mdpl;
+
+ /* Message callback related arguments */
+ ossl_msg_cb msg_callback;
+ void *msg_callback_arg;
+ SSL *msg_callback_s;
} OSSL_QTX_ARGS;
/* Instantiates a new QTX. */
# define QUIC_STATELESS_RESET_TOKEN_LEN 16
+typedef void (*ossl_msg_cb)(int write_p, int version, int content_type,
+ const void *buf, size_t len, SSL *ssl, void *arg);
+
# endif
#endif
* If partial is 0, the input is assumed to have already had header protection
* removed, and all header fields are decoded.
*
+ * If nodata is 1, the input is assumed to have no payload data in it. Otherwise
+ * payload data must be present.
+ *
* On success, the logical decode of the packet header is written to *hdr.
* hdr->partial is set or cleared according to whether a partial decode was
* performed. *ptrs is filled with pointers to various parts of the packet
int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
size_t short_conn_id_len,
int partial,
+ int nodata,
QUIC_PKT_HDR *hdr,
QUIC_PKT_HDR_PTRS *ptrs);
/* We plug in a network write BIO to the QTX later when we get one. */
qtx_args.libctx = ch->libctx;
qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN;
+ /* Callback related arguments */
+ qtx_args.msg_callback = ch->msg_callback;
+ qtx_args.msg_callback_arg = ch->msg_callback_arg;
+ qtx_args.msg_callback_s = ch->msg_callback_s;
ch->rx_max_udp_payload_size = qtx_args.mdpl;
ch->qtx = ossl_qtx_new(&qtx_args);
* operation to fail if we get a 1-RTT packet. This is fine since we only
* care about Initial packets.
*/
- if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, &hdr, NULL))
+ if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, 0, &hdr, NULL))
goto undesirable;
switch (hdr.version) {
need_second_decode = !pkt_is_marked(&urxe->hpr_removed, pkt_idx);
if (!ossl_quic_wire_decode_pkt_hdr(pkt,
qrx->short_conn_id_len,
- need_second_decode, &rxe->hdr, &ptrs))
+ need_second_decode, 0, &rxe->hdr, &ptrs))
goto malformed;
/*
/* Decode the now unprotected header. */
if (ossl_quic_wire_decode_pkt_hdr(pkt, qrx->short_conn_id_len,
- 0, &rxe->hdr, NULL) != 1)
+ 0, 0, &rxe->hdr, NULL) != 1)
goto malformed;
-
- if (qrx->msg_callback != NULL)
- qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, sop,
- eop - sop, qrx->msg_callback_s, qrx->msg_callback_arg);
}
/* Validate header and decode PN. */
if (!qrx_validate_hdr(qrx, rxe))
goto malformed;
+ if (qrx->msg_callback != NULL)
+ qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, sop,
+ eop - sop - rxe->hdr.len, qrx->msg_callback_s,
+ qrx->msg_callback_arg);
+
/*
* The AAD data is the entire (unprotected) packet header including the PN.
* The packet header has been unprotected in place, so we can just reuse the
ossl_mutate_packet_cb mutatecb;
ossl_finish_mutate_cb finishmutatecb;
void *mutatearg;
+
+ /* Message callback related arguments */
+ ossl_msg_cb msg_callback;
+ void *msg_callback_arg;
+ SSL *msg_callback_s;
};
/* Instantiates a new QTX. */
qtx->propq = args->propq;
qtx->bio = args->bio;
qtx->mdpl = args->mdpl;
+ qtx->msg_callback = args->msg_callback;
+ qtx->msg_callback_arg = args->msg_callback_arg;
+ qtx->msg_callback_s = args->msg_callback_s;
return qtx;
}
{
WPACKET wpkt;
size_t l = 0;
+ unsigned char *data = txe_data(txe) + txe->data_len;
- if (!WPACKET_init_static_len(&wpkt, txe_data(txe) + txe->data_len,
- txe->alloc_len - txe->data_len, 0))
+ if (!WPACKET_init_static_len(&wpkt, data, txe->alloc_len - txe->data_len, 0))
return 0;
if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, hdr->dst_conn_id.id_len,
WPACKET_finish(&wpkt);
return 0;
}
+ WPACKET_finish(&wpkt);
+
+ if (qtx->msg_callback != NULL)
+ qtx->msg_callback(1, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_PACKET, data, l,
+ qtx->msg_callback_s, qtx->msg_callback_arg);
txe->data_len += l;
- WPACKET_finish(&wpkt);
+
return 1;
}
* TODO(QUIC): We need to query the short connection id len here,
* e.g. via some API SSL_get_short_conn_id_len()
*/
- if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, &hdr, NULL) != 1)
+ if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 1, &hdr, NULL) != 1)
return 0;
BIO_puts(bio, write_p ? "Sent" : "Received");
int ossl_quic_wire_decode_pkt_hdr(PACKET *pkt,
size_t short_conn_id_len,
int partial,
+ int nodata,
QUIC_PKT_HDR *hdr,
QUIC_PKT_HDR_PTRS *ptrs)
{
hdr->pn_len = partial ? 0 : (b0 & 3) + 1;
if (!PACKET_get_quic_vlint(pkt, &len)
- || len < sizeof(hdr->pn)
- || len > PACKET_remaining(pkt))
+ || len < sizeof(hdr->pn))
+ return 0;
+
+ if (!nodata && len > PACKET_remaining(pkt))
return 0;
/*
hdr->len = (size_t)(len - hdr->pn_len);
}
- hdr->data = PACKET_data(pkt);
+ if (nodata) {
+ hdr->data = NULL;
+ } else {
+ hdr->data = PACKET_data(pkt);
- /* Skip over packet body. */
- if (!PACKET_forward(pkt, hdr->len))
- return 0;
+ /* Skip over packet body. */
+ if (!PACKET_forward(pkt, hdr->len))
+ return 0;
+ }
}
}
}
do {
if (!ossl_quic_wire_decode_pkt_hdr(&pkt,
0 /* TODO(QUIC): Not sure how this should be set*/, 1,
- &hdr, NULL))
+ 0, &hdr, NULL))
goto out;
/*
goto err;
if (!TEST_int_eq(ossl_quic_wire_decode_pkt_hdr(&pkt, t->short_conn_id_len,
- 0, &hdr, &ptrs),
+ 0, 0, &hdr, &ptrs),
!expect_fail))
goto err;
if (!TEST_true(PACKET_buf_init(&pkt, retry_encoded, sizeof(retry_encoded))))
goto err;
- if (!TEST_true(ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, &hdr, NULL)))
+ if (!TEST_true(ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 0, &hdr, NULL)))
goto err;
if (!TEST_int_eq(hdr.type, QUIC_PKT_TYPE_RETRY))