@decentnetwork/lan 0.1.53 → 0.1.55
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/cli/commands.js
CHANGED
|
@@ -1306,7 +1306,7 @@ export async function cmdDoctor(args) {
|
|
|
1306
1306
|
const pid = daemonPid(config);
|
|
1307
1307
|
if (pid === null) {
|
|
1308
1308
|
bad("Daemon is not running", `start it: sudo agentnet up --real-tun --config-dir ${dir}`);
|
|
1309
|
-
info("
|
|
1309
|
+
info("As a service: logs are in `journalctl -u agentnet -f` (older installs: /var/log/agentnet.log).");
|
|
1310
1310
|
return;
|
|
1311
1311
|
}
|
|
1312
1312
|
ok(`Daemon running (pid ${pid})`);
|
|
@@ -1345,7 +1345,7 @@ export async function cmdDoctor(args) {
|
|
|
1345
1345
|
ok(`${nameOf(f)} — connected`);
|
|
1346
1346
|
for (const f of connecting)
|
|
1347
1347
|
info(`${nameOf(f)} — connecting (other end offline, or upgraded-but-not-restarted: restart its daemon)`);
|
|
1348
|
-
console.log("\n Watch live:
|
|
1348
|
+
console.log("\n Watch live: journalctl -u agentnet -f (\"Peers:\" line every 30s; older installs: /var/log/agentnet.log)");
|
|
1349
1349
|
}
|
|
1350
1350
|
/**
|
|
1351
1351
|
* Enable dora integration. Accepts either `--address` (preferred — the
|
|
@@ -1612,8 +1612,12 @@ User=root
|
|
|
1612
1612
|
ExecStart=${agentnetBin} up --real-tun --config-dir ${dir}
|
|
1613
1613
|
Restart=on-failure
|
|
1614
1614
|
RestartSec=5
|
|
1615
|
-
|
|
1616
|
-
|
|
1615
|
+
# Log to the journal so the intuitive 'journalctl -u agentnet -f' just works.
|
|
1616
|
+
# (The old 'append:/var/log/agentnet.log' redirect sent output to a file and
|
|
1617
|
+
# left journalctl empty — the #1 "why no logs?" confusion.)
|
|
1618
|
+
StandardOutput=journal
|
|
1619
|
+
StandardError=journal
|
|
1620
|
+
SyslogIdentifier=agentnet
|
|
1617
1621
|
|
|
1618
1622
|
[Install]
|
|
1619
1623
|
WantedBy=multi-user.target
|
|
@@ -1629,7 +1633,7 @@ WantedBy=multi-user.target
|
|
|
1629
1633
|
execSync("systemctl daemon-reload");
|
|
1630
1634
|
execSync("systemctl enable --now agentnet");
|
|
1631
1635
|
console.log(`Installed ${unitPath} and started agentnet.service.`);
|
|
1632
|
-
console.log(`Logs: journalctl -u agentnet -f
|
|
1636
|
+
console.log(`Logs: journalctl -u agentnet -f`);
|
|
1633
1637
|
return;
|
|
1634
1638
|
}
|
|
1635
1639
|
if (process.platform === "darwin") {
|
|
@@ -41,9 +41,17 @@ export declare class DoraIntegration {
|
|
|
41
41
|
private retryBootstrapTimer?;
|
|
42
42
|
/** The IP dora handed us. Falls back to preferredIp on registry failure. */
|
|
43
43
|
private allocatedIp;
|
|
44
|
-
/**
|
|
45
|
-
* 60s roster refresh from spamming sendFriendRequest
|
|
46
|
-
|
|
44
|
+
/** Userid -> last time (ms) we sent an auto-friend request. Keeps the
|
|
45
|
+
* 60s roster refresh from spamming sendFriendRequest, but — unlike a
|
|
46
|
+
* plain "sent once" Set — lets us RE-send periodically to a peer that's
|
|
47
|
+
* still not connected. A single missed delivery (express hiccup, or the
|
|
48
|
+
* peer's daemon was offline/running old code when we first sent) used to
|
|
49
|
+
* strand the friendship until a client restart; re-asserting every few
|
|
50
|
+
* minutes self-heals it the moment the other end comes back. */
|
|
51
|
+
private friendRequestedAt;
|
|
52
|
+
/** Re-send an auto-friend request to a still-unconnected roster peer at
|
|
53
|
+
* most this often. */
|
|
54
|
+
private static readonly AUTOFRIEND_RESEND_MS;
|
|
47
55
|
/** Set once we've successfully registered. The retry-bootstrap loop
|
|
48
56
|
* uses this to know when to stop trying. */
|
|
49
57
|
private registered;
|
|
@@ -21,9 +21,17 @@ export class DoraIntegration {
|
|
|
21
21
|
retryBootstrapTimer;
|
|
22
22
|
/** The IP dora handed us. Falls back to preferredIp on registry failure. */
|
|
23
23
|
allocatedIp;
|
|
24
|
-
/**
|
|
25
|
-
* 60s roster refresh from spamming sendFriendRequest
|
|
26
|
-
|
|
24
|
+
/** Userid -> last time (ms) we sent an auto-friend request. Keeps the
|
|
25
|
+
* 60s roster refresh from spamming sendFriendRequest, but — unlike a
|
|
26
|
+
* plain "sent once" Set — lets us RE-send periodically to a peer that's
|
|
27
|
+
* still not connected. A single missed delivery (express hiccup, or the
|
|
28
|
+
* peer's daemon was offline/running old code when we first sent) used to
|
|
29
|
+
* strand the friendship until a client restart; re-asserting every few
|
|
30
|
+
* minutes self-heals it the moment the other end comes back. */
|
|
31
|
+
friendRequestedAt = new Map();
|
|
32
|
+
/** Re-send an auto-friend request to a still-unconnected roster peer at
|
|
33
|
+
* most this often. */
|
|
34
|
+
static AUTOFRIEND_RESEND_MS = 5 * 60_000;
|
|
27
35
|
/** Set once we've successfully registered. The retry-bootstrap loop
|
|
28
36
|
* uses this to know when to stop trying. */
|
|
29
37
|
registered = false;
|
|
@@ -362,10 +370,17 @@ export class DoraIntegration {
|
|
|
362
370
|
* re-register the peer or fall back to a manual friend-request.
|
|
363
371
|
*/
|
|
364
372
|
maybeFriend(entry) {
|
|
365
|
-
|
|
366
|
-
return;
|
|
373
|
+
// Already connected → nothing to do (and clear any resend timer).
|
|
367
374
|
if (this.opts.peerManager.isFriend(entry.userid)) {
|
|
368
|
-
this.
|
|
375
|
+
this.friendRequestedAt.set(entry.userid, Date.now());
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
// Not connected yet: send the first time, then RE-send at most every
|
|
379
|
+
// AUTOFRIEND_RESEND_MS. This is the self-heal — a peer that was offline
|
|
380
|
+
// or running old code when we first sent gets re-asserted once it's back,
|
|
381
|
+
// instead of staying stranded until a client restart.
|
|
382
|
+
const lastSent = this.friendRequestedAt.get(entry.userid);
|
|
383
|
+
if (lastSent !== undefined && Date.now() - lastSent < DoraIntegration.AUTOFRIEND_RESEND_MS) {
|
|
369
384
|
return;
|
|
370
385
|
}
|
|
371
386
|
// Policy gate. The undefined default is "all" because a peer
|
|
@@ -389,19 +404,22 @@ export class DoraIntegration {
|
|
|
389
404
|
if (!entry.address) {
|
|
390
405
|
this.logger.warn(`Roster entry ${entry.name} (${entry.userid.slice(0, 12)}...) has no address — can't auto-friend. ` +
|
|
391
406
|
`Have them re-register against a newer dora server, or run 'agentnet friend-request' manually.`);
|
|
392
|
-
|
|
407
|
+
// Re-warn at most once per resend window, not every 60s.
|
|
408
|
+
this.friendRequestedAt.set(entry.userid, Date.now());
|
|
393
409
|
return;
|
|
394
410
|
}
|
|
395
|
-
|
|
411
|
+
const isResend = lastSent !== undefined;
|
|
412
|
+
this.friendRequestedAt.set(entry.userid, Date.now());
|
|
396
413
|
this.opts.peerManager
|
|
397
414
|
.sendFriendRequest(entry.address, `dora roster auto-friend (${this.opts.nodeName})`)
|
|
398
415
|
.then(() => {
|
|
399
|
-
this.logger.info(`Auto-friend sent to ${entry.name} (${entry.userid.slice(0, 12)}...)`);
|
|
416
|
+
this.logger.info(`Auto-friend ${isResend ? "re-sent" : "sent"} to ${entry.name} (${entry.userid.slice(0, 12)}...)`);
|
|
400
417
|
})
|
|
401
418
|
.catch((err) => {
|
|
402
419
|
this.logger.warn(`Auto-friend ${entry.name}: ${err instanceof Error ? err.message : err}`);
|
|
403
|
-
//
|
|
404
|
-
|
|
420
|
+
// Clear the timestamp so the next refresh cycle retries immediately
|
|
421
|
+
// rather than waiting out the resend window.
|
|
422
|
+
this.friendRequestedAt.delete(entry.userid);
|
|
405
423
|
});
|
|
406
424
|
}
|
|
407
425
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
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",
|