Skip to content

Commit 0d6f3cb

Browse files
committed
quic: add various useful common constants and types
For golang/go#58547 Change-Id: I178373329de20fe8e1b3d256638f0ae7ab366d03 Reviewed-on: https://go-review.googlesource.com/c/net/+/475435 Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matt Layher <mdlayher@gmail.com>
1 parent ee6956f commit 0d6f3cb

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

internal/quic/quic.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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+
"time"
9+
)
10+
11+
// connIDLen is the length in bytes of connection IDs chosen by this package.
12+
// Since 1-RTT packets don't include a connection ID length field,
13+
// we use a consistent length for all our IDs.
14+
// https://www.rfc-editor.org/rfc/rfc9000.html#section-5.1-6
15+
const connIDLen = 8
16+
17+
// Local values of various transport parameters.
18+
// https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2
19+
const (
20+
// The max_udp_payload_size transport parameter is the size of our
21+
// network receive buffer.
22+
//
23+
// Set this to the largest UDP packet that can be sent over
24+
// Ethernet without using jumbo frames: 1500 byte Ethernet frame,
25+
// minus 20 byte IPv4 header and 8 byte UDP header.
26+
//
27+
// The maximum possible UDP payload is 65527 bytes. Supporting this
28+
// without wasting memory in unused receive buffers will require some
29+
// care. For now, just limit ourselves to the most common case.
30+
maxUDPPayloadSize = 1472
31+
32+
ackDelayExponent = 3 // ack_delay_exponent
33+
maxAckDelay = 25 * time.Millisecond // max_ack_delay
34+
)
35+
36+
// A side distinguishes between the client and server sides of a connection.
37+
type side int8
38+
39+
const (
40+
clientSide = side(iota)
41+
serverSide
42+
)
43+
44+
func (s side) String() string {
45+
switch s {
46+
case clientSide:
47+
return "client"
48+
case serverSide:
49+
return "server"
50+
default:
51+
return "BUG"
52+
}
53+
}
54+
55+
// A numberSpace is the context in which a packet number applies.
56+
// https://www.rfc-editor.org/rfc/rfc9000.html#section-12.3-7
57+
type numberSpace byte
58+
59+
const (
60+
initialSpace = numberSpace(iota)
61+
handshakeSpace
62+
appDataSpace
63+
)
64+
65+
func (n numberSpace) String() string {
66+
switch n {
67+
case initialSpace:
68+
return "Initial"
69+
case handshakeSpace:
70+
return "Handshake"
71+
case appDataSpace:
72+
return "AppData"
73+
default:
74+
return "BUG"
75+
}
76+
}
77+
78+
// A streamType is the type of a stream: bidirectional or unidirectional.
79+
type streamType uint8
80+
81+
const (
82+
bidiStream = streamType(iota)
83+
uniStream
84+
)
85+
86+
func (s streamType) String() string {
87+
switch s {
88+
case bidiStream:
89+
return "bidi"
90+
case uniStream:
91+
return "uni"
92+
default:
93+
return "BUG"
94+
}
95+
}
96+
97+
// A streamID is a QUIC stream ID.
98+
// https://www.rfc-editor.org/rfc/rfc9000.html#section-2.1
99+
type streamID uint64
100+
101+
// The two least significant bits of a stream ID indicate the initiator
102+
// and directionality of the stream. The upper bits are the stream number.
103+
// Each of the four possible combinations of initiator and direction
104+
// each has a distinct number space.
105+
const (
106+
clientInitiatedStreamBit = 0x0
107+
serverInitiatedStreamBit = 0x1
108+
initiatorStreamBitMask = 0x1
109+
110+
bidiStreamBit = 0x0
111+
uniStreamBit = 0x2
112+
dirStreamBitMask = 0x2
113+
)
114+
115+
func newStreamID(initiator side, typ streamType, num int64) streamID {
116+
id := streamID(num << 2)
117+
if typ == uniStream {
118+
id |= uniStreamBit
119+
}
120+
if initiator == serverSide {
121+
id |= serverInitiatedStreamBit
122+
}
123+
return id
124+
}
125+
126+
func (s streamID) initiator() side {
127+
if s&initiatorStreamBitMask == serverInitiatedStreamBit {
128+
return serverSide
129+
}
130+
return clientSide
131+
}
132+
133+
func (s streamID) num() int64 {
134+
return int64(s) >> 2
135+
}
136+
137+
func (s streamID) streamType() streamType {
138+
if s&dirStreamBitMask == uniStreamBit {
139+
return uniStream
140+
}
141+
return bidiStream
142+
}

0 commit comments

Comments
 (0)