Source file src/vendor/golang.org/x/net/quic/skip.go
1 // Copyright 2025 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package quic 6 7 // skipState is state for optimistic ACK defenses. 8 // 9 // An endpoint performs an optimistic ACK attack by sending acknowledgements for packets 10 // which it has not received, potentially convincing the sender's congestion controller to 11 // send at rates beyond what the network supports. 12 // 13 // We defend against this by periodically skipping packet numbers. 14 // Receiving an ACK for an unsent packet number is a PROTOCOL_VIOLATION error. 15 // 16 // We only skip packet numbers in the Application Data number space. 17 // The total data sent in the Initial/Handshake spaces should generally fit into 18 // the initial congestion window. 19 // 20 // https://www.rfc-editor.org/rfc/rfc9000.html#section-21.4 21 type skipState struct { 22 // skip is the next packet number (in the Application Data space) we should skip. 23 skip packetNumber 24 25 // maxSkip is the maximum number of packets to send before skipping another number. 26 // Increases over time. 27 maxSkip int64 28 } 29 30 func (ss *skipState) init(c *Conn) { 31 ss.maxSkip = 256 // skip our first packet number within this range 32 ss.updateNumberSkip(c) 33 } 34 35 // shouldSkip returns whether we should skip the given packet number. 36 func (ss *skipState) shouldSkip(num packetNumber) bool { 37 return ss.skip == num 38 } 39 40 // updateNumberSkip schedules a packet to be skipped after skipping lastSkipped. 41 func (ss *skipState) updateNumberSkip(c *Conn) { 42 // Send at least this many packets before skipping. 43 // Limits the impact of skipping a little, 44 // plus allows most tests to ignore skipping. 45 const minSkip = 64 46 47 skip := minSkip + c.prng.Int64N(ss.maxSkip-minSkip) 48 ss.skip += packetNumber(skip) 49 50 // Double the size of the skip each time until we reach 128k. 51 // The idea here is that an attacker needs to correctly ack ~N packets in order 52 // to send an optimistic ack for another ~N packets. 53 // Skipping packet numbers comes with a small cost (it causes the receiver to 54 // send an immediate ACK rather than the usual delayed ACK), so we increase the 55 // time between skips as a connection's lifetime grows. 56 // 57 // The 128k cap is arbitrary, chosen so that we skip a packet number 58 // about once a second when sending full-size datagrams at 1Gbps. 59 if ss.maxSkip < 128*1024 { 60 ss.maxSkip *= 2 61 } 62 } 63