From 3d7114169387d9487e433ca6958f8c0f1b7f531a Mon Sep 17 00:00:00 2001 From: Ferenc Szabo Date: Fri, 25 Jan 2019 15:34:27 +0100 Subject: [PATCH] p2p/protocols: fix rare data race in Peer.Handshake() The race occurred in the `!p.Inbound()` case if `send()` did return an error. Write #1: in handle closure `rhs = msg` (goroutine) Write #2: `return nil, error` => `nil` is written to `rhs` (main thread) fixes ethersphere/go-ethereum#1160 --- p2p/protocols/protocol.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/p2p/protocols/protocol.go b/p2p/protocols/protocol.go index bf879b9851..1600a11f99 100644 --- a/p2p/protocols/protocol.go +++ b/p2p/protocols/protocol.go @@ -386,10 +386,12 @@ func (p *Peer) handleIncoming(handle func(ctx context.Context, msg interface{}) // * the dialing peer needs to send the handshake first and then waits for remote // * the listening peer waits for the remote handshake and then sends it // returns the remote handshake and an error -func (p *Peer) Handshake(ctx context.Context, hs interface{}, verify func(interface{}) error) (rhs interface{}, err error) { +func (p *Peer) Handshake(ctx context.Context, hs interface{}, verify func(interface{}) error) (interface{}, error) { if _, ok := p.spec.GetCode(hs); !ok { return nil, errorf(ErrHandshake, "unknown handshake message type: %T", hs) } + + var rhs interface{} errc := make(chan error, 2) handle := func(ctx context.Context, msg interface{}) error { rhs = msg @@ -412,6 +414,7 @@ func (p *Peer) Handshake(ctx context.Context, hs interface{}, verify func(interf }() for i := 0; i < 2; i++ { + var err error select { case err = <-errc: case <-ctx.Done():