-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(network): check connection threshold on gater (#803)
- Loading branch information
Showing
9 changed files
with
266 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,8 +119,8 @@ func SaveTestnetConfig(path string, numValidators int) error { | |
"/dns/pactus.nodesync.top/tcp/21777/p2p/12D3KooWP25ejVsd7cL5DvWAPwEu4JTUwnPniHBf4w93tgSezVt8", // NodeSync.Top ([email protected]) | ||
"/ip4/95.217.89.202/tcp/21777/p2p/12D3KooWMsi5oYkbbpyyXctmPXzF8UZu2pCvKPRZGyvymhN9BzTD", // CodeBlockLabs ([email protected]) | ||
} | ||
conf.Network.MinConns = 8 | ||
conf.Network.MaxConns = 16 | ||
conf.Network.MinConns = 16 | ||
conf.Network.MaxConns = 32 | ||
conf.Network.EnableNAT = false | ||
conf.Network.EnableRelay = false | ||
conf.Network.RelayAddrStrings = []string{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,108 @@ | ||
package network | ||
|
||
import ( | ||
"sync" | ||
|
||
lp2pconnmgr "github.com/libp2p/go-libp2p/core/connmgr" | ||
lp2pcontrol "github.com/libp2p/go-libp2p/core/control" | ||
lp2pnetwork "github.com/libp2p/go-libp2p/core/network" | ||
lp2ppeer "github.com/libp2p/go-libp2p/core/peer" | ||
lp2pconngater "github.com/libp2p/go-libp2p/p2p/net/conngater" | ||
"github.com/multiformats/go-multiaddr" | ||
"github.com/pactus-project/pactus/util/logger" | ||
) | ||
|
||
var _ lp2pconnmgr.ConnectionGater = &ConnectionGater{} | ||
|
||
type ConnectionGater struct { | ||
*lp2pconngater.BasicConnectionGater | ||
logger *logger.SubLogger | ||
lk sync.RWMutex | ||
|
||
filters *multiaddr.Filters | ||
peerMgr *peerMgr | ||
maxConn int | ||
logger *logger.SubLogger | ||
} | ||
|
||
func NewConnectionGater(conf *Config, log *logger.SubLogger) (*ConnectionGater, error) { | ||
connGater, err := lp2pconngater.NewBasicConnectionGater(nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
filters := multiaddr.NewFilters() | ||
if !conf.ForcePrivateNetwork { | ||
privateSubnets := PrivateSubnets() | ||
for _, sn := range privateSubnets { | ||
err := connGater.BlockSubnet(sn) | ||
if err != nil { | ||
return nil, LibP2PError{Err: err} | ||
} | ||
} | ||
filters = SubnetsToFilters(privateSubnets, multiaddr.ActionDeny) | ||
} | ||
|
||
return &ConnectionGater{ | ||
BasicConnectionGater: connGater, | ||
logger: log, | ||
filters: filters, | ||
maxConn: conf.MaxConns, | ||
logger: log, | ||
}, nil | ||
} | ||
|
||
func (g *ConnectionGater) InterceptPeerDial(p lp2ppeer.ID) bool { | ||
allow := g.BasicConnectionGater.InterceptPeerDial(p) | ||
if !allow { | ||
g.logger.Debug("InterceptPeerDial not allowed", "p") | ||
func (g *ConnectionGater) SetPeerManager(peerMgr *peerMgr) { | ||
g.lk.Lock() | ||
defer g.lk.Unlock() | ||
|
||
g.peerMgr = peerMgr | ||
} | ||
|
||
func (g *ConnectionGater) hasMaxConnections() bool { | ||
if g.peerMgr == nil { | ||
return false | ||
} | ||
|
||
return allow | ||
return g.peerMgr.NumOfConnected() > g.maxConn | ||
} | ||
|
||
func (g *ConnectionGater) InterceptAddrDial(p lp2ppeer.ID, ma multiaddr.Multiaddr) bool { | ||
allow := g.BasicConnectionGater.InterceptAddrDial(p, ma) | ||
if !allow { | ||
g.logger.Debug("InterceptAddrDial not allowed", "p", p, "ma", ma.String()) | ||
func (g *ConnectionGater) InterceptPeerDial(pid lp2ppeer.ID) bool { | ||
g.lk.RLock() | ||
defer g.lk.RUnlock() | ||
|
||
if g.hasMaxConnections() { | ||
g.logger.Debug("InterceptPeerDial rejected: many connections", "pid", pid) | ||
return false | ||
} | ||
|
||
return allow | ||
return true | ||
} | ||
|
||
func (g *ConnectionGater) InterceptAccept(cma lp2pnetwork.ConnMultiaddrs) bool { | ||
allow := g.BasicConnectionGater.InterceptAccept(cma) | ||
if !allow { | ||
g.logger.Debug("InterceptAccept not allowed") | ||
func (g *ConnectionGater) InterceptAddrDial(pid lp2ppeer.ID, ma multiaddr.Multiaddr) bool { | ||
g.lk.RLock() | ||
defer g.lk.RUnlock() | ||
|
||
if g.hasMaxConnections() { | ||
g.logger.Debug("InterceptAddrDial rejected: many connections", "pid", pid, "ma", ma.String()) | ||
return false | ||
} | ||
|
||
deny := g.filters.AddrBlocked(ma) | ||
if deny { | ||
g.logger.Debug("InterceptAddrDial rejected", "pid", pid, "ma", ma.String()) | ||
return false | ||
} | ||
|
||
return allow | ||
return true | ||
} | ||
|
||
func (g *ConnectionGater) InterceptSecured(dir lp2pnetwork.Direction, p lp2ppeer.ID, | ||
cma lp2pnetwork.ConnMultiaddrs, | ||
) bool { | ||
allow := g.BasicConnectionGater.InterceptSecured(dir, p, cma) | ||
if !allow { | ||
g.logger.Debug("InterceptSecured not allowed", "p", p) | ||
func (g *ConnectionGater) InterceptAccept(cma lp2pnetwork.ConnMultiaddrs) bool { | ||
g.lk.RLock() | ||
defer g.lk.RUnlock() | ||
|
||
if g.hasMaxConnections() { | ||
g.logger.Debug("InterceptAccept rejected: many connections") | ||
return false | ||
} | ||
|
||
return allow | ||
deny := g.filters.AddrBlocked(cma.RemoteMultiaddr()) | ||
if deny { | ||
g.logger.Debug("InterceptAccept rejected") | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
func (g *ConnectionGater) InterceptSecured(_ lp2pnetwork.Direction, _ lp2ppeer.ID, _ lp2pnetwork.ConnMultiaddrs) bool { | ||
return true | ||
} | ||
|
||
func (g *ConnectionGater) InterceptUpgraded(con lp2pnetwork.Conn) (bool, lp2pcontrol.DisconnectReason) { | ||
return g.BasicConnectionGater.InterceptUpgraded(con) | ||
func (g *ConnectionGater) InterceptUpgraded(_ lp2pnetwork.Conn) (bool, lp2pcontrol.DisconnectReason) { | ||
return true, 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,83 @@ | ||
package network | ||
|
||
import ( | ||
"testing" | ||
|
||
lp2pnet "github.com/libp2p/go-libp2p/core/network" | ||
"github.com/multiformats/go-multiaddr" | ||
"github.com/pactus-project/pactus/util/testsuite" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
type mockConnMultiaddrs struct { | ||
remote multiaddr.Multiaddr | ||
} | ||
|
||
func (cma *mockConnMultiaddrs) LocalMultiaddr() multiaddr.Multiaddr { | ||
return nil | ||
} | ||
|
||
func (cma *mockConnMultiaddrs) RemoteMultiaddr() multiaddr.Multiaddr { | ||
return cma.remote | ||
} | ||
|
||
func TestAllowedConnections(t *testing.T) { | ||
ts := testsuite.NewTestSuite(t) | ||
conf := testConfig() | ||
net := makeTestNetwork(t, conf, nil) | ||
|
||
maPrivate := multiaddr.StringCast("/ip4/127.0.0.1/tcp/1234") | ||
maPublic := multiaddr.StringCast("/ip4/8.8.8.8/tcp/1234") | ||
cmaPrivate := &mockConnMultiaddrs{remote: maPrivate} | ||
cmaPublic := &mockConnMultiaddrs{remote: maPublic} | ||
pid := ts.RandPeerID() | ||
|
||
assert.True(t, net.connGater.InterceptPeerDial(pid)) | ||
assert.True(t, net.connGater.InterceptAddrDial(pid, maPrivate)) | ||
assert.True(t, net.connGater.InterceptAddrDial(pid, maPublic)) | ||
assert.True(t, net.connGater.InterceptAccept(cmaPrivate)) | ||
assert.True(t, net.connGater.InterceptAccept(cmaPublic)) | ||
} | ||
|
||
func TestDenyPrivate(t *testing.T) { | ||
ts := testsuite.NewTestSuite(t) | ||
conf := testConfig() | ||
conf.ForcePrivateNetwork = false | ||
net := makeTestNetwork(t, conf, nil) | ||
|
||
maPrivate := multiaddr.StringCast("/ip4/127.0.0.1/tcp/1234") | ||
maPublic := multiaddr.StringCast("/ip4/8.8.8.8/tcp/1234") | ||
cmaPrivate := &mockConnMultiaddrs{remote: maPrivate} | ||
cmaPublic := &mockConnMultiaddrs{remote: maPublic} | ||
pid := ts.RandPeerID() | ||
|
||
assert.True(t, net.connGater.InterceptPeerDial(pid)) | ||
assert.False(t, net.connGater.InterceptAddrDial(pid, maPrivate)) | ||
assert.True(t, net.connGater.InterceptAddrDial(pid, maPublic)) | ||
assert.False(t, net.connGater.InterceptAccept(cmaPrivate)) | ||
assert.True(t, net.connGater.InterceptAccept(cmaPublic)) | ||
} | ||
|
||
func TestMaxConnection(t *testing.T) { | ||
ts := testsuite.NewTestSuite(t) | ||
conf := testConfig() | ||
conf.MaxConns = 1 | ||
net := makeTestNetwork(t, conf, nil) | ||
|
||
maPrivate := multiaddr.StringCast("/ip4/127.0.0.1/tcp/1234") | ||
maPublic := multiaddr.StringCast("/ip4/8.8.8.8/tcp/1234") | ||
cmaPrivate := &mockConnMultiaddrs{remote: maPrivate} | ||
cmaPublic := &mockConnMultiaddrs{remote: maPublic} | ||
pid := ts.RandPeerID() | ||
|
||
net.peerMgr.AddPeer(ts.RandPeerID(), | ||
multiaddr.StringCast("/ip4/2.2.2.2/tcp/1234"), lp2pnet.DirInbound, nil) | ||
net.peerMgr.AddPeer(ts.RandPeerID(), | ||
multiaddr.StringCast("/ip4/3.3.3.3/tcp/1234"), lp2pnet.DirInbound, nil) | ||
|
||
assert.False(t, net.connGater.InterceptPeerDial(pid)) | ||
assert.False(t, net.connGater.InterceptAddrDial(pid, maPrivate)) | ||
assert.False(t, net.connGater.InterceptAddrDial(pid, maPublic)) | ||
assert.False(t, net.connGater.InterceptAccept(cmaPrivate)) | ||
assert.False(t, net.connGater.InterceptAccept(cmaPublic)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.