MINOR: quic: Anti-amplification implementation

A QUIC server MUST not send more than three times as many bytes as received
by clients before its address validation.
diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h
index be3e8d0..8662945 100644
--- a/include/haproxy/xprt_quic-t.h
+++ b/include/haproxy/xprt_quic-t.h
@@ -606,6 +606,8 @@
 /* Flag the packet number space as requiring an ACK frame to be sent. */
 #define QUIC_FL_PKTNS_ACK_REQUIRED_BIT 0
 #define QUIC_FL_PKTNS_ACK_REQUIRED  (1UL << QUIC_FL_PKTNS_ACK_REQUIRED_BIT)
+
+#define QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED (1UL << 1)
 struct quic_conn {
 	uint32_t version;
 	/* QUIC transport parameters TLS extension */
@@ -650,6 +652,8 @@
 		int rbuf;
 		/* Number of sent bytes. */
 		uint64_t bytes;
+		/* Number of bytes for prepared packets */
+		uint64_t prep_bytes;
 		/* The number of datagrams which may be sent
 		 * when sending probe packets.
 		 */
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 27b67ee..a5740db 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -644,9 +644,14 @@
 		goto out;
 	}
 
-	/* XXX TODO: anti-amplification: the timer must be
+	/* anti-amplification: the timer must be
 	 * cancelled for a server which reached the anti-amplification limit.
 	 */
+	if (qc->flags & QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED) {
+		TRACE_PROTO("anti-amplification reached", QUIC_EV_CONN_STIMER, ctx->conn);
+		qc->timer = TICK_ETERNITY;
+		goto out;
+	}
 
 	if (!qc->path->ifae_pkts && quic_peer_validated_addr(ctx)) {
 		TRACE_PROTO("timer cancellation", QUIC_EV_CONN_STIMER, ctx->conn);
@@ -2204,7 +2209,14 @@
 		if (!prv_pkt) {
 			/* Leave room for the datagram header */
 			pos += dg_headlen;
-			end = pos + qc->path->mtu;
+			if (!quic_peer_validated_addr(ctx) && objt_listener(ctx->conn->target)) {
+				if (qc->tx.prep_bytes >= 3 * qc->rx.bytes)
+					qc->flags |= QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED;
+				end = pos + QUIC_MIN(qc->path->mtu, 3 * qc->rx.bytes - qc->tx.prep_bytes);
+			}
+			else {
+				end = pos + qc->path->mtu;
+			}
 		}
 
 		cur_pkt = qc_build_pkt(&pos, end, qel, qc, dglen, padding,
@@ -4496,6 +4508,7 @@
 		goto err;
 	}
 
+	qc->tx.prep_bytes += pkt->len;
 	/* Now that a correct packet is built, let us consume <*pos> buffer. */
 	*pos = end;
 	/* Attach the built packet to its tree. */