Skip to content

Commit b39f81b

Browse files
committed
Merge branch 'p2p-discover-repeat-challenge' into gethintegration
2 parents 65fa51e + 0fd0c83 commit b39f81b

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

p2p/discover/v5_udp.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ type codecV5 interface {
5656
// Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails.
5757
// The *enode.Node return value is non-nil when the input contains a handshake response.
5858
Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error)
59+
60+
CurrentChallenge(enode.ID, string) *v5wire.Whoareyou
5961
}
6062

6163
// UDPv5 is the implementation of protocol version 5.
@@ -863,6 +865,19 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort
863865

864866
// handleUnknown initiates a handshake by responding with WHOAREYOU.
865867
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
868+
currentChallenge := t.codec.CurrentChallenge(fromID, fromAddr.String())
869+
if currentChallenge != nil {
870+
// This case happens when the sender issues multiple concurrent requests.
871+
// Since we only support one in-progress handshake at a time, we need to tell
872+
// them which handshake attempt they need to complete. We tell them to use the
873+
// existing handshake attempt since the response to that one might still be in
874+
// transit.
875+
t.log.Warn("Repeating discv5 handshake challenge", "id", fromID, "addr", fromAddr)
876+
t.sendResponse(fromID, fromAddr, currentChallenge)
877+
return
878+
}
879+
880+
// Send a fresh challenge.
866881
challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
867882
crand.Read(challenge.IDNonce[:])
868883
if n := t.GetNode(fromID); n != nil {

p2p/discover/v5_udp_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,10 @@ func (c *testCodec) Encode(toID enode.ID, addr string, p v5wire.Packet, _ *v5wir
717717
return frame, authTag, err
718718
}
719719

720+
func (c *testCodec) CurrentChallenge(enode.ID, string) *v5wire.Whoareyou {
721+
return nil
722+
}
723+
720724
func (c *testCodec) Decode(input []byte, addr string) (enode.ID, *enode.Node, v5wire.Packet, error) {
721725
frame, p, err := c.decodeFrame(input)
722726
if err != nil {

p2p/discover/v5wire/encoding.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ func (c *Codec) EncodeRaw(id enode.ID, head Header, msgdata []byte) ([]byte, err
245245
return c.buf.Bytes(), nil
246246
}
247247

248+
// CurrentChallenge returns the latest challenge sent to the given node.
249+
// This will return non-nil while a handshake is in progress.
250+
func (c *Codec) CurrentChallenge(id enode.ID, addr string) *Whoareyou {
251+
return c.sc.getHandshake(id, addr)
252+
}
253+
248254
func (c *Codec) writeHeaders(head *Header) {
249255
c.buf.Reset()
250256
c.buf.Write(head.IV[:])

0 commit comments

Comments
 (0)