From 1c0e833749f455e359ef74a8428ffe3b5c78e39f Mon Sep 17 00:00:00 2001 From: Bouke van der Bijl Date: Wed, 24 Jun 2026 14:14:36 +0200 Subject: [PATCH] ipn/ipnlocal: normalize IPv6-mapped IPv4 addrs in WhoIs WhoIs lookups for an IPv6-mapped IPv4 address such as "::ffff:100.87.98.86" failed to match the node's canonical IPv4 address. Unmap the address before looking it up so these resolve. Fixes #20235 Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Bouke van der Bijl --- ipn/ipnlocal/local.go | 5 +++++ ipn/ipnlocal/local_test.go | 1 + 2 files changed, 6 insertions(+) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 24e5e0500..12b998149 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -1730,6 +1730,11 @@ var debugWhoIs = envknob.RegisterBool("TS_DEBUG_WHOIS") // If ok == true, n and u are valid. func (b *LocalBackend) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) { var zero tailcfg.NodeView + + // Normalize IPv4-mapped IPv6 addresses (e.g. "::ffff:100.87.98.86") to + // their canonical IPv4 form so the lookup matches the node's IPv4 address. + ipp = netip.AddrPortFrom(ipp.Addr().Unmap(), ipp.Port()) + b.mu.Lock() defer b.mu.Unlock() diff --git a/ipn/ipnlocal/local_test.go b/ipn/ipnlocal/local_test.go index f62e11a47..d98f0a76d 100644 --- a/ipn/ipnlocal/local_test.go +++ b/ipn/ipnlocal/local_test.go @@ -2904,6 +2904,7 @@ func TestWhoIs(t *testing.T) { {"round1MyselfWithPort", "100.101.102.103:123", 1, "Myself", nil}, {"round1Peer2NoPort", "100.200.200.200:0", 2, "Peer2", []string{"group:foo"}}, {"round1Peer2WithPort", "100.200.200.200:123", 2, "Peer2", []string{"group:foo"}}, + {"round1Peer2Mapped4in6", "[::ffff:100.200.200.200]:123", 2, "Peer2", []string{"group:foo"}}, {"round1UnknownPeer", "100.4.0.4:404", 0, "", nil}, } expectWhois(t, testsRound1, b)