From bc8d6e186294a7f1a21603b147c48d564fada103 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 00:11:12 +0100 Subject: [PATCH 1/6] initial capver packet tracking version Signed-off-by: Kristoffer Dalby --- hscontrol/capver/capver.go | 66 +++++++++++ hscontrol/capver/capver_generated.go | 54 +++++++++ hscontrol/capver/capver_test.go | 53 +++++++++ hscontrol/capver/gen/main.go | 157 +++++++++++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 hscontrol/capver/capver.go create mode 100644 hscontrol/capver/capver_generated.go create mode 100644 hscontrol/capver/capver_test.go create mode 100644 hscontrol/capver/gen/main.go diff --git a/hscontrol/capver/capver.go b/hscontrol/capver/capver.go new file mode 100644 index 0000000000..f2af1f9f15 --- /dev/null +++ b/hscontrol/capver/capver.go @@ -0,0 +1,66 @@ +package capver + +import ( + "sort" + "strings" + + xmaps "golang.org/x/exp/maps" + "tailscale.com/tailcfg" +) + +func tailscaleVersSorted() []string { + vers := xmaps.Keys(tailscaleToCapVer) + sort.Strings(vers) + return vers +} + +func capVersSorted() []tailcfg.CapabilityVersion { + capVers := xmaps.Keys(capVerToTailscaleVer) + sort.Slice(capVers, func(i, j int) bool { + return capVers[i] < capVers[j] + }) + return capVers +} + +// TailscaleVersion returns the Tailscale version for the given CapabilityVersion. +func TailscaleVersion(ver tailcfg.CapabilityVersion) string { + return capVerToTailscaleVer[ver] +} + +// CapabilityVersion returns the CapabilityVersion for the given Tailscale version. +func CapabilityVersion(ver string) tailcfg.CapabilityVersion { + if !strings.HasPrefix(ver, "v") { + ver = "v" + ver + } + return tailscaleToCapVer[ver] +} + +// TailscaleLatest returns the n latest Tailscale versions. +func TailscaleLatest(n int) []string { + if n <= 0 { + return nil + } + + tsSorted := tailscaleVersSorted() + + if n > len(tsSorted) { + return tsSorted + } + + return tsSorted[len(tsSorted)-n:] +} + +// CapVerLatest returns the n latest CapabilityVersions. +func CapVerLatest(n int) []tailcfg.CapabilityVersion { + if n <= 0 { + return nil + } + + s := capVersSorted() + + if n > len(s) { + return s + } + + return s[len(s)-n:] +} diff --git a/hscontrol/capver/capver_generated.go b/hscontrol/capver/capver_generated.go new file mode 100644 index 0000000000..d5a1f3d987 --- /dev/null +++ b/hscontrol/capver/capver_generated.go @@ -0,0 +1,54 @@ +package capver + +//Generated DO NOT EDIT + +import "tailscale.com/tailcfg" + +var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{ + "v1.44.3": 63, + "v1.56.1": 82, + "v1.58.0": 85, + "v1.58.1": 85, + "v1.58.2": 85, + "v1.60.0": 87, + "v1.60.1": 87, + "v1.62.0": 88, + "v1.62.1": 88, + "v1.64.0": 90, + "v1.64.1": 90, + "v1.64.2": 90, + "v1.66.0": 95, + "v1.66.1": 95, + "v1.66.2": 95, + "v1.66.3": 95, + "v1.66.4": 95, + "v1.68.0": 97, + "v1.68.1": 97, + "v1.68.2": 97, + "v1.70.0": 102, + "v1.72.0": 104, + "v1.72.1": 104, + "v1.74.0": 106, + "v1.74.1": 106, + "v1.76.0": 106, + "v1.76.1": 106, + "v1.76.6": 106, + "v1.78.0": 109, + "v1.78.1": 109, +} + + +var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{ + 63: "v1.44.3", + 82: "v1.56.1", + 85: "v1.58.0", + 87: "v1.60.0", + 88: "v1.62.0", + 90: "v1.64.0", + 95: "v1.66.0", + 97: "v1.68.0", + 102: "v1.70.0", + 104: "v1.72.0", + 106: "v1.74.0", + 109: "v1.78.0", +} diff --git a/hscontrol/capver/capver_test.go b/hscontrol/capver/capver_test.go new file mode 100644 index 0000000000..8d4659e1d3 --- /dev/null +++ b/hscontrol/capver/capver_test.go @@ -0,0 +1,53 @@ +package capver + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "tailscale.com/tailcfg" +) + +func TestTailscaleLatestMajorMinor(t *testing.T) { + tests := []struct { + n int + stripV bool + expected []string + }{ + {3, false, []string{"v1.74", "v1.76", "v1.78"}}, + {2, true, []string{"1.76", "1.78"}}, + {0, false, nil}, + } + + for _, test := range tests { + t.Run("", func(t *testing.T) { + output := TailscaleLatestMajorMinor(test.n, test.stripV) + if diff := cmp.Diff(output, test.expected); diff != "" { + t.Errorf("TailscaleLatestMajorMinor(%d, %v) mismatch (-want +got):\n%s", test.n, test.stripV, diff) + } + }) + } +} + +func TestCapVerMinimumTailscaleVersion(t *testing.T) { + tests := []struct { + input tailcfg.CapabilityVersion + expected string + }{ + {85, "v1.58.0"}, + {90, "v1.64.0"}, + {95, "v1.66.0"}, + {106, "v1.74.0"}, + {109, "v1.78.0"}, + {9001, ""}, // Test case for a version higher than any in the map + {60, ""}, // Test case for a version lower than any in the map + } + + for _, test := range tests { + t.Run("", func(t *testing.T) { + output := TailscaleVersion(test.input) + if output != test.expected { + t.Errorf("CapVerFromTailscaleVersion(%d) = %s; want %s", test.input, output, test.expected) + } + }) + } +} diff --git a/hscontrol/capver/gen/main.go b/hscontrol/capver/gen/main.go new file mode 100644 index 0000000000..3b31686d79 --- /dev/null +++ b/hscontrol/capver/gen/main.go @@ -0,0 +1,157 @@ +package main + +//go:generate go run main.go + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "regexp" + "sort" + "strconv" + "strings" + + xmaps "golang.org/x/exp/maps" + "tailscale.com/tailcfg" +) + +const ( + releasesURL = "https://api.github.com/repos/tailscale/tailscale/releases" + rawFileURL = "https://github.com/tailscale/tailscale/raw/refs/tags/%s/tailcfg/tailcfg.go" + outputFile = "../capver_generated.go" +) + +type Release struct { + Name string `json:"name"` +} + +func getCapabilityVersions() (map[string]tailcfg.CapabilityVersion, error) { + // Fetch the releases + resp, err := http.Get(releasesURL) + if err != nil { + return nil, fmt.Errorf("error fetching releases: %w", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + + var releases []Release + err = json.Unmarshal(body, &releases) + if err != nil { + return nil, fmt.Errorf("error unmarshalling JSON: %w", err) + } + + // Regular expression to find the CurrentCapabilityVersion line + re := regexp.MustCompile(`const CurrentCapabilityVersion CapabilityVersion = (\d+)`) + + versions := make(map[string]tailcfg.CapabilityVersion) + + for _, release := range releases { + version := strings.TrimSpace(release.Name) + if !strings.HasPrefix(version, "v") { + version = "v" + version + } + + // Fetch the raw Go file + rawURL := fmt.Sprintf(rawFileURL, version) + resp, err := http.Get(rawURL) + if err != nil { + fmt.Printf("Error fetching raw file for version %s: %v\n", version, err) + continue + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Printf("Error reading raw file for version %s: %v\n", version, err) + continue + } + + // Find the CurrentCapabilityVersion + matches := re.FindStringSubmatch(string(body)) + if len(matches) > 1 { + capabilityVersionStr := matches[1] + capabilityVersion, _ := strconv.Atoi(capabilityVersionStr) + versions[version] = tailcfg.CapabilityVersion(capabilityVersion) + } else { + fmt.Printf("Version: %s, CurrentCapabilityVersion not found\n", version) + } + } + + return versions, nil +} + +func writeCapabilityVersionsToFile(versions map[string]tailcfg.CapabilityVersion) error { + // Open the output file + file, err := os.Create(outputFile) + if err != nil { + return fmt.Errorf("error creating file: %w", err) + } + defer file.Close() + + // Write the package declaration and variable + file.WriteString("package capver\n\n") + file.WriteString("//Generated DO NOT EDIT\n\n") + file.WriteString(`import "tailscale.com/tailcfg"`) + file.WriteString("\n\n") + file.WriteString("var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{\n") + + sortedVersions := xmaps.Keys(versions) + sort.Strings(sortedVersions) + for _, version := range sortedVersions { + file.WriteString(fmt.Sprintf("\t\"%s\": %d,\n", version, versions[version])) + } + file.WriteString("}\n") + + file.WriteString("\n\n") + file.WriteString("var capVerToTailscaleVer = map[tailcfg.CapabilityVersion]string{\n") + + capVarToTailscaleVer := make(map[tailcfg.CapabilityVersion]string) + for _, v := range sortedVersions { + cap := versions[v] + log.Printf("cap for v: %d, %s", cap, v) + + // If it is already set, skip and continue, + // we only want the first tailscale vsion per + // capability vsion. + if _, ok := capVarToTailscaleVer[cap]; ok { + log.Printf("Skipping %d, %s", cap, v) + continue + } + log.Printf("Storing %d, %s", cap, v) + capVarToTailscaleVer[cap] = v + } + + capsSorted := xmaps.Keys(capVarToTailscaleVer) + sort.Slice(capsSorted, func(i, j int) bool { + return capsSorted[i] < capsSorted[j] + }) + for _, capVer := range capsSorted { + file.WriteString(fmt.Sprintf("\t%d:\t\t\"%s\",\n", capVer, capVarToTailscaleVer[capVer])) + } + file.WriteString("}\n") + + return nil +} + +func main() { + versions, err := getCapabilityVersions() + if err != nil { + fmt.Println("Error:", err) + return + } + + err = writeCapabilityVersionsToFile(versions) + if err != nil { + fmt.Println("Error writing to file:", err) + return + } + + fmt.Println("Capability versions written to", outputFile) +} From 95ef6e734c24a28d63532cd69503c8b92c3b9df3 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 00:11:43 +0100 Subject: [PATCH 2/6] Log the minimum version as client version, not only capver Signed-off-by: Kristoffer Dalby --- hscontrol/app.go | 6 ++++++ hscontrol/noise.go | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/hscontrol/app.go b/hscontrol/app.go index 263342d769..36f7df5d0c 100644 --- a/hscontrol/app.go +++ b/hscontrol/app.go @@ -24,6 +24,7 @@ import ( grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/juanfont/headscale" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/juanfont/headscale/hscontrol/capver" "github.com/juanfont/headscale/hscontrol/db" "github.com/juanfont/headscale/hscontrol/derp" derpServer "github.com/juanfont/headscale/hscontrol/derp/server" @@ -560,6 +561,11 @@ func (h *Headscale) Serve() error { spew.Dump(h.cfg) } + log.Info(). + Caller(). + Str("minimum_version", capver.TailscaleVersion(MinimumCapVersion)). + Msg("Clients with a lower minimum version will be rejected") + // Fetch an initial DERP Map before we start serving h.DERPMap = derp.GetDERPMap(h.cfg.DERP) h.mapper = mapper.NewMapper(h.db, h.cfg, h.DERPMap, h.nodeNotifier, h.polMan) diff --git a/hscontrol/noise.go b/hscontrol/noise.go index b9107f1f53..c1da8eac1a 100644 --- a/hscontrol/noise.go +++ b/hscontrol/noise.go @@ -8,6 +8,7 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/juanfont/headscale/hscontrol/capver" "github.com/juanfont/headscale/hscontrol/types" "github.com/rs/zerolog/log" "golang.org/x/net/http2" @@ -158,7 +159,14 @@ func isSupportedVersion(version tailcfg.CapabilityVersion) bool { func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVersion) bool { // Reject unsupported versions if !isSupportedVersion(version) { - httpError(writer, nil, "unsupported client version", http.StatusBadRequest) + log.Error(). + Caller(). + Int("minimum_cap_ver", int(MinimumCapVersion)). + Int("client_cap_ver", int(version)). + Str("minimum_version", capver.TailscaleVersion(MinimumCapVersion)). + Str("client_version", capver.TailscaleVersion(version)). + Msg("unsupported client connected") + http.Error(writer, "unsupported client version", http.StatusBadRequest) return true } From 60d6900847f899c4c5db21d60a9d2ee48a34a0cc Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 00:16:39 +0100 Subject: [PATCH 3/6] remove old versions Signed-off-by: Kristoffer Dalby --- integration/scenario.go | 47 ----------------------------------------- 1 file changed, 47 deletions(-) diff --git a/integration/scenario.go b/integration/scenario.go index e45446a719..6324dcf74d 100644 --- a/integration/scenario.go +++ b/integration/scenario.go @@ -51,53 +51,6 @@ var ( errNoUserAvailable = errors.New("no user available") errNoClientFound = errors.New("client not found") - // Tailscale started adding TS2021 support in CapabilityVersion>=28 (v1.24.0), but - // proper support in Headscale was only added for CapabilityVersion>=39 clients (v1.30.0). - tailscaleVersions2021 = map[string]bool{ - "head": true, - "unstable": true, - "1.74": true, // CapVer: 106 - "1.72": true, // CapVer: 104 - "1.70": true, // CapVer: 102 - "1.68": true, // CapVer: 97 - "1.66": true, // CapVer: 95 - "1.64": true, // CapVer: 90 - "1.62": true, // CapVer: 88 - "1.60": true, // CapVer: 87 - "1.58": true, // CapVer: 85 - "1.56": true, // Oldest supported version, CapVer: 82 - "1.54": false, // CapVer: 79 - "1.52": false, // CapVer: 79 - "1.50": false, // CapVer: 74 - "1.48": false, // CapVer: 68 - "1.46": false, // CapVer: 65 - "1.44": false, // CapVer: 63 - "1.42": false, // CapVer: 61 - "1.40": false, // CapVer: 61 - "1.38": false, // CapVer: 58 - "1.36": false, // CapVer: 56 - "1.34": false, // CapVer: 51 - "1.32": false, // CapVer: 46 - "1.30": false, - } - - tailscaleVersions2019 = map[string]bool{ - "1.28": false, - "1.26": false, - "1.24": false, // Tailscale SSH - "1.22": false, - "1.20": false, - "1.18": false, - } - - // tailscaleVersionsUnavailable = []string{ - // // These versions seem to fail when fetching from apt. - // "1.14.6", - // "1.12.4", - // "1.10.2", - // "1.8.7", - // }. - // AllVersions represents a list of Tailscale versions the suite // uses to test compatibility with the ControlServer. // From fbb48c3c908e0da4bda9663afccc8c893bcf7aff Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 10:28:01 +0100 Subject: [PATCH 4/6] use capver for integration tests Signed-off-by: Kristoffer Dalby --- hscontrol/capver/capver.go | 26 ++++++++++++++++++++++++++ integration/scenario.go | 6 ++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/hscontrol/capver/capver.go b/hscontrol/capver/capver.go index f2af1f9f15..8dc7a437f5 100644 --- a/hscontrol/capver/capver.go +++ b/hscontrol/capver/capver.go @@ -6,6 +6,7 @@ import ( xmaps "golang.org/x/exp/maps" "tailscale.com/tailcfg" + "tailscale.com/util/set" ) func tailscaleVersSorted() []string { @@ -50,6 +51,31 @@ func TailscaleLatest(n int) []string { return tsSorted[len(tsSorted)-n:] } +// TailscaleLatestMajorMinor returns the n latest Tailscale versions (e.g. 1.80). +func TailscaleLatestMajorMinor(n int, stripV bool) []string { + if n <= 0 { + return nil + } + + majors := set.Set[string]{} + for _, vers := range tailscaleVersSorted() { + if stripV { + vers = strings.TrimPrefix(vers, "v") + } + v := strings.Split(vers, ".") + majors.Add(v[0] + "." + v[1]) + } + + majorSl := majors.Slice() + sort.Strings(majorSl) + + if n > len(majorSl) { + return majorSl + } + + return majorSl[len(majorSl)-n:] +} + // CapVerLatest returns the n latest CapabilityVersions. func CapVerLatest(n int) []tailcfg.CapabilityVersion { if n <= 0 { diff --git a/integration/scenario.go b/integration/scenario.go index 6324dcf74d..93d1f2affd 100644 --- a/integration/scenario.go +++ b/integration/scenario.go @@ -12,6 +12,7 @@ import ( "time" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/juanfont/headscale/hscontrol/capver" "github.com/juanfont/headscale/hscontrol/util" "github.com/juanfont/headscale/integration/dockertestutil" "github.com/juanfont/headscale/integration/dsic" @@ -60,10 +61,7 @@ var ( // // The rest of the version represents Tailscale versions that can be // found in Tailscale's apt repository. - AllVersions = append( - enabledVersions(tailscaleVersions2021), - enabledVersions(tailscaleVersions2019)..., - ) + AllVersions = append([]string{"head", "unstable"}, capver.TailscaleLatestMajorMinor(10, true)...) // MustTestVersions is the minimum set of versions we should test. // At the moment, this is arbitrarily chosen as: From 655ba667dfbf550fe1bb5f3a30a07223c38a05f4 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 15:04:20 +0100 Subject: [PATCH 5/6] changelog Signed-off-by: Kristoffer Dalby --- CHANGELOG.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4306373b7a..5a56a1361e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ - `oidc.map_legacy_users` is now `false` by default [#2350](https://github.com/juanfont/headscale/pull/2350) +- Print Tailscale version instead of capability versions for outdated nodes + [#2391](https://github.com/juanfont/headscale/pull/2391) ## 0.24.2 (2025-01-30) @@ -24,8 +26,8 @@ [#2367](https://github.com/juanfont/headscale/pull/2367) - Relax username validation to allow emails [#2364](https://github.com/juanfont/headscale/pull/2364) -- Remove invalid routes and add stronger constraints for routes to avoid API panic - [#2371](https://github.com/juanfont/headscale/pull/2371) +- Remove invalid routes and add stronger constraints for routes to avoid API + panic [#2371](https://github.com/juanfont/headscale/pull/2371) - Fix panic when `derp.update_frequency` is 0 [#2368](https://github.com/juanfont/headscale/pull/2368) @@ -60,8 +62,7 @@ and have it populate to Headscale automatically the next time they log in. However, this may affect the way you reference users in policies. Headscale v0.23.0 and earlier never recorded the `iss` and `sub` fields, so all -legacy (existing) OIDC accounts _need to be migrated_ to be properly -secured. +legacy (existing) OIDC accounts _need to be migrated_ to be properly secured. #### What do I need to do to migrate? @@ -73,8 +74,8 @@ The migration will mostly be done automatically, with one exception. If your OIDC does not provide an `email_verified` claim, Headscale will ignore the `email`. This means that either the administrator will have to mark the user emails as verified, or ensure the users verify their emails. Any unverified -emails will be ignored, meaning that the users will get new accounts instead -of being migrated. +emails will be ignored, meaning that the users will get new accounts instead of +being migrated. After this exception is ensured, make all users log into Headscale with their account, and Headscale will automatically update the account record. This will @@ -175,7 +176,8 @@ This will also affect the way you - User gRPC/API [#2261](https://github.com/juanfont/headscale/pull/2261): - If you depend on a Headscale Web UI, you should wait with this update until the UI have been updated to match the new API. - - `GET /api/v1/user/{name}` and `GetUser` have been removed in favour of `ListUsers` with an ID parameter + - `GET /api/v1/user/{name}` and `GetUser` have been removed in favour of + `ListUsers` with an ID parameter - `RenameUser` and `DeleteUser` now require an ID instead of a name. ### Changes @@ -197,9 +199,12 @@ This will also affect the way you - CLI for managing users now accepts `--identifier` in addition to `--name`, usage of `--identifier` is recommended [#2261](https://github.com/juanfont/headscale/pull/2261) -- Add `dns.extra_records_path` configuration option [#2262](https://github.com/juanfont/headscale/issues/2262) -- Support client verify for DERP [#2046](https://github.com/juanfont/headscale/pull/2046) -- Add PKCE Verifier for OIDC [#2314](https://github.com/juanfont/headscale/pull/2314) +- Add `dns.extra_records_path` configuration option + [#2262](https://github.com/juanfont/headscale/issues/2262) +- Support client verify for DERP + [#2046](https://github.com/juanfont/headscale/pull/2046) +- Add PKCE Verifier for OIDC + [#2314](https://github.com/juanfont/headscale/pull/2314) ## 0.23.0 (2024-09-18) @@ -730,8 +735,8 @@ behaviour. - All machines can communicate with all machines by default - Tags should now work correctly and adding a host to Headscale should now reload the rules. - - The documentation have a [fictional example](./docs/ref/acls.md) that should cover - some use cases of the ACLs features + - The documentation have a [fictional example](./docs/ref/acls.md) that should + cover some use cases of the ACLs features ### Features @@ -749,7 +754,8 @@ behaviour. - Add IPv6 support to the prefix assigned to namespaces - Add API Key support - - Enable remote control of `headscale` via CLI [docs](./docs/ref/remote-cli.md) + - Enable remote control of `headscale` via CLI + [docs](./docs/ref/remote-cli.md) - Enable HTTP API (beta, subject to change) - OpenID Connect users will be mapped per namespaces - Each user will get its own namespace, created if it does not exist From 3656a8b69a1a8cafd91162f0b65b3c32981ba428 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 30 Jan 2025 15:17:46 +0100 Subject: [PATCH 6/6] patch through m and n key Signed-off-by: Kristoffer Dalby --- hscontrol/noise.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hscontrol/noise.go b/hscontrol/noise.go index c1da8eac1a..b4e90f31d0 100644 --- a/hscontrol/noise.go +++ b/hscontrol/noise.go @@ -156,7 +156,7 @@ func isSupportedVersion(version tailcfg.CapabilityVersion) bool { return version >= MinimumCapVersion } -func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVersion) bool { +func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVersion, mkey key.MachinePublic, nkey key.NodePublic) bool { // Reject unsupported versions if !isSupportedVersion(version) { log.Error(). @@ -165,6 +165,8 @@ func rejectUnsupported(writer http.ResponseWriter, version tailcfg.CapabilityVer Int("client_cap_ver", int(version)). Str("minimum_version", capver.TailscaleVersion(MinimumCapVersion)). Str("client_version", capver.TailscaleVersion(version)). + Str("node_key", nkey.ShortString()). + Str("machine_key", mkey.ShortString()). Msg("unsupported client connected") http.Error(writer, "unsupported client version", http.StatusBadRequest) @@ -196,7 +198,7 @@ func (ns *noiseServer) NoisePollNetMapHandler( } // Reject unsupported versions - if rejectUnsupported(writer, mapRequest.Version) { + if rejectUnsupported(writer, mapRequest.Version, ns.machineKey, mapRequest.NodeKey) { return } @@ -241,7 +243,7 @@ func (ns *noiseServer) NoiseRegistrationHandler( } // Reject unsupported versions - if rejectUnsupported(writer, registerRequest.Version) { + if rejectUnsupported(writer, registerRequest.Version, ns.machineKey, registerRequest.NodeKey) { return }