github.com/impedro29/bor@v0.1.4/p2p/discover/v4_udp.go (about)

     1  // Copyright 2015 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  	"container/list"
    22  	"crypto/ecdsa"
    23  	crand "crypto/rand"
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"net"
    28  	"sync"
    29  	"time"
    30  
    31  	"github.com/maticnetwork/bor/crypto"
    32  	"github.com/maticnetwork/bor/log"
    33  	"github.com/maticnetwork/bor/p2p/enode"
    34  	"github.com/maticnetwork/bor/p2p/enr"
    35  	"github.com/maticnetwork/bor/p2p/netutil"
    36  	"github.com/maticnetwork/bor/rlp"
    37  )
    38  
    39  // Errors
    40  var (
    41  	errPacketTooSmall   = errors.New("too small")
    42  	errBadHash          = errors.New("bad hash")
    43  	errExpired          = errors.New("expired")
    44  	errUnsolicitedReply = errors.New("unsolicited reply")
    45  	errUnknownNode      = errors.New("unknown node")
    46  	errTimeout          = errors.New("RPC timeout")
    47  	errClockWarp        = errors.New("reply deadline too far in the future")
    48  	errClosed           = errors.New("socket closed")
    49  )
    50  
    51  const (
    52  	respTimeout    = 500 * time.Millisecond
    53  	expiration     = 20 * time.Second
    54  	bondExpiration = 24 * time.Hour
    55  
    56  	maxFindnodeFailures = 5                // nodes exceeding this limit are dropped
    57  	ntpFailureThreshold = 32               // Continuous timeouts after which to check NTP
    58  	ntpWarningCooldown  = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning
    59  	driftThreshold      = 10 * time.Second // Allowed clock drift before warning user
    60  
    61  	// Discovery packets are defined to be no larger than 1280 bytes.
    62  	// Packets larger than this size will be cut at the end and treated
    63  	// as invalid because their hash won't match.
    64  	maxPacketSize = 1280
    65  )
    66  
    67  // RPC packet types
    68  const (
    69  	p_pingV4 = iota + 1 // zero is 'reserved'
    70  	p_pongV4
    71  	p_findnodeV4
    72  	p_neighborsV4
    73  	p_enrRequestV4
    74  	p_enrResponseV4
    75  )
    76  
    77  // RPC request structures
    78  type (
    79  	pingV4 struct {
    80  		senderKey *ecdsa.PublicKey // filled in by preverify
    81  
    82  		Version    uint
    83  		From, To   rpcEndpoint
    84  		Expiration uint64
    85  		// Ignore additional fields (for forward compatibility).
    86  		Rest []rlp.RawValue `rlp:"tail"`
    87  	}
    88  
    89  	// pongV4 is the reply to pingV4.
    90  	pongV4 struct {
    91  		// This field should mirror the UDP envelope address
    92  		// of the ping packet, which provides a way to discover the
    93  		// the external address (after NAT).
    94  		To rpcEndpoint
    95  
    96  		ReplyTok   []byte // This contains the hash of the ping packet.
    97  		Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
    98  		// Ignore additional fields (for forward compatibility).
    99  		Rest []rlp.RawValue `rlp:"tail"`
   100  	}
   101  
   102  	// findnodeV4 is a query for nodes close to the given target.
   103  	findnodeV4 struct {
   104  		Target     encPubkey
   105  		Expiration uint64
   106  		// Ignore additional fields (for forward compatibility).
   107  		Rest []rlp.RawValue `rlp:"tail"`
   108  	}
   109  
   110  	// neighborsV4 is the reply to findnodeV4.
   111  	neighborsV4 struct {
   112  		Nodes      []rpcNode
   113  		Expiration uint64
   114  		// Ignore additional fields (for forward compatibility).
   115  		Rest []rlp.RawValue `rlp:"tail"`
   116  	}
   117  
   118  	// enrRequestV4 queries for the remote node's record.
   119  	enrRequestV4 struct {
   120  		Expiration uint64
   121  		// Ignore additional fields (for forward compatibility).
   122  		Rest []rlp.RawValue `rlp:"tail"`
   123  	}
   124  
   125  	// enrResponseV4 is the reply to enrRequestV4.
   126  	enrResponseV4 struct {
   127  		ReplyTok []byte // Hash of the enrRequest packet.
   128  		Record   enr.Record
   129  		// Ignore additional fields (for forward compatibility).
   130  		Rest []rlp.RawValue `rlp:"tail"`
   131  	}
   132  
   133  	rpcNode struct {
   134  		IP  net.IP // len 4 for IPv4 or 16 for IPv6
   135  		UDP uint16 // for discovery protocol
   136  		TCP uint16 // for RLPx protocol
   137  		ID  encPubkey
   138  	}
   139  
   140  	rpcEndpoint struct {
   141  		IP  net.IP // len 4 for IPv4 or 16 for IPv6
   142  		UDP uint16 // for discovery protocol
   143  		TCP uint16 // for RLPx protocol
   144  	}
   145  )
   146  
   147  // packetV4 is implemented by all v4 protocol messages.
   148  type packetV4 interface {
   149  	// preverify checks whether the packet is valid and should be handled at all.
   150  	preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error
   151  	// handle handles the packet.
   152  	handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte)
   153  	// packet name and type for logging purposes.
   154  	name() string
   155  	kind() byte
   156  }
   157  
   158  func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {
   159  	ip := net.IP{}
   160  	if ip4 := addr.IP.To4(); ip4 != nil {
   161  		ip = ip4
   162  	} else if ip6 := addr.IP.To16(); ip6 != nil {
   163  		ip = ip6
   164  	}
   165  	return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
   166  }
   167  
   168  func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) {
   169  	if rn.UDP <= 1024 {
   170  		return nil, errors.New("low port")
   171  	}
   172  	if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
   173  		return nil, err
   174  	}
   175  	if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
   176  		return nil, errors.New("not contained in netrestrict whitelist")
   177  	}
   178  	key, err := decodePubkey(rn.ID)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	n := wrapNode(enode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP)))
   183  	err = n.ValidateComplete()
   184  	return n, err
   185  }
   186  
   187  func nodeToRPC(n *node) rpcNode {
   188  	var key ecdsa.PublicKey
   189  	var ekey encPubkey
   190  	if err := n.Load((*enode.Secp256k1)(&key)); err == nil {
   191  		ekey = encodePubkey(&key)
   192  	}
   193  	return rpcNode{ID: ekey, IP: n.IP(), UDP: uint16(n.UDP()), TCP: uint16(n.TCP())}
   194  }
   195  
   196  // UDPv4 implements the v4 wire protocol.
   197  type UDPv4 struct {
   198  	conn        UDPConn
   199  	log         log.Logger
   200  	netrestrict *netutil.Netlist
   201  	priv        *ecdsa.PrivateKey
   202  	localNode   *enode.LocalNode
   203  	db          *enode.DB
   204  	tab         *Table
   205  	closeOnce   sync.Once
   206  	wg          sync.WaitGroup
   207  
   208  	addReplyMatcher chan *replyMatcher
   209  	gotreply        chan reply
   210  	closing         chan struct{}
   211  }
   212  
   213  // replyMatcher represents a pending reply.
   214  //
   215  // Some implementations of the protocol wish to send more than one
   216  // reply packet to findnode. In general, any neighbors packet cannot
   217  // be matched up with a specific findnode packet.
   218  //
   219  // Our implementation handles this by storing a callback function for
   220  // each pending reply. Incoming packets from a node are dispatched
   221  // to all callback functions for that node.
   222  type replyMatcher struct {
   223  	// these fields must match in the reply.
   224  	from  enode.ID
   225  	ip    net.IP
   226  	ptype byte
   227  
   228  	// time when the request must complete
   229  	deadline time.Time
   230  
   231  	// callback is called when a matching reply arrives. If it returns matched == true, the
   232  	// reply was acceptable. The second return value indicates whether the callback should
   233  	// be removed from the pending reply queue. If it returns false, the reply is considered
   234  	// incomplete and the callback will be invoked again for the next matching reply.
   235  	callback replyMatchFunc
   236  
   237  	// errc receives nil when the callback indicates completion or an
   238  	// error if no further reply is received within the timeout.
   239  	errc chan error
   240  
   241  	// reply contains the most recent reply. This field is safe for reading after errc has
   242  	// received a value.
   243  	reply packetV4
   244  }
   245  
   246  type replyMatchFunc func(interface{}) (matched bool, requestDone bool)
   247  
   248  // reply is a reply packet from a certain node.
   249  type reply struct {
   250  	from enode.ID
   251  	ip   net.IP
   252  	data packetV4
   253  	// loop indicates whether there was
   254  	// a matching request by sending on this channel.
   255  	matched chan<- bool
   256  }
   257  
   258  func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
   259  	t := &UDPv4{
   260  		conn:            c,
   261  		priv:            cfg.PrivateKey,
   262  		netrestrict:     cfg.NetRestrict,
   263  		localNode:       ln,
   264  		db:              ln.Database(),
   265  		closing:         make(chan struct{}),
   266  		gotreply:        make(chan reply),
   267  		addReplyMatcher: make(chan *replyMatcher),
   268  		log:             cfg.Log,
   269  	}
   270  	if t.log == nil {
   271  		t.log = log.Root()
   272  	}
   273  	tab, err := newTable(t, ln.Database(), cfg.Bootnodes, t.log)
   274  	if err != nil {
   275  		return nil, err
   276  	}
   277  	t.tab = tab
   278  	go tab.loop()
   279  
   280  	t.wg.Add(2)
   281  	go t.loop()
   282  	go t.readLoop(cfg.Unhandled)
   283  	return t, nil
   284  }
   285  
   286  // Self returns the local node.
   287  func (t *UDPv4) Self() *enode.Node {
   288  	return t.localNode.Node()
   289  }
   290  
   291  // Close shuts down the socket and aborts any running queries.
   292  func (t *UDPv4) Close() {
   293  	t.closeOnce.Do(func() {
   294  		close(t.closing)
   295  		t.conn.Close()
   296  		t.wg.Wait()
   297  		t.tab.close()
   298  	})
   299  }
   300  
   301  // ReadRandomNodes reads random nodes from the local table.
   302  func (t *UDPv4) ReadRandomNodes(buf []*enode.Node) int {
   303  	return t.tab.ReadRandomNodes(buf)
   304  }
   305  
   306  // LookupRandom finds random nodes in the network.
   307  func (t *UDPv4) LookupRandom() []*enode.Node {
   308  	if t.tab.len() == 0 {
   309  		// All nodes were dropped, refresh. The very first query will hit this
   310  		// case and run the bootstrapping logic.
   311  		<-t.tab.refresh()
   312  	}
   313  	return t.lookupRandom()
   314  }
   315  
   316  func (t *UDPv4) LookupPubkey(key *ecdsa.PublicKey) []*enode.Node {
   317  	if t.tab.len() == 0 {
   318  		// All nodes were dropped, refresh. The very first query will hit this
   319  		// case and run the bootstrapping logic.
   320  		<-t.tab.refresh()
   321  	}
   322  	return unwrapNodes(t.lookup(encodePubkey(key)))
   323  }
   324  
   325  func (t *UDPv4) lookupRandom() []*enode.Node {
   326  	var target encPubkey
   327  	crand.Read(target[:])
   328  	return unwrapNodes(t.lookup(target))
   329  }
   330  
   331  func (t *UDPv4) lookupSelf() []*enode.Node {
   332  	return unwrapNodes(t.lookup(encodePubkey(&t.priv.PublicKey)))
   333  }
   334  
   335  // lookup performs a network search for nodes close to the given target. It approaches the
   336  // target by querying nodes that are closer to it on each iteration. The given target does
   337  // not need to be an actual node identifier.
   338  func (t *UDPv4) lookup(targetKey encPubkey) []*node {
   339  	var (
   340  		target         = enode.ID(crypto.Keccak256Hash(targetKey[:]))
   341  		asked          = make(map[enode.ID]bool)
   342  		seen           = make(map[enode.ID]bool)
   343  		reply          = make(chan []*node, alpha)
   344  		pendingQueries = 0
   345  		result         *nodesByDistance
   346  	)
   347  	// Don't query further if we hit ourself.
   348  	// Unlikely to happen often in practice.
   349  	asked[t.Self().ID()] = true
   350  
   351  	// Generate the initial result set.
   352  	t.tab.mutex.Lock()
   353  	result = t.tab.closest(target, bucketSize, false)
   354  	t.tab.mutex.Unlock()
   355  
   356  	for {
   357  		// ask the alpha closest nodes that we haven't asked yet
   358  		for i := 0; i < len(result.entries) && pendingQueries < alpha; i++ {
   359  			n := result.entries[i]
   360  			if !asked[n.ID()] {
   361  				asked[n.ID()] = true
   362  				pendingQueries++
   363  				go t.lookupWorker(n, targetKey, reply)
   364  			}
   365  		}
   366  		if pendingQueries == 0 {
   367  			// we have asked all closest nodes, stop the search
   368  			break
   369  		}
   370  		select {
   371  		case nodes := <-reply:
   372  			for _, n := range nodes {
   373  				if n != nil && !seen[n.ID()] {
   374  					seen[n.ID()] = true
   375  					result.push(n, bucketSize)
   376  				}
   377  			}
   378  		case <-t.tab.closeReq:
   379  			return nil // shutdown, no need to continue.
   380  		}
   381  		pendingQueries--
   382  	}
   383  	return result.entries
   384  }
   385  
   386  func (t *UDPv4) lookupWorker(n *node, targetKey encPubkey, reply chan<- []*node) {
   387  	fails := t.db.FindFails(n.ID(), n.IP())
   388  	r, err := t.findnode(n.ID(), n.addr(), targetKey)
   389  	if err == errClosed {
   390  		// Avoid recording failures on shutdown.
   391  		reply <- nil
   392  		return
   393  	} else if len(r) == 0 {
   394  		fails++
   395  		t.db.UpdateFindFails(n.ID(), n.IP(), fails)
   396  		t.log.Trace("Findnode failed", "id", n.ID(), "failcount", fails, "err", err)
   397  		if fails >= maxFindnodeFailures {
   398  			t.log.Trace("Too many findnode failures, dropping", "id", n.ID(), "failcount", fails)
   399  			t.tab.delete(n)
   400  		}
   401  	} else if fails > 0 {
   402  		// Reset failure counter because it counts _consecutive_ failures.
   403  		t.db.UpdateFindFails(n.ID(), n.IP(), 0)
   404  	}
   405  
   406  	// Grab as many nodes as possible. Some of them might not be alive anymore, but we'll
   407  	// just remove those again during revalidation.
   408  	for _, n := range r {
   409  		t.tab.addSeenNode(n)
   410  	}
   411  	reply <- r
   412  }
   413  
   414  // Resolve searches for a specific node with the given ID and tries to get the most recent
   415  // version of the node record for it. It returns n if the node could not be resolved.
   416  func (t *UDPv4) Resolve(n *enode.Node) *enode.Node {
   417  	// Try asking directly. This works if the node is still responding on the endpoint we have.
   418  	if rn, err := t.RequestENR(n); err == nil {
   419  		return rn
   420  	}
   421  	// Check table for the ID, we might have a newer version there.
   422  	if intable := t.tab.getNode(n.ID()); intable != nil && intable.Seq() > n.Seq() {
   423  		n = intable
   424  		if rn, err := t.RequestENR(n); err == nil {
   425  			return rn
   426  		}
   427  	}
   428  	// Otherwise perform a network lookup.
   429  	var key enode.Secp256k1
   430  	if n.Load(&key) != nil {
   431  		return n // no secp256k1 key
   432  	}
   433  	result := t.LookupPubkey((*ecdsa.PublicKey)(&key))
   434  	for _, rn := range result {
   435  		if rn.ID() == n.ID() {
   436  			if rn, err := t.RequestENR(rn); err == nil {
   437  				return rn
   438  			}
   439  		}
   440  	}
   441  	return n
   442  }
   443  
   444  func (t *UDPv4) ourEndpoint() rpcEndpoint {
   445  	n := t.Self()
   446  	a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
   447  	return makeEndpoint(a, uint16(n.TCP()))
   448  }
   449  
   450  // Ping sends a ping message to the given node.
   451  func (t *UDPv4) Ping(n *enode.Node) error {
   452  	_, err := t.ping(n)
   453  	return err
   454  }
   455  
   456  // ping sends a ping message to the given node and waits for a reply.
   457  func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
   458  	rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil)
   459  	if err = <-rm.errc; err == nil {
   460  		seq = seqFromTail(rm.reply.(*pongV4).Rest)
   461  	}
   462  	return seq, err
   463  }
   464  
   465  // sendPing sends a ping message to the given node and invokes the callback
   466  // when the reply arrives.
   467  func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher {
   468  	req := t.makePing(toaddr)
   469  	packet, hash, err := t.encode(t.priv, req)
   470  	if err != nil {
   471  		errc := make(chan error, 1)
   472  		errc <- err
   473  		return &replyMatcher{errc: errc}
   474  	}
   475  	// Add a matcher for the reply to the pending reply queue. Pongs are matched if they
   476  	// reference the ping we're about to send.
   477  	rm := t.pending(toid, toaddr.IP, p_pongV4, func(p interface{}) (matched bool, requestDone bool) {
   478  		matched = bytes.Equal(p.(*pongV4).ReplyTok, hash)
   479  		if matched && callback != nil {
   480  			callback()
   481  		}
   482  		return matched, matched
   483  	})
   484  	// Send the packet.
   485  	t.localNode.UDPContact(toaddr)
   486  	t.write(toaddr, toid, req.name(), packet)
   487  	return rm
   488  }
   489  
   490  func (t *UDPv4) makePing(toaddr *net.UDPAddr) *pingV4 {
   491  	seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq())
   492  	return &pingV4{
   493  		Version:    4,
   494  		From:       t.ourEndpoint(),
   495  		To:         makeEndpoint(toaddr, 0),
   496  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   497  		Rest:       []rlp.RawValue{seq},
   498  	}
   499  }
   500  
   501  // findnode sends a findnode request to the given node and waits until
   502  // the node has sent up to k neighbors.
   503  func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target encPubkey) ([]*node, error) {
   504  	t.ensureBond(toid, toaddr)
   505  
   506  	// Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is
   507  	// active until enough nodes have been received.
   508  	nodes := make([]*node, 0, bucketSize)
   509  	nreceived := 0
   510  	rm := t.pending(toid, toaddr.IP, p_neighborsV4, func(r interface{}) (matched bool, requestDone bool) {
   511  		reply := r.(*neighborsV4)
   512  		for _, rn := range reply.Nodes {
   513  			nreceived++
   514  			n, err := t.nodeFromRPC(toaddr, rn)
   515  			if err != nil {
   516  				t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err)
   517  				continue
   518  			}
   519  			nodes = append(nodes, n)
   520  		}
   521  		return true, nreceived >= bucketSize
   522  	})
   523  	t.send(toaddr, toid, &findnodeV4{
   524  		Target:     target,
   525  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   526  	})
   527  	return nodes, <-rm.errc
   528  }
   529  
   530  // RequestENR sends enrRequest to the given node and waits for a response.
   531  func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
   532  	addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
   533  	t.ensureBond(n.ID(), addr)
   534  
   535  	req := &enrRequestV4{
   536  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   537  	}
   538  	packet, hash, err := t.encode(t.priv, req)
   539  	if err != nil {
   540  		return nil, err
   541  	}
   542  	// Add a matcher for the reply to the pending reply queue. Responses are matched if
   543  	// they reference the request we're about to send.
   544  	rm := t.pending(n.ID(), addr.IP, p_enrResponseV4, func(r interface{}) (matched bool, requestDone bool) {
   545  		matched = bytes.Equal(r.(*enrResponseV4).ReplyTok, hash)
   546  		return matched, matched
   547  	})
   548  	// Send the packet and wait for the reply.
   549  	t.write(addr, n.ID(), req.name(), packet)
   550  	if err := <-rm.errc; err != nil {
   551  		return nil, err
   552  	}
   553  	// Verify the response record.
   554  	respN, err := enode.New(enode.ValidSchemes, &rm.reply.(*enrResponseV4).Record)
   555  	if err != nil {
   556  		return nil, err
   557  	}
   558  	if respN.ID() != n.ID() {
   559  		return nil, fmt.Errorf("invalid ID in response record")
   560  	}
   561  	if respN.Seq() < n.Seq() {
   562  		return n, nil // response record is older
   563  	}
   564  	if err := netutil.CheckRelayIP(addr.IP, respN.IP()); err != nil {
   565  		return nil, fmt.Errorf("invalid IP in response record: %v", err)
   566  	}
   567  	return respN, nil
   568  }
   569  
   570  // pending adds a reply matcher to the pending reply queue.
   571  // see the documentation of type replyMatcher for a detailed explanation.
   572  func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchFunc) *replyMatcher {
   573  	ch := make(chan error, 1)
   574  	p := &replyMatcher{from: id, ip: ip, ptype: ptype, callback: callback, errc: ch}
   575  	select {
   576  	case t.addReplyMatcher <- p:
   577  		// loop will handle it
   578  	case <-t.closing:
   579  		ch <- errClosed
   580  	}
   581  	return p
   582  }
   583  
   584  // handleReply dispatches a reply packet, invoking reply matchers. It returns
   585  // whether any matcher considered the packet acceptable.
   586  func (t *UDPv4) handleReply(from enode.ID, fromIP net.IP, req packetV4) bool {
   587  	matched := make(chan bool, 1)
   588  	select {
   589  	case t.gotreply <- reply{from, fromIP, req, matched}:
   590  		// loop will handle it
   591  		return <-matched
   592  	case <-t.closing:
   593  		return false
   594  	}
   595  }
   596  
   597  // loop runs in its own goroutine. it keeps track of
   598  // the refresh timer and the pending reply queue.
   599  func (t *UDPv4) loop() {
   600  	defer t.wg.Done()
   601  
   602  	var (
   603  		plist        = list.New()
   604  		timeout      = time.NewTimer(0)
   605  		nextTimeout  *replyMatcher // head of plist when timeout was last reset
   606  		contTimeouts = 0           // number of continuous timeouts to do NTP checks
   607  		ntpWarnTime  = time.Unix(0, 0)
   608  	)
   609  	<-timeout.C // ignore first timeout
   610  	defer timeout.Stop()
   611  
   612  	resetTimeout := func() {
   613  		if plist.Front() == nil || nextTimeout == plist.Front().Value {
   614  			return
   615  		}
   616  		// Start the timer so it fires when the next pending reply has expired.
   617  		now := time.Now()
   618  		for el := plist.Front(); el != nil; el = el.Next() {
   619  			nextTimeout = el.Value.(*replyMatcher)
   620  			if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout {
   621  				timeout.Reset(dist)
   622  				return
   623  			}
   624  			// Remove pending replies whose deadline is too far in the
   625  			// future. These can occur if the system clock jumped
   626  			// backwards after the deadline was assigned.
   627  			nextTimeout.errc <- errClockWarp
   628  			plist.Remove(el)
   629  		}
   630  		nextTimeout = nil
   631  		timeout.Stop()
   632  	}
   633  
   634  	for {
   635  		resetTimeout()
   636  
   637  		select {
   638  		case <-t.closing:
   639  			for el := plist.Front(); el != nil; el = el.Next() {
   640  				el.Value.(*replyMatcher).errc <- errClosed
   641  			}
   642  			return
   643  
   644  		case p := <-t.addReplyMatcher:
   645  			p.deadline = time.Now().Add(respTimeout)
   646  			plist.PushBack(p)
   647  
   648  		case r := <-t.gotreply:
   649  			var matched bool // whether any replyMatcher considered the reply acceptable.
   650  			for el := plist.Front(); el != nil; el = el.Next() {
   651  				p := el.Value.(*replyMatcher)
   652  				if p.from == r.from && p.ptype == r.data.kind() && p.ip.Equal(r.ip) {
   653  					ok, requestDone := p.callback(r.data)
   654  					matched = matched || ok
   655  					// Remove the matcher if callback indicates that all replies have been received.
   656  					if requestDone {
   657  						p.reply = r.data
   658  						p.errc <- nil
   659  						plist.Remove(el)
   660  					}
   661  					// Reset the continuous timeout counter (time drift detection)
   662  					contTimeouts = 0
   663  				}
   664  			}
   665  			r.matched <- matched
   666  
   667  		case now := <-timeout.C:
   668  			nextTimeout = nil
   669  
   670  			// Notify and remove callbacks whose deadline is in the past.
   671  			for el := plist.Front(); el != nil; el = el.Next() {
   672  				p := el.Value.(*replyMatcher)
   673  				if now.After(p.deadline) || now.Equal(p.deadline) {
   674  					p.errc <- errTimeout
   675  					plist.Remove(el)
   676  					contTimeouts++
   677  				}
   678  			}
   679  			// If we've accumulated too many timeouts, do an NTP time sync check
   680  			if contTimeouts > ntpFailureThreshold {
   681  				if time.Since(ntpWarnTime) >= ntpWarningCooldown {
   682  					ntpWarnTime = time.Now()
   683  					go checkClockDrift()
   684  				}
   685  				contTimeouts = 0
   686  			}
   687  		}
   688  	}
   689  }
   690  
   691  const (
   692  	macSize  = 256 / 8
   693  	sigSize  = 520 / 8
   694  	headSize = macSize + sigSize // space of packet frame data
   695  )
   696  
   697  var (
   698  	headSpace = make([]byte, headSize)
   699  
   700  	// Neighbors replies are sent across multiple packets to
   701  	// stay below the packet size limit. We compute the maximum number
   702  	// of entries by stuffing a packet until it grows too large.
   703  	maxNeighbors int
   704  )
   705  
   706  func init() {
   707  	p := neighborsV4{Expiration: ^uint64(0)}
   708  	maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
   709  	for n := 0; ; n++ {
   710  		p.Nodes = append(p.Nodes, maxSizeNode)
   711  		size, _, err := rlp.EncodeToReader(p)
   712  		if err != nil {
   713  			// If this ever happens, it will be caught by the unit tests.
   714  			panic("cannot encode: " + err.Error())
   715  		}
   716  		if headSize+size+1 >= maxPacketSize {
   717  			maxNeighbors = n
   718  			break
   719  		}
   720  	}
   721  }
   722  
   723  func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req packetV4) ([]byte, error) {
   724  	packet, hash, err := t.encode(t.priv, req)
   725  	if err != nil {
   726  		return hash, err
   727  	}
   728  	return hash, t.write(toaddr, toid, req.name(), packet)
   729  }
   730  
   731  func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error {
   732  	_, err := t.conn.WriteToUDP(packet, toaddr)
   733  	t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err)
   734  	return err
   735  }
   736  
   737  func (t *UDPv4) encode(priv *ecdsa.PrivateKey, req packetV4) (packet, hash []byte, err error) {
   738  	name := req.name()
   739  	b := new(bytes.Buffer)
   740  	b.Write(headSpace)
   741  	b.WriteByte(req.kind())
   742  	if err := rlp.Encode(b, req); err != nil {
   743  		t.log.Error(fmt.Sprintf("Can't encode %s packet", name), "err", err)
   744  		return nil, nil, err
   745  	}
   746  	packet = b.Bytes()
   747  	sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv)
   748  	if err != nil {
   749  		t.log.Error(fmt.Sprintf("Can't sign %s packet", name), "err", err)
   750  		return nil, nil, err
   751  	}
   752  	copy(packet[macSize:], sig)
   753  	// add the hash to the front. Note: this doesn't protect the
   754  	// packet in any way. Our public key will be part of this hash in
   755  	// The future.
   756  	hash = crypto.Keccak256(packet[macSize:])
   757  	copy(packet, hash)
   758  	return packet, hash, nil
   759  }
   760  
   761  // readLoop runs in its own goroutine. it handles incoming UDP packets.
   762  func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) {
   763  	defer t.wg.Done()
   764  	if unhandled != nil {
   765  		defer close(unhandled)
   766  	}
   767  
   768  	buf := make([]byte, maxPacketSize)
   769  	for {
   770  		nbytes, from, err := t.conn.ReadFromUDP(buf)
   771  		if netutil.IsTemporaryError(err) {
   772  			// Ignore temporary read errors.
   773  			t.log.Debug("Temporary UDP read error", "err", err)
   774  			continue
   775  		} else if err != nil {
   776  			// Shut down the loop for permament errors.
   777  			if err != io.EOF {
   778  				t.log.Debug("UDP read error", "err", err)
   779  			}
   780  			return
   781  		}
   782  		if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil {
   783  			select {
   784  			case unhandled <- ReadPacket{buf[:nbytes], from}:
   785  			default:
   786  			}
   787  		}
   788  	}
   789  }
   790  
   791  func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error {
   792  	packet, fromKey, hash, err := decodeV4(buf)
   793  	if err != nil {
   794  		t.log.Debug("Bad discv4 packet", "addr", from, "err", err)
   795  		return err
   796  	}
   797  	fromID := fromKey.id()
   798  	if err == nil {
   799  		err = packet.preverify(t, from, fromID, fromKey)
   800  	}
   801  	t.log.Trace("<< "+packet.name(), "id", fromID, "addr", from, "err", err)
   802  	if err == nil {
   803  		packet.handle(t, from, fromID, hash)
   804  	}
   805  	return err
   806  }
   807  
   808  func decodeV4(buf []byte) (packetV4, encPubkey, []byte, error) {
   809  	if len(buf) < headSize+1 {
   810  		return nil, encPubkey{}, nil, errPacketTooSmall
   811  	}
   812  	hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
   813  	shouldhash := crypto.Keccak256(buf[macSize:])
   814  	if !bytes.Equal(hash, shouldhash) {
   815  		return nil, encPubkey{}, nil, errBadHash
   816  	}
   817  	fromKey, err := recoverNodeKey(crypto.Keccak256(buf[headSize:]), sig)
   818  	if err != nil {
   819  		return nil, fromKey, hash, err
   820  	}
   821  
   822  	var req packetV4
   823  	switch ptype := sigdata[0]; ptype {
   824  	case p_pingV4:
   825  		req = new(pingV4)
   826  	case p_pongV4:
   827  		req = new(pongV4)
   828  	case p_findnodeV4:
   829  		req = new(findnodeV4)
   830  	case p_neighborsV4:
   831  		req = new(neighborsV4)
   832  	case p_enrRequestV4:
   833  		req = new(enrRequestV4)
   834  	case p_enrResponseV4:
   835  		req = new(enrResponseV4)
   836  	default:
   837  		return nil, fromKey, hash, fmt.Errorf("unknown type: %d", ptype)
   838  	}
   839  	s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0)
   840  	err = s.Decode(req)
   841  	return req, fromKey, hash, err
   842  }
   843  
   844  // checkBond checks if the given node has a recent enough endpoint proof.
   845  func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool {
   846  	return time.Since(t.db.LastPongReceived(id, ip)) < bondExpiration
   847  }
   848  
   849  // ensureBond solicits a ping from a node if we haven't seen a ping from it for a while.
   850  // This ensures there is a valid endpoint proof on the remote end.
   851  func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) {
   852  	tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration
   853  	if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures {
   854  		rm := t.sendPing(toid, toaddr, nil)
   855  		<-rm.errc
   856  		// Wait for them to ping back and process our pong.
   857  		time.Sleep(respTimeout)
   858  	}
   859  }
   860  
   861  // expired checks whether the given UNIX time stamp is in the past.
   862  func expired(ts uint64) bool {
   863  	return time.Unix(int64(ts), 0).Before(time.Now())
   864  }
   865  
   866  func seqFromTail(tail []rlp.RawValue) uint64 {
   867  	if len(tail) == 0 {
   868  		return 0
   869  	}
   870  	var seq uint64
   871  	rlp.DecodeBytes(tail[0], &seq)
   872  	return seq
   873  }
   874  
   875  // PING/v4
   876  
   877  func (req *pingV4) name() string { return "PING/v4" }
   878  func (req *pingV4) kind() byte   { return p_pingV4 }
   879  
   880  func (req *pingV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
   881  	if expired(req.Expiration) {
   882  		return errExpired
   883  	}
   884  	key, err := decodePubkey(fromKey)
   885  	if err != nil {
   886  		return errors.New("invalid public key")
   887  	}
   888  	req.senderKey = key
   889  	return nil
   890  }
   891  
   892  func (req *pingV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
   893  	// Reply.
   894  	seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq())
   895  	t.send(from, fromID, &pongV4{
   896  		To:         makeEndpoint(from, req.From.TCP),
   897  		ReplyTok:   mac,
   898  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   899  		Rest:       []rlp.RawValue{seq},
   900  	})
   901  
   902  	// Ping back if our last pong on file is too far in the past.
   903  	n := wrapNode(enode.NewV4(req.senderKey, from.IP, int(req.From.TCP), from.Port))
   904  	if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration {
   905  		t.sendPing(fromID, from, func() {
   906  			t.tab.addVerifiedNode(n)
   907  		})
   908  	} else {
   909  		t.tab.addVerifiedNode(n)
   910  	}
   911  
   912  	// Update node database and endpoint predictor.
   913  	t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now())
   914  	t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
   915  }
   916  
   917  // PONG/v4
   918  
   919  func (req *pongV4) name() string { return "PONG/v4" }
   920  func (req *pongV4) kind() byte   { return p_pongV4 }
   921  
   922  func (req *pongV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
   923  	if expired(req.Expiration) {
   924  		return errExpired
   925  	}
   926  	if !t.handleReply(fromID, from.IP, req) {
   927  		return errUnsolicitedReply
   928  	}
   929  	return nil
   930  }
   931  
   932  func (req *pongV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
   933  	t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
   934  	t.db.UpdateLastPongReceived(fromID, from.IP, time.Now())
   935  }
   936  
   937  // FINDNODE/v4
   938  
   939  func (req *findnodeV4) name() string { return "FINDNODE/v4" }
   940  func (req *findnodeV4) kind() byte   { return p_findnodeV4 }
   941  
   942  func (req *findnodeV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
   943  	if expired(req.Expiration) {
   944  		return errExpired
   945  	}
   946  	if !t.checkBond(fromID, from.IP) {
   947  		// No endpoint proof pong exists, we don't process the packet. This prevents an
   948  		// attack vector where the discovery protocol could be used to amplify traffic in a
   949  		// DDOS attack. A malicious actor would send a findnode request with the IP address
   950  		// and UDP port of the target as the source address. The recipient of the findnode
   951  		// packet would then send a neighbors packet (which is a much bigger packet than
   952  		// findnode) to the victim.
   953  		return errUnknownNode
   954  	}
   955  	return nil
   956  }
   957  
   958  func (req *findnodeV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
   959  	// Determine closest nodes.
   960  	target := enode.ID(crypto.Keccak256Hash(req.Target[:]))
   961  	t.tab.mutex.Lock()
   962  	closest := t.tab.closest(target, bucketSize, true).entries
   963  	t.tab.mutex.Unlock()
   964  
   965  	// Send neighbors in chunks with at most maxNeighbors per packet
   966  	// to stay below the packet size limit.
   967  	p := neighborsV4{Expiration: uint64(time.Now().Add(expiration).Unix())}
   968  	var sent bool
   969  	for _, n := range closest {
   970  		if netutil.CheckRelayIP(from.IP, n.IP()) == nil {
   971  			p.Nodes = append(p.Nodes, nodeToRPC(n))
   972  		}
   973  		if len(p.Nodes) == maxNeighbors {
   974  			t.send(from, fromID, &p)
   975  			p.Nodes = p.Nodes[:0]
   976  			sent = true
   977  		}
   978  	}
   979  	if len(p.Nodes) > 0 || !sent {
   980  		t.send(from, fromID, &p)
   981  	}
   982  }
   983  
   984  // NEIGHBORS/v4
   985  
   986  func (req *neighborsV4) name() string { return "NEIGHBORS/v4" }
   987  func (req *neighborsV4) kind() byte   { return p_neighborsV4 }
   988  
   989  func (req *neighborsV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
   990  	if expired(req.Expiration) {
   991  		return errExpired
   992  	}
   993  	if !t.handleReply(fromID, from.IP, req) {
   994  		return errUnsolicitedReply
   995  	}
   996  	return nil
   997  }
   998  
   999  func (req *neighborsV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
  1000  }
  1001  
  1002  // ENRREQUEST/v4
  1003  
  1004  func (req *enrRequestV4) name() string { return "ENRREQUEST/v4" }
  1005  func (req *enrRequestV4) kind() byte   { return p_enrRequestV4 }
  1006  
  1007  func (req *enrRequestV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
  1008  	if expired(req.Expiration) {
  1009  		return errExpired
  1010  	}
  1011  	if !t.checkBond(fromID, from.IP) {
  1012  		return errUnknownNode
  1013  	}
  1014  	return nil
  1015  }
  1016  
  1017  func (req *enrRequestV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
  1018  	t.send(from, fromID, &enrResponseV4{
  1019  		ReplyTok: mac,
  1020  		Record:   *t.localNode.Node().Record(),
  1021  	})
  1022  }
  1023  
  1024  // ENRRESPONSE/v4
  1025  
  1026  func (req *enrResponseV4) name() string { return "ENRRESPONSE/v4" }
  1027  func (req *enrResponseV4) kind() byte   { return p_enrResponseV4 }
  1028  
  1029  func (req *enrResponseV4) preverify(t *UDPv4, from *net.UDPAddr, fromID enode.ID, fromKey encPubkey) error {
  1030  	if !t.handleReply(fromID, from.IP, req) {
  1031  		return errUnsolicitedReply
  1032  	}
  1033  	return nil
  1034  }
  1035  
  1036  func (req *enrResponseV4) handle(t *UDPv4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
  1037  }