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 {
// or /ip6zone/<any value>/ip6/<one of the preceding ip6 values>/*
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
......
......@@ -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)
}
}
......@@ -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 {
......
......@@ -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)
......
......@@ -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}
}
......
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