diff --git a/net/ip.go b/net/ip.go index 66f9197..ef936c5 100644 --- a/net/ip.go +++ b/net/ip.go @@ -60,6 +60,9 @@ func IsThinWaist(m ma.Multiaddr) bool { // or /ip6zone//ip6//* func IsIPLoopback(m ma.Multiaddr) bool { m = zoneless(m) + if m == nil { + return false + } c, _ := ma.SplitFirst(m) if c == nil { return false @@ -76,6 +79,9 @@ func IsIPLoopback(m ma.Multiaddr) bool { // routable. func IsIP6LinkLocal(m ma.Multiaddr) bool { m = zoneless(m) + if m == nil { + return false + } c, _ := ma.SplitFirst(m) if c == nil || c.Protocol().Code != ma.P_IP6 { return false diff --git a/net/net_test.go b/net/net_test.go index 3e84010..86cfc50 100644 --- a/net/net_test.go +++ b/net/net_test.go @@ -682,3 +682,12 @@ func TestNetListener(t *testing.T) { } nc.Close() } + +func BenchmarkResolveUnspecifiedAddress(b *testing.B) { + b.ReportAllocs() + a := ma.StringCast("/ip4/0.0.0.0/udp/42/quic-v1") + iaddrs, _ := interfaceAddresses() + for i := 0; i < b.N; i++ { + ResolveUnspecifiedAddress(a, iaddrs) + } +} diff --git a/net/resolve.go b/net/resolve.go index a2478e7..44c2ef1 100644 --- a/net/resolve.go +++ b/net/resolve.go @@ -11,22 +11,26 @@ import ( // from the network stack. (this is so you can provide a cached value if resolving many addrs) func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) { // split address into its components - split := ma.Split(resolve) + first, rest := ma.SplitFirst(resolve) // if first component (ip) is not unspecified, use it as is. - if !IsIPUnspecified(split[0]) { + if !IsIPUnspecified(first) { return []ma.Multiaddr{resolve}, nil } + resolveProto := resolve.Protocols()[0].Code out := make([]ma.Multiaddr, 0, len(ifaceAddrs)) for _, ia := range ifaceAddrs { + iafirst, _ := ma.SplitFirst(ia) // must match the first protocol to be resolve. - if ia.Protocols()[0].Code != resolve.Protocols()[0].Code { + if iafirst.Protocol().Code != resolveProto { continue } - split[0] = ia - joined := ma.Join(split...) + joined := ia + if rest != nil { + joined = ma.Join(ia, rest) + } out = append(out, joined) } if len(out) < 1 { diff --git a/net/resolve_test.go b/net/resolve_test.go index 387e70a..e4af820 100644 --- a/net/resolve_test.go +++ b/net/resolve_test.go @@ -13,6 +13,7 @@ func TestResolvingAddrs(t *testing.T) { newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"), newMultiaddr(t, "/ip6/::/tcp/1234"), newMultiaddr(t, "/ip6/::100/tcp/1234"), + newMultiaddr(t, "/ip4/0.0.0.0"), } iface := []ma.Multiaddr{ @@ -29,6 +30,8 @@ func TestResolvingAddrs(t *testing.T) { newMultiaddr(t, "/ip6/::1/tcp/1234"), newMultiaddr(t, "/ip6/::f/tcp/1234"), newMultiaddr(t, "/ip6/::100/tcp/1234"), + newMultiaddr(t, "/ip4/127.0.0.1"), + newMultiaddr(t, "/ip4/10.20.30.40"), } actual, err := ResolveUnspecifiedAddresses(unspec, iface) diff --git a/util.go b/util.go index cf4469a..013cbaa 100644 --- a/util.go +++ b/util.go @@ -27,16 +27,14 @@ func Join(ms ...Multiaddr) Multiaddr { } length := 0 - bs := make([][]byte, len(ms)) - for i, m := range ms { - bs[i] = m.Bytes() - length += len(bs[i]) + for _, m := range ms { + length += len(m.Bytes()) } bidx := 0 b := make([]byte, length) - for _, mb := range bs { - bidx += copy(b[bidx:], mb) + for _, mb := range ms { + bidx += copy(b[bidx:], mb.Bytes()) } return &multiaddr{bytes: b} }