The test sets up an HTTP-over-Unix server and a reverse proxy pointed at
this server, but prior to this change did not round-trip anything to the
backing server. This change ensures that we test code paths which proxy
Unix sockets for serve.
Fixes#19232
Signed-off-by: Harry Harpham <harry@tailscale.com>
Prior to this change, closing multiple ServiceListeners concurrently
could result in failures as the independent close operations vie for the
attention of the Server's LocalBackend. The close operations would each
obtain the current ETag of the serve config and try to write new serve
config using this ETag. When one write invalidated the ETag of another,
the latter would fail. Exacerbating the issue, ServiceListener.Close
cannot be retried.
This change resolves the bug by using Server.mu to synchronize across
all ServiceListener.Close operations, ensuring they happen serially.
Fixes#19169
Signed-off-by: Harry Harpham <harry@tailscale.com>
This is a regression test for #19166, in which it was discovered that
after calling Server.ListenService for multiple Services, only the
Service from the most recent call would be advertised.
The bug was fixed in 99f8039101
Updates #19166
Signed-off-by: Harry Harpham <harry@tailscale.com>
Previous to this change, closing the listener returned by
Server.ListenService would free system resources, but not clean up state
in the Server's local backend. With this change, the local backend state
is now cleaned on close.
Fixestailscale/corp#35860
Signed-off-by: Harry Harpham <harry@tailscale.com>
TestListenService needs to setup state (capabilities, advertised routes,
ACL tags, etc.). It is imperative that this state propagates to all nodes
in the test tailnet before proceeding with the test. To achieve this,
TestListenService currently polls each node's local backend in a loop.
Using local.Client.WatchIPNBus improves the situation by blocking until
a new netmap comes in.
Fixestailscale/corp#36244
Signed-off-by: Harry Harpham <harry@tailscale.com>
This helps us distribute tests across CI runners. Most tsnet tests call
tstest.Shard, but two recently added tests do not: tsnet.TestFunnelClose
and tsnet.TestListenService. This commit resolves the oversight.
Fixestailscale/corp#36242
Signed-off-by: Harry Harpham <harry@tailscale.com>
Updating a node on a testcontrol server should trigger netmap updates to
all connected streaming clients. This was not the case previous to this
change and consequently caused race conditions in tests. It was possible
for a test to call UpdateNode and for connected nodes to never see the
update propagate.
Updates #16340Fixes#18703
Signed-off-by: Harry Harpham <harry@tailscale.com>
TestOnlyTaggedPeersCanBeDialed has a race condition:
- The test untags ps[2] and waits until ps[0] sees this tag dropped from
ps[2] in the netmap.
- Later the test tries to dial ps[2] from ps[0] and expects the dial to
fail as authorization to dial relies on the presence of the tag, now
removed from ps[2].
- However, the authorization layer caches the status used to consult peer
tags. When the dial happens before the cache times out, the test fails.
- Due to a bug in testcontrol.Server.UpdateNode, which the test uses to
remove the tag, netmap updates are not immediately triggered. The test
has to wait for the next natural set of netmap updates, which on my
machine takes about 22 seconds. As a result, the cache in the
authorization layer times out and the test passes.
- If one fixes the bug in UpdateNode, then netmap updates happen
immediately, the cache is no longer timed out when the dial occurs, and
the test fails.
Fixes#18720
Updates #18703
Signed-off-by: Harry Harpham <harry@tailscale.com>
Two methods were recently added to the testcontrol.Server type:
AddDNSRecords and SetGlobalAppCaps. These two methods should trigger
netmap updates for all nodes connected to the Server instance, the way
that other state-change methods do (see SetNodeCapMap, for example).
This will also allow us to get rid of Server.ForceNetmapUpdate, which
was a band-aid fix to force the netmap updates which should have been
triggered by the aforementioned methods.
Fixestailscale/corp#37102
Signed-off-by: Harry Harpham <harry@tailscale.com>
Every other listen method on tsnet.Server makes this clarification, so
should ListenService.
Fixestailscale/corp#36207
Signed-off-by: Harry Harpham <harry@tailscale.com>
This change allows tsnet nodes to act as Service hosts by adding a new
function, tsnet.Server.ListenService. Invoking this function will
advertise the node as a host for the Service and create a listener to
receive traffic for the Service.
Fixes#17697Fixestailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
This change adds API to ipn.LocalBackend to retrieve the ETag when
querying for the current serve config. This allows consumers of
ipn.LocalBackend.SetServeConfig to utilize the concurrency control
offered by ETags. Previous to this change, utilizing serve config ETags
required copying the local backend's internal ETag calcuation.
The local API server was previously copying the local backend's ETag
calculation as described above. With this change, the local API server
now uses the new ETag retrieval function instead. Serve config ETags are
therefore now opaque to clients, in line with best practices.
Fixestailscale/corp#35857
Signed-off-by: Harry Harpham <harry@tailscale.com>
Previously the funnel listener would leave artifacts in the serve
config. This caused weird out-of-sync effects like the admin panel
showing that funnel was enabled for a node, but the node rejecting
packets because the listener was closed.
This change resolves these synchronization issues by ensuring that
funnel listeners clean up the serve config when closed.
See also:
https://github.com/tailscale/tailscale/commit/e109cf9fdd405153a8d8c0ec52a87d7c8ce8689b
Updates #cleanup
Signed-off-by: Harry Harpham <harry@tailscale.com>
Prior to this change, we were resetting the tsnet's serve config every
time tsnet.Server.Up was run. This is important to do on startup, to
prevent messy interactions with stale configuration when the code has
changed.
However, Up is frequently run as a just-in-case step (for example, by
Server.ListenTLS/ListenFunnel and possibly by consumers of tsnet). When
the serve config is reset on each of these calls to Up, this creates
situations in which the serve config disappears unexpectedly. The
solution is to reset the serve config only on the first call to Up.
Fixes#8800
Updates tailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
The funnel command is sort of an alias for the serve command. This means
that the subcommands added to serve to support Services appear as
subcommands for funnel as well, despite having no meaning for funnel.
This change removes all such Services-specific subcommands from funnel.
Fixestailscale/corp#34167
Signed-off-by: Harry Harpham <harry@tailscale.com>
These validations were previously performed in the CLI frontend. There
are two motivations for moving these to the local backend:
1. The backend controls synchronization around the relevant state, so
only the backend can guarantee many of these validations.
2. Doing these validations in the back-end avoids the need to repeat
them across every frontend (e.g. the CLI and tsnet).
Updates tailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
Service hosts must be tagged nodes, meaning it is only valid to
advertise a Service from a machine which has at least one ACL tag.
Fixestailscale/corp#33197
Signed-off-by: Harry Harpham <harry@tailscale.com>