@decentnetwork/peer 0.1.103 → 0.1.104

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 +26 -2
  2. package/package.json +1 -1
package/dist/peer.js CHANGED
@@ -210,8 +210,22 @@ const RECV_REQUEST_MIN_INTERVAL_MS = 200;
210
210
  export class Peer {
211
211
  #opts;
212
212
  #events = new EventEmitter();
213
+ /** While negotiating a non-LAN file, temporarily stop sending this friend
214
+ * UDP control traffic. Peer <=0.1.94 routes FILE_CONTROL UDP-only whenever
215
+ * it has seen recent inbound UDP, even when that public/NAT path is one-way.
216
+ * Repeated relay-only offers let that 4s freshness expire, after which the
217
+ * old peer returns ACCEPT/ACK over its reliable TCP relay. */
218
+ #fileRelayNegotiationUntil = new Map();
213
219
  // Toxcore-standard file transfer (wire-compatible with native Carrier/toxcore).
214
- #fileTransfer = new FileTransferManager((friendId, packetId, payload) => this.#sendMessengerPacket(friendId, packetId, payload), (event, payload) => { this.#events.emit(event, payload); }, (friendId) => {
220
+ #fileTransfer = new FileTransferManager((friendId, packetId, payload) => {
221
+ if (packetId === PACKET_ID_FILE_SENDREQUEST) {
222
+ const session = this.#friendSessions.get(friendId);
223
+ const lan = !!session?.lanRemoteHost && session.remote?.host === session.lanRemoteHost;
224
+ if (!lan)
225
+ this.#fileRelayNegotiationUntil.set(friendId, Date.now() + 6_000);
226
+ }
227
+ return this.#sendMessengerPacket(friendId, packetId, payload);
228
+ }, (event, payload) => { this.#events.emit(event, payload); }, (friendId) => {
215
229
  const session = this.#friendSessions.get(friendId);
216
230
  return !!session?.lanRemoteHost && session.remote?.host === session.lanRemoteHost;
217
231
  });
@@ -604,6 +618,7 @@ export class Peer {
604
618
  clearTimeout(timer);
605
619
  this.#profileRetryTimers.clear();
606
620
  this.#profileRetryAttempts.clear();
621
+ this.#fileRelayNegotiationUntil.clear();
607
622
  if (this.#expressPollTimer) {
608
623
  clearInterval(this.#expressPollTimer);
609
624
  this.#expressPollTimer = undefined;
@@ -980,6 +995,7 @@ export class Peer {
980
995
  }
981
996
  const existed = this.#friends.delete(friendId);
982
997
  this.#friendSessions.delete(friendId);
998
+ this.#fileRelayNegotiationUntil.delete(friendId);
983
999
  this.#pendingFriendRequests.delete(friendId);
984
1000
  this.#cookieRetryCount.delete(friendId);
985
1001
  this.#lastCookieSentKey.delete(friendId);
@@ -3345,6 +3361,11 @@ export class Peer {
3345
3361
  * buffered packets through the exact same dispatch. `kind` is the first
3346
3362
  * payload byte (never undefined here — the caller defaults it). */
3347
3363
  #deliverLosslessPayload(friendId, state, kind, inner, remote, packetNumber = 0) {
3364
+ // Any file response proves the receiver can hear this session. Release the
3365
+ // old-peer relay-only negotiation guard before the data pump chooses its
3366
+ // normal LAN/reliable-public path.
3367
+ if (kind === PACKET_ID_FILE_CONTROL)
3368
+ this.#fileRelayNegotiationUntil.delete(friendId);
3348
3369
  // Toxcore file transfer (FILE_SENDREQUEST/CONTROL/DATA = 80/81/82).
3349
3370
  if (this.#fileTransfer.handlePacket(friendId, kind, inner))
3350
3371
  return;
@@ -3964,6 +3985,8 @@ export class Peer {
3964
3985
  const udpFresh = !!realUdpRemote &&
3965
3986
  s?.lastUdpRecvMs !== undefined &&
3966
3987
  Date.now() - s.lastUdpRecvMs < 4_000;
3988
+ const forceFileRelay = (this.#fileRelayNegotiationUntil.get(friendId) ?? 0) > Date.now() &&
3989
+ !(s?.lanRemoteHost && s.remote?.host === s.lanRemoteHost);
3967
3990
  // A freshly-received UDP packet proves only the peer -> us direction.
3968
3991
  // That is enough for lossy IP/video bulk, whose inner TCP stream can
3969
3992
  // recover a dropped packet, but not for reliable file data: returning
@@ -3980,7 +4003,8 @@ export class Peer {
3980
4003
  // lastUdpRecvMs). This converts a multi-second blackout into a few
3981
4004
  // seconds of higher relay latency. Control packets always probe UDP
3982
4005
  // (to keep the NAT mapping warm) so we still try UDP for them.
3983
- const tryUdp = realUdpRemote &&
4006
+ const tryUdp = !forceFileRelay &&
4007
+ realUdpRemote &&
3984
4008
  (isBulkData ? udpFresh && fileUdpOnlyConfirmed : true);
3985
4009
  if (tryUdp && s?.remote) {
3986
4010
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/peer",
3
- "version": "0.1.103",
3
+ "version": "0.1.104",
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",