Improve VPN client connection management
Build and Deploy Gateway / build-and-push (push) Successful in 20s
Build and Deploy Gateway / deploy (push) Successful in 13s

This commit is contained in:
2026-08-12 21:48:37 +03:00
parent 068a7f9890
commit 9e52ccc24d
22 changed files with 962 additions and 76 deletions
+36
View File
@@ -28,6 +28,16 @@ const snapshot = {
proxyDownloadBytes: '0',
proxyTrafficObservedAt: null,
}],
directTraffic: {
observedAt,
uploadBytes: '99',
downloadBytes: '999',
series: [{
deviceId: 'dev_0011223344556677',
uploadBytes: '77',
downloadBytes: '888',
}],
},
domainTraffic: {
observedAt,
overflowConnections: '2',
@@ -36,6 +46,19 @@ const snapshot = {
unknown_device: '4',
unsupported_source: '5',
},
tracked: [{
source: 'gateway',
outbound: 'vpn',
uploadBytes: '77',
downloadBytes: '777',
}],
routes: [{
deviceId: 'dev_0011223344556677',
source: 'gateway',
outbound: 'vpn',
uploadBytes: '55',
downloadBytes: '666',
}],
series: [{
deviceId: 'dev_0011223344556677',
domain: 'chatgpt.com',
@@ -58,6 +81,15 @@ test('Prometheus exposition keeps exact counters, stable identity and escaped na
assert.doesNotMatch(output, /harbor_device_traffic_bytes_total\{[^\n]*source="proxy"/);
assert.doesNotMatch(output, /00:11:22:33:44:55/);
assert.match(output, /harbor_device_traffic_last_observed_timestamp_seconds\{device_id="dev_0011223344556677",source="gateway"\} 1786183200/);
assert.match(output, /# TYPE harbor_direct_ipv4_packet_bytes_total counter/);
assert.match(output, /harbor_direct_ipv4_packet_bytes_total\{direction="download"\} 999/);
assert.match(output, /# TYPE harbor_device_direct_ipv4_packet_bytes_total counter/);
assert.match(output, /harbor_device_direct_ipv4_packet_bytes_total\{device_id="dev_0011223344556677",direction="download"\} 888/);
assert.match(output, /harbor_direct_ipv4_packet_last_observed_timestamp_seconds 1786183200/);
assert.match(output, /# TYPE harbor_singbox_tracked_bytes_total counter/);
assert.match(output, /harbor_singbox_tracked_bytes_total\{source="gateway",outbound="vpn",direction="download"\} 777/);
assert.match(output, /# TYPE harbor_device_singbox_tracked_bytes_total counter/);
assert.match(output, /harbor_device_singbox_tracked_bytes_total\{device_id="dev_0011223344556677",source="gateway",outbound="vpn",direction="upload"\} 55/);
assert.match(output, /harbor_device_domain_traffic_bytes_total\{device_id="dev_0011223344556677",domain="chatgpt\.com",service="OpenAI \/ ChatGPT",source="proxy",direction="download"\} 345/);
assert.match(output, /harbor_domain_traffic_last_observed_timestamp_seconds 1786183200/);
assert.match(output, /harbor_domain_traffic_overflow_connections_total 2/);
@@ -66,6 +98,7 @@ test('Prometheus exposition keeps exact counters, stable identity and escaped na
assert.match(output, /harbor_domain_traffic_attribution_events_total\{outcome="unknown_device"\} 4/);
assert.match(output, /harbor_domain_traffic_attribution_events_total\{outcome="unsupported_source"\} 5/);
assert.doesNotMatch(output, /harbor_device_domain_traffic_bytes_total\{[^\n]*name=/);
assert.doesNotMatch(output, /harbor_device_(?:direct_ipv4_packet|singbox_tracked)_bytes_total\{[^\n]*(?:name|ip|mac|server)=/);
assert.equal(output.endsWith('\n'), true);
});
@@ -99,6 +132,9 @@ test('invalid canonical counters fail the scrape instead of publishing corrupt v
() => sendPrometheusMetrics({ writeHead() { throw new Error('headers sent'); } }, invalid),
/Invalid Prometheus counter/,
);
const invalidRoute = structuredClone(snapshot);
invalidRoute.domainTraffic.routes[0].outbound = 'vpn-server-tag';
assert.throws(() => renderPrometheusMetrics(invalidRoute), /Invalid sing-box outbound labels/);
});
function routeResponse() {