feat(core): add QUIC TLS admission transport
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
@@ -476,6 +477,83 @@ func TestAdmissionQUICMTLSRelayAndCleanup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestStableErrorFramePrecedesConnectionTeardown(t *testing.T) {
|
||||
for _, retryable := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("retryable=%t", retryable), func(t *testing.T) {
|
||||
serverTLS, clientTLS := testTLS(t)
|
||||
clientTLS.NextProtos = []string{"versevdi-gateway-v1"}
|
||||
fake := NewFakeApollo(FakeApolloConfig{Now: time.Now()})
|
||||
authority := protocol.SessionAuthority{
|
||||
Version: "1", SessionID: "session-1", GatewayID: "gateway-1", Audience: "versevdi-gateway",
|
||||
ExpiresAt: time.Now().Add(time.Minute).UTC().Format(time.RFC3339Nano), Capabilities: DefaultCapabilities(),
|
||||
ProviderProfile: ProviderProfileApollo, ProviderIdentity: fake.config.Identity.Key(),
|
||||
}
|
||||
server, err := NewServer(ServerConfig{ListenAddress: "127.0.0.1:0", TLSConfig: serverTLS, GatewayID: authority.GatewayID, Admission: &oneTimeAdmission{authority: authority, released: make(chan struct{})}, Provider: fake})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if retryable {
|
||||
server.BeginDrain()
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go func() { _ = server.Serve(ctx) }()
|
||||
connection, err := quic.DialAddr(context.Background(), server.Addr().String(), clientTLS, &quic.Config{EnableDatagrams: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stream, err := connection.OpenStreamSync(context.Background())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gatewayID := authority.GatewayID
|
||||
if !retryable {
|
||||
gatewayID = "wrong-gateway"
|
||||
}
|
||||
request := protocol.TunnelAdmissionRequest{Version: "1", SessionID: authority.SessionID, GatewayID: gatewayID, Audience: authority.Audience, Grant: strings.Repeat("g", 64), ClientNonce: "nonce-0000000001", DeviceSignature: strings.Repeat("s", 86), Capabilities: DefaultCapabilities()}
|
||||
payload, err := protocol.EncodeTunnelAdmissionRequest(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := writeWire(stream, payload, defaultHelloLimit); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
response, err := readWire(stream, defaultHelloLimit)
|
||||
if err != nil {
|
||||
t.Fatalf("stable response lost before connection teardown: %v", err)
|
||||
}
|
||||
stable, err := protocol.DecodeStableError(response)
|
||||
if err != nil || stable.Retryable != retryable {
|
||||
t.Fatalf("stable response = %#v, %v", stable, err)
|
||||
}
|
||||
select {
|
||||
case <-connection.Context().Done():
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("server retained rejected connection")
|
||||
}
|
||||
_ = server.Close()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStableErrorNeverLeaksInternalProviderDetails(t *testing.T) {
|
||||
var wire bytes.Buffer
|
||||
if err := writeStableError(&wire, "provider_unavailable", errors.New("https://provider.invalid/launch?rikey=secret-sentinel"), true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
response, err := readWire(&wire, defaultHelloLimit)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stable, err := protocol.DecodeStableError(response)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(stable.Message, "provider.invalid") || strings.Contains(stable.Message, "secret-sentinel") {
|
||||
t.Fatalf("stable error leaked internal details: %q", stable.Message)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGatewayTelemetrySeparatesQueueProcessingAndPacing(t *testing.T) {
|
||||
serverTLS, clientTLS := testTLS(t)
|
||||
session := &fakeSession{
|
||||
|
||||
Reference in New Issue
Block a user