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} } }