Map VPN packet batches to fabric frames

This commit is contained in:
2026-05-16 00:44:30 +03:00
parent aa09c10252
commit 5d1523ec4e
3 changed files with 296 additions and 0 deletions
@@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/fabricproto"
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/mesh"
)
@@ -241,6 +242,83 @@ func TestFabricPacketInboxDropsEmptyPackets(t *testing.T) {
}
}
func TestFabricVPNPacketDataFrameRoundTrip(t *testing.T) {
packet := testIPv4TCPPacket([4]byte{10, 77, 0, 2}, [4]byte{192, 168, 200, 95}, 57032, 3389)
packet[33] = 0x18
now := time.Unix(1700000000, 123).UTC()
frame, err := NewFabricVPNPacketDataFrame(FabricVPNPacketFrameInput{
StreamID: 55,
Sequence: 9,
VPNConnectionID: "vpn-1",
Direction: FabricDirectionClientToGateway,
TrafficClass: FabricTrafficClassInteractive,
Packets: [][]byte{packet},
Now: now,
})
if err != nil {
t.Fatalf("new fabric vpn frame: %v", err)
}
if frame.Type != fabricproto.FrameData || frame.StreamID != 55 || frame.Sequence != 9 || frame.TrafficClass != fabricproto.TrafficClassInteractive {
t.Fatalf("frame = %+v", frame)
}
payload, err := DecodeFabricVPNPacketDataFrame(frame)
if err != nil {
t.Fatalf("decode fabric vpn frame: %v", err)
}
if payload.SchemaVersion != "rap.vpn_packet_batch.fabric.v1" ||
payload.VPNConnectionID != "vpn-1" ||
payload.Direction != FabricDirectionClientToGateway ||
!payload.SentAt.Equal(now) ||
len(payload.Packets) != 1 ||
string(payload.Packets[0]) != string(packet) {
t.Fatalf("payload = %+v", payload)
}
}
func TestFabricPacketInboxReceivesFabricSessionFrame(t *testing.T) {
inbox := NewFabricPacketInbox(4)
frame, err := NewFabricVPNPacketDataFrame(FabricVPNPacketFrameInput{
StreamID: 88,
Sequence: 1,
VPNConnectionID: "vpn-1",
Direction: FabricDirectionGatewayToClient,
Packets: [][]byte{[]byte("reply")},
})
if err != nil {
t.Fatalf("new fabric vpn frame: %v", err)
}
if err := inbox.DeliverFabricSessionFrame(context.Background(), frame); err != nil {
t.Fatalf("deliver fabric session frame: %v", err)
}
packets, err := inbox.Receive(context.Background(), "vpn-1", FabricDirectionGatewayToClient, time.Second)
if err != nil {
t.Fatalf("receive fabric session packet: %v", err)
}
if len(packets) != 1 || string(packets[0]) != "reply" {
t.Fatalf("packets = %#v", packets)
}
}
func TestFabricVPNPacketDataFrameInfersInteractiveTCPControl(t *testing.T) {
packet := testIPv4TCPPacket([4]byte{192, 168, 200, 95}, [4]byte{10, 77, 0, 2}, 3389, 57032)
packet[33] = 0x12
frame, err := NewFabricVPNPacketDataFrame(FabricVPNPacketFrameInput{
StreamID: 91,
Sequence: 1,
VPNConnectionID: "vpn-1",
Direction: FabricDirectionGatewayToClient,
TrafficClass: FabricTrafficClassBulk,
Packets: [][]byte{packet},
})
if err != nil {
t.Fatalf("new fabric vpn frame: %v", err)
}
if frame.TrafficClass != fabricproto.TrafficClassInteractive {
t.Fatalf("traffic class = %v, want interactive", frame.TrafficClass)
}
}
func TestFabricPacketInboxPrioritizesGatewayTCPControlPackets(t *testing.T) {
inbox := NewFabricPacketInbox(4)
normal := testIPv4TCPPacket([4]byte{185, 16, 148, 89}, [4]byte{10, 77, 0, 2}, 443, 56000)