MINOR: quic: Make xprt support 0-RTT.

A client sends a 0-RTT data packet after an Initial one in the same datagram.
We must be able to parse such packets just after having parsed the Initial packets.
diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h
index 47946cc..209576a 100644
--- a/include/haproxy/quic_tls.h
+++ b/include/haproxy/quic_tls.h
@@ -423,13 +423,16 @@
 /* Set <*level> and <*next_level> depending on <state> QUIC handshake state. */
 static inline int quic_get_tls_enc_levels(enum quic_tls_enc_level *level,
                                           enum quic_tls_enc_level *next_level,
-                                          enum quic_handshake_state state)
+                                          enum quic_handshake_state state, int zero_rtt)
 {
 	switch (state) {
 	case QUIC_HS_ST_SERVER_INITIAL:
 	case QUIC_HS_ST_CLIENT_INITIAL:
 		*level = QUIC_TLS_ENC_LEVEL_INITIAL;
-		*next_level = QUIC_TLS_ENC_LEVEL_HANDSHAKE;
+		if (zero_rtt)
+			*next_level = QUIC_TLS_ENC_LEVEL_EARLY_DATA;
+		else
+			*next_level = QUIC_TLS_ENC_LEVEL_HANDSHAKE;
 		break;
 	case QUIC_HS_ST_SERVER_HANDSHAKE:
 	case QUIC_HS_ST_CLIENT_HANDSHAKE:
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index b4669db..0dfd108 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2415,7 +2415,7 @@
 
 	TRACE_ENTER(QUIC_EV_CONN_PHPKTS, ctx->conn);
 	qc = ctx->conn->qc;
-	if (!quic_get_tls_enc_levels(&tel, &next_tel, HA_ATOMIC_LOAD(&qc->state))) {
+	if (!quic_get_tls_enc_levels(&tel, &next_tel, HA_ATOMIC_LOAD(&qc->state), 0)) {
 		TRACE_DEVEL("unknown enc. levels", QUIC_EV_CONN_PHPKTS, ctx->conn);
 		goto err;
 	}
@@ -3082,7 +3082,7 @@
 	struct quic_enc_level *qel, *next_qel;
 	struct quic_tls_ctx *tls_ctx;
 	struct qring *qr; // Tx ring
-	int prev_st, st, force_ack;
+	int prev_st, st, force_ack, zero_rtt;
 
 	ctx = context;
 	qc = ctx->conn->qc;
@@ -3090,8 +3090,9 @@
 	st = HA_ATOMIC_LOAD(&qc->state);
 	TRACE_ENTER(QUIC_EV_CONN_HDSHK, ctx->conn, &st);
 	ssl_err = SSL_ERROR_NONE;
+	zero_rtt = !MT_LIST_ISEMPTY(&qc->els[QUIC_TLS_ENC_LEVEL_EARLY_DATA].rx.pqpkts);
  start:
-	if (!quic_get_tls_enc_levels(&tel, &next_tel, st))
+	if (!quic_get_tls_enc_levels(&tel, &next_tel, st, zero_rtt))
 		goto err;
 
 	qel = &qc->els[tel];
@@ -3113,6 +3114,13 @@
 	if (!qc_treat_rx_pkts(qel, next_qel, ctx, force_ack))
 		goto err;
 
+	if (zero_rtt && next_qel && !MT_LIST_ISEMPTY(&next_qel->rx.pqpkts) &&
+	    (next_qel->tls_ctx.rx.flags & QUIC_FL_TLS_SECRETS_SET)) {
+		qel = next_qel;
+		next_qel = NULL;
+		goto next_level;
+	}
+
 	st = HA_ATOMIC_LOAD(&qc->state);
 	if (st >= QUIC_HS_ST_COMPLETE &&
 	    (prev_st == QUIC_HS_ST_SERVER_INITIAL || prev_st == QUIC_HS_ST_SERVER_HANDSHAKE)) {
@@ -3466,7 +3474,9 @@
 		/* Check that the length of this received DCID matches the CID lengths
 		 * of our implementation for non Initials packets only.
 		 */
-		if (pkt->type != QUIC_PACKET_TYPE_INITIAL && dcid_len != QUIC_CID_LEN)
+		if (pkt->type != QUIC_PACKET_TYPE_INITIAL &&
+		    pkt->type != QUIC_PACKET_TYPE_0RTT &&
+		    dcid_len != QUIC_CID_LEN)
 			return 0;
 
 		memcpy(pkt->dcid.data, *buf, dcid_len);
@@ -3929,7 +3939,8 @@
 		/* For Initial packets, and for servers (QUIC clients connections),
 		 * there is no Initial connection IDs storage.
 		 */
-		if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
+		if (pkt->type == QUIC_PACKET_TYPE_INITIAL ||
+		    pkt->type == QUIC_PACKET_TYPE_0RTT) {
 			uint64_t token_len;
 			/* DCIDs of first packets coming from clients may have the same values.
 			 * Let's distinguish them concatenating the socket addresses to the DCIDs.
@@ -3937,20 +3948,22 @@
 			quic_cid_saddr_cat(&pkt->dcid, saddr);
 			cids = &l->rx.odcids;
 
-			if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) ||
-			    end - *buf < token_len) {
-				TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
-				goto err;
-			}
+			if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
+				if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) ||
+					end - *buf < token_len) {
+					TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
+					goto err;
+				}
 
-			/* XXX TO DO XXX 0 value means "the token is not present".
-			 * A server which sends an Initial packet must not set the token.
-			 * So, a client which receives an Initial packet with a token
-			 * MUST discard the packet or generate a connection error with
-			 * PROTOCOL_VIOLATION as type.
-			 * The token must be provided in a Retry packet or NEW_TOKEN frame.
-			 */
-			pkt->token_len = token_len;
+				/* XXX TO DO XXX 0 value means "the token is not present".
+				 * A server which sends an Initial packet must not set the token.
+				 * So, a client which receives an Initial packet with a token
+				 * MUST discard the packet or generate a connection error with
+				 * PROTOCOL_VIOLATION as type.
+				 * The token must be provided in a Retry packet or NEW_TOKEN frame.
+				 */
+				pkt->token_len = token_len;
+			}
 		}
 		else {
 			if (pkt->dcid.len != QUIC_CID_LEN) {
@@ -4069,7 +4082,8 @@
 			node = &qc->odcid_node;
 		}
 		else {
-			if (pkt->type == QUIC_PACKET_TYPE_INITIAL && cids == &l->rx.odcids) {
+			if ((pkt->type == QUIC_PACKET_TYPE_INITIAL ||
+			     pkt->type == QUIC_PACKET_TYPE_0RTT) && cids == &l->rx.odcids) {
 				qc = ebmb_entry(node, struct quic_conn, odcid_node);
 			}
 			else {