Source file src/vendor/golang.org/x/net/quic/sent_packet.go

     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  package quic
     6  
     7  import (
     8  	"sync"
     9  	"time"
    10  
    11  	"golang.org/x/net/internal/quic/quicwire"
    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  	state        sentPacketState
    23  	ackEliciting bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.4.1
    24  	inFlight     bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.6.1
    25  
    26  	// Frames sent in the packet.
    27  	//
    28  	// This is an abbreviated version of the packet payload, containing only the information
    29  	// we need to process an ack for or loss of this packet.
    30  	// For example, a CRYPTO frame is recorded as the frame type (0x06), offset, and length,
    31  	// but does not include the sent data.
    32  	//
    33  	// This buffer is written by packetWriter.append* and read by Conn.handleAckOrLoss.
    34  	b []byte
    35  	n int // read offset into b
    36  }
    37  
    38  type sentPacketState uint8
    39  
    40  const (
    41  	sentPacketSent   = sentPacketState(iota) // sent but neither acked nor lost
    42  	sentPacketAcked                          // acked
    43  	sentPacketLost                           // declared lost
    44  	sentPacketUnsent                         // never sent
    45  )
    46  
    47  var sentPool = sync.Pool{
    48  	New: func() any {
    49  		return &sentPacket{}
    50  	},
    51  }
    52  
    53  func newSentPacket() *sentPacket {
    54  	sent := sentPool.Get().(*sentPacket)
    55  	sent.reset()
    56  	return sent
    57  }
    58  
    59  // recycle returns a sentPacket to the pool.
    60  func (sent *sentPacket) recycle() {
    61  	sentPool.Put(sent)
    62  }
    63  
    64  func (sent *sentPacket) reset() {
    65  	*sent = sentPacket{
    66  		b: sent.b[:0],
    67  	}
    68  }
    69  
    70  // markAckEliciting marks the packet as containing an ack-eliciting frame.
    71  func (sent *sentPacket) markAckEliciting() {
    72  	sent.ackEliciting = true
    73  	sent.inFlight = true
    74  }
    75  
    76  // The append* methods record information about frames in the packet.
    77  
    78  func (sent *sentPacket) appendNonAckElicitingFrame(frameType byte) {
    79  	sent.b = append(sent.b, frameType)
    80  }
    81  
    82  func (sent *sentPacket) appendAckElicitingFrame(frameType byte) {
    83  	sent.ackEliciting = true
    84  	sent.inFlight = true
    85  	sent.b = append(sent.b, frameType)
    86  }
    87  
    88  func (sent *sentPacket) appendInt(v uint64) {
    89  	sent.b = quicwire.AppendVarint(sent.b, v)
    90  }
    91  
    92  func (sent *sentPacket) appendOffAndSize(start int64, size int) {
    93  	sent.b = quicwire.AppendVarint(sent.b, uint64(start))
    94  	sent.b = quicwire.AppendVarint(sent.b, uint64(size))
    95  }
    96  
    97  // The next* methods read back information about frames in the packet.
    98  
    99  func (sent *sentPacket) next() (frameType byte) {
   100  	f := sent.b[sent.n]
   101  	sent.n++
   102  	return f
   103  }
   104  
   105  func (sent *sentPacket) nextInt() uint64 {
   106  	v, n := quicwire.ConsumeVarint(sent.b[sent.n:])
   107  	sent.n += n
   108  	return v
   109  }
   110  
   111  func (sent *sentPacket) nextRange() (start, end int64) {
   112  	start = int64(sent.nextInt())
   113  	end = start + int64(sent.nextInt())
   114  	return start, end
   115  }
   116  
   117  func (sent *sentPacket) done() bool {
   118  	return sent.n == len(sent.b)
   119  }
   120  

View as plain text