Merge pull request #4849 from filecoin-project/feat/conngater
Connection Gater support
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/libp2p/go-libp2p-peerstore/pstoremem"
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
record "github.com/libp2p/go-libp2p-record"
|
||||
"github.com/libp2p/go-libp2p/p2p/net/conngater"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -98,6 +99,7 @@ var (
|
||||
ConnectionManagerKey = special{9} // Libp2p option
|
||||
AutoNATSvcKey = special{10} // Libp2p option
|
||||
BandwidthReporterKey = special{11} // Libp2p option
|
||||
ConnGaterKey = special{12} // libp2p option
|
||||
)
|
||||
|
||||
type invoke int
|
||||
@@ -220,6 +222,9 @@ func libp2p() Option {
|
||||
|
||||
Override(PstoreAddSelfKeysKey, lp2p.PstoreAddSelfKeys),
|
||||
Override(StartListeningKey, lp2p.StartListening(config.DefaultFullNode().Libp2p.ListenAddresses)),
|
||||
|
||||
Override(new(*conngater.BasicConnectionGater), lp2p.ConnGater),
|
||||
Override(ConnGaterKey, lp2p.ConnGaterOption),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
swarm "github.com/libp2p/go-libp2p-swarm"
|
||||
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
"github.com/libp2p/go-libp2p/p2p/net/conngater"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"go.uber.org/fx"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -36,6 +37,7 @@ type CommonAPI struct {
|
||||
RawHost lp2p.RawHost
|
||||
Host host.Host
|
||||
Router lp2p.BaseIpfsRouting
|
||||
ConnGater *conngater.BasicConnectionGater
|
||||
Reporter metrics.Reporter
|
||||
Sk *dtypes.ScoreKeeper
|
||||
ShutdownChan dtypes.ShutdownChan
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
)
|
||||
|
||||
var cLog = logging.Logger("conngater")
|
||||
|
||||
func (a *CommonAPI) NetBlockAdd(ctx context.Context, acl api.NetBlockList) error {
|
||||
for _, p := range acl.Peers {
|
||||
err := a.ConnGater.BlockPeer(p)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error blocking peer %s: %w", p, err)
|
||||
}
|
||||
|
||||
for _, c := range a.Host.Network().ConnsToPeer(p) {
|
||||
err = c.Close()
|
||||
if err != nil {
|
||||
// just log this, don't fail
|
||||
cLog.Warnf("error closing connection to %s: %s", p, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, addr := range acl.IPAddrs {
|
||||
ip := net.ParseIP(addr)
|
||||
if ip == nil {
|
||||
return xerrors.Errorf("error parsing IP address %s", addr)
|
||||
}
|
||||
|
||||
err := a.ConnGater.BlockAddr(ip)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error blocking IP address %s: %w", addr, err)
|
||||
}
|
||||
|
||||
for _, c := range a.Host.Network().Conns() {
|
||||
remote := c.RemoteMultiaddr()
|
||||
remoteIP, err := manet.ToIP(remote)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if ip.Equal(remoteIP) {
|
||||
err = c.Close()
|
||||
if err != nil {
|
||||
// just log this, don't fail
|
||||
cLog.Warnf("error closing connection to %s: %s", remoteIP, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, subnet := range acl.IPSubnets {
|
||||
_, cidr, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error parsing subnet %s: %w", subnet, err)
|
||||
}
|
||||
|
||||
err = a.ConnGater.BlockSubnet(cidr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error blocking subunet %s: %w", subnet, err)
|
||||
}
|
||||
|
||||
for _, c := range a.Host.Network().Conns() {
|
||||
remote := c.RemoteMultiaddr()
|
||||
remoteIP, err := manet.ToIP(remote)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if cidr.Contains(remoteIP) {
|
||||
err = c.Close()
|
||||
if err != nil {
|
||||
// just log this, don't fail
|
||||
cLog.Warnf("error closing connection to %s: %s", remoteIP, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *CommonAPI) NetBlockRemove(ctx context.Context, acl api.NetBlockList) error {
|
||||
for _, p := range acl.Peers {
|
||||
err := a.ConnGater.UnblockPeer(p)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error unblocking peer %s: %w", p, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, addr := range acl.IPAddrs {
|
||||
ip := net.ParseIP(addr)
|
||||
if ip == nil {
|
||||
return xerrors.Errorf("error parsing IP address %s", addr)
|
||||
}
|
||||
|
||||
err := a.ConnGater.UnblockAddr(ip)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error unblocking IP address %s: %w", addr, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, subnet := range acl.IPSubnets {
|
||||
_, cidr, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error parsing subnet %s: %w", subnet, err)
|
||||
}
|
||||
|
||||
err = a.ConnGater.UnblockSubnet(cidr)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error unblocking subunet %s: %w", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *CommonAPI) NetBlockList(ctx context.Context) (result api.NetBlockList, err error) {
|
||||
result.Peers = a.ConnGater.ListBlockedPeers()
|
||||
for _, ip := range a.ConnGater.ListBlockedAddrs() {
|
||||
result.IPAddrs = append(result.IPAddrs, ip.String())
|
||||
}
|
||||
for _, subnet := range a.ConnGater.ListBlockedSubnets() {
|
||||
result.IPSubnets = append(result.IPSubnets, subnet.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package lp2p
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p/p2p/net/conngater"
|
||||
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
)
|
||||
|
||||
func ConnGater(ds dtypes.MetadataDS) (*conngater.BasicConnectionGater, error) {
|
||||
return conngater.NewBasicConnectionGater(ds)
|
||||
}
|
||||
|
||||
func ConnGaterOption(cg *conngater.BasicConnectionGater) (opts Libp2pOpts, err error) {
|
||||
opts.Opts = append(opts.Opts, libp2p.ConnectionGater(cg))
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user