Commit 5c3adb60 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet
Browse files

addr: proper filter + subtract

parent 4d877044
...@@ -41,19 +41,27 @@ func init() { ...@@ -41,19 +41,27 @@ func init() {
SupportedTransportProtocols = transports SupportedTransportProtocols = transports
} }
// FilterAddrs is a filter that removes certain addresses // FilterAddrs is a filter that removes certain addresses, according to filter.
// from a list. the addresses removed are those known NOT // if filter returns true, the address is kept.
// to work with our network. Namely, addresses with UTP. func FilterAddrs(a []ma.Multiaddr, filter func(ma.Multiaddr) bool) []ma.Multiaddr {
func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
b := make([]ma.Multiaddr, 0, len(a)) b := make([]ma.Multiaddr, 0, len(a))
for _, addr := range a { for _, addr := range a {
if AddrUsable(addr, false) { if filter(addr) {
b = append(b, addr) b = append(b, addr)
} }
} }
return b return b
} }
// FilterUsableAddrs removes certain addresses
// from a list. the addresses removed are those known NOT
// to work with our network. Namely, addresses with UTP.
func FilterUsableAddrs(a []ma.Multiaddr) []ma.Multiaddr {
return FilterAddrs(a, func(m ma.Multiaddr) bool {
return AddrUsable(m, false)
})
}
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link // AddrOverNonLocalIP returns whether the addr uses a non-local ip link
func AddrOverNonLocalIP(a ma.Multiaddr) bool { func AddrOverNonLocalIP(a ma.Multiaddr) bool {
split := ma.Split(a) split := ma.Split(a)
...@@ -228,13 +236,19 @@ func AddrIsShareableOnWAN(addr ma.Multiaddr) bool { ...@@ -228,13 +236,19 @@ func AddrIsShareableOnWAN(addr ma.Multiaddr) bool {
// WANShareableAddrs filters addresses based on whether they're shareable on WAN // WANShareableAddrs filters addresses based on whether they're shareable on WAN
func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr { func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr {
out := make([]ma.Multiaddr, 0, len(inp)) return FilterAddrs(inp, AddrIsShareableOnWAN)
for _, a := range inp { }
if AddrIsShareableOnWAN(a) {
out = append(out, a) // Subtract filters out all addrs in b from a
func Subtract(a, b []ma.Multiaddr) []ma.Multiaddr {
return FilterAddrs(a, func(m ma.Multiaddr) bool {
for _, bb := range b {
if m.Equal(bb) {
return false
} }
} }
return out return true
})
} }
// CheckNATWarning checks if our observed addresses differ. if so, // CheckNATWarning checks if our observed addresses differ. if so,
......
...@@ -53,9 +53,9 @@ func TestFilterAddrs(t *testing.T) { ...@@ -53,9 +53,9 @@ func TestFilterAddrs(t *testing.T) {
} }
} }
subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{}) subtestAddrsEqual(t, FilterUsableAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, FilterAddrs(good), good) subtestAddrsEqual(t, FilterUsableAddrs(good), good)
subtestAddrsEqual(t, FilterAddrs(goodAndBad), good) subtestAddrsEqual(t, FilterUsableAddrs(goodAndBad), good)
} }
func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) { func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
...@@ -196,3 +196,37 @@ func TestWANShareable(t *testing.T) { ...@@ -196,3 +196,37 @@ func TestWANShareable(t *testing.T) {
t.Error("should be zero") t.Error("should be zero")
} }
} }
func TestSubtract(t *testing.T) {
a := []ma.Multiaddr{
newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
newMultiaddr(t, "/ip6/::1/tcp/1234"),
newMultiaddr(t, "/ip6/::/tcp/1234"),
newMultiaddr(t, "/ip6/fe80::1/tcp/1234"),
newMultiaddr(t, "/ip6/fe80::/tcp/1234"),
}
b := []ma.Multiaddr{
newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
newMultiaddr(t, "/ip6/::1/tcp/1234"),
newMultiaddr(t, "/ip6/fe80::1/tcp/1234"),
}
c1 := []ma.Multiaddr{
newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
newMultiaddr(t, "/ip6/::/tcp/1234"),
newMultiaddr(t, "/ip6/fe80::/tcp/1234"),
}
c2 := Subtract(a, b)
if len(c1) != len(c2) {
t.Error("should be the same")
}
for i, ca := range c1 {
if !c2[i].Equal(ca) {
t.Error("should be the same", ca, c2[i])
}
}
}
...@@ -41,7 +41,7 @@ func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr, ...@@ -41,7 +41,7 @@ func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
local peer.ID, peers peer.Peerstore) (*Swarm, error) { local peer.ID, peers peer.Peerstore) (*Swarm, error) {
if len(listenAddrs) > 0 { if len(listenAddrs) > 0 {
filtered := addrutil.FilterAddrs(listenAddrs) filtered := addrutil.FilterUsableAddrs(listenAddrs)
if len(filtered) < 1 { if len(filtered) < 1 {
return nil, fmt.Errorf("swarm cannot use any addr in: %s", listenAddrs) return nil, fmt.Errorf("swarm cannot use any addr in: %s", listenAddrs)
} }
......
...@@ -51,9 +51,9 @@ func TestFilterAddrs(t *testing.T) { ...@@ -51,9 +51,9 @@ func TestFilterAddrs(t *testing.T) {
} }
} }
subtestAddrsEqual(t, addrutil.FilterAddrs(bad), []ma.Multiaddr{}) subtestAddrsEqual(t, addrutil.FilterUsableAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, addrutil.FilterAddrs(good), good) subtestAddrsEqual(t, addrutil.FilterUsableAddrs(good), good)
subtestAddrsEqual(t, addrutil.FilterAddrs(goodAndBad), good) subtestAddrsEqual(t, addrutil.FilterUsableAddrs(goodAndBad), good)
// now test it with swarm // now test it with swarm
......
...@@ -41,7 +41,7 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) { ...@@ -41,7 +41,7 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
remoteAddrs := s.peers.Addresses(p) remoteAddrs := s.peers.Addresses(p)
// make sure we can use the addresses. // make sure we can use the addresses.
remoteAddrs = addrutil.FilterAddrs(remoteAddrs) remoteAddrs = addrutil.FilterUsableAddrs(remoteAddrs)
if len(remoteAddrs) == 0 { if len(remoteAddrs) == 0 {
return nil, errors.New("peer has no addresses") return nil, errors.New("peer has no addresses")
} }
......
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