[NOD-479] Separate max outbound connections and max inbound connections (#509)

* [NOD-479] Separate max outbound connections and max inbound connections

* [NOD-479] Fix merge

* [NOD-479] Renames and add function countinboundPeers

* [NOD-479] Remove redundant check on maximum outbound peers

* [NOD-479] Rename countinboundPeers -> countInboundPeers
This commit is contained in:
Ori Newman 2019-12-03 12:27:49 +02:00 committed by stasatdaglabs
parent bcd73012de
commit 9cc2a7260b
3 changed files with 40 additions and 36 deletions

View File

@ -32,15 +32,16 @@ import (
) )
const ( const (
defaultConfigFilename = "btcd.conf" defaultConfigFilename = "btcd.conf"
defaultDataDirname = "data" defaultDataDirname = "data"
defaultLogLevel = "info" defaultLogLevel = "info"
defaultLogDirname = "logs" defaultLogDirname = "logs"
defaultLogFilename = "btcd.log" defaultLogFilename = "btcd.log"
defaultErrLogFilename = "btcd_err.log" defaultErrLogFilename = "btcd_err.log"
defaultMaxPeers = 125 defaultTargetOutboundPeers = 8
defaultBanDuration = time.Hour * 24 defaultMaxInboundPeers = 117
defaultBanThreshold = 100 defaultBanDuration = time.Hour * 24
defaultBanThreshold = 100
//DefaultConnectTimeout is the default connection timeout when dialing //DefaultConnectTimeout is the default connection timeout when dialing
DefaultConnectTimeout = time.Second * 30 DefaultConnectTimeout = time.Second * 30
defaultMaxRPCClients = 10 defaultMaxRPCClients = 10
@ -101,7 +102,8 @@ type Flags struct {
ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"` ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"`
DisableListen bool `long:"nolisten" description:"Disable listening for incoming connections -- NOTE: Listening is automatically disabled if the --connect or --proxy options are used without also specifying listen interfaces via --listen"` DisableListen bool `long:"nolisten" description:"Disable listening for incoming connections -- NOTE: Listening is automatically disabled if the --connect or --proxy options are used without also specifying listen interfaces via --listen"`
Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"` Listeners []string `long:"listen" description:"Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: 18333)"`
MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"` TargetOutboundPeers int `long:"outpeers" description:"Target number of outbound peers"`
MaxInboundPeers int `long:"maxinpeers" description:"Max number of inbound peers"`
DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"` DisableBanning bool `long:"nobanning" description:"Disable banning of misbehaving peers"`
BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"` BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"`
BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."` BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."`
@ -296,7 +298,8 @@ func loadConfig() (*Config, []string, error) {
cfgFlags := Flags{ cfgFlags := Flags{
ConfigFile: defaultConfigFile, ConfigFile: defaultConfigFile,
DebugLevel: defaultLogLevel, DebugLevel: defaultLogLevel,
MaxPeers: defaultMaxPeers, TargetOutboundPeers: defaultTargetOutboundPeers,
MaxInboundPeers: defaultMaxInboundPeers,
BanDuration: defaultBanDuration, BanDuration: defaultBanDuration,
BanThreshold: defaultBanThreshold, BanThreshold: defaultBanThreshold,
RPCMaxClients: defaultMaxRPCClients, RPCMaxClients: defaultMaxRPCClients,

View File

@ -40,9 +40,9 @@ var (
//ErrDialNil is used to indicate that Dial cannot be nil in the configuration. //ErrDialNil is used to indicate that Dial cannot be nil in the configuration.
ErrDialNil = errors.New("Config: Dial cannot be nil") ErrDialNil = errors.New("Config: Dial cannot be nil")
// ErrMaxPeers is an error that is thrown when the max amount of peers had // ErrMaxOutboundPeers is an error that is thrown when the max amount of peers had
// been reached. // been reached.
ErrMaxPeers = errors.New("max peers reached") ErrMaxOutboundPeers = errors.New("max outbound peers reached")
// ErrAlreadyConnected is an error that is thrown if the peer is already // ErrAlreadyConnected is an error that is thrown if the peer is already
// connected. // connected.

View File

@ -53,9 +53,6 @@ const (
// required to be supported by outbound peers. // required to be supported by outbound peers.
defaultRequiredServices = wire.SFNodeNetwork defaultRequiredServices = wire.SFNodeNetwork
// defaultTargetOutbound is the default number of outbound peers to target.
defaultTargetOutbound = 8
// connectionRetryInterval is the base amount of time to wait in between // connectionRetryInterval is the base amount of time to wait in between
// retries when connecting to persistent peers. It is adjusted by the // retries when connecting to persistent peers. It is adjusted by the
// number of retries such that there is a retry backoff. // number of retries such that there is a retry backoff.
@ -191,7 +188,15 @@ type peerState struct {
// Count returns the count of all known peers. // Count returns the count of all known peers.
func (ps *peerState) Count() int { func (ps *peerState) Count() int {
return len(ps.inboundPeers) + len(ps.outboundPeers) + return ps.countInboundPeers() + ps.countOutboundPeers()
}
func (ps *peerState) countInboundPeers() int {
return len(ps.inboundPeers)
}
func (ps *peerState) countOutboundPeers() int {
return len(ps.outboundPeers) +
len(ps.persistentPeers) len(ps.persistentPeers)
} }
@ -693,12 +698,10 @@ func (s *Server) handleAddPeerMsg(state *peerState, sp *Peer) bool {
// TODO: Check for max peers from a single IP. // TODO: Check for max peers from a single IP.
// Limit max number of total peers. // Limit max number of total peers.
if state.Count() >= config.ActiveConfig().MaxPeers { if sp.Inbound() && len(state.inboundPeers) >= config.ActiveConfig().MaxInboundPeers {
srvrLog.Infof("Max peers reached [%d] - disconnecting peer %s", srvrLog.Infof("Max inbound peers reached [%d] - disconnecting peer %s",
config.ActiveConfig().MaxPeers, sp) config.ActiveConfig().MaxInboundPeers, sp)
sp.Disconnect() sp.Disconnect()
// TODO: how to handle permanent peers here?
// they should be rescheduled.
return false return false
} }
@ -944,8 +947,8 @@ func (s *Server) handleQuery(state *peerState, querymsg interface{}) {
case ConnectNodeMsg: case ConnectNodeMsg:
// TODO: duplicate oneshots? // TODO: duplicate oneshots?
// Limit max number of total peers. // Limit max number of total peers.
if state.Count() >= config.ActiveConfig().MaxPeers { if state.countOutboundPeers() >= config.ActiveConfig().TargetOutboundPeers {
msg.Reply <- connmgr.ErrMaxPeers msg.Reply <- connmgr.ErrMaxOutboundPeers
return return
} }
for _, peer := range state.persistentPeers { for _, peer := range state.persistentPeers {
@ -1619,18 +1622,20 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
} }
} }
maxPeers := config.ActiveConfig().TargetOutboundPeers + config.ActiveConfig().MaxInboundPeers
s := Server{ s := Server{
DAGParams: dagParams, DAGParams: dagParams,
addrManager: amgr, addrManager: amgr,
newPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), newPeers: make(chan *Peer, maxPeers),
donePeers: make(chan *Peer, config.ActiveConfig().MaxPeers), donePeers: make(chan *Peer, maxPeers),
banPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), banPeers: make(chan *Peer, maxPeers),
Query: make(chan interface{}), Query: make(chan interface{}),
relayInv: make(chan relayMsg, config.ActiveConfig().MaxPeers), relayInv: make(chan relayMsg, maxPeers),
broadcast: make(chan broadcastMsg, config.ActiveConfig().MaxPeers), broadcast: make(chan broadcastMsg, maxPeers),
quit: make(chan struct{}), quit: make(chan struct{}),
modifyRebroadcastInv: make(chan interface{}), modifyRebroadcastInv: make(chan interface{}),
newOutboundConnection: make(chan *outboundPeerConnectedMsg, config.ActiveConfig().MaxPeers), // TODO: replace with target outbound newOutboundConnection: make(chan *outboundPeerConnectedMsg, config.ActiveConfig().TargetOutboundPeers),
nat: nat, nat: nat,
db: db, db: db,
TimeSource: blockdag.NewMedianTime(), TimeSource: blockdag.NewMedianTime(),
@ -1734,7 +1739,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
TxMemPool: s.TxMemPool, TxMemPool: s.TxMemPool,
ChainParams: s.DAGParams, ChainParams: s.DAGParams,
DisableCheckpoints: cfg.DisableCheckpoints, DisableCheckpoints: cfg.DisableCheckpoints,
MaxPeers: cfg.MaxPeers, MaxPeers: maxPeers,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -1792,15 +1797,11 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
} }
// Create a connection manager. // Create a connection manager.
targetOutbound := defaultTargetOutbound
if config.ActiveConfig().MaxPeers < targetOutbound {
targetOutbound = config.ActiveConfig().MaxPeers
}
cmgr, err := connmgr.New(&connmgr.Config{ cmgr, err := connmgr.New(&connmgr.Config{
Listeners: listeners, Listeners: listeners,
OnAccept: s.inboundPeerConnected, OnAccept: s.inboundPeerConnected,
RetryDuration: connectionRetryInterval, RetryDuration: connectionRetryInterval,
TargetOutbound: uint32(targetOutbound), TargetOutbound: uint32(config.ActiveConfig().TargetOutboundPeers),
Dial: serverutils.BTCDDial, Dial: serverutils.BTCDDial,
OnConnection: func(c *connmgr.ConnReq, conn net.Conn) { OnConnection: func(c *connmgr.ConnReq, conn net.Conn) {
s.newOutboundConnection <- &outboundPeerConnectedMsg{ s.newOutboundConnection <- &outboundPeerConnectedMsg{