@decentnetwork/peer 0.1.131 → 0.1.133

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 (2) hide show
  1. package/dist/peer.js +32 -0
  2. package/package.json +1 -1
package/dist/peer.js CHANGED
@@ -3524,6 +3524,38 @@ export class Peer {
3524
3524
  // keys; it must NOT keep a transportless relay session as a 180s
3525
3525
  // zombie (iOS flap: peer sees us vanish while we still show them
3526
3526
  // online and drop every send). Fast-track those to teardown.
3527
+ // Self-heal a remote we could never have reached.
3528
+ //
3529
+ // The adoption guards keep a bad endpoint out, but a session that
3530
+ // already holds one never re-examines it, and session.remote is sticky
3531
+ // — so the daemon keeps addressing a host it cannot reach for as long
3532
+ // as the session lives. It sits ABOVE the branches below on purpose:
3533
+ // an established session is exactly the case that never re-evaluates,
3534
+ // and putting this inside the not-yet-online branch (where it started)
3535
+ // meant it never ran at all.
3536
+ //
3537
+ // tokyo held 10.0.0.245 for a laptop across the Pacific, through
3538
+ // restarts, with lastUdpRecvMs null throughout. Visible as a link that
3539
+ // alternates between fast and dead in runs of several seconds, because
3540
+ // only some of the paths in play actually reach the peer.
3541
+ //
3542
+ // Both conditions are needed: an address outside every subnet we are
3543
+ // on, AND no UDP ever received here. A real same-LAN peer fails the
3544
+ // first; a peer we have genuinely heard from fails the second.
3545
+ if (session.remote &&
3546
+ !session.remote.host.startsWith("tcp:") &&
3547
+ session.lastUdpRecvMs === undefined &&
3548
+ isPrivateAddress(session.remote.host) &&
3549
+ !isCgnatAddress(session.remote.host) &&
3550
+ !getPhysicalLanSubnets().some((sub) => isInIpv4Subnet(session.remote.host, sub))) {
3551
+ const dead = session.remote;
3552
+ this.#debugLog(`clearing unreachable remote ${dead.host}:${dead.port} for ${friendId} ` +
3553
+ `— private, off our LANs, and never received UDP from it`);
3554
+ session.remote = undefined;
3555
+ session.lanRemoteHost = undefined;
3556
+ // Drop it from the candidates too, or the next sweep re-adopts it.
3557
+ session.endpointCandidates = (session.endpointCandidates ?? []).filter((c) => !(c.host === dead.host && c.port === dead.port));
3558
+ }
3527
3559
  const relayOnly = !session.remote || session.remote.host.startsWith("tcp:");
3528
3560
  const pathless = relayOnly && !session.hasTcpRoute;
3529
3561
  const deadline = proven && !pathless ? PROVEN_SESSION_HARD_TIMEOUT_MS : FRIEND_TIMEOUT_MS;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.131",
3
+ "version": "0.1.133",
4
4
  "description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",