[caplin] conn gater (#7900)

conn gater


so this is what prysm did to address the issue
https://github.com/prysmaticlabs/prysm/pull/8648/files
This commit is contained in:
a 2023-07-16 01:31:06 -05:00 committed by GitHub
parent 735a800eb7
commit 19bc41198e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 172 additions and 15 deletions

View File

@ -33,6 +33,7 @@ type ConsensusClientCliCfg struct {
ServerTcpPort uint `json:"serverTcpPort"`
LogLvl uint `json:"logLevel"`
NoDiscovery bool `json:"noDiscovery"`
LocalDiscovery bool `json:"localDiscovery"`
CheckpointUri string `json:"checkpointUri"`
Chaindata string `json:"chaindata"`
ErigonPrivateApi string `json:"erigonPrivateApi"`
@ -117,6 +118,7 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) {
cfg.LogLvl = uint(log.LvlDebug)
}
cfg.NoDiscovery = ctx.Bool(flags.NoDiscovery.Name)
cfg.LocalDiscovery = ctx.Bool(flags.LocalDiscovery.Name)
if ctx.String(flags.CheckpointSyncUrlFlag.Name) != "" {
cfg.CheckpointUri = ctx.String(flags.CheckpointSyncUrlFlag.Name)
} else {

View File

@ -80,6 +80,11 @@ var (
Usage: "turn off or on the lightclient finding peers",
Value: false,
}
LocalDiscovery = cli.BoolFlag{
Name: "local-discovery",
Usage: "enable to also attempt to find peers over private ips. turning this on may cause issues with hosts such as hetzner",
Value: false,
}
ChaindataFlag = cli.StringFlag{
Name: "chaindata",
Usage: "chaindata of database",

View File

@ -45,13 +45,14 @@ func runSentinelNode(cliCtx *cli.Context) error {
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler))
log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg)
_, err := service.StartSentinelService(&sentinel.SentinelConfig{
IpAddr: cfg.Addr,
Port: int(cfg.Port),
TCPPort: cfg.ServerTcpPort,
GenesisConfig: cfg.GenesisCfg,
NetworkConfig: cfg.NetworkCfg,
BeaconConfig: cfg.BeaconCfg,
NoDiscovery: cfg.NoDiscovery,
IpAddr: cfg.Addr,
Port: int(cfg.Port),
TCPPort: cfg.ServerTcpPort,
GenesisConfig: cfg.GenesisCfg,
NetworkConfig: cfg.NetworkCfg,
BeaconConfig: cfg.BeaconCfg,
NoDiscovery: cfg.NoDiscovery,
LocalDiscovery: cfg.LocalDiscovery,
}, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, nil, log.Root())
if err != nil {
log.Error("[Sentinel] Could not start sentinel", "err", err)

View File

@ -36,13 +36,14 @@ type SentinelConfig struct {
Port int
TCPPort uint
// Optional
LocalIP string
EnableUPnP bool
RelayNodeAddr string
HostAddress string
HostDNS string
NoDiscovery bool
TmpDir string
LocalIP string
EnableUPnP bool
RelayNodeAddr string
HostAddress string
HostDNS string
NoDiscovery bool
TmpDir string
LocalDiscovery bool
}
func convertToCryptoPrivkey(privkey *ecdsa.PrivateKey) (crypto.PrivKey, error) {

View File

@ -0,0 +1,139 @@
package sentinel
import (
"net"
"github.com/libp2p/go-libp2p/core/control"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)
var privateCIDRList = []string{
// https://tools.ietf.org/html/rfc1918
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
// https://tools.ietf.org/html/rfc6598
"100.64.0.0/10",
// https://tools.ietf.org/html/rfc3927
"169.254.0.0/16",
}
type Gater struct {
filter *multiaddr.Filters
}
func NewGater(cfg *SentinelConfig) (g *Gater, err error) {
g = &Gater{}
g.filter, err = configureFilter(cfg)
if err != nil {
return nil, err
}
return g, nil
}
// InterceptPeerDial tests whether we're permitted to Dial the specified peer.
// This is called by the network.Network implementation when dialling a peer.
func (g *Gater) InterceptPeerDial(p peer.ID) (allow bool) {
return true
}
// InterceptAddrDial tests whether we're permitted to dial the specified
// multiaddr for the given peer.
//
// This is called by the network.Network implementation after it has
// resolved the peer's addrs, and prior to dialling each.
func (g *Gater) InterceptAddrDial(_ peer.ID, n multiaddr.Multiaddr) (allow bool) {
return filterConnections(g.filter, n)
}
// InterceptAccept tests whether an incipient inbound connection is allowed.
//
// This is called by the upgrader, or by the transport directly (e.g. QUIC,
// Bluetooth), straight after it has accepted a connection from its socket.
func (g *Gater) InterceptAccept(n network.ConnMultiaddrs) (allow bool) {
return filterConnections(g.filter, n.RemoteMultiaddr())
}
// InterceptSecured tests whether a given connection, now authenticated,
// is allowed.
//
// This is called by the upgrader, after it has performed the security
// handshake, and before it negotiates the muxer, or by the directly by the
// transport, at the exact same checkpoint.
func (g *Gater) InterceptSecured(_ network.Direction, _ peer.ID, _ network.ConnMultiaddrs) (allow bool) {
return true
}
// InterceptUpgraded tests whether a fully capable connection is allowed.
//
// At this point, the connection a multiplexer has been selected.
// When rejecting a connection, the gater can return a DisconnectReason.
// Refer to the godoc on the ConnectionGater type for more information.
//
// NOTE: the go-libp2p implementation currently IGNORES the disconnect reason.
func (g *Gater) InterceptUpgraded(_ network.Conn) (allow bool, reason control.DisconnectReason) {
return true, 0
}
func filterConnections(f *multiaddr.Filters, a multiaddr.Multiaddr) bool {
acceptedNets := f.FiltersForAction(multiaddr.ActionAccept)
restrictConns := len(acceptedNets) != 0
// If we have an allow list added in, we by default reject all
// connection attempts except for those coming in from the
// appropriate ip subnets.
if restrictConns {
ip, err := manet.ToIP(a)
if err != nil {
return false
}
found := false
for _, ipnet := range acceptedNets {
if ipnet.Contains(ip) {
found = true
break
}
}
return found
}
return !f.AddrBlocked(a)
}
func configureFilter(cfg *SentinelConfig) (*multiaddr.Filters, error) {
var err error
addrFilter := multiaddr.NewFilters()
if !cfg.LocalDiscovery {
addrFilter, err = privateCIDRFilter(addrFilter, multiaddr.ActionDeny)
if err != nil {
return nil, err
}
}
return addrFilter, nil
}
// helper function to either accept or deny all private addresses
// if a new rule for a private address is in conflict with a previous one, log a warning
func privateCIDRFilter(addrFilter *multiaddr.Filters, action multiaddr.Action) (*multiaddr.Filters, error) {
for _, privCidr := range privateCIDRList {
_, ipnet, err := net.ParseCIDR(privCidr)
if err != nil {
return nil, err
}
// curAction, _ := addrFilter.ActionForFilter(*ipnet)
// switch {
// case action == multiaddr.ActionAccept:
// if curAction == multiaddr.ActionDeny {
// // rule conflict
// }
// case action == multiaddr.ActionDeny:
// if curAction == multiaddr.ActionAccept {
// // rule conflict
// }
// }
addrFilter.AddFilter(*ipnet, action)
}
return addrFilter, nil
}

View File

@ -276,6 +276,14 @@ func New(
}
opts = append(opts, libp2p.ResourceManager(rmgr))
}
gater, err := NewGater(cfg)
if err != nil {
return nil, err
}
opts = append(opts, libp2p.ConnectionGater(gater))
host, err := libp2p.New(opts...)
if err != nil {
return nil, err

View File

@ -105,7 +105,8 @@ func sntpDrift(measurements int) (time.Duration, error) {
nanosec := sec*1e9 + (frac*1e9)>>32
t := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nanosec)).Local()
// nolint:gosmopolitan
t := time.Date(1900, 1, 1, 0, 0, 0, 0, time.Local).Add(time.Duration(nanosec))
// Calculate the drift based on an assumed answer time of RRT/2
drifts = append(drifts, sent.Sub(t)+elapsed/2)