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.
This commit is contained in:
Frédéric Lécaille 2021-11-10 17:30:15 +01:00
parent a956d15118
commit ca98a7f9c0
2 changed files with 19 additions and 2 deletions

View File

@ -606,6 +606,8 @@ struct rxbuf {
/* Flag the packet number space as requiring an ACK frame to be sent. */ /* 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_BIT 0
#define QUIC_FL_PKTNS_ACK_REQUIRED (1UL << QUIC_FL_PKTNS_ACK_REQUIRED_BIT) #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 { struct quic_conn {
uint32_t version; uint32_t version;
/* QUIC transport parameters TLS extension */ /* QUIC transport parameters TLS extension */
@ -650,6 +652,8 @@ struct quic_conn {
int rbuf; int rbuf;
/* Number of sent bytes. */ /* Number of sent bytes. */
uint64_t bytes; uint64_t bytes;
/* Number of bytes for prepared packets */
uint64_t prep_bytes;
/* The number of datagrams which may be sent /* The number of datagrams which may be sent
* when sending probe packets. * when sending probe packets.
*/ */

View File

@ -644,9 +644,14 @@ static inline void qc_set_timer(struct ssl_sock_ctx *ctx)
goto out; 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. * 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)) { if (!qc->path->ifae_pkts && quic_peer_validated_addr(ctx)) {
TRACE_PROTO("timer cancellation", QUIC_EV_CONN_STIMER, ctx->conn); TRACE_PROTO("timer cancellation", QUIC_EV_CONN_STIMER, ctx->conn);
@ -2204,7 +2209,14 @@ static int qc_prep_hdshk_pkts(struct qring *qr, struct ssl_sock_ctx *ctx)
if (!prv_pkt) { if (!prv_pkt) {
/* Leave room for the datagram header */ /* Leave room for the datagram header */
pos += dg_headlen; 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, cur_pkt = qc_build_pkt(&pos, end, qel, qc, dglen, padding,
@ -4496,6 +4508,7 @@ static struct quic_tx_packet *qc_build_pkt(unsigned char **pos,
goto err; goto err;
} }
qc->tx.prep_bytes += pkt->len;
/* Now that a correct packet is built, let us consume <*pos> buffer. */ /* Now that a correct packet is built, let us consume <*pos> buffer. */
*pos = end; *pos = end;
/* Attach the built packet to its tree. */ /* Attach the built packet to its tree. */