14
errPacketNumberLenNotSet = errors.New("PublicHeader: PacketNumberLen not set")
15
errResetAndVersionFlagSet = errors.New("PublicHeader: Reset Flag and Version Flag should not be set at the same time")
16
errReceivedTruncatedConnectionID = qerr.Error(qerr.InvalidPacketHeader, "receiving packets with truncated ConnectionID is not supported")
17
errInvalidConnectionID = qerr.Error(qerr.InvalidPacketHeader, "connection ID cannot be 0")
18
errGetLengthOnlyForRegularPackets = errors.New("PublicHeader: GetLength can only be called for regular packets")
13
errPacketNumberLenNotSet = errors.New("PublicHeader: PacketNumberLen not set")
14
errResetAndVersionFlagSet = errors.New("PublicHeader: Reset Flag and Version Flag should not be set at the same time")
15
errReceivedTruncatedConnectionID = qerr.Error(qerr.InvalidPacketHeader, "receiving packets with truncated ConnectionID is not supported")
16
errInvalidConnectionID = qerr.Error(qerr.InvalidPacketHeader, "connection ID cannot be 0")
17
errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets")
21
20
// The PublicHeader of a QUIC packet
27
26
TruncateConnectionID bool
28
27
PacketNumberLen protocol.PacketNumberLen
29
28
PacketNumber protocol.PacketNumber
30
VersionNumber protocol.VersionNumber
29
VersionNumber protocol.VersionNumber // VersionNumber sent by the client
30
SupportedVersions []protocol.VersionNumber // VersionNumbers sent by the server
31
31
DiversificationNonce []byte
34
34
// Write writes a public header
35
func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber) error {
35
func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pers protocol.Perspective) error {
36
36
publicFlagByte := uint8(0x00)
37
38
if h.VersionFlag && h.ResetFlag {
38
39
return errResetAndVersionFlagSet
41
43
publicFlagByte |= 0x01
73
76
utils.WriteUint64(b, uint64(h.ConnectionID))
79
if h.VersionFlag && pers == protocol.PerspectiveClient {
80
utils.WriteUint32(b, protocol.VersionNumberToTag(h.VersionNumber))
76
83
if len(h.DiversificationNonce) > 0 {
77
84
b.Write(h.DiversificationNonce)
80
if !h.ResetFlag && !h.VersionFlag {
81
switch h.PacketNumberLen {
82
case protocol.PacketNumberLen1:
83
b.WriteByte(uint8(h.PacketNumber))
84
case protocol.PacketNumberLen2:
85
utils.WriteUint16(b, uint16(h.PacketNumber))
86
case protocol.PacketNumberLen4:
87
utils.WriteUint32(b, uint32(h.PacketNumber))
88
case protocol.PacketNumberLen6:
89
utils.WriteUint48(b, uint64(h.PacketNumber))
91
return errPacketNumberLenNotSet
87
// if we're a server, and the VersionFlag is set, we must not include anything else in the packet
88
if !h.hasPacketNumber(pers) {
92
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
93
return errPacketNumberLenNotSet
96
switch h.PacketNumberLen {
97
case protocol.PacketNumberLen1:
98
b.WriteByte(uint8(h.PacketNumber))
99
case protocol.PacketNumberLen2:
100
utils.WriteUint16(b, uint16(h.PacketNumber))
101
case protocol.PacketNumberLen4:
102
utils.WriteUint32(b, uint32(h.PacketNumber))
103
case protocol.PacketNumberLen6:
104
utils.WriteUint48(b, uint64(h.PacketNumber))
106
return errPacketNumberLenNotSet
98
112
// ParsePublicHeader parses a QUIC packet's public header
99
func ParsePublicHeader(b io.ByteReader) (*PublicHeader, error) {
113
// the packetSentBy is the perspective of the peer that sent this PublicHeader, i.e. if we're the server, packetSentBy should be PerspectiveClient
114
func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*PublicHeader, error) {
100
115
header := &PublicHeader{}
117
132
return nil, errReceivedTruncatedConnectionID
120
switch publicFlagByte & 0x30 {
122
header.PacketNumberLen = protocol.PacketNumberLen6
124
header.PacketNumberLen = protocol.PacketNumberLen4
126
header.PacketNumberLen = protocol.PacketNumberLen2
128
header.PacketNumberLen = protocol.PacketNumberLen1
135
if header.hasPacketNumber(packetSentBy) {
136
switch publicFlagByte & 0x30 {
138
header.PacketNumberLen = protocol.PacketNumberLen6
140
header.PacketNumberLen = protocol.PacketNumberLen4
142
header.PacketNumberLen = protocol.PacketNumberLen2
144
header.PacketNumberLen = protocol.PacketNumberLen1
136
154
header.ConnectionID = protocol.ConnectionID(connID)
137
155
if header.ConnectionID == 0 {
138
156
return nil, errInvalidConnectionID
159
if packetSentBy == protocol.PerspectiveServer && publicFlagByte&0x04 > 0 {
160
// TODO: remove the if once the Google servers send the correct value
161
// assume that a packet doesn't contain a diversification nonce if the version flag or the reset flag is set, no matter what the public flag says
162
// see https://github.com/lucas-clemente/quic-go/issues/232
163
if !header.VersionFlag && !header.ResetFlag {
164
header.DiversificationNonce = make([]byte, 32)
165
// this Read can never return an EOF for a valid packet, since the diversification nonce is followed by the packet number
166
_, err = b.Read(header.DiversificationNonce)
141
173
// Version (optional)
142
if header.VersionFlag {
143
var versionTag uint32
144
versionTag, err = utils.ReadUint32(b)
174
if !header.ResetFlag {
175
if header.VersionFlag {
176
if packetSentBy == protocol.PerspectiveClient {
177
var versionTag uint32
178
versionTag, err = utils.ReadUint32(b)
182
header.VersionNumber = protocol.VersionTagToNumber(versionTag)
183
} else { // parse the version negotiaton packet
185
return nil, qerr.InvalidVersionNegotiationPacket
187
header.SupportedVersions = make([]protocol.VersionNumber, 0)
189
var versionTag uint32
190
versionTag, err = utils.ReadUint32(b)
194
v := protocol.VersionTagToNumber(versionTag)
195
if !protocol.IsSupportedVersion(v) {
196
v = protocol.VersionUnsupported
198
header.SupportedVersions = append(header.SupportedVersions, v)
205
if header.hasPacketNumber(packetSentBy) {
206
packetNumber, err := utils.ReadUintN(b, uint8(header.PacketNumberLen))
148
header.VersionNumber = protocol.VersionTagToNumber(versionTag)
152
packetNumber, err := utils.ReadUintN(b, uint8(header.PacketNumberLen))
156
header.PacketNumber = protocol.PacketNumber(packetNumber)
210
header.PacketNumber = protocol.PacketNumber(packetNumber)
158
213
return header, nil
161
216
// GetLength gets the length of the publicHeader in bytes
162
217
// can only be called for regular packets
163
func (h *PublicHeader) GetLength() (protocol.ByteCount, error) {
164
if h.VersionFlag || h.ResetFlag {
165
return 0, errGetLengthOnlyForRegularPackets
218
func (h *PublicHeader) GetLength(pers protocol.Perspective) (protocol.ByteCount, error) {
219
if h.VersionFlag && h.ResetFlag {
220
return 0, errResetAndVersionFlagSet
223
if h.VersionFlag && pers == protocol.PerspectiveServer {
224
return 0, errGetLengthNotForVersionNegotiation
168
227
length := protocol.ByteCount(1) // 1 byte for public flags
169
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
170
return 0, errPacketNumberLenNotSet
229
if h.hasPacketNumber(pers) {
230
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
231
return 0, errPacketNumberLenNotSet
233
length += protocol.ByteCount(h.PacketNumberLen)
172
236
if !h.TruncateConnectionID {
173
237
length += 8 // 8 bytes for the connection ID
240
// Version Number in packets sent by the client
175
245
length += protocol.ByteCount(len(h.DiversificationNonce))
176
length += protocol.ByteCount(h.PacketNumberLen)
177
247
return length, nil
250
// hasPacketNumber determines if this PublicHeader will contain a packet number
251
// this depends on the ResetFlag, the VersionFlag and who sent the packet
252
func (h *PublicHeader) hasPacketNumber(packetSentBy protocol.Perspective) bool {
256
if h.VersionFlag && packetSentBy == protocol.PerspectiveServer {