Refactor RDP proxy handling and update related tests

This commit is contained in:
2026-05-17 20:38:35 +03:00
parent 8e9402580f
commit d551e57fd5
172 changed files with 22117 additions and 2509 deletions
@@ -9,6 +9,7 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
"encoding/json"
"encoding/pem"
"math/big"
"strings"
@@ -341,6 +342,119 @@ func TestQUICFabricTransportLimitsStreamsPerConnection(t *testing.T) {
defer second.Close()
}
func TestQUICFabricTransportReusesInboundConnectionForReverseStream(t *testing.T) {
reverseTransport := NewQUICFabricTransport(nil)
defer reverseTransport.Close()
server, err := StartQUICFabricServer(context.Background(), QUICFabricServerConfig{
ListenAddr: "127.0.0.1:0",
TLSConfig: testQUICTLSConfig(t),
ReverseTransport: reverseTransport,
SyntheticForwardHandler: func(_ context.Context, envelope SyntheticEnvelope) (SyntheticEnvelope, error) {
envelope.To, envelope.From = envelope.From, PeerIdentity{ClusterID: envelope.ClusterID, NodeID: "node-r"}
return envelope, nil
},
})
if err != nil {
t.Fatalf("start quic fabric server: %v", err)
}
defer server.Close()
clientTransport := NewQUICFabricTransport(nil)
defer clientTransport.Close()
clientTransport.SetLocalPeerID("node-a")
clientTransport.SetInboundHandlers(func(_ context.Context, envelope ProductionEnvelope) (ProductionForwardResult, error) {
return ProductionForwardResult{
Accepted: true,
Delivered: true,
Forwarded: true,
By: PeerIdentity{ClusterID: envelope.ClusterID, NodeID: "node-a"},
MessageID: envelope.MessageID,
RouteID: envelope.RouteID,
}, nil
}, nil, nil)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
session, err := clientTransport.Connect(ctx, FabricTransportTarget{
PeerID: "node-r",
Endpoint: server.Addr().String(),
TLSConfig: &tls.Config{
InsecureSkipVerify: true,
NextProtos: []string{fabricQUICNextProto},
},
Timeout: time.Second,
InboundBuffer: 4,
ErrorBuffer: 4,
})
if err != nil {
t.Fatalf("client connect: %v", err)
}
defer session.Close()
deadline := time.Now().Add(time.Second)
for {
if reverseTransport.Snapshot().Stats.ReverseRegisters > 0 {
break
}
if time.Now().After(deadline) {
t.Fatalf("reverse hello did not register connection: %+v", reverseTransport.Snapshot())
}
time.Sleep(10 * time.Millisecond)
}
reverseSession, err := reverseTransport.Connect(ctx, FabricTransportTarget{
PeerID: "node-a",
Endpoint: "10.0.0.2:19443",
Transport: "relay_quic",
Timeout: time.Second,
InboundBuffer: 4,
ErrorBuffer: 4,
})
if err != nil {
t.Fatalf("reverse connect: %v", err)
}
defer reverseSession.Close()
productionPayload, err := json.Marshal(ProductionEnvelope{
FabricProtocolVersion: ProtocolVersion,
MessageID: "msg-1",
RouteID: "route-r-a",
ClusterID: "cluster-1",
SourceNodeID: "node-r",
DestinationNodeID: "node-a",
CurrentHopNodeID: "node-a",
NextHopNodeID: "node-a",
ChannelClass: ProductionChannelFabricControl,
MessageType: ProductionMessageFabricControl,
TTL: 4,
CreatedAt: time.Now().UTC(),
ExpiresAt: time.Now().UTC().Add(time.Minute),
PayloadHash: "unused-by-test-handler",
})
if err != nil {
t.Fatalf("marshal production: %v", err)
}
if err := reverseSession.Send(ctx, fabricproto.Frame{Type: fabricproto.FrameData, TrafficClass: fabricproto.TrafficClassReliable, StreamID: ProductionForwardQUICStreamID, Sequence: 2, Payload: productionPayload}); err != nil {
t.Fatalf("send reverse production: %v", err)
}
select {
case frame := <-reverseSession.Frames():
var response quicProductionForwardResponse
if err := json.Unmarshal(frame.Payload, &response); err != nil {
t.Fatalf("decode response: %v", err)
}
if !response.Result.Accepted || !response.Result.Delivered || response.Result.By.NodeID != "node-a" {
t.Fatalf("response = %+v", response)
}
case err := <-reverseSession.Errors():
t.Fatalf("reverse session error: %v", err)
case <-ctx.Done():
t.Fatal(ctx.Err())
}
snapshot := reverseTransport.Snapshot()
if snapshot.Stats.ReverseRegisters == 0 || snapshot.Stats.ReverseReuses == 0 {
t.Fatalf("reverse connection was not registered/reused: %+v", snapshot)
}
}
func TestQUICFabricServerHandlesFabricFrames(t *testing.T) {
var events []FabricSessionEventLogEntry
server, err := StartQUICFabricServer(context.Background(), QUICFabricServerConfig{
@@ -389,6 +503,68 @@ func TestQUICFabricServerHandlesFabricFrames(t *testing.T) {
}
}
func TestQUICFabricServerHandlesWebIngressForwardFrames(t *testing.T) {
var received []byte
server, err := StartQUICFabricServer(context.Background(), QUICFabricServerConfig{
ListenAddr: "127.0.0.1:0",
TLSConfig: testQUICTLSConfig(t),
WebIngressForwardHandler: func(_ context.Context, payload []byte) ([]byte, error) {
received = append([]byte(nil), payload...)
return []byte(`{"schema_version":"rap.web_ingress.fabric_runtime_response.v1","status_code":200,"body_b64":"b2s="}`), nil
},
})
if err != nil {
t.Fatalf("start quic fabric server: %v", err)
}
defer server.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
session, err := NewQUICFabricTransport(nil).Connect(ctx, FabricTransportTarget{
Endpoint: server.Addr().String(),
TLSConfig: &tls.Config{
InsecureSkipVerify: true,
NextProtos: []string{fabricQUICNextProto},
},
Timeout: time.Second,
InboundBuffer: 4,
ErrorBuffer: 4,
})
if err != nil {
t.Fatalf("connect quic fabric: %v", err)
}
defer session.Close()
if err := session.Send(ctx, fabricproto.Frame{
Type: fabricproto.FrameData,
TrafficClass: fabricproto.TrafficClassReliable,
StreamID: WebIngressForwardQUICStreamID,
Sequence: 44,
Payload: []byte(`{"envelope":true}`),
}); err != nil {
t.Fatalf("send web ingress frame: %v", err)
}
select {
case frame := <-session.Frames():
if frame.Type != fabricproto.FrameData || frame.StreamID != WebIngressForwardQUICStreamID || frame.Sequence != 44 {
t.Fatalf("frame = %+v", frame)
}
var response quicWebIngressForwardResponse
if err := json.Unmarshal(frame.Payload, &response); err != nil {
t.Fatalf("decode response: %v", err)
}
if string(response.Payload) != `{"schema_version":"rap.web_ingress.fabric_runtime_response.v1","status_code":200,"body_b64":"b2s="}` || response.Error != "" {
t.Fatalf("response = %+v", response)
}
case err := <-session.Errors():
t.Fatalf("session error: %v", err)
case <-ctx.Done():
t.Fatal(ctx.Err())
}
if string(received) != `{"envelope":true}` {
t.Fatalf("received = %s", string(received))
}
}
func startQUICFabricEchoServer(t *testing.T) *quic.Listener {
t.Helper()
return startQUICFabricEchoServerWithTLS(t, testQUICTLSConfig(t))