implement stateless handling of Initial packets for the TLS server

This commit is contained in:
Marten Seemann
2017-11-11 08:38:27 +08:00
parent 57c6f3ceb5
commit 25a6dc9654
36 changed files with 1617 additions and 724 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/lucas-clemente/quic-go/internal/crypto"
"github.com/lucas-clemente/quic-go/internal/handshake"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/testdata"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/internal/wire"
"github.com/lucas-clemente/quic-go/qerr"
@@ -67,6 +68,7 @@ func (s *mockSession) RemoteAddr() net.Addr { panic("not imple
func (*mockSession) Context() context.Context { panic("not implemented") }
func (*mockSession) GetVersion() protocol.VersionNumber { return protocol.VersionWhatever }
func (s *mockSession) handshakeStatus() <-chan handshakeEvent { return s.handshakeChan }
func (*mockSession) getCryptoStream() cryptoStream { panic("not implemented") }
var _ Session = &mockSession{}
var _ NonFWSession = &mockSession{}
@@ -96,7 +98,8 @@ var _ = Describe("Server", func() {
)
BeforeEach(func() {
conn = &mockPacketConn{addr: &net.UDPAddr{}}
conn = newMockPacketConn()
conn.addr = &net.UDPAddr{}
config = &Config{Versions: protocol.SupportedVersions}
})
@@ -235,14 +238,14 @@ var _ = Describe("Server", func() {
})
It("works if no quic.Config is given", func(done Done) {
ln, err := ListenAddr("127.0.0.1:0", nil, config)
ln, err := ListenAddr("127.0.0.1:0", testdata.GetTLSConfig(), nil)
Expect(err).ToNot(HaveOccurred())
Expect(ln.Close()).To(Succeed())
close(done)
}, 1)
It("closes properly", func() {
ln, err := ListenAddr("127.0.0.1:0", nil, config)
ln, err := ListenAddr("127.0.0.1:0", testdata.GetTLSConfig(), config)
Expect(err).ToNot(HaveOccurred())
var returned bool
@@ -409,7 +412,7 @@ var _ = Describe("Server", func() {
}
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
conn.dataToRead = b.Bytes()
conn.dataToRead <- b.Bytes()
conn.dataReadFrom = udpAddr
ln, err := Listen(conn, nil, config)
Expect(err).ToNot(HaveOccurred())
@@ -432,7 +435,7 @@ var _ = Describe("Server", func() {
})
It("sends an IETF draft style Version Negotaion Packet, if the client sent a IETF draft style header", func() {
config.Versions = []protocol.VersionNumber{99}
config.Versions = []protocol.VersionNumber{99, protocol.VersionTLS}
b := &bytes.Buffer{}
hdr := wire.Header{
Type: protocol.PacketTypeInitial,
@@ -441,11 +444,12 @@ var _ = Describe("Server", func() {
PacketNumber: 0x55,
Version: 0x1234,
}
hdr.Write(b, protocol.PerspectiveClient, protocol.VersionTLS)
err := hdr.Write(b, protocol.PerspectiveClient, protocol.VersionTLS)
Expect(err).ToNot(HaveOccurred())
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
conn.dataToRead = b.Bytes()
conn.dataToRead <- b.Bytes()
conn.dataReadFrom = udpAddr
ln, err := Listen(conn, nil, config)
ln, err := Listen(conn, testdata.GetTLSConfig(), config)
Expect(err).ToNot(HaveOccurred())
done := make(chan struct{})
@@ -466,9 +470,32 @@ var _ = Describe("Server", func() {
Consistently(done).ShouldNot(BeClosed())
})
It("ignores IETF draft style Initial packets, if it doesn't support TLS", func() {
version := protocol.VersionNumber(99)
Expect(version.UsesTLS()).To(BeFalse())
config.Versions = []protocol.VersionNumber{version}
b := &bytes.Buffer{}
hdr := wire.Header{
Type: protocol.PacketTypeInitial,
IsLongHeader: true,
ConnectionID: 0x1337,
PacketNumber: 0x55,
Version: protocol.VersionTLS,
}
err := hdr.Write(b, protocol.PerspectiveClient, protocol.VersionTLS)
Expect(err).ToNot(HaveOccurred())
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
conn.dataToRead <- b.Bytes()
conn.dataReadFrom = udpAddr
ln, err := Listen(conn, testdata.GetTLSConfig(), config)
defer ln.Close()
Expect(err).ToNot(HaveOccurred())
Consistently(func() int { return conn.dataWritten.Len() }).Should(BeZero())
})
It("sends a PublicReset for new connections that don't have the VersionFlag set", func() {
conn.dataReadFrom = udpAddr
conn.dataToRead = []byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x01}
conn.dataToRead <- []byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x01}
ln, err := Listen(conn, nil, config)
Expect(err).ToNot(HaveOccurred())
go func() {