return !ret;
}
-/* Parse <frm> CRYPTO frame coming with <pkt> packet at <qel> <qc> connectionn.
- * Returns 1 if succeeded, 0 if not. Also set <*fast_retrans> to 1 if the
- * speed up handshake completion may be run after having received duplicated
- * CRYPTO data.
+/* Parse <frm> CRYPTO frame coming with <pkt> packet at <qel> <qc> connection.
+ *
+ * Returns 0 on success or a negative error code. A positive value is used to
+ * indicate that the current frame cannot be handled immediately, but it could
+ * be solved by running a new packet parsing iteration.
+ *
+ * Also set <*fast_retrans> as output parameter to 1 if the speed up handshake
+ * completion may be run after having received duplicated CRYPTO data.
*/
-static int qc_handle_crypto_frm(struct quic_conn *qc,
- struct qf_crypto *crypto_frm, struct quic_rx_packet *pkt,
- struct quic_enc_level *qel, int *fast_retrans)
+static enum quic_rx_ret_frm qc_handle_crypto_frm(struct quic_conn *qc,
+ struct qf_crypto *crypto_frm,
+ struct quic_rx_packet *pkt,
+ struct quic_enc_level *qel)
{
- int ret = 0;
enum ncb_ret ncb_ret;
+ enum quic_rx_ret_frm ret = QUIC_RX_RET_FRM_DONE;
/* XXX TO DO: <cfdebug> is used only for the traces. */
struct quic_rx_crypto_frm cfdebug = {
.offset_node.key = crypto_frm->offset,
if (crypto_frm->offset + crypto_frm->len <= cstream->rx.offset) {
/* Nothing to do */
TRACE_PROTO("Already received CRYPTO data",
- QUIC_EV_CONN_RXPKT, qc, pkt, &cfdebug);
- if (qc_is_listener(qc) && qel == qc->iel &&
- !(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP))
- *fast_retrans = 1;
+ QUIC_EV_CONN_RXPKT, qc, pkt, &cfdebug);
+ ret = QUIC_RX_RET_FRM_DUP;
goto done;
}
if (!quic_get_ncbuf(ncbuf) || ncb_is_null(ncbuf)) {
TRACE_ERROR("CRYPTO ncbuf allocation failed", QUIC_EV_CONN_PRSHPKT, qc);
- goto leave;
+ goto err;
}
/* crypto_frm->offset > cstream-trx.offset */
TRACE_ERROR("cannot bufferize frame due to gap size limit",
QUIC_EV_CONN_PRSHPKT, qc);
}
- goto leave;
+ goto err;
}
/* Reschedule with TASK_HEAVY if CRYPTO data ready for decoding. */
}
done:
- ret = 1;
- leave:
TRACE_LEAVE(QUIC_EV_CONN_PRSHPKT, qc);
return ret;
+
+ err:
+ TRACE_DEVEL("leaving on error", QUIC_EV_CONN_PRSHPKT, qc);
+ return QUIC_RX_RET_FRM_FATAL;
}
/* Handle RETIRE_CONNECTION_ID frame from <frm> frame.
{
struct quic_frame *frm = NULL;
const unsigned char *pos, *end;
+ enum quic_rx_ret_frm ret;
int fast_retrans = 0;
TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc);
break;
}
case QUIC_FT_CRYPTO:
- if (!qc_handle_crypto_frm(qc, &frm->crypto, pkt, qel, &fast_retrans))
+ ret = qc_handle_crypto_frm(qc, &frm->crypto, pkt, qel);
+ switch (ret) {
+ case QUIC_RX_RET_FRM_FATAL:
goto err;
+ case QUIC_RX_RET_FRM_DUP:
+ if (qc_is_listener(qc) && qel == qc->iel &&
+ !(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP)) {
+ fast_retrans = 1;
+ }
+ break;
+ case QUIC_RX_RET_FRM_DONE:
+ /* nothing to do here */
+ break;
+ }
break;
case QUIC_FT_NEW_TOKEN:
/* TODO */