Lines 10-50javascript
10import { CRYPTO_PACKET_DHTPK, CRYPTO_PACKET_FRIEND_REQ, NET_PACKET_CRYPTO, createToxDhtCryptoRequest, openToxDhtCryptoRequest } from "./compat/tox-dht-crypto.js";
11import { NET_PACKET_PING_REQUEST, NET_PACKET_PING_RESPONSE, NET_PACKET_GET_NODES, NET_PACKET_SEND_NODES, encodeDhtRpc, decodeDhtRpc, buildPingPlain, parsePingPlain, buildGetNodesPlain, parseGetNodesPlain, buildSendNodesPlain, parseSendNodesNodeBytes, packUdpNodeV4 } from "./compat/dht-rpc.js";
12import { FileTransferManager, PACKET_ID_FILE_SENDREQUEST, PACKET_ID_FILE_CONTROL, PACKET_ID_FILE_DATA, PACKET_ID_FILE_FEC } from "./compat/filetransfer.js";
13import { NET_PACKET_CRYPTO_DATA, NET_PACKET_CRYPTO_HS, NET_PACKET_COOKIE_REQUEST, NET_PACKET_COOKIE_RESPONSE, createCookieRequest, createCookieResponse, createCryptoDataPacket, createCryptoHandshake, openCookieRequest, openCookieResponse, openCryptoDataPacket, openCryptoHandshake, incrementNonce } from "./compat/net-crypto.js";
14import { LegacyExpressClient } from "./compat/express.js";
15import { TcpRelayPool } from "./compat/tcp-relay-pool.js";
16import { LegacyDhtClient } from "./compat/dht.js";
17import { loadOrCreateKeyPair } from "./crypto/keypair.js";
18import { signDetached } from "./crypto/sign.js";
19import { base58ToBytes } from "./utils/base58.js";
20import { UdpTransport } from "./transport/udp.js";
21import { bytesToHex, concatBytes, randomBytes } from "./utils/bytes.js";
22import { buildBindingRequest, decodeStun, decodeXorMappedAddress, findAttr, STUN_ATTR_XOR_MAPPED_ADDRESS, STUN_BINDING_SUCCESS } from "./stun.js";
23import { TurnClient } from "./turn.js";
24import { createSocket as createDgramSocket } from "dgram";
25// Dedicated TURN relay servers — fixed public relays used as a stable
26// fallback path when direct UDP hole-punch fails or flaps (symmetric NAT,
27// NAT remaps, lossy direct path). A relay endpoint never NAT-flaps, so the
28// path stays put even when the peers' NATs churn. Static long-term creds.
29const TURN_RELAY_SERVERS = [
30 { host: "tokyo.fi.chat", port: 3478, username: "allcom", password: "allcompass" }
32const ANNOUNCE_WAIT_TIMEOUT_MS = readEnvInt("DECENT_ANNOUNCE_WAIT_TIMEOUT_MS", 4000);
33const MAX_FRIEND_ROUTE_ATTEMPTS = readEnvInt("DECENT_FRIEND_ROUTE_MAX_ATTEMPTS", 12);
34// How many in-flight announce step1 requests to fan out at once. Toxcore
35// pipelines all 12 of its onion clients in parallel; we batch up to this
36// many concurrent #sendAnnounceAndWait calls so the worst-case walk drops
37// from (per-node-timeout × 12) ≈ 60s down to ~10s. Configurable via
38// DECENT_FRIEND_ROUTE_BATCH_SIZE — set to 1 to revert to sequential.
39const FRIEND_ROUTE_BATCH_SIZE = readEnvInt("DECENT_FRIEND_ROUTE_BATCH_SIZE", 8);
40// Node soft-blacklist: after N consecutive failures (timeouts) a node
41// is parked for a TTL window so we don't waste batch slots on it.
42// Set NODE_BLACKLIST_THRESHOLD=0 to disable. Successful response from
43// the same node clears it instantly.
44const NODE_BLACKLIST_THRESHOLD = readEnvInt("DECENT_NODE_BLACKLIST_THRESHOLD", 5);
45const NODE_BLACKLIST_BASE_TTL_MS = readEnvInt("DECENT_NODE_BLACKLIST_BASE_TTL_MS", 60_000);
46const NODE_BLACKLIST_MAX_TTL_MS = readEnvInt("DECENT_NODE_BLACKLIST_MAX_TTL_MS", 600_000);
47const FRIEND_ANNOUNCE_ATTEMPTS = readEnvInt("DECENT_FRIEND_ANNOUNCE_ATTEMPTS", 1);
48const JOIN_ANNOUNCE_TIMEOUT_MS = readEnvInt("DECENT_JOIN_ANNOUNCE_TIMEOUT_MS", 12000);
49const SELF_ANNOUNCE_INTERVAL_MS = readEnvInt("DECENT_SELF_ANNOUNCE_INTERVAL_MS", 20000);
50// Classic-DHT maintenance cadence. Every tick we get_nodes toward our own key