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 }