WIP: rebase fork onto upstream/main (v1.103.0) #15

Closed
codinget wants to merge 670 commits from webnet into save/webnet-2026-07-29
2 changed files with 41 additions and 34 deletions
Showing only changes of commit 65fd320aa6 - Show all commits
+7 -18
View File
@@ -4710,19 +4710,18 @@ func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netip.Addr) (peer tai
var zero tailcfg.NodeView
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
// PeerByTailscaleIP needs an up-to-date Peers slice.
nm := b.NetMapWithPeers()
if nm == nil {
return zero, "", errors.New("no netmap")
cn := b.currentNode()
var ok bool
if nid, addrOK := cn.NodeByAddr(ip); addrOK {
peer, ok = cn.PeerByID(nid)
}
peer, ok := nm.PeerByTailscaleIP(ip)
if !ok {
return zero, "", fmt.Errorf("no peer found with Tailscale IP %v", ip)
}
if peer.Expired() {
return zero, "", errors.New("peer's node key has expired")
}
base := peerAPIBase(nm, peer)
base := peerAPIBase(cn.NetMap(), peer)
if base == "" {
return zero, "", fmt.Errorf("no PeerAPI base found for peer %v (%v)", peer.ID(), ip)
}
@@ -7968,22 +7967,12 @@ func (b *LocalBackend) DebugPeerRelayServers() set.Set[netip.Addr] {
}
// DebugPeerDiscoKeys returns the disco public keys this node has learned for
// each of its peers from the most recent network map. Intended for tests
// each of its current peers. Intended for tests
// (the production [ipnstate.PeerStatus] purposefully does not surface disco
// keys; surfacing them via the [ipnstate.Status] API would also pollute
// every PeerStatus consumer with a non-comparable struct field).
func (b *LocalBackend) DebugPeerDiscoKeys() map[key.NodePublic]key.DiscoPublic {
nm := b.currentNode().NetMap()
if nm == nil {
return nil
}
m := make(map[key.NodePublic]key.DiscoPublic, len(nm.Peers))
for _, p := range nm.Peers {
if dk := p.DiscoKey(); !dk.IsZero() {
m[p.Key()] = dk
}
}
return m
return b.currentNode().peerDiscoKeys()
}
// ControlKnobs returns the node's control knobs.
+34 -16
View File
@@ -345,6 +345,30 @@ func (nb *nodeBackend) Peers() []tailcfg.NodeView {
return slicesx.MapValues(nb.peers)
}
// PeerByID returns the current state of the peer (not self) node with
// the given ID, or ok=false if it is not a current peer.
func (nb *nodeBackend) PeerByID(id tailcfg.NodeID) (_ tailcfg.NodeView, ok bool) {
nb.mu.Lock()
defer nb.mu.Unlock()
n, ok := nb.peers[id]
return n, ok
}
// peerDiscoKeys returns the disco public keys of all current peers,
// keyed by their node public keys. Peers without a disco key are
// omitted.
func (nb *nodeBackend) peerDiscoKeys() map[key.NodePublic]key.DiscoPublic {
nb.mu.Lock()
defer nb.mu.Unlock()
m := make(map[key.NodePublic]key.DiscoPublic, len(nb.peers))
for _, p := range nb.peers {
if dk := p.DiscoKey(); !dk.IsZero() {
m[p.Key()] = dk
}
}
return m
}
func (nb *nodeBackend) PeersForTest() []tailcfg.NodeView {
nb.mu.Lock()
defer nb.mu.Unlock()
@@ -363,28 +387,22 @@ func (nb *nodeBackend) CollectServices() bool {
// AppendMatchingPeers returns base with all peers that match pred appended.
//
// It acquires b.mu to read the netmap but releases it before calling pred.
// It acquires nb.mu to snapshot the peers but releases it before
// calling pred.
func (nb *nodeBackend) AppendMatchingPeers(base []tailcfg.NodeView, pred func(tailcfg.NodeView) bool) []tailcfg.NodeView {
var peers []tailcfg.NodeView
nb.mu.Lock()
if nb.netMap != nil {
// All fields on b.netMap are immutable, so this is
// safe to copy and use outside the lock.
peers = nb.netMap.Peers
}
peers := slicesx.MapValues(nb.peers)
nb.mu.Unlock()
// Sort by node ID for deterministic results; the map iteration
// above is randomly ordered.
slices.SortFunc(peers, func(a, b tailcfg.NodeView) int {
return cmp.Compare(a.ID(), b.ID())
})
ret := base
for _, peer := range peers {
// The peers in b.netMap don't contain updates made via
// UpdateNetmapDelta. So only use PeerView in b.netMap for its NodeID,
// and then look up the latest copy in b.peers which is updated in
// response to UpdateNetmapDelta edits.
nb.mu.Lock()
peer, ok := nb.peers[peer.ID()]
nb.mu.Unlock()
if ok && pred(peer) {
if pred(peer) {
ret = append(ret, peer)
}
}