* function was not provided).
*/
OSSL_TIME time;
+
+ /*
+ * Used by the QRX to mark whether a datagram has been deferred. Used by the
+ * QRX only; not used by the demuxer.
+ */
+ char deferred;
};
/* Accessors for URXE buffer. */
/* Length of connection IDs used in short-header packets in bytes. */
size_t short_conn_id_len;
+ /*
+ * Maximum number of deferred datagrams buffered at any one time.
+ * Suggested value: 32.
+ */
+ size_t max_deferred;
+
/* Initial reference PN used for RX. */
QUIC_PN init_largest_pn[QUIC_PN_SPACE_NUM];
* as do calls made after a corresponding call to ossl_qrx_discard_enc_level for
* that EL. The secret for a EL cannot be changed after it is set because QUIC
* has no facility for introducing additional key material after an EL is setup.
- * QUIC key updates are managed automatically by the QRX and do not require user
- * intervention.
+ * QUIC key updates are managed semi-automatically by the QRX but do require
+ * some caller handling (see below).
*
* md is for internal use and should be NULL.
*
int ossl_qrx_processed_read_pending(OSSL_QRX *qrx);
/*
- * Returns 1 if there arre any unprocessed (i.e. not yet decrypted) packets
+ * Returns 1 if there are any unprocessed (i.e. not yet decrypted) packets
* waiting to be processed by the QRX. These may or may not result in
* successfully decrypted packets once processed. This indicates whether
* unprocessed data is buffered by the QRX, not whether any data is available in
* current substate of the PROVISIONED state is to the DISCARDED state, which is
* the terminal state.
*
- * Note that non-1RTT ELs cannot undergo key update, therefore a non-1RT EL is
+ * Note that non-1RTT ELs cannot undergo key update, therefore a non-1RTT EL is
* always in the NORMAL substate if it is in the PROVISIONED state.
*/
/* Length of connection IDs used in short-header packets in bytes. */
size_t short_conn_id_len;
+ /* Maximum number of deferred datagrams buffered at any one time. */
+ size_t max_deferred;
+
+ /* Current count of deferred datagrams. */
+ size_t num_deferred;
+
/*
* List of URXEs which are filled with received encrypted data.
* These are returned to the DEMUX's free list as they are processed.
OSSL_QRX *qrx;
size_t i;
- if (args->demux == NULL)
+ if (args->demux == NULL || args->max_deferred == 0)
return 0;
qrx = OPENSSL_zalloc(sizeof(OSSL_QRX));
qrx->demux = args->demux;
qrx->short_conn_id_len = args->short_conn_id_len;
qrx->init_key_phase_bit = args->init_key_phase_bit;
+ qrx->max_deferred = args->max_deferred;
return qrx;
}
/* Initialize our own fields inside the URXE and add to the pending list. */
urxe->processed = 0;
urxe->hpr_removed = 0;
+ urxe->deferred = 0;
ossl_quic_urxe_insert_tail(&qrx->urx_pending, urxe);
}
* either the free or deferred list.
*/
ossl_quic_urxe_remove(&qrx->urx_pending, e);
- if (was_deferred > 0)
+ if (was_deferred > 0 &&
+ (e->deferred || qrx->num_deferred < qrx->max_deferred)) {
ossl_quic_urxe_insert_tail(&qrx->urx_deferred, e);
- else
+ if (!e->deferred) {
+ e->deferred = 1;
+ ++qrx->num_deferred;
+ }
+ } else {
+ if (e->deferred) {
+ e->deferred = 0;
+ --qrx->num_deferred;
+ }
ossl_quic_demux_release_urxe(qrx->demux, e);
+ }
return 1;
}
NULL)))
return 0;
- s->args.demux = s->demux;
+ s->args.demux = s->demux;
+ s->args.max_deferred = 32;
if (s->qrx == NULL
&& !TEST_ptr(s->qrx = ossl_qrx_new(&s->args)))