Three fixes to what the extension tells you about itself, and one to what it does before it is ready.
No re-registration is needed this time — the native messaging host name has not changed since v1.2.1. Upgrading still means replacing the backend binary, since it is copied into your browser's configuration directory at install time:
go run github.com/iazat/ts-browser-ext@latest --install=C<your-extension-id> # Chrome
go run github.com/iazat/ts-browser-ext@latest --install=F # Firefox
Traffic could leave through your own address for the first seconds
The proxy starts listening and reports its port to the extension before tsnet has finished starting, and the browser is pointed at it straight away. Until the tailnet reached Running there was a window — seconds, on a cold start — in which a request went out through this machine's own connection instead of the exit node.
Nothing about it was visible afterwards. By the time you looked, the backend was running and the popup named the exit node correctly, so a page that went out from the real address looked no different from one that did not. A site that decides what to serve by address would answer that first request from the wrong country and keep the result.
The proxy now refuses to dial until the tailnet is actually carrying traffic. Two cases stay open deliberately: with no exit node configured, leaving through this machine is what you asked for, and the login page has to stay reachable because it is fetched through this same proxy.
If you load a page in the first moment after the backend restarts, you may now see not routing yet: an exit node is configured but the tailnet is Starting instead of the page. That is the fix working. It clears in a second or two.
The popup said "Connected as Not connected"
Whenever the backend came up already logged in, the popup reported an empty tailnet name — sometimes for a long time, because the name only arrived when something about the tailnet happened to change. The management page at 100.100.100.100 was unaffected and named the tailnet correctly, which is what made the two disagree on screen.
The backend was subscribing to the IPN bus without asking for the initial network map. It does now, and falls back to the status it already fetches for the exit node list. Where the name genuinely is not known, the popup says plain Connected rather than filling the gap with a phrase that contradicts itself.
The exit node picker claimed None before it knew
None is a claim: it says no exit node is configured. Two states at startup looked identical to the code building the picker and meant nothing of the kind — the preferences had not been read yet, or they had been read and named a node that was not in the peer list yet because the network map was still arriving.
Both settle within seconds, and both were announced as None at the moment you are most likely to be looking: right after switching on. The picker now shows a disabled Connecting… while the answer is still unknown.
Disabling it matters as much as the label. The picker sends your selection on every change, and an empty value means "stop using an exit node" — so touching a list that was wrongly showing None would have cleared a selection you could not see.
The preferences read also has its own deadline now instead of inheriting whatever was left of the one the status call ahead of it had already spent, and a failure to read them is logged rather than passed off as an answer.
Known limitations
- Firefox has still not been run live. Its test suite passes and it is exercised against a mocked browser API on every commit, but nobody has loaded it through
about:debugging. - Losing the backend still hands the browser a direct connection. When the native messaging host goes away, the extension resets the browser proxy to direct rather than to a dead port — about a second per reconnect, with the same exposure as the startup window fixed above. Making that fail closed would mean pages stop loading entirely whenever the backend dies, and has not been done.
- Windows cannot register the native host. The binary builds, but there is no registry install path yet.