@decentnetwork/peer 0.1.115 → 0.1.116

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 +27 -1
  2. package/package.json +1 -1
package/dist/peer.js CHANGED
@@ -841,7 +841,24 @@ export class Peer {
841
841
  // reply) makes the hot distance-sort + memory grow without limit; a few
842
842
  // hundred nodes is plenty to stay findable and to announce on the closest.
843
843
  const merged = dedupeNodes([...nodes, ...this.#knownNodes]);
844
- this.#knownNodes = merged.length > MAX_KNOWN_NODES ? merged.slice(0, MAX_KNOWN_NODES) : merged;
844
+ if (merged.length > MAX_KNOWN_NODES) {
845
+ const kept = merged.slice(0, MAX_KNOWN_NODES);
846
+ // Pin the bootstrap nodes. They are the only guaranteed-public,
847
+ // onion-capable nodes we have; newest-first truncation on a busy DHT
848
+ // evicted them within hours, leaving the onion hop pool with only
849
+ // NAT'd/CGNAT peers — every onion path died at hop A, so announce and
850
+ // DHTPK delivery failed for days ("no onion path" / "self announce
851
+ // step1 no response" floods) and natives could never (re)discover us.
852
+ const keptIds = new Set(kept.map((node) => `${node.host}:${node.port}`));
853
+ for (const bn of this.#opts.bootstrapNodes) {
854
+ if (!keptIds.has(`${bn.host}:${bn.port}`))
855
+ kept.push(bn);
856
+ }
857
+ this.#knownNodes = kept;
858
+ }
859
+ else {
860
+ this.#knownNodes = merged;
861
+ }
845
862
  }
846
863
  knownNodes() {
847
864
  return [...this.#knownNodes];
@@ -6184,6 +6201,15 @@ export class Peer {
6184
6201
  if (id === nodeDId || node.host === nodeD.host || seenHosts.has(node.host)) {
6185
6202
  continue;
6186
6203
  }
6204
+ // Onion hops must be PUBLICLY routable: they forward our request onward
6205
+ // and route the response back. A CGNAT (Tailscale 100.64/10), RFC1918,
6206
+ // or own-host address cannot do either from the open internet — yet
6207
+ // such peer endpoints leak into #knownNodes and were being picked as
6208
+ // hop A (observed: 1900+ onion initials sent via a friend's Tailscale
6209
+ // 100.76.x address, all black-holed).
6210
+ if (isPrivateAddress(node.host) || isCgnatAddress(node.host) || isOwnAddress(node.host)) {
6211
+ continue;
6212
+ }
6187
6213
  // Skip blacklisted relays — onion paths through dead nodes
6188
6214
  // silently swallow the request and the announce times out.
6189
6215
  if (this.#isNodeBlacklisted(id)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.115",
3
+ "version": "0.1.116",
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",