fix(dns): use the port holder enable said it would use - #267
Merged
Conversation
Preflight finds a bridge this run did not start, asks it the clearnet question, and on a good answer prints that it "is being used as-is". Then `enable` started a second daemon anyway. `startDaemon` decides "already running" from our own pidfile, so a holder it did not record is invisible to it. Both bridges then bind -- the socket is created with reuseAddr -- and the kernel hands the query to whichever took the more specific address. On the machine that found this, ours took 127.0.0.1 while the holder had 0.0.0.0, so the bridge the note promised would serve was the one receiving nothing. `holderForwards` was computed, returned and printed, and never read again before the start. This gates the start on it. The existing test was already named for this -- "a holder that forwards is used, not refused" -- and only asserted the note was printed, which is why the second daemon went unnoticed. It now asserts the bridge is not started, and a new test covers the other half: a holder that fails the clearnet question is the stale-bridge case, so --force past it must still start ours. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ThreatCrush Security Scan87 finding(s) HIGH/CRITICAL: 50 | MEDIUM: 37
…and 37 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
ralyodio
marked this pull request as ready for review
August 3, 2026 14:41
Merged
ralyodio
added a commit
that referenced
this pull request
Aug 3, 2026
Two resolver fixes, both of which look like working DNS from outside. #268 — a name pointed at a host answered an authoritative NOERROR with no records, which a client treats as final. seo.rank, chovy.hacker and alt.2600 were all unreachable while google.com resolved, so the machine looked healthy. RECORD_TYPES never consulted a published A or AAAA for an address question, and targetAddress() returned null for a hostname with nothing picking up after it. #267 — `dns enable` reported that a bridge already on the port "is being used as-is" and then started a second daemon anyway, which bound alongside it and took the queries the note promised to the first. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by running
sudo moshcode dns enableon a box that already had a bridge on 5354.Both lines are true, and they contradict each other.
What happens
preflightEnablefinds the holder, asks it the same clearnet questioncatchAllSafetyasks, and on a good answer reports it is being used as-is.startDaemonthen decides "already running" from our own pidfile — a holder it did not record is invisible to it — so it spawns a second daemon regardless.Both bind, because the socket is created with
reuseAddr: true(src/dns.mjs:816), and the kernel delivers to whichever took the more specific address. On the machine that found this, ours took127.0.0.1while the holder had0.0.0.0, so the bridge the note promised would serve was the one getting nothing.src/dns.mjs:1379-1398already documents this hazard in the other direction — ours starved by a holder. This is the same collision with the roles swapped, and the note makes it worse than silence by claiming the opposite.holderForwardswas computed at1458, used at1459to block a holder that does not forward, returned at1473, printed at2070— and never read again. The start at2315never saw it.The change
Gate the start on the preflight's own conclusion. A holder that forwards is reused and said so; everything else starts as before.
Deliberately narrow: a holder that fails the clearnet question stays a blocker, and
--forcepast it still starts ours over it. That is the stale-bridge case, where putting a working bridge in front is the point.Tests
a holder that forwards is used, not refusedwas already named for this behaviour and only asserted the note printed — which is exactly why the second daemon went unnoticed. It now assertsstartBridgeis never called and that the output says so. Revertingsrc/dns.mjsfails it onthe holder is used as-is, so there is nothing to start.A second test covers the forced non-forwarding path, so the gate cannot be widened into "never start when anything holds the port" without a failure.
Full suite: one failure,
TUI /prd still publishes a PRD in a healthy cwd, which times out identically on an unmodified checkout — pre-existing, a TUI test waiting on a pty, unrelated to this.🤖 Generated with Claude Code