44package network
55
66import (
7+ "errors"
78 "fmt"
89 "math/rand"
910 "net"
@@ -47,6 +48,12 @@ const (
4748 defaultPingFrequency = 3 * defaultPingPongTimeout / 4
4849)
4950
51+ var (
52+ errNetworkClosed = errors .New ("network closed" )
53+ errPeerIsMyself = errors .New ("peer is myself" )
54+ errDuplicatedConnection = errors .New ("duplicated connection" )
55+ )
56+
5057func init () { rand .Seed (time .Now ().UnixNano ()) }
5158
5259// Network defines the functionality of the networking library.
@@ -635,15 +642,15 @@ func (n *network) Dispatch() error {
635642 for {
636643 conn , err := n .listener .Accept ()
637644 if err != nil {
638- n .stateLock .Lock ()
639- closed := n .closed
640- n .stateLock .Unlock ()
641-
642- if closed {
643- return err
645+ if netErr , ok := err .(net.Error ); ok && netErr .Temporary () {
646+ // Sleep for a small amount of time to try to wait for the
647+ // temporary error to go away.
648+ time .Sleep (time .Millisecond )
649+ continue
644650 }
651+
645652 n .log .Debug ("error during server accept: %s" , err )
646- continue
653+ return err
647654 }
648655 go n .upgrade (& peer {
649656 net : n ,
@@ -675,17 +682,17 @@ func (n *network) Peers() []PeerID {
675682
676683// Close implements the Network interface
677684func (n * network ) Close () error {
685+ err := n .listener .Close ()
686+ if err != nil {
687+ n .log .Debug ("closing network listener failed with: %s" , err )
688+ }
689+
678690 n .stateLock .Lock ()
679691 if n .closed {
680692 n .stateLock .Unlock ()
681693 return nil
682694 }
683-
684695 n .closed = true
685- err := n .listener .Close ()
686- if err != nil {
687- n .log .Debug ("closing network listener failed with: %s" , err )
688- }
689696
690697 peersToClose := []* peer (nil )
691698 for _ , peer := range n .peers {
@@ -935,21 +942,28 @@ func (n *network) upgrade(p *peer, upgrader Upgrader) error {
935942 p .id = id
936943 p .conn = conn
937944
938- key := id .Key ()
945+ if err := n .tryAddPeer (p ); err != nil {
946+ _ = p .conn .Close ()
947+ n .log .Debug ("dropping peer connection due to: %s" , err )
948+ }
949+ return nil
950+ }
951+
952+ func (n * network ) tryAddPeer (p * peer ) error {
953+ key := p .id .Key ()
939954
940955 n .stateLock .Lock ()
941956 defer n .stateLock .Unlock ()
942957
943958 if n .closed {
944959 // the network is closing, so make sure that no further reconnect
945960 // attempts are made.
946- _ = p .conn .Close ()
947- return nil
961+ return errNetworkClosed
948962 }
949963
950964 // if this connection is myself, then I should delete the connection and
951965 // mark the IP as one of mine.
952- if id .Equals (n .id ) {
966+ if p . id .Equals (n .id ) {
953967 if ! p .ip .IsZero () {
954968 // if n.ip is less useful than p.ip set it to this IP
955969 if n .ip .IsZero () {
@@ -962,10 +976,7 @@ func (n *network) upgrade(p *peer, upgrader Upgrader) error {
962976 delete (n .retryDelay , str )
963977 n .myIPs [str ] = struct {}{}
964978 }
965- // don't attempt to reconnect to myself, so return nil even if closing
966- // returns an error
967- _ = p .conn .Close ()
968- return nil
979+ return errPeerIsMyself
969980 }
970981
971982 // If I am already connected to this peer, then I should close this new
@@ -976,10 +987,7 @@ func (n *network) upgrade(p *peer, upgrader Upgrader) error {
976987 delete (n .disconnectedIPs , str )
977988 delete (n .retryDelay , str )
978989 }
979- // I'm already connected to this peer, so don't attempt to reconnect to
980- // this ip, even if an error occurres during closing
981- _ = p .conn .Close ()
982- return nil
990+ return errDuplicatedConnection
983991 }
984992
985993 n .peers [key ] = p
0 commit comments