And also validate opts for unknown types, before other side effects.
Fixes#15833
Change-Id: I4cabe16c49c5b7566dcafbec59f2cd1e0c8b4b3c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of using the version package (which depends on
tailcfg.CurrentCapabilityVersion) to get the git commit hash, do it
directly using debug.BuildInfo. This way, when changing struct fields in
tailcfg, we can successfully `go generate` it without compiler errors.
Updates #9634
Updates https://github.com/tailscale/corp/issues/26717
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
TS_CONTROL_IS_PLAINTEXT_HTTP no longer does anything as of
8fd471ce5748d2129dba584b4fa14b0d29229299
Updates #13597
Change-Id: I32ae7f8c5f2a2632e80323b1302a36295ee00736
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for Taildrop integration tests using them from another package.
Updates #15812
Change-Id: I6a995de4e7400658229d99c90349ad5bd1f503ae
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So it can be exported & used by other packages in future changes.
Updates #15812
Change-Id: I319000989ebc294e29c92be7f44a0e11ae6f7761
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were missing this metric, but it can be important for some workloads.
Varz memstats output allocation cost reduced from 30 allocs per
invocation to 1 alloc per invocation.
Updates tailscale/corp#28033
Signed-off-by: James Tucker <james@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We update profileManager to allow registering a single state (profile+prefs) change hook.
This is to invert the dependency between the profileManager and the LocalBackend, so that
instead of LocalBackend asking profileManager for the state, we can have profileManager
call LocalBackend when the state changes.
We also update feature.Hook with a new (*feature.Hook).GetOk method to avoid calling both
IsSet and Get.
Updates tailscale/corp#28014
Updates #12614
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This further minimizes the number of places where the profile manager updates the current profile and prefs.
We also document a scenario where an implicit profile switch can occur.
We should be able to address it after (partially?) inverting the dependency between
LocalBackend and profileManager, so that profileManager notifies LocalBackend
of profile changes instead of the other way around.
Updates tailscale/corp#28014
Updates #12614
Signed-off-by: Nick Khyl <nickk@tailscale.com>
The previous strategy assumed clients maintained adequate state to
understand the relationship between endpoint allocation and the server
it was allocated on.
magicsock will not have awareness of the server's disco key
pre-allocation, it only understands peerAPI address at this point. The
second client to allocate on the same server could trigger
re-allocation, breaking a functional relay server endpoint.
If magicsock needs to force reallocation we can add opt-in behaviors
for this later.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We had an ordered set type (set.Slice) already but we occasionally want
to do the same thing with a map, preserving the order things were added,
so add that too, as mapsx.OrderedMap[K, V], and then use in ipnext.
Updates #12614
Change-Id: I85e6f5e11035571a28316441075e952aef9a0863
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Now that 25c4dc5fd70 removed unregistering hooks and made them into
slices, just expose the slices and remove the setter funcs.
This removes boilerplate ceremony around adding new hooks.
This does export the hooks and make them mutable at runtime in theory,
but that'd be a data race. If we really wanted to lock it down in the
future we could make the feature.Hooks slice type be an opaque struct
with an All() iterator and a "frozen" bool and we could freeze all the
hooks after init. But that doesn't seem worth it.
This means that hook registration is also now all in one place, rather
than being mixed into ProfilesService vs ipnext.Host vs FooService vs
BarService. I view that as a feature. When we have a ton of hooks and
the list is long, then we can rearrange the fields in the Hooks struct
as needed, or make sub-structs, or big comments.
Updates #12614
Change-Id: I05ce5baa45a61e79c04591c2043c05f3288d8587
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The typical way to implement union types in Go
is to use an interface where the set of types is limited.
However, there historically has been poor support
in v1 "encoding/json" with interface types where
you can marshal such values, but fail to unmarshal them
since type information about the concrete type is lost.
The MakeInterfaceCoders function constructs custom
marshal/unmarshal functions such that the type name
is encoded in the JSON representation.
The set of valid concrete types for an interface
must be statically specified for this to function.
Updates tailscale/corp#22024
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
These were likely added after everything else was updated to use tsd.NewSystem,
in a feature branch, and before it was merged back into main.
Updates #15160
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Both are populated from the current netmap's MagicDNSSuffix.
But building a full ipnstate.Status (with peers!) is expensive and unnecessary.
Updates #cleanup
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Replace all instances of interface{} with any to resolve the
golangci-lint errors that appeared in the previous tsidp PR.
Updates #cleanup
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
tstime.GoDuration JSON serializes with time.Duration.String(), which is
more human-friendly than nanoseconds.
ServerEndpoint is currently experimental, therefore breaking changes
are tolerable.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
The encoding/json/v2 effort may end up changing
the default represention of time.Duration in JSON.
See https://go.dev/issue/71631
The GoDuration type allows us to explicitly use
the time.Duration.String representation regardless of
whether we serialize with v1 or v2 of encoding/json.
Updates tailscale/corp#27502
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We added this helper in 1e2e319e7d26. Remove this copy.
Updates #cleanup
Change-Id: I5b0681acc23692beed35951c9902ac9ceca0a8b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The relay server is still permanently disabled until node attribute
changes are wired up in a future commit.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
QNAP now requires builds to be signed with an HSM.
This removes support for signing with a local keypair.
This adds support for signing with a Google Cloud hosted key.
The key should be an RSA key with protection level `HSM` and that uses PSS padding and a SHA256 digest.
The GCloud project, keyring and key name are passed in as command-line arguments.
The GCloud credentials and the PEM signing certificate are passed in as Base64-encoded command-line arguments.
Updates tailscale/corp#23528
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This adds a feature/taildrop package, a ts_omit_taildrop build tag,
and starts moving code to feature/taildrop. In some cases, code
remains where it was but is now behind a build tag. Future changes
will move code to an extension and out of LocalBackend, etc.
Updates #12614
Change-Id: Idf96c61144d1a5f707039ceb2ff59c99f5c1642f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When an event bus is plumbed in, use it to subscribe and react to port mapping
updates instead of using the client's callback mechanism. For now, the callback
remains available as a fallback when an event bus is not provided.
Updates #15160
Change-Id: I026adca44bf6187692ee87ae8ec02641c12f7774
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
When an event bus is configured publish an event each time a new port mapping
is updated. Publication is unconditional and occurs prior to calling any
callback that is registered. For now, the callback is still fired in a separate
goroutine as before -- later, those callbacks should become subscriptions to
the published event.
For now, the event type is defined as a new type here in the package. We will
want to move it to a more central package when there are subscribers. The event
wrapper is effectively a subset of the data exported by the internal mapping
interface, but on a concrete struct so the bus plumbing can inspect it.
Updates #15160
Change-Id: I951f212429ac791223af8d75b6eb39a0d2a0053a
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
In preparation for adding more parameters (and later, moving some away), rework
the portmapper constructor to accept its arguments on a Config struct rather
than positionally.
This is a breaking change to the function signature, but one that is very easy
to update, and a search of GitHub reveals only six instances of usage outside
clones and forks of Tailscale itself, that are not direct copies of the code
fixed up here.
While we could stub in another constructor, I think it is safe to let those
folks do the update in-place, since their usage is already affected by other
changes we can't test for anyway.
Updates #15160
Change-Id: I9f8a5e12b38885074c98894b7376039261b43f43
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
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>
This feature is "registered" as an ipnlocal.Extension, and
conditionally linked depending on GOOS and ts_omit_relayserver build
tag.
The feature is not linked on iOS in attempt to limit the impact to
binary size and resulting effect of pushing up against NetworkExtension
limits. Eventually we will want to support the relay server on iOS,
specifically on the Apple TV. Apple TVs are well-fitted to act as
underlay relay servers as they are effectively always-on servers.
This skeleton begins to tie a PeerAPI endpoint to a net/udprelay.Server.
The PeerAPI endpoint is currently no-op as
extension.shouldRunRelayServer() always returns false. Follow-up commits
will implement extension.shouldRunRelayServer().
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>