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.
Files changed (3) hide show
  1. package/client.js +104 -4
  2. package/package.json +2 -2
  3. 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
- if (seed.transport_addr) addressesToTry.push(seed.transport_addr);
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
- addressesToTry.push(`${parts[2]}:${parts[4]}`);
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
- socket = await this.connect(host, port);
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) throw new Error('All seed connection attempts failed.');
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.2.6",
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