magnetk 2.2.5 → 2.3.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/client.js +91 -5
- package/download.js +1 -1
- package/package.json +2 -2
- package/share.js +4 -4
package/client.js
CHANGED
|
@@ -62,19 +62,30 @@ DISCOVERY_PRIORITY=dht,relay,direct
|
|
|
62
62
|
|
|
63
63
|
# ===== Chunking =====
|
|
64
64
|
CHUNK_SIZE_MB=1
|
|
65
|
+
ADAPTIVE_CHUNKING=true
|
|
65
66
|
MAX_PARALLEL_CHUNKS=10
|
|
67
|
+
|
|
68
|
+
# ===== Connection Strategy =====
|
|
69
|
+
# RELAY_ASSISTED: auto | true | false
|
|
70
|
+
# auto = try direct P2P first, fall back to relay if unreachable
|
|
71
|
+
# true = always route data through relay (privacy mode)
|
|
72
|
+
# false = direct P2P only, fail if unreachable
|
|
73
|
+
RELAY_ASSISTED=auto
|
|
74
|
+
# HOLE_PUNCH: Enable NAT traversal via STUN + libp2p hole punching
|
|
75
|
+
HOLE_PUNCH=true
|
|
76
|
+
# RELAY_TIMEOUT_MS: How long to wait for direct connection before relay fallback
|
|
77
|
+
RELAY_TIMEOUT_MS=5000
|
|
66
78
|
`;
|
|
67
79
|
|
|
68
80
|
export class MagnetkClient extends EventEmitter {
|
|
69
81
|
constructor(config = {}) {
|
|
70
82
|
super();
|
|
71
83
|
this.config = {
|
|
72
|
-
// Relay settings (supports multiple relays for failover)
|
|
84
|
+
// Relay settings (supports multiple relays for failover/scaling)
|
|
73
85
|
relayUrl: '69.169.109.243',
|
|
74
86
|
relayPort: 4003,
|
|
75
87
|
relays: [], // Array of {host, port} for multi-relay failover
|
|
76
88
|
seedPort: 4002,
|
|
77
|
-
enableSTUN: true,
|
|
78
89
|
seederPath: null,
|
|
79
90
|
configPath: null,
|
|
80
91
|
|
|
@@ -83,6 +94,13 @@ export class MagnetkClient extends EventEmitter {
|
|
|
83
94
|
dhtBootstrapPeers: [], // Custom bootstrap peer multiaddrs
|
|
84
95
|
discoveryPriority: ['dht', 'relay', 'direct'], // Discovery order
|
|
85
96
|
|
|
97
|
+
// Connection strategy
|
|
98
|
+
stunServers: ['stun:stun.l.google.com:19302'], // STUN servers for NAT traversal
|
|
99
|
+
holePunch: true, // Enable NAT hole punching (STUN first, relay fallback)
|
|
100
|
+
relayAssisted: 'auto', // 'auto' | true | false — relay-assisted data transfer
|
|
101
|
+
enableRelayFallback: true, // Fall back to relay if direct P2P fails
|
|
102
|
+
relayTimeout: 5000, // ms to wait for direct connection before relay fallback
|
|
103
|
+
|
|
86
104
|
// Auto-config: create settings.conf if missing
|
|
87
105
|
autoConfig: true,
|
|
88
106
|
...config
|
|
@@ -307,6 +325,23 @@ export class MagnetkClient extends EventEmitter {
|
|
|
307
325
|
args.push('-bootstrap', this.config.dhtBootstrapPeers.join(','));
|
|
308
326
|
}
|
|
309
327
|
|
|
328
|
+
// Connection strategy flags
|
|
329
|
+
if (this.config.holePunch) {
|
|
330
|
+
args.push('-holepunch');
|
|
331
|
+
}
|
|
332
|
+
if (this.config.relayAssisted !== undefined) {
|
|
333
|
+
const mode = this.config.relayAssisted === true ? 'true'
|
|
334
|
+
: this.config.relayAssisted === false ? 'false'
|
|
335
|
+
: this.config.relayAssisted;
|
|
336
|
+
args.push('-relay-assisted', mode);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Multi-relay: pass additional relay addresses
|
|
340
|
+
if (this.config.relays && this.config.relays.length > 0) {
|
|
341
|
+
const relayAddrs = this.config.relays.map(r => `${r.host}:${r.port}`).join(',');
|
|
342
|
+
args.push('-relay-addresses', relayAddrs);
|
|
343
|
+
}
|
|
344
|
+
|
|
310
345
|
console.log(`[Magnetk-JS] Spawning seeder: ${binPath} ${args.join(' ')}`);
|
|
311
346
|
|
|
312
347
|
return new Promise((resolve, reject) => {
|
|
@@ -391,21 +426,68 @@ export class MagnetkClient extends EventEmitter {
|
|
|
391
426
|
}
|
|
392
427
|
|
|
393
428
|
const addressesToTry = [];
|
|
429
|
+
|
|
430
|
+
// Helper: filter out non-routable addresses
|
|
431
|
+
const isRoutable = (host) => {
|
|
432
|
+
if (!host) return false;
|
|
433
|
+
// 0.0.0.0 is a bind-all address, not valid for connecting
|
|
434
|
+
if (host === '0.0.0.0') return false;
|
|
435
|
+
// Link-local, loopback handled separately
|
|
436
|
+
if (host.startsWith('169.254.')) return false;
|
|
437
|
+
return true;
|
|
438
|
+
};
|
|
439
|
+
|
|
394
440
|
if (lookupResult && lookupResult.found && lookupResult.seeds.length > 0) {
|
|
395
441
|
const seed = lookupResult.seeds[0];
|
|
396
|
-
|
|
442
|
+
console.log(`[Magnetk-JS] Relay returned seed: peer_id=${seed.peer_id}, transport_addr=${seed.transport_addr}, addresses=${JSON.stringify(seed.addresses)}`);
|
|
443
|
+
|
|
444
|
+
// Add transport_addr if routable
|
|
445
|
+
if (seed.transport_addr) {
|
|
446
|
+
const [h] = seed.transport_addr.split(':');
|
|
447
|
+
if (isRoutable(h)) {
|
|
448
|
+
addressesToTry.push(seed.transport_addr);
|
|
449
|
+
} else {
|
|
450
|
+
console.log(`[Magnetk-JS] Skipping non-routable transport_addr: ${seed.transport_addr}`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Parse multiaddr addresses
|
|
397
455
|
if (seed.addresses) {
|
|
398
456
|
seed.addresses.forEach(addr => {
|
|
399
457
|
const parts = addr.split('/');
|
|
400
458
|
if (parts.length >= 5 && parts[1] === 'ip4' && parts[3] === 'tcp') {
|
|
401
|
-
|
|
459
|
+
const ip = parts[2];
|
|
460
|
+
if (isRoutable(ip)) {
|
|
461
|
+
addressesToTry.push(`${ip}:${parts[4]}`);
|
|
462
|
+
} else {
|
|
463
|
+
console.log(`[Magnetk-JS] Skipping non-routable address: ${addr}`);
|
|
464
|
+
}
|
|
402
465
|
}
|
|
403
466
|
});
|
|
404
467
|
}
|
|
468
|
+
} else {
|
|
469
|
+
console.log(`[Magnetk-JS] Relay lookup: no seeds found for this file hash`);
|
|
405
470
|
}
|
|
471
|
+
|
|
472
|
+
// Fallback: extract seed IP from magnet link relay addr
|
|
473
|
+
// If the magnet link contains the relay multiaddr, the seed's IP might be known
|
|
474
|
+
// from the relay's host (when seed is on same VPS as relay)
|
|
475
|
+
if (addressesToTry.length === 0 && ml.relayAddr) {
|
|
476
|
+
// Try to parse /ip4/HOST/tcp/PORT from relay multiaddr
|
|
477
|
+
const parts = ml.relayAddr.split('/');
|
|
478
|
+
if (parts.length >= 3 && parts[1] === 'ip4') {
|
|
479
|
+
const seedAddr = `${parts[2]}:${this.config.seedPort}`;
|
|
480
|
+
console.log(`[Magnetk-JS] No routable seeds from relay, trying relay host as seed: ${seedAddr}`);
|
|
481
|
+
addressesToTry.push(seedAddr);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Local fallback (same machine)
|
|
406
486
|
addressesToTry.push(`127.0.0.1:${this.config.seedPort}`);
|
|
407
487
|
|
|
408
488
|
const uniqueAddrs = [...new Set(addressesToTry)];
|
|
489
|
+
console.log(`[Magnetk-JS] Connection attempts: ${uniqueAddrs.join(', ')}`);
|
|
490
|
+
|
|
409
491
|
let socket;
|
|
410
492
|
let connectionType = CONNECTION_TYPE.UNKNOWN;
|
|
411
493
|
let finalAddr = null;
|
|
@@ -415,7 +497,11 @@ export class MagnetkClient extends EventEmitter {
|
|
|
415
497
|
const port = parseInt(portStr, 10) || 4002;
|
|
416
498
|
|
|
417
499
|
try {
|
|
418
|
-
|
|
500
|
+
// Use configurable timeout for connection attempts
|
|
501
|
+
socket = await Promise.race([
|
|
502
|
+
this.connect(host, port),
|
|
503
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), this.config.relayTimeout || 5000))
|
|
504
|
+
]);
|
|
419
505
|
finalAddr = addr;
|
|
420
506
|
if (host === '127.0.0.1' || host === 'localhost') connectionType = CONNECTION_TYPE.LOCAL;
|
|
421
507
|
else if (host === relayHost) connectionType = CONNECTION_TYPE.RELAYED;
|
package/download.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magnetk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "JavaScript SDK for Magnetk P2P File Transfer System",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
],
|
|
35
35
|
"author": "Magnetk Contributors",
|
|
36
36
|
"license": "MIT"
|
|
37
|
-
}
|
|
37
|
+
}
|
package/share.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MagnetkClient } from '
|
|
1
|
+
import { MagnetkClient } from './client.js';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import 'dotenv/config';
|
|
3
|
+
// import 'dotenv/config';
|
|
4
4
|
|
|
5
5
|
const filePath = "./app.txt";
|
|
6
6
|
|
|
@@ -8,8 +8,8 @@ async function share() {
|
|
|
8
8
|
const client = new MagnetkClient({
|
|
9
9
|
relayUrl: '69.169.109.243', // Default to local for dev, change to public IPs for prod
|
|
10
10
|
relayPort: 4003,
|
|
11
|
-
seederPath: process.env.MAGNETK_SEEDER_PATH,
|
|
12
|
-
seedPort:
|
|
11
|
+
// seederPath: process.env.MAGNETK_SEEDER_PATH || "~root/Desktop/Magnetk/magnetk/bin/seed",
|
|
12
|
+
seedPort: 4002 // Data transfer port (must not conflict with relay 4003)
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
console.log(`[Share] Preparing to share: ${filePath}`);
|