Refactor RDP proxy handling and update related tests
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user