95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
|
package autonat
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p-core/host"
|
||
|
ma "github.com/multiformats/go-multiaddr"
|
||
|
manet "github.com/multiformats/go-multiaddr/net"
|
||
|
)
|
||
|
|
||
|
type dialPolicy struct {
|
||
|
allowSelfDials bool
|
||
|
host host.Host
|
||
|
}
|
||
|
|
||
|
// skipDial indicates that a multiaddress isn't worth attempted dialing.
|
||
|
// The same logic is used when the autonat client is considering if
|
||
|
// a remote peer is worth using as a server, and when the server is
|
||
|
// considering if a requested client is worth dialing back.
|
||
|
func (d *dialPolicy) skipDial(addr ma.Multiaddr) bool {
|
||
|
// skip relay addresses
|
||
|
_, err := addr.ValueForProtocol(ma.P_CIRCUIT)
|
||
|
if err == nil {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
if d.allowSelfDials {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// skip private network (unroutable) addresses
|
||
|
if !manet.IsPublicAddr(addr) {
|
||
|
return true
|
||
|
}
|
||
|
candidateIP, err := manet.ToIP(addr)
|
||
|
if err != nil {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
// Skip dialing addresses we believe are the local node's
|
||
|
for _, localAddr := range d.host.Addrs() {
|
||
|
localIP, err := manet.ToIP(localAddr)
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
if localIP.Equal(candidateIP) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// skipPeer indicates that the collection of multiaddresses representing a peer
|
||
|
// isn't worth attempted dialing. If one of the addresses matches an address
|
||
|
// we believe is ours, we exclude the peer, even if there are other valid
|
||
|
// public addresses in the list.
|
||
|
func (d *dialPolicy) skipPeer(addrs []ma.Multiaddr) bool {
|
||
|
localAddrs := d.host.Addrs()
|
||
|
localHosts := make([]net.IP, 0)
|
||
|
for _, lAddr := range localAddrs {
|
||
|
if _, err := lAddr.ValueForProtocol(ma.P_CIRCUIT); err != nil && manet.IsPublicAddr(lAddr) {
|
||
|
lIP, err := manet.ToIP(lAddr)
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
localHosts = append(localHosts, lIP)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if a public IP of the peer is one of ours: skip the peer.
|
||
|
goodPublic := false
|
||
|
for _, addr := range addrs {
|
||
|
if _, err := addr.ValueForProtocol(ma.P_CIRCUIT); err != nil && manet.IsPublicAddr(addr) {
|
||
|
aIP, err := manet.ToIP(addr)
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
for _, lIP := range localHosts {
|
||
|
if lIP.Equal(aIP) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
goodPublic = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if d.allowSelfDials {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
return !goodPublic
|
||
|
}
|