MINOR: quic: Speeding up Handshake Completion

According to RFC 9002 par. 6.2.3. when receving duplicate Initial CRYPTO
data a server may a packet containing non unacknowledged before the PTO
expiry.
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 630f8d1..5d9b82e 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2170,6 +2170,34 @@
 		return qc_handle_bidi_strm_frm(pkt, strm_frm, qc);
 }
 
+/* Prepare a fast retransmission from <qel> encryption level
+ * which must be Initial encryption level.
+ */
+static void qc_prep_fast_retrans(struct quic_enc_level *qel,
+                                 struct quic_conn *qc)
+{
+	struct eb_root *pkts = &qel->pktns->tx.pkts;
+	struct eb64_node *node = eb64_first(pkts);
+	struct quic_tx_packet *pkt;
+	struct quic_frame *frm, *frmbak;
+
+ start:
+	pkts = &qel->pktns->tx.pkts;
+	node = eb64_first(pkts);
+	if (!node)
+		return;
+
+	pkt = eb64_entry(&node->node, struct quic_tx_packet, pn_node);
+	list_for_each_entry_safe(frm, frmbak, &pkt->frms, list)
+		qc_treat_nacked_tx_frm(qc, frm, qel->pktns);
+	if (qel == &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL] &&
+	    qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns->tx.in_flight) {
+		qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns->tx.pto_probe = 1;
+		qel = &qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE];
+		goto start;
+	}
+}
+
 /* Parse all the frames of <pkt> QUIC packet for QUIC connection with <ctx>
  * as I/O handler context and <qel> as encryption level.
  * Returns 1 if succeeded, 0 if failed.
@@ -2180,6 +2208,7 @@
 	struct quic_frame frm;
 	const unsigned char *pos, *end;
 	struct quic_conn *qc = ctx->qc;
+	int fast_retrans = 0;
 
 	TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc);
 	/* Skip the AAD */
@@ -2231,6 +2260,9 @@
 					/* Nothing to do */
 					TRACE_PROTO("Already received CRYPTO data",
 					            QUIC_EV_CONN_ELRXPKTS, qc, pkt, &cfdebug);
+					if (objt_listener(ctx->conn->target) &&
+					    qel == &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL])
+						fast_retrans = 1;
 					break;
 				}
 				else {
@@ -2321,6 +2353,12 @@
 		}
 	}
 
+	if (fast_retrans) {
+		qc_prep_fast_retrans(qel, qc);
+		if (qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns->tx.in_flight)
+			qc_prep_fast_retrans(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE], qc);
+	}
+
 	/* The server must switch from INITIAL to HANDSHAKE handshake state when it
 	 * has successfully parse a Handshake packet. The Initial encryption must also
 	 * be discarded.