@decentnetwork/peer 0.1.93 → 0.1.94
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/dist/peer.js +18 -4
- package/package.json +1 -1
package/dist/peer.js
CHANGED
|
@@ -1760,10 +1760,19 @@ export class Peer {
|
|
|
1760
1760
|
const now = Date.now();
|
|
1761
1761
|
const peerSendingUndecryptable = state.undecryptableRecvMs !== undefined &&
|
|
1762
1762
|
now - state.undecryptableRecvMs < FRIEND_TIMEOUT_MS;
|
|
1763
|
+
// A duplicate handshake can also be the first packet from a freshly
|
|
1764
|
+
// restarted peer whose KILL notice was lost during shutdown. The
|
|
1765
|
+
// holder still has the peer's old accepted session shell, while the
|
|
1766
|
+
// restarted process needs our handshake reply before it can derive the
|
|
1767
|
+
// shared key. Re-send our CURRENT handshake (same key, so no local
|
|
1768
|
+
// reset) even if we also initiated a cookie chain: after a blackout
|
|
1769
|
+
// both sides commonly initiate at once, so `weInitiated` cannot tell a
|
|
1770
|
+
// request from a reply here. The 2s rate limit bounds duplicate traffic;
|
|
1771
|
+
// the immediate reply cannot bounce because it arrives inside the
|
|
1772
|
+
// limit. This is also the normal lost-reply recovery path.
|
|
1763
1773
|
const resyncDue = now - (state.lastResyncHandshakeMs ?? 0) > 2000;
|
|
1764
|
-
if (
|
|
1774
|
+
if (resyncDue) {
|
|
1765
1775
|
state.lastResyncHandshakeMs = now;
|
|
1766
|
-
state.lastPingRecvMs = now;
|
|
1767
1776
|
const reply = createCryptoHandshake({
|
|
1768
1777
|
recipientCookie: hs.embeddedCookie,
|
|
1769
1778
|
baseNonce: state.ourBaseNonce,
|
|
@@ -1779,11 +1788,16 @@ export class Peer {
|
|
|
1779
1788
|
? Promise.resolve(this.#tcpRelays?.sendOobToFriend(hs.senderDhtPublicKey, reply) ?? 0)
|
|
1780
1789
|
: this.#sendPacket(reply, { host: remote.address, port: remote.port });
|
|
1781
1790
|
void sendResync()
|
|
1782
|
-
.then(() => this.#debugLog(`hs_recv duplicate
|
|
1791
|
+
.then(() => this.#debugLog(`hs_recv duplicate — re-sent our handshake to resync friend=${friendId} ` +
|
|
1792
|
+
`reason=${peerSendingUndecryptable ? "undecryptable-data" : "duplicate-handshake"}`))
|
|
1783
1793
|
.catch((error) => this.#debugLog(`resync handshake failed for ${friendId}: ${error.message}`));
|
|
1784
1794
|
return;
|
|
1785
1795
|
}
|
|
1786
|
-
|
|
1796
|
+
// A handshake proves reachability, not that this net_crypto session can
|
|
1797
|
+
// decrypt data. Refreshing lastPingRecvMs here kept a stale session
|
|
1798
|
+
// immortal: the restarted peer retransmitted handshakes every second,
|
|
1799
|
+
// and each retransmit postponed the 32s dead-session breaker forever.
|
|
1800
|
+
// Only successfully decrypted CRYPTO_DATA may refresh liveness.
|
|
1787
1801
|
this.#debugVerboseLog(`hs_recv duplicate friend=${friendId} remote=${remote.address}:${remote.port} (session preserved)`);
|
|
1788
1802
|
return;
|
|
1789
1803
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.94",
|
|
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",
|