mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-09 08:01:31 +00:00
derp: add PeerPresentFlags bitmask to Watch messages
Updates tailscale/corp#17816 Change-Id: Ib5baf6c981a6a4c279f8bbfef02048cfbfb3323b Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
d7a4f9d31c
commit
5ffb2668ef
@@ -566,7 +566,7 @@ func (s *Server) registerClient(c *sclient) {
|
||||
}
|
||||
s.keyOfAddr[c.remoteIPPort] = c.key
|
||||
s.curClients.Add(1)
|
||||
s.broadcastPeerStateChangeLocked(c.key, c.remoteIPPort, true)
|
||||
s.broadcastPeerStateChangeLocked(c.key, c.remoteIPPort, c.presentFlags(), true)
|
||||
}
|
||||
|
||||
// broadcastPeerStateChangeLocked enqueues a message to all watchers
|
||||
@@ -574,12 +574,13 @@ func (s *Server) registerClient(c *sclient) {
|
||||
// presence changed.
|
||||
//
|
||||
// s.mu must be held.
|
||||
func (s *Server) broadcastPeerStateChangeLocked(peer key.NodePublic, ipPort netip.AddrPort, present bool) {
|
||||
func (s *Server) broadcastPeerStateChangeLocked(peer key.NodePublic, ipPort netip.AddrPort, flags PeerPresentFlags, present bool) {
|
||||
for w := range s.watchers {
|
||||
w.peerStateChange = append(w.peerStateChange, peerConnState{
|
||||
peer: peer,
|
||||
present: present,
|
||||
ipPort: ipPort,
|
||||
flags: flags,
|
||||
})
|
||||
go w.requestMeshUpdate()
|
||||
}
|
||||
@@ -601,7 +602,7 @@ func (s *Server) unregisterClient(c *sclient) {
|
||||
delete(s.clientsMesh, c.key)
|
||||
s.notePeerGoneFromRegionLocked(c.key)
|
||||
}
|
||||
s.broadcastPeerStateChangeLocked(c.key, netip.AddrPort{}, false)
|
||||
s.broadcastPeerStateChangeLocked(c.key, netip.AddrPort{}, 0, false)
|
||||
case *dupClientSet:
|
||||
c.debugLogf("removed duplicate client")
|
||||
if set.removeClient(c) {
|
||||
@@ -700,6 +701,7 @@ func (s *Server) addWatcher(c *sclient) {
|
||||
peer: peer,
|
||||
present: true,
|
||||
ipPort: ac.remoteIPPort,
|
||||
flags: ac.presentFlags(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1435,11 +1437,26 @@ type sclient struct {
|
||||
peerGoneLim *rate.Limiter
|
||||
}
|
||||
|
||||
func (c *sclient) presentFlags() PeerPresentFlags {
|
||||
var f PeerPresentFlags
|
||||
if c.info.IsProber {
|
||||
f |= PeerPresentIsProber
|
||||
}
|
||||
if c.canMesh {
|
||||
f |= PeerPresentIsMeshPeer
|
||||
}
|
||||
if f == 0 {
|
||||
return PeerPresentIsRegular
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// peerConnState represents whether a peer is connected to the server
|
||||
// or not.
|
||||
type peerConnState struct {
|
||||
ipPort netip.AddrPort // if present, the peer's IP:port
|
||||
peer key.NodePublic
|
||||
flags PeerPresentFlags
|
||||
present bool
|
||||
}
|
||||
|
||||
@@ -1634,9 +1651,9 @@ func (c *sclient) sendPeerGone(peer key.NodePublic, reason PeerGoneReasonType) e
|
||||
}
|
||||
|
||||
// sendPeerPresent sends a peerPresent frame, without flushing.
|
||||
func (c *sclient) sendPeerPresent(peer key.NodePublic, ipPort netip.AddrPort) error {
|
||||
func (c *sclient) sendPeerPresent(peer key.NodePublic, ipPort netip.AddrPort, flags PeerPresentFlags) error {
|
||||
c.setWriteDeadline()
|
||||
const frameLen = keyLen + 16 + 2
|
||||
const frameLen = keyLen + 16 + 2 + 1 // 16 byte IP + 2 byte port + 1 byte flags
|
||||
if err := writeFrameHeader(c.bw.bw(), framePeerPresent, frameLen); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1645,6 +1662,7 @@ func (c *sclient) sendPeerPresent(peer key.NodePublic, ipPort netip.AddrPort) er
|
||||
a16 := ipPort.Addr().As16()
|
||||
copy(payload[keyLen:], a16[:])
|
||||
binary.BigEndian.PutUint16(payload[keyLen+16:], ipPort.Port())
|
||||
payload[keyLen+18] = byte(flags)
|
||||
_, err := c.bw.Write(payload)
|
||||
return err
|
||||
}
|
||||
@@ -1675,7 +1693,7 @@ drainUpdates:
|
||||
}
|
||||
var err error
|
||||
if pcs.present {
|
||||
err = c.sendPeerPresent(pcs.peer, pcs.ipPort)
|
||||
err = c.sendPeerPresent(pcs.peer, pcs.ipPort, pcs.flags)
|
||||
} else {
|
||||
err = c.sendPeerGone(pcs.peer, PeerGoneReasonDisconnected)
|
||||
}
|
||||
|
Reference in New Issue
Block a user