golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/version_test.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.21
     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  	// Packet of unknown contents for some unrecognized QUIC version.
    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 Negotiation")
    43  	}
    44  	if got := getPacketType(gotPkt); got != packetTypeVersionNegotiation {
    45  		t.Fatalf("got packet type %v; want Version Negotiation", 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() // client Initial packet
    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() // client Initial packet
    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() // client Initial packet
    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  }