mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
p2p/discover: repeat WHOAREYOU challenge when handshake in progress
This commit is contained in:
parent
1cdf4d6da7
commit
ad06df0473
3 changed files with 25 additions and 0 deletions
|
|
@ -55,6 +55,8 @@ type codecV5 interface {
|
||||||
// Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails.
|
// Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails.
|
||||||
// The *enode.Node return value is non-nil when the input contains a handshake response.
|
// The *enode.Node return value is non-nil when the input contains a handshake response.
|
||||||
Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error)
|
Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error)
|
||||||
|
|
||||||
|
CurrentChallenge(enode.ID, string) *v5wire.Whoareyou
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPv5 is the implementation of protocol version 5.
|
// UDPv5 is the implementation of protocol version 5.
|
||||||
|
|
@ -824,6 +826,19 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort
|
||||||
|
|
||||||
// handleUnknown initiates a handshake by responding with WHOAREYOU.
|
// handleUnknown initiates a handshake by responding with WHOAREYOU.
|
||||||
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
|
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||||
|
currentChallenge := t.codec.CurrentChallenge(fromID, fromAddr.String())
|
||||||
|
if currentChallenge != nil {
|
||||||
|
// This case happens when the sender issues multiple concurrent requests.
|
||||||
|
// Since we only support one in-progress handshake at a time, we need to tell
|
||||||
|
// them which handshake attempt they need to complete. We tell them to use the
|
||||||
|
// existing handshake attempt since the response to that one might still be in
|
||||||
|
// transit.
|
||||||
|
t.log.Warn("Repeating discv5 handshake challenge", "id", fromID, "addr", fromAddr)
|
||||||
|
t.sendResponse(fromID, fromAddr, currentChallenge)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a fresh challenge.
|
||||||
challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
|
challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
|
||||||
crand.Read(challenge.IDNonce[:])
|
crand.Read(challenge.IDNonce[:])
|
||||||
if n := t.GetNode(fromID); n != nil {
|
if n := t.GetNode(fromID); n != nil {
|
||||||
|
|
|
||||||
|
|
@ -717,6 +717,10 @@ func (c *testCodec) Encode(toID enode.ID, addr string, p v5wire.Packet, _ *v5wir
|
||||||
return frame, authTag, err
|
return frame, authTag, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *testCodec) CurrentChallenge(enode.ID, string) *v5wire.Whoareyou {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *testCodec) Decode(input []byte, addr string) (enode.ID, *enode.Node, v5wire.Packet, error) {
|
func (c *testCodec) Decode(input []byte, addr string) (enode.ID, *enode.Node, v5wire.Packet, error) {
|
||||||
frame, p, err := c.decodeFrame(input)
|
frame, p, err := c.decodeFrame(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,12 @@ func (c *Codec) EncodeRaw(id enode.ID, head Header, msgdata []byte) ([]byte, err
|
||||||
return c.buf.Bytes(), nil
|
return c.buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentChallenge returns the latest challenge sent to the given node.
|
||||||
|
// This will return non-nil while a handshake is in progress.
|
||||||
|
func (c *Codec) CurrentChallenge(id enode.ID, addr string) *Whoareyou {
|
||||||
|
return c.sc.getHandshake(id, addr)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Codec) writeHeaders(head *Header) {
|
func (c *Codec) writeHeaders(head *Header) {
|
||||||
c.buf.Reset()
|
c.buf.Reset()
|
||||||
c.buf.Write(head.IV[:])
|
c.buf.Write(head.IV[:])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue