golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/sent_val.go (about) 1 // Copyright 2023 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 //go:build go1.21 6 7 package quic 8 9 // A sentVal tracks sending some piece of information to the peer. 10 // It tracks whether the information has been sent, acked, and 11 // (when in-flight) the most recent packet to carry it. 12 // 13 // For example, a sentVal can track sending of a RESET_STREAM frame. 14 // 15 // - unset: stream is active, no need to send RESET_STREAM 16 // - unsent: we should send a RESET_STREAM, but have not yet 17 // - sent: we have sent a RESET_STREAM, but have not received an ack 18 // - received: we have sent a RESET_STREAM, and the peer has acked the packet that contained it 19 // 20 // In the "sent" state, a sentVal also tracks the latest packet number to carry 21 // the information. (QUIC packet numbers are always at most 62 bits in size, 22 // so the sentVal keeps the number in the low 62 bits and the state in the high 2 bits.) 23 type sentVal uint64 24 25 const ( 26 sentValUnset = 0 // unset 27 sentValUnsent = 1 << 62 // set, not sent to the peer 28 sentValSent = 2 << 62 // set, sent to the peer but not yet acked; pnum is set 29 sentValReceived = 3 << 62 // set, peer acked receipt 30 31 sentValStateMask = 3 << 62 32 ) 33 34 // isSet reports whether the value is set. 35 func (s sentVal) isSet() bool { return s != 0 } 36 37 // shouldSend reports whether the value is set and has not been sent to the peer. 38 func (s sentVal) shouldSend() bool { return s.state() == sentValUnsent } 39 40 // shouldSend reports whether the value needs to be sent to the peer. 41 // The value needs to be sent if it is set and has not been sent. 42 // If pto is true, indicating that we are sending a PTO probe, the value 43 // should also be sent if it is set and has not been acknowledged. 44 func (s sentVal) shouldSendPTO(pto bool) bool { 45 st := s.state() 46 return st == sentValUnsent || (pto && st == sentValSent) 47 } 48 49 // isReceived reports whether the value has been received by the peer. 50 func (s sentVal) isReceived() bool { return s == sentValReceived } 51 52 // set sets the value and records that it should be sent to the peer. 53 // If the value has already been sent, it is not resent. 54 func (s *sentVal) set() { 55 if *s == 0 { 56 *s = sentValUnsent 57 } 58 } 59 60 // reset sets the value to the unsent state. 61 func (s *sentVal) setUnsent() { *s = sentValUnsent } 62 63 // clear sets the value to the unset state. 64 func (s *sentVal) clear() { *s = sentValUnset } 65 66 // setSent sets the value to the send state and records the number of the most recent 67 // packet containing the value. 68 func (s *sentVal) setSent(pnum packetNumber) { 69 *s = sentValSent | sentVal(pnum) 70 } 71 72 // setReceived sets the value to the received state. 73 func (s *sentVal) setReceived() { *s = sentValReceived } 74 75 // ackOrLoss reports that an acknowledgement has been received for the value, 76 // or that the packet carrying the value has been lost. 77 func (s *sentVal) ackOrLoss(pnum packetNumber, fate packetFate) { 78 if fate == packetAcked { 79 *s = sentValReceived 80 } else if *s == sentVal(pnum)|sentValSent { 81 *s = sentValUnsent 82 } 83 } 84 85 // ackLatestOrLoss reports that an acknowledgement has been received for the value, 86 // or that the packet carrying the value has been lost. 87 // The value is set to the acked state only if pnum is the latest packet containing it. 88 // 89 // We use this to handle acks for data that varies every time it is sent. 90 // For example, if we send a MAX_DATA frame followed by an updated MAX_DATA value in a 91 // second packet, we consider the data sent only upon receiving an ack for the most 92 // recent value. 93 func (s *sentVal) ackLatestOrLoss(pnum packetNumber, fate packetFate) { 94 if fate == packetAcked { 95 if *s == sentVal(pnum)|sentValSent { 96 *s = sentValReceived 97 } 98 } else { 99 if *s == sentVal(pnum)|sentValSent { 100 *s = sentValUnsent 101 } 102 } 103 } 104 105 func (s sentVal) state() uint64 { return uint64(s) & sentValStateMask }