@decentnetwork/lan 0.1.257 → 0.1.259
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.
|
@@ -17,6 +17,12 @@ const RATE_REPORT_INTERVAL_MS = 1000;
|
|
|
17
17
|
// pacing a trickle (SSH/keepalives), and it keeps reports sparse. The pacer's
|
|
18
18
|
// loss window derives its verdict from these reports vs. what it sent.
|
|
19
19
|
const RATE_REPORT_MIN_BYTES = 32 * 1024; // ~256 kbps sustained
|
|
20
|
+
/** Session keepalive: one zero byte on the data channel.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately not a valid IP packet — the receiver recognises and swallows
|
|
23
|
+
* it. It exists only to keep the Carrier session warm, so it must never be
|
|
24
|
+
* counted as forwarded traffic OR as a drop. */
|
|
25
|
+
const KEEPALIVE_PACKET = new Uint8Array([0]);
|
|
20
26
|
export class PacketRouter extends EventEmitter {
|
|
21
27
|
tunDevice;
|
|
22
28
|
peerManager;
|
|
@@ -198,7 +204,7 @@ export class PacketRouter extends EventEmitter {
|
|
|
198
204
|
if (!session?.isConnected())
|
|
199
205
|
continue;
|
|
200
206
|
try {
|
|
201
|
-
await session.send(
|
|
207
|
+
await session.send(KEEPALIVE_PACKET);
|
|
202
208
|
}
|
|
203
209
|
catch {
|
|
204
210
|
// ignore — session may have just gone offline
|
|
@@ -345,8 +351,30 @@ export class PacketRouter extends EventEmitter {
|
|
|
345
351
|
return;
|
|
346
352
|
const parsed = IpParser.parse(packet);
|
|
347
353
|
if (!parsed) {
|
|
348
|
-
|
|
349
|
-
|
|
354
|
+
// Classify instead of lumping. IpParser returns null for three very
|
|
355
|
+
// different situations and they need different fixes: a short packet
|
|
356
|
+
// means the transport handed us a truncated frame (MTU / reassembly),
|
|
357
|
+
// while IPv6 means the SENDER is forwarding traffic we never support --
|
|
358
|
+
// one is a bug in us, the other is a filter missing upstream. Recording
|
|
359
|
+
// it per-source also makes it visible in `agentnet diag`, which is how
|
|
360
|
+
// this stayed hidden: the old code bumped the counter and logged at
|
|
361
|
+
// debug, so tens of thousands of drops had neither reason nor owner.
|
|
362
|
+
// OUR OWN keepalive, not a loss. sendKeepalivesToActiveSessions emits a
|
|
363
|
+
// single zero byte on the data channel and the receiver was counting
|
|
364
|
+
// every one of them as a dropped packet: 24015 "drops" on mac-dev with
|
|
365
|
+
// only ~2038 attributable, 16919 on cn against 5. That made the drop
|
|
366
|
+
// metric useless exactly when it was needed to explain real packet loss,
|
|
367
|
+
// and sent this investigation down a wrong path first. Swallow it
|
|
368
|
+
// silently — it did its job by arriving.
|
|
369
|
+
if (packet.length === KEEPALIVE_PACKET.length && packet[0] === KEEPALIVE_PACKET[0]) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const reason = packet.length < 20
|
|
373
|
+
? "inbound-too-short"
|
|
374
|
+
: ((packet[0] >> 4) & 0x0f) !== 4
|
|
375
|
+
? "inbound-not-ipv4"
|
|
376
|
+
: "inbound-bad-header";
|
|
377
|
+
this.recordDrop(`from:${srcPubkey.slice(0, 12)}`, reason, `len=${packet.length}`);
|
|
350
378
|
return;
|
|
351
379
|
}
|
|
352
380
|
// Auto-learn (srcPubkey -> srcIp) into IPAM. Without this, ubuntu
|
package/dist/router/types.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export declare const IP_PROTO_ICMP = 1;
|
|
|
18
18
|
* isn't my ping working?" — without forcing them to crank up the
|
|
19
19
|
* log level.
|
|
20
20
|
*/
|
|
21
|
-
export type DropReason = "invalid-ip" | "no-port" | "no-ipam-record" | "friend-offline" | "handshake-failed" | "send-failed" | "tun-write-failed" | "tun-down";
|
|
21
|
+
export type DropReason = "invalid-ip" | "inbound-too-short" | "inbound-not-ipv4" | "inbound-bad-header" | "no-port" | "no-ipam-record" | "friend-offline" | "handshake-failed" | "send-failed" | "tun-write-failed" | "tun-down";
|
|
22
22
|
export interface DstDropInfo {
|
|
23
23
|
/** Total drops to this destination. */
|
|
24
24
|
count: number;
|
package/dist/ui/desktop/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
window.__DK_UI_VERSION="0.1.
|
|
1
|
+
window.__DK_UI_VERSION="0.1.259";
|
|
2
2
|
const ICON_PATHS = {
|
|
3
3
|
// ---- tab bar (the four must feel like one set) ----
|
|
4
4
|
users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.259",
|
|
4
4
|
"description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@decentnetwork/dora": "^0.1.14",
|
|
87
|
-
"@decentnetwork/peer": "^0.1.
|
|
87
|
+
"@decentnetwork/peer": "^0.1.126",
|
|
88
88
|
"@decentnetwork/peer-webrtc": "^0.2.10",
|
|
89
89
|
"ink": "^5.2.1",
|
|
90
90
|
"js-yaml": "^4.1.0",
|