magnetk 2.2.6 → 2.4.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 +104 -4
- package/package.json +2 -2
- package/share.js +1 -1
package/client.js
CHANGED
|
@@ -24,6 +24,8 @@ const MSG_TYPE = {
|
|
|
24
24
|
MSG_CHUNK_RES: 0x21,
|
|
25
25
|
MSG_GET_IDENTITY: 0x32,
|
|
26
26
|
MSG_IDENTITY_RES: 0x33,
|
|
27
|
+
MSG_PROXY_CONNECT: 0x40,
|
|
28
|
+
MSG_PROXY_READY: 0x41,
|
|
27
29
|
MSG_ERROR: 0xFF
|
|
28
30
|
};
|
|
29
31
|
|
|
@@ -426,21 +428,68 @@ export class MagnetkClient extends EventEmitter {
|
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
const addressesToTry = [];
|
|
431
|
+
|
|
432
|
+
// Helper: filter out non-routable addresses
|
|
433
|
+
const isRoutable = (host) => {
|
|
434
|
+
if (!host) return false;
|
|
435
|
+
// 0.0.0.0 is a bind-all address, not valid for connecting
|
|
436
|
+
if (host === '0.0.0.0') return false;
|
|
437
|
+
// Link-local, loopback handled separately
|
|
438
|
+
if (host.startsWith('169.254.')) return false;
|
|
439
|
+
return true;
|
|
440
|
+
};
|
|
441
|
+
|
|
429
442
|
if (lookupResult && lookupResult.found && lookupResult.seeds.length > 0) {
|
|
430
443
|
const seed = lookupResult.seeds[0];
|
|
431
|
-
|
|
444
|
+
console.log(`[Magnetk-JS] Relay returned seed: peer_id=${seed.peer_id}, transport_addr=${seed.transport_addr}, addresses=${JSON.stringify(seed.addresses)}`);
|
|
445
|
+
|
|
446
|
+
// Add transport_addr if routable
|
|
447
|
+
if (seed.transport_addr) {
|
|
448
|
+
const [h] = seed.transport_addr.split(':');
|
|
449
|
+
if (isRoutable(h)) {
|
|
450
|
+
addressesToTry.push(seed.transport_addr);
|
|
451
|
+
} else {
|
|
452
|
+
console.log(`[Magnetk-JS] Skipping non-routable transport_addr: ${seed.transport_addr}`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Parse multiaddr addresses
|
|
432
457
|
if (seed.addresses) {
|
|
433
458
|
seed.addresses.forEach(addr => {
|
|
434
459
|
const parts = addr.split('/');
|
|
435
460
|
if (parts.length >= 5 && parts[1] === 'ip4' && parts[3] === 'tcp') {
|
|
436
|
-
|
|
461
|
+
const ip = parts[2];
|
|
462
|
+
if (isRoutable(ip)) {
|
|
463
|
+
addressesToTry.push(`${ip}:${parts[4]}`);
|
|
464
|
+
} else {
|
|
465
|
+
console.log(`[Magnetk-JS] Skipping non-routable address: ${addr}`);
|
|
466
|
+
}
|
|
437
467
|
}
|
|
438
468
|
});
|
|
439
469
|
}
|
|
470
|
+
} else {
|
|
471
|
+
console.log(`[Magnetk-JS] Relay lookup: no seeds found for this file hash`);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Fallback: extract seed IP from magnet link relay addr
|
|
475
|
+
// If the magnet link contains the relay multiaddr, the seed's IP might be known
|
|
476
|
+
// from the relay's host (when seed is on same VPS as relay)
|
|
477
|
+
if (addressesToTry.length === 0 && ml.relayAddr) {
|
|
478
|
+
// Try to parse /ip4/HOST/tcp/PORT from relay multiaddr
|
|
479
|
+
const parts = ml.relayAddr.split('/');
|
|
480
|
+
if (parts.length >= 3 && parts[1] === 'ip4') {
|
|
481
|
+
const seedAddr = `${parts[2]}:${this.config.seedPort}`;
|
|
482
|
+
console.log(`[Magnetk-JS] No routable seeds from relay, trying relay host as seed: ${seedAddr}`);
|
|
483
|
+
addressesToTry.push(seedAddr);
|
|
484
|
+
}
|
|
440
485
|
}
|
|
486
|
+
|
|
487
|
+
// Local fallback (same machine)
|
|
441
488
|
addressesToTry.push(`127.0.0.1:${this.config.seedPort}`);
|
|
442
489
|
|
|
443
490
|
const uniqueAddrs = [...new Set(addressesToTry)];
|
|
491
|
+
console.log(`[Magnetk-JS] Connection attempts: ${uniqueAddrs.join(', ')}`);
|
|
492
|
+
|
|
444
493
|
let socket;
|
|
445
494
|
let connectionType = CONNECTION_TYPE.UNKNOWN;
|
|
446
495
|
let finalAddr = null;
|
|
@@ -450,7 +499,11 @@ export class MagnetkClient extends EventEmitter {
|
|
|
450
499
|
const port = parseInt(portStr, 10) || 4002;
|
|
451
500
|
|
|
452
501
|
try {
|
|
453
|
-
|
|
502
|
+
// Use configurable timeout for connection attempts
|
|
503
|
+
socket = await Promise.race([
|
|
504
|
+
this.connect(host, port),
|
|
505
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), this.config.relayTimeout || 5000))
|
|
506
|
+
]);
|
|
454
507
|
finalAddr = addr;
|
|
455
508
|
if (host === '127.0.0.1' || host === 'localhost') connectionType = CONNECTION_TYPE.LOCAL;
|
|
456
509
|
else if (host === relayHost) connectionType = CONNECTION_TYPE.RELAYED;
|
|
@@ -461,7 +514,54 @@ export class MagnetkClient extends EventEmitter {
|
|
|
461
514
|
} catch (e) { }
|
|
462
515
|
}
|
|
463
516
|
|
|
464
|
-
if (!socket)
|
|
517
|
+
if (!socket) {
|
|
518
|
+
// ===== RELAY PROXY FALLBACK =====
|
|
519
|
+
// All direct connections failed — try connecting through the relay
|
|
520
|
+
if (this.config.enableRelayFallback !== false && lookupResult && lookupResult.found && lookupResult.seeds.length > 0) {
|
|
521
|
+
const seed = lookupResult.seeds[0];
|
|
522
|
+
console.log(`[Magnetk-JS] Direct connection failed, trying relay proxy for seed ${seed.peer_id.substring(0, 12)}...`);
|
|
523
|
+
|
|
524
|
+
try {
|
|
525
|
+
socket = await this.connect(relayHost, discoveryPort);
|
|
526
|
+
const proxyWriter = new FrameWriter(socket);
|
|
527
|
+
const proxyReader = new FrameReader(socket);
|
|
528
|
+
|
|
529
|
+
// Request relay to proxy connection to seed
|
|
530
|
+
await proxyWriter.writeJSON(MSG_TYPE.MSG_PROXY_CONNECT, {
|
|
531
|
+
peer_id: seed.peer_id,
|
|
532
|
+
file_hash: ml.fileHash
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
// Wait for proxy ready or error
|
|
536
|
+
const proxyFrame = await proxyReader.readFrame();
|
|
537
|
+
if (proxyFrame.type === MSG_TYPE.MSG_PROXY_READY) {
|
|
538
|
+
const proxyResult = JSON.parse(proxyFrame.payload.toString());
|
|
539
|
+
if (proxyResult.success) {
|
|
540
|
+
console.log(`[Magnetk-JS] Relay proxy connected to seed`);
|
|
541
|
+
connectionType = CONNECTION_TYPE.RELAYED;
|
|
542
|
+
finalAddr = `relay-proxy:${relayHost}:${discoveryPort}`;
|
|
543
|
+
this.emit('connection-type', { type: connectionType });
|
|
544
|
+
} else {
|
|
545
|
+
socket.destroy();
|
|
546
|
+
socket = null;
|
|
547
|
+
}
|
|
548
|
+
} else if (proxyFrame.type === MSG_TYPE.MSG_ERROR) {
|
|
549
|
+
const errResult = JSON.parse(proxyFrame.payload.toString());
|
|
550
|
+
console.log(`[Magnetk-JS] Relay proxy error: ${errResult.message}`);
|
|
551
|
+
socket.destroy();
|
|
552
|
+
socket = null;
|
|
553
|
+
} else {
|
|
554
|
+
socket.destroy();
|
|
555
|
+
socket = null;
|
|
556
|
+
}
|
|
557
|
+
} catch (e) {
|
|
558
|
+
console.log(`[Magnetk-JS] Relay proxy failed: ${e.message}`);
|
|
559
|
+
if (socket) { socket.destroy(); socket = null; }
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (!socket) throw new Error('All seed connection attempts failed (direct + relay proxy).');
|
|
465
565
|
|
|
466
566
|
this.lastDownloadStats.connectionType = connectionType;
|
|
467
567
|
this.lastDownloadStats.remoteAddr = finalAddr;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magnetk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.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
|
@@ -8,7 +8,7 @@ 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,
|
|
11
|
+
// seederPath: process.env.MAGNETK_SEEDER_PATH || "~root/Desktop/Magnetk/magnetk/bin/seed",
|
|
12
12
|
seedPort: 4002 // Data transfer port (must not conflict with relay 4003)
|
|
13
13
|
});
|
|
14
14
|
|