gitlab.com/yannislg/go-pulse@v0.0.0-20210722055913-a3e24e95638d/p2p/discover/v5_udp.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package discover
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"crypto/ecdsa"
    23  	crand "crypto/rand"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"math"
    28  	"net"
    29  	"sync"
    30  	"time"
    31  
    32  	"github.com/ethereum/go-ethereum/common/mclock"
    33  	"github.com/ethereum/go-ethereum/log"
    34  	"github.com/ethereum/go-ethereum/p2p/enode"
    35  	"github.com/ethereum/go-ethereum/p2p/enr"
    36  	"github.com/ethereum/go-ethereum/p2p/netutil"
    37  )
    38  
    39  const (
    40  	lookupRequestLimit      = 3  // max requests against a single node during lookup
    41  	findnodeResultLimit     = 15 // applies in FINDNODE handler
    42  	totalNodesResponseLimit = 5  // applies in waitForNodes
    43  	nodesResponseItemLimit  = 3  // applies in sendNodes
    44  
    45  	respTimeoutV5 = 700 * time.Millisecond
    46  )
    47  
    48  // codecV5 is implemented by wireCodec (and testCodec).
    49  //
    50  // The UDPv5 transport is split into two objects: the codec object deals with
    51  // encoding/decoding and with the handshake; the UDPv5 object handles higher-level concerns.
    52  type codecV5 interface {
    53  	// encode encodes a packet. The 'challenge' parameter is non-nil for calls which got a
    54  	// WHOAREYOU response.
    55  	encode(fromID enode.ID, fromAddr string, p packetV5, challenge *whoareyouV5) (enc []byte, authTag []byte, err error)
    56  
    57  	// decode decodes a packet. It returns an *unknownV5 packet if decryption fails.
    58  	// The fromNode return value is non-nil when the input contains a handshake response.
    59  	decode(input []byte, fromAddr string) (fromID enode.ID, fromNode *enode.Node, p packetV5, err error)
    60  }
    61  
    62  // packetV5 is implemented by all discv5 packet type structs.
    63  type packetV5 interface {
    64  	// These methods provide information and set the request ID.
    65  	name() string
    66  	kind() byte
    67  	setreqid([]byte)
    68  	// handle should perform the appropriate action to handle the packet, i.e. this is the
    69  	// place to send the response.
    70  	handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr)
    71  }
    72  
    73  // UDPv5 is the implementation of protocol version 5.
    74  type UDPv5 struct {
    75  	// static fields
    76  	conn         UDPConn
    77  	tab          *Table
    78  	netrestrict  *netutil.Netlist
    79  	priv         *ecdsa.PrivateKey
    80  	localNode    *enode.LocalNode
    81  	db           *enode.DB
    82  	log          log.Logger
    83  	clock        mclock.Clock
    84  	validSchemes enr.IdentityScheme
    85  
    86  	// channels into dispatch
    87  	packetInCh    chan ReadPacket
    88  	readNextCh    chan struct{}
    89  	callCh        chan *callV5
    90  	callDoneCh    chan *callV5
    91  	respTimeoutCh chan *callTimeout
    92  
    93  	// state of dispatch
    94  	codec            codecV5
    95  	activeCallByNode map[enode.ID]*callV5
    96  	activeCallByAuth map[string]*callV5
    97  	callQueue        map[enode.ID][]*callV5
    98  
    99  	// shutdown stuff
   100  	closeOnce      sync.Once
   101  	closeCtx       context.Context
   102  	cancelCloseCtx context.CancelFunc
   103  	wg             sync.WaitGroup
   104  }
   105  
   106  // callV5 represents a remote procedure call against another node.
   107  type callV5 struct {
   108  	node         *enode.Node
   109  	packet       packetV5
   110  	responseType byte // expected packet type of response
   111  	reqid        []byte
   112  	ch           chan packetV5 // responses sent here
   113  	err          chan error    // errors sent here
   114  
   115  	// Valid for active calls only:
   116  	authTag        []byte       // authTag of request packet
   117  	handshakeCount int          // # times we attempted handshake for this call
   118  	challenge      *whoareyouV5 // last sent handshake challenge
   119  	timeout        mclock.Timer
   120  }
   121  
   122  // callTimeout is the response timeout event of a call.
   123  type callTimeout struct {
   124  	c     *callV5
   125  	timer mclock.Timer
   126  }
   127  
   128  // ListenV5 listens on the given connection.
   129  func ListenV5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) {
   130  	t, err := newUDPv5(conn, ln, cfg)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	go t.tab.loop()
   135  	t.wg.Add(2)
   136  	go t.readLoop()
   137  	go t.dispatch()
   138  	return t, nil
   139  }
   140  
   141  // newUDPv5 creates a UDPv5 transport, but doesn't start any goroutines.
   142  func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) {
   143  	closeCtx, cancelCloseCtx := context.WithCancel(context.Background())
   144  	cfg = cfg.withDefaults()
   145  	t := &UDPv5{
   146  		// static fields
   147  		conn:         conn,
   148  		localNode:    ln,
   149  		db:           ln.Database(),
   150  		netrestrict:  cfg.NetRestrict,
   151  		priv:         cfg.PrivateKey,
   152  		log:          cfg.Log,
   153  		validSchemes: cfg.ValidSchemes,
   154  		clock:        cfg.Clock,
   155  		// channels into dispatch
   156  		packetInCh:    make(chan ReadPacket, 1),
   157  		readNextCh:    make(chan struct{}, 1),
   158  		callCh:        make(chan *callV5),
   159  		callDoneCh:    make(chan *callV5),
   160  		respTimeoutCh: make(chan *callTimeout),
   161  		// state of dispatch
   162  		codec:            newWireCodec(ln, cfg.PrivateKey, cfg.Clock),
   163  		activeCallByNode: make(map[enode.ID]*callV5),
   164  		activeCallByAuth: make(map[string]*callV5),
   165  		callQueue:        make(map[enode.ID][]*callV5),
   166  		// shutdown
   167  		closeCtx:       closeCtx,
   168  		cancelCloseCtx: cancelCloseCtx,
   169  	}
   170  	tab, err := newTable(t, t.db, cfg.Bootnodes, cfg.Log)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	t.tab = tab
   175  	return t, nil
   176  }
   177  
   178  // Self returns the local node record.
   179  func (t *UDPv5) Self() *enode.Node {
   180  	return t.localNode.Node()
   181  }
   182  
   183  // Close shuts down packet processing.
   184  func (t *UDPv5) Close() {
   185  	t.closeOnce.Do(func() {
   186  		t.cancelCloseCtx()
   187  		t.conn.Close()
   188  		t.wg.Wait()
   189  		t.tab.close()
   190  	})
   191  }
   192  
   193  // Ping sends a ping message to the given node.
   194  func (t *UDPv5) Ping(n *enode.Node) error {
   195  	_, err := t.ping(n)
   196  	return err
   197  }
   198  
   199  // Resolve searches for a specific node with the given ID and tries to get the most recent
   200  // version of the node record for it. It returns n if the node could not be resolved.
   201  func (t *UDPv5) Resolve(n *enode.Node) *enode.Node {
   202  	if intable := t.tab.getNode(n.ID()); intable != nil && intable.Seq() > n.Seq() {
   203  		n = intable
   204  	}
   205  	// Try asking directly. This works if the node is still responding on the endpoint we have.
   206  	if resp, err := t.RequestENR(n); err == nil {
   207  		return resp
   208  	}
   209  	// Otherwise do a network lookup.
   210  	result := t.Lookup(n.ID())
   211  	for _, rn := range result {
   212  		if rn.ID() == n.ID() && rn.Seq() > n.Seq() {
   213  			return rn
   214  		}
   215  	}
   216  	return n
   217  }
   218  
   219  func (t *UDPv5) RandomNodes() enode.Iterator {
   220  	if t.tab.len() == 0 {
   221  		// All nodes were dropped, refresh. The very first query will hit this
   222  		// case and run the bootstrapping logic.
   223  		<-t.tab.refresh()
   224  	}
   225  
   226  	return newLookupIterator(t.closeCtx, t.newRandomLookup)
   227  }
   228  
   229  // Lookup performs a recursive lookup for the given target.
   230  // It returns the closest nodes to target.
   231  func (t *UDPv5) Lookup(target enode.ID) []*enode.Node {
   232  	return t.newLookup(t.closeCtx, target).run()
   233  }
   234  
   235  // lookupRandom looks up a random target.
   236  // This is needed to satisfy the transport interface.
   237  func (t *UDPv5) lookupRandom() []*enode.Node {
   238  	return t.newRandomLookup(t.closeCtx).run()
   239  }
   240  
   241  // lookupSelf looks up our own node ID.
   242  // This is needed to satisfy the transport interface.
   243  func (t *UDPv5) lookupSelf() []*enode.Node {
   244  	return t.newLookup(t.closeCtx, t.Self().ID()).run()
   245  }
   246  
   247  func (t *UDPv5) newRandomLookup(ctx context.Context) *lookup {
   248  	var target enode.ID
   249  	crand.Read(target[:])
   250  	return t.newLookup(ctx, target)
   251  }
   252  
   253  func (t *UDPv5) newLookup(ctx context.Context, target enode.ID) *lookup {
   254  	return newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) {
   255  		return t.lookupWorker(n, target)
   256  	})
   257  }
   258  
   259  // lookupWorker performs FINDNODE calls against a single node during lookup.
   260  func (t *UDPv5) lookupWorker(destNode *node, target enode.ID) ([]*node, error) {
   261  	var (
   262  		dists = lookupDistances(target, destNode.ID())
   263  		nodes = nodesByDistance{target: target}
   264  		err   error
   265  	)
   266  	for i := 0; i < lookupRequestLimit && len(nodes.entries) < findnodeResultLimit; i++ {
   267  		var r []*enode.Node
   268  		r, err = t.findnode(unwrapNode(destNode), dists[i])
   269  		if err == errClosed {
   270  			return nil, err
   271  		}
   272  		for _, n := range r {
   273  			if n.ID() != t.Self().ID() {
   274  				nodes.push(wrapNode(n), findnodeResultLimit)
   275  			}
   276  		}
   277  	}
   278  	return nodes.entries, err
   279  }
   280  
   281  // lookupDistances computes the distance parameter for FINDNODE calls to dest.
   282  // It chooses distances adjacent to logdist(target, dest), e.g. for a target
   283  // with logdist(target, dest) = 255 the result is [255, 256, 254].
   284  func lookupDistances(target, dest enode.ID) (dists []int) {
   285  	td := enode.LogDist(target, dest)
   286  	dists = append(dists, td)
   287  	for i := 1; len(dists) < lookupRequestLimit; i++ {
   288  		if td+i < 256 {
   289  			dists = append(dists, td+i)
   290  		}
   291  		if td-i > 0 {
   292  			dists = append(dists, td-i)
   293  		}
   294  	}
   295  	return dists
   296  }
   297  
   298  // ping calls PING on a node and waits for a PONG response.
   299  func (t *UDPv5) ping(n *enode.Node) (uint64, error) {
   300  	resp := t.call(n, p_pongV5, &pingV5{ENRSeq: t.localNode.Node().Seq()})
   301  	defer t.callDone(resp)
   302  	select {
   303  	case pong := <-resp.ch:
   304  		return pong.(*pongV5).ENRSeq, nil
   305  	case err := <-resp.err:
   306  		return 0, err
   307  	}
   308  }
   309  
   310  // requestENR requests n's record.
   311  func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) {
   312  	nodes, err := t.findnode(n, 0)
   313  	if err != nil {
   314  		return nil, err
   315  	}
   316  	if len(nodes) != 1 {
   317  		return nil, fmt.Errorf("%d nodes in response for distance zero", len(nodes))
   318  	}
   319  	return nodes[0], nil
   320  }
   321  
   322  // requestTicket calls REQUESTTICKET on a node and waits for a TICKET response.
   323  func (t *UDPv5) requestTicket(n *enode.Node) ([]byte, error) {
   324  	resp := t.call(n, p_ticketV5, &pingV5{})
   325  	defer t.callDone(resp)
   326  	select {
   327  	case response := <-resp.ch:
   328  		return response.(*ticketV5).Ticket, nil
   329  	case err := <-resp.err:
   330  		return nil, err
   331  	}
   332  }
   333  
   334  // findnode calls FINDNODE on a node and waits for responses.
   335  func (t *UDPv5) findnode(n *enode.Node, distance int) ([]*enode.Node, error) {
   336  	resp := t.call(n, p_nodesV5, &findnodeV5{Distance: uint(distance)})
   337  	return t.waitForNodes(resp, distance)
   338  }
   339  
   340  // waitForNodes waits for NODES responses to the given call.
   341  func (t *UDPv5) waitForNodes(c *callV5, distance int) ([]*enode.Node, error) {
   342  	defer t.callDone(c)
   343  
   344  	var (
   345  		nodes           []*enode.Node
   346  		seen            = make(map[enode.ID]struct{})
   347  		received, total = 0, -1
   348  	)
   349  	for {
   350  		select {
   351  		case responseP := <-c.ch:
   352  			response := responseP.(*nodesV5)
   353  			for _, record := range response.Nodes {
   354  				node, err := t.verifyResponseNode(c, record, distance, seen)
   355  				if err != nil {
   356  					t.log.Debug("Invalid record in "+response.name(), "id", c.node.ID(), "err", err)
   357  					continue
   358  				}
   359  				nodes = append(nodes, node)
   360  			}
   361  			if total == -1 {
   362  				total = min(int(response.Total), totalNodesResponseLimit)
   363  			}
   364  			if received++; received == total {
   365  				return nodes, nil
   366  			}
   367  		case err := <-c.err:
   368  			return nodes, err
   369  		}
   370  	}
   371  }
   372  
   373  // verifyResponseNode checks validity of a record in a NODES response.
   374  func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distance int, seen map[enode.ID]struct{}) (*enode.Node, error) {
   375  	node, err := enode.New(t.validSchemes, r)
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  	if err := netutil.CheckRelayIP(c.node.IP(), node.IP()); err != nil {
   380  		return nil, err
   381  	}
   382  	if c.node.UDP() <= 1024 {
   383  		return nil, errLowPort
   384  	}
   385  	if distance != -1 {
   386  		if d := enode.LogDist(c.node.ID(), node.ID()); d != distance {
   387  			return nil, fmt.Errorf("wrong distance %d", d)
   388  		}
   389  	}
   390  	if _, ok := seen[node.ID()]; ok {
   391  		return nil, fmt.Errorf("duplicate record")
   392  	}
   393  	seen[node.ID()] = struct{}{}
   394  	return node, nil
   395  }
   396  
   397  // call sends the given call and sets up a handler for response packets (of type c.responseType).
   398  // Responses are dispatched to the call's response channel.
   399  func (t *UDPv5) call(node *enode.Node, responseType byte, packet packetV5) *callV5 {
   400  	c := &callV5{
   401  		node:         node,
   402  		packet:       packet,
   403  		responseType: responseType,
   404  		reqid:        make([]byte, 8),
   405  		ch:           make(chan packetV5, 1),
   406  		err:          make(chan error, 1),
   407  	}
   408  	// Assign request ID.
   409  	crand.Read(c.reqid)
   410  	packet.setreqid(c.reqid)
   411  	// Send call to dispatch.
   412  	select {
   413  	case t.callCh <- c:
   414  	case <-t.closeCtx.Done():
   415  		c.err <- errClosed
   416  	}
   417  	return c
   418  }
   419  
   420  // callDone tells dispatch that the active call is done.
   421  func (t *UDPv5) callDone(c *callV5) {
   422  	// This needs a loop because further responses may be incoming until the
   423  	// send to callDoneCh has completed. Such responses need to be discarded
   424  	// in order to avoid blocking the dispatch loop.
   425  	for {
   426  		select {
   427  		case <-c.ch:
   428  			// late response, discard.
   429  		case <-c.err:
   430  			// late error, discard.
   431  		case t.callDoneCh <- c:
   432  			return
   433  		case <-t.closeCtx.Done():
   434  			return
   435  		}
   436  	}
   437  }
   438  
   439  // dispatch runs in its own goroutine, handles incoming packets and deals with calls.
   440  //
   441  // For any destination node there is at most one 'active call', stored in the t.activeCall*
   442  // maps. A call is made active when it is sent. The active call can be answered by a
   443  // matching response, in which case c.ch receives the response; or by timing out, in which case
   444  // c.err receives the error. When the function that created the call signals the active
   445  // call is done through callDone, the next call from the call queue is started.
   446  //
   447  // Calls may also be answered by a WHOAREYOU packet referencing the call packet's authTag.
   448  // When that happens the call is simply re-sent to complete the handshake. We allow one
   449  // handshake attempt per call.
   450  func (t *UDPv5) dispatch() {
   451  	defer t.wg.Done()
   452  
   453  	// Arm first read.
   454  	t.readNextCh <- struct{}{}
   455  
   456  	for {
   457  		select {
   458  		case c := <-t.callCh:
   459  			id := c.node.ID()
   460  			t.callQueue[id] = append(t.callQueue[id], c)
   461  			t.sendNextCall(id)
   462  
   463  		case ct := <-t.respTimeoutCh:
   464  			active := t.activeCallByNode[ct.c.node.ID()]
   465  			if ct.c == active && ct.timer == active.timeout {
   466  				ct.c.err <- errTimeout
   467  			}
   468  
   469  		case c := <-t.callDoneCh:
   470  			id := c.node.ID()
   471  			active := t.activeCallByNode[id]
   472  			if active != c {
   473  				panic("BUG: callDone for inactive call")
   474  			}
   475  			c.timeout.Stop()
   476  			delete(t.activeCallByAuth, string(c.authTag))
   477  			delete(t.activeCallByNode, id)
   478  			t.sendNextCall(id)
   479  
   480  		case p := <-t.packetInCh:
   481  			t.handlePacket(p.Data, p.Addr)
   482  			// Arm next read.
   483  			t.readNextCh <- struct{}{}
   484  
   485  		case <-t.closeCtx.Done():
   486  			close(t.readNextCh)
   487  			for id, queue := range t.callQueue {
   488  				for _, c := range queue {
   489  					c.err <- errClosed
   490  				}
   491  				delete(t.callQueue, id)
   492  			}
   493  			for id, c := range t.activeCallByNode {
   494  				c.err <- errClosed
   495  				delete(t.activeCallByNode, id)
   496  				delete(t.activeCallByAuth, string(c.authTag))
   497  			}
   498  			return
   499  		}
   500  	}
   501  }
   502  
   503  // startResponseTimeout sets the response timer for a call.
   504  func (t *UDPv5) startResponseTimeout(c *callV5) {
   505  	if c.timeout != nil {
   506  		c.timeout.Stop()
   507  	}
   508  	var (
   509  		timer mclock.Timer
   510  		done  = make(chan struct{})
   511  	)
   512  	timer = t.clock.AfterFunc(respTimeoutV5, func() {
   513  		<-done
   514  		select {
   515  		case t.respTimeoutCh <- &callTimeout{c, timer}:
   516  		case <-t.closeCtx.Done():
   517  		}
   518  	})
   519  	c.timeout = timer
   520  	close(done)
   521  }
   522  
   523  // sendNextCall sends the next call in the call queue if there is no active call.
   524  func (t *UDPv5) sendNextCall(id enode.ID) {
   525  	queue := t.callQueue[id]
   526  	if len(queue) == 0 || t.activeCallByNode[id] != nil {
   527  		return
   528  	}
   529  	t.activeCallByNode[id] = queue[0]
   530  	t.sendCall(t.activeCallByNode[id])
   531  	if len(queue) == 1 {
   532  		delete(t.callQueue, id)
   533  	} else {
   534  		copy(queue, queue[1:])
   535  		t.callQueue[id] = queue[:len(queue)-1]
   536  	}
   537  }
   538  
   539  // sendCall encodes and sends a request packet to the call's recipient node.
   540  // This performs a handshake if needed.
   541  func (t *UDPv5) sendCall(c *callV5) {
   542  	if len(c.authTag) > 0 {
   543  		// The call already has an authTag from a previous handshake attempt. Remove the
   544  		// entry for the authTag because we're about to generate a new authTag for this
   545  		// call.
   546  		delete(t.activeCallByAuth, string(c.authTag))
   547  	}
   548  
   549  	addr := &net.UDPAddr{IP: c.node.IP(), Port: c.node.UDP()}
   550  	newTag, _ := t.send(c.node.ID(), addr, c.packet, c.challenge)
   551  	c.authTag = newTag
   552  	t.activeCallByAuth[string(c.authTag)] = c
   553  	t.startResponseTimeout(c)
   554  }
   555  
   556  // sendResponse sends a response packet to the given node.
   557  // This doesn't trigger a handshake even if no keys are available.
   558  func (t *UDPv5) sendResponse(toID enode.ID, toAddr *net.UDPAddr, packet packetV5) error {
   559  	_, err := t.send(toID, toAddr, packet, nil)
   560  	return err
   561  }
   562  
   563  // send sends a packet to the given node.
   564  func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet packetV5, c *whoareyouV5) ([]byte, error) {
   565  	addr := toAddr.String()
   566  	enc, authTag, err := t.codec.encode(toID, addr, packet, c)
   567  	if err != nil {
   568  		t.log.Warn(">> "+packet.name(), "id", toID, "addr", addr, "err", err)
   569  		return authTag, err
   570  	}
   571  	_, err = t.conn.WriteToUDP(enc, toAddr)
   572  	t.log.Trace(">> "+packet.name(), "id", toID, "addr", addr)
   573  	return authTag, err
   574  }
   575  
   576  // readLoop runs in its own goroutine and reads packets from the network.
   577  func (t *UDPv5) readLoop() {
   578  	defer t.wg.Done()
   579  
   580  	buf := make([]byte, maxPacketSize)
   581  	for range t.readNextCh {
   582  		nbytes, from, err := t.conn.ReadFromUDP(buf)
   583  		if netutil.IsTemporaryError(err) {
   584  			// Ignore temporary read errors.
   585  			t.log.Debug("Temporary UDP read error", "err", err)
   586  			continue
   587  		} else if err != nil {
   588  			// Shut down the loop for permament errors.
   589  			if err != io.EOF {
   590  				t.log.Debug("UDP read error", "err", err)
   591  			}
   592  			return
   593  		}
   594  		t.dispatchReadPacket(from, buf[:nbytes])
   595  	}
   596  }
   597  
   598  // dispatchReadPacket sends a packet into the dispatch loop.
   599  func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool {
   600  	select {
   601  	case t.packetInCh <- ReadPacket{content, from}:
   602  		return true
   603  	case <-t.closeCtx.Done():
   604  		return false
   605  	}
   606  }
   607  
   608  // handlePacket decodes and processes an incoming packet from the network.
   609  func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error {
   610  	addr := fromAddr.String()
   611  	fromID, fromNode, packet, err := t.codec.decode(rawpacket, addr)
   612  	if err != nil {
   613  		t.log.Debug("Bad discv5 packet", "id", fromID, "addr", addr, "err", err)
   614  		return err
   615  	}
   616  	if fromNode != nil {
   617  		// Handshake succeeded, add to table.
   618  		t.tab.addSeenNode(wrapNode(fromNode))
   619  	}
   620  	if packet.kind() != p_whoareyouV5 {
   621  		// WHOAREYOU logged separately to report the sender ID.
   622  		t.log.Trace("<< "+packet.name(), "id", fromID, "addr", addr)
   623  	}
   624  	packet.handle(t, fromID, fromAddr)
   625  	return nil
   626  }
   627  
   628  // handleCallResponse dispatches a response packet to the call waiting for it.
   629  func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr *net.UDPAddr, reqid []byte, p packetV5) {
   630  	ac := t.activeCallByNode[fromID]
   631  	if ac == nil || !bytes.Equal(reqid, ac.reqid) {
   632  		t.log.Debug(fmt.Sprintf("Unsolicited/late %s response", p.name()), "id", fromID, "addr", fromAddr)
   633  		return
   634  	}
   635  	if !fromAddr.IP.Equal(ac.node.IP()) || fromAddr.Port != ac.node.UDP() {
   636  		t.log.Debug(fmt.Sprintf("%s from wrong endpoint", p.name()), "id", fromID, "addr", fromAddr)
   637  		return
   638  	}
   639  	if p.kind() != ac.responseType {
   640  		t.log.Debug(fmt.Sprintf("Wrong disv5 response type %s", p.name()), "id", fromID, "addr", fromAddr)
   641  		return
   642  	}
   643  	t.startResponseTimeout(ac)
   644  	ac.ch <- p
   645  }
   646  
   647  // getNode looks for a node record in table and database.
   648  func (t *UDPv5) getNode(id enode.ID) *enode.Node {
   649  	if n := t.tab.getNode(id); n != nil {
   650  		return n
   651  	}
   652  	if n := t.localNode.Database().Node(id); n != nil {
   653  		return n
   654  	}
   655  	return nil
   656  }
   657  
   658  // UNKNOWN
   659  
   660  func (p *unknownV5) name() string       { return "UNKNOWN/v5" }
   661  func (p *unknownV5) kind() byte         { return p_unknownV5 }
   662  func (p *unknownV5) setreqid(id []byte) {}
   663  
   664  func (p *unknownV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   665  	challenge := &whoareyouV5{AuthTag: p.AuthTag}
   666  	crand.Read(challenge.IDNonce[:])
   667  	if n := t.getNode(fromID); n != nil {
   668  		challenge.node = n
   669  		challenge.RecordSeq = n.Seq()
   670  	}
   671  	t.sendResponse(fromID, fromAddr, challenge)
   672  }
   673  
   674  // WHOAREYOU
   675  
   676  func (p *whoareyouV5) name() string       { return "WHOAREYOU/v5" }
   677  func (p *whoareyouV5) kind() byte         { return p_whoareyouV5 }
   678  func (p *whoareyouV5) setreqid(id []byte) {}
   679  
   680  func (p *whoareyouV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   681  	c, err := p.matchWithCall(t, p.AuthTag)
   682  	if err != nil {
   683  		t.log.Debug("Invalid WHOAREYOU/v5", "addr", fromAddr, "err", err)
   684  		return
   685  	}
   686  	// Resend the call that was answered by WHOAREYOU.
   687  	t.log.Trace("<< "+p.name(), "id", c.node.ID(), "addr", fromAddr)
   688  	c.handshakeCount++
   689  	c.challenge = p
   690  	p.node = c.node
   691  	t.sendCall(c)
   692  }
   693  
   694  var (
   695  	errChallengeNoCall = errors.New("no matching call")
   696  	errChallengeTwice  = errors.New("second handshake")
   697  )
   698  
   699  // matchWithCall checks whether the handshake attempt matches the active call.
   700  func (p *whoareyouV5) matchWithCall(t *UDPv5, authTag []byte) (*callV5, error) {
   701  	c := t.activeCallByAuth[string(authTag)]
   702  	if c == nil {
   703  		return nil, errChallengeNoCall
   704  	}
   705  	if c.handshakeCount > 0 {
   706  		return nil, errChallengeTwice
   707  	}
   708  	return c, nil
   709  }
   710  
   711  // PING
   712  
   713  func (p *pingV5) name() string       { return "PING/v5" }
   714  func (p *pingV5) kind() byte         { return p_pingV5 }
   715  func (p *pingV5) setreqid(id []byte) { p.ReqID = id }
   716  
   717  func (p *pingV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   718  	t.sendResponse(fromID, fromAddr, &pongV5{
   719  		ReqID:  p.ReqID,
   720  		ToIP:   fromAddr.IP,
   721  		ToPort: uint16(fromAddr.Port),
   722  		ENRSeq: t.localNode.Node().Seq(),
   723  	})
   724  }
   725  
   726  // PONG
   727  
   728  func (p *pongV5) name() string       { return "PONG/v5" }
   729  func (p *pongV5) kind() byte         { return p_pongV5 }
   730  func (p *pongV5) setreqid(id []byte) { p.ReqID = id }
   731  
   732  func (p *pongV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   733  	t.localNode.UDPEndpointStatement(fromAddr, &net.UDPAddr{IP: p.ToIP, Port: int(p.ToPort)})
   734  	t.handleCallResponse(fromID, fromAddr, p.ReqID, p)
   735  }
   736  
   737  // FINDNODE
   738  
   739  func (p *findnodeV5) name() string       { return "FINDNODE/v5" }
   740  func (p *findnodeV5) kind() byte         { return p_findnodeV5 }
   741  func (p *findnodeV5) setreqid(id []byte) { p.ReqID = id }
   742  
   743  func (p *findnodeV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   744  	if p.Distance == 0 {
   745  		t.sendNodes(fromID, fromAddr, p.ReqID, []*enode.Node{t.Self()})
   746  		return
   747  	}
   748  	if p.Distance > 256 {
   749  		p.Distance = 256
   750  	}
   751  	// Get bucket entries.
   752  	t.tab.mutex.Lock()
   753  	nodes := unwrapNodes(t.tab.bucketAtDistance(int(p.Distance)).entries)
   754  	t.tab.mutex.Unlock()
   755  	if len(nodes) > findnodeResultLimit {
   756  		nodes = nodes[:findnodeResultLimit]
   757  	}
   758  	t.sendNodes(fromID, fromAddr, p.ReqID, nodes)
   759  }
   760  
   761  // sendNodes sends the given records in one or more NODES packets.
   762  func (t *UDPv5) sendNodes(toID enode.ID, toAddr *net.UDPAddr, reqid []byte, nodes []*enode.Node) {
   763  	// TODO livenessChecks > 1
   764  	// TODO CheckRelayIP
   765  	total := uint8(math.Ceil(float64(len(nodes)) / 3))
   766  	resp := &nodesV5{ReqID: reqid, Total: total, Nodes: make([]*enr.Record, 3)}
   767  	sent := false
   768  	for len(nodes) > 0 {
   769  		items := min(nodesResponseItemLimit, len(nodes))
   770  		resp.Nodes = resp.Nodes[:items]
   771  		for i := 0; i < items; i++ {
   772  			resp.Nodes[i] = nodes[i].Record()
   773  		}
   774  		t.sendResponse(toID, toAddr, resp)
   775  		nodes = nodes[items:]
   776  		sent = true
   777  	}
   778  	// Ensure at least one response is sent.
   779  	if !sent {
   780  		resp.Total = 1
   781  		resp.Nodes = nil
   782  		t.sendResponse(toID, toAddr, resp)
   783  	}
   784  }
   785  
   786  // NODES
   787  
   788  func (p *nodesV5) name() string       { return "NODES/v5" }
   789  func (p *nodesV5) kind() byte         { return p_nodesV5 }
   790  func (p *nodesV5) setreqid(id []byte) { p.ReqID = id }
   791  
   792  func (p *nodesV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   793  	t.handleCallResponse(fromID, fromAddr, p.ReqID, p)
   794  }
   795  
   796  // REQUESTTICKET
   797  
   798  func (p *requestTicketV5) name() string       { return "REQUESTTICKET/v5" }
   799  func (p *requestTicketV5) kind() byte         { return p_requestTicketV5 }
   800  func (p *requestTicketV5) setreqid(id []byte) { p.ReqID = id }
   801  
   802  func (p *requestTicketV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   803  	t.sendResponse(fromID, fromAddr, &ticketV5{ReqID: p.ReqID})
   804  }
   805  
   806  // TICKET
   807  
   808  func (p *ticketV5) name() string       { return "TICKET/v5" }
   809  func (p *ticketV5) kind() byte         { return p_ticketV5 }
   810  func (p *ticketV5) setreqid(id []byte) { p.ReqID = id }
   811  
   812  func (p *ticketV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   813  	t.handleCallResponse(fromID, fromAddr, p.ReqID, p)
   814  }
   815  
   816  // REGTOPIC
   817  
   818  func (p *regtopicV5) name() string       { return "REGTOPIC/v5" }
   819  func (p *regtopicV5) kind() byte         { return p_regtopicV5 }
   820  func (p *regtopicV5) setreqid(id []byte) { p.ReqID = id }
   821  
   822  func (p *regtopicV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   823  	t.sendResponse(fromID, fromAddr, &regconfirmationV5{ReqID: p.ReqID, Registered: false})
   824  }
   825  
   826  // REGCONFIRMATION
   827  
   828  func (p *regconfirmationV5) name() string       { return "REGCONFIRMATION/v5" }
   829  func (p *regconfirmationV5) kind() byte         { return p_regconfirmationV5 }
   830  func (p *regconfirmationV5) setreqid(id []byte) { p.ReqID = id }
   831  
   832  func (p *regconfirmationV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   833  	t.handleCallResponse(fromID, fromAddr, p.ReqID, p)
   834  }
   835  
   836  // TOPICQUERY
   837  
   838  func (p *topicqueryV5) name() string       { return "TOPICQUERY/v5" }
   839  func (p *topicqueryV5) kind() byte         { return p_topicqueryV5 }
   840  func (p *topicqueryV5) setreqid(id []byte) { p.ReqID = id }
   841  
   842  func (p *topicqueryV5) handle(t *UDPv5, fromID enode.ID, fromAddr *net.UDPAddr) {
   843  }