aboutsummaryrefslogtreecommitdiffstats
path: root/p2p
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-04-13 23:34:08 +0800
committerFelix Lange <fjl@twurst.com>2015-04-13 23:34:08 +0800
commit995fab2ebc3b145a1dbb85841c5241cd024362ac (patch)
tree68894e8cf4b30787ba9ebe0810d2738c7fe3fdb0 /p2p
parent79a6782c1c4a056b27d2c242f656dfcf5633ae3f (diff)
downloadgo-tangerine-995fab2ebc3b145a1dbb85841c5241cd024362ac.tar.gz
go-tangerine-995fab2ebc3b145a1dbb85841c5241cd024362ac.tar.zst
go-tangerine-995fab2ebc3b145a1dbb85841c5241cd024362ac.zip
p2p: fix yet another disconnect hang
Peer.readLoop will only terminate if the connection is closed. Fix the hang by closing the connection before waiting for readLoop to terminate. This also removes the british disconnect procedure where we're waiting for the remote end to close the connection. I have confirmed with @subtly that cpp-ethereum doesn't adhere to it either.
Diffstat (limited to 'p2p')
-rw-r--r--p2p/peer.go30
1 files changed, 8 insertions, 22 deletions
diff --git a/p2p/peer.go b/p2p/peer.go
index 7bc4f9cf6..1262ba64a 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"net"
"sort"
"sync"
@@ -20,8 +19,7 @@ const (
baseProtocolLength = uint64(16)
baseProtocolMaxMsgSize = 10 * 1024 * 1024
- pingInterval = 15 * time.Second
- disconnectGracePeriod = 2 * time.Second
+ pingInterval = 15 * time.Second
)
const (
@@ -129,39 +127,27 @@ func (p *Peer) run() DiscReason {
case err := <-readErr:
if r, ok := err.(DiscReason); ok {
reason = r
- break
+ } else {
+ // Note: We rely on protocols to abort if there is a write
+ // error. It might be more robust to handle them here as well.
+ p.DebugDetailf("Read error: %v\n", err)
+ reason = DiscNetworkError
}
- // Note: We rely on protocols to abort if there is a write
- // error. It might be more robust to handle them here as well.
- p.DebugDetailf("Read error: %v\n", err)
- p.conn.Close()
- reason = DiscNetworkError
case err := <-p.protoErr:
reason = discReasonForError(err)
case reason = <-p.disc:
}
close(p.closed)
+ p.politeDisconnect(reason)
p.wg.Wait()
- if reason != DiscNetworkError {
- p.politeDisconnect(reason)
- }
p.Debugf("Disconnected: %v\n", reason)
return reason
}
func (p *Peer) politeDisconnect(reason DiscReason) {
- done := make(chan struct{})
- go func() {
+ if reason != DiscNetworkError {
SendItems(p.rw, discMsg, uint(reason))
- // Wait for the other side to close the connection.
- // Discard any data that they send until then.
- io.Copy(ioutil.Discard, p.conn)
- close(done)
- }()
- select {
- case <-done:
- case <-time.After(disconnectGracePeriod):
}
p.conn.Close()
}