addr: proper filter + subtract
Juan Batiz-Benet committed
Jan 12, 2015 at 20:49 UTC
7aa4a83f2e100da7029124fa55321eee4c632809
6 files changed
+68
-20
core/core.go
+1
-1
@@ -359,7 +359,7 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
359
360
// make sure we error out if our config does not have addresses we can use
361
log.Debugf("Config.Addresses.Swarm:%s", listenAddrs)
362
- filteredAddrs := addrutil.FilterAddrs(listenAddrs)
362
+ filteredAddrs := addrutil.FilterUsableAddrs(listenAddrs)
363
log.Debugf("Config.Addresses.Swarm:%s (filtered)", listenAddrs)
364
if len(filteredAddrs) < 1 {
365
return nil, debugerror.Errorf("addresses in config not usable: %s", listenAddrs)
p2p/net/swarm/addr/addr.go
+25
-11
@@ -41,19 +41,27 @@ func init() {
41
SupportedTransportProtocols = transports
42
}
43
44
-// FilterAddrs is a filter that removes certain addresses
45
-// from a list. the addresses removed are those known NOT
46
-// to work with our network. Namely, addresses with UTP.
47
-func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
44
+// FilterAddrs is a filter that removes certain addresses, according to filter.
45
+// if filter returns true, the address is kept.
46
+func FilterAddrs(a []ma.Multiaddr, filter func(ma.Multiaddr) bool) []ma.Multiaddr {
47
b := make([]ma.Multiaddr, 0, len(a))
48
for _, addr := range a {
50
- if AddrUsable(addr, false) {
49
+ if filter(addr) {
50
b = append(b, addr)
51
}
52
}
53
return b
54
}
55
56
+// FilterUsableAddrs removes certain addresses
57
+// from a list. the addresses removed are those known NOT
58
+// to work with our network. Namely, addresses with UTP.
59
+func FilterUsableAddrs(a []ma.Multiaddr) []ma.Multiaddr {
60
+ return FilterAddrs(a, func(m ma.Multiaddr) bool {
61
+ return AddrUsable(m, false)
62
+ })
63
+}
64
+
65
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link
66
func AddrOverNonLocalIP(a ma.Multiaddr) bool {
67
split := ma.Split(a)
@@ -228,13 +236,19 @@ func AddrIsShareableOnWAN(addr ma.Multiaddr) bool {
236
237
// WANShareableAddrs filters addresses based on whether they're shareable on WAN
238
func WANShareableAddrs(inp []ma.Multiaddr) []ma.Multiaddr {
231
- out := make([]ma.Multiaddr, 0, len(inp))
232
- for _, a := range inp {
233
- if AddrIsShareableOnWAN(a) {
234
- out = append(out, a)
239
+ return FilterAddrs(inp, AddrIsShareableOnWAN)
240
+}
241
+
242
+// Subtract filters out all addrs in b from a
243
+func Subtract(a, b []ma.Multiaddr) []ma.Multiaddr {
244
+ return FilterAddrs(a, func(m ma.Multiaddr) bool {
245
+ for _, bb := range b {
246
+ if m.Equal(bb) {
247
+ return false
248
+ }
249
}
236
- }
237
- return out
250
+ return true
251
+ })
252
}
253
254
// CheckNATWarning checks if our observed addresses differ. if so,
p2p/net/swarm/addr/addr_test.go
+37
-3
@@ -53,9 +53,9 @@ func TestFilterAddrs(t *testing.T) {
53
}
54
}
55
56
- subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{})
57
- subtestAddrsEqual(t, FilterAddrs(good), good)
58
- subtestAddrsEqual(t, FilterAddrs(goodAndBad), good)
56
+ subtestAddrsEqual(t, FilterUsableAddrs(bad), []ma.Multiaddr{})
57
+ subtestAddrsEqual(t, FilterUsableAddrs(good), good)
58
+ subtestAddrsEqual(t, FilterUsableAddrs(goodAndBad), good)
59
}
60
61
func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
@@ -196,3 +196,37 @@ func TestWANShareable(t *testing.T) {
196
t.Error("should be zero")
197
}
198
}
199
+
200
+func TestSubtract(t *testing.T) {
201
+
202
+ a := []ma.Multiaddr{
203
+ newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
204
+ newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
205
+ newMultiaddr(t, "/ip6/::1/tcp/1234"),
206
+ newMultiaddr(t, "/ip6/::/tcp/1234"),
207
+ newMultiaddr(t, "/ip6/fe80::1/tcp/1234"),
208
+ newMultiaddr(t, "/ip6/fe80::/tcp/1234"),
209
+ }
210
+
211
+ b := []ma.Multiaddr{
212
+ newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234"),
213
+ newMultiaddr(t, "/ip6/::1/tcp/1234"),
214
+ newMultiaddr(t, "/ip6/fe80::1/tcp/1234"),
215
+ }
216
+
217
+ c1 := []ma.Multiaddr{
218
+ newMultiaddr(t, "/ip4/0.0.0.0/tcp/1234"),
219
+ newMultiaddr(t, "/ip6/::/tcp/1234"),
220
+ newMultiaddr(t, "/ip6/fe80::/tcp/1234"),
221
+ }
222
+
223
+ c2 := Subtract(a, b)
224
+ if len(c1) != len(c2) {
225
+ t.Error("should be the same")
226
+ }
227
+ for i, ca := range c1 {
228
+ if !c2[i].Equal(ca) {
229
+ t.Error("should be the same", ca, c2[i])
230
+ }
231
+ }
232
+}
p2p/net/swarm/swarm.go
+1
-1
@@ -41,7 +41,7 @@ func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
41
local peer.ID, peers peer.Peerstore) (*Swarm, error) {
42
43
if len(listenAddrs) > 0 {
44
- filtered := addrutil.FilterAddrs(listenAddrs)
44
+ filtered := addrutil.FilterUsableAddrs(listenAddrs)
45
if len(filtered) < 1 {
46
return nil, fmt.Errorf("swarm cannot use any addr in: %s", listenAddrs)
47
}
p2p/net/swarm/swarm_addr_test.go
+3
-3
@@ -51,9 +51,9 @@ func TestFilterAddrs(t *testing.T) {
51
}
52
}
53
54
- subtestAddrsEqual(t, addrutil.FilterAddrs(bad), []ma.Multiaddr{})
55
- subtestAddrsEqual(t, addrutil.FilterAddrs(good), good)
56
- subtestAddrsEqual(t, addrutil.FilterAddrs(goodAndBad), good)
54
+ subtestAddrsEqual(t, addrutil.FilterUsableAddrs(bad), []ma.Multiaddr{})
55
+ subtestAddrsEqual(t, addrutil.FilterUsableAddrs(good), good)
56
+ subtestAddrsEqual(t, addrutil.FilterUsableAddrs(goodAndBad), good)
57
58
// now test it with swarm
59
p2p/net/swarm/swarm_dial.go
+1
-1
@@ -41,7 +41,7 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
41
42
remoteAddrs := s.peers.Addresses(p)
43
// make sure we can use the addresses.
44
- remoteAddrs = addrutil.FilterAddrs(remoteAddrs)
44
+ remoteAddrs = addrutil.FilterUsableAddrs(remoteAddrs)
45
if len(remoteAddrs) == 0 {
46
return nil, errors.New("peer has no addresses")
47
}