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() {
SupportedTransportProtocols = transports
}
// FilterAddrs is a filter that removes certain addresses
// from a list. the addresses removed are those known NOT
// to work with our network. Namely, addresses with UTP.
func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
// FilterAddrs is a filter that removes certain addresses, according to filter.
// if filter returns true, the address is kept.
func FilterAddrs(a []ma.Multiaddr, filter func(ma.Multiaddr) bool) []ma.Multiaddr {
b := make([]ma.Multiaddr, 0, len(a))
for _, addr := range a {
if AddrUsable(addr, false) {
if filter(addr) {
b = append(b, addr)
}
}
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
func AddrOverNonLocalIP(a ma.Multiaddr) bool {
split := ma.Split(a)
......@@ -228,13 +236,19 @@ func AddrIsShareableOnWAN(addr ma.Multiaddr) bool {
// WANShareableAddrs filters addresses based on whether they're shareable on WAN
func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr {
out := make([]ma.Multiaddr, 0, len(inp))
for _, a := range inp {
if AddrIsShareableOnWAN(a) {
out = append(out, a)
return FilterAddrs(inp, AddrIsShareableOnWAN)
}
// 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,
......
......@@ -53,9 +53,9 @@ func TestFilterAddrs(t *testing.T) {
}
}
subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, FilterAddrs(good), good)
subtestAddrsEqual(t, FilterAddrs(goodAndBad), good)
subtestAddrsEqual(t, FilterUsableAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, FilterUsableAddrs(good), good)
subtestAddrsEqual(t, FilterUsableAddrs(goodAndBad), good)
}
func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
......@@ -196,3 +196,37 @@ func TestWANShareable(t *testing.T) {
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,
local peer.ID, peers peer.Peerstore) (*Swarm, error) {
if len(listenAddrs) > 0 {
filtered := addrutil.FilterAddrs(listenAddrs)
filtered := addrutil.FilterUsableAddrs(listenAddrs)
if len(filtered) < 1 {
return nil, fmt.Errorf("swarm cannot use any addr in: %s", listenAddrs)
}
......
......@@ -51,9 +51,9 @@ func TestFilterAddrs(t *testing.T) {
}
}
subtestAddrsEqual(t, addrutil.FilterAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, addrutil.FilterAddrs(good), good)
subtestAddrsEqual(t, addrutil.FilterAddrs(goodAndBad), good)
subtestAddrsEqual(t, addrutil.FilterUsableAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, addrutil.FilterUsableAddrs(good), good)
subtestAddrsEqual(t, addrutil.FilterUsableAddrs(goodAndBad), good)
// now test it with swarm
......
......@@ -41,7 +41,7 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
remoteAddrs := s.peers.Addresses(p)
// make sure we can use the addresses.
remoteAddrs = addrutil.FilterAddrs(remoteAddrs)
remoteAddrs = addrutil.FilterUsableAddrs(remoteAddrs)
if len(remoteAddrs) == 0 {
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