summaryrefslogtreecommitdiffhomepage
path: root/ipn/ipnserver/server_test.go
AgeCommit message (Collapse)AuthorFilesLines
2025-09-25various: allow tailscaled shutdown via LocalAPINick Khyl1-0/+60
A customer wants to allow their employees to restart tailscaled at will, when access rights and MDM policy allow it, as a way to fully reset client state and re-create the tunnel in case of connectivity issues. On Windows, the main tailscaled process runs as a child of a service process. The service restarts the child when it exits (or crashes) until the service itself is stopped. Regular (non-admin) users can't stop the service, and allowing them to do so isn't ideal, especially in managed or multi-user environments. In this PR, we add a LocalAPI endpoint that instructs ipnserver.Server, and by extension the tailscaled process, to shut down. The service then restarts the child tailscaled. Shutting down tailscaled requires LocalAPI write access and an enabled policy setting. Updates tailscale/corp#32674 Updates tailscale/corp#32675 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-05-09ipn/ipn{server,test}: extract the LocalAPI test client and server into ipntestNick Khyl1-335/+44
In this PR, we extract the in-process LocalAPI client/server implementation from ipn/ipnserver/server_test.go into a new ipntest package to be used in high‑level black‑box tests, such as those for the tailscale CLI. Updates #15575 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-16net/netmon: publish events to event busDavid Anderson1-1/+1
Updates #15160 Signed-off-by: David Anderson <dave@tailscale.com>
2025-04-16all: update the tsd.System constructor name (#15372)M. J. Fromberger1-1/+1
Replace NewSystemWithEventBus with plain NewSystem, and update all usage. See https://github.com/tailscale/tailscale/pull/15355#discussion_r2003910766 Updates #15160 Change-Id: I64d337f09576b41d9ad78eba301a74b9a9d6ebf4 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-04-16all: construct new System values with an event bus pre-populatedM. J. Fromberger1-1/+1
Although, at the moment, we do not yet require an event bus to be present, as we start to add more pieces we will want to ensure it is always available. Add a new constructor and replace existing uses of new(tsd.System) throughout. Update generated files for import changes. Updates #15160 Change-Id: Ie5460985571ade87b8eac8b416948c7f49f0f64b Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
2025-02-05all: use new LocalAPI client package locationBrad Fitzpatrick1-9/+10
It was moved in f57fa3cbc30e. Updates tailscale/corp#22748 Change-Id: I19f965e6bded1d4c919310aa5b864f2de0cd6220 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-15ipn/ipnserver: fix a deadlock in (*Server).blockWhileIdentityInUseNick Khyl1-0/+46
If the server was in use at the time of the initial check, but disconnected and was removed from the activeReqs map by the time we registered a waiter, the ready channel will never be closed, resulting in a deadlock. To avoid this, we check whether the server is still busy after registering the wait. Fixes #14655 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-15ipn/ipnserver: fix TestConcurrentOSUserSwitchingOnWindowsNick Khyl1-1/+14
I made a last-minute change in #14626 to split a single loop that created 1_000 concurrent connections into an inner and outer loop that create 100 concurrent connections 10 times. This introduced a race because the last user's connection may still be active (from the server's perspective) when a new outer iteration begins. Since every new client gets a unique ClientID, but we reuse usernames and UIDs, the server may let a user in (as the UID matches, which is fine), but the test might then fail due to a ClientID mismatch: server_test.go:232: CurrentUser(Initial): got &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-2 false false}; want &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-114 false false} In this PR, we update (*testIPNServer).blockWhileInUse to check whether the server is currently busy and wait until it frees up. We then call blockWhileInUse at the end of each outer iteration so that the server is always in a known idle state at the beginning of the inner loop. We also check that the current user is not set when the server is idle. Updates tailscale/corp#25804 Updates #14655 (found when working on it) Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/ipnserver: fix race condition where LocalBackend is reset after a ↵Nick Khyl1-0/+67
different user connects In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly sets and unsets the current user when two different clients send requests concurrently (A sends request, B sends request, A's request completes, B's request completes). The expectation is that the user who wins the race becomes the current user from the LocalBackend's perspective, remaining in this state until they disconnect, after which a different user should be able to connect and use the LocalBackend. We then fix the second of two bugs in (*Server).addActiveHTTPRequest, where a race condition causes the LocalBackend's state to be reset after a new client connects, instead of after the last active request of the previous client completes and the server becomes idle. Fixes tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/{ipnlocal,ipnserver}: remove redundant ↵Nick Khyl1-0/+29
(*LocalBackend).ResetForClientDisconnect In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly sets and unsets the current user when two different users connect sequentially (A connects, A disconnects, B connects, B disconnects). We then fix the test by updating (*ipn/ipnserver.Server).addActiveHTTPRequest to avoid calling (*LocalBackend).ResetForClientDisconnect again after a new user has connected and been set as the current user with (*LocalBackend).SetCurrentUser(). Since ipn/ipnserver.Server does not allow simultaneous connections from different Windows users and relies on the LocalBackend's current user, and since we already reset the LocalBackend's state by calling ResetForClientDisconnect when the last active request completes (indicating the server is idle and can accept connections from any Windows user), it is unnecessary to track the last connected user on the ipnserver.Server side or call ResetForClientDisconnect again when the user changes. Additionally, the second call to ResetForClientDisconnect occurs after the new user has been set as the current user, resetting the correct state for the new user instead of the old state of the now-disconnected user, causing issues. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-14ipn/{ipnauth,ipnlocal,ipnserver}, client/tailscale: make ipnserver.Server ↵Nick Khyl1-0/+358
testable We update client/tailscale.LocalClient to allow specifying an optional Transport (http.RoundTripper) for LocalAPI HTTP requests, and implement one that injects an ipnauth.TestActor via request headers. We also add several functions and types to make testing an ipn/ipnserver.Server possible (or at least easier). We then use these updates to write basic tests for ipnserver.Server, ensuring it works on non-Windows platforms and correctly sets and unsets the LocalBackend's current user when a Windows user connects and disconnects. We intentionally omit tests for switching between different OS users and will add them in follow-up commits. Updates tailscale/corp#25804 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2023-01-27all: update copyright and license headersWill Norris1-3/+2
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
2022-12-03ipn/{ipnserver,localapi}: fix InUseOtherUser handling with WatchIPNBusBrad Fitzpatrick1-0/+47
Updates tailscale/corp#8222 Change-Id: I2d6fa6514c7b8d0f89fded35a2d44e7df27e6fb1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-11-25ipn/ipnserver: remove IPN protocol serverBrad Fitzpatrick1-86/+0
Unused in this repo as of the earlier #6450 (300aba61a6) and unused in the Windows GUI as of tailscale/corp#8065. With this ipn.BackendServer is no longer used and could also be removed from this repo. The macOS and iOS clients still temporarily depend on it, but I can move it to that repo instead while and let its migration proceed on its own schedule while we clean this repo up. Updates #6417 Updates tailscale/corp#8051 Change-Id: Ie13f82af3eb9f96b3a21c56cdda51be31ddebdcf Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-06-03ipn/ipnserver, cmd/tailscaled: fix peerapi on WindowsBrad Fitzpatrick1-1/+7
We weren't wiring up netstack.Impl to the LocalBackend in some cases on Windows. This fixes Windows 7 when run as a service. Updates #4750 (fixes after pull in to corp repo) Change-Id: I9ce51b797710f2bedfa90545776b7628c7528e99 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2022-03-17all: use any instead of interface{}Josh Bleecher Snyder1-2/+2
My favorite part of generics. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2022-02-28ipn/store: add common package for instantiating ipn.StateStoresMaisem Ali1-1/+2
Also move KubeStore and MemStore into their own package. RELNOTE: tsnet now supports providing a custom ipn.StateStore. Signed-off-by: Maisem Ali <maisem@tailscale.com>
2021-12-09safesocket: add ConnectionStrategy, provide control over fallbacksJosh Bleecher Snyder1-1/+2
fee2d9fad added support for cmd/tailscale to connect to IPNExtension. It came in two parts: If no socket was provided, dial IPNExtension first, and also, if dialing the socket failed, fall back to IPNExtension. The second half of that support caused the integration tests to fail when run on a machine that was also running IPNExtension. The integration tests want to wait until the tailscaled instances that they spun up are listening. They do that by dialing the new instance. But when that dial failed, it was falling back to IPNExtension, so it appeared (incorrectly) that tailscaled was running. Hilarity predictably ensued. If a user (or a test) explicitly provides a socket to dial, it is a reasonable assumption that they have a specific tailscaled in mind and don't want to fall back to IPNExtension. It is certainly true of the integration tests. Instead of adding a bool to Connect, split out the notion of a connection strategy. For now, the implementation remains the same, but with the details hidden a bit. Later, we can improve that. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-02net/tsdial: give netstack a Dialer, start refactoring name resolutionBrad Fitzpatrick1-1/+2
This starts to refactor tsdial.Dialer's name resolution to have different stages: in-memory MagicDNS vs system resolution. A future change will plug in ExitDNS resolution. This also plumbs a Dialer into netstack and unexports the dnsMap internals. And it removes some of the async AddNetworkMapCallback usage and replaces it with synchronous updates of the Dialer's netmap from LocalBackend, since the LocalBackend has the Dialer too. Updates #3475 Change-Id: Idcb7b1169878c74f0522f5151031ccbc49fe4cb4 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-12-01net/tsdial: also plumb TUN name and monitor into tsdial.DialerBrad Fitzpatrick1-1/+1
In prep for moving stuff out of LocalBackend. Change-Id: I9725aa9c3ebc7275f8c40e040b326483c0340127 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-11-05cmd/tailscaled, ipn/ipnserver: refactor ipnserverBrad Fitzpatrick1-4/+10
More work towards removing the massive ipnserver.Run and ipnserver.Options and making composable pieces. Work remains. (The getEngine retry loop on Windows complicates things.) For now some duplicate code exists. Once the Windows side is fixed to either not need the retry loop or to move the retry loop into a custom wgengine.Engine wrapper, then we can unify tailscaled_windows.go too. Change-Id: If84d16e3cd15b54ead3c3bb301f27ae78d055f80 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-09-15all: close fake userspace engines when tests completeJosh Bleecher Snyder1-1/+1
We were leaking FDs. In a few places, switch from defer to t.Cleanup. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-03-01cmd/tailscaled, wgengine: remove --fake, replace with netstackBrad Fitzpatrick1-1/+1
And add a --socks5-server flag. And fix a race in SOCKS5 replies where the response header was written concurrently with the copy from the backend. Co-authored with Naman Sood. Updates #707 Updates #504 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-01-11cmd/tailscaled, wgengine/netstack: add start of gvisor userspace netstack workBrad Fitzpatrick1-1/+1
Not usefully functional yet (mostly a proof of concept), but getting it submitted for some work @namansood is going to do atop this. Updates #707 Updates #634 Updates #48 Updates #835
2020-10-02all: use testing.T.TempDirJosh Bleecher Snyder1-7/+1
Bit of Friday cleanup. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2020-07-29ipn/ipnserver: make Engine argument a func that tries again for each connectionBrad Fitzpatrick1-1/+1
So a backend in server-an-error state (as used by Windows) can try to create a new Engine again each time somebody re-connects, relaunching the GUI app. (The proper fix is actually fixing Windows issues, but this makes things better in the short term) Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-05-15wgengine: log node IDs when peers are added/removed (#381)Wendi Yu1-5/+1
Also stop logging data sent/received from nodes we're not connected to (ie all those `x`s being logged in the `peers: ` line) Signed-off-by: Wendi <wendi.yu@yahoo.ca>
2020-05-08Implement rate limiting on log messages (#356)Wendi Yu1-1/+5
Implement rate limiting on log messages Addresses issue #317, where logs can get spammed with the same message nonstop. Created a rate limiting closure on logging functions, which limits the number of messages being logged per second based on format string. To keep memory usage as constant as possible, the previous cache purging at periodic time intervals has been replaced by an LRU that discards the oldest string when the capacity of the cache is reached. Signed-off-by: Wendi Yu <wendi.yu@yahoo.ca>
2020-03-03ipn/ipnserver: document potential race, start on test for itBrad Fitzpatrick1-0/+77