Commit bd5f3815 authored by sukun's avatar sukun Committed by Rod Vagg

manet: reduce allocations in resolve unspecified address

parent 63824cdf
...@@ -60,6 +60,9 @@ func IsThinWaist(m ma.Multiaddr) bool { ...@@ -60,6 +60,9 @@ func IsThinWaist(m ma.Multiaddr) bool {
// or /ip6zone/<any value>/ip6/<one of the preceding ip6 values>/* // or /ip6zone/<any value>/ip6/<one of the preceding ip6 values>/*
func IsIPLoopback(m ma.Multiaddr) bool { func IsIPLoopback(m ma.Multiaddr) bool {
m = zoneless(m) m = zoneless(m)
if m == nil {
return false
}
c, _ := ma.SplitFirst(m) c, _ := ma.SplitFirst(m)
if c == nil { if c == nil {
return false return false
...@@ -76,6 +79,9 @@ func IsIPLoopback(m ma.Multiaddr) bool { ...@@ -76,6 +79,9 @@ func IsIPLoopback(m ma.Multiaddr) bool {
// routable. // routable.
func IsIP6LinkLocal(m ma.Multiaddr) bool { func IsIP6LinkLocal(m ma.Multiaddr) bool {
m = zoneless(m) m = zoneless(m)
if m == nil {
return false
}
c, _ := ma.SplitFirst(m) c, _ := ma.SplitFirst(m)
if c == nil || c.Protocol().Code != ma.P_IP6 { if c == nil || c.Protocol().Code != ma.P_IP6 {
return false return false
......
...@@ -682,3 +682,12 @@ func TestNetListener(t *testing.T) { ...@@ -682,3 +682,12 @@ func TestNetListener(t *testing.T) {
} }
nc.Close() 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)
}
}
...@@ -11,22 +11,26 @@ import ( ...@@ -11,22 +11,26 @@ import (
// from the network stack. (this is so you can provide a cached value if resolving many addrs) // 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) { func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
// split address into its components // 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 first component (ip) is not unspecified, use it as is.
if !IsIPUnspecified(split[0]) { if !IsIPUnspecified(first) {
return []ma.Multiaddr{resolve}, nil return []ma.Multiaddr{resolve}, nil
} }
resolveProto := resolve.Protocols()[0].Code
out := make([]ma.Multiaddr, 0, len(ifaceAddrs)) out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
for _, ia := range ifaceAddrs { for _, ia := range ifaceAddrs {
iafirst, _ := ma.SplitFirst(ia)
// must match the first protocol to be resolve. // must match the first protocol to be resolve.
if ia.Protocols()[0].Code != resolve.Protocols()[0].Code { if iafirst.Protocol().Code != resolveProto {
continue continue
} }
split[0] = ia joined := ia
joined := ma.Join(split...) if rest != nil {
joined = ma.Join(ia, rest)
}
out = append(out, joined) out = append(out, joined)
} }
if len(out) < 1 { if len(out) < 1 {
......
...@@ -13,6 +13,7 @@ func TestResolvingAddrs(t *testing.T) { ...@@ -13,6 +13,7 @@ func TestResolvingAddrs(t *testing.T) {
newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"), newMultiaddr(t, "/ip4/1.2.3.4/tcp/1234"),
newMultiaddr(t, "/ip6/::/tcp/1234"), newMultiaddr(t, "/ip6/::/tcp/1234"),
newMultiaddr(t, "/ip6/::100/tcp/1234"), newMultiaddr(t, "/ip6/::100/tcp/1234"),
newMultiaddr(t, "/ip4/0.0.0.0"),
} }
iface := []ma.Multiaddr{ iface := []ma.Multiaddr{
...@@ -29,6 +30,8 @@ func TestResolvingAddrs(t *testing.T) { ...@@ -29,6 +30,8 @@ func TestResolvingAddrs(t *testing.T) {
newMultiaddr(t, "/ip6/::1/tcp/1234"), newMultiaddr(t, "/ip6/::1/tcp/1234"),
newMultiaddr(t, "/ip6/::f/tcp/1234"), newMultiaddr(t, "/ip6/::f/tcp/1234"),
newMultiaddr(t, "/ip6/::100/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) actual, err := ResolveUnspecifiedAddresses(unspec, iface)
......
...@@ -27,16 +27,14 @@ func Join(ms ...Multiaddr) Multiaddr { ...@@ -27,16 +27,14 @@ func Join(ms ...Multiaddr) Multiaddr {
} }
length := 0 length := 0
bs := make([][]byte, len(ms)) for _, m := range ms {
for i, m := range ms { length += len(m.Bytes())
bs[i] = m.Bytes()
length += len(bs[i])
} }
bidx := 0 bidx := 0
b := make([]byte, length) b := make([]byte, length)
for _, mb := range bs { for _, mb := range ms {
bidx += copy(b[bidx:], mb) bidx += copy(b[bidx:], mb.Bytes())
} }
return &multiaddr{bytes: b} return &multiaddr{bytes: b}
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment