Skip to content

Commit d02fc3a

Browse files
ninabarbakadzerach-id
authored andcommittedNov 18, 2024
fix: DNS TTL not respected (#1442)
## Description Fixes #1425 ## Testing Testing DNS change is not really possible in unit tests so @smuu agreed to help me test manually
1 parent cb76c8f commit d02fc3a

File tree

8 files changed

+77
-13
lines changed

8 files changed

+77
-13
lines changed
 

‎blockchain/v2/reactor_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func (mp mockPeer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.RemoteIP()
4343

4444
func (mp mockPeer) IsOutbound() bool { return true }
4545
func (mp mockPeer) IsPersistent() bool { return true }
46+
func (mp mockPeer) HasIPChanged() bool { return false }
4647
func (mp mockPeer) CloseConn() error { return nil }
4748

4849
func (mp mockPeer) NodeInfo() p2p.NodeInfo {

‎p2p/mock/peer.go

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func (mp *Peer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{}
5757
func (mp *Peer) ID() p2p.ID { return mp.id }
5858
func (mp *Peer) IsOutbound() bool { return mp.Outbound }
5959
func (mp *Peer) IsPersistent() bool { return mp.Persistent }
60+
func (mp *Peer) HasIPChanged() bool { return false }
6061
func (mp *Peer) Get(key string) interface{} {
6162
if value, ok := mp.kv[key]; ok {
6263
return value

‎p2p/mocks/peer.go

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎p2p/mocks/peer_envelope_sender.go

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎p2p/peer.go

+14
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type Peer interface {
3232
IsOutbound() bool // did we dial the peer
3333
IsPersistent() bool // do we redial this peer when we disconnect
3434

35+
HasIPChanged() bool // has the peer's IP changed
36+
3537
CloseConn() error // close original connection
3638

3739
NodeInfo() NodeInfo // peer's info
@@ -303,6 +305,18 @@ func (p *peer) IsPersistent() bool {
303305
return p.peerConn.persistent
304306
}
305307

308+
// HasIPChanged returns true and the new IP if the peer's IP has changed.
309+
func (p *peer) HasIPChanged() bool {
310+
oldIP := p.ip
311+
if oldIP == nil {
312+
return false
313+
}
314+
// Reset the IP so we can get the new one
315+
p.ip = nil
316+
newIP := p.RemoteIP()
317+
return !oldIP.Equal(newIP)
318+
}
319+
306320
// NodeInfo returns a copy of the peer's NodeInfo.
307321
func (p *peer) NodeInfo() NodeInfo {
308322
return p.nodeInfo

‎p2p/peer_set_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (mp *mockPeer) NodeInfo() NodeInfo { return DefaultNodeInfo{}
2727
func (mp *mockPeer) Status() ConnectionStatus { return ConnectionStatus{} }
2828
func (mp *mockPeer) ID() ID { return mp.id }
2929
func (mp *mockPeer) IsOutbound() bool { return false }
30+
func (mp *mockPeer) HasIPChanged() bool { return false }
3031
func (mp *mockPeer) IsPersistent() bool { return true }
3132
func (mp *mockPeer) Get(s string) interface{} { return s }
3233
func (mp *mockPeer) Set(string, interface{}) {}

‎p2p/switch.go

+28-11
Original file line numberDiff line numberDiff line change
@@ -381,20 +381,37 @@ func (sw *Switch) StopPeerForError(peer Peer, reason interface{}) {
381381
sw.stopAndRemovePeer(peer, reason)
382382

383383
if peer.IsPersistent() {
384-
var addr *NetAddress
385-
if peer.IsOutbound() { // socket address for outbound peers
386-
addr = peer.SocketAddr()
387-
} else { // self-reported address for inbound peers
388-
var err error
389-
addr, err = peer.NodeInfo().NetAddress()
390-
if err != nil {
391-
sw.Logger.Error("Wanted to reconnect to inbound peer, but self-reported address is wrong",
392-
"peer", peer, "err", err)
393-
return
394-
}
384+
addr, err := sw.getPeerAddress(peer)
385+
if err != nil {
386+
sw.Logger.Error("Failed to get address for persistent peer", "peer", peer, "err", err)
387+
return
395388
}
396389
go sw.reconnectToPeer(addr)
397390
}
391+
392+
if peer.HasIPChanged() {
393+
addr, err := sw.getPeerAddress(peer)
394+
if err != nil {
395+
sw.Logger.Error("Failed to get address for peer with changed IP", "peer", peer, "err", err)
396+
}
397+
go sw.reconnectToPeer(addr)
398+
}
399+
}
400+
401+
// getPeerAddress returns the appropriate NetAddress for a given peer,
402+
// handling both outbound and inbound peers.
403+
func (sw *Switch) getPeerAddress(peer Peer) (*NetAddress, error) {
404+
if peer.IsOutbound() {
405+
return peer.SocketAddr(), nil
406+
}
407+
// For inbound peers, get the self-reported address
408+
addr, err := peer.NodeInfo().NetAddress()
409+
if err != nil {
410+
sw.Logger.Error("Failed to get address for inbound peer",
411+
"peer", peer, "err", err)
412+
return nil, err
413+
}
414+
return addr, nil
398415
}
399416

400417
// StopPeerGracefully disconnects from a peer gracefully.

‎test/fuzz/p2p/pex/reactor_receive.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ func (fp *fuzzPeer) RemoteIP() net.IP { return net.IPv4(0, 0, 0, 0) }
7474
func (fp *fuzzPeer) RemoteAddr() net.Addr {
7575
return &net.TCPAddr{IP: fp.RemoteIP(), Port: 98991, Zone: ""}
7676
}
77-
func (fp *fuzzPeer) IsOutbound() bool { return false }
78-
func (fp *fuzzPeer) IsPersistent() bool { return false }
77+
func (fp *fuzzPeer) IsOutbound() bool { return false }
78+
func (fp *fuzzPeer) IsPersistent() bool { return false }
79+
func (fp *fuzzPeer) HasIPChanged() bool { return false }
80+
7981
func (fp *fuzzPeer) CloseConn() error { return nil }
8082
func (fp *fuzzPeer) NodeInfo() p2p.NodeInfo { return defaultNodeInfo }
8183
func (fp *fuzzPeer) Status() p2p.ConnectionStatus { var cs p2p.ConnectionStatus; return cs }

0 commit comments

Comments
 (0)
Please sign in to comment.