omniwire 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -24
- package/dist/mcp/server.js +152 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/nodes/manager.js +67 -122
- package/dist/nodes/manager.js.map +1 -1
- package/dist/nodes/transfer.d.ts +1 -1
- package/dist/nodes/transfer.js +59 -51
- package/dist/nodes/transfer.js.map +1 -1
- package/package.json +1 -1
package/dist/nodes/manager.js
CHANGED
|
@@ -3,12 +3,24 @@ import { Client } from 'ssh2';
|
|
|
3
3
|
import { readFileSync } from 'node:fs';
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
5
|
import { remoteNodes, getHostCandidates } from '../protocol/config.js';
|
|
6
|
-
const MAX_OUTPUT_BYTES = 2 * 1024 * 1024;
|
|
7
|
-
const STATUS_CACHE_TTL = 5000;
|
|
8
|
-
const HEALTH_PING_INTERVAL = 30_000;
|
|
9
|
-
const CIRCUIT_OPEN_DURATION =
|
|
6
|
+
const MAX_OUTPUT_BYTES = 2 * 1024 * 1024;
|
|
7
|
+
const STATUS_CACHE_TTL = 5000;
|
|
8
|
+
const HEALTH_PING_INTERVAL = 30_000;
|
|
9
|
+
const CIRCUIT_OPEN_DURATION = 15_000; // 15s circuit breaker — faster recovery
|
|
10
10
|
const CIRCUIT_FAILURE_THRESHOLD = 3;
|
|
11
|
-
const CONNECT_TIMEOUT =
|
|
11
|
+
const CONNECT_TIMEOUT = 5000; // 5s connection timeout
|
|
12
|
+
// Prefer fast ciphers + key exchange for lowest latency
|
|
13
|
+
const PREFERRED_CIPHERS = [
|
|
14
|
+
'aes128-gcm@openssh.com', // AES-NI accelerated, lowest overhead
|
|
15
|
+
'chacha20-poly1305@openssh.com', // fast on non-AES-NI CPUs
|
|
16
|
+
'aes256-gcm@openssh.com',
|
|
17
|
+
'aes128-ctr',
|
|
18
|
+
];
|
|
19
|
+
const PREFERRED_KEX = [
|
|
20
|
+
'curve25519-sha256', // fastest modern key exchange
|
|
21
|
+
'curve25519-sha256@libssh.org',
|
|
22
|
+
'ecdh-sha2-nistp256',
|
|
23
|
+
];
|
|
12
24
|
export class NodeManager {
|
|
13
25
|
connections = new Map();
|
|
14
26
|
reconnectCallbacks = [];
|
|
@@ -16,7 +28,6 @@ export class NodeManager {
|
|
|
16
28
|
statusCache = new Map();
|
|
17
29
|
healthTimer = null;
|
|
18
30
|
keyCache = new Map();
|
|
19
|
-
// Cache SSH keys to avoid repeated disk reads
|
|
20
31
|
getKey(path) {
|
|
21
32
|
let key = this.keyCache.get(path);
|
|
22
33
|
if (!key) {
|
|
@@ -30,7 +41,6 @@ export class NodeManager {
|
|
|
30
41
|
await Promise.allSettled(nodes.map((node) => this.connectWithFallback(node)));
|
|
31
42
|
this.startHealthPing();
|
|
32
43
|
}
|
|
33
|
-
// Try each host candidate (WG -> Tailscale -> Public) until one connects
|
|
34
44
|
async connectWithFallback(node) {
|
|
35
45
|
if (node.isLocal)
|
|
36
46
|
return;
|
|
@@ -51,14 +61,8 @@ export class NodeManager {
|
|
|
51
61
|
const client = new Client();
|
|
52
62
|
const existing = this.connections.get(node.id);
|
|
53
63
|
const conn = existing ?? {
|
|
54
|
-
node,
|
|
55
|
-
|
|
56
|
-
connected: false,
|
|
57
|
-
activeHost: null,
|
|
58
|
-
lastPing: null,
|
|
59
|
-
reconnecting: false,
|
|
60
|
-
failures: 0,
|
|
61
|
-
circuitOpenUntil: 0,
|
|
64
|
+
node, client, connected: false, activeHost: null,
|
|
65
|
+
lastPing: null, reconnecting: false, failures: 0, circuitOpenUntil: 0,
|
|
62
66
|
};
|
|
63
67
|
conn.client = client;
|
|
64
68
|
this.connections.set(node.id, conn);
|
|
@@ -91,10 +95,12 @@ export class NodeManager {
|
|
|
91
95
|
username: node.user,
|
|
92
96
|
privateKey: this.getKey(node.identityFile),
|
|
93
97
|
readyTimeout: CONNECT_TIMEOUT,
|
|
94
|
-
keepaliveInterval:
|
|
95
|
-
keepaliveCountMax: 2,
|
|
98
|
+
keepaliveInterval: 2000, // 2s keepalive — fastest dead detection
|
|
99
|
+
keepaliveCountMax: 2, // 4s total before disconnect
|
|
96
100
|
algorithms: {
|
|
97
|
-
|
|
101
|
+
cipher: PREFERRED_CIPHERS,
|
|
102
|
+
kex: PREFERRED_KEX,
|
|
103
|
+
compress: ['none'],
|
|
98
104
|
},
|
|
99
105
|
};
|
|
100
106
|
client.connect(config);
|
|
@@ -105,22 +111,21 @@ export class NodeManager {
|
|
|
105
111
|
if (!conn || conn.reconnecting)
|
|
106
112
|
return;
|
|
107
113
|
conn.reconnecting = true;
|
|
108
|
-
const currentDelay = this.reconnectDelays.get(node.id) ??
|
|
109
|
-
const jitter = Math.floor(Math.random() *
|
|
114
|
+
const currentDelay = this.reconnectDelays.get(node.id) ?? 300; // start at 300ms
|
|
115
|
+
const jitter = Math.floor(Math.random() * 500);
|
|
110
116
|
setTimeout(async () => {
|
|
111
117
|
try {
|
|
112
118
|
await this.connectWithFallback(node);
|
|
113
119
|
conn.reconnecting = false;
|
|
114
120
|
conn.failures = 0;
|
|
115
121
|
conn.circuitOpenUntil = 0;
|
|
116
|
-
this.reconnectDelays.set(node.id,
|
|
122
|
+
this.reconnectDelays.set(node.id, 300);
|
|
117
123
|
for (const cb of this.reconnectCallbacks)
|
|
118
124
|
cb(node.id);
|
|
119
125
|
}
|
|
120
126
|
catch {
|
|
121
127
|
conn.reconnecting = false;
|
|
122
|
-
|
|
123
|
-
this.reconnectDelays.set(node.id, Math.min(currentDelay * 2, 15_000));
|
|
128
|
+
this.reconnectDelays.set(node.id, Math.min(currentDelay * 2, 10_000)); // 10s cap
|
|
124
129
|
this.scheduleReconnect(node);
|
|
125
130
|
}
|
|
126
131
|
}, currentDelay + jitter);
|
|
@@ -150,36 +155,23 @@ export class NodeManager {
|
|
|
150
155
|
}
|
|
151
156
|
return online;
|
|
152
157
|
}
|
|
153
|
-
// Remote execution via SSH2 client.exec()
|
|
154
|
-
// All commands run on remote nodes over authenticated SSH channels
|
|
158
|
+
// Remote execution via SSH2 client.exec() -- NOT child_process.exec()
|
|
155
159
|
async exec(nodeId, command) {
|
|
156
160
|
const start = Date.now();
|
|
157
161
|
if (nodeId === 'windows') {
|
|
158
162
|
return this.execLocal(command, start);
|
|
159
163
|
}
|
|
160
164
|
const conn = this.connections.get(nodeId);
|
|
161
|
-
// Circuit breaker: skip if circuit is open
|
|
162
165
|
if (conn && conn.circuitOpenUntil > Date.now()) {
|
|
163
|
-
return {
|
|
164
|
-
nodeId,
|
|
165
|
-
stdout: '',
|
|
166
|
-
stderr: `Node ${nodeId} circuit open (${conn.failures} consecutive failures)`,
|
|
167
|
-
code: -1,
|
|
168
|
-
durationMs: Date.now() - start,
|
|
169
|
-
};
|
|
166
|
+
return { nodeId, stdout: '', stderr: `Node ${nodeId} circuit open`, code: -1, durationMs: Date.now() - start };
|
|
170
167
|
}
|
|
171
168
|
if (!conn?.connected) {
|
|
172
|
-
return {
|
|
173
|
-
nodeId,
|
|
174
|
-
stdout: '',
|
|
175
|
-
stderr: `Node ${nodeId} is offline`,
|
|
176
|
-
code: -1,
|
|
177
|
-
durationMs: Date.now() - start,
|
|
178
|
-
};
|
|
169
|
+
return { nodeId, stdout: '', stderr: `Node ${nodeId} is offline`, code: -1, durationMs: Date.now() - start };
|
|
179
170
|
}
|
|
180
171
|
return new Promise((resolve) => {
|
|
181
|
-
|
|
182
|
-
|
|
172
|
+
const chunks = []; // array join is faster than string concat
|
|
173
|
+
const errChunks = [];
|
|
174
|
+
let totalBytes = 0;
|
|
183
175
|
let truncated = false;
|
|
184
176
|
conn.client.exec(command, (err, stream) => {
|
|
185
177
|
if (err) {
|
|
@@ -187,44 +179,36 @@ export class NodeManager {
|
|
|
187
179
|
if (conn.failures >= CIRCUIT_FAILURE_THRESHOLD) {
|
|
188
180
|
conn.circuitOpenUntil = Date.now() + CIRCUIT_OPEN_DURATION;
|
|
189
181
|
}
|
|
190
|
-
resolve({
|
|
191
|
-
nodeId,
|
|
192
|
-
stdout: '',
|
|
193
|
-
stderr: err.message,
|
|
194
|
-
code: -1,
|
|
195
|
-
durationMs: Date.now() - start,
|
|
196
|
-
});
|
|
182
|
+
resolve({ nodeId, stdout: '', stderr: err.message, code: -1, durationMs: Date.now() - start });
|
|
197
183
|
return;
|
|
198
184
|
}
|
|
199
185
|
stream.on('data', (data) => {
|
|
200
|
-
if (!truncated
|
|
201
|
-
|
|
202
|
-
|
|
186
|
+
if (!truncated) {
|
|
187
|
+
const str = data.toString();
|
|
188
|
+
totalBytes += str.length;
|
|
189
|
+
if (totalBytes < MAX_OUTPUT_BYTES) {
|
|
190
|
+
chunks.push(str);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
203
193
|
truncated = true;
|
|
194
|
+
}
|
|
204
195
|
}
|
|
205
196
|
});
|
|
206
197
|
stream.stderr.on('data', (data) => {
|
|
207
|
-
|
|
208
|
-
|
|
198
|
+
const str = data.toString();
|
|
199
|
+
if (errChunks.join('').length < MAX_OUTPUT_BYTES) {
|
|
200
|
+
errChunks.push(str);
|
|
209
201
|
}
|
|
210
202
|
});
|
|
211
203
|
stream.on('close', (code) => {
|
|
212
204
|
conn.lastPing = new Date();
|
|
213
|
-
conn.failures = 0;
|
|
214
|
-
const
|
|
215
|
-
resolve({
|
|
216
|
-
nodeId,
|
|
217
|
-
stdout: stdout.trimEnd() + suffix,
|
|
218
|
-
stderr: stderr.trimEnd(),
|
|
219
|
-
code: code ?? 0,
|
|
220
|
-
durationMs: Date.now() - start,
|
|
221
|
-
});
|
|
205
|
+
conn.failures = 0;
|
|
206
|
+
const stdout = chunks.join('').trimEnd() + (truncated ? '\n[truncated at 2MB]' : '');
|
|
207
|
+
resolve({ nodeId, stdout, stderr: errChunks.join('').trimEnd(), code: code ?? 0, durationMs: Date.now() - start });
|
|
222
208
|
});
|
|
223
209
|
});
|
|
224
210
|
});
|
|
225
211
|
}
|
|
226
|
-
// Local execution uses execFile with bash -c to avoid shell injection
|
|
227
|
-
// Command strings here come from the user's own terminal input, not external sources
|
|
228
212
|
execLocal(command, start) {
|
|
229
213
|
return new Promise((resolve) => {
|
|
230
214
|
execFile('bash', ['-c', command], {
|
|
@@ -242,77 +226,38 @@ export class NodeManager {
|
|
|
242
226
|
});
|
|
243
227
|
}
|
|
244
228
|
async execAll(command) {
|
|
245
|
-
|
|
246
|
-
return Promise.all(nodeIds.map((id) => this.exec(id, command)));
|
|
229
|
+
return Promise.all(this.getOnlineNodes().map((id) => this.exec(id, command)));
|
|
247
230
|
}
|
|
248
231
|
async execRemote(command) {
|
|
249
|
-
|
|
250
|
-
return Promise.all(nodeIds.map((id) => this.exec(id, command)));
|
|
232
|
+
return Promise.all(this.getOnlineNodes().filter((id) => id !== 'windows').map((id) => this.exec(id, command)));
|
|
251
233
|
}
|
|
252
234
|
async execOn(nodeIds, command) {
|
|
253
235
|
return Promise.all(nodeIds.map((id) => this.exec(id, command)));
|
|
254
236
|
}
|
|
255
237
|
async getNodeStatus(nodeId) {
|
|
256
238
|
if (nodeId === 'windows') {
|
|
257
|
-
return {
|
|
258
|
-
nodeId: 'windows',
|
|
259
|
-
online: true,
|
|
260
|
-
latencyMs: 0,
|
|
261
|
-
lastSeen: new Date(),
|
|
262
|
-
uptime: null,
|
|
263
|
-
loadAvg: null,
|
|
264
|
-
memUsedPct: null,
|
|
265
|
-
diskUsedPct: null,
|
|
266
|
-
};
|
|
239
|
+
return { nodeId: 'windows', online: true, latencyMs: 0, lastSeen: new Date(), uptime: null, loadAvg: null, memUsedPct: null, diskUsedPct: null };
|
|
267
240
|
}
|
|
268
|
-
// Return cached status if fresh enough
|
|
269
241
|
const cached = this.statusCache.get(nodeId);
|
|
270
|
-
if (cached && Date.now() - cached.at < STATUS_CACHE_TTL)
|
|
242
|
+
if (cached && Date.now() - cached.at < STATUS_CACHE_TTL)
|
|
271
243
|
return cached.status;
|
|
272
|
-
}
|
|
273
244
|
if (!this.isConnected(nodeId)) {
|
|
274
|
-
const status = {
|
|
275
|
-
nodeId,
|
|
276
|
-
online: false,
|
|
277
|
-
latencyMs: null,
|
|
278
|
-
lastSeen: this.connections.get(nodeId)?.lastPing ?? null,
|
|
279
|
-
uptime: null,
|
|
280
|
-
loadAvg: null,
|
|
281
|
-
memUsedPct: null,
|
|
282
|
-
diskUsedPct: null,
|
|
283
|
-
};
|
|
245
|
+
const status = { nodeId, online: false, latencyMs: null, lastSeen: this.connections.get(nodeId)?.lastPing ?? null, uptime: null, loadAvg: null, memUsedPct: null, diskUsedPct: null };
|
|
284
246
|
this.statusCache.set(nodeId, { status, at: Date.now() });
|
|
285
247
|
return status;
|
|
286
248
|
}
|
|
287
249
|
const start = Date.now();
|
|
288
|
-
|
|
250
|
+
// Single compact command — all metrics in one fork, no pipes
|
|
251
|
+
const result = await this.exec(nodeId, "awk '{u=$2-$1;t=$2;if(t>0)printf \"%.0f\\n\",u/t*100}' /proc/stat 2>/dev/null|head -1;cat /proc/loadavg 2>/dev/null|cut -d' ' -f1-3;awk '/MemTotal/{t=$2}/MemAvailable/{a=$2}END{if(t>0)printf \"%.1f\\n\",(t-a)/t*100}' /proc/meminfo;df / 2>/dev/null|awk 'NR==2{print $5}'|tr -d '%';uptime -p 2>/dev/null");
|
|
289
252
|
const latency = Date.now() - start;
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
loadAvg: null,
|
|
299
|
-
memUsedPct: null,
|
|
300
|
-
diskUsedPct: null,
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
const lines = result.stdout.split('\n');
|
|
305
|
-
status = {
|
|
306
|
-
nodeId,
|
|
307
|
-
online: true,
|
|
308
|
-
latencyMs: latency,
|
|
309
|
-
lastSeen: new Date(),
|
|
310
|
-
uptime: lines[0] ?? null,
|
|
311
|
-
loadAvg: lines[1] ?? null,
|
|
312
|
-
memUsedPct: parseFloat(lines[2]) || null,
|
|
313
|
-
diskUsedPct: parseFloat(lines[3]) || null,
|
|
314
|
-
};
|
|
315
|
-
}
|
|
253
|
+
const lines = result.stdout.split('\n');
|
|
254
|
+
const status = {
|
|
255
|
+
nodeId, online: true, latencyMs: latency, lastSeen: new Date(),
|
|
256
|
+
uptime: lines[4] ?? null,
|
|
257
|
+
loadAvg: lines[1] ?? null,
|
|
258
|
+
memUsedPct: parseFloat(lines[2]) || null,
|
|
259
|
+
diskUsedPct: parseFloat(lines[3]) || null,
|
|
260
|
+
};
|
|
316
261
|
this.statusCache.set(nodeId, { status, at: Date.now() });
|
|
317
262
|
return status;
|
|
318
263
|
}
|
|
@@ -347,16 +292,16 @@ export class NodeManager {
|
|
|
347
292
|
});
|
|
348
293
|
});
|
|
349
294
|
}
|
|
350
|
-
//
|
|
295
|
+
// Parallel health pings with minimal overhead (echo > true — avoids hash lookup)
|
|
351
296
|
startHealthPing() {
|
|
352
297
|
this.healthTimer = setInterval(() => {
|
|
353
298
|
const pings = [...this.connections.entries()]
|
|
354
299
|
.filter(([, conn]) => conn.connected && conn.circuitOpenUntil <= Date.now())
|
|
355
300
|
.map(async ([nodeId]) => {
|
|
356
301
|
const start = Date.now();
|
|
357
|
-
const result = await this.exec(nodeId, '
|
|
302
|
+
const result = await this.exec(nodeId, ':'); // ':' is bash builtin — zero fork
|
|
358
303
|
const elapsed = Date.now() - start;
|
|
359
|
-
if (elapsed >
|
|
304
|
+
if (elapsed > 2000 || result.code !== 0) {
|
|
360
305
|
process.stderr.write(`[health] ${nodeId} degraded (${elapsed}ms)\n`);
|
|
361
306
|
}
|
|
362
307
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/nodes/manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/nodes/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/nodes/transfer.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare class TransferEngine {
|
|
|
12
12
|
private transferNetcat;
|
|
13
13
|
private transferAria2c;
|
|
14
14
|
private transferSshPipe;
|
|
15
|
-
private
|
|
15
|
+
private transferSftpStream;
|
|
16
16
|
readFile(nodeId: string, path: string): Promise<string>;
|
|
17
17
|
writeFile(nodeId: string, path: string, content: string): Promise<void>;
|
|
18
18
|
stat(nodeId: string, path: string): Promise<FileInfo>;
|
package/dist/nodes/transfer.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
// OmniWire Transfer Engine — raw TCP transfers over WireGuard mesh
|
|
2
2
|
// Modes: netcat+tar (fastest), aria2c (large files), SSH pipe (small files)
|
|
3
3
|
// NOTE: All commands execute via SSH on remote Linux nodes (not local shell).
|
|
4
|
-
// The manager.exec() method uses ssh2 client.exec() for remote nodes, which
|
|
5
|
-
// does not involve local shell interpretation. Path inputs come from trusted
|
|
6
|
-
// terminal/MCP context (operator's own commands).
|
|
7
4
|
import { findNode } from '../protocol/config.js';
|
|
8
|
-
const STAT_CACHE_TTL = 10_000;
|
|
5
|
+
const STAT_CACHE_TTL = 10_000;
|
|
9
6
|
export class TransferEngine {
|
|
10
7
|
manager;
|
|
11
8
|
statCache = new Map();
|
|
@@ -14,7 +11,6 @@ export class TransferEngine {
|
|
|
14
11
|
}
|
|
15
12
|
async transfer(srcNode, srcPath, dstNode, dstPath, opts) {
|
|
16
13
|
const start = Date.now();
|
|
17
|
-
// Determine file size for auto mode selection
|
|
18
14
|
const stat = await this.stat(srcNode, srcPath);
|
|
19
15
|
const mode = opts?.mode ?? this.selectMode(stat.size, stat.isDirectory);
|
|
20
16
|
let bytesTransferred = stat.size;
|
|
@@ -30,28 +26,23 @@ export class TransferEngine {
|
|
|
30
26
|
break;
|
|
31
27
|
}
|
|
32
28
|
const durationMs = Date.now() - start;
|
|
33
|
-
const speedMBps = durationMs > 0 ? (bytesTransferred /
|
|
29
|
+
const speedMBps = durationMs > 0 ? (bytesTransferred / 1048576) / (durationMs / 1000) : 0;
|
|
34
30
|
return { srcNode, dstNode, srcPath, dstPath, mode, bytesTransferred, durationMs, speedMBps };
|
|
35
31
|
}
|
|
36
32
|
selectMode(sizeBytes, isDirectory) {
|
|
37
33
|
if (isDirectory)
|
|
38
34
|
return 'netcat-tar';
|
|
39
35
|
if (sizeBytes < 10 * 1024 * 1024)
|
|
40
|
-
return 'ssh-pipe';
|
|
36
|
+
return 'ssh-pipe';
|
|
41
37
|
if (sizeBytes > 1024 * 1024 * 1024)
|
|
42
|
-
return 'aria2c';
|
|
43
|
-
return 'netcat-tar';
|
|
38
|
+
return 'aria2c';
|
|
39
|
+
return 'netcat-tar';
|
|
44
40
|
}
|
|
45
|
-
//
|
|
46
|
-
// Uses manager.exec() which runs via SSH2 client.exec(), not child_process
|
|
41
|
+
// Fastest port finder — pure bash, no python fork
|
|
47
42
|
async findFreePort(nodeId) {
|
|
48
|
-
const result = await this.manager.exec(nodeId,
|
|
43
|
+
const result = await this.manager.exec(nodeId, "shuf -i 49152-65535 -n 1");
|
|
49
44
|
const port = parseInt(result.stdout.trim());
|
|
50
|
-
|
|
51
|
-
// Fallback: random port
|
|
52
|
-
return 49152 + Math.floor(Math.random() * (65535 - 49152));
|
|
53
|
-
}
|
|
54
|
-
return port;
|
|
45
|
+
return (port && !isNaN(port)) ? port : 49152 + Math.floor(Math.random() * 16383);
|
|
55
46
|
}
|
|
56
47
|
async transferNetcat(srcNode, srcPath, dstNode, dstPath, isDirectory) {
|
|
57
48
|
const dstIp = findNode(dstNode)?.host;
|
|
@@ -61,17 +52,23 @@ export class TransferEngine {
|
|
|
61
52
|
const dstDir = isDirectory ? dstPath : dstPath.substring(0, dstPath.lastIndexOf('/')) || '/tmp';
|
|
62
53
|
const srcDir = srcPath.substring(0, srcPath.lastIndexOf('/')) || '/';
|
|
63
54
|
const srcName = srcPath.substring(srcPath.lastIndexOf('/') + 1);
|
|
64
|
-
//
|
|
65
|
-
|
|
55
|
+
// Try lz4 first (10x faster than gzip), fallback to gzip
|
|
56
|
+
// Start receiver + sender with minimal delay
|
|
57
|
+
const hasLz4 = await this.manager.exec(dstNode, 'command -v lz4 >/dev/null && echo y || echo n');
|
|
58
|
+
const useLz4 = hasLz4.stdout.trim() === 'y';
|
|
59
|
+
const compress = useLz4 ? 'lz4 -1' : 'gzip -1';
|
|
60
|
+
const decompress = useLz4 ? 'lz4 -d' : 'gzip -d';
|
|
61
|
+
const receiverCmd = `timeout 30 bash -c 'nc -l -p ${port} | ${decompress} | tar xf - -C "${dstDir}"'`;
|
|
66
62
|
const receiverPromise = this.manager.exec(dstNode, `mkdir -p "${dstDir}" && ${receiverCmd}`);
|
|
67
|
-
//
|
|
68
|
-
await new Promise((r) => setTimeout(r,
|
|
69
|
-
// Start sender — gzip compressed
|
|
63
|
+
// 50ms is enough for nc to bind — tested on WireGuard mesh
|
|
64
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
70
65
|
const senderCmd = isDirectory
|
|
71
|
-
? `tar
|
|
72
|
-
: `tar
|
|
73
|
-
const senderResult = await
|
|
74
|
-
|
|
66
|
+
? `tar cf - -C "${srcPath}" . | ${compress} | nc -w 10 ${dstIp} ${port}`
|
|
67
|
+
: `tar cf - -C "${srcDir}" "${srcName}" | ${compress} | nc -w 10 ${dstIp} ${port}`;
|
|
68
|
+
const [senderResult] = await Promise.all([
|
|
69
|
+
this.manager.exec(srcNode, senderCmd),
|
|
70
|
+
receiverPromise,
|
|
71
|
+
]);
|
|
75
72
|
if (senderResult.code !== 0) {
|
|
76
73
|
throw new Error(`netcat transfer failed: ${senderResult.stderr}`);
|
|
77
74
|
}
|
|
@@ -86,10 +83,9 @@ export class TransferEngine {
|
|
|
86
83
|
const srcDir = srcPath.substring(0, srcPath.lastIndexOf('/')) || '/';
|
|
87
84
|
const fileName = srcPath.substring(srcPath.lastIndexOf('/') + 1);
|
|
88
85
|
const dstDir = dstPath.substring(0, dstPath.lastIndexOf('/')) || '/tmp';
|
|
89
|
-
// Start HTTP server on source (background, auto-kill after transfer)
|
|
90
86
|
const serverCmd = `cd "${srcDir}" && timeout 300 python3 -m http.server ${port} --bind 0.0.0.0 &`;
|
|
91
87
|
await this.manager.exec(srcNode, `bash -c '${serverCmd}'`);
|
|
92
|
-
await new Promise((r) => setTimeout(r,
|
|
88
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
93
89
|
try {
|
|
94
90
|
const downloadCmd = `mkdir -p "${dstDir}" && aria2c -x16 -s16 --allow-overwrite=true -d "${dstDir}" -o "${fileName}" "http://${srcIp}:${port}/${fileName}" 2>&1`;
|
|
95
91
|
const result = await this.manager.exec(dstNode, downloadCmd);
|
|
@@ -103,29 +99,26 @@ export class TransferEngine {
|
|
|
103
99
|
return parseInt(sizeResult.stdout.trim()) || 0;
|
|
104
100
|
}
|
|
105
101
|
async transferSshPipe(srcNode, srcPath, dstNode, dstPath) {
|
|
106
|
-
// Try SFTP first (binary-safe, no encoding overhead)
|
|
107
102
|
const srcClient = this.manager.getClient(srcNode);
|
|
108
103
|
const dstClient = this.manager.getClient(dstNode);
|
|
109
104
|
if (srcClient && dstClient) {
|
|
110
105
|
try {
|
|
111
|
-
return await this.
|
|
106
|
+
return await this.transferSftpStream(srcClient, dstClient, srcPath, dstPath);
|
|
112
107
|
}
|
|
113
108
|
catch (sftpErr) {
|
|
114
|
-
// SFTP failed — only fall through to base64 for small files (< 1MB arg limit)
|
|
115
109
|
const stat = await this.manager.exec(srcNode, `stat -c%s "${srcPath}" 2>/dev/null || echo 0`);
|
|
116
110
|
const fileSize = parseInt(stat.stdout.trim()) || 0;
|
|
117
111
|
if (fileSize > 1_000_000) {
|
|
118
|
-
throw new Error(`SFTP
|
|
112
|
+
throw new Error(`SFTP failed, file too large for base64 (${fileSize}B): ${sftpErr.message}`);
|
|
119
113
|
}
|
|
120
114
|
}
|
|
121
115
|
}
|
|
122
|
-
// Fallback: base64
|
|
116
|
+
// Fallback: base64 for tiny files
|
|
123
117
|
const b64Result = await this.manager.exec(srcNode, `base64 "${srcPath}"`);
|
|
124
118
|
if (b64Result.code !== 0)
|
|
125
119
|
throw new Error(`Failed to encode ${srcPath}: ${b64Result.stderr}`);
|
|
126
120
|
const dstDir = dstPath.substring(0, dstPath.lastIndexOf('/')) || '/tmp';
|
|
127
121
|
const b64Content = b64Result.stdout;
|
|
128
|
-
// Use printf + base64 -d to avoid heredoc issues with special content
|
|
129
122
|
const writeCmd = `mkdir -p "${dstDir}" && printf '%s' '${b64Content.replace(/'/g, "'\\''")}' | base64 -d > "${dstPath}"`;
|
|
130
123
|
const writeResult = await this.manager.exec(dstNode, writeCmd);
|
|
131
124
|
if (writeResult.code !== 0)
|
|
@@ -133,19 +126,19 @@ export class TransferEngine {
|
|
|
133
126
|
const sizeResult = await this.manager.exec(dstNode, `stat -c%s "${dstPath}" 2>/dev/null || echo 0`);
|
|
134
127
|
return parseInt(sizeResult.stdout.trim()) || 0;
|
|
135
128
|
}
|
|
136
|
-
//
|
|
137
|
-
|
|
129
|
+
// Stream-based SFTP — reads into buffer once, writes once. No double callback nesting.
|
|
130
|
+
transferSftpStream(srcClient, dstClient, srcPath, dstPath) {
|
|
138
131
|
return new Promise((resolve, reject) => {
|
|
139
|
-
srcClient.sftp((
|
|
140
|
-
if (
|
|
141
|
-
return reject(
|
|
132
|
+
srcClient.sftp((err, srcSftp) => {
|
|
133
|
+
if (err)
|
|
134
|
+
return reject(err);
|
|
142
135
|
srcSftp.readFile(srcPath, (readErr, data) => {
|
|
143
136
|
srcSftp.end();
|
|
144
137
|
if (readErr)
|
|
145
138
|
return reject(readErr);
|
|
146
|
-
dstClient.sftp((
|
|
147
|
-
if (
|
|
148
|
-
return reject(
|
|
139
|
+
dstClient.sftp((dstErr, dstSftp) => {
|
|
140
|
+
if (dstErr)
|
|
141
|
+
return reject(dstErr);
|
|
149
142
|
dstSftp.writeFile(dstPath, data, (writeErr) => {
|
|
150
143
|
dstSftp.end();
|
|
151
144
|
if (writeErr)
|
|
@@ -158,6 +151,27 @@ export class TransferEngine {
|
|
|
158
151
|
});
|
|
159
152
|
}
|
|
160
153
|
async readFile(nodeId, path) {
|
|
154
|
+
// Try SFTP first — faster for larger files, avoids cat shell overhead
|
|
155
|
+
const client = this.manager.getClient(nodeId);
|
|
156
|
+
if (client) {
|
|
157
|
+
try {
|
|
158
|
+
return await new Promise((resolve, reject) => {
|
|
159
|
+
client.sftp((err, sftp) => {
|
|
160
|
+
if (err)
|
|
161
|
+
return reject(err);
|
|
162
|
+
sftp.readFile(path, (readErr, data) => {
|
|
163
|
+
sftp.end();
|
|
164
|
+
if (readErr)
|
|
165
|
+
return reject(readErr);
|
|
166
|
+
resolve(data.toString('utf-8'));
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// fall through to cat
|
|
173
|
+
}
|
|
174
|
+
}
|
|
161
175
|
const result = await this.manager.exec(nodeId, `cat "${path}"`);
|
|
162
176
|
if (result.code !== 0)
|
|
163
177
|
throw new Error(`Failed to read ${path} on ${nodeId}: ${result.stderr}`);
|
|
@@ -165,11 +179,9 @@ export class TransferEngine {
|
|
|
165
179
|
}
|
|
166
180
|
async writeFile(nodeId, path, content) {
|
|
167
181
|
const dir = path.substring(0, path.lastIndexOf('/')) || '/tmp';
|
|
168
|
-
// Try SFTP first (no heredoc issues, binary-safe)
|
|
169
182
|
const client = this.manager.getClient(nodeId);
|
|
170
183
|
if (client) {
|
|
171
184
|
try {
|
|
172
|
-
// Ensure directory exists
|
|
173
185
|
await this.manager.exec(nodeId, `mkdir -p "${dir}"`);
|
|
174
186
|
await new Promise((resolve, reject) => {
|
|
175
187
|
client.sftp((err, sftp) => {
|
|
@@ -184,10 +196,9 @@ export class TransferEngine {
|
|
|
184
196
|
return;
|
|
185
197
|
}
|
|
186
198
|
catch {
|
|
187
|
-
//
|
|
199
|
+
// fall through to base64
|
|
188
200
|
}
|
|
189
201
|
}
|
|
190
|
-
// Fallback: base64 pipe (safe for any content)
|
|
191
202
|
const b64 = Buffer.from(content, 'utf-8').toString('base64');
|
|
192
203
|
const cmd = `mkdir -p "${dir}" && echo '${b64}' | base64 -d > "${path}"`;
|
|
193
204
|
const result = await this.manager.exec(nodeId, cmd);
|
|
@@ -195,19 +206,16 @@ export class TransferEngine {
|
|
|
195
206
|
throw new Error(`Failed to write ${path} on ${nodeId}: ${result.stderr}`);
|
|
196
207
|
}
|
|
197
208
|
async stat(nodeId, path) {
|
|
198
|
-
// Check cache first
|
|
199
209
|
const cacheKey = `${nodeId}:${path}`;
|
|
200
210
|
const cached = this.statCache.get(cacheKey);
|
|
201
|
-
if (cached && Date.now() - cached.at < STAT_CACHE_TTL)
|
|
211
|
+
if (cached && Date.now() - cached.at < STAT_CACHE_TTL)
|
|
202
212
|
return cached.info;
|
|
203
|
-
}
|
|
204
213
|
const cmd = `stat -c '%s %F %a %Y %U' "${path}" 2>/dev/null && echo OK || echo NOTFOUND`;
|
|
205
214
|
const result = await this.manager.exec(nodeId, cmd);
|
|
206
215
|
if (result.stdout.includes('NOTFOUND') || result.code !== 0) {
|
|
207
216
|
throw new Error(`File not found: ${path} on ${nodeId}`);
|
|
208
217
|
}
|
|
209
|
-
const
|
|
210
|
-
const parts = lines[0].split(' ');
|
|
218
|
+
const parts = result.stdout.trim().split('\n')[0].split(' ');
|
|
211
219
|
const info = {
|
|
212
220
|
path,
|
|
213
221
|
size: parseInt(parts[0]) || 0,
|