fix(gateway): strip provider authority from client egress
Verify Data Plane / gateway (push) Failing after 4m32s

This commit is contained in:
sechmachine
2026-08-12 12:30:28 +07:00
parent 93246c14bf
commit 12ad2a4daa
4 changed files with 75 additions and 13 deletions
+65 -8
View File
@@ -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
+7 -4
View File
@@ -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 {