From 8f314797ce8d558e22ab89d061838f40360a2df7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sat, 20 Jun 2026 10:28:03 +0000 Subject: [PATCH] all: fix full-tree golangci-lint findings The new full-tree golangci-lint check reports issues the --new-from-rev diff lint hid: nine wsl_v5 whitespace gaps, a prealloc, and an unparam (setCSRFCookie never errored, so drop the return and update callers). gocyclo on the central UpdateNodeFromMapRequest and an SA1019 NetMap deprecation in an integration helper are suppressed with reasons. --- cmd/headscale/cli/nodes.go | 1 + hscontrol/derp/derp.go | 1 + hscontrol/derp/server/derp_server.go | 1 + hscontrol/mapper/node_conn.go | 1 + hscontrol/oidc.go | 16 ++++------------ hscontrol/oidc_test.go | 3 +-- hscontrol/servertest/client.go | 1 + hscontrol/state/state.go | 3 ++- hscontrol/types/common.go | 1 + hscontrol/util/dns.go | 2 +- integration/dockertestutil/network.go | 1 + integration/hsic/hsic.go | 1 + integration/tsic/tsic.go | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 671a68cc..9dc798a3 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -146,6 +146,7 @@ var listNodeRoutesCmd = &cobra.Command{ } nodes := resp.JSON200.Nodes + if identifier != 0 { idStr := strconv.FormatUint(identifier, util.Base10) for _, node := range nodes { diff --git a/hscontrol/derp/derp.go b/hscontrol/derp/derp.go index 909c4cb5..beeb66ad 100644 --- a/hscontrol/derp/derp.go +++ b/hscontrol/derp/derp.go @@ -28,6 +28,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { } var derpMap tailcfg.DERPMap + err = yaml.Unmarshal(b, &derpMap) return &derpMap, err diff --git a/hscontrol/derp/server/derp_server.go b/hscontrol/derp/server/derp_server.go index 0cb8339b..e164c608 100644 --- a/hscontrol/derp/server/derp_server.go +++ b/hscontrol/derp/server/derp_server.go @@ -80,6 +80,7 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) { host, portStr, err := net.SplitHostPort(serverURL.Host) var port int + if err != nil { host = serverURL.Host if serverURL.Scheme == "https" { diff --git a/hscontrol/mapper/node_conn.go b/hscontrol/mapper/node_conn.go index 27a43a13..97d024a8 100644 --- a/hscontrol/mapper/node_conn.go +++ b/hscontrol/mapper/node_conn.go @@ -309,6 +309,7 @@ func (mc *multiChannelNodeConn) send(data *tailcfg.MapResponse) error { snapshot = append(snapshot, conn) } } + mc.mutex.RUnlock() if len(snapshot) == 0 { diff --git a/hscontrol/oidc.go b/hscontrol/oidc.go index a4fb06f1..fa2c3809 100644 --- a/hscontrol/oidc.go +++ b/hscontrol/oidc.go @@ -156,18 +156,10 @@ func (a *AuthProviderOIDC) authHandler( } // Set the state and nonce cookies to protect against CSRF attacks - state, err := setCSRFCookie(writer, req, "state") - if err != nil { - httpUserError(writer, err) - return - } + state := setCSRFCookie(writer, req, "state") // Set the state and nonce cookies to protect against CSRF attacks - nonce, err := setCSRFCookie(writer, req, "nonce") - if err != nil { - httpUserError(writer, err) - return - } + nonce := setCSRFCookie(writer, req, "nonce") registrationInfo := AuthInfo{ AuthID: authID, @@ -928,7 +920,7 @@ func getCookieName(baseName, value string) string { return fmt.Sprintf("%s_%s", baseName, value[:n]) } -func setCSRFCookie(w http.ResponseWriter, r *http.Request, name string) (string, error) { +func setCSRFCookie(w http.ResponseWriter, r *http.Request, name string) string { val := rands.HexString(64) //nolint:gosec // G124: Secure set conditionally via r.TLS; HttpOnly + SameSite set below @@ -948,5 +940,5 @@ func setCSRFCookie(w http.ResponseWriter, r *http.Request, name string) (string, } http.SetCookie(w, c) - return val, nil + return val } diff --git a/hscontrol/oidc_test.go b/hscontrol/oidc_test.go index 0472f01c..2c581407 100644 --- a/hscontrol/oidc_test.go +++ b/hscontrol/oidc_test.go @@ -186,8 +186,7 @@ func TestSetCSRFCookieSameSite(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/auth/abcdef0123456789", nil) - _, err := setCSRFCookie(w, r, "state") - require.NoError(t, err) + setCSRFCookie(w, r, "state") cookies := w.Result().Cookies() require.Len(t, cookies, 1) diff --git a/hscontrol/servertest/client.go b/hscontrol/servertest/client.go index 54d87004..67232dd3 100644 --- a/hscontrol/servertest/client.go +++ b/hscontrol/servertest/client.go @@ -204,6 +204,7 @@ func (c *TestClient) startPollLoop() { go func() { defer close(c.pollDone) + _ = c.direct.PollNetMap(c.pollCtx, c) }() } diff --git a/hscontrol/state/state.go b/hscontrol/state/state.go index 1069d8de..ab4fe997 100644 --- a/hscontrol/state/state.go +++ b/hscontrol/state/state.go @@ -2432,6 +2432,7 @@ func (s *State) HandleNodeFromPreAuthKey( node.User = nil node.Expiry = nil } + node.AuthKey = pak node.AuthKeyID = &pak.ID // Do NOT reset IsOnline here. Online status is managed exclusively by @@ -2793,7 +2794,7 @@ func isAutoDerivedGivenName(given, hostname string) bool { // - node.PeerChangeFromMapRequest // - node.ApplyPeerChange // - logTracePeerChange in poll.go. -func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest) (change.Change, error) { +func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest) (change.Change, error) { //nolint:gocyclo // central map-request reconciliation; the sequential branch flow reads clearer as one function than split across helpers log.Trace(). Caller(). Uint64(zf.NodeID, id.Uint64()). diff --git a/hscontrol/types/common.go b/hscontrol/types/common.go index 86e42f28..e96aef9b 100644 --- a/hscontrol/types/common.go +++ b/hscontrol/types/common.go @@ -237,6 +237,7 @@ func (rn *AuthRequest) FinishAuth(verdict AuthVerdict) { } rn.finished <- verdict + close(rn.finished) } diff --git a/hscontrol/util/dns.go b/hscontrol/util/dns.go index c705ee88..025cb50d 100644 --- a/hscontrol/util/dns.go +++ b/hscontrol/util/dns.go @@ -164,7 +164,7 @@ func GenerateIPv6DNSRootDomain(ipPrefix netip.Prefix) []dnsname.FQDN { // but the inputs are not so long as to cause problems, // and from what I can see, the generateMagicDNSRootDomains // function is called only once over the lifetime of a server process. - prefixConstantParts := []string{} + prefixConstantParts := make([]string, 0, maskBits/nibbleLen) for i := range maskBits / nibbleLen { prefixConstantParts = append(prefixConstantParts, string(nibbleStr[i])) } diff --git a/integration/dockertestutil/network.go b/integration/dockertestutil/network.go index 83fa1619..df7f55c1 100644 --- a/integration/dockertestutil/network.go +++ b/integration/dockertestutil/network.go @@ -231,6 +231,7 @@ func waitNetworkContainer( } found := false + for _, c := range net.Containers { if (c.Name == testContainer || c.Name == "/"+testContainer) && match(c) { found = true diff --git a/integration/hsic/hsic.go b/integration/hsic/hsic.go index add0bc48..ed580992 100644 --- a/integration/hsic/hsic.go +++ b/integration/hsic/hsic.go @@ -1334,6 +1334,7 @@ func (t *HeadscaleInContainer) NodesByUser() (map[string][]*clientv1.Node, error } userMap := make(map[string][]*clientv1.Node) + for _, node := range nodes { name := node.User.Name userMap[name] = append(userMap[name], node) diff --git a/integration/tsic/tsic.go b/integration/tsic/tsic.go index 553cc0a8..901a263e 100644 --- a/integration/tsic/tsic.go +++ b/integration/tsic/tsic.go @@ -1111,7 +1111,7 @@ func (t *TailscaleInContainer) watchIPN(ctx context.Context) (*ipn.Notify, error resultChan <- result{nil, fmt.Errorf("parse notify: %w", err)} } - if notify.NetMap != nil { + if notify.NetMap != nil { //nolint:staticcheck // SA1019: NetMap is still populated on the platforms our integration containers run; migrating to InitialStatus/PeerChanges is a separate change resultChan <- result{¬ify, nil} } }