@cryptotaxi247 / kubo / commits / 500bb5175

p2p/net/identify: clump addr observers into groups

Different mutliaddrs is not enough. Nodes may share transports. NAT port mappings will likely only work on the base IP/TCP port pair. We go one step further, and require different root (IP) addrs. Just in case some NATs group by IP. In practice, this is what we want: use addresses only if hosts that are on different parts of the network have seen this address.

Juan Batiz-Benet committed Jun 7, 2015 at 17:00 UTC 500bb51759503cf5481d7150c8a4a1d791ba9078
2 files changed +29 -3
p2p/protocol/identify/obsaddr.go
+16 -2
@@ -85,11 +85,25 @@ func (oas *ObservedAddrSet) Add(addr ma.Multiaddr, observer ma.Multiaddr) {
85 oas.addrs[s] = oa
86 }
87
88 - // Add current observer.
89 - oa.SeenBy[observer.String()] = struct{}{}
88 + // mark the observer
89 + oa.SeenBy[observerGroup(observer)] = struct{}{}
90 oa.LastSeen = time.Now()
91 }
92
93 +// observerGroup is a function that determines what part of
94 +// a multiaddr counts as a different observer. for example,
95 +// two ipfs nodes at the same IP/TCP transport would get
96 +// the exact same NAT mapping; they would count as the
97 +// same observer. This may protect against NATs who assign
98 +// different ports to addresses at different IP hosts, but
99 +// not TCP ports.
100 +//
101 +// Here, we use the root multiaddr address. This is mostly
102 +// IP addresses. In practice, this is what we want.
103 +func observerGroup(m ma.Multiaddr) string {
104 + return ma.Split(m)[0].String()
105 +}
106 +
107 func (oas *ObservedAddrSet) SetTTL(ttl time.Duration) {
108 oas.Lock()
109 defer oas.Unlock()
p2p/protocol/identify/obsaddr_test.go
+13 -1
@@ -38,7 +38,8 @@ func TestObsAddrSet(t *testing.T) {
38 a3 := m("/ip4/1.2.3.4/tcp/1233")
39 a4 := m("/ip4/1.2.3.4/tcp/1234")
40 a5 := m("/ip4/1.2.3.4/tcp/1235")
41 - a6 := m("/ip4/1.2.3.4/tcp/1236")
41 + a6 := m("/ip4/1.2.3.6/tcp/1236")
42 + a7 := m("/ip4/1.2.3.7/tcp/1237")
43
44 oas := ObservedAddrSet{}
45
@@ -63,7 +64,15 @@ func TestObsAddrSet(t *testing.T) {
64 t.Error("addrs should _still_ be empty (same obs)")
65 }
66
67 + // different observer, but same observer group.
68 oas.Add(a1, a5)
69 + oas.Add(a2, a5)
70 + oas.Add(a3, a5)
71 + if !addrsMarch(oas.Addrs(), nil) {
72 + t.Error("addrs should _still_ be empty (same obs group)")
73 + }
74 +
75 + oas.Add(a1, a6)
76 if !addrsMarch(oas.Addrs(), []ma.Multiaddr{a1}) {
77 t.Error("addrs should only have a1")
78 }
@@ -74,6 +83,9 @@ func TestObsAddrSet(t *testing.T) {
83 oas.Add(a2, a6)
84 oas.Add(a1, a6)
85 oas.Add(a1, a6)
86 + oas.Add(a2, a7)
87 + oas.Add(a1, a7)
88 + oas.Add(a1, a7)
89 if !addrsMarch(oas.Addrs(), []ma.Multiaddr{a1, a2}) {
90 t.Error("addrs should only have a1, a2")
91 }