forked from quic-go/quic-go
* use require in benchmark tests * translate the QLOGDIR test * translate handshake tests * translate the handshake RTT tests * translate the early data test * translate the MTU tests * translate the key update test * translate the stateless reset tests * translate the packetization test * translate the close test * translate the resumption test * translate the tracer test * translate the connection ID length test * translate the RTT tests * translate the multiplexing tests * translate the drop tests * translate the handshake drop tests * translate the 0-RTT tests * translate the hotswap test * translate the stream test * translate the unidirectional stream test * translate the timeout tests * translate the MITM test * rewrite the datagram tests * translate the cancellation tests * translate the deadline tests * translate the test helpers
181 lines
5.0 KiB
Go
181 lines
5.0 KiB
Go
package self_test
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/quic-go/quic-go"
|
|
quicproxy "github.com/quic-go/quic-go/integrationtests/tools/proxy"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func handshakeWithRTT(t *testing.T, serverAddr net.Addr, tlsConf *tls.Config, quicConf *quic.Config, rtt time.Duration) quic.Connection {
|
|
t.Helper()
|
|
|
|
proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
|
|
RemoteAddr: serverAddr.String(),
|
|
DelayPacket: func(_ quicproxy.Direction, _ []byte) time.Duration { return rtt / 2 },
|
|
})
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { proxy.Close() })
|
|
|
|
conn, err := quic.DialAddr(
|
|
context.Background(),
|
|
fmt.Sprintf("localhost:%d", proxy.LocalAddr().(*net.UDPAddr).Port),
|
|
tlsConf,
|
|
quicConf,
|
|
)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() { conn.CloseWithError(0, "") })
|
|
return conn
|
|
}
|
|
|
|
func TestHandshakeRTTWithoutRetry(t *testing.T) {
|
|
ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil))
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
clientConfig := getQuicConfig(&quic.Config{
|
|
GetConfigForClient: func(info *quic.ClientHelloInfo) (*quic.Config, error) {
|
|
require.False(t, info.AddrVerified)
|
|
return nil, nil
|
|
},
|
|
})
|
|
|
|
const rtt = 400 * time.Millisecond
|
|
start := time.Now()
|
|
handshakeWithRTT(t, ln.Addr(), getTLSClientConfig(), clientConfig, rtt)
|
|
rtts := time.Since(start).Seconds() / rtt.Seconds()
|
|
require.GreaterOrEqual(t, rtts, float64(1))
|
|
require.Less(t, rtts, float64(2))
|
|
}
|
|
|
|
func TestHandshakeRTTWithRetry(t *testing.T) {
|
|
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
|
|
require.NoError(t, err)
|
|
defer udpConn.Close()
|
|
|
|
tr := &quic.Transport{
|
|
Conn: udpConn,
|
|
VerifySourceAddress: func(net.Addr) bool { return true },
|
|
}
|
|
addTracer(tr)
|
|
defer tr.Close()
|
|
ln, err := tr.Listen(getTLSConfig(), getQuicConfig(nil))
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
clientConfig := getQuicConfig(&quic.Config{
|
|
GetConfigForClient: func(info *quic.ClientHelloInfo) (*quic.Config, error) {
|
|
require.True(t, info.AddrVerified)
|
|
return nil, nil
|
|
},
|
|
})
|
|
const rtt = 400 * time.Millisecond
|
|
start := time.Now()
|
|
handshakeWithRTT(t, ln.Addr(), getTLSClientConfig(), clientConfig, rtt)
|
|
rtts := time.Since(start).Seconds() / rtt.Seconds()
|
|
require.GreaterOrEqual(t, rtts, float64(2))
|
|
require.Less(t, rtts, float64(3))
|
|
}
|
|
|
|
func TestHandshakeRTTWithHelloRetryRequest(t *testing.T) {
|
|
tlsConf := getTLSConfig()
|
|
tlsConf.CurvePreferences = []tls.CurveID{tls.CurveP384}
|
|
|
|
ln, err := quic.ListenAddr("localhost:0", tlsConf, getQuicConfig(nil))
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
const rtt = 400 * time.Millisecond
|
|
start := time.Now()
|
|
handshakeWithRTT(t, ln.Addr(), getTLSClientConfig(), getQuicConfig(nil), rtt)
|
|
rtts := time.Since(start).Seconds() / rtt.Seconds()
|
|
require.GreaterOrEqual(t, rtts, float64(2))
|
|
require.Less(t, rtts, float64(3))
|
|
}
|
|
|
|
func TestHandshakeRTTReceiveMessage(t *testing.T) {
|
|
sendAndReceive := func(t *testing.T, serverConn, clientConn quic.Connection) {
|
|
t.Helper()
|
|
serverStr, err := serverConn.OpenUniStream()
|
|
require.NoError(t, err)
|
|
_, err = serverStr.Write([]byte("foobar"))
|
|
require.NoError(t, err)
|
|
require.NoError(t, serverStr.Close())
|
|
|
|
str, err := clientConn.AcceptUniStream(context.Background())
|
|
require.NoError(t, err)
|
|
data, err := io.ReadAll(str)
|
|
require.NoError(t, err)
|
|
require.Equal(t, []byte("foobar"), data)
|
|
}
|
|
|
|
t.Run("using ListenAddr", func(t *testing.T) {
|
|
ln, err := quic.ListenAddr("localhost:0", getTLSConfig(), getQuicConfig(nil))
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
connChan := make(chan quic.Connection, 1)
|
|
go func() {
|
|
conn, err := ln.Accept(context.Background())
|
|
if err != nil {
|
|
t.Logf("failed to accept connection: %s", err)
|
|
close(connChan)
|
|
return
|
|
}
|
|
connChan <- conn
|
|
}()
|
|
|
|
const rtt = 400 * time.Millisecond
|
|
start := time.Now()
|
|
conn := handshakeWithRTT(t, ln.Addr(), getTLSClientConfig(), getQuicConfig(nil), rtt)
|
|
serverConn := <-connChan
|
|
if serverConn == nil {
|
|
t.Fatal("serverConn is nil")
|
|
}
|
|
sendAndReceive(t, serverConn, conn)
|
|
|
|
rtts := time.Since(start).Seconds() / rtt.Seconds()
|
|
require.GreaterOrEqual(t, rtts, float64(2))
|
|
require.Less(t, rtts, float64(3))
|
|
})
|
|
|
|
t.Run("using ListenAddrEarly", func(t *testing.T) {
|
|
ln, err := quic.ListenAddrEarly("localhost:0", getTLSConfig(), getQuicConfig(nil))
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
connChan := make(chan quic.Connection, 1)
|
|
go func() {
|
|
conn, err := ln.Accept(context.Background())
|
|
if err != nil {
|
|
t.Logf("failed to accept connection: %s", err)
|
|
close(connChan)
|
|
return
|
|
}
|
|
connChan <- conn
|
|
}()
|
|
|
|
const rtt = 400 * time.Millisecond
|
|
start := time.Now()
|
|
conn := handshakeWithRTT(t, ln.Addr(), getTLSClientConfig(), getQuicConfig(nil), rtt)
|
|
serverConn := <-connChan
|
|
if serverConn == nil {
|
|
t.Fatal("serverConn is nil")
|
|
}
|
|
sendAndReceive(t, serverConn, conn)
|
|
|
|
took := time.Since(start)
|
|
rtts := float64(took) / float64(rtt)
|
|
require.GreaterOrEqual(t, rtts, float64(1))
|
|
require.Less(t, rtts, float64(2))
|
|
})
|
|
}
|