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 }