Add batcher cases for NodeEndpoint and NodeDERP that query
NodeStore for current state and send PeerChangedPatch with
both endpoints and DERP region, avoiding full map responses.
Update batcher_test to pass NodeView to change constructors.
Detect when only endpoints or DERP region changed and return
specific change types instead of generic NodeAdded. This allows
the batcher to send lightweight PeerChangedPatch responses.
When both endpoint and DERP change together, prioritize endpoint
change type. The batcher will include both in the patch response.
Also fix NodeOnline/NodeOffline calls to pass NodeView.
Add specific change types for endpoint and DERP region updates,
enabling lightweight patch responses instead of full map updates.
Also fix NodeOnline/NodeOffline to accept NodeView and properly
extract IsSubnetRouter flag, fixing a bug where subnet routers
would incorrectly receive patch responses instead of full maps.
Add EndpointsChanged function that compares endpoint slices
without regard to ordering. Uses netip.AddrPort.Compare with
slices.SortFunc to enable accurate change detection.
Update PeerChangeFromMapRequest to only include endpoints in
PeerChange when they actually changed, avoiding unnecessary
updates to peers.
Correctly identify Viper's ConfigFileNotFoundError in LoadConfig to log a warning and use defaults, unifying behavior with empty config files. Fixes fatal error when no config file is present for CLI commands relying on environment variables.
This PR addresses some consistency issues that was introduced or discovered with the nodestore.
nodestore:
Now returns the node that is being put or updated when it is finished. This closes a race condition where when we read it back, we do not necessarily get the node with the given change and it ensures we get all the other updates from that batch write.
auth:
Authentication paths have been unified and simplified. It removes a lot of bad branches and ensures we only do the minimal work.
A comprehensive auth test set has been created so we do not have to run integration tests to validate auth and it has allowed us to generate test cases for all the branches we currently know of.
integration:
added a lot more tooling and checks to validate that nodes reach the expected state when they come up and down. Standardised between the different auth models. A lot of this is to support or detect issues in the changes to nodestore (races) and auth (inconsistencies after login and reaching correct state)
This PR was assisted, particularly tests, by claude code.
- tailscale client gets a new AuthUrl and sets entry in the regcache
- regcache entry expires
- client doesn't know about that
- client always polls followup request а gets error
When user clicks "Login" in the app (after cache expiry), they visit
invalid URL and get "node not found in registration cache". Some clients
on Windows for e.g. can't get a new AuthUrl without restart the app.
To fix that we can issue a new reg id and return user a new valid
AuthUrl.
RegisterNode is refactored to be created with NewRegisterNode() to
autocreate channel and other stuff.