fix(gateway): strip provider authority from client egress
Verify Data Plane / gateway (push) Failing after 4m32s
Verify Data Plane / gateway (push) Failing after 4m32s
This commit is contained in:
+65
-8
@@ -12,6 +12,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
@@ -969,10 +970,61 @@ func newNativeGatewayLifecycleHarness(t *testing.T, sessionID string) nativeGate
|
||||
return nativeGatewayLifecycleHarness{native: native, key: key, client: client, admission: admission, reporter: reporter}
|
||||
}
|
||||
|
||||
func TestGatewayEgressReturnsProviderFreeClientAuthority(t *testing.T) {
|
||||
h := newNativeGatewayLifecycleHarness(t, "session-client-authority")
|
||||
var got map[string]any
|
||||
if err := json.Unmarshal(h.client.authorityRaw, &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := map[string]any{
|
||||
"version": "1",
|
||||
"session_id": "session-client-authority",
|
||||
"gateway_id": "gateway-1",
|
||||
"audience": "versevdi-gateway",
|
||||
"reconnect_sequence": float64(0),
|
||||
"expires_at": h.admission.authority.ExpiresAt,
|
||||
"capabilities": map[string]any{
|
||||
"transport": "quic-tls13",
|
||||
"framing": "datagram-v2",
|
||||
"media": "encoded",
|
||||
"audio": "encoded",
|
||||
"source_rate_control": "server",
|
||||
"client_decode": []any{"h264-opus"},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("raw client authority = %s", h.client.authorityRaw)
|
||||
}
|
||||
if err := h.client.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
h.waitReleased(t)
|
||||
if !reflect.DeepEqual(h.admission.releaseAuthority, h.admission.authority) {
|
||||
t.Fatalf("release authority = %#v, want provider-bearing %#v", h.admission.releaseAuthority, h.admission.authority)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientSessionAuthorityRejectsProviderBearingRC3(t *testing.T) {
|
||||
var _ protocol.ClientSessionAuthority = Client{}.Authority
|
||||
raw, err := protocol.EncodeSessionAuthority(protocol.SessionAuthority{
|
||||
Version: "1", SessionID: "session-rc3", GatewayID: "gateway-1", Audience: "versevdi-gateway",
|
||||
ExpiresAt: time.Now().Add(time.Minute).UTC().Format(time.RFC3339Nano), Capabilities: DefaultCapabilities(),
|
||||
ProviderProfile: ProviderProfileApollo, ProviderIdentity: "apollo-fixture-1#sha256:fixture-apollo-1",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := protocol.DecodeClientSessionAuthority(raw); err == nil {
|
||||
t.Fatalf("accepted provider-bearing RC3 authority: %s", raw)
|
||||
}
|
||||
}
|
||||
|
||||
type independentGatewayClient struct {
|
||||
connection *quic.Conn
|
||||
control *quic.Stream
|
||||
media independentMediaReassembler
|
||||
connection *quic.Conn
|
||||
control *quic.Stream
|
||||
authority protocol.ClientSessionAuthority
|
||||
authorityRaw []byte
|
||||
media independentMediaReassembler
|
||||
}
|
||||
|
||||
func dialIndependentGateway(ctx context.Context, address string, tlsConfig *tls.Config, request protocol.TunnelAdmissionRequest) (*independentGatewayClient, error) {
|
||||
@@ -994,17 +1046,20 @@ func dialIndependentGateway(ctx context.Context, address string, tlsConfig *tls.
|
||||
if err == nil {
|
||||
encoded, err = independentReadWire(stream, defaultHelloLimit)
|
||||
}
|
||||
var authority protocol.ClientSessionAuthority
|
||||
if err == nil {
|
||||
_, err = protocol.DecodeSessionAuthority(encoded)
|
||||
authority, err = protocol.DecodeClientSessionAuthority(encoded)
|
||||
}
|
||||
if err != nil {
|
||||
_ = connection.CloseWithError(applicationError, "independent client admission failed")
|
||||
return nil, err
|
||||
}
|
||||
return &independentGatewayClient{
|
||||
connection: connection,
|
||||
control: stream,
|
||||
media: independentMediaReassembler{incomplete: make(map[independentMediaKey]*independentMediaUnit)},
|
||||
connection: connection,
|
||||
control: stream,
|
||||
authority: authority,
|
||||
authorityRaw: encoded,
|
||||
media: independentMediaReassembler{incomplete: make(map[independentMediaKey]*independentMediaUnit)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1529,6 +1584,7 @@ func testTLS(t *testing.T) (*tls.Config, *tls.Config) {
|
||||
type oneTimeAdmission struct {
|
||||
used atomic.Bool
|
||||
authority protocol.SessionAuthority
|
||||
releaseAuthority protocol.SessionAuthority
|
||||
releases atomic.Int64
|
||||
released chan struct{}
|
||||
streamPolicy protocol.ProviderStreamPolicy
|
||||
@@ -1603,8 +1659,9 @@ func (a *oneTimeAdmission) ProviderWork(_ context.Context, authority protocol.Se
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *oneTimeAdmission) Release(context.Context, protocol.SessionAuthority) error {
|
||||
func (a *oneTimeAdmission) Release(_ context.Context, authority protocol.SessionAuthority) error {
|
||||
if a.releases.Add(1) == 1 {
|
||||
a.releaseAuthority = authority
|
||||
close(a.released)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -291,8 +291,11 @@ func (s *Server) handleConnection(parent context.Context, connection *quic.Conn)
|
||||
_ = writeStableError(stream, "provider_state_unavailable", err, true)
|
||||
return
|
||||
}
|
||||
authority.Capabilities = selected
|
||||
authorityBytes, err := protocol.EncodeSessionAuthority(authority)
|
||||
clientAuthority := protocol.ClientSessionAuthority{
|
||||
Version: authority.Version, SessionID: authority.SessionID, GatewayID: authority.GatewayID, Audience: authority.Audience,
|
||||
ReconnectSequence: authority.ReconnectSequence, ExpiresAt: authority.ExpiresAt, Capabilities: selected,
|
||||
}
|
||||
authorityBytes, err := protocol.EncodeClientSessionAuthority(clientAuthority)
|
||||
if err != nil || writeWire(stream, authorityBytes, defaultHelloLimit) != nil {
|
||||
_ = providerSession.ReleaseAll(context.Background())
|
||||
_ = providerSession.Terminate(context.Background())
|
||||
@@ -1010,7 +1013,7 @@ type Client struct {
|
||||
controlReadMu sync.Mutex
|
||||
controlWriteMu sync.Mutex
|
||||
pendingControl map[string][][]byte
|
||||
Authority protocol.SessionAuthority
|
||||
Authority protocol.ClientSessionAuthority
|
||||
}
|
||||
|
||||
func Dial(ctx context.Context, address string, tlsConfig *tls.Config, request protocol.TunnelAdmissionRequest) (*Client, error) {
|
||||
@@ -1045,7 +1048,7 @@ func Dial(ctx context.Context, address string, tlsConfig *tls.Config, request pr
|
||||
_ = connection.CloseWithError(applicationError, "no authority")
|
||||
return nil, err
|
||||
}
|
||||
authority, authorityErr := protocol.DecodeSessionAuthority(response)
|
||||
authority, authorityErr := protocol.DecodeClientSessionAuthority(response)
|
||||
if authorityErr != nil {
|
||||
stable, stableErr := protocol.DecodeStableError(response)
|
||||
if stableErr == nil {
|
||||
|
||||
Reference in New Issue
Block a user