packages/hyprspace: prevent connection loops

This commit is contained in:
Max Headroom 2024-04-21 23:44:45 +02:00
parent 9ae4ed5ce9
commit 5d2b42f9f8
3 changed files with 59 additions and 1 deletions

View file

@ -104,6 +104,7 @@ func UpRun(r *cmd.Root, c *cmd.Sub) {
cfg.ListenAddresses, cfg.ListenAddresses,
streamHandler, streamHandler,
p2p.NewClosedCircuitRelayFilter(cfg.Peers), p2p.NewClosedCircuitRelayFilter(cfg.Peers),
p2p.NewRecursionGater(cfg),
cfg.Peers, cfg.Peers,
) )
checkErr(err) checkErr(err)

View file

@ -16,6 +16,7 @@ import (
"github.com/ipfs/boxo/routing/http/contentrouter" "github.com/ipfs/boxo/routing/http/contentrouter"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht" dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/connmgr"
"github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/network"
@ -110,7 +111,7 @@ func getExtraBootstrapNodes(addr ma.Multiaddr) (nodesList []string) {
} }
// CreateNode creates an internal Libp2p nodes and returns it and it's DHT Discovery service. // CreateNode creates an internal Libp2p nodes and returns it and it's DHT Discovery service.
func CreateNode(ctx context.Context, privateKey crypto.PrivKey, listenAddreses []ma.Multiaddr, handler network.StreamHandler, acl relay.ACLFilter, vpnPeers []config.Peer) (node host.Host, dhtOut *dht.IpfsDHT, err error) { func CreateNode(ctx context.Context, privateKey crypto.PrivKey, listenAddreses []ma.Multiaddr, handler network.StreamHandler, acl relay.ACLFilter, gater connmgr.ConnectionGater, vpnPeers []config.Peer) (node host.Host, dhtOut *dht.IpfsDHT, err error) {
maybePrivateNet := libp2p.ChainOptions() maybePrivateNet := libp2p.ChainOptions()
swarmKeyFile, ok := os.LookupEnv("HYPRSPACE_SWARM_KEY") swarmKeyFile, ok := os.LookupEnv("HYPRSPACE_SWARM_KEY")
if ok { if ok {
@ -134,6 +135,7 @@ func CreateNode(ctx context.Context, privateKey crypto.PrivKey, listenAddreses [
libp2p.Identity(privateKey), libp2p.Identity(privateKey),
libp2p.UserAgent("hyprspace"), libp2p.UserAgent("hyprspace"),
libp2p.DefaultSecurity, libp2p.DefaultSecurity,
libp2p.ConnectionGater(gater),
libp2p.NATPortMap(), libp2p.NATPortMap(),
libp2p.DefaultMuxers, libp2p.DefaultMuxers,
libp2p.Transport(libp2pquic.NewTransport), libp2p.Transport(libp2pquic.NewTransport),

View file

@ -2,11 +2,17 @@ package p2p
import ( import (
"context" "context"
"net"
"sync" "sync"
"time" "time"
"github.com/hyprspace/hyprspace/config"
"github.com/libp2p/go-libp2p/core/control"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/peer"
routedhost "github.com/libp2p/go-libp2p/p2p/host/routed" routedhost "github.com/libp2p/go-libp2p/p2p/host/routed"
ma "github.com/multiformats/go-multiaddr"
"github.com/vishvananda/netlink"
) )
type ParallelRouting struct { type ParallelRouting struct {
@ -40,3 +46,52 @@ func (pr ParallelRouting) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInf
cancelSubCtx() cancelSubCtx()
return info, nil return info, nil
} }
type RecursionGater struct {
config *config.Config
ifindex int
}
func NewRecursionGater(config *config.Config) RecursionGater {
link, err := netlink.LinkByName(config.Interface)
if err != nil {
panic(err)
}
return RecursionGater{
config: config,
ifindex: link.Attrs().Index,
}
}
func (rg RecursionGater) InterceptAddrDial(pid peer.ID, addr ma.Multiaddr) bool {
if ip4str, err := addr.ValueForProtocol(ma.P_IP4); err == nil {
ip4 := net.ParseIP(ip4str)
if rte, ok := rg.config.FindRouteForIP(ip4); ok {
if rte.Target.ID == pid {
routes, err := netlink.RouteGet(ip4)
if err == nil {
if len(routes) > 0 && routes[0].LinkIndex == rg.ifindex {
return false
}
}
}
}
}
return true
}
func (rg RecursionGater) InterceptPeerDial(pid peer.ID) bool {
return true
}
func (rg RecursionGater) InterceptAccept(addrs network.ConnMultiaddrs) bool {
return true
}
func (rg RecursionGater) InterceptSecured(direction network.Direction, pid peer.ID, addrs network.ConnMultiaddrs) bool {
return true
}
func (rg RecursionGater) InterceptUpgraded(network.Conn) (bool, control.DisconnectReason) {
return true, 0
}