-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathsent_packet.go
119 lines (96 loc) · 3 KB
/
sent_packet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quic
import (
"sync"
"time"
"golang.org/x/net/internal/quic/quicwire"
)
// A sentPacket tracks state related to an in-flight packet we sent,
// to be committed when the peer acks it or resent if the packet is lost.
type sentPacket struct {
num packetNumber
size int // size in bytes
time time.Time // time sent
ptype packetType
state sentPacketState
ackEliciting bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.4.1
inFlight bool // https://www.rfc-editor.org/rfc/rfc9002.html#section-2-3.6.1
// Frames sent in the packet.
//
// This is an abbreviated version of the packet payload, containing only the information
// we need to process an ack for or loss of this packet.
// For example, a CRYPTO frame is recorded as the frame type (0x06), offset, and length,
// but does not include the sent data.
//
// This buffer is written by packetWriter.append* and read by Conn.handleAckOrLoss.
b []byte
n int // read offset into b
}
type sentPacketState uint8
const (
sentPacketSent = sentPacketState(iota) // sent but neither acked nor lost
sentPacketAcked // acked
sentPacketLost // declared lost
sentPacketUnsent // never sent
)
var sentPool = sync.Pool{
New: func() any {
return &sentPacket{}
},
}
func newSentPacket() *sentPacket {
sent := sentPool.Get().(*sentPacket)
sent.reset()
return sent
}
// recycle returns a sentPacket to the pool.
func (sent *sentPacket) recycle() {
sentPool.Put(sent)
}
func (sent *sentPacket) reset() {
*sent = sentPacket{
b: sent.b[:0],
}
}
// markAckEliciting marks the packet as containing an ack-eliciting frame.
func (sent *sentPacket) markAckEliciting() {
sent.ackEliciting = true
sent.inFlight = true
}
// The append* methods record information about frames in the packet.
func (sent *sentPacket) appendNonAckElicitingFrame(frameType byte) {
sent.b = append(sent.b, frameType)
}
func (sent *sentPacket) appendAckElicitingFrame(frameType byte) {
sent.ackEliciting = true
sent.inFlight = true
sent.b = append(sent.b, frameType)
}
func (sent *sentPacket) appendInt(v uint64) {
sent.b = quicwire.AppendVarint(sent.b, v)
}
func (sent *sentPacket) appendOffAndSize(start int64, size int) {
sent.b = quicwire.AppendVarint(sent.b, uint64(start))
sent.b = quicwire.AppendVarint(sent.b, uint64(size))
}
// The next* methods read back information about frames in the packet.
func (sent *sentPacket) next() (frameType byte) {
f := sent.b[sent.n]
sent.n++
return f
}
func (sent *sentPacket) nextInt() uint64 {
v, n := quicwire.ConsumeVarint(sent.b[sent.n:])
sent.n += n
return v
}
func (sent *sentPacket) nextRange() (start, end int64) {
start = int64(sent.nextInt())
end = start + int64(sent.nextInt())
return start, end
}
func (sent *sentPacket) done() bool {
return sent.n == len(sent.b)
}