fix: DHT bootstrap + hostname redirect fallback - #231
Conversation
|
Thank you for this fix a ton! I don't know a ton about DHT internals so wasn't comfy looking into it myself. |
6793516 to
58f2322
Compare
|
Context from digging into the "DHT stuck at 1 node under Bun" issue, in case it's useful (related: #232). The bencode The real reason the routing table stalls at one node is usage, not bencode:
On the same machine/network, libtorrent reaches ~67 DHT nodes while #232 addresses the usage issues (calls Not a knock on this PR — the hostname-redirect fallback here is a separate, orthogonal improvement. Just flagging that the bencode piece can likely be dropped. |
When a peer's /auth response advertises a different hostname than what was connected to (common with dynamic IPs/NAT), the previous code redirected auth to the advertised hostname. If that hostname was unreachable, the connection failed entirely — even though the original hostname was responding fine. Fix: if advertised hostname auth fails, fall back to verifying the server signature against the advertised identity while keeping the original route. Also adds extra DHT bootstrap nodes for better resilience.
58f2322 to
0aeddca
Compare
|
Thanks for the thorough investigation @bluejorts — you're right on all counts. I verified the dependency chain myself:
So This PR now contains only the two orthogonal fixes:
|
ba49850 to
3c224bc
Compare
The DHT routing table was stuck at a single node (itself) on cold start,
while libtorrent reached 67 nodes on the same network — so this was a
usage problem, not the network. Five compounding issues, all fixed:
- dht.listen() was never called, so the socket's 'listening' event never
fired and bittorrent-dht's internal bucket-refresh / re-bootstrap-when-
isolated maintenance loop never started. Now bind explicitly on a free
ephemeral port (node.port belongs to the UTP transport).
- The 5s query timeout was passed to k-rpc, which ignores it; the socket
used its 2s default and dropped slow-but-live routers. Moved to
krpcSocket({ timeout: 5000 }).
- Only a single shallow bootstrap lookup ran, then the DHT idled until the
15-minute reannounce. Added a cold-bootstrap loop that re-seeds routers
and re-runs lookup(ownId) every 10s until the table reaches 20 nodes.
- Raised k-rpc concurrency (16→32) and backgroundConcurrency (4→16) for
faster traversal; added backgroundConcurrency to the KRPCOptions type.
- Cache persistence only fired at >50 nodes (never reached), so restarts
were always cold. Now persists whenever the table reaches a new high of
>=8 nodes, seeding cacheSize from the loaded cache.
Bootstrap list: replaced the mostly-dead/mis-configured set (wrong
dht.libtorrent.org port :6881, defunct utorrent/bitcomet/aelitis routers,
and Hydrabase peer hostnames that don't speak the DHT) with the routers
empirically verified live: dht.transmissionbt.com:6881,
dht.libtorrent.org:25401 (correct port), the canonical bittorrent/utorrent
routers, and a transmissionbt IP fallback.
Verified: real app now reaches "Ready with 53 nodes" on startup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VjgRYtdZZk6LuvTmsmpSh
# Conflicts:
# src/backend/config.ts
3c224bc to
68ccbf3
Compare
Cherry-picked bluejorts's DHT fixes from #232 into this branch so CI passes.
Changes
DHT bootstrap fixes (from #232, bluejorts)
dht.listen()— now called explicitly so bittorrent-dht's internal bucket-refresh / re-bootstrap-when-isolated maintenance loop fires.krpcSocket({ timeout: 5000 })(k-rpc ignores the timeout option, k-rpc-socket respects it).lookup(ownId)every 10s until the table reaches 20 nodes, instead of a single shallow lookup.Hostname redirect fallback (
src/backend/networking/http.ts)When a peer's
/authresponse advertises a different hostname (common with dynamic IPs / NAT), fall back to verifying the server signature against the advertised identity while keeping the original route.Bootstrap nodes (
src/backend/config.ts)Aligned with bluejorts's verified list (correct port for
dht.libtorrent.org:25401, removed dead routers).Testing