Skip to content

Commit

Permalink
reduce allocations in net.ResolveUnspecifiedAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt committed Jun 3, 2023
1 parent f317559 commit f33d995
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
21 changes: 13 additions & 8 deletions net/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,31 @@ import (
)

// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
// use the known local interfaces
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 == nil {
return []ma.Multiaddr{resolve}, nil
}

// if first component (ip) is not unspecified, use it as is.
if !IsIPUnspecified(split[0]) {
if !IsIPUnspecified(first) {
return []ma.Multiaddr{resolve}, nil
}

out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
for _, ia := range ifaceAddrs {
// must match the first protocol to be resolve.
if ia.Protocols()[0].Code != resolve.Protocols()[0].Code {
match := false
ma.ForEach(ia, func(c ma.Component) bool {
match = c.Protocol().Code == first.Protocol().Code
return false
})
if !match {
continue
}

split[0] = ia
joined := ma.Join(split...)
joined := ma.Join(ia, rest)
out = append(out, joined)
}
if len(out) < 1 {
Expand Down
15 changes: 15 additions & 0 deletions net/resolve_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manet

import (
"math/rand"
"testing"

ma "github.com/multiformats/go-multiaddr"
Expand Down Expand Up @@ -55,3 +56,17 @@ func TestResolvingAddrs(t *testing.T) {
t.Fatal("should have failed")
}
}

func BenchmarkResolveAddr(b *testing.B) {
b.ReportAllocs()
unspec := []ma.Multiaddr{
ma.StringCast("/ip4/0.0.0.0/tcp/1234"),
}

iface := []ma.Multiaddr{
ma.StringCast("/ip4/127.0.0.1"),
}
for i := 0; i < b.N; i++ {
ResolveUnspecifiedAddress(unspec[rand.Intn(len(unspec))], iface)
}
}
10 changes: 4 additions & 6 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 _, m := range ms {
bidx += copy(b[bidx:], m.Bytes())
}
return &multiaddr{bytes: b}
}
Expand Down

0 comments on commit f33d995

Please sign in to comment.