golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/sent_packet.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  import (
    10  	"sync"
    11  	"time"
    12  )
    13  
    14  // A sentPacket tracks state related to an in-flight packet we sent,
    15  // to be committed when the peer acks it or resent if the packet is lost.
    16  type sentPacket struct {
    17  	num   packetNumber
    18  	size  int       // size in bytes
    19  	time  time.Time // time sent
    20  	ptype packetType
    21  
    22  	ackEliciting bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.4.1
    23  	inFlight     bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.6.1
    24  	acked        bool // ack has been received
    25  	lost         bool // packet is presumed lost
    26  
    27  	// Frames sent in the packet.
    28  	//
    29  	// This is an abbreviated version of the packet payload, containing only the information
    30  	// we need to process an ack for or loss of this packet.
    31  	// For example, a CRYPTO frame is recorded as the frame type (0x06), offset, and length,
    32  	// but does not include the sent data.
    33  	//
    34  	// This buffer is written by packetWriter.append* and read by Conn.handleAckOrLoss.
    35  	b []byte
    36  	n int // read offset into b
    37  }
    38  
    39  var sentPool = sync.Pool{
    40  	New: func() any {
    41  		return &sentPacket{}
    42  	},
    43  }
    44  
    45  func newSentPacket() *sentPacket {
    46  	sent := sentPool.Get().(*sentPacket)
    47  	sent.reset()
    48  	return sent
    49  }
    50  
    51  // recycle returns a sentPacket to the pool.
    52  func (sent *sentPacket) recycle() {
    53  	sentPool.Put(sent)
    54  }
    55  
    56  func (sent *sentPacket) reset() {
    57  	*sent = sentPacket{
    58  		b: sent.b[:0],
    59  	}
    60  }
    61  
    62  // markAckEliciting marks the packet as containing an ack-eliciting frame.
    63  func (sent *sentPacket) markAckEliciting() {
    64  	sent.ackEliciting = true
    65  	sent.inFlight = true
    66  }
    67  
    68  // The append* methods record information about frames in the packet.
    69  
    70  func (sent *sentPacket) appendNonAckElicitingFrame(frameType byte) {
    71  	sent.b = append(sent.b, frameType)
    72  }
    73  
    74  func (sent *sentPacket) appendAckElicitingFrame(frameType byte) {
    75  	sent.ackEliciting = true
    76  	sent.inFlight = true
    77  	sent.b = append(sent.b, frameType)
    78  }
    79  
    80  func (sent *sentPacket) appendInt(v uint64) {
    81  	sent.b = appendVarint(sent.b, v)
    82  }
    83  
    84  func (sent *sentPacket) appendOffAndSize(start int64, size int) {
    85  	sent.b = appendVarint(sent.b, uint64(start))
    86  	sent.b = appendVarint(sent.b, uint64(size))
    87  }
    88  
    89  // The next* methods read back information about frames in the packet.
    90  
    91  func (sent *sentPacket) next() (frameType byte) {
    92  	f := sent.b[sent.n]
    93  	sent.n++
    94  	return f
    95  }
    96  
    97  func (sent *sentPacket) nextInt() uint64 {
    98  	v, n := consumeVarint(sent.b[sent.n:])
    99  	sent.n += n
   100  	return v
   101  }
   102  
   103  func (sent *sentPacket) nextRange() (start, end int64) {
   104  	start = int64(sent.nextInt())
   105  	end = start + int64(sent.nextInt())
   106  	return start, end
   107  }
   108  
   109  func (sent *sentPacket) done() bool {
   110  	return sent.n == len(sent.b)
   111  }