Skip to content

Commit

Permalink
manet: reduce allocations in resolve unspecified address
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt authored and rvagg committed Jan 10, 2024
1 parent 63824cd commit bd5f381
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
6 changes: 6 additions & 0 deletions net/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
9 changes: 9 additions & 0 deletions net/net_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
14 changes: 9 additions & 5 deletions net/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions net/resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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)
Expand Down
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 _, mb := range ms {
bidx += copy(b[bidx:], mb.Bytes())
}
return &multiaddr{bytes: b}
}
Expand Down

0 comments on commit bd5f381

Please sign in to comment.