diff --git a/config/config.go b/config/config.go index 5b499611e..ff4fae23b 100644 --- a/config/config.go +++ b/config/config.go @@ -32,15 +32,16 @@ import ( ) const ( - defaultConfigFilename = "btcd.conf" - defaultDataDirname = "data" - defaultLogLevel = "info" - defaultLogDirname = "logs" - defaultLogFilename = "btcd.log" - defaultErrLogFilename = "btcd_err.log" - defaultMaxPeers = 125 - defaultBanDuration = time.Hour * 24 - defaultBanThreshold = 100 + defaultConfigFilename = "btcd.conf" + defaultDataDirname = "data" + defaultLogLevel = "info" + defaultLogDirname = "logs" + defaultLogFilename = "btcd.log" + defaultErrLogFilename = "btcd_err.log" + defaultTargetOutboundPeers = 8 + defaultMaxInboundPeers = 117 + defaultBanDuration = time.Hour * 24 + defaultBanThreshold = 100 //DefaultConnectTimeout is the default connection timeout when dialing DefaultConnectTimeout = time.Second * 30 defaultMaxRPCClients = 10 @@ -101,7 +102,8 @@ type Flags struct { 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"` 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"` 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."` @@ -296,7 +298,8 @@ func loadConfig() (*Config, []string, error) { cfgFlags := Flags{ ConfigFile: defaultConfigFile, DebugLevel: defaultLogLevel, - MaxPeers: defaultMaxPeers, + TargetOutboundPeers: defaultTargetOutboundPeers, + MaxInboundPeers: defaultMaxInboundPeers, BanDuration: defaultBanDuration, BanThreshold: defaultBanThreshold, RPCMaxClients: defaultMaxRPCClients, diff --git a/connmgr/connmanager.go b/connmgr/connmanager.go index a345ff77a..b90789cb3 100644 --- a/connmgr/connmanager.go +++ b/connmgr/connmanager.go @@ -40,9 +40,9 @@ var ( //ErrDialNil is used to indicate that Dial cannot be nil in the configuration. 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. - 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 // connected. diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index e74544749..01ab892b2 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -53,9 +53,6 @@ const ( // required to be supported by outbound peers. 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 // retries when connecting to persistent peers. It is adjusted by the // 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. 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) } @@ -693,12 +698,10 @@ func (s *Server) handleAddPeerMsg(state *peerState, sp *Peer) bool { // TODO: Check for max peers from a single IP. // Limit max number of total peers. - if state.Count() >= config.ActiveConfig().MaxPeers { - srvrLog.Infof("Max peers reached [%d] - disconnecting peer %s", - config.ActiveConfig().MaxPeers, sp) + if sp.Inbound() && len(state.inboundPeers) >= config.ActiveConfig().MaxInboundPeers { + srvrLog.Infof("Max inbound peers reached [%d] - disconnecting peer %s", + config.ActiveConfig().MaxInboundPeers, sp) sp.Disconnect() - // TODO: how to handle permanent peers here? - // they should be rescheduled. return false } @@ -944,8 +947,8 @@ func (s *Server) handleQuery(state *peerState, querymsg interface{}) { case ConnectNodeMsg: // TODO: duplicate oneshots? // Limit max number of total peers. - if state.Count() >= config.ActiveConfig().MaxPeers { - msg.Reply <- connmgr.ErrMaxPeers + if state.countOutboundPeers() >= config.ActiveConfig().TargetOutboundPeers { + msg.Reply <- connmgr.ErrMaxOutboundPeers return } 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{ DAGParams: dagParams, addrManager: amgr, - newPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), - donePeers: make(chan *Peer, config.ActiveConfig().MaxPeers), - banPeers: make(chan *Peer, config.ActiveConfig().MaxPeers), + newPeers: make(chan *Peer, maxPeers), + donePeers: make(chan *Peer, maxPeers), + banPeers: make(chan *Peer, maxPeers), Query: make(chan interface{}), - relayInv: make(chan relayMsg, config.ActiveConfig().MaxPeers), - broadcast: make(chan broadcastMsg, config.ActiveConfig().MaxPeers), + relayInv: make(chan relayMsg, maxPeers), + broadcast: make(chan broadcastMsg, maxPeers), quit: make(chan struct{}), 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, db: db, TimeSource: blockdag.NewMedianTime(), @@ -1734,7 +1739,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params TxMemPool: s.TxMemPool, ChainParams: s.DAGParams, DisableCheckpoints: cfg.DisableCheckpoints, - MaxPeers: cfg.MaxPeers, + MaxPeers: maxPeers, }) if err != nil { return nil, err @@ -1792,15 +1797,11 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params } // Create a connection manager. - targetOutbound := defaultTargetOutbound - if config.ActiveConfig().MaxPeers < targetOutbound { - targetOutbound = config.ActiveConfig().MaxPeers - } cmgr, err := connmgr.New(&connmgr.Config{ Listeners: listeners, OnAccept: s.inboundPeerConnected, RetryDuration: connectionRetryInterval, - TargetOutbound: uint32(targetOutbound), + TargetOutbound: uint32(config.ActiveConfig().TargetOutboundPeers), Dial: serverutils.BTCDDial, OnConnection: func(c *connmgr.ConnReq, conn net.Conn) { s.newOutboundConnection <- &outboundPeerConnectedMsg{