1
2
3
4
5
6
7 package quic
8
9 import (
10 "bytes"
11 "crypto/tls"
12 "io"
13 "log/slog"
14 "reflect"
15 "testing"
16 "time"
17
18 "golang.org/x/net/internal/quic/qlog"
19 )
20
21 func TestParseLongHeaderPacket(t *testing.T) {
22
23
24 cid := unhex(`8394c8f03e515708`)
25 initialServerKeys := initialKeys(cid, clientSide).r
26 pkt := unhex(`
27 cf000000010008f067a5502a4262b500 4075c0d95a482cd0991cd25b0aac406a
28 5816b6394100f37a1c69797554780bb3 8cc5a99f5ede4cf73c3ec2493a1839b3
29 dbcba3f6ea46c5b7684df3548e7ddeb9 c3bf9c73cc3f3bded74b562bfb19fb84
30 022f8ef4cdd93795d77d06edbb7aaf2f 58891850abbdca3d20398c276456cbc4
31 2158407dd074ee
32 `)
33 want := longPacket{
34 ptype: packetTypeInitial,
35 version: 1,
36 num: 1,
37 dstConnID: []byte{},
38 srcConnID: unhex(`f067a5502a4262b5`),
39 payload: unhex(`
40 02000000000600405a020000560303ee fce7f7b37ba1d1632e96677825ddf739
41 88cfc79825df566dc5430b9a045a1200 130100002e00330024001d00209d3c94
42 0d89690b84d08a60993c144eca684d10 81287c834d5311bcf32bb9da1a002b00
43 020304
44 `),
45 extra: []byte{},
46 }
47
48
49 got, n := parseLongHeaderPacket(pkt, initialServerKeys, 0)
50 if n != len(pkt) {
51 t.Errorf("parseLongHeaderPacket: n=%v, want %v", n, len(pkt))
52 }
53 if !reflect.DeepEqual(got, want) {
54 t.Errorf("parseLongHeaderPacket:\n got: %+v\nwant: %+v", got, want)
55 }
56
57
58 if got, want := skipLongHeaderPacket(pkt), len(pkt); got != want {
59 t.Errorf("skipLongHeaderPacket: n=%v, want %v", got, want)
60 }
61
62
63 for i := 0; i < len(pkt); i++ {
64 if _, n := parseLongHeaderPacket(pkt[:i], initialServerKeys, 0); n != -1 {
65 t.Fatalf("parse truncated long header packet: n=%v, want -1\ninput: %x", n, pkt[:i])
66 }
67 if n := skipLongHeaderPacket(pkt[:i]); n != -1 {
68 t.Errorf("skip truncated long header packet: n=%v, want -1", n)
69 }
70 }
71
72
73 invalidKeys := initialKeys([]byte{}, clientSide).w
74 if _, n := parseLongHeaderPacket(pkt, invalidKeys, 0); n != -1 {
75 t.Fatalf("parse long header packet with wrong keys: n=%v, want -1", n)
76 }
77 }
78
79 func TestRoundtripEncodeLongPacket(t *testing.T) {
80 var aes128Keys, aes256Keys, chachaKeys fixedKeys
81 aes128Keys.init(tls.TLS_AES_128_GCM_SHA256, []byte("secret"))
82 aes256Keys.init(tls.TLS_AES_256_GCM_SHA384, []byte("secret"))
83 chachaKeys.init(tls.TLS_CHACHA20_POLY1305_SHA256, []byte("secret"))
84 for _, test := range []struct {
85 desc string
86 p longPacket
87 k fixedKeys
88 }{{
89 desc: "Initial, 1-byte number, AES128",
90 p: longPacket{
91 ptype: packetTypeInitial,
92 version: 0x11223344,
93 num: 0,
94 dstConnID: []byte{1, 2, 3, 4},
95 srcConnID: []byte{5, 6, 7, 8},
96 payload: []byte("payload"),
97 extra: []byte("token"),
98 },
99 k: aes128Keys,
100 }, {
101 desc: "0-RTT, 2-byte number, AES256",
102 p: longPacket{
103 ptype: packetType0RTT,
104 version: 0x11223344,
105 num: 0x100,
106 dstConnID: []byte{1, 2, 3, 4},
107 srcConnID: []byte{5, 6, 7, 8},
108 payload: []byte("payload"),
109 },
110 k: aes256Keys,
111 }, {
112 desc: "0-RTT, 3-byte number, AES256",
113 p: longPacket{
114 ptype: packetType0RTT,
115 version: 0x11223344,
116 num: 0x10000,
117 dstConnID: []byte{1, 2, 3, 4},
118 srcConnID: []byte{5, 6, 7, 8},
119 payload: []byte{0},
120 },
121 k: aes256Keys,
122 }, {
123 desc: "Handshake, 4-byte number, ChaCha20Poly1305",
124 p: longPacket{
125 ptype: packetTypeHandshake,
126 version: 0x11223344,
127 num: 0x1000000,
128 dstConnID: []byte{1, 2, 3, 4},
129 srcConnID: []byte{5, 6, 7, 8},
130 payload: []byte("payload"),
131 },
132 k: chachaKeys,
133 }} {
134 t.Run(test.desc, func(t *testing.T) {
135 var w packetWriter
136 w.reset(1200)
137 w.startProtectedLongHeaderPacket(0, test.p)
138 w.b = append(w.b, test.p.payload...)
139 w.finishProtectedLongHeaderPacket(0, test.k, test.p)
140 pkt := w.datagram()
141
142 got, n := parseLongHeaderPacket(pkt, test.k, 0)
143 if n != len(pkt) {
144 t.Errorf("parseLongHeaderPacket: n=%v, want %v", n, len(pkt))
145 }
146 if !reflect.DeepEqual(got, test.p) {
147 t.Errorf("Round-trip encode/decode did not preserve packet.\nsent: %+v\n got: %+v\nwire: %x", test.p, got, pkt)
148 }
149 })
150 }
151 }
152
153 func TestRoundtripEncodeShortPacket(t *testing.T) {
154 var aes128Keys, aes256Keys, chachaKeys updatingKeyPair
155 aes128Keys.r.init(tls.TLS_AES_128_GCM_SHA256, []byte("secret"))
156 aes256Keys.r.init(tls.TLS_AES_256_GCM_SHA384, []byte("secret"))
157 chachaKeys.r.init(tls.TLS_CHACHA20_POLY1305_SHA256, []byte("secret"))
158 aes128Keys.w = aes128Keys.r
159 aes256Keys.w = aes256Keys.r
160 chachaKeys.w = chachaKeys.r
161 aes128Keys.updateAfter = maxPacketNumber
162 aes256Keys.updateAfter = maxPacketNumber
163 chachaKeys.updateAfter = maxPacketNumber
164 connID := make([]byte, connIDLen)
165 for i := range connID {
166 connID[i] = byte(i)
167 }
168 for _, test := range []struct {
169 desc string
170 num packetNumber
171 payload []byte
172 k updatingKeyPair
173 }{{
174 desc: "1-byte number, AES128",
175 num: 0,
176 payload: []byte("payload"),
177 k: aes128Keys,
178 }, {
179 desc: "2-byte number, AES256",
180 num: 0x100,
181 payload: []byte("payload"),
182 k: aes256Keys,
183 }, {
184 desc: "3-byte number, ChaCha20Poly1305",
185 num: 0x10000,
186 payload: []byte("payload"),
187 k: chachaKeys,
188 }, {
189 desc: "4-byte number, ChaCha20Poly1305",
190 num: 0x1000000,
191 payload: []byte{0},
192 k: chachaKeys,
193 }} {
194 t.Run(test.desc, func(t *testing.T) {
195 var w packetWriter
196 w.reset(1200)
197 w.start1RTTPacket(test.num, 0, connID)
198 w.b = append(w.b, test.payload...)
199 w.finish1RTTPacket(test.num, 0, connID, &test.k)
200 pkt := w.datagram()
201 p, err := parse1RTTPacket(pkt, &test.k, connIDLen, 0)
202 if err != nil {
203 t.Errorf("parse1RTTPacket: err=%v, want nil", err)
204 }
205 if p.num != test.num || !bytes.Equal(p.payload, test.payload) {
206 t.Errorf("Round-trip encode/decode did not preserve packet.\nsent: num=%v, payload={%x}\ngot: num=%v, payload={%x}", test.num, test.payload, p.num, p.payload)
207 }
208 })
209 }
210 }
211
212 func TestFrameEncodeDecode(t *testing.T) {
213 for _, test := range []struct {
214 s string
215 j string
216 f debugFrame
217 b []byte
218 truncated []byte
219 }{{
220 s: "PADDING*1",
221 j: `{"frame_type":"padding","length":1}`,
222 f: debugFramePadding{
223 size: 1,
224 },
225 b: []byte{
226 0x00,
227
228 },
229 }, {
230 s: "PING",
231 j: `{"frame_type":"ping"}`,
232 f: debugFramePing{},
233 b: []byte{
234 0x01,
235 },
236 }, {
237 s: "ACK Delay=10 [0,16) [17,32) [48,64)",
238 j: `"error: debugFrameAck should not appear as a slog Value"`,
239 f: debugFrameAck{
240 ackDelay: 10,
241 ranges: []i64range[packetNumber]{
242 {0x00, 0x10},
243 {0x11, 0x20},
244 {0x30, 0x40},
245 },
246 },
247 b: []byte{
248 0x02,
249 0x3f,
250 10,
251 0x02,
252 0x0f,
253 0x0f,
254 0x0e,
255 0x00,
256 0x0f,
257 },
258 truncated: []byte{
259 0x02,
260 0x3f,
261 10,
262 0x01,
263 0x0f,
264 0x0f,
265 0x0e,
266 },
267 }, {
268 s: "RESET_STREAM ID=1 Code=2 FinalSize=3",
269 j: `{"frame_type":"reset_stream","stream_id":1,"final_size":3}`,
270 f: debugFrameResetStream{
271 id: 1,
272 code: 2,
273 finalSize: 3,
274 },
275 b: []byte{
276 0x04,
277 0x01,
278 0x02,
279 0x03,
280 },
281 }, {
282 s: "STOP_SENDING ID=1 Code=2",
283 j: `{"frame_type":"stop_sending","stream_id":1,"error_code":2}`,
284 f: debugFrameStopSending{
285 id: 1,
286 code: 2,
287 },
288 b: []byte{
289 0x05,
290 0x01,
291 0x02,
292 },
293 }, {
294 s: "CRYPTO Offset=1 Length=2",
295 j: `{"frame_type":"crypto","offset":1,"length":2}`,
296 f: debugFrameCrypto{
297 off: 1,
298 data: []byte{3, 4},
299 },
300 b: []byte{
301 0x06,
302 0x01,
303 0x02,
304 0x03, 0x04,
305 },
306 truncated: []byte{
307 0x06,
308 0x01,
309 0x01,
310 0x03,
311 },
312 }, {
313 s: "NEW_TOKEN Token=0304",
314 j: `{"frame_type":"new_token","token":"0304"}`,
315 f: debugFrameNewToken{
316 token: []byte{3, 4},
317 },
318 b: []byte{
319 0x07,
320 0x02,
321 0x03, 0x04,
322 },
323 }, {
324 s: "STREAM ID=1 Offset=0 Length=0",
325 j: `{"frame_type":"stream","stream_id":1,"offset":0,"length":0}`,
326 f: debugFrameStream{
327 id: 1,
328 fin: false,
329 off: 0,
330 data: []byte{},
331 },
332 b: []byte{
333 0x0a,
334 0x01,
335
336 0x00,
337
338 },
339 }, {
340 s: "STREAM ID=100 Offset=4 Length=3",
341 j: `{"frame_type":"stream","stream_id":100,"offset":4,"length":3}`,
342 f: debugFrameStream{
343 id: 100,
344 fin: false,
345 off: 4,
346 data: []byte{0xa0, 0xa1, 0xa2},
347 },
348 b: []byte{
349 0x0e,
350 0x40, 0x64,
351 0x04,
352 0x03,
353 0xa0, 0xa1, 0xa2,
354 },
355 truncated: []byte{
356 0x0e,
357 0x40, 0x64,
358 0x04,
359 0x02,
360 0xa0, 0xa1,
361 },
362 }, {
363 s: "STREAM ID=100 FIN Offset=4 Length=3",
364 j: `{"frame_type":"stream","stream_id":100,"offset":4,"length":3,"fin":true}`,
365 f: debugFrameStream{
366 id: 100,
367 fin: true,
368 off: 4,
369 data: []byte{0xa0, 0xa1, 0xa2},
370 },
371 b: []byte{
372 0x0f,
373 0x40, 0x64,
374 0x04,
375 0x03,
376 0xa0, 0xa1, 0xa2,
377 },
378 truncated: []byte{
379 0x0e,
380 0x40, 0x64,
381 0x04,
382 0x02,
383 0xa0, 0xa1,
384 },
385 }, {
386 s: "STREAM ID=1 FIN Offset=100 Length=0",
387 j: `{"frame_type":"stream","stream_id":1,"offset":100,"length":0,"fin":true}`,
388 f: debugFrameStream{
389 id: 1,
390 fin: true,
391 off: 100,
392 data: []byte{},
393 },
394 b: []byte{
395 0x0f,
396 0x01,
397 0x40, 0x64,
398 0x00,
399
400 },
401 }, {
402 s: "MAX_DATA Max=10",
403 j: `{"frame_type":"max_data","maximum":10}`,
404 f: debugFrameMaxData{
405 max: 10,
406 },
407 b: []byte{
408 0x10,
409 0x0a,
410 },
411 }, {
412 s: "MAX_STREAM_DATA ID=1 Max=10",
413 j: `{"frame_type":"max_stream_data","stream_id":1,"maximum":10}`,
414 f: debugFrameMaxStreamData{
415 id: 1,
416 max: 10,
417 },
418 b: []byte{
419 0x11,
420 0x01,
421 0x0a,
422 },
423 }, {
424 s: "MAX_STREAMS Type=bidi Max=1",
425 j: `{"frame_type":"max_streams","stream_type":"bidirectional","maximum":1}`,
426 f: debugFrameMaxStreams{
427 streamType: bidiStream,
428 max: 1,
429 },
430 b: []byte{
431 0x12,
432 0x01,
433 },
434 }, {
435 s: "MAX_STREAMS Type=uni Max=1",
436 j: `{"frame_type":"max_streams","stream_type":"unidirectional","maximum":1}`,
437 f: debugFrameMaxStreams{
438 streamType: uniStream,
439 max: 1,
440 },
441 b: []byte{
442 0x13,
443 0x01,
444 },
445 }, {
446 s: "DATA_BLOCKED Max=1",
447 j: `{"frame_type":"data_blocked","limit":1}`,
448 f: debugFrameDataBlocked{
449 max: 1,
450 },
451 b: []byte{
452 0x14,
453 0x01,
454 },
455 }, {
456 s: "STREAM_DATA_BLOCKED ID=1 Max=2",
457 j: `{"frame_type":"stream_data_blocked","stream_id":1,"limit":2}`,
458 f: debugFrameStreamDataBlocked{
459 id: 1,
460 max: 2,
461 },
462 b: []byte{
463 0x15,
464 0x01,
465 0x02,
466 },
467 }, {
468 s: "STREAMS_BLOCKED Type=bidi Max=1",
469 j: `{"frame_type":"streams_blocked","stream_type":"bidirectional","limit":1}`,
470 f: debugFrameStreamsBlocked{
471 streamType: bidiStream,
472 max: 1,
473 },
474 b: []byte{
475 0x16,
476 0x01,
477 },
478 }, {
479 s: "STREAMS_BLOCKED Type=uni Max=1",
480 j: `{"frame_type":"streams_blocked","stream_type":"unidirectional","limit":1}`,
481 f: debugFrameStreamsBlocked{
482 streamType: uniStream,
483 max: 1,
484 },
485 b: []byte{
486 0x17,
487 0x01,
488 },
489 }, {
490 s: "NEW_CONNECTION_ID Seq=3 Retire=2 ID=a0a1a2a3 Token=0102030405060708090a0b0c0d0e0f10",
491 j: `{"frame_type":"new_connection_id","sequence_number":3,"retire_prior_to":2,"connection_id":"a0a1a2a3","stateless_reset_token":"0102030405060708090a0b0c0d0e0f10"}`,
492 f: debugFrameNewConnectionID{
493 seq: 3,
494 retirePriorTo: 2,
495 connID: []byte{0xa0, 0xa1, 0xa2, 0xa3},
496 token: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
497 },
498 b: []byte{
499 0x18,
500 0x03,
501 0x02,
502 0x04,
503 0xa0, 0xa1, 0xa2, 0xa3,
504 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
505 },
506 }, {
507 s: "RETIRE_CONNECTION_ID Seq=1",
508 j: `{"frame_type":"retire_connection_id","sequence_number":1}`,
509 f: debugFrameRetireConnectionID{
510 seq: 1,
511 },
512 b: []byte{
513 0x19,
514 0x01,
515 },
516 }, {
517 s: "PATH_CHALLENGE Data=0123456789abcdef",
518 j: `{"frame_type":"path_challenge","data":"0123456789abcdef"}`,
519 f: debugFramePathChallenge{
520 data: 0x0123456789abcdef,
521 },
522 b: []byte{
523 0x1a,
524 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
525 },
526 }, {
527 s: "PATH_RESPONSE Data=0123456789abcdef",
528 j: `{"frame_type":"path_response","data":"0123456789abcdef"}`,
529 f: debugFramePathResponse{
530 data: 0x0123456789abcdef,
531 },
532 b: []byte{
533 0x1b,
534 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
535 },
536 }, {
537 s: `CONNECTION_CLOSE Code=INTERNAL_ERROR FrameType=2 Reason="oops"`,
538 j: `{"frame_type":"connection_close","error_space":"transport","error_code_value":1,"reason":"oops"}`,
539 f: debugFrameConnectionCloseTransport{
540 code: 1,
541 frameType: 2,
542 reason: "oops",
543 },
544 b: []byte{
545 0x1c,
546 0x01,
547 0x02,
548 0x04,
549 'o', 'o', 'p', 's',
550 },
551 }, {
552 s: `CONNECTION_CLOSE AppCode=1 Reason="oops"`,
553 j: `{"frame_type":"connection_close","error_space":"application","error_code_value":1,"reason":"oops"}`,
554 f: debugFrameConnectionCloseApplication{
555 code: 1,
556 reason: "oops",
557 },
558 b: []byte{
559 0x1d,
560 0x01,
561 0x04,
562 'o', 'o', 'p', 's',
563 },
564 }, {
565 s: "HANDSHAKE_DONE",
566 j: `{"frame_type":"handshake_done"}`,
567 f: debugFrameHandshakeDone{},
568 b: []byte{
569 0x1e,
570 },
571 }} {
572 var w packetWriter
573 w.reset(1200)
574 w.start1RTTPacket(0, 0, nil)
575 w.pktLim = w.payOff + len(test.b)
576 if added := test.f.write(&w); !added {
577 t.Errorf("encoding %v with %v bytes available: write unexpectedly failed", test.f, len(test.b))
578 }
579 if got, want := w.payload(), test.b; !bytes.Equal(got, want) {
580 t.Errorf("encoding %v:\ngot {%x}\nwant {%x}", test.f, got, want)
581 }
582 gotf, n := parseDebugFrame(test.b)
583 if n != len(test.b) || !reflect.DeepEqual(gotf, test.f) {
584 t.Errorf("decoding {%x}:\ndecoded %v bytes, want %v\ngot: %v\nwant: %v", test.b, n, len(test.b), gotf, test.f)
585 }
586 if got, want := test.f.String(), test.s; got != want {
587 t.Errorf("frame.String():\ngot %q\nwant %q", got, want)
588 }
589 if got, want := frameJSON(test.f), test.j; got != want {
590 t.Errorf("frame.LogValue():\ngot %q\nwant %q", got, want)
591 }
592
593
594
595
596 w.reset(1200)
597 w.start1RTTPacket(0, 0, nil)
598 w.pktLim = w.payOff + len(test.b) - 1
599 if added := test.f.write(&w); added {
600 if test.truncated == nil {
601 t.Errorf("encoding %v with %v-1 bytes available: write unexpectedly succeeded", test.f, len(test.b))
602 } else if got, want := w.payload(), test.truncated; !bytes.Equal(got, want) {
603 t.Errorf("encoding %v with %v-1 bytes available:\ngot {%x}\nwant {%x}", test.f, len(test.b), got, want)
604 }
605 }
606
607
608 for i := 0; i < len(test.b); i++ {
609 f, n := parseDebugFrame(test.b[:i])
610 if n >= 0 {
611 t.Errorf("decoding truncated frame {%x}:\ngot: %v\nwant error", test.b[:i], f)
612 }
613 }
614 }
615 }
616
617 func TestFrameScaledAck(t *testing.T) {
618 for _, test := range []struct {
619 j string
620 f debugFrameScaledAck
621 }{{
622 j: `{"frame_type":"ack","acked_ranges":[[0,15],[17],[48,63]],"ack_delay":10.000000}`,
623 f: debugFrameScaledAck{
624 ackDelay: 10 * time.Millisecond,
625 ranges: []i64range[packetNumber]{
626 {0x00, 0x10},
627 {0x11, 0x12},
628 {0x30, 0x40},
629 },
630 },
631 }} {
632 if got, want := frameJSON(test.f), test.j; got != want {
633 t.Errorf("frame.LogValue():\ngot %q\nwant %q", got, want)
634 }
635 }
636 }
637
638 func frameJSON(f slog.LogValuer) string {
639 var buf bytes.Buffer
640 h := qlog.NewJSONHandler(qlog.HandlerOptions{
641 Level: QLogLevelFrame,
642 NewTrace: func(info qlog.TraceInfo) (io.WriteCloser, error) {
643 return nopCloseWriter{&buf}, nil
644 },
645 })
646
647 slog.New(h).Info("message", slog.Any("frame", f))
648 _, b, _ := bytes.Cut(buf.Bytes(), []byte(`"frame":`))
649 b = bytes.TrimSuffix(b, []byte("}}\n"))
650 return string(b)
651 }
652
653 func TestFrameDecode(t *testing.T) {
654 for _, test := range []struct {
655 desc string
656 want debugFrame
657 b []byte
658 }{{
659 desc: "STREAM frame with LEN bit unset",
660 want: debugFrameStream{
661 id: 1,
662 fin: false,
663 data: []byte{0x01, 0x02, 0x03},
664 },
665 b: []byte{
666 0x08,
667 0x01,
668
669
670 0x01, 0x02, 0x03,
671 },
672 }, {
673 desc: "ACK frame with ECN counts",
674 want: debugFrameAck{
675 ackDelay: 10,
676 ranges: []i64range[packetNumber]{
677 {0, 1},
678 },
679 },
680 b: []byte{
681 0x03,
682 0x00,
683 10,
684 0x00,
685 0x00,
686 0x01, 0x02, 0x03,
687 },
688 }} {
689 got, n := parseDebugFrame(test.b)
690 if n != len(test.b) || !reflect.DeepEqual(got, test.want) {
691 t.Errorf("decoding {%x}:\ndecoded %v bytes, want %v\ngot: %v\nwant: %v", test.b, n, len(test.b), got, test.want)
692 }
693 }
694 }
695
696 func TestFrameDecodeErrors(t *testing.T) {
697 for _, test := range []struct {
698 name string
699 b []byte
700 }{{
701 name: "ACK [-1,0]",
702 b: []byte{
703 0x02,
704 0x00,
705 0x00,
706 0x00,
707 0x01,
708 },
709 }, {
710 name: "ACK [-1,16]",
711 b: []byte{
712 0x02,
713 0x10,
714 0x00,
715 0x00,
716 0x11,
717 },
718 }, {
719 name: "ACK [-1,0],[1,2]",
720 b: []byte{
721 0x02,
722 0x02,
723 0x00,
724 0x01,
725 0x00,
726 0x01,
727 0x01,
728 },
729 }, {
730 name: "NEW_TOKEN with zero-length token",
731 b: []byte{
732 0x07,
733 0x00,
734 },
735 }, {
736 name: "MAX_STREAMS with too many streams",
737 b: func() []byte {
738
739 return appendVarint([]byte{frameTypeMaxStreamsBidi}, (1<<60)+1)
740 }(),
741 }, {
742 name: "NEW_CONNECTION_ID too small",
743 b: []byte{
744 0x18,
745 0x03,
746 0x02,
747 0x00,
748
749 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
750 },
751 }, {
752 name: "NEW_CONNECTION_ID too large",
753 b: []byte{
754 0x18,
755 0x03,
756 0x02,
757 21,
758 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
759 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
760 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
761 },
762 }, {
763 name: "NEW_CONNECTION_ID sequence smaller than retire",
764 b: []byte{
765 0x18,
766 0x02,
767 0x03,
768 0x02,
769 0xff, 0xff,
770 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
771 },
772 }} {
773 f, n := parseDebugFrame(test.b)
774 if n >= 0 {
775 t.Errorf("%v: no error when parsing invalid frame {%x}\ngot: %v", test.name, test.b, f)
776 }
777 }
778 }
779
780 func FuzzParseLongHeaderPacket(f *testing.F) {
781 cid := unhex(`0000000000000000`)
782 initialServerKeys := initialKeys(cid, clientSide).r
783 f.Fuzz(func(t *testing.T, in []byte) {
784 parseLongHeaderPacket(in, initialServerKeys, 0)
785 })
786 }
787
788 func FuzzFrameDecode(f *testing.F) {
789 f.Fuzz(func(t *testing.T, in []byte) {
790 parseDebugFrame(in)
791 })
792 }
793
View as plain text