aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-10-24 07:43:10 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-10-24 07:43:10 +0800
commitc43db8a2ee99df6649d017772e1eb70cc9842c6c (patch)
tree0cc915c81e8b26921bb1190e9edea9b03c73914b
parent0aeab5fd83acae44e63840bf5a20834e5b52ae78 (diff)
parent3cf74336c99a8a0ee18291edd61be9c9587d3c6a (diff)
downloaddexon-c43db8a2ee99df6649d017772e1eb70cc9842c6c.tar.gz
dexon-c43db8a2ee99df6649d017772e1eb70cc9842c6c.tar.zst
dexon-c43db8a2ee99df6649d017772e1eb70cc9842c6c.zip
Merge pull request #1924 from fjl/eth-status-timeout
eth: time out status message exchange after 5s
-rw-r--r--eth/peer.go36
1 files changed, 27 insertions, 9 deletions
diff --git a/eth/peer.go b/eth/peer.go
index 68ce903a6..695e910f6 100644
--- a/eth/peer.go
+++ b/eth/peer.go
@@ -21,6 +21,7 @@ import (
"fmt"
"math/big"
"sync"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
@@ -38,8 +39,9 @@ var (
)
const (
- maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS)
- maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS)
+ maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS)
+ maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS)
+ handshakeTimeout = 5 * time.Second
)
type peer struct {
@@ -267,8 +269,8 @@ func (p *peer) RequestReceipts(hashes []common.Hash) error {
// Handshake executes the eth protocol handshake, negotiating version number,
// network IDs, difficulties, head and genesis blocks.
func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) error {
- // Send out own handshake in a new thread
- errc := make(chan error, 1)
+ errc := make(chan error, 2)
+ var status statusData // safe to read after two values have been received from errc
go func() {
errc <- p2p.Send(p.rw, StatusMsg, &statusData{
ProtocolVersion: uint32(p.version),
@@ -278,7 +280,26 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err
GenesisBlock: genesis,
})
}()
- // In the mean time retrieve the remote status message
+ go func() {
+ errc <- p.readStatus(&status, genesis)
+ }()
+ timeout := time.NewTimer(handshakeTimeout)
+ defer timeout.Stop()
+ for i := 0; i < 2; i++ {
+ select {
+ case err := <-errc:
+ if err != nil {
+ return err
+ }
+ case <-timeout.C:
+ return p2p.DiscReadTimeout
+ }
+ }
+ p.td, p.head = status.TD, status.CurrentBlock
+ return nil
+}
+
+func (p *peer) readStatus(status *statusData, genesis common.Hash) (err error) {
msg, err := p.rw.ReadMsg()
if err != nil {
return err
@@ -290,7 +311,6 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err
return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
}
// Decode the handshake and make sure everything matches
- var status statusData
if err := msg.Decode(&status); err != nil {
return errResp(ErrDecode, "msg %v: %v", msg, err)
}
@@ -303,9 +323,7 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, genesis common.Hash) err
if int(status.ProtocolVersion) != p.version {
return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version)
}
- // Configure the remote peer, and sanity check out handshake too
- p.td, p.head = status.TD, status.CurrentBlock
- return <-errc
+ return nil
}
// String implements fmt.Stringer.