preserve original address and dial it instead of self-reported address (#1994)
Refs #1720
This commit is contained in:
parent
6c4ca140ed
commit
b31ee798bd
|
@ -206,3 +206,4 @@ func (tp *bcrTestPeer) IsPersistent() bool { return true }
|
||||||
func (tp *bcrTestPeer) Get(s string) interface{} { return s }
|
func (tp *bcrTestPeer) Get(s string) interface{} { return s }
|
||||||
func (tp *bcrTestPeer) Set(string, interface{}) {}
|
func (tp *bcrTestPeer) Set(string, interface{}) {}
|
||||||
func (tp *bcrTestPeer) RemoteIP() net.IP { return []byte{127, 0, 0, 1} }
|
func (tp *bcrTestPeer) RemoteIP() net.IP { return []byte{127, 0, 0, 1} }
|
||||||
|
func (tp *bcrTestPeer) OriginalAddr() *p2p.NetAddress { return nil }
|
||||||
|
|
|
@ -3,9 +3,9 @@ package dummy
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
p2p "github.com/tendermint/tendermint/p2p"
|
p2p "github.com/tendermint/tendermint/p2p"
|
||||||
tmconn "github.com/tendermint/tendermint/p2p/conn"
|
tmconn "github.com/tendermint/tendermint/p2p/conn"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type peer struct {
|
type peer struct {
|
||||||
|
@ -78,3 +78,8 @@ func (p *peer) Get(key string) interface{} {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OriginalAddr always returns nil.
|
||||||
|
func (p *peer) OriginalAddr() *p2p.NetAddress {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
35
p2p/peer.go
35
p2p/peer.go
|
@ -26,6 +26,7 @@ type Peer interface {
|
||||||
IsPersistent() bool // do we redial this peer when we disconnect
|
IsPersistent() bool // do we redial this peer when we disconnect
|
||||||
NodeInfo() NodeInfo // peer's info
|
NodeInfo() NodeInfo // peer's info
|
||||||
Status() tmconn.ConnectionStatus
|
Status() tmconn.ConnectionStatus
|
||||||
|
OriginalAddr() *NetAddress
|
||||||
|
|
||||||
Send(byte, []byte) bool
|
Send(byte, []byte) bool
|
||||||
TrySend(byte, []byte) bool
|
TrySend(byte, []byte) bool
|
||||||
|
@ -38,11 +39,12 @@ type Peer interface {
|
||||||
|
|
||||||
// peerConn contains the raw connection and its config.
|
// peerConn contains the raw connection and its config.
|
||||||
type peerConn struct {
|
type peerConn struct {
|
||||||
outbound bool
|
outbound bool
|
||||||
persistent bool
|
persistent bool
|
||||||
config *config.P2PConfig
|
config *config.P2PConfig
|
||||||
conn net.Conn // source connection
|
conn net.Conn // source connection
|
||||||
ip net.IP
|
ip net.IP
|
||||||
|
originalAddr *NetAddress // nil for inbound connections
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID only exists for SecretConnection.
|
// ID only exists for SecretConnection.
|
||||||
|
@ -139,7 +141,7 @@ func newOutboundPeerConn(
|
||||||
return peerConn{}, cmn.ErrorWrap(err, "Error creating peer")
|
return peerConn{}, cmn.ErrorWrap(err, "Error creating peer")
|
||||||
}
|
}
|
||||||
|
|
||||||
pc, err := newPeerConn(conn, config, true, persistent, ourNodePrivKey)
|
pc, err := newPeerConn(conn, config, true, persistent, ourNodePrivKey, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cerr := conn.Close(); cerr != nil {
|
if cerr := conn.Close(); cerr != nil {
|
||||||
return peerConn{}, cmn.ErrorWrap(err, cerr.Error())
|
return peerConn{}, cmn.ErrorWrap(err, cerr.Error())
|
||||||
|
@ -166,7 +168,7 @@ func newInboundPeerConn(
|
||||||
|
|
||||||
// TODO: issue PoW challenge
|
// TODO: issue PoW challenge
|
||||||
|
|
||||||
return newPeerConn(conn, config, false, false, ourNodePrivKey)
|
return newPeerConn(conn, config, false, false, ourNodePrivKey, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPeerConn(
|
func newPeerConn(
|
||||||
|
@ -174,6 +176,7 @@ func newPeerConn(
|
||||||
cfg *config.P2PConfig,
|
cfg *config.P2PConfig,
|
||||||
outbound, persistent bool,
|
outbound, persistent bool,
|
||||||
ourNodePrivKey crypto.PrivKey,
|
ourNodePrivKey crypto.PrivKey,
|
||||||
|
originalAddr *NetAddress,
|
||||||
) (pc peerConn, err error) {
|
) (pc peerConn, err error) {
|
||||||
conn := rawConn
|
conn := rawConn
|
||||||
|
|
||||||
|
@ -200,10 +203,11 @@ func newPeerConn(
|
||||||
|
|
||||||
// Only the information we already have
|
// Only the information we already have
|
||||||
return peerConn{
|
return peerConn{
|
||||||
config: cfg,
|
config: cfg,
|
||||||
outbound: outbound,
|
outbound: outbound,
|
||||||
persistent: persistent,
|
persistent: persistent,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
|
originalAddr: originalAddr,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +258,15 @@ func (p *peer) NodeInfo() NodeInfo {
|
||||||
return p.nodeInfo
|
return p.nodeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OriginalAddr returns the original address, which was used to connect with
|
||||||
|
// the peer. Returns nil for inbound peers.
|
||||||
|
func (p *peer) OriginalAddr() *NetAddress {
|
||||||
|
if p.peerConn.outbound {
|
||||||
|
return p.peerConn.originalAddr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Status returns the peer's ConnectionStatus.
|
// Status returns the peer's ConnectionStatus.
|
||||||
func (p *peer) Status() tmconn.ConnectionStatus {
|
func (p *peer) Status() tmconn.ConnectionStatus {
|
||||||
return p.mconn.Status()
|
return p.mconn.Status()
|
||||||
|
|
|
@ -372,12 +372,13 @@ func (mp mockPeer) NodeInfo() p2p.NodeInfo {
|
||||||
ListenAddr: mp.addr.DialString(),
|
ListenAddr: mp.addr.DialString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (mp mockPeer) RemoteIP() net.IP { return net.ParseIP("127.0.0.1") }
|
func (mockPeer) RemoteIP() net.IP { return net.ParseIP("127.0.0.1") }
|
||||||
func (mp mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} }
|
func (mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} }
|
||||||
func (mp mockPeer) Send(byte, []byte) bool { return false }
|
func (mockPeer) Send(byte, []byte) bool { return false }
|
||||||
func (mp mockPeer) TrySend(byte, []byte) bool { return false }
|
func (mockPeer) TrySend(byte, []byte) bool { return false }
|
||||||
func (mp mockPeer) Set(string, interface{}) {}
|
func (mockPeer) Set(string, interface{}) {}
|
||||||
func (mp mockPeer) Get(string) interface{} { return nil }
|
func (mockPeer) Get(string) interface{} { return nil }
|
||||||
|
func (mockPeer) OriginalAddr() *p2p.NetAddress { return nil }
|
||||||
|
|
||||||
func assertPeersWithTimeout(
|
func assertPeersWithTimeout(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/config"
|
"github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p/conn"
|
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
|
"github.com/tendermint/tendermint/p2p/conn"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -281,8 +281,11 @@ func (sw *Switch) StopPeerForError(peer Peer, reason interface{}) {
|
||||||
sw.stopAndRemovePeer(peer, reason)
|
sw.stopAndRemovePeer(peer, reason)
|
||||||
|
|
||||||
if peer.IsPersistent() {
|
if peer.IsPersistent() {
|
||||||
// NOTE: this is the self-reported addr, not the original we dialed
|
addr := peer.OriginalAddr()
|
||||||
go sw.reconnectToPeer(peer.NodeInfo().NetAddress())
|
if addr == nil {
|
||||||
|
panic(fmt.Sprintf("persistent peer %v with no original address", peer))
|
||||||
|
}
|
||||||
|
go sw.reconnectToPeer(addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue