Browse Source

p2p: use fake net.Pipe since only >=Go1.10 implements SetDeadline

Fixes https://github.com/tendermint/tendermint/issues/851

Go1.9 and below's net.Pipe did not implement the SetDeadline
method so after commit
e2dd8ca946
this problem was exposed since now we check for errors.

To counter this problem, implement a simple composition for
net.Conn that always returns nil on SetDeadline instead of
tripping out.

Added build tags so that anyone using go1.10 when it is released
will be able to automatically use net.Pipe's net.Conns
pull/852/head
Emmanuel Odeke 7 years ago
parent
commit
283544c7f3
No known key found for this signature in database GPG Key ID: 1CA47A292F89DD40
4 changed files with 48 additions and 9 deletions
  1. +15
    -0
      p2p/conn_go110.go
  2. +6
    -6
      p2p/connection_test.go
  3. +25
    -1
      p2p/switch.go
  4. +2
    -2
      p2p/switch_test.go

+ 15
- 0
p2p/conn_go110.go View File

@ -0,0 +1,15 @@
// +build go1.10
package p2p
// Go1.10 has a proper net.Conn implementation that
// has the SetDeadline method implemented as per
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
// lest we run into problems like
// https://github.com/tendermint/tendermint/issues/851
import "net"
func netPipe() (net.Conn, net.Conn) {
return net.Pipe()
}

+ 6
- 6
p2p/connection_test.go View File

@ -31,7 +31,7 @@ func createMConnectionWithCallbacks(conn net.Conn, onReceive func(chID byte, msg
func TestMConnectionSend(t *testing.T) {
assert, require := assert.New(t), require.New(t)
server, client := net.Pipe()
server, client := netPipe()
defer server.Close()
defer client.Close()
@ -58,7 +58,7 @@ func TestMConnectionSend(t *testing.T) {
func TestMConnectionReceive(t *testing.T) {
assert, require := assert.New(t), require.New(t)
server, client := net.Pipe()
server, client := netPipe()
defer server.Close()
defer client.Close()
@ -96,7 +96,7 @@ func TestMConnectionReceive(t *testing.T) {
func TestMConnectionStatus(t *testing.T) {
assert, require := assert.New(t), require.New(t)
server, client := net.Pipe()
server, client := netPipe()
defer server.Close()
defer client.Close()
@ -113,7 +113,7 @@ func TestMConnectionStatus(t *testing.T) {
func TestMConnectionStopsAndReturnsError(t *testing.T) {
assert, require := assert.New(t), require.New(t)
server, client := net.Pipe()
server, client := netPipe()
defer server.Close()
defer client.Close()
@ -144,7 +144,7 @@ func TestMConnectionStopsAndReturnsError(t *testing.T) {
}
func newClientAndServerConnsForReadErrors(require *require.Assertions, chOnErr chan struct{}) (*MConnection, *MConnection) {
server, client := net.Pipe()
server, client := netPipe()
onReceive := func(chID byte, msgBytes []byte) {}
onError := func(r interface{}) {}
@ -275,7 +275,7 @@ func TestMConnectionReadErrorUnknownMsgType(t *testing.T) {
func TestMConnectionTrySend(t *testing.T) {
assert, require := assert.New(t), require.New(t)
server, client := net.Pipe()
server, client := netPipe()
defer server.Close()
defer client.Close()


+ 25
- 1
p2p/switch.go View File

@ -515,7 +515,7 @@ var PanicOnAddPeerErr = false
func Connect2Switches(switches []*Switch, i, j int) {
switchI := switches[i]
switchJ := switches[j]
c1, c2 := net.Pipe()
c1, c2 := netPipe()
doneCh := make(chan struct{})
go func() {
err := switchI.addPeerWithConnection(c1)
@ -593,3 +593,27 @@ func (sw *Switch) addPeerWithConnectionAndConfig(conn net.Conn, config *PeerConf
return nil
}
// Only Go1.10 has a proper net.Conn implementation that
// has the SetDeadline method implemented as per
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
// lest we run into problems like
// https://github.com/tendermint/tendermint/issues/851
// so for go versions < Go1.10 use our custom net.Conn creator
// that doesn't return an `Unimplemented error` for net.Conn.
// Before https://github.com/tendermint/tendermint/commit/49faa79bdce5663894b3febbf4955fb1d172df04
// we hadn't cared about errors from SetDeadline so swallow them up anyways.
type pipe struct {
net.Conn
}
func (p *pipe) SetDeadline(t time.Time) error {
return nil
}
func netPipe() (net.Conn, net.Conn) {
p1, p2 := net.Pipe()
return &pipe{p1}, &pipe{p2}
}
var _ net.Conn = (*pipe)(nil)

+ 2
- 2
p2p/switch_test.go View File

@ -160,7 +160,7 @@ func TestConnAddrFilter(t *testing.T) {
defer s1.Stop()
defer s2.Stop()
c1, c2 := net.Pipe()
c1, c2 := netPipe()
s1.SetAddrFilter(func(addr net.Addr) error {
if addr.String() == c1.RemoteAddr().String() {
@ -194,7 +194,7 @@ func TestConnPubKeyFilter(t *testing.T) {
defer s1.Stop()
defer s2.Stop()
c1, c2 := net.Pipe()
c1, c2 := netPipe()
// set pubkey filter
s1.SetPubKeyFilter(func(pubkey crypto.PubKeyEd25519) error {


Loading…
Cancel
Save