1
2
3
4
5
6
7 package quic
8
9 import (
10 "bytes"
11 "context"
12 "crypto/tls"
13 "testing"
14 )
15
16 func TestVersionNegotiationServerReceivesUnknownVersion(t *testing.T) {
17 config := &Config{
18 TLSConfig: newTestTLSConfig(serverSide),
19 }
20 te := newTestEndpoint(t, config)
21
22
23 dstConnID := []byte{1, 2, 3, 4}
24 srcConnID := []byte{5, 6, 7, 8}
25 pkt := []byte{
26 0b1000_0000,
27 0x00, 0x00, 0x00, 0x0f,
28 }
29 pkt = append(pkt, byte(len(dstConnID)))
30 pkt = append(pkt, dstConnID...)
31 pkt = append(pkt, byte(len(srcConnID)))
32 pkt = append(pkt, srcConnID...)
33 for len(pkt) < paddedInitialDatagramSize {
34 pkt = append(pkt, 0)
35 }
36
37 te.write(&datagram{
38 b: pkt,
39 })
40 gotPkt := te.read()
41 if gotPkt == nil {
42 t.Fatalf("got no response; want Version Negotiaion")
43 }
44 if got := getPacketType(gotPkt); got != packetTypeVersionNegotiation {
45 t.Fatalf("got packet type %v; want Version Negotiaion", got)
46 }
47 gotDst, gotSrc, versions := parseVersionNegotiation(gotPkt)
48 if got, want := gotDst, srcConnID; !bytes.Equal(got, want) {
49 t.Errorf("got Destination Connection ID %x, want %x", got, want)
50 }
51 if got, want := gotSrc, dstConnID; !bytes.Equal(got, want) {
52 t.Errorf("got Source Connection ID %x, want %x", got, want)
53 }
54 if got, want := versions, []byte{0, 0, 0, 1}; !bytes.Equal(got, want) {
55 t.Errorf("got Supported Version %x, want %x", got, want)
56 }
57 }
58
59 func TestVersionNegotiationClientAborts(t *testing.T) {
60 tc := newTestConn(t, clientSide)
61 p := tc.readPacket()
62 tc.endpoint.write(&datagram{
63 b: appendVersionNegotiation(nil, p.srcConnID, p.dstConnID, 10),
64 })
65 tc.wantIdle("connection does not send a CONNECTION_CLOSE")
66 if err := tc.conn.waitReady(canceledContext()); err != errVersionNegotiation {
67 t.Errorf("conn.waitReady() = %v, want errVersionNegotiation", err)
68 }
69 }
70
71 func TestVersionNegotiationClientIgnoresAfterProcessingPacket(t *testing.T) {
72 tc := newTestConn(t, clientSide)
73 tc.ignoreFrame(frameTypeAck)
74 p := tc.readPacket()
75 tc.writeFrames(packetTypeInitial,
76 debugFrameCrypto{
77 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
78 })
79 tc.endpoint.write(&datagram{
80 b: appendVersionNegotiation(nil, p.srcConnID, p.dstConnID, 10),
81 })
82 if err := tc.conn.waitReady(canceledContext()); err != context.Canceled {
83 t.Errorf("conn.waitReady() = %v, want context.Canceled", err)
84 }
85 tc.writeFrames(packetTypeHandshake,
86 debugFrameCrypto{
87 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
88 })
89 tc.wantFrameType("conn ignores Version Negotiation and continues with handshake",
90 packetTypeHandshake, debugFrameCrypto{})
91 }
92
93 func TestVersionNegotiationClientIgnoresMismatchingSourceConnID(t *testing.T) {
94 tc := newTestConn(t, clientSide)
95 tc.ignoreFrame(frameTypeAck)
96 p := tc.readPacket()
97 tc.endpoint.write(&datagram{
98 b: appendVersionNegotiation(nil, p.srcConnID, []byte("mismatch"), 10),
99 })
100 tc.writeFrames(packetTypeInitial,
101 debugFrameCrypto{
102 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
103 })
104 tc.writeFrames(packetTypeHandshake,
105 debugFrameCrypto{
106 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
107 })
108 tc.wantFrameType("conn ignores Version Negotiation and continues with handshake",
109 packetTypeHandshake, debugFrameCrypto{})
110 }
111
View as plain text