wgengine/magicsock: allow disco communication without known endpoints

Just because we don't have known endpoints for a peer does not mean that
the peer should become unreachable. If we know the peers key, it should
be able to call us, then we can talk back via whatever path it called us
on. First step - don't drop the packet in this context.

Updates tailscale/corp#19106

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker 2024-03-27 16:35:34 -07:00 committed by James Tucker
parent 7f4cda23ac
commit a2eb1c22b0
2 changed files with 8 additions and 7 deletions

View File

@ -1389,10 +1389,10 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke
return
}
if !c.peerMap.anyEndpointForDiscoKey(sender) {
if !c.peerMap.knownPeerDiscoKey(sender) {
metricRecvDiscoBadPeer.Add(1)
if debugDisco() {
c.logf("magicsock: disco: ignoring disco-looking frame, don't know endpoint for %v", sender.ShortString())
c.logf("magicsock: disco: ignoring disco-looking frame, don't know of key %v", sender.ShortString())
}
return
}
@ -2050,7 +2050,7 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) {
// discokeys might have changed in the above. Discard unused info.
for dk := range c.discoInfo {
if !c.peerMap.anyEndpointForDiscoKey(dk) {
if !c.peerMap.knownPeerDiscoKey(dk) {
delete(c.discoInfo, dk)
}
}

View File

@ -60,10 +60,11 @@ func (m *peerMap) nodeCount() int {
return len(m.byNodeKey)
}
// anyEndpointForDiscoKey reports whether there exists any
// peers in the netmap with dk as their DiscoKey.
func (m *peerMap) anyEndpointForDiscoKey(dk key.DiscoPublic) bool {
return len(m.nodesOfDisco[dk]) > 0
// knownPeerDiscoKey reports whether there exists any peer with the disco key
// dk.
func (m *peerMap) knownPeerDiscoKey(dk key.DiscoPublic) bool {
_, ok := m.nodesOfDisco[dk]
return ok
}
// endpointForNodeKey returns the endpoint for nk, or nil if