@decentnetwork/peer 0.1.37 → 0.1.38
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.
|
@@ -64,7 +64,7 @@ export declare class TcpRelayPool extends EventEmitter {
|
|
|
64
64
|
* online. Returns the count of relays that accepted the write — 0 if
|
|
65
65
|
* the friend isn't online on any TCP relay.
|
|
66
66
|
*/
|
|
67
|
-
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array): number;
|
|
67
|
+
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array, droppable?: boolean): number;
|
|
68
68
|
/** Diagnostics. */
|
|
69
69
|
connectedCount(): number;
|
|
70
70
|
/**
|
|
@@ -173,7 +173,7 @@ export class TcpRelayPool extends EventEmitter {
|
|
|
173
173
|
* online. Returns the count of relays that accepted the write — 0 if
|
|
174
174
|
* the friend isn't online on any TCP relay.
|
|
175
175
|
*/
|
|
176
|
-
sendToFriend(friendPublicKey, payload) {
|
|
176
|
+
sendToFriend(friendPublicKey, payload, droppable = false) {
|
|
177
177
|
if (friendPublicKey.length !== KEY_SIZE)
|
|
178
178
|
return 0;
|
|
179
179
|
// Send via the FIRST connected relay where the friend is online; only
|
|
@@ -191,7 +191,7 @@ export class TcpRelayPool extends EventEmitter {
|
|
|
191
191
|
continue;
|
|
192
192
|
if (!r.client.hasFriendOnline(friendPublicKey))
|
|
193
193
|
continue;
|
|
194
|
-
if (r.client.sendToFriend(friendPublicKey, payload)) {
|
|
194
|
+
if (r.client.sendToFriend(friendPublicKey, payload, droppable)) {
|
|
195
195
|
return 1;
|
|
196
196
|
}
|
|
197
197
|
}
|
|
@@ -82,11 +82,11 @@ export declare class TcpRelayClient extends EventEmitter {
|
|
|
82
82
|
* if the relay says they're offline. Caller should treat false as
|
|
83
83
|
* "try another transport".
|
|
84
84
|
*/
|
|
85
|
-
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array): boolean;
|
|
85
|
+
sendToFriend(friendPublicKey: Uint8Array, payload: Uint8Array, droppable?: boolean): boolean;
|
|
86
86
|
/** Send a PING; relay echoes it as PONG. ping_id is opaque 8 bytes. */
|
|
87
87
|
sendPing(): boolean;
|
|
88
88
|
/** Send DATA payload to the friend at `connectionId`. */
|
|
89
|
-
sendData(connectionId: number, payload: Uint8Array): boolean;
|
|
89
|
+
sendData(connectionId: number, payload: Uint8Array, droppable?: boolean): boolean;
|
|
90
90
|
/** Send OOB_SEND (used for delivering friend requests via TCP relay). */
|
|
91
91
|
sendOob(receiverPublicKey: Uint8Array, payload: Uint8Array): boolean;
|
|
92
92
|
close(reason?: string): void;
|
package/dist/compat/tcp-relay.js
CHANGED
|
@@ -37,6 +37,15 @@ import { incrementNonce } from "./net-crypto.js";
|
|
|
37
37
|
const KEY_SIZE = 32;
|
|
38
38
|
const NONCE_SIZE = 24;
|
|
39
39
|
const MAC_SIZE = 16;
|
|
40
|
+
// Max bytes we let pile up in the relay socket's write buffer before we start
|
|
41
|
+
// DROPPING droppable (bulk IP) frames. Node's socket.write() buffers without
|
|
42
|
+
// bound when the kernel send buffer is full, so a congested relay link would
|
|
43
|
+
// otherwise queue SECONDS of IP packets — the multi-second bufferbloat behind
|
|
44
|
+
// the snoopy/lili 13s pings. ~64KB is well under a second of queue even on a
|
|
45
|
+
// slow transpacific relay; past it we behave like a real congested network and
|
|
46
|
+
// drop, letting the inner protocol (TCP/QUIC) retransmit instead of delivering
|
|
47
|
+
// stale packets late. Control frames (droppable=false) always go through.
|
|
48
|
+
const RELAY_SEND_BUFFER_CAP = 64 * 1024;
|
|
40
49
|
/** TCP_HANDSHAKE_PLAIN_SIZE in toxcore — temp pubkey + initial nonce. */
|
|
41
50
|
const TCP_HANDSHAKE_PLAIN_SIZE = KEY_SIZE + NONCE_SIZE;
|
|
42
51
|
/** Outbound handshake: self_dht_pk(32) + nonce(24) + box(plain)(KEY_SIZE+NONCE_SIZE+MAC_SIZE = 72) = 128. */
|
|
@@ -276,13 +285,18 @@ export class TcpRelayClient extends EventEmitter {
|
|
|
276
285
|
return opened;
|
|
277
286
|
}
|
|
278
287
|
/** Encrypt a payload and write it as one framed packet. */
|
|
279
|
-
#sendFrame(payload) {
|
|
288
|
+
#sendFrame(payload, droppable = false) {
|
|
280
289
|
if (this.#state !== "connected" || !this.#sessionKey || !this.#sentNonce || !this.#socket) {
|
|
281
290
|
return false;
|
|
282
291
|
}
|
|
283
292
|
if (payload.length === 0 || payload.length > MAX_PACKET_SIZE - MAC_SIZE) {
|
|
284
293
|
return false;
|
|
285
294
|
}
|
|
295
|
+
// Bound the relay queue: drop bulk IP frames once the socket buffer is
|
|
296
|
+
// backed up rather than letting Node buffer seconds of packets (bufferbloat).
|
|
297
|
+
if (droppable && this.#socket.writableLength > RELAY_SEND_BUFFER_CAP) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
286
300
|
const cipher = nacl.secretbox(payload, this.#sentNonce, this.#sessionKey);
|
|
287
301
|
incrementNonce(this.#sentNonce);
|
|
288
302
|
// Wire layout: [4-byte iveg][2-byte BE length][cipher].
|
|
@@ -418,13 +432,13 @@ export class TcpRelayClient extends EventEmitter {
|
|
|
418
432
|
* if the relay says they're offline. Caller should treat false as
|
|
419
433
|
* "try another transport".
|
|
420
434
|
*/
|
|
421
|
-
sendToFriend(friendPublicKey, payload) {
|
|
435
|
+
sendToFriend(friendPublicKey, payload, droppable = false) {
|
|
422
436
|
if (friendPublicKey.length !== KEY_SIZE)
|
|
423
437
|
return false;
|
|
424
438
|
const cid = this.#cidByFriend.get(Buffer.from(friendPublicKey).toString("hex"));
|
|
425
439
|
if (cid === undefined)
|
|
426
440
|
return false;
|
|
427
|
-
return this.sendData(cid, payload);
|
|
441
|
+
return this.sendData(cid, payload, droppable);
|
|
428
442
|
}
|
|
429
443
|
/** Send a PING; relay echoes it as PONG. ping_id is opaque 8 bytes. */
|
|
430
444
|
sendPing() {
|
|
@@ -432,12 +446,12 @@ export class TcpRelayClient extends EventEmitter {
|
|
|
432
446
|
return this.#sendFrame(concatBytes([Uint8Array.of(TCP_PACKET_PING), pingId]));
|
|
433
447
|
}
|
|
434
448
|
/** Send DATA payload to the friend at `connectionId`. */
|
|
435
|
-
sendData(connectionId, payload) {
|
|
449
|
+
sendData(connectionId, payload, droppable = false) {
|
|
436
450
|
if (connectionId < 16 || connectionId > 0xff)
|
|
437
451
|
return false;
|
|
438
452
|
if (payload.length === 0)
|
|
439
453
|
return false;
|
|
440
|
-
return this.#sendFrame(concatBytes([Uint8Array.of(connectionId), payload]));
|
|
454
|
+
return this.#sendFrame(concatBytes([Uint8Array.of(connectionId), payload]), droppable);
|
|
441
455
|
}
|
|
442
456
|
/** Send OOB_SEND (used for delivering friend requests via TCP relay). */
|
|
443
457
|
sendOob(receiverPublicKey, payload) {
|
package/dist/peer.js
CHANGED
|
@@ -2775,7 +2775,10 @@ export class Peer {
|
|
|
2775
2775
|
// would silently drop on iPad's side and leave the session
|
|
2776
2776
|
// looking healthy on our side while iPad never sees the
|
|
2777
2777
|
// packets.
|
|
2778
|
-
|
|
2778
|
+
// Bulk IP data is droppable over the relay: under backpressure the
|
|
2779
|
+
// relay client drops it (bounded queue) rather than buffering seconds
|
|
2780
|
+
// of packets. Control frames pass isBulkData=false and always queue.
|
|
2781
|
+
const sent = this.#tcpRelays.sendToFriend(tcpKey, packet, isBulkData);
|
|
2779
2782
|
if (sent > 0) {
|
|
2780
2783
|
tcpOk = true;
|
|
2781
2784
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
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",
|