Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stricter definition of public for DHT #596

Merged
merged 1 commit into from
Apr 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 50 additions & 5 deletions dht_filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,41 @@ type QueryFilterFunc func(dht *IpfsDHT, ai peer.AddrInfo) bool
// the local route table.
type RouteTableFilterFunc func(dht *IpfsDHT, conns []network.Conn) bool

var publicCIDR6 = "2000::/3"
var public6 *net.IPNet

func init() {
_, public6, _ = net.ParseCIDR(publicCIDR6)
}

// isPublicAddr follows the logic of manet.IsPublicAddr, except it uses
// a stricter definition of "public" for ipv6: namely "is it in 2000::/3"?
func isPublicAddr(a ma.Multiaddr) bool {
ip, err := manet.ToIP(a)
if err != nil {
return false
}
if ip.To4() != nil {
return !inAddrRange(ip, manet.Private4) && !inAddrRange(ip, manet.Unroutable4)
}

return public6.Contains(ip)
}

// isPrivateAddr follows the logic of manet.IsPrivateAddr, except that
// it uses a stricter definition of "public" for ipv6
func isPrivateAddr(a ma.Multiaddr) bool {
ip, err := manet.ToIP(a)
if err != nil {
return false
}
if ip.To4() != nil {
return inAddrRange(ip, manet.Private4)
}

return !public6.Contains(ip) && !inAddrRange(ip, manet.Unroutable6)
}

// PublicQueryFilter returns true if the peer is suspected of being publicly accessible
func PublicQueryFilter(_ *IpfsDHT, ai peer.AddrInfo) bool {
if len(ai.Addrs) == 0 {
Expand All @@ -31,7 +66,7 @@ func PublicQueryFilter(_ *IpfsDHT, ai peer.AddrInfo) bool {

var hasPublicAddr bool
for _, a := range ai.Addrs {
if !isRelayAddr(a) && manet.IsPublicAddr(a) {
if !isRelayAddr(a) && isPublicAddr(a) {
hasPublicAddr = true
}
}
Expand All @@ -51,7 +86,7 @@ func PublicRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {
id := conns[0].RemotePeer()
known := dht.peerstore.PeerInfo(id)
for _, a := range known.Addrs {
if !isRelayAddr(a) && manet.IsPublicAddr(a) {
if !isRelayAddr(a) && isPublicAddr(a) {
return true
}
}
Expand Down Expand Up @@ -106,7 +141,7 @@ func PrivateRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {
router := getCachedRouter()
myAdvertisedIPs := make([]net.IP, 0)
for _, a := range dht.Host().Addrs() {
if manet.IsPublicAddr(a) && !isRelayAddr(a) {
if isPublicAddr(a) && !isRelayAddr(a) {
ip, err := manet.ToIP(a)
if err != nil {
continue
Expand All @@ -117,11 +152,11 @@ func PrivateRoutingTableFilter(dht *IpfsDHT, conns []network.Conn) bool {

for _, c := range conns {
ra := c.RemoteMultiaddr()
if manet.IsPrivateAddr(ra) && !isRelayAddr(ra) {
if isPrivateAddr(ra) && !isRelayAddr(ra) {
return true
}

if manet.IsPublicAddr(ra) {
if isPublicAddr(ra) {
ip, err := manet.ToIP(ra)
if err != nil {
continue
Expand Down Expand Up @@ -173,3 +208,13 @@ func isRelayAddr(a ma.Multiaddr) bool {
})
return found
}

func inAddrRange(ip net.IP, ipnets []*net.IPNet) bool {
for _, ipnet := range ipnets {
if ipnet.Contains(ip) {
return true
}
}

return false
}