From e75f6f24ba0f58b9bd049416a9395d667441083f Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 26 Feb 2026 11:37:47 +0800 Subject: [PATCH 1/3] cmd/devp2p: fix discv5 PingMultiIP handshake reply addr Signed-off-by: Delweng --- cmd/devp2p/internal/v5test/framework.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/devp2p/internal/v5test/framework.go b/cmd/devp2p/internal/v5test/framework.go index 92a5048150..57f33d8561 100644 --- a/cmd/devp2p/internal/v5test/framework.go +++ b/cmd/devp2p/internal/v5test/framework.go @@ -65,6 +65,7 @@ type conn struct { log logger codec *v5wire.Codec idCounter uint32 + lastFrom string } type logger interface { @@ -200,7 +201,11 @@ func (tc *conn) findnode(c net.PacketConn, dists []uint) ([]*enode.Node, error) // write sends a packet on the given connection. func (tc *conn) write(c net.PacketConn, p v5wire.Packet, challenge *v5wire.Whoareyou) v5wire.Nonce { - packet, nonce, err := tc.codec.Encode(tc.remote.ID(), tc.remoteAddr.String(), p, challenge) + addr := tc.remoteAddr.String() + if challenge != nil && tc.lastFrom != "" { + addr = tc.lastFrom + } + packet, nonce, err := tc.codec.Encode(tc.remote.ID(), addr, p, challenge) if err != nil { panic(fmt.Errorf("can't encode %v packet: %v", p.Name(), err)) } @@ -222,6 +227,7 @@ func (tc *conn) read(c net.PacketConn) v5wire.Packet { if err != nil { return &readError{err} } + tc.lastFrom = fromAddr.String() _, _, p, err := tc.codec.Decode(buf[:n], fromAddr.String()) if err != nil { return &readError{err} From 42e4cf8648b8ea9e548637849e67e9e4b4344899 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 26 Feb 2026 12:35:04 +0800 Subject: [PATCH 2/3] cmd/devp2p: store lastLocal as well Signed-off-by: Delweng --- cmd/devp2p/internal/v5test/framework.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/devp2p/internal/v5test/framework.go b/cmd/devp2p/internal/v5test/framework.go index 57f33d8561..24ba75e3e2 100644 --- a/cmd/devp2p/internal/v5test/framework.go +++ b/cmd/devp2p/internal/v5test/framework.go @@ -66,6 +66,7 @@ type conn struct { codec *v5wire.Codec idCounter uint32 lastFrom string + lastLocal net.IP } type logger interface { @@ -201,6 +202,13 @@ func (tc *conn) findnode(c net.PacketConn, dists []uint) ([]*enode.Node, error) // write sends a packet on the given connection. func (tc *conn) write(c net.PacketConn, p v5wire.Packet, challenge *v5wire.Whoareyou) v5wire.Nonce { + lip := laddr(c).IP + if tc.lastLocal != nil && !tc.lastLocal.Equal(lip) && challenge == nil { + // New local endpoint: drop old sessions to avoid reusing them across IPs. + tc.codec = v5wire.NewCodec(tc.localNode, tc.localKey, mclock.System{}, nil) + } + tc.lastLocal = slices.Clone(lip) + addr := tc.remoteAddr.String() if challenge != nil && tc.lastFrom != "" { addr = tc.lastFrom From f8f660eebec745cf391b11d921e8dce4d7e8a549 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 26 Feb 2026 12:35:50 +0800 Subject: [PATCH 3/3] fix: import Signed-off-by: Delweng --- cmd/devp2p/internal/v5test/framework.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/devp2p/internal/v5test/framework.go b/cmd/devp2p/internal/v5test/framework.go index 24ba75e3e2..ad98837b31 100644 --- a/cmd/devp2p/internal/v5test/framework.go +++ b/cmd/devp2p/internal/v5test/framework.go @@ -22,6 +22,7 @@ import ( "encoding/binary" "fmt" "net" + "slices" "time" "github.com/ethereum/go-ethereum/common/mclock"