Skip to content

Commit

Permalink
Allow modification of dial and connection timeouts
Browse files Browse the repository at this point in the history
Now dialHistoryExpiration and inboundThrottleTime can be configured via
config. This allows for the writing of fast tests.
  • Loading branch information
piersy committed Sep 30, 2021
1 parent dbd2d69 commit 2fce4a5
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
3 changes: 3 additions & 0 deletions node/node.go
Expand Up @@ -135,6 +135,9 @@ func New(conf *Config) (*Node, error) {
if node.server.Config.NodeDatabase == "" {
node.server.Config.NodeDatabase = node.config.NodeDB()
}
if node.server.Config.InboundThrottleTime == 0 {
node.server.Config.InboundThrottleTime = p2p.InboundThrottleTime
}

if node.config.Proxy {
// Initialize the proxy p2p server. This creates the node key and
Expand Down
10 changes: 8 additions & 2 deletions p2p/dial.go
Expand Up @@ -37,7 +37,7 @@ const (
// This is the amount of time spent waiting in between redialing a certain node. The
// limit is a bit higher than inboundThrottleTime to prevent failing dials in small
// private networks.
dialHistoryExpiration = inboundThrottleTime + 10*time.Millisecond
dialHistoryExpiration = InboundThrottleTime + 5*time.Second

// Config for the "Looking for peers" message.
dialStatsLogInterval = 10 * time.Second // printed at most this often
Expand Down Expand Up @@ -139,6 +139,9 @@ type dialConfig struct {
log log.Logger
clock mclock.Clock
rand *mrand.Rand

// The time waited before redialling a certain node
dialHistoryExpiration time.Duration
}

func (cfg dialConfig) withDefaults() dialConfig {
Expand All @@ -157,6 +160,9 @@ func (cfg dialConfig) withDefaults() dialConfig {
seed := int64(binary.BigEndian.Uint64(seedb))
cfg.rand = mrand.New(mrand.NewSource(seed))
}
if cfg.dialHistoryExpiration == 0 {
cfg.dialHistoryExpiration = dialHistoryExpiration
}
return cfg
}

Expand Down Expand Up @@ -456,7 +462,7 @@ func (d *dialScheduler) removeFromStaticPool(idx int) {
func (d *dialScheduler) startDial(task *dialTask) {
d.log.Trace("Starting p2p dial", "id", task.dest.ID(), "ip", task.dest.IP(), "flag", task.flags)
hkey := string(task.dest.ID().Bytes())
d.history.add(hkey, d.clock.Now().Add(dialHistoryExpiration))
d.history.add(hkey, d.clock.Now().Add(d.dialHistoryExpiration))
d.dialing[task.dest.ID()] = task
go func() {
task.run(d)
Expand Down
28 changes: 19 additions & 9 deletions p2p/server.go
Expand Up @@ -55,7 +55,7 @@ const (
defaultDialRatio = 3

// This time limits inbound connection attempts per source IP.
inboundThrottleTime = 200 * time.Millisecond
InboundThrottleTime = 30 * time.Second

// Maximum time allowed for reading a complete message.
// This is effectively the amount of time a connection can be idle.
Expand Down Expand Up @@ -171,6 +171,15 @@ type Config struct {
Logger log.Logger `toml:",omitempty"`

clock mclock.Clock

// DialHistoryExpiration is the time waited between dialling a specific node.
DialHistoryExpiration time.Duration

// InboundThrottleTime is used to rate limit inbound connection attempts
// from a specific IP. If setting up a small private network this should
// probably be set smaller than DialHistoryExpiration to avoid lots of
// failed dial attempts.
InboundThrottleTime time.Duration
}

// Server manages all peer connections.
Expand Down Expand Up @@ -708,13 +717,14 @@ func (srv *Server) setupDiscovery() error {

func (srv *Server) setupDialScheduler() {
config := dialConfig{
self: srv.localnode.ID(),
maxDialPeers: srv.maxDialedConns(),
maxActiveDials: srv.MaxPendingPeers,
log: srv.Logger,
netRestrict: srv.NetRestrict,
dialer: srv.Dialer,
clock: srv.clock,
self: srv.localnode.ID(),
maxDialPeers: srv.maxDialedConns(),
maxActiveDials: srv.MaxPendingPeers,
log: srv.Logger,
netRestrict: srv.NetRestrict,
dialer: srv.Dialer,
clock: srv.clock,
dialHistoryExpiration: srv.DialHistoryExpiration,
}
if srv.ntab != nil {
config.resolver = srv.ntab
Expand Down Expand Up @@ -1102,7 +1112,7 @@ func (srv *Server) checkInboundConn(fd net.Conn, remoteIP net.IP) error {
if !netutil.IsLAN(remoteIP) && srv.inboundHistory.contains(remoteIP.String()) {
return fmt.Errorf("too many attempts")
}
srv.inboundHistory.add(remoteIP.String(), now.Add(inboundThrottleTime))
srv.inboundHistory.add(remoteIP.String(), now.Add(srv.InboundThrottleTime))
return nil
}

Expand Down
8 changes: 5 additions & 3 deletions test/node.go
Expand Up @@ -38,9 +38,11 @@ var (
Name: "celo",
Version: params.Version,
P2P: p2p.Config{
MaxPeers: 100,
NoDiscovery: true,
ListenAddr: "0.0.0.0:0",
MaxPeers: 100,
NoDiscovery: true,
ListenAddr: "0.0.0.0:0",
InboundThrottleTime: 200 * time.Millisecond,
DialHistoryExpiration: 210 * time.Millisecond,
},
NoUSB: true,
// It is important that HTTPHost and WSHost remain the same. This
Expand Down

0 comments on commit 2fce4a5

Please sign in to comment.