From c5332537f5726610c3c1606ead8cbaa83144b537 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 10 Apr 2015 17:24:41 +0200 Subject: [PATCH] p2p: limit number of lingering inbound pre-handshake connections This is supposed to apply some back pressure so Server is not accepting more connections than it can actually handle. The current limit is 50. This doesn't really need to be configurable, but we'll see how it behaves in our test nodes and adjust accordingly. --- p2p/server.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/p2p/server.go b/p2p/server.go index 7b880f77b4..5cd3dc2adf 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -21,6 +21,11 @@ const ( defaultDialTimeout = 10 * time.Second refreshPeersInterval = 30 * time.Second + // This is the maximum number of inbound connection + // that are allowed to linger between 'accepted' and + // 'added as peer'. + maxAcceptConns = 50 + // total timeout for encryption handshake and protocol // handshake in both directions. handshakeTimeout = 5 * time.Second @@ -269,15 +274,28 @@ func (srv *Server) Self() *discover.Node { // main loop for adding connections via listening func (srv *Server) listenLoop() { defer srv.loopWG.Done() + + // This channel acts as a semaphore limiting + // active inbound connections that are lingering pre-handshake. + // If all slots are taken, no further connections are accepted. + slots := make(chan struct{}, maxAcceptConns) + for i := 0; i < maxAcceptConns; i++ { + slots <- struct{}{} + } + glog.V(logger.Info).Infoln("Listening on", srv.listener.Addr()) for { + <-slots conn, err := srv.listener.Accept() if err != nil { return } glog.V(logger.Debug).Infof("Accepted conn %v\n", conn.RemoteAddr()) srv.peerWG.Add(1) - go srv.startPeer(conn, nil) + go func() { + srv.startPeer(conn, nil) + slots <- struct{}{} + }() } }