mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-19 06:05:10 -04:00
ipn/ipnlocal, all: split LocalBackend.NetMap into NetMapNoPeers / NetMapWithPeers
Add two narrower accessors alongside the existing
[LocalBackend.NetMap], with docs that distinguish their semantics:
- NetMapNoPeers: cheap (returns the cached *netmap.NetworkMap with
a possibly-stale Peers slice). For callers that only read non-Peers
fields like SelfNode, DNS, PacketFilter, capabilities.
- NetMapWithPeers: documented as returning an up-to-date Peers slice.
For callers that genuinely need to iterate Peers or call
PeerByXxx.
Mark the existing NetMap deprecated and point readers at the two new
accessors. NetMap, NetMapNoPeers, and NetMapWithPeers all currently
return the same value (b.currentNode().NetMap()): this commit is a
no-op behaviorally, just a renaming and migration of in-tree callers.
A subsequent change in the same series will switch
NetMapWithPeers to actually rebuild the Peers slice from the live
per-node-backend peers map (O(N) per call), at which point the
distinction between the two new accessors becomes load-bearing.
Migrate in-tree callers to the appropriate accessor based on what
fields they read:
- NetMapNoPeers (most common): localapi handlers, peerapi accept,
GetCertPEMWithValidity, web client noise request, doctor DNS
resolver check, tsnet CertDomains/TailscaleIPs, ssh/tailssh
SSH-policy/cap reads, several LocalBackend internals
(isLocalIP, allowExitNodeDNSProxyToServeName, pauseForNetwork
nil-check, serve config).
- NetMapWithPeers: writeNetmapToDiskLocked (persist full netmap to
disk for fast restart), PeerByTailscaleIP lookup.
Tests still call the legacy NetMap; they'll see the deprecation
warning but otherwise behave identically.
Also add two pieces of plumbing the next change in this series will
need, but which are already useful on their own:
- [client/local.GetDebugResultJSON]: a generic [Client.DebugResultJSON]
that decodes directly into a target type T, avoiding the
marshal/unmarshal roundtrip callers otherwise need.
- localapi "current-netmap" debug action: returns the current
netmap (with peers) as JSON. Documented as debug-only — the
netmap.NetworkMap shape is internal and may change without notice.
This commit is part of a series breaking up a larger change for
review; on its own it is a no-op refactor.
Updates #12542
Change-Id: Idbb30707414f8da3149c44ca0273262708375b02
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
92179b1fc7
commit
159cf8707a
@@ -607,6 +607,24 @@ func (lc *Client) DebugResultJSON(ctx context.Context, action string) (any, erro
|
|||||||
return x, nil
|
return x, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDebugResultJSON invokes a debug action and decodes the JSON response
|
||||||
|
// into a value of type T. It avoids the marshal/unmarshal roundtrip that
|
||||||
|
// callers of [Client.DebugResultJSON] otherwise need to do to get a typed
|
||||||
|
// value.
|
||||||
|
//
|
||||||
|
// These are development tools and subject to change or removal over time.
|
||||||
|
func GetDebugResultJSON[T any](ctx context.Context, lc *Client, action string) (T, error) {
|
||||||
|
var v T
|
||||||
|
body, err := lc.send(ctx, "POST", "/localapi/v0/debug?action="+url.QueryEscape(action), 200, nil)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("error %w: %s", err, body)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(body, &v); err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
// QueryOptionalFeatures queries the optional features supported by the Tailscale daemon.
|
// QueryOptionalFeatures queries the optional features supported by the Tailscale daemon.
|
||||||
func (lc *Client) QueryOptionalFeatures(ctx context.Context) (*apitype.OptionalFeatures, error) {
|
func (lc *Client) QueryOptionalFeatures(ctx context.Context) (*apitype.OptionalFeatures, error) {
|
||||||
body, err := lc.send(ctx, "POST", "/localapi/v0/debug-optional-features", 200, nil)
|
body, err := lc.send(ctx, "POST", "/localapi/v0/debug-optional-features", 200, nil)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func visitDoctor(ctx context.Context, b *ipnlocal.LocalBackend, logf logger.Logf
|
|||||||
// IPs; this can interfere with our ability to connect to the Tailscale
|
// IPs; this can interfere with our ability to connect to the Tailscale
|
||||||
// controlplane.
|
// controlplane.
|
||||||
checks = append(checks, doctor.CheckFunc("dns-resolvers", func(_ context.Context, logf logger.Logf) error {
|
checks = append(checks, doctor.CheckFunc("dns-resolvers", func(_ context.Context, logf logger.Logf) error {
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -909,7 +909,7 @@ func (b *LocalBackend) resolveCertDomain(domain string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the netmap once to get both CertDomains and capabilities atomically.
|
// Read the netmap once to get both CertDomains and capabilities atomically.
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return "", errors.New("no netmap available")
|
return "", errors.New("no netmap available")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -701,7 +701,9 @@ func (b *LocalBackend) onHomeDERPUpdateLocked(du magicsock.HomeDERPChanged) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := b.writeNetmapToDiskLocked(b.NetMap()); err != nil {
|
// Persist the full netmap (including up-to-date Peers) to disk for
|
||||||
|
// fast restart.
|
||||||
|
if err := b.writeNetmapToDiskLocked(b.NetMapWithPeers()); err != nil {
|
||||||
b.logf("write netmap to cache: %v", err)
|
b.logf("write netmap to cache: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1023,7 +1025,7 @@ func (b *LocalBackend) pauseOrResumeControlClientLocked() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
networkUp := b.interfaceState.AnyInterfaceUp()
|
networkUp := b.interfaceState.AnyInterfaceUp()
|
||||||
pauseForNetwork := (b.state == ipn.Stopped && b.NetMap() != nil) || (!networkUp && !testenv.InTest() && !envknob.AssumeNetworkUp())
|
pauseForNetwork := (b.state == ipn.Stopped && b.NetMapNoPeers() != nil) || (!networkUp && !testenv.InTest() && !envknob.AssumeNetworkUp())
|
||||||
|
|
||||||
prefs := b.pm.CurrentPrefs()
|
prefs := b.pm.CurrentPrefs()
|
||||||
pauseForSyncPref := prefs.Valid() && prefs.Sync().EqualBool(false)
|
pauseForSyncPref := prefs.Valid() && prefs.Sync().EqualBool(false)
|
||||||
@@ -4057,7 +4059,8 @@ func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netip.Addr) (peer tai
|
|||||||
var zero tailcfg.NodeView
|
var zero tailcfg.NodeView
|
||||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
nm := b.NetMap()
|
// PeerByTailscaleIP needs an up-to-date Peers slice.
|
||||||
|
nm := b.NetMapWithPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return zero, "", errors.New("no netmap")
|
return zero, "", errors.New("no netmap")
|
||||||
}
|
}
|
||||||
@@ -4967,7 +4970,7 @@ func (b *LocalBackend) handlePeerAPIConn(remote, local netip.AddrPort, c net.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *LocalBackend) isLocalIP(ip netip.Addr) bool {
|
func (b *LocalBackend) isLocalIP(ip netip.Addr) bool {
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
return nm != nil && views.SliceContains(nm.GetAddresses(), netip.PrefixFrom(ip, ip.BitLen()))
|
return nm != nil && views.SliceContains(nm.GetAddresses(), netip.PrefixFrom(ip, ip.BitLen()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5119,10 +5122,46 @@ func extractPeerAPIPorts(services []tailcfg.Service) portPair {
|
|||||||
|
|
||||||
// NetMap returns the latest cached network map received from
|
// NetMap returns the latest cached network map received from
|
||||||
// controlclient, or nil if no network map was received yet.
|
// controlclient, or nil if no network map was received yet.
|
||||||
|
//
|
||||||
|
// Deprecated: callers should declare their needs explicitly by calling
|
||||||
|
// either [LocalBackend.NetMapNoPeers] (cheap; for code that reads
|
||||||
|
// non-Peers fields like SelfNode, DNS, PacketFilter, capabilities) or
|
||||||
|
// [LocalBackend.NetMapWithPeers] (currently the same; will be made to
|
||||||
|
// return an up-to-date Peers slice in a follow-up change, at the cost of
|
||||||
|
// O(N) work per call). NetMap will eventually be removed.
|
||||||
func (b *LocalBackend) NetMap() *netmap.NetworkMap {
|
func (b *LocalBackend) NetMap() *netmap.NetworkMap {
|
||||||
return b.currentNode().NetMap()
|
return b.currentNode().NetMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetMapNoPeers returns the latest cached network map received from
|
||||||
|
// controlclient WITHOUT a freshly-built Peers slice.
|
||||||
|
//
|
||||||
|
// On a tailnet with frequent peer churn the cached netmap's Peers slice
|
||||||
|
// can be stale relative to the live per-node-backend peers map; non-Peers
|
||||||
|
// fields (SelfNode, DNS, PacketFilter, capabilities, ...) are always
|
||||||
|
// current. Use this for any caller that does not need to iterate Peers,
|
||||||
|
// since it's O(1) regardless of tailnet size.
|
||||||
|
//
|
||||||
|
// Returns nil if no network map has been received yet.
|
||||||
|
func (b *LocalBackend) NetMapNoPeers() *netmap.NetworkMap {
|
||||||
|
return b.currentNode().NetMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetMapWithPeers returns the latest network map with the Peers slice
|
||||||
|
// populated.
|
||||||
|
//
|
||||||
|
// Currently this is the same as [LocalBackend.NetMapNoPeers]: the cached
|
||||||
|
// netmap's Peers slice may be stale relative to the live per-node-backend
|
||||||
|
// peers map. A follow-up change will switch this method to return a
|
||||||
|
// freshly-built netmap with up-to-date Peers, at O(N) cost per call.
|
||||||
|
// Callers that genuinely need the up-to-date peer set should use this
|
||||||
|
// method (and document why) so the upcoming change reaches them.
|
||||||
|
//
|
||||||
|
// Returns nil if no network map has been received yet.
|
||||||
|
func (b *LocalBackend) NetMapWithPeers() *netmap.NetworkMap {
|
||||||
|
return b.currentNode().NetMap()
|
||||||
|
}
|
||||||
|
|
||||||
// lookupPeerByIP returns the node public key for the peer that owns the
|
// lookupPeerByIP returns the node public key for the peer that owns the
|
||||||
// given IP address. It is the fast path for [Engine.SetPeerByIPPacketFunc],
|
// given IP address. It is the fast path for [Engine.SetPeerByIPPacketFunc],
|
||||||
// handling exact-IP matches against node addresses; subnet routes and exit
|
// handling exact-IP matches against node addresses; subnet routes and exit
|
||||||
@@ -6978,7 +7017,7 @@ func (b *LocalBackend) AppConnector() *appc.AppConnector {
|
|||||||
func (b *LocalBackend) allowExitNodeDNSProxyToServeName(name string) bool {
|
func (b *LocalBackend) allowExitNodeDNSProxyToServeName(name string) bool {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) {
|
|||||||
c.Close()
|
c.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := pln.lb.NetMap()
|
nm := pln.lb.NetMapNoPeers()
|
||||||
if nm == nil || !nm.SelfNode.Valid() {
|
if nm == nil || !nm.SelfNode.Valid() {
|
||||||
logf("peerapi: no netmap")
|
logf("peerapi: no netmap")
|
||||||
c.Close()
|
c.Close()
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
b.logf("netMap is nil")
|
b.logf("netMap is nil")
|
||||||
return
|
return
|
||||||
@@ -333,7 +333,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
|
|||||||
return errors.New("can't reconfigure tailscaled when using a config file; config file is locked")
|
return errors.New("can't reconfigure tailscaled when using a config file; config file is locked")
|
||||||
}
|
}
|
||||||
|
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return errors.New("netMap is nil")
|
return errors.New("netMap is nil")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ func (b *LocalBackend) waitWebClientAuthURL(ctx context.Context, id string, src
|
|||||||
// one to be completed, based on the presence or absence of the
|
// one to be completed, based on the presence or absence of the
|
||||||
// provided id value.
|
// provided id value.
|
||||||
func (b *LocalBackend) doWebClientNoiseRequest(ctx context.Context, id string, src tailcfg.NodeID) (*tailcfg.WebClientAuthResponse, error) {
|
func (b *LocalBackend) doWebClientNoiseRequest(ctx context.Context, id string, src tailcfg.NodeID) (*tailcfg.WebClientAuthResponse, error) {
|
||||||
nm := b.NetMap()
|
nm := b.NetMapNoPeers()
|
||||||
if nm == nil || !nm.SelfNode.Valid() {
|
if nm == nil || !nm.SelfNode.Valid() {
|
||||||
return nil, errors.New("[unexpected] no self node")
|
return nil, errors.New("[unexpected] no self node")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"cmp"
|
"cmp"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@@ -249,6 +250,22 @@ func (h *Handler) serveDebug(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
case "clear-netmap-cache":
|
case "clear-netmap-cache":
|
||||||
h.b.ClearNetmapCache(r.Context())
|
h.b.ClearNetmapCache(r.Context())
|
||||||
|
case "current-netmap":
|
||||||
|
// Return the current netmap (with peers populated) as JSON. This
|
||||||
|
// is a debug-only path: the netmap.NetworkMap shape is an
|
||||||
|
// internal type and may change without notice. Production
|
||||||
|
// callers should fetch the narrower bits they need via their
|
||||||
|
// own LocalAPI methods instead.
|
||||||
|
nm := h.b.NetMapWithPeers()
|
||||||
|
if nm == nil {
|
||||||
|
err = errors.New("no netmap")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
err = json.NewEncoder(w).Encode(nm)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
case "":
|
case "":
|
||||||
err = fmt.Errorf("missing parameter 'action'")
|
err = fmt.Errorf("missing parameter 'action'")
|
||||||
default:
|
default:
|
||||||
@@ -284,7 +301,7 @@ func (h *Handler) serveDebugPacketFilterRules(w http.ResponseWriter, r *http.Req
|
|||||||
http.Error(w, "debug access denied", http.StatusForbidden)
|
http.Error(w, "debug access denied", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := h.b.NetMap()
|
nm := h.b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
http.Error(w, "no netmap", http.StatusNotFound)
|
http.Error(w, "no netmap", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
@@ -301,7 +318,7 @@ func (h *Handler) serveDebugPacketFilterMatches(w http.ResponseWriter, r *http.R
|
|||||||
http.Error(w, "debug access denied", http.StatusForbidden)
|
http.Error(w, "debug access denied", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := h.b.NetMap()
|
nm := h.b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
http.Error(w, "no netmap", http.StatusNotFound)
|
http.Error(w, "no netmap", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ func (h *Handler) serveIDToken(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "id-token access denied", http.StatusForbidden)
|
http.Error(w, "id-token access denied", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := h.b.NetMap()
|
nm := h.b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
@@ -417,7 +417,7 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Information about the current node from the netmap
|
// Information about the current node from the netmap
|
||||||
if nm := h.b.NetMap(); nm != nil {
|
if nm := h.b.NetMapNoPeers(); nm != nil {
|
||||||
if self := nm.SelfNode; self.Valid() {
|
if self := nm.SelfNode; self.Valid() {
|
||||||
h.logf("user bugreport node info: nodeid=%q stableid=%q expiry=%q", self.ID(), self.StableID(), self.KeyExpiry().Format(time.RFC3339))
|
h.logf("user bugreport node info: nodeid=%q stableid=%q expiry=%q", self.ID(), self.StableID(), self.KeyExpiry().Format(time.RFC3339))
|
||||||
}
|
}
|
||||||
@@ -1476,7 +1476,7 @@ func (h *Handler) serveQueryFeature(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "missing feature", http.StatusInternalServerError)
|
http.Error(w, "missing feature", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := h.b.NetMap()
|
nm := h.b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
@@ -1731,7 +1731,7 @@ func (h *Handler) serveServices(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "only GET allowed", http.StatusMethodNotAllowed)
|
http.Error(w, "only GET allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nm := h.b.NetMap()
|
nm := h.b.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
http.Error(w, "no netmap", http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
incubatorArgs = append(incubatorArgs, "--is-selinux-enforcing")
|
incubatorArgs = append(incubatorArgs, "--is-selinux-enforcing")
|
||||||
}
|
}
|
||||||
|
|
||||||
nm := ss.conn.srv.lb.NetMap()
|
nm := ss.conn.srv.lb.NetMapNoPeers()
|
||||||
forceV1Behavior := nm.HasCap(tailcfg.NodeAttrSSHBehaviorV1) && !nm.HasCap(tailcfg.NodeAttrSSHBehaviorV2)
|
forceV1Behavior := nm.HasCap(tailcfg.NodeAttrSSHBehaviorV1) && !nm.HasCap(tailcfg.NodeAttrSSHBehaviorV2)
|
||||||
if forceV1Behavior {
|
if forceV1Behavior {
|
||||||
incubatorArgs = append(incubatorArgs, "--force-v1-behavior")
|
incubatorArgs = append(incubatorArgs, "--force-v1-behavior")
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err
|
|||||||
"--tty-name=", // updated in-place by startWithPTY
|
"--tty-name=", // updated in-place by startWithPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
nm := ss.conn.srv.lb.NetMap()
|
nm := ss.conn.srv.lb.NetMapNoPeers()
|
||||||
forceV1Behavior := nm.HasCap(tailcfg.NodeAttrSSHBehaviorV1) && !nm.HasCap(tailcfg.NodeAttrSSHBehaviorV2)
|
forceV1Behavior := nm.HasCap(tailcfg.NodeAttrSSHBehaviorV1) && !nm.HasCap(tailcfg.NodeAttrSSHBehaviorV2)
|
||||||
if forceV1Behavior {
|
if forceV1Behavior {
|
||||||
incubatorArgs = append(incubatorArgs, "--force-v1-behavior")
|
incubatorArgs = append(incubatorArgs, "--force-v1-behavior")
|
||||||
|
|||||||
@@ -76,6 +76,7 @@
|
|||||||
type ipnLocalBackend interface {
|
type ipnLocalBackend interface {
|
||||||
ShouldRunSSH() bool
|
ShouldRunSSH() bool
|
||||||
NetMap() *netmap.NetworkMap
|
NetMap() *netmap.NetworkMap
|
||||||
|
NetMapNoPeers() *netmap.NetworkMap
|
||||||
WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool)
|
WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool)
|
||||||
DoNoiseRequest(req *http.Request) (*http.Response, error)
|
DoNoiseRequest(req *http.Request) (*http.Response, error)
|
||||||
Dialer() *tsdial.Dialer
|
Dialer() *tsdial.Dialer
|
||||||
@@ -598,7 +599,7 @@ func (c *conn) sshPolicy() (_ *tailcfg.SSHPolicy, ok bool) {
|
|||||||
if !lb.ShouldRunSSH() {
|
if !lb.ShouldRunSSH() {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
nm := lb.NetMap()
|
nm := lb.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -717,7 +718,7 @@ func (c *conn) handleSessionPostSSHAuth(s gliderssh.Session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) expandDelegateURLLocked(actionURL string) string {
|
func (c *conn) expandDelegateURLLocked(actionURL string) string {
|
||||||
nm := c.srv.lb.NetMap()
|
nm := c.srv.lb.NetMapNoPeers()
|
||||||
ci := c.info
|
ci := c.info
|
||||||
lu := c.localUser
|
lu := c.localUser
|
||||||
var dstNodeID string
|
var dstNodeID string
|
||||||
|
|||||||
@@ -910,6 +910,8 @@ func (tb *testBackend) NetMap() *netmap.NetworkMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tb *testBackend) NetMapNoPeers() *netmap.NetworkMap { return tb.NetMap() }
|
||||||
|
|
||||||
func (tb *testBackend) WhoIs(_ string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) {
|
func (tb *testBackend) WhoIs(_ string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) {
|
||||||
return (&tailcfg.Node{}).View(), tailcfg.UserProfile{
|
return (&tailcfg.Node{}).View(), tailcfg.UserProfile{
|
||||||
LoginName: tb.localUser + "@example.com",
|
LoginName: tb.localUser + "@example.com",
|
||||||
|
|||||||
@@ -422,6 +422,8 @@ func (ts *localState) NetMap() *netmap.NetworkMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ts *localState) NetMapNoPeers() *netmap.NetworkMap { return ts.NetMap() }
|
||||||
|
|
||||||
func (ts *localState) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) {
|
func (ts *localState) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) {
|
||||||
if proto != "tcp" {
|
if proto != "tcp" {
|
||||||
return tailcfg.NodeView{}, tailcfg.UserProfile{}, false
|
return tailcfg.NodeView{}, tailcfg.UserProfile{}, false
|
||||||
|
|||||||
@@ -668,7 +668,7 @@ func (s *Server) doInit() {
|
|||||||
// Server.
|
// Server.
|
||||||
// If the server is not running, it returns nil.
|
// If the server is not running, it returns nil.
|
||||||
func (s *Server) CertDomains() []string {
|
func (s *Server) CertDomains() []string {
|
||||||
nm := s.lb.NetMap()
|
nm := s.lb.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -679,7 +679,7 @@ func (s *Server) CertDomains() []string {
|
|||||||
// has not yet joined a tailnet or is otherwise unaware of its own IP addresses,
|
// has not yet joined a tailnet or is otherwise unaware of its own IP addresses,
|
||||||
// the returned ip4, ip6 will be !netip.IsValid().
|
// the returned ip4, ip6 will be !netip.IsValid().
|
||||||
func (s *Server) TailscaleIPs() (ip4, ip6 netip.Addr) {
|
func (s *Server) TailscaleIPs() (ip4, ip6 netip.Addr) {
|
||||||
nm := s.lb.NetMap()
|
nm := s.lb.NetMapNoPeers()
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user