~hduran-8/+junk/caddy

« back to all changes in this revision

Viewing changes to debian/gocode/src/github.com/lucas-clemente/quic-go/public_header.go

  • Committer: Horacio Durán
  • Date: 2017-01-20 16:21:20 UTC
  • Revision ID: horacio.duran@canonical.com-20170120162120-l82mfqwmsclnk838
Upgrade to 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
import (
4
4
        "bytes"
5
5
        "errors"
6
 
        "io"
7
6
 
8
7
        "github.com/lucas-clemente/quic-go/protocol"
9
8
        "github.com/lucas-clemente/quic-go/qerr"
11
10
)
12
11
 
13
12
var (
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")
19
18
)
20
19
 
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
32
32
}
33
33
 
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
 
37
38
        if h.VersionFlag && h.ResetFlag {
38
39
                return errResetAndVersionFlagSet
39
40
        }
 
41
 
40
42
        if h.VersionFlag {
41
43
                publicFlagByte |= 0x01
42
44
        }
54
56
                publicFlagByte |= 0x04
55
57
        }
56
58
 
57
 
        if !h.ResetFlag && !h.VersionFlag {
 
59
        // only set PacketNumberLen bits if a packet number will be written
 
60
        if h.hasPacketNumber(pers) {
58
61
                switch h.PacketNumberLen {
59
62
                case protocol.PacketNumberLen1:
60
63
                        publicFlagByte |= 0x00
73
76
                utils.WriteUint64(b, uint64(h.ConnectionID))
74
77
        }
75
78
 
 
79
        if h.VersionFlag && pers == protocol.PerspectiveClient {
 
80
                utils.WriteUint32(b, protocol.VersionNumberToTag(h.VersionNumber))
 
81
        }
 
82
 
76
83
        if len(h.DiversificationNonce) > 0 {
77
84
                b.Write(h.DiversificationNonce)
78
85
        }
79
86
 
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))
90
 
                default:
91
 
                        return errPacketNumberLenNotSet
92
 
                }
 
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) {
 
89
                return nil
 
90
        }
 
91
 
 
92
        if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
 
93
                return errPacketNumberLenNotSet
 
94
        }
 
95
 
 
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))
 
105
        default:
 
106
                return errPacketNumberLenNotSet
93
107
        }
94
108
 
95
109
        return nil
96
110
}
97
111
 
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{}
101
116
 
102
117
        // First byte
117
132
                return nil, errReceivedTruncatedConnectionID
118
133
        }
119
134
 
120
 
        switch publicFlagByte & 0x30 {
121
 
        case 0x30:
122
 
                header.PacketNumberLen = protocol.PacketNumberLen6
123
 
        case 0x20:
124
 
                header.PacketNumberLen = protocol.PacketNumberLen4
125
 
        case 0x10:
126
 
                header.PacketNumberLen = protocol.PacketNumberLen2
127
 
        case 0x00:
128
 
                header.PacketNumberLen = protocol.PacketNumberLen1
 
135
        if header.hasPacketNumber(packetSentBy) {
 
136
                switch publicFlagByte & 0x30 {
 
137
                case 0x30:
 
138
                        header.PacketNumberLen = protocol.PacketNumberLen6
 
139
                case 0x20:
 
140
                        header.PacketNumberLen = protocol.PacketNumberLen4
 
141
                case 0x10:
 
142
                        header.PacketNumberLen = protocol.PacketNumberLen2
 
143
                case 0x00:
 
144
                        header.PacketNumberLen = protocol.PacketNumberLen1
 
145
                }
129
146
        }
130
147
 
131
148
        // Connection ID
133
150
        if err != nil {
134
151
                return nil, err
135
152
        }
 
153
 
136
154
        header.ConnectionID = protocol.ConnectionID(connID)
137
155
        if header.ConnectionID == 0 {
138
156
                return nil, errInvalidConnectionID
139
157
        }
140
158
 
 
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)
 
167
                        if err != nil {
 
168
                                return nil, err
 
169
                        }
 
170
                }
 
171
        }
 
172
 
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)
 
179
                                if err != nil {
 
180
                                        return nil, err
 
181
                                }
 
182
                                header.VersionNumber = protocol.VersionTagToNumber(versionTag)
 
183
                        } else { // parse the version negotiaton packet
 
184
                        if b.Len()%4 != 0 {
 
185
                                return nil, qerr.InvalidVersionNegotiationPacket
 
186
                        }
 
187
                                header.SupportedVersions = make([]protocol.VersionNumber, 0)
 
188
                                for {
 
189
                                        var versionTag uint32
 
190
                                        versionTag, err = utils.ReadUint32(b)
 
191
                                        if err != nil {
 
192
                                                break
 
193
                                        }
 
194
                                        v := protocol.VersionTagToNumber(versionTag)
 
195
                                        if !protocol.IsSupportedVersion(v) {
 
196
                                                v = protocol.VersionUnsupported
 
197
                                        }
 
198
                                        header.SupportedVersions = append(header.SupportedVersions, v)
 
199
                                }
 
200
                        }
 
201
                }
 
202
        }
 
203
 
 
204
        // Packet number
 
205
        if header.hasPacketNumber(packetSentBy) {
 
206
                packetNumber, err := utils.ReadUintN(b, uint8(header.PacketNumberLen))
145
207
                if err != nil {
146
208
                        return nil, err
147
209
                }
148
 
                header.VersionNumber = protocol.VersionTagToNumber(versionTag)
149
 
        }
150
 
 
151
 
        // Packet number
152
 
        packetNumber, err := utils.ReadUintN(b, uint8(header.PacketNumberLen))
153
 
        if err != nil {
154
 
                return nil, err
155
 
        }
156
 
        header.PacketNumber = protocol.PacketNumber(packetNumber)
 
210
                header.PacketNumber = protocol.PacketNumber(packetNumber)
 
211
        }
157
212
 
158
213
        return header, nil
159
214
}
160
215
 
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
 
221
        }
 
222
 
 
223
        if h.VersionFlag && pers == protocol.PerspectiveServer {
 
224
                return 0, errGetLengthNotForVersionNegotiation
166
225
        }
167
226
 
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
 
228
 
 
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
 
232
                }
 
233
                length += protocol.ByteCount(h.PacketNumberLen)
171
234
        }
 
235
 
172
236
        if !h.TruncateConnectionID {
173
237
                length += 8 // 8 bytes for the connection ID
174
238
        }
 
239
 
 
240
        // Version Number in packets sent by the client
 
241
        if h.VersionFlag {
 
242
                length += 4
 
243
        }
 
244
 
175
245
        length += protocol.ByteCount(len(h.DiversificationNonce))
176
 
        length += protocol.ByteCount(h.PacketNumberLen)
 
246
 
177
247
        return length, nil
178
248
}
 
249
 
 
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 {
 
253
        if h.ResetFlag {
 
254
                return false
 
255
        }
 
256
        if h.VersionFlag && packetSentBy == protocol.PerspectiveServer {
 
257
                return false
 
258
        }
 
259
        return true
 
260
}