diff --git a/ip.go b/ip.go index 7ca7a3e..d188957 100644 --- a/ip.go +++ b/ip.go @@ -24,6 +24,14 @@ var ( IP6Unspecified = ma.StringCast("/ip6/::") ) +// Loopback multiaddr prefixes. Any multiaddr beginning with one of the +// following byte sequences is considered a loopback multiaddr. +var loopbackPrefixes = [][]byte{ + {ma.P_IP4, 127}, // 127.* + IP6LinkLocalLoopback.Bytes(), + IP6Loopback.Bytes(), +} + // IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols. // This means: /{IP4, IP6}[/{TCP, UDP}] func IsThinWaist(m ma.Multiaddr) bool { @@ -52,21 +60,14 @@ func IsThinWaist(m ma.Multiaddr) bool { } // IsIPLoopback returns whether a Multiaddr is a "Loopback" IP address -// This means either /ip4/127.0.0.1 or /ip6/::1 -// TODO: differentiate IsIPLoopback and OverIPLoopback +// This means either /ip4/127.*.*.*, /ip6/::1, or /ip6/fe80::1 func IsIPLoopback(m ma.Multiaddr) bool { b := m.Bytes() - - // /ip4/127 prefix (_entire_ /8 is loopback...) - if bytes.HasPrefix(b, []byte{ma.P_IP4, 127}) { - return true + for _, prefix := range loopbackPrefixes { + if bytes.HasPrefix(b, prefix) { + return true + } } - - // /ip6/::1 - if !m.Decapsulate(IP6Loopback).Equal(m) || !m.Decapsulate(IP6LinkLocalLoopback).Equal(m) { - return true - } - return false } diff --git a/net_test.go b/net_test.go index 44bdfd7..e7299b2 100644 --- a/net_test.go +++ b/net_test.go @@ -314,6 +314,18 @@ func TestIPLoopback(t *testing.T) { t.Error("IsIPLoopback failed (IP4Loopback)") } + if !IsIPLoopback(newMultiaddr(t, "/ip4/127.1.80.9")) { + t.Error("IsIPLoopback failed (/ip4/127.1.80.9)") + } + + if IsIPLoopback(newMultiaddr(t, "/ip4/112.123.11.1")) { + t.Error("IsIPLoopback false positive (/ip4/112.123.11.1)") + } + + if IsIPLoopback(newMultiaddr(t, "/ip4/192.168.0.1/ip6/::1")) { + t.Error("IsIPLoopback false positive (/ip4/192.168.0.1/ip6/::1)") + } + if !IsIPLoopback(IP6Loopback) { t.Error("IsIPLoopback failed (IP6Loopback)") }