Disable QUIC 0-RTT
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
This commit is contained in:
parent
98c624bf1a
commit
900784a95a
4 changed files with 140 additions and 25 deletions
|
@ -4,10 +4,12 @@ import (
|
|||
"bufio"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||
|
@ -86,7 +88,7 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
epConfig.SetDefaults()
|
||||
|
||||
entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{
|
||||
Address: "127.0.0.1:8090",
|
||||
Address: "127.0.0.1:0",
|
||||
Transport: epConfig,
|
||||
ForwardedHeaders: &static.ForwardedHeaders{},
|
||||
HTTP2: &static.HTTP2Config{},
|
||||
|
@ -106,14 +108,20 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
rw.WriteHeader(http.StatusOK)
|
||||
}), nil)
|
||||
|
||||
go entryPoint.Start(context.Background())
|
||||
ctx := context.Background()
|
||||
go entryPoint.Start(ctx)
|
||||
entryPoint.SwitchRouter(router)
|
||||
|
||||
conn, err := tls.Dial("tcp", "127.0.0.1:8090", &tls.Config{
|
||||
conn, err := tls.Dial("tcp", entryPoint.listener.Addr().String(), &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = conn.Close()
|
||||
entryPoint.Shutdown(ctx)
|
||||
})
|
||||
|
||||
// We are racing with the http3Server readiness happening in the goroutine starting the entrypoint
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
@ -129,3 +137,109 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
assert.NotContains(t, r.Header.Get("Alt-Svc"), ":8090")
|
||||
assert.Contains(t, r.Header.Get("Alt-Svc"), ":8080")
|
||||
}
|
||||
|
||||
func TestHTTP30RTT(t *testing.T) {
|
||||
certContent, err := localhostCert.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
keyContent, err := localhostKey.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
tlsCert, err := tls.X509KeyPair(certContent, keyContent)
|
||||
require.NoError(t, err)
|
||||
|
||||
epConfig := &static.EntryPointsTransport{}
|
||||
epConfig.SetDefaults()
|
||||
|
||||
entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{
|
||||
Address: "127.0.0.1:8090",
|
||||
Transport: epConfig,
|
||||
ForwardedHeaders: &static.ForwardedHeaders{},
|
||||
HTTP2: &static.HTTP2Config{},
|
||||
HTTP3: &static.HTTP3Config{},
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
router, err := tcprouter.NewRouter()
|
||||
require.NoError(t, err)
|
||||
|
||||
router.AddHTTPTLSConfig("example.com", &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
})
|
||||
router.SetHTTPSHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), nil)
|
||||
|
||||
ctx := context.Background()
|
||||
go entryPoint.Start(ctx)
|
||||
entryPoint.SwitchRouter(router)
|
||||
|
||||
// We are racing with the http3Server readiness happening in the goroutine starting the entrypoint.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
certPool := x509.NewCertPool()
|
||||
certPool.AppendCertsFromPEM(certContent)
|
||||
|
||||
tlsConf := &tls.Config{
|
||||
RootCAs: certPool,
|
||||
ServerName: "example.com",
|
||||
NextProtos: []string{"h3"},
|
||||
}
|
||||
|
||||
// Define custom cache.
|
||||
gets := make(chan string, 100)
|
||||
puts := make(chan string, 100)
|
||||
cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts)
|
||||
tlsConf.ClientSessionCache = cache
|
||||
|
||||
// This first DialAddrEarly connection is here to populate the cache.
|
||||
earlyConnection, err := quic.DialAddrEarly(context.Background(), "127.0.0.1:8090", tlsConf, &quic.Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = earlyConnection.CloseWithError(0, "")
|
||||
entryPoint.Shutdown(ctx)
|
||||
})
|
||||
|
||||
// wait for the handshake complete.
|
||||
<-earlyConnection.HandshakeComplete()
|
||||
|
||||
// 0RTT is always false on the first connection.
|
||||
require.False(t, earlyConnection.ConnectionState().Used0RTT)
|
||||
|
||||
earlyConnection, err = quic.DialAddrEarly(context.Background(), "127.0.0.1:8090", tlsConf, &quic.Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
<-earlyConnection.HandshakeComplete()
|
||||
|
||||
// 0RTT need to be false.
|
||||
assert.False(t, earlyConnection.ConnectionState().Used0RTT)
|
||||
}
|
||||
|
||||
type clientSessionCache struct {
|
||||
cache tls.ClientSessionCache
|
||||
|
||||
gets chan<- string
|
||||
puts chan<- string
|
||||
}
|
||||
|
||||
func newClientSessionCache(cache tls.ClientSessionCache, gets, puts chan<- string) *clientSessionCache {
|
||||
return &clientSessionCache{
|
||||
cache: cache,
|
||||
gets: gets,
|
||||
puts: puts,
|
||||
}
|
||||
}
|
||||
|
||||
var _ tls.ClientSessionCache = &clientSessionCache{}
|
||||
|
||||
func (c *clientSessionCache) Get(sessionKey string) (*tls.ClientSessionState, bool) {
|
||||
session, ok := c.cache.Get(sessionKey)
|
||||
c.gets <- sessionKey
|
||||
return session, ok
|
||||
}
|
||||
|
||||
func (c *clientSessionCache) Put(sessionKey string, cs *tls.ClientSessionState) {
|
||||
c.cache.Put(sessionKey, cs)
|
||||
c.puts <- sessionKey
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue