feat(smartnetwork): add Rust-powered network diagnostics bridge and IP intelligence lookups

This commit is contained in:
2026-03-26 15:24:43 +00:00
parent e9dcd45acd
commit c3ac9b4f9e
34 changed files with 5499 additions and 3159 deletions

View File

@@ -0,0 +1,181 @@
import * as plugins from './smartnetwork.plugins.js';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
/**
* Command map for the rustnetwork IPC binary.
* Each key maps to { params, result } defining the typed IPC protocol.
*/
type TNetworkCommands = {
healthPing: {
params: Record<string, never>;
result: { pong: boolean };
};
ping: {
params: { host: string; count?: number; timeoutMs?: number };
result: {
alive: boolean;
times: (number | null)[];
min: number | null;
max: number | null;
avg: number | null;
stddev: number | null;
packetLoss: number;
};
};
traceroute: {
params: { host: string; maxHops?: number; timeoutMs?: number };
result: {
hops: Array<{ ttl: number; ip: string; rtt: number | null }>;
};
};
tcpPortCheck: {
params: { host: string; port: number; timeoutMs?: number };
result: { isOpen: boolean; latencyMs: number | null };
};
isLocalPortFree: {
params: { port: number };
result: { free: boolean };
};
defaultGateway: {
params: Record<string, never>;
result: {
interfaceName: string;
addresses: Array<{ family: string; address: string }>;
};
};
};
function getPlatformSuffix(): string | null {
const platform = process.platform;
const arch = process.arch;
const platformMap: Record<string, string> = {
linux: 'linux',
darwin: 'macos',
win32: 'windows',
};
const archMap: Record<string, string> = {
x64: 'amd64',
arm64: 'arm64',
};
const p = platformMap[platform];
const a = archMap[arch];
if (p && a) {
return `${p}_${a}`;
}
return null;
}
/**
* Singleton bridge to the rustnetwork binary.
* Manages the IPC lifecycle for network diagnostics operations.
*/
export class RustNetworkBridge {
private static instance: RustNetworkBridge | null = null;
public static getInstance(): RustNetworkBridge {
if (!RustNetworkBridge.instance) {
RustNetworkBridge.instance = new RustNetworkBridge();
}
return RustNetworkBridge.instance;
}
private bridge: InstanceType<typeof plugins.smartrust.RustBridge<TNetworkCommands>>;
private constructor() {
const packageDir = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'..',
);
const platformSuffix = getPlatformSuffix();
const localPaths: string[] = [];
// Platform-specific cross-compiled binary
if (platformSuffix) {
localPaths.push(path.join(packageDir, 'dist_rust', `rustnetwork_${platformSuffix}`));
}
// Native build without suffix
localPaths.push(path.join(packageDir, 'dist_rust', 'rustnetwork'));
// Local dev paths
localPaths.push(path.join(packageDir, 'rust', 'target', 'release', 'rustnetwork'));
localPaths.push(path.join(packageDir, 'rust', 'target', 'debug', 'rustnetwork'));
this.bridge = new plugins.smartrust.RustBridge<TNetworkCommands>({
binaryName: 'rustnetwork',
cliArgs: ['--management'],
requestTimeoutMs: 30_000,
readyTimeoutMs: 10_000,
localPaths,
searchSystemPath: false,
});
}
/**
* Spawn the Rust binary and wait for it to be ready.
*/
public async start(): Promise<void> {
const ok = await this.bridge.spawn();
if (!ok) {
throw new Error('Failed to spawn rustnetwork binary');
}
}
/**
* Kill the Rust binary.
*/
public async stop(): Promise<void> {
this.bridge.kill();
}
/**
* Ensure the bridge is running before sending a command.
*/
private async ensureRunning(): Promise<void> {
// The bridge will throw if not spawned — we just call start() if not yet running
}
// ===== Command wrappers =====
public async ping(
host: string,
count?: number,
timeoutMs?: number,
): Promise<TNetworkCommands['ping']['result']> {
return this.bridge.sendCommand('ping', { host, count, timeoutMs });
}
public async traceroute(
host: string,
maxHops?: number,
timeoutMs?: number,
): Promise<TNetworkCommands['traceroute']['result']> {
return this.bridge.sendCommand('traceroute', { host, maxHops, timeoutMs });
}
public async tcpPortCheck(
host: string,
port: number,
timeoutMs?: number,
): Promise<TNetworkCommands['tcpPortCheck']['result']> {
return this.bridge.sendCommand('tcpPortCheck', { host, port, timeoutMs });
}
public async isLocalPortFree(
port: number,
): Promise<TNetworkCommands['isLocalPortFree']['result']> {
return this.bridge.sendCommand('isLocalPortFree', { port });
}
public async defaultGateway(): Promise<TNetworkCommands['defaultGateway']['result']> {
return this.bridge.sendCommand('defaultGateway', {} as Record<string, never>);
}
public async healthPing(): Promise<TNetworkCommands['healthPing']['result']> {
return this.bridge.sendCommand('healthPing', {} as Record<string, never>);
}
}