рабочий вариант, но скороть 10 МБит
build / backend (push) Has been cancelled
build / node-agent (push) Has been cancelled
build / worker (push) Has been cancelled

This commit is contained in:
2026-05-22 21:46:49 +03:00
parent 469fa0e860
commit 20d361a886
280 changed files with 954890 additions and 18524 deletions
@@ -3,11 +3,14 @@ package fabricvpn
import (
"os"
"testing"
"time"
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/vpnruntime"
)
func TestFabricRuntimeEndpointsPreferRouteBundle(t *testing.T) {
cfg := runtimeConfig{
Endpoints: []endpointConfig{{EndpointID: "legacy", Address: "quic://legacy.example:19131"}},
Endpoints: []endpointConfig{{EndpointID: "compat", Address: "quic://compat.example:19131"}},
RouteBundle: routeBundleConfig{
EndpointCandidates: []endpointConfig{{EndpointID: "bundle", Address: "quic://bundle.example:19131"}},
},
@@ -20,7 +23,7 @@ func TestFabricRuntimeEndpointsPreferRouteBundle(t *testing.T) {
func TestFabricRuntimeEndpointsPreferRouteLease(t *testing.T) {
cfg := runtimeConfig{
Endpoints: []endpointConfig{{EndpointID: "legacy", Address: "quic://legacy.example:19131"}},
Endpoints: []endpointConfig{{EndpointID: "compat", Address: "quic://compat.example:19131"}},
RouteBundle: routeBundleConfig{
EndpointCandidates: []endpointConfig{{EndpointID: "bundle", Address: "quic://bundle.example:19131"}},
RouteLease: routeLeaseConfig{
@@ -41,13 +44,148 @@ func TestFabricRuntimeEndpointsPreferRouteLease(t *testing.T) {
}
}
func TestFabricRuntimeEndpointsFallbackToLegacyEndpoints(t *testing.T) {
func TestFabricRuntimePacketTargetIsLongLived(t *testing.T) {
cfg := runtimeConfig{
Endpoints: []endpointConfig{{EndpointID: "legacy", Address: "quic://legacy.example:19131"}},
RouteBundle: routeBundleConfig{RouteLease: routeLeaseConfig{
PrimaryPath: routeLeasePath{TargetNodeID: "exit-1"},
}},
}
target := fabricRuntimePacketTarget(cfg, endpointConfig{
EndpointID: "exit-public",
NodeID: "exit-1",
Address: "quic://203.0.113.10:19131",
Transport: "direct_quic",
PeerCertSHA256: "abc123",
})
if target.Timeout != 0 {
t.Fatalf("packet target timeout = %s, want 0 for long-lived vpn stream", target.Timeout)
}
if target.PeerID != "exit-1" || target.Endpoint != "quic://203.0.113.10:19131" || target.PeerCertSHA256 != "abc123" {
t.Fatalf("unexpected packet target: %+v", target)
}
}
func TestServiceTunnelFromRuntimeConfigCarriesRouteEpoch(t *testing.T) {
cfg := runtimeConfig{
TunnelID: "tunnel-1",
PoolID: "home-ipv4",
ServiceID: "svc-1",
ServiceKind: "ipv4-tunnel",
ServiceClass: "vpn_packets",
RouteLeaseID: "lease-1",
RouteGeneration: "route-gen-1",
StreamShards: 8,
}
tunnel := serviceTunnelFromRuntimeConfig(cfg)
if tunnel.RouteLeaseID != "lease-1" || tunnel.RouteGeneration != "route-gen-1" || tunnel.StreamShards != 8 {
t.Fatalf("service tunnel route epoch = %+v", tunnel)
}
}
func TestManagerUpdateRuntimeConfigKeepsTunnelAndUpdatesRouteEpoch(t *testing.T) {
manager := NewManager()
manager.cfg = runtimeConfig{
ClusterID: "cluster-1",
LocalNodeID: "android-1",
TunnelID: "tunnel-1",
PoolID: "home-ipv4",
ServiceID: "svc-1",
ServiceKind: "ipv4-tunnel",
ServiceClass: "vpn_packets",
RouteLeaseID: "lease-1",
RouteGeneration: "route-gen-1",
StreamShards: 4,
}
manager.packet = &vpnruntime.FabricSessionPacketTransport{
TunnelID: "tunnel-1",
ServiceTunnel: vpnruntime.FabricServiceTunnel{
TunnelID: "tunnel-1",
PoolID: "home-ipv4",
ServiceID: "svc-1",
RouteLeaseID: "lease-1",
RouteGeneration: "route-gen-1",
},
}
err := manager.UpdateRuntimeConfig(`{
"cluster_id":"cluster-1",
"local_node_id":"android-1",
"tunnel_id":"tunnel-1",
"pool_id":"home-ipv4",
"service_id":"svc-1",
"service_kind":"ipv4-tunnel",
"service_class":"vpn_packets",
"route_lease_id":"lease-2",
"route_generation":"route-gen-2",
"stream_shards":4,
"service_channel_request":{"schema_version":"rap.fabric_service_channel_request.v1"}
}`)
if err != nil {
t.Fatalf("update runtime config: %v", err)
}
snapshot := manager.packet.Snapshot()
if snapshot["route_lease_id"] != "lease-2" || snapshot["route_generation"] != "route-gen-2" || snapshot["route_transition_count"] != uint64(1) {
t.Fatalf("packet route epoch not updated: %+v", snapshot)
}
if err := manager.UpdateRuntimeConfig(`{"tunnel_id":"other-tunnel"}`); err == nil {
t.Fatal("expected changed tunnel id to be rejected")
}
}
func TestRuntimeRouteReconnectDecisionTracksTargetAndEndpoints(t *testing.T) {
current := runtimeConfig{
TunnelID: "tunnel-1",
Endpoints: []endpointConfig{{EndpointID: "exit-a", NodeID: "node-a", Address: "quic://node-a:19131", Transport: "direct_quic"}},
RouteBundle: routeBundleConfig{RouteLease: routeLeaseConfig{
PrimaryPath: routeLeasePath{TargetNodeID: "node-a"},
}},
}
sameLeaseNewGeneration := current
sameLeaseNewGeneration.RouteLeaseID = "lease-2"
sameLeaseNewGeneration.RouteGeneration = "route-gen-2"
if shouldReconnectForRuntimeRoute(current, sameLeaseNewGeneration) {
t.Fatal("same target/endpoints should update route epoch without reconnect")
}
newTarget := current
newTarget.RouteBundle.RouteLease.PrimaryPath.TargetNodeID = "node-b"
if !shouldReconnectForRuntimeRoute(current, newTarget) {
t.Fatal("changed target node should reconnect fabric session")
}
newEndpoint := current
newEndpoint.Endpoints = []endpointConfig{{EndpointID: "exit-b", NodeID: "node-b", Address: "quic://node-b:19131", Transport: "direct_quic"}}
if !shouldReconnectForRuntimeRoute(current, newEndpoint) {
t.Fatal("changed endpoint candidates should reconnect fabric session")
}
}
func TestPacketBatchSendTimeoutScalesWithPayload(t *testing.T) {
small := packetBatchSendTimeout([][]byte{make([]byte, 1200)})
large := packetBatchSendTimeout([][]byte{make([]byte, 4*1024*1024)})
if small != minPacketBatchSendTimeout {
t.Fatalf("small timeout = %s, want %s", small, minPacketBatchSendTimeout)
}
if large <= small {
t.Fatalf("large timeout = %s, want greater than %s", large, small)
}
many := make([][]byte, 2048)
for i := range many {
many[i] = make([]byte, 1200)
}
if got := packetBatchSendTimeout(many); got <= small {
t.Fatalf("many-packet timeout = %s, want greater than %s", got, small)
}
if got := packetBatchSendTimeout([][]byte{make([]byte, 100*1024*1024)}); got != maxPacketBatchSendTimeout {
t.Fatalf("capped timeout = %s, want %s", got, maxPacketBatchSendTimeout)
}
}
func TestFabricRuntimeEndpointsFallbackToDisallowedEndpoints(t *testing.T) {
cfg := runtimeConfig{
Endpoints: []endpointConfig{{EndpointID: "compat", Address: "quic://compat.example:19131"}},
}
got := fabricRuntimeEndpoints(cfg)
if len(got) != 1 || got[0].EndpointID != "legacy" {
t.Fatalf("endpoints = %+v, want legacy endpoint fallback", got)
if len(got) != 1 || got[0].EndpointID != "compat" {
t.Fatalf("endpoints = %+v, want compat endpoint fallback", got)
}
}
@@ -76,18 +214,18 @@ func TestLiveFabricVPNRuntimeStartsFromRouteLease(t *testing.T) {
t.Fatalf("receive live dns packet: %v", err)
}
if len(packet) > 0 {
if packet[9] != 17 || packet[12] != 1 || packet[13] != 1 || packet[14] != 1 || packet[15] != 1 {
t.Fatalf("unexpected response packet header: %v", packet[:min(20, len(packet))])
if len(packet) >= 20 && packet[9] == 17 && packet[12] == 1 && packet[13] == 1 && packet[14] == 1 && packet[15] == 1 {
return
}
return
}
}
t.Fatal("timed out waiting for live dns response through fabric vpn")
}
func testDNSIPv4Packet() []byte {
nonce := uint16(time.Now().UnixNano())
dns := []byte{
0x12, 0x34, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
byte(nonce >> 8), byte(nonce), 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 'e', 'x', 'a',
'm', 'p', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00,
0x00, 0x01, 0x00, 0x01,
@@ -102,8 +240,8 @@ func testDNSIPv4Packet() []byte {
packet[9] = 17
copy(packet[12:16], []byte{10, 77, 0, 2})
copy(packet[16:20], []byte{1, 1, 1, 1})
packet[20] = 0xcf
packet[21] = 0x08
packet[20] = byte(0xc0 | ((nonce >> 8) & 0x3f))
packet[21] = byte(nonce)
packet[22] = 0x00
packet[23] = 0x35
packet[24] = byte(udpLen >> 8)