1
2
3
4
5
6
7 package quic
8
9 import (
10 "bytes"
11 "encoding/binary"
12 "errors"
13 "time"
14 )
15
16 func (c *Conn) handleDatagram(now time.Time, dgram *datagram) {
17 buf := dgram.b
18 c.loss.datagramReceived(now, len(buf))
19 if c.isDraining() {
20 return
21 }
22 for len(buf) > 0 {
23 var n int
24 ptype := getPacketType(buf)
25 switch ptype {
26 case packetTypeInitial:
27 if c.side == serverSide && len(dgram.b) < paddedInitialDatagramSize {
28
29
30 return
31 }
32 n = c.handleLongHeader(now, ptype, initialSpace, c.keysInitial.r, buf)
33 case packetTypeHandshake:
34 n = c.handleLongHeader(now, ptype, handshakeSpace, c.keysHandshake.r, buf)
35 case packetType1RTT:
36 n = c.handle1RTT(now, buf)
37 case packetTypeRetry:
38 c.handleRetry(now, buf)
39 return
40 case packetTypeVersionNegotiation:
41 c.handleVersionNegotiation(now, buf)
42 return
43 default:
44 n = -1
45 }
46 if n <= 0 {
47
48
49
50
51
52
53
54
55
56 if len(buf) == len(dgram.b) && len(buf) > statelessResetTokenLen {
57 var token statelessResetToken
58 copy(token[:], buf[len(buf)-len(token):])
59 c.handleStatelessReset(now, token)
60 }
61
62 break
63 }
64 c.idleHandlePacketReceived(now)
65 buf = buf[n:]
66 }
67 }
68
69 func (c *Conn) handleLongHeader(now time.Time, ptype packetType, space numberSpace, k fixedKeys, buf []byte) int {
70 if !k.isSet() {
71 return skipLongHeaderPacket(buf)
72 }
73
74 pnumMax := c.acks[space].largestSeen()
75 p, n := parseLongHeaderPacket(buf, k, pnumMax)
76 if n < 0 {
77 return -1
78 }
79 if buf[0]&reservedLongBits != 0 {
80
81
82 c.abort(now, localTransportError{
83 code: errProtocolViolation,
84 reason: "reserved header bits are not zero",
85 })
86 return -1
87 }
88 if p.version != quicVersion1 {
89
90 c.abort(now, localTransportError{
91 code: errProtocolViolation,
92 reason: "protocol version changed during handshake",
93 })
94 return -1
95 }
96
97 if !c.acks[space].shouldProcess(p.num) {
98 return n
99 }
100
101 if logPackets {
102 logInboundLongPacket(c, p)
103 }
104 if c.logEnabled(QLogLevelPacket) {
105 c.logLongPacketReceived(p, buf[:n])
106 }
107 c.connIDState.handlePacket(c, p.ptype, p.srcConnID)
108 ackEliciting := c.handleFrames(now, ptype, space, p.payload)
109 c.acks[space].receive(now, space, p.num, ackEliciting)
110 if p.ptype == packetTypeHandshake && c.side == serverSide {
111 c.loss.validateClientAddress()
112
113
114
115
116 c.discardKeys(now, initialSpace)
117 }
118 return n
119 }
120
121 func (c *Conn) handle1RTT(now time.Time, buf []byte) int {
122 if !c.keysAppData.canRead() {
123
124
125 return len(buf)
126 }
127
128 pnumMax := c.acks[appDataSpace].largestSeen()
129 p, err := parse1RTTPacket(buf, &c.keysAppData, connIDLen, pnumMax)
130 if err != nil {
131
132
133 if _, ok := err.(localTransportError); ok {
134 c.abort(now, err)
135 }
136 return -1
137 }
138 if buf[0]&reserved1RTTBits != 0 {
139
140
141 c.abort(now, localTransportError{
142 code: errProtocolViolation,
143 reason: "reserved header bits are not zero",
144 })
145 return -1
146 }
147
148 if !c.acks[appDataSpace].shouldProcess(p.num) {
149 return len(buf)
150 }
151
152 if logPackets {
153 logInboundShortPacket(c, p)
154 }
155 if c.logEnabled(QLogLevelPacket) {
156 c.log1RTTPacketReceived(p, buf)
157 }
158 ackEliciting := c.handleFrames(now, packetType1RTT, appDataSpace, p.payload)
159 c.acks[appDataSpace].receive(now, appDataSpace, p.num, ackEliciting)
160 return len(buf)
161 }
162
163 func (c *Conn) handleRetry(now time.Time, pkt []byte) {
164 if c.side != clientSide {
165 return
166 }
167
168
169
170 if !c.keysInitial.canRead() {
171 return
172 }
173 if c.acks[initialSpace].seen.numRanges() != 0 {
174 return
175 }
176 if c.retryToken != nil {
177 return
178 }
179
180
181
182 p, ok := parseRetryPacket(pkt, c.connIDState.originalDstConnID)
183 if !ok {
184 return
185 }
186
187
188 if len(p.token) == 0 {
189 return
190 }
191 c.retryToken = cloneBytes(p.token)
192 c.connIDState.handleRetryPacket(p.srcConnID)
193
194
195 c.loss.discardPackets(initialSpace, c.handleAckOrLoss)
196
197 }
198
199 var errVersionNegotiation = errors.New("server does not support QUIC version 1")
200
201 func (c *Conn) handleVersionNegotiation(now time.Time, pkt []byte) {
202 if c.side != clientSide {
203 return
204 }
205
206
207
208 if !c.keysInitial.canRead() {
209 return
210 }
211 if c.acks[initialSpace].seen.numRanges() != 0 {
212 return
213 }
214 _, srcConnID, versions := parseVersionNegotiation(pkt)
215 if len(c.connIDState.remote) < 1 || !bytes.Equal(c.connIDState.remote[0].cid, srcConnID) {
216 return
217 }
218 for len(versions) >= 4 {
219 ver := binary.BigEndian.Uint32(versions)
220 if ver == 1 {
221
222
223
224 return
225 }
226 versions = versions[4:]
227 }
228
229
230
231
232 c.abortImmediately(now, errVersionNegotiation)
233 }
234
235 func (c *Conn) handleFrames(now time.Time, ptype packetType, space numberSpace, payload []byte) (ackEliciting bool) {
236 if len(payload) == 0 {
237
238
239
240 c.abort(now, localTransportError{
241 code: errProtocolViolation,
242 reason: "packet contains no frames",
243 })
244 return false
245 }
246
247 frameOK := func(c *Conn, ptype, mask packetType) (ok bool) {
248 if ptype&mask == 0 {
249
250
251
252
253 c.abort(now, localTransportError{
254 code: errProtocolViolation,
255 reason: "frame not allowed in packet",
256 })
257 return false
258 }
259 return true
260 }
261
262
263 const (
264 IH_1 = packetTypeInitial | packetTypeHandshake | packetType1RTT
265 __01 = packetType0RTT | packetType1RTT
266 ___1 = packetType1RTT
267 )
268 for len(payload) > 0 {
269 switch payload[0] {
270 case frameTypePadding, frameTypeAck, frameTypeAckECN,
271 frameTypeConnectionCloseTransport, frameTypeConnectionCloseApplication:
272 default:
273 ackEliciting = true
274 }
275 n := -1
276 switch payload[0] {
277 case frameTypePadding:
278
279 n = 1
280 case frameTypePing:
281
282
283
284
285 n = 1
286 case frameTypeAck, frameTypeAckECN:
287 if !frameOK(c, ptype, IH_1) {
288 return
289 }
290 n = c.handleAckFrame(now, space, payload)
291 case frameTypeResetStream:
292 if !frameOK(c, ptype, __01) {
293 return
294 }
295 n = c.handleResetStreamFrame(now, space, payload)
296 case frameTypeStopSending:
297 if !frameOK(c, ptype, __01) {
298 return
299 }
300 n = c.handleStopSendingFrame(now, space, payload)
301 case frameTypeCrypto:
302 if !frameOK(c, ptype, IH_1) {
303 return
304 }
305 n = c.handleCryptoFrame(now, space, payload)
306 case frameTypeNewToken:
307 if !frameOK(c, ptype, ___1) {
308 return
309 }
310 _, n = consumeNewTokenFrame(payload)
311 case 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f:
312 if !frameOK(c, ptype, __01) {
313 return
314 }
315 n = c.handleStreamFrame(now, space, payload)
316 case frameTypeMaxData:
317 if !frameOK(c, ptype, __01) {
318 return
319 }
320 n = c.handleMaxDataFrame(now, payload)
321 case frameTypeMaxStreamData:
322 if !frameOK(c, ptype, __01) {
323 return
324 }
325 n = c.handleMaxStreamDataFrame(now, payload)
326 case frameTypeMaxStreamsBidi, frameTypeMaxStreamsUni:
327 if !frameOK(c, ptype, __01) {
328 return
329 }
330 n = c.handleMaxStreamsFrame(now, payload)
331 case frameTypeDataBlocked:
332 if !frameOK(c, ptype, __01) {
333 return
334 }
335 _, n = consumeDataBlockedFrame(payload)
336 case frameTypeStreamsBlockedBidi, frameTypeStreamsBlockedUni:
337 if !frameOK(c, ptype, __01) {
338 return
339 }
340 _, _, n = consumeStreamsBlockedFrame(payload)
341 case frameTypeStreamDataBlocked:
342 if !frameOK(c, ptype, __01) {
343 return
344 }
345 _, _, n = consumeStreamDataBlockedFrame(payload)
346 case frameTypeNewConnectionID:
347 if !frameOK(c, ptype, __01) {
348 return
349 }
350 n = c.handleNewConnectionIDFrame(now, space, payload)
351 case frameTypeRetireConnectionID:
352 if !frameOK(c, ptype, __01) {
353 return
354 }
355 n = c.handleRetireConnectionIDFrame(now, space, payload)
356 case frameTypeConnectionCloseTransport:
357
358 n = c.handleConnectionCloseTransportFrame(now, payload)
359 case frameTypeConnectionCloseApplication:
360 if !frameOK(c, ptype, __01) {
361 return
362 }
363 n = c.handleConnectionCloseApplicationFrame(now, payload)
364 case frameTypeHandshakeDone:
365 if !frameOK(c, ptype, ___1) {
366 return
367 }
368 n = c.handleHandshakeDoneFrame(now, space, payload)
369 }
370 if n < 0 {
371 c.abort(now, localTransportError{
372 code: errFrameEncoding,
373 reason: "frame encoding error",
374 })
375 return false
376 }
377 payload = payload[n:]
378 }
379 return ackEliciting
380 }
381
382 func (c *Conn) handleAckFrame(now time.Time, space numberSpace, payload []byte) int {
383 c.loss.receiveAckStart()
384 largest, ackDelay, n := consumeAckFrame(payload, func(rangeIndex int, start, end packetNumber) {
385 if end > c.loss.nextNumber(space) {
386
387 c.abort(now, localTransportError{
388 code: errProtocolViolation,
389 reason: "acknowledgement for unsent packet",
390 })
391 return
392 }
393 c.loss.receiveAckRange(now, space, rangeIndex, start, end, c.handleAckOrLoss)
394 })
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415 var delay time.Duration
416 if c.peerAckDelayExponent >= 0 {
417 delay = ackDelay.Duration(uint8(c.peerAckDelayExponent))
418 }
419 c.loss.receiveAckEnd(now, space, delay, c.handleAckOrLoss)
420 if space == appDataSpace {
421 c.keysAppData.handleAckFor(largest)
422 }
423 return n
424 }
425
426 func (c *Conn) handleMaxDataFrame(now time.Time, payload []byte) int {
427 maxData, n := consumeMaxDataFrame(payload)
428 if n < 0 {
429 return -1
430 }
431 c.streams.outflow.setMaxData(maxData)
432 return n
433 }
434
435 func (c *Conn) handleMaxStreamDataFrame(now time.Time, payload []byte) int {
436 id, maxStreamData, n := consumeMaxStreamDataFrame(payload)
437 if n < 0 {
438 return -1
439 }
440 if s := c.streamForFrame(now, id, sendStream); s != nil {
441 if err := s.handleMaxStreamData(maxStreamData); err != nil {
442 c.abort(now, err)
443 return -1
444 }
445 }
446 return n
447 }
448
449 func (c *Conn) handleMaxStreamsFrame(now time.Time, payload []byte) int {
450 styp, max, n := consumeMaxStreamsFrame(payload)
451 if n < 0 {
452 return -1
453 }
454 c.streams.localLimit[styp].setMax(max)
455 return n
456 }
457
458 func (c *Conn) handleResetStreamFrame(now time.Time, space numberSpace, payload []byte) int {
459 id, code, finalSize, n := consumeResetStreamFrame(payload)
460 if n < 0 {
461 return -1
462 }
463 if s := c.streamForFrame(now, id, recvStream); s != nil {
464 if err := s.handleReset(code, finalSize); err != nil {
465 c.abort(now, err)
466 }
467 }
468 return n
469 }
470
471 func (c *Conn) handleStopSendingFrame(now time.Time, space numberSpace, payload []byte) int {
472 id, code, n := consumeStopSendingFrame(payload)
473 if n < 0 {
474 return -1
475 }
476 if s := c.streamForFrame(now, id, sendStream); s != nil {
477 if err := s.handleStopSending(code); err != nil {
478 c.abort(now, err)
479 }
480 }
481 return n
482 }
483
484 func (c *Conn) handleCryptoFrame(now time.Time, space numberSpace, payload []byte) int {
485 off, data, n := consumeCryptoFrame(payload)
486 err := c.handleCrypto(now, space, off, data)
487 if err != nil {
488 c.abort(now, err)
489 return -1
490 }
491 return n
492 }
493
494 func (c *Conn) handleStreamFrame(now time.Time, space numberSpace, payload []byte) int {
495 id, off, fin, b, n := consumeStreamFrame(payload)
496 if n < 0 {
497 return -1
498 }
499 if s := c.streamForFrame(now, id, recvStream); s != nil {
500 if err := s.handleData(off, b, fin); err != nil {
501 c.abort(now, err)
502 }
503 }
504 return n
505 }
506
507 func (c *Conn) handleNewConnectionIDFrame(now time.Time, space numberSpace, payload []byte) int {
508 seq, retire, connID, resetToken, n := consumeNewConnectionIDFrame(payload)
509 if n < 0 {
510 return -1
511 }
512 if err := c.connIDState.handleNewConnID(c, seq, retire, connID, resetToken); err != nil {
513 c.abort(now, err)
514 }
515 return n
516 }
517
518 func (c *Conn) handleRetireConnectionIDFrame(now time.Time, space numberSpace, payload []byte) int {
519 seq, n := consumeRetireConnectionIDFrame(payload)
520 if n < 0 {
521 return -1
522 }
523 if err := c.connIDState.handleRetireConnID(c, seq); err != nil {
524 c.abort(now, err)
525 }
526 return n
527 }
528
529 func (c *Conn) handleConnectionCloseTransportFrame(now time.Time, payload []byte) int {
530 code, _, reason, n := consumeConnectionCloseTransportFrame(payload)
531 if n < 0 {
532 return -1
533 }
534 c.handlePeerConnectionClose(now, peerTransportError{code: code, reason: reason})
535 return n
536 }
537
538 func (c *Conn) handleConnectionCloseApplicationFrame(now time.Time, payload []byte) int {
539 code, reason, n := consumeConnectionCloseApplicationFrame(payload)
540 if n < 0 {
541 return -1
542 }
543 c.handlePeerConnectionClose(now, &ApplicationError{Code: code, Reason: reason})
544 return n
545 }
546
547 func (c *Conn) handleHandshakeDoneFrame(now time.Time, space numberSpace, payload []byte) int {
548 if c.side == serverSide {
549
550
551 c.abort(now, localTransportError{
552 code: errProtocolViolation,
553 reason: "client sent HANDSHAKE_DONE",
554 })
555 return -1
556 }
557 if c.isAlive() {
558 c.confirmHandshake(now)
559 }
560 return 1
561 }
562
563 var errStatelessReset = errors.New("received stateless reset")
564
565 func (c *Conn) handleStatelessReset(now time.Time, resetToken statelessResetToken) {
566 if !c.connIDState.isValidStatelessResetToken(resetToken) {
567 return
568 }
569 c.setFinalError(errStatelessReset)
570 c.enterDraining(now)
571 }
572
View as plain text