github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/p2p/discover/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  	"errors"
    24  	"fmt"
    25  	"net"
    26  	"time"
    27  
    28  	"github.com/ethereumproject/go-ethereum/crypto"
    29  	"github.com/ethereumproject/go-ethereum/logger"
    30  	"github.com/ethereumproject/go-ethereum/logger/glog"
    31  	"github.com/ethereumproject/go-ethereum/p2p/distip"
    32  	"github.com/ethereumproject/go-ethereum/p2p/nat"
    33  	"github.com/ethereumproject/go-ethereum/rlp"
    34  )
    35  
    36  const Version = 4
    37  
    38  // Errors
    39  var (
    40  	errPacketTooSmall   = errors.New("too small")
    41  	errBadHash          = errors.New("bad hash")
    42  	errExpired          = errors.New("expired")
    43  	errUnsolicitedReply = errors.New("unsolicited reply")
    44  	errUnknownNode      = errors.New("unknown node")
    45  	errReservedAddress  = errors.New("reserved address neighbor from non-reserved source")
    46  	errInvalidIp        = errors.New("invalid ip")
    47  	errTimeout          = errors.New("RPC timeout")
    48  	errClockWarp        = errors.New("reply deadline too far in the future")
    49  	errClosed           = errors.New("socket closed")
    50  
    51  	// Note: golang/net.IP provides some similar functionality via #IsLinkLocalUnicast, ...Multicast, etc.
    52  	// I would rather duplicate the information in a unified and comprehensive system than
    53  	// patch-in with a couple available library methods.
    54  	// I expect many of these occasions will be very unlikely.
    55  	//
    56  	// IPv4
    57  	Ipv4ReservedRangeThis               = [2]net.IP{net.ParseIP("0.0.0.0"), net.ParseIP("0.255.255.255")}
    58  	Ipv4ReservedRangePrivateNetwork     = [2]net.IP{net.ParseIP("10.0.0.0"), net.ParseIP("10.255.255.255")}
    59  	ipv4ReservedRangeProviderSubscriber = [2]net.IP{net.ParseIP("100.64.0.0"), net.ParseIP("100.127.255.255")}
    60  	Ipv4ReservedRangeLoopback           = [2]net.IP{net.ParseIP("127.0.0.0"), net.ParseIP("127.255.255.255")}
    61  	ipv4ReservedRangeLinkLocal          = [2]net.IP{net.ParseIP("169.254.0.0"), net.ParseIP("169.254.255.255")}
    62  	ipv4ReservedRangeLocalPrivate1      = [2]net.IP{net.ParseIP("172.16.0.0"), net.ParseIP("172.31.255.255")}
    63  	ipv4ReservedRangeSpecialPurpose     = [2]net.IP{net.ParseIP("192.0.0.0"), net.ParseIP("192.0.0.255")}
    64  	ipv4ReservedRangeTestNet1           = [2]net.IP{net.ParseIP("192.0.2.0"), net.ParseIP("192.0.2.255")}
    65  	ipv4ReservedRange6to4               = [2]net.IP{net.ParseIP("192.88.99.0"), net.ParseIP("192.88.99.255")}
    66  	Ipv4ReservedRangeLocalPrivate2      = [2]net.IP{net.ParseIP("192.168.0.0"), net.ParseIP("192.168.255.255")}
    67  	ipv4ReservedRangeSubnets            = [2]net.IP{net.ParseIP("198.18.0.0"), net.ParseIP("198.19.255.255")}
    68  	ipv4ReservedRangeTestNet2           = [2]net.IP{net.ParseIP("198.51.100.0"), net.ParseIP("198.51.100.255")}
    69  	ipv4ReservedRangeTestNet3           = [2]net.IP{net.ParseIP("203.0.113.0"), net.ParseIP("203.0.113.255")}
    70  	ipv4ReservedRangeMulticast          = [2]net.IP{net.ParseIP("224.0.0.0"), net.ParseIP("239.255.255.255")}
    71  	ipv4ReservedRangeFuture             = [2]net.IP{net.ParseIP("240.0.0.0"), net.ParseIP("255.255.255.254")}
    72  	ipv4ReservedRangeLimitedBroadcast   = [2]net.IP{net.ParseIP("255.255.255.255"), net.ParseIP("255.255.255.255")}
    73  
    74  	// IPv6
    75  	ipv6ReservedRangeUnspecified   = [2]net.IP{net.ParseIP("::"), net.ParseIP("::")}
    76  	Ipv6ReservedRangeLoopback      = [2]net.IP{net.ParseIP("::1"), net.ParseIP("::1")}
    77  	ipv6ReservedRangeDocumentation = [2]net.IP{net.ParseIP("2001:db8::"), net.ParseIP("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")}
    78  	ipv6ReservedRange6to4          = [2]net.IP{net.ParseIP("2002::"), net.ParseIP("2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
    79  	ipv6ReservedRangeUniqueLocal   = [2]net.IP{net.ParseIP("fc00::"), net.ParseIP("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
    80  	ipv6ReservedRangeLinkLocal     = [2]net.IP{net.ParseIP("fe80::"), net.ParseIP("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
    81  	ipv6ReservedRangeMulticast     = [2]net.IP{net.ParseIP("ff00::"), net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
    82  )
    83  
    84  // Timeouts
    85  const (
    86  	respTimeout = 500 * time.Millisecond
    87  	expiration  = 20 * time.Second
    88  
    89  	ntpFailureThreshold = 32               // Continuous timeouts after which to check NTP
    90  	ntpWarningCooldown  = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning
    91  	driftThreshold      = 10 * time.Second // Allowed clock drift before warning user
    92  )
    93  
    94  // RPC packet types
    95  const (
    96  	pingPacket = iota + 1 // zero is 'reserved'
    97  	pongPacket
    98  	findnodePacket
    99  	neighborsPacket
   100  )
   101  
   102  // RPC request structures
   103  type (
   104  	ping struct {
   105  		Version    uint
   106  		From, To   rpcEndpoint
   107  		Expiration uint64
   108  		// Ignore additional fields (for forward compatibility).
   109  		Rest []rlp.RawValue `rlp:"tail"`
   110  	}
   111  
   112  	// pong is the reply to ping.
   113  	pong struct {
   114  		// This field should mirror the UDP envelope address
   115  		// of the ping packet, which provides a way to discover the
   116  		// the external address (after NAT).
   117  		To rpcEndpoint
   118  
   119  		ReplyTok   []byte // This contains the hash of the ping packet.
   120  		Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
   121  		// Ignore additional fields (for forward compatibility).
   122  		Rest []rlp.RawValue `rlp:"tail"`
   123  	}
   124  
   125  	// findnode is a query for nodes close to the given target.
   126  	findnode struct {
   127  		Target     NodeID // doesn't need to be an actual public key
   128  		Expiration uint64
   129  		// Ignore additional fields (for forward compatibility).
   130  		Rest []rlp.RawValue `rlp:"tail"`
   131  	}
   132  
   133  	// reply to findnode
   134  	neighbors struct {
   135  		Nodes      []rpcNode
   136  		Expiration uint64
   137  		// Ignore additional fields (for forward compatibility).
   138  		Rest []rlp.RawValue `rlp:"tail"`
   139  	}
   140  
   141  	rpcNode struct {
   142  		IP  net.IP // len 4 for IPv4 or 16 for IPv6
   143  		UDP uint16 // for discovery protocol
   144  		TCP uint16 // for RLPx protocol
   145  		ID  NodeID
   146  	}
   147  
   148  	rpcEndpoint struct {
   149  		IP  net.IP // len 4 for IPv4 or 16 for IPv6
   150  		UDP uint16 // for discovery protocol
   151  		TCP uint16 // for RLPx protocol
   152  	}
   153  )
   154  
   155  func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {
   156  	ip := addr.IP.To4()
   157  	if ip == nil {
   158  		ip = addr.IP.To16()
   159  	}
   160  	return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
   161  }
   162  
   163  func (t *udp) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*Node, error) {
   164  	if rn.UDP <= 1024 {
   165  		return nil, errors.New("low port")
   166  	}
   167  	if err := distip.CheckRelayIP(sender.IP, rn.IP); err != nil {
   168  		return nil, err
   169  	}
   170  	if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
   171  		return nil, errors.New("not contained in netrestrict whitelist")
   172  	}
   173  	n := NewNode(rn.ID, rn.IP, rn.UDP, rn.TCP)
   174  	err := n.validateComplete()
   175  	return n, err
   176  }
   177  
   178  func nodeToRPC(n *Node) rpcNode {
   179  	return rpcNode{ID: n.ID, IP: n.IP, UDP: n.UDP, TCP: n.TCP}
   180  }
   181  
   182  type packet interface {
   183  	handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error
   184  }
   185  
   186  type conn interface {
   187  	ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error)
   188  	WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error)
   189  	Close() error
   190  	LocalAddr() net.Addr
   191  }
   192  
   193  // udp implements the RPC protocol.
   194  type udp struct {
   195  	conn        conn
   196  	netrestrict *distip.Netlist
   197  	priv        *ecdsa.PrivateKey
   198  	ourEndpoint rpcEndpoint
   199  
   200  	addpending chan *pending
   201  	gotreply   chan reply
   202  
   203  	closing chan struct{}
   204  
   205  	*Table
   206  }
   207  
   208  // pending represents a pending reply.
   209  //
   210  // some implementations of the protocol wish to send more than one
   211  // reply packet to findnode. in general, any neighbors packet cannot
   212  // be matched up with a specific findnode packet.
   213  //
   214  // our implementation handles this by storing a callback function for
   215  // each pending reply. incoming packets from a node are dispatched
   216  // to all the callback functions for that node.
   217  type pending struct {
   218  	// these fields must match in the reply.
   219  	from  NodeID
   220  	ptype byte
   221  
   222  	// time when the request must complete
   223  	deadline time.Time
   224  
   225  	// callback is called when a matching reply arrives. if it returns
   226  	// true, the callback is removed from the pending reply queue.
   227  	// if it returns false, the reply is considered incomplete and
   228  	// the callback will be invoked again for the next matching reply.
   229  	callback func(resp interface{}) (done bool)
   230  
   231  	// errc receives nil when the callback indicates completion or an
   232  	// error if no further reply is received within the timeout.
   233  	errc chan<- error
   234  }
   235  
   236  type reply struct {
   237  	from  NodeID
   238  	ptype byte
   239  	data  interface{}
   240  	// loop indicates whether there was
   241  	// a matching request by sending on this channel.
   242  	matched chan<- bool
   243  }
   244  
   245  // ListenUDP returns a new table that listens for UDP packets on laddr.
   246  func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBPath string) (*Table, error) {
   247  	addr, err := net.ResolveUDPAddr("udp", laddr)
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	conn, err := net.ListenUDP("udp", addr)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  	tab, _, err := newUDP(priv, conn, natm, nodeDBPath)
   256  	if err != nil {
   257  		return nil, err
   258  	}
   259  	glog.V(logger.Info).Infoln("Listening,", tab.self)
   260  	glog.D(logger.Warn).Infoln("UDP listening. Client enode:", logger.ColorGreen(tab.self.String()))
   261  
   262  	return tab, nil
   263  }
   264  
   265  func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath string) (*Table, *udp, error) {
   266  	udp := &udp{
   267  		conn:       c,
   268  		priv:       priv,
   269  		closing:    make(chan struct{}),
   270  		gotreply:   make(chan reply),
   271  		addpending: make(chan *pending),
   272  	}
   273  	realaddr := c.LocalAddr().(*net.UDPAddr)
   274  	if natm != nil {
   275  		if !realaddr.IP.IsLoopback() {
   276  			go nat.Map(natm, udp.closing, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
   277  		}
   278  		// TODO: react to external IP changes over time.
   279  		if ext, err := natm.ExternalIP(); err == nil {
   280  			realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
   281  		}
   282  	}
   283  	// TODO: separate TCP port
   284  	udp.ourEndpoint = makeEndpoint(realaddr, uint16(realaddr.Port))
   285  	tab, err := newTable(udp, PubkeyID(&priv.PublicKey), realaddr, nodeDBPath)
   286  	if err != nil {
   287  		return nil, nil, err
   288  	}
   289  	udp.Table = tab
   290  
   291  	go udp.loop()
   292  	go udp.readLoop()
   293  	return udp.Table, udp, nil
   294  }
   295  
   296  func (t *udp) close() {
   297  	close(t.closing)
   298  	t.conn.Close()
   299  	// TODO: wait for the loops to end.
   300  }
   301  
   302  // ping sends a ping message to the given node and waits for a reply.
   303  func (t *udp) ping(toid NodeID, toaddr *net.UDPAddr) error {
   304  	// TODO: maybe check for ReplyTo field in callback to measure RTT
   305  	errc := t.pending(toid, pongPacket, func(interface{}) bool { return true })
   306  	t.send(toaddr, pingPacket, ping{
   307  		Version:    Version,
   308  		From:       t.ourEndpoint,
   309  		To:         makeEndpoint(toaddr, 0), // TODO: maybe use known TCP port from DB
   310  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   311  	})
   312  	return <-errc
   313  }
   314  
   315  func (t *udp) waitping(from NodeID) error {
   316  	return <-t.pending(from, pingPacket, func(interface{}) bool { return true })
   317  }
   318  
   319  // findnode sends a findnode request to the given node and waits until
   320  // the node has sent up to k neighbors.
   321  func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node, error) {
   322  	nodes := make([]*Node, 0, bucketSize)
   323  	nreceived := 0
   324  	errc := t.pending(toid, neighborsPacket, func(r interface{}) bool {
   325  		reply := r.(*neighbors)
   326  		for _, rn := range reply.Nodes {
   327  			nreceived++
   328  			if n, err := t.nodeFromRPC(toaddr, rn); err == nil {
   329  				nodes = append(nodes, n)
   330  			}
   331  		}
   332  		return nreceived >= bucketSize
   333  	})
   334  	t.send(toaddr, findnodePacket, findnode{
   335  		Target:     target,
   336  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   337  	})
   338  	err := <-errc
   339  
   340  	// remove nodes from *neighbors response
   341  	// where the originating address (toaddr) is *not* reserved and the given neighbor is reserved.
   342  	// This prevents irrelevant private network addresses from causing
   343  	// attempted discoveries on reserved ips that are not on
   344  	// our node's network.
   345  	// > https://en.wikipedia.org/wiki/Reserved_IP_addresses
   346  	// > https://github.com/ethereumproject/go-ethereum/issues/283
   347  	// > https://tools.ietf.org/html/rfc5737
   348  	// > https://tools.ietf.org/html/rfc3849
   349  	if !isReserved(toaddr.IP) {
   350  		var okNodes []*Node
   351  		for _, n := range nodes {
   352  			if isReserved(n.IP) {
   353  				glog.V(logger.Detail).Warnf("%v: removing from neighbors: toaddr: %v, id: %v, ip: %v", errReservedAddress, toaddr, n.ID, n.IP)
   354  				continue
   355  			}
   356  			okNodes = append(okNodes, n)
   357  		}
   358  		nodes = okNodes
   359  	}
   360  
   361  	return nodes, err
   362  }
   363  
   364  // pending adds a reply callback to the pending reply queue.
   365  // see the documentation of type pending for a detailed explanation.
   366  func (t *udp) pending(id NodeID, ptype byte, callback func(interface{}) bool) <-chan error {
   367  	ch := make(chan error, 1)
   368  	p := &pending{from: id, ptype: ptype, callback: callback, errc: ch}
   369  	select {
   370  	case t.addpending <- p:
   371  		// loop will handle it
   372  	case <-t.closing:
   373  		ch <- errClosed
   374  	}
   375  	return ch
   376  }
   377  
   378  func (t *udp) handleReply(from NodeID, ptype byte, req packet) bool {
   379  	matched := make(chan bool, 1)
   380  	select {
   381  	case t.gotreply <- reply{from, ptype, req, matched}:
   382  		// loop will handle it
   383  		return <-matched
   384  	case <-t.closing:
   385  		return false
   386  	}
   387  }
   388  
   389  // loop runs in its own goroutine. it keeps track of
   390  // the refresh timer and the pending reply queue.
   391  func (t *udp) loop() {
   392  	var (
   393  		plist        = list.New()
   394  		timeout      = time.NewTimer(0)
   395  		nextTimeout  *pending // head of plist when timeout was last reset
   396  		contTimeouts = 0      // number of continuous timeouts to do NTP checks
   397  		ntpWarnTime  = time.Unix(0, 0)
   398  	)
   399  	<-timeout.C // ignore first timeout
   400  	defer timeout.Stop()
   401  
   402  	resetTimeout := func() {
   403  		if plist.Front() == nil || nextTimeout == plist.Front().Value {
   404  			return
   405  		}
   406  		// Start the timer so it fires when the next pending reply has expired.
   407  		now := time.Now()
   408  		for el := plist.Front(); el != nil; el = el.Next() {
   409  			nextTimeout = el.Value.(*pending)
   410  			if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout {
   411  				timeout.Reset(dist)
   412  				return
   413  			}
   414  			// Remove pending replies whose deadline is too far in the
   415  			// future. These can occur if the system clock jumped
   416  			// backwards after the deadline was assigned.
   417  			nextTimeout.errc <- errClockWarp
   418  			plist.Remove(el)
   419  		}
   420  		nextTimeout = nil
   421  		timeout.Stop()
   422  	}
   423  
   424  	for {
   425  		resetTimeout()
   426  
   427  		select {
   428  		case <-t.closing:
   429  			for el := plist.Front(); el != nil; el = el.Next() {
   430  				el.Value.(*pending).errc <- errClosed
   431  			}
   432  			return
   433  
   434  		case p := <-t.addpending:
   435  			p.deadline = time.Now().Add(respTimeout)
   436  			plist.PushBack(p)
   437  
   438  		case r := <-t.gotreply:
   439  			var matched bool
   440  			for el := plist.Front(); el != nil; el = el.Next() {
   441  				p := el.Value.(*pending)
   442  				if p.from == r.from && p.ptype == r.ptype {
   443  					matched = true
   444  					// Remove the matcher if its callback indicates
   445  					// that all replies have been received. This is
   446  					// required for packet types that expect multiple
   447  					// reply packets.
   448  					if p.callback(r.data) {
   449  						p.errc <- nil
   450  						plist.Remove(el)
   451  					}
   452  					// Reset the continuous timeout counter (time drift detection)
   453  					contTimeouts = 0
   454  				}
   455  			}
   456  			r.matched <- matched
   457  
   458  		case now := <-timeout.C:
   459  			nextTimeout = nil
   460  
   461  			// Notify and remove callbacks whose deadline is in the past.
   462  			for el := plist.Front(); el != nil; el = el.Next() {
   463  				p := el.Value.(*pending)
   464  				if now.After(p.deadline) || now.Equal(p.deadline) {
   465  					p.errc <- errTimeout
   466  					plist.Remove(el)
   467  					contTimeouts++
   468  				}
   469  			}
   470  			// If we've accumulated too many timeouts, do an NTP time sync check
   471  			if contTimeouts > ntpFailureThreshold {
   472  				if time.Since(ntpWarnTime) >= ntpWarningCooldown {
   473  					ntpWarnTime = time.Now()
   474  					go checkClockDrift()
   475  				}
   476  				contTimeouts = 0
   477  			}
   478  		}
   479  	}
   480  }
   481  
   482  const (
   483  	macSize  = 256 / 8
   484  	sigSize  = 520 / 8
   485  	headSize = macSize + sigSize // space of packet frame data
   486  )
   487  
   488  var (
   489  	headSpace = make([]byte, headSize)
   490  
   491  	// Neighbors replies are sent across multiple packets to
   492  	// stay below the 1280 byte limit. We compute the maximum number
   493  	// of entries by stuffing a packet until it grows too large.
   494  	maxNeighbors int
   495  )
   496  
   497  func init() {
   498  	p := neighbors{Expiration: ^uint64(0)}
   499  	maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
   500  	for n := 0; ; n++ {
   501  		p.Nodes = append(p.Nodes, maxSizeNode)
   502  		size, _, err := rlp.EncodeToReader(p)
   503  		if err != nil {
   504  			// If this ever happens, it will be caught by the unit tests.
   505  			panic("cannot encode: " + err.Error())
   506  		}
   507  		if headSize+size+1 >= 1280 {
   508  			maxNeighbors = n
   509  			break
   510  		}
   511  	}
   512  }
   513  
   514  func (t *udp) send(toaddr *net.UDPAddr, ptype byte, req interface{}) error {
   515  	packet, err := encodePacket(t.priv, ptype, req)
   516  	if err != nil {
   517  		return err
   518  	}
   519  	if logger.MlogEnabled() {
   520  		switch ptype {
   521  		// @sorpass: again, performance penalty?
   522  		case pingPacket:
   523  			mlogPingSendTo.AssignDetails(
   524  				toaddr.String(),
   525  				len(packet),
   526  			).Send(mlogDiscover)
   527  		case pongPacket:
   528  			mlogPongSendTo.AssignDetails(
   529  				toaddr.String(),
   530  				len(packet),
   531  			).Send(mlogDiscover)
   532  		case findnodePacket:
   533  			mlogFindNodeSendTo.AssignDetails(
   534  				toaddr.String(),
   535  				len(packet),
   536  			).Send(mlogDiscover)
   537  		case neighborsPacket:
   538  			mlogNeighborsSendTo.AssignDetails(
   539  				toaddr.String(),
   540  				len(packet),
   541  			).Send(mlogDiscover)
   542  		}
   543  	}
   544  	if glog.V(logger.Detail) {
   545  		glog.Infof(">>> %v %T\n", toaddr, req)
   546  	}
   547  
   548  	if _, err = t.conn.WriteToUDP(packet, toaddr); err != nil {
   549  		glog.V(logger.Detail).Infoln("UDP send failed:", err)
   550  	}
   551  	return err
   552  }
   553  
   554  func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte, error) {
   555  	b := new(bytes.Buffer)
   556  	b.Write(headSpace)
   557  	b.WriteByte(ptype)
   558  	if err := rlp.Encode(b, req); err != nil {
   559  		glog.V(logger.Error).Infoln("error encoding packet:", err)
   560  		return nil, err
   561  	}
   562  	packet := b.Bytes()
   563  	sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv)
   564  	if err != nil {
   565  		glog.V(logger.Error).Infoln("could not sign packet:", err)
   566  		return nil, err
   567  	}
   568  	copy(packet[macSize:], sig)
   569  	// add the hash to the front. Note: this doesn't protect the
   570  	// packet in any way. Our public key will be part of this hash in
   571  	// The future.
   572  	copy(packet, crypto.Keccak256(packet[macSize:]))
   573  	return packet, nil
   574  }
   575  
   576  func isTemporaryError(err error) bool {
   577  	tempErr, ok := err.(interface {
   578  		Temporary() bool
   579  	})
   580  	return ok && tempErr.Temporary() || isPacketTooBig(err)
   581  }
   582  
   583  // readLoop runs in its own goroutine. it handles incoming UDP packets.
   584  func (t *udp) readLoop() {
   585  	defer t.conn.Close()
   586  	// Discovery packets are defined to be no larger than 1280 bytes.
   587  	// Packets larger than this size will be cut at the end and treated
   588  	// as invalid because their hash won't match.
   589  	buf := make([]byte, 1280)
   590  	for {
   591  		nbytes, from, err := t.conn.ReadFromUDP(buf)
   592  		if isTemporaryError(err) {
   593  			// Ignore temporary read errors.
   594  			glog.V(logger.Debug).Infof("Temporary read error: %v", err)
   595  			continue
   596  		} else if err != nil {
   597  			// Shut down the loop for permament errors.
   598  			glog.V(logger.Debug).Infof("Read error: %v", err)
   599  			return
   600  		}
   601  		t.handlePacket(from, buf[:nbytes])
   602  	}
   603  }
   604  
   605  func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error {
   606  	packet, fromID, hash, err := decodePacket(buf)
   607  	if err != nil {
   608  		glog.V(logger.Debug).Infof("Bad packet from %v: %v\n", from, err)
   609  		return err
   610  	}
   611  	status := "ok"
   612  	if err = packet.handle(t, from, fromID, hash); err != nil {
   613  		status = err.Error()
   614  	}
   615  	if logger.MlogEnabled() {
   616  		// Use fmt Type interpolator to decide kind of request received,
   617  		// since packet is an interface with 1 method: handle.
   618  		switch p := fmt.Sprintf("%T", packet); p {
   619  		case "*discover.ping":
   620  			mlogPingHandleFrom.AssignDetails(
   621  				from.String(),
   622  				fromID.String(),
   623  				len(buf),
   624  			).Send(mlogDiscover)
   625  		case "*discover.pong":
   626  			mlogPongHandleFrom.AssignDetails(
   627  				from.String(),
   628  				fromID.String(),
   629  				len(buf),
   630  			).Send(mlogDiscover)
   631  		case "*discover.findnode":
   632  			mlogFindNodeHandleFrom.AssignDetails(
   633  				from.String(),
   634  				fromID.String(),
   635  				len(buf),
   636  			).Send(mlogDiscover)
   637  		case "*discover.neighbors":
   638  			mlogNeighborsHandleFrom.AssignDetails(
   639  				from.String(),
   640  				fromID.String(),
   641  				len(buf),
   642  			).Send(mlogDiscover)
   643  		}
   644  	}
   645  	if glog.V(logger.Detail) {
   646  		glog.Infof("<<< %v %T: %s\n", from, packet, status)
   647  	}
   648  	return err
   649  }
   650  
   651  func decodePacket(buf []byte) (packet, NodeID, []byte, error) {
   652  	if len(buf) < headSize+1 {
   653  		return nil, NodeID{}, nil, errPacketTooSmall
   654  	}
   655  	hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
   656  	shouldhash := crypto.Keccak256(buf[macSize:])
   657  	if !bytes.Equal(hash, shouldhash) {
   658  		return nil, NodeID{}, nil, errBadHash
   659  	}
   660  	fromID, err := recoverNodeID(crypto.Keccak256(buf[headSize:]), sig)
   661  	if err != nil {
   662  		return nil, NodeID{}, hash, err
   663  	}
   664  	var req packet
   665  	switch ptype := sigdata[0]; ptype {
   666  	case pingPacket:
   667  		req = new(ping)
   668  	case pongPacket:
   669  		req = new(pong)
   670  	case findnodePacket:
   671  		req = new(findnode)
   672  	case neighborsPacket:
   673  		req = new(neighbors)
   674  	default:
   675  		return nil, fromID, hash, fmt.Errorf("unknown type: %d", ptype)
   676  	}
   677  	s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0)
   678  	err = s.Decode(req)
   679  	return req, fromID, hash, err
   680  }
   681  
   682  func (req *ping) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
   683  	if expired(req.Expiration) {
   684  		return errExpired
   685  	}
   686  	t.send(from, pongPacket, pong{
   687  		To:         makeEndpoint(from, req.From.TCP),
   688  		ReplyTok:   mac,
   689  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   690  	})
   691  	if !t.handleReply(fromID, pingPacket, req) {
   692  		// Note: we're ignoring the provided IP address right now
   693  		go t.bond(true, fromID, from, req.From.TCP)
   694  	}
   695  	return nil
   696  }
   697  
   698  func (req *pong) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
   699  	if expired(req.Expiration) {
   700  		return errExpired
   701  	}
   702  	if !t.handleReply(fromID, pongPacket, req) {
   703  		return errUnsolicitedReply
   704  	}
   705  	return nil
   706  }
   707  
   708  func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
   709  	if expired(req.Expiration) {
   710  		return errExpired
   711  	}
   712  	if t.db.node(fromID) == nil {
   713  		// No bond exists, we don't process the packet. This prevents
   714  		// an attack vector where the discovery protocol could be used
   715  		// to amplify traffic in a DDOS attack. A malicious actor
   716  		// would send a findnode request with the IP address and UDP
   717  		// port of the target as the source address. The recipient of
   718  		// the findnode packet would then send a neighbors packet
   719  		// (which is a much bigger packet than findnode) to the victim.
   720  		return errUnknownNode
   721  	}
   722  	closest := t.closest(req.Target).Slice()
   723  
   724  	p := neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}
   725  
   726  	// Send neighbors in chunks with at most maxNeighbors per packet
   727  	// to stay below the 1280 byte limit.
   728  	for i, n := range closest {
   729  		p.Nodes = append(p.Nodes, nodeToRPC(n))
   730  		if len(p.Nodes) == maxNeighbors || i == len(closest)-1 {
   731  			t.send(from, neighborsPacket, p)
   732  			p.Nodes = p.Nodes[:0]
   733  		}
   734  	}
   735  	return nil
   736  }
   737  
   738  func (req *neighbors) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
   739  	if expired(req.Expiration) {
   740  		return errExpired
   741  	}
   742  	if !t.handleReply(fromID, neighborsPacket, req) {
   743  		return errUnsolicitedReply
   744  	}
   745  	return nil
   746  }
   747  
   748  func expired(ts uint64) bool {
   749  	return time.Unix(int64(ts), 0).Before(time.Now())
   750  }
   751  
   752  func isReserved(ip net.IP) bool {
   753  	reserved := [][2]net.IP{
   754  		Ipv4ReservedRangeThis,
   755  		Ipv4ReservedRangePrivateNetwork,
   756  		ipv4ReservedRangeProviderSubscriber,
   757  		Ipv4ReservedRangeLoopback,
   758  		ipv4ReservedRangeLinkLocal,
   759  		ipv4ReservedRangeLocalPrivate1,
   760  		ipv4ReservedRangeSpecialPurpose,
   761  		ipv4ReservedRangeTestNet1,
   762  		ipv4ReservedRange6to4,
   763  		Ipv4ReservedRangeLocalPrivate2,
   764  		ipv4ReservedRangeSubnets,
   765  		ipv4ReservedRangeTestNet2,
   766  		ipv4ReservedRangeTestNet3,
   767  		ipv4ReservedRangeMulticast,
   768  		ipv4ReservedRangeFuture,
   769  		ipv4ReservedRangeLimitedBroadcast,
   770  		ipv6ReservedRangeUnspecified,
   771  		Ipv6ReservedRangeLoopback,
   772  		ipv6ReservedRangeDocumentation,
   773  		ipv6ReservedRange6to4,
   774  		ipv6ReservedRangeUniqueLocal,
   775  		ipv6ReservedRangeLinkLocal,
   776  		ipv6ReservedRangeMulticast,
   777  	}
   778  	for _, r := range reserved {
   779  		isReserved, err := IpBetween(r[0], r[1], ip)
   780  		if err != nil {
   781  			glog.V(logger.Debug).Infof("error checking if ip reserved: %v", err)
   782  			return true
   783  		}
   784  		if isReserved {
   785  			return true
   786  		}
   787  	}
   788  	return false
   789  }
   790  
   791  // IpBetween determines if a given ip is between two others (inclusive)
   792  // > https://stackoverflow.com/questions/19882961/go-golang-check-ip-address-in-range
   793  func IpBetween(from net.IP, to net.IP, test net.IP) (bool, error) {
   794  	if from == nil || to == nil || test == nil {
   795  		return false, errInvalidIp
   796  	}
   797  
   798  	from16 := from.To16()
   799  	to16 := to.To16()
   800  	test16 := test.To16()
   801  	if from16 == nil || to16 == nil || test16 == nil {
   802  		return false, errors.New("ip did not convert to a 16 byte")
   803  	}
   804  
   805  	if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
   806  		return true, nil
   807  	}
   808  	return false, nil
   809  }