Skip to content

Commit d7bb32d

Browse files
authored
Merge pull request #596 from libp2p/bug/strictv6pub
stricter definition of public for DHT
2 parents 7c7c46d + 278c3ea commit d7bb32d

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

dht_filters.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,41 @@ type QueryFilterFunc func(dht *IpfsDHT, ai peer.AddrInfo) bool
2323
// the local route table.
2424
type RouteTableFilterFunc func(dht *IpfsDHT, conns []network.Conn) bool
2525

26+
var publicCIDR6 = "2000::/3"
27+
var public6 *net.IPNet
28+
29+
func init() {
30+
_, public6, _ = net.ParseCIDR(publicCIDR6)
31+
}
32+
33+
// isPublicAddr follows the logic of manet.IsPublicAddr, except it uses
34+
// a stricter definition of "public" for ipv6: namely "is it in 2000::/3"?
35+
func isPublicAddr(a ma.Multiaddr) bool {
36+
ip, err := manet.ToIP(a)
37+
if err != nil {
38+
return false
39+
}
40+
if ip.To4() != nil {
41+
return !inAddrRange(ip, manet.Private4) && !inAddrRange(ip, manet.Unroutable4)
42+
}
43+
44+
return public6.Contains(ip)
45+
}
46+
47+
// isPrivateAddr follows the logic of manet.IsPrivateAddr, except that
48+
// it uses a stricter definition of "public" for ipv6
49+
func isPrivateAddr(a ma.Multiaddr) bool {
50+
ip, err := manet.ToIP(a)
51+
if err != nil {
52+
return false
53+
}
54+
if ip.To4() != nil {
55+
return inAddrRange(ip, manet.Private4)
56+
}
57+
58+
return !public6.Contains(ip) && !inAddrRange(ip, manet.Unroutable6)
59+
}
60+
2661
// PublicQueryFilter returns true if the peer is suspected of being publicly accessible
2762
func PublicQueryFilter(_ *IpfsDHT, ai peer.AddrInfo) bool {
2863
if len(ai.Addrs) == 0 {
@@ -31,7 +66,7 @@ func PublicQueryFilter(_ *IpfsDHT, ai peer.AddrInfo) bool {
3166

3267
var hasPublicAddr bool
3368
for _, a := range ai.Addrs {
34-
if !isRelayAddr(a) && manet.IsPublicAddr(a) {
69+
if !isRelayAddr(a) && isPublicAddr(a) {
3570
hasPublicAddr = true
3671
}
3772
}
@@ -51,7 +86,7 @@ func PublicRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {
5186
id := conns[0].RemotePeer()
5287
known := dht.peerstore.PeerInfo(id)
5388
for _, a := range known.Addrs {
54-
if !isRelayAddr(a) && manet.IsPublicAddr(a) {
89+
if !isRelayAddr(a) && isPublicAddr(a) {
5590
return true
5691
}
5792
}
@@ -106,7 +141,7 @@ func PrivateRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {
106141
router := getCachedRouter()
107142
myAdvertisedIPs := make([]net.IP, 0)
108143
for _, a := range dht.Host().Addrs() {
109-
if manet.IsPublicAddr(a) && !isRelayAddr(a) {
144+
if isPublicAddr(a) && !isRelayAddr(a) {
110145
ip, err := manet.ToIP(a)
111146
if err != nil {
112147
continue
@@ -117,11 +152,11 @@ func PrivateRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {
117152

118153
for _, c := range conns {
119154
ra := c.RemoteMultiaddr()
120-
if manet.IsPrivateAddr(ra) && !isRelayAddr(ra) {
155+
if isPrivateAddr(ra) && !isRelayAddr(ra) {
121156
return true
122157
}
123158

124-
if manet.IsPublicAddr(ra) {
159+
if isPublicAddr(ra) {
125160
ip, err := manet.ToIP(ra)
126161
if err != nil {
127162
continue
@@ -173,3 +208,13 @@ func isRelayAddr(a ma.Multiaddr) bool {
173208
})
174209
return found
175210
}
211+
212+
func inAddrRange(ip net.IP, ipnets []*net.IPNet) bool {
213+
for _, ipnet := range ipnets {
214+
if ipnet.Contains(ip) {
215+
return true
216+
}
217+
}
218+
219+
return false
220+
}

0 commit comments

Comments
 (0)