github.com/annchain/OG@v0.0.9/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  //go:generate msgp
    17  package discover
    18  
    19  import (
    20  	"bytes"
    21  	"container/list"
    22  	"crypto/ecdsa"
    23  	"errors"
    24  	"fmt"
    25  	"github.com/annchain/OG/arefactor/common/goroutine"
    26  	ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto"
    27  	"github.com/annchain/OG/p2p/onode"
    28  	"github.com/sirupsen/logrus"
    29  	"net"
    30  	"sync"
    31  	"time"
    32  
    33  	"github.com/annchain/OG/p2p/netutil"
    34  )
    35  
    36  // Errors
    37  var (
    38  	errPacketTooSmall   = errors.New("too small")
    39  	errBadHash          = errors.New("bad hash")
    40  	errExpired          = errors.New("expired")
    41  	errUnsolicitedReply = errors.New("unsolicited reply")
    42  	errUnknownNode      = errors.New("unknown node")
    43  	errTimeout          = errors.New("RPC timeout")
    44  	errClockWarp        = errors.New("reply deadline too far in the future")
    45  	errClosed           = errors.New("socket closed")
    46  )
    47  
    48  // Timeouts
    49  const (
    50  	respTimeout    = 500 * time.Millisecond
    51  	expiration     = 20 * time.Second
    52  	bondExpiration = 24 * time.Hour
    53  
    54  	ntpFailureThreshold = 32               // Continuous timeouts after which to check NTP
    55  	ntpWarningCooldown  = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning
    56  	driftThreshold      = 10 * time.Second // Allowed clock drift before warning user
    57  )
    58  
    59  // RPC packet types
    60  const (
    61  	pingPacket = iota + 1 // zero is 'reserved'
    62  	pongPacket
    63  	findnodePacket
    64  	neighborsPacket
    65  )
    66  
    67  // RPC request structures
    68  type (
    69  	//msgp:tuple Ping
    70  	Ping struct {
    71  		Version    uint
    72  		From, To   RpcEndpoint
    73  		Expiration uint64
    74  		// Ignore additional fields (for forward compatibility).
    75  		Rest [][]byte `rlp:"tail"`
    76  	}
    77  
    78  	// pong is the reply to ping.
    79  	//msgp:tuple Pong
    80  	Pong struct {
    81  		// This field should mirror the UDP envelope address
    82  		// of the ping packet, which provides a way to discover the
    83  		// the external address (after NAT).
    84  		To RpcEndpoint
    85  
    86  		ReplyTok   []byte // This contains the hash of the ping packet.
    87  		Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
    88  		// Ignore additional fields (for forward compatibility).
    89  		Rest [][]byte `rlp:"tail"`
    90  	}
    91  
    92  	// findnode is a query for nodes close to the given target.
    93  	//msgp:tuple Findnode
    94  	Findnode struct {
    95  		//Target     NodeID // doesn't need to be an actual public key
    96  		Target     EncPubkey
    97  		Expiration uint64
    98  		// Ignore additional fields (for forward compatibility).
    99  		Rest [][]byte `rlp:"tail"`
   100  	}
   101  
   102  	// reply to findnode
   103  	//msgp:tuple Neighbors
   104  	Neighbors struct {
   105  		Nodes      []RpcNode
   106  		Expiration uint64
   107  		// Ignore additional fields (for forward compatibility).
   108  		Rest [][]byte `rlp:"tail"`
   109  	}
   110  
   111  	//msgp:tuple RpcNode
   112  	RpcNode struct {
   113  		//IP  net.IP // len 4 for IPv4 or 16 for IPv6
   114  		IP  []byte
   115  		UDP uint16 // for discovery protocol
   116  		TCP uint16 // for RLPx protocol
   117  		ID  EncPubkey
   118  	}
   119  
   120  	//msgp:tuple RpcEndpoint
   121  	RpcEndpoint struct {
   122  		//IP  net.IP // len 4 for IPv4 or 16 for IPv6
   123  		IP  []byte
   124  		UDP uint16 // for discovery protocol
   125  		TCP uint16 // for RLPx protocol
   126  	}
   127  )
   128  
   129  func (r RpcEndpoint) Equal(r1 RpcEndpoint) bool {
   130  	if len(r.IP) != len(r1.IP) {
   131  		return false
   132  	}
   133  	if !bytes.Equal(r.IP, r1.IP) {
   134  		return false
   135  	}
   136  	if r.TCP != r1.TCP {
   137  		return false
   138  	}
   139  	if r.UDP != r1.UDP {
   140  		return false
   141  	}
   142  	return true
   143  }
   144  
   145  func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) RpcEndpoint {
   146  	ip := net.IP{}
   147  	if ip4 := addr.IP.To4(); ip4 != nil {
   148  		ip = ip4
   149  	} else if ip6 := addr.IP.To16(); ip6 != nil {
   150  		ip = ip6
   151  	}
   152  	return RpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
   153  }
   154  
   155  func (t *udp) nodeFromRPC(sender *net.UDPAddr, rn RpcNode) (*node, error) {
   156  	if rn.UDP <= 1024 {
   157  		return nil, errors.New("low port")
   158  	}
   159  	if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
   160  		return nil, err
   161  	}
   162  	if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
   163  		return nil, errors.New("not contained in netrestrict whitelist")
   164  	}
   165  	key, err := decodePubkey(rn.ID)
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  	n := wrapNode(onode.NewV4(key, rn.IP, int(rn.TCP), int(rn.UDP)))
   170  	err = n.ValidateComplete()
   171  	return n, err
   172  }
   173  
   174  func nodeToRPC(n *node) RpcNode {
   175  	var key ecdsa.PublicKey
   176  	var ekey EncPubkey
   177  	if err := n.Load((*onode.Secp256k1)(&key)); err == nil {
   178  		ekey = encodePubkey(&key)
   179  	}
   180  	return RpcNode{ID: ekey, IP: n.IP(), UDP: uint16(n.UDP()), TCP: uint16(n.TCP())}
   181  }
   182  
   183  type packet interface {
   184  	handle(t *udp, from *net.UDPAddr, fromKey EncPubkey, mac []byte) error
   185  	name() string
   186  }
   187  
   188  type conn interface {
   189  	ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error)
   190  	WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error)
   191  	Close() error
   192  	LocalAddr() net.Addr
   193  }
   194  
   195  // udp implements the discovery v4 UDP wire protocol.
   196  type udp struct {
   197  	conn        conn
   198  	netrestrict *netutil.Netlist
   199  	priv        *ecdsa.PrivateKey
   200  	localNode   *onode.LocalNode
   201  	db          *onode.DB
   202  	tab         *Table
   203  	wg          sync.WaitGroup
   204  
   205  	addpending chan *pending
   206  	gotreply   chan reply
   207  	closing    chan struct{}
   208  }
   209  
   210  // pending represents a pending reply.
   211  //
   212  // some implementations of the protocol wish to send more than one
   213  // reply packet to findnode. in general, any neighbors packet cannot
   214  // be matched up with a specific findnode packet.
   215  //
   216  // our implementation handles this by storing a callback function for
   217  // each pending reply. incoming packets from a node are dispatched
   218  // to all the callback functions for that node.
   219  type pending struct {
   220  	// these fields must match in the reply.
   221  	from  onode.ID
   222  	ptype byte
   223  
   224  	// time when the request must complete
   225  	deadline time.Time
   226  
   227  	// callback is called when a matching reply arrives. if it returns
   228  	// true, the callback is removed from the pending reply queue.
   229  	// if it returns false, the reply is considered incomplete and
   230  	// the callback will be invoked again for the next matching reply.
   231  	callback func(resp interface{}) (done bool)
   232  
   233  	// errc receives nil when the callback indicates completion or an
   234  	// error if no further reply is received within the timeout.
   235  	errc chan<- error
   236  }
   237  
   238  type reply struct {
   239  	from  onode.ID
   240  	ptype byte
   241  	data  interface{}
   242  	// loop indicates whether there was
   243  	// a matching request by sending on this channel.
   244  	matched chan<- bool
   245  }
   246  
   247  // ReadPacket is sent to the unhandled channel when it could not be processed
   248  //msgp:tuple ReadPacket
   249  type ReadPacket struct {
   250  	Data []byte       `msg:"-"`
   251  	Addr *net.UDPAddr `msg:"-"`
   252  }
   253  
   254  // Config holds Table-related settings.
   255  type Config struct {
   256  	// These settings are required and configure the UDP listener:
   257  	PrivateKey *ecdsa.PrivateKey `msg:"-"`
   258  
   259  	// These settings are optional:
   260  	NetRestrict *netutil.Netlist  `msg:"-"` // network whitelist
   261  	Bootnodes   []*onode.Node     `msg:"-"` // list of bootstrap nodes
   262  	Unhandled   chan<- ReadPacket `msg:"-"` // unhandled packets are sent on this channel
   263  }
   264  
   265  // ListenUDP returns a new table that listens for UDP packets on laddr.
   266  func ListenUDP(c conn, ln *onode.LocalNode, cfg Config) (*Table, error) {
   267  	tab, _, err := newUDP(c, ln, cfg)
   268  	if err != nil {
   269  		return nil, err
   270  	}
   271  	return tab, nil
   272  }
   273  
   274  func newUDP(c conn, ln *onode.LocalNode, cfg Config) (*Table, *udp, error) {
   275  	udp := &udp{
   276  		conn:        c,
   277  		priv:        cfg.PrivateKey,
   278  		netrestrict: cfg.NetRestrict,
   279  		localNode:   ln,
   280  		db:          ln.Database(),
   281  		closing:     make(chan struct{}),
   282  		gotreply:    make(chan reply),
   283  		addpending:  make(chan *pending),
   284  	}
   285  	tab, err := newTable(udp, ln.Database(), cfg.Bootnodes)
   286  	if err != nil {
   287  		return nil, nil, err
   288  	}
   289  	udp.tab = tab
   290  
   291  	udp.wg.Add(2)
   292  	goroutine.New(udp.loop)
   293  	goroutine.New(func() {
   294  		udp.readLoop(cfg.Unhandled)
   295  	})
   296  	return udp.tab, udp, nil
   297  }
   298  
   299  func (t *udp) self() *onode.Node {
   300  	return t.localNode.Node()
   301  }
   302  
   303  func (t *udp) close() {
   304  	close(t.closing)
   305  	t.conn.Close()
   306  	t.wg.Wait()
   307  }
   308  func (t *udp) ourEndpoint() RpcEndpoint {
   309  	n := t.self()
   310  	a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
   311  	return makeEndpoint(a, uint16(n.TCP()))
   312  }
   313  
   314  // ping sends a ping message to the given node and waits for a reply.
   315  func (t *udp) ping(toid onode.ID, toaddr *net.UDPAddr) error {
   316  	return <-t.sendPing(toid, toaddr, nil)
   317  }
   318  
   319  // sendPing sends a ping message to the given node and invokes the callback
   320  // when the reply arrives.
   321  func (t *udp) sendPing(toid onode.ID, toaddr *net.UDPAddr, callback func()) <-chan error {
   322  	req := &Ping{
   323  		Version:    4,
   324  		From:       t.ourEndpoint(),
   325  		To:         makeEndpoint(toaddr, 0), // TODO: maybe use known TCP port from DB
   326  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   327  	}
   328  	data, _ := req.MarshalMsg(nil)
   329  	packet, hash, err := encodePacket(t.priv, pingPacket, data)
   330  	if err != nil {
   331  		errc := make(chan error, 1)
   332  		errc <- err
   333  		return errc
   334  	}
   335  	errc := t.pending(toid, pongPacket, func(p interface{}) bool {
   336  		ok := bytes.Equal(p.(*Pong).ReplyTok, hash)
   337  		if ok && callback != nil {
   338  			callback()
   339  		}
   340  		return ok
   341  	})
   342  	t.localNode.UDPContact(toaddr)
   343  	t.write(toaddr, req.name(), packet)
   344  	return errc
   345  }
   346  
   347  func (t *udp) waitping(from onode.ID) error {
   348  	return <-t.pending(from, pingPacket, func(interface{}) bool { return true })
   349  }
   350  
   351  // findnode sends a findnode request to the given node and waits until
   352  // the node has sent up to k neighbors.
   353  func (t *udp) findnode(toid onode.ID, toaddr *net.UDPAddr, target EncPubkey) ([]*node, error) {
   354  	// If we haven't seen a ping from the destination node for a while, it won't remember
   355  	// our endpoint proof and reject findnode. Solicit a ping first.
   356  	if time.Since(t.db.LastPingReceived(toid)) > bondExpiration {
   357  		t.ping(toid, toaddr)
   358  		t.waitping(toid)
   359  	}
   360  
   361  	nodes := make([]*node, 0, bucketSize)
   362  	nreceived := 0
   363  	errc := t.pending(toid, neighborsPacket, func(r interface{}) bool {
   364  		reply := r.(*Neighbors)
   365  		for _, rn := range reply.Nodes {
   366  			nreceived++
   367  			n, err := t.nodeFromRPC(toaddr, rn)
   368  			if err != nil {
   369  				log.WithFields(logrus.Fields{"ip": rn.IP, "addr": toaddr, "udp": rn.UDP}).
   370  					WithError(err).
   371  					Trace("Invalid neighbor node received")
   372  				continue
   373  			}
   374  			nodes = append(nodes, n)
   375  		}
   376  		return nreceived >= bucketSize
   377  	})
   378  	findNode := &Findnode{
   379  		Target:     target,
   380  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   381  	}
   382  	data, _ := findNode.MarshalMsg(nil)
   383  	t.send(toaddr, findnodePacket, data, findNode.name())
   384  	return nodes, <-errc
   385  }
   386  
   387  // pending adds a reply callback to the pending reply queue.
   388  // see the documentation of type pending for a detailed explanation.
   389  func (t *udp) pending(id onode.ID, ptype byte, callback func(interface{}) bool) <-chan error {
   390  	ch := make(chan error, 1)
   391  	p := &pending{from: id, ptype: ptype, callback: callback, errc: ch}
   392  	select {
   393  	case t.addpending <- p:
   394  		// loop will handle it
   395  	case <-t.closing:
   396  		ch <- errClosed
   397  	}
   398  	return ch
   399  }
   400  
   401  func (t *udp) handleReply(from onode.ID, ptype byte, req packet) bool {
   402  	matched := make(chan bool, 1)
   403  	select {
   404  	case t.gotreply <- reply{from, ptype, req, matched}:
   405  		// loop will handle it
   406  		return <-matched
   407  	case <-t.closing:
   408  		return false
   409  	}
   410  }
   411  
   412  // loop runs in its own goroutine. it keeps track of
   413  // the refresh timer and the pending reply queue.
   414  func (t *udp) loop() {
   415  	defer t.wg.Done()
   416  
   417  	var (
   418  		plist        = list.New()
   419  		timeout      = time.NewTimer(0)
   420  		nextTimeout  *pending // head of plist when timeout was last reset
   421  		contTimeouts = 0      // number of continuous timeouts to do NTP checks
   422  		ntpWarnTime  = time.Unix(0, 0)
   423  	)
   424  	<-timeout.C // ignore first timeout
   425  	defer timeout.Stop()
   426  
   427  	resetTimeout := func() {
   428  		if plist.Front() == nil || nextTimeout == plist.Front().Value {
   429  			return
   430  		}
   431  		// Start the timer so it fires when the next pending reply has expired.
   432  		now := time.Now()
   433  		for el := plist.Front(); el != nil; el = el.Next() {
   434  			nextTimeout = el.Value.(*pending)
   435  			if dist := nextTimeout.deadline.Sub(now); dist < 2*respTimeout {
   436  				timeout.Reset(dist)
   437  				return
   438  			}
   439  			// Remove pending replies whose deadline is too far in the
   440  			// future. These can occur if the system clock jumped
   441  			// backwards after the deadline was assigned.
   442  			nextTimeout.errc <- errClockWarp
   443  			plist.Remove(el)
   444  		}
   445  		nextTimeout = nil
   446  		timeout.Stop()
   447  	}
   448  
   449  	for {
   450  		resetTimeout()
   451  
   452  		select {
   453  		case <-t.closing:
   454  			for el := plist.Front(); el != nil; el = el.Next() {
   455  				el.Value.(*pending).errc <- errClosed
   456  			}
   457  			return
   458  
   459  		case p := <-t.addpending:
   460  			p.deadline = time.Now().Add(respTimeout)
   461  			plist.PushBack(p)
   462  
   463  		case r := <-t.gotreply:
   464  			var matched bool
   465  			for el := plist.Front(); el != nil; el = el.Next() {
   466  				p := el.Value.(*pending)
   467  				if p.from == r.from && p.ptype == r.ptype {
   468  					matched = true
   469  					// Remove the matcher if its callback indicates
   470  					// that all replies have been received. This is
   471  					// required for packet types that expect multiple
   472  					// reply packets.
   473  					if p.callback(r.data) {
   474  						p.errc <- nil
   475  						plist.Remove(el)
   476  					}
   477  					// Reset the continuous timeout counter (time drift detection)
   478  					contTimeouts = 0
   479  				}
   480  			}
   481  			if matched == false {
   482  				log.WithField("fromId", r.from.TerminalString()).WithField(
   483  					//"rfrom",r.fromAddr.String()).WithField(
   484  					"rtype", r.ptype).Debug("mismatch")
   485  			}
   486  			r.matched <- matched
   487  
   488  		case now := <-timeout.C:
   489  			nextTimeout = nil
   490  
   491  			// Notify and remove callbacks whose deadline is in the past.
   492  			for el := plist.Front(); el != nil; el = el.Next() {
   493  				p := el.Value.(*pending)
   494  				if now.After(p.deadline) || now.Equal(p.deadline) {
   495  					p.errc <- errTimeout
   496  					plist.Remove(el)
   497  					contTimeouts++
   498  				}
   499  			}
   500  			// If we've accumulated too many timeouts, do an NTP time sync check
   501  			if contTimeouts > ntpFailureThreshold {
   502  				if time.Since(ntpWarnTime) >= ntpWarningCooldown {
   503  					ntpWarnTime = time.Now()
   504  					goroutine.New(checkClockDrift)
   505  				}
   506  				contTimeouts = 0
   507  			}
   508  		}
   509  
   510  	}
   511  }
   512  
   513  const (
   514  	macSize  = 256 / 8
   515  	sigSize  = 520 / 8
   516  	headSize = macSize + sigSize // space of packet frame data
   517  )
   518  
   519  var (
   520  	headSpace = make([]byte, headSize)
   521  
   522  	// Neighbors replies are sent across multiple packets to
   523  	// stay below the 1280 byte limit. We compute the maximum number
   524  	// of entries by stuffing a packet until it grows too large.
   525  	maxNeighbors int
   526  )
   527  
   528  func init() {
   529  	p := Neighbors{Expiration: ^uint64(0)}
   530  	maxSizeNode := RpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
   531  	for n := 0; ; n++ {
   532  		p.Nodes = append(p.Nodes, maxSizeNode)
   533  		data, err := p.MarshalMsg(nil)
   534  		//size, _, err := rlp.EncodeToReader(p)
   535  		if err != nil {
   536  			// If this ever happens, it will be caught by the unit tests.
   537  			panic("cannot encode: " + err.Error())
   538  		}
   539  		size := len(data)
   540  		if headSize+size+1 >= 1280 {
   541  			maxNeighbors = n
   542  			break
   543  		}
   544  	}
   545  }
   546  
   547  func (t *udp) send(toaddr *net.UDPAddr, ptype byte, data []byte, name string) ([]byte, error) {
   548  	packet, hash, err := encodePacket(t.priv, ptype, data)
   549  	if err != nil {
   550  		return hash, err
   551  	}
   552  	return hash, t.write(toaddr, name, packet)
   553  }
   554  
   555  func (t *udp) write(toaddr *net.UDPAddr, what string, packet []byte) error {
   556  	_, err := t.conn.WriteToUDP(packet, toaddr)
   557  	log.WithField("addr", toaddr).WithError(err).Trace(">>write  " + what)
   558  	return err
   559  }
   560  
   561  func encodePacket(priv *ecdsa.PrivateKey, ptype byte, data []byte) (packet, hash []byte, err error) {
   562  	b := new(bytes.Buffer)
   563  	b.Write(headSpace)
   564  	b.WriteByte(ptype)
   565  	b.Write(data)
   566  	packet = b.Bytes()
   567  	sig, err := ogcrypto2.Sign(ogcrypto2.Keccak256(packet[headSize:]), priv)
   568  	if err != nil {
   569  		log.WithError(err).Error("Can't sign discv4 packet")
   570  		return nil, nil, err
   571  	}
   572  	copy(packet[macSize:], sig)
   573  	// add the hash to the front. Note: this doesn't protect the
   574  	// packet in any way. Our public key will be part of this hash in
   575  	// The future.
   576  	hash = ogcrypto2.Keccak256(packet[macSize:])
   577  	copy(packet, hash)
   578  	return packet, hash, nil
   579  }
   580  
   581  // readLoop runs in its own goroutine. it handles incoming UDP packets.
   582  func (t *udp) readLoop(unhandled chan<- ReadPacket) {
   583  	defer t.wg.Done()
   584  	if unhandled != nil {
   585  		defer close(unhandled)
   586  	}
   587  	// Discovery packets are defined to be no larger than 1280 bytes.
   588  	// Packets larger than this size will be cut at the end and treated
   589  	// as invalid because their hash won't match.
   590  	buf := make([]byte, 1280)
   591  	for {
   592  		nbytes, from, err := t.conn.ReadFromUDP(buf)
   593  		if netutil.IsTemporaryError(err) {
   594  			// Ignore temporary read errors.
   595  			log.WithError(err).Debug("Temporary UDP read error")
   596  			continue
   597  		} else if err != nil {
   598  			// Shut down the loop for permament errors.
   599  			log.WithError(err).Debug("UDP read error")
   600  			return
   601  		}
   602  		if t.handlePacket(from, buf[:nbytes]) != nil && unhandled != nil {
   603  			select {
   604  			case unhandled <- ReadPacket{buf[:nbytes], from}:
   605  			default:
   606  			}
   607  		}
   608  	}
   609  }
   610  
   611  func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error {
   612  	packet, fromKey, hash, err := decodePacket(buf)
   613  	if err != nil {
   614  		log.WithError(err).WithField("addr", from).Debug("Bad discv4 packet")
   615  		return err
   616  	}
   617  	err = packet.handle(t, from, fromKey, hash)
   618  	log.WithError(err).WithField("from key", fromKey.id().TerminalString()).WithField("addr", from).Trace("<< handle  " + packet.name())
   619  	return err
   620  }
   621  
   622  func decodePacket(buf []byte) (packet, EncPubkey, []byte, error) {
   623  	if len(buf) < headSize+1 {
   624  		return nil, EncPubkey{}, nil, errPacketTooSmall
   625  	}
   626  	hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
   627  	shouldhash := ogcrypto2.Keccak256(buf[macSize:])
   628  	if !bytes.Equal(hash, shouldhash) {
   629  		return nil, EncPubkey{}, nil, errBadHash
   630  	}
   631  	fromID, err := recoverNodeKey(ogcrypto2.Keccak256(buf[headSize:]), sig)
   632  	if err != nil {
   633  		return nil, EncPubkey{}, hash, err
   634  	}
   635  	data := sigdata[1:]
   636  	//var req packet
   637  	switch ptype := sigdata[0]; ptype {
   638  	case pingPacket:
   639  		req := new(Ping)
   640  		_, err = req.UnmarshalMsg(data)
   641  		return req, fromID, hash, err
   642  	case pongPacket:
   643  		req := new(Pong)
   644  		_, err = req.UnmarshalMsg(data)
   645  		return req, fromID, hash, err
   646  	case findnodePacket:
   647  		req := new(Findnode)
   648  		_, err = req.UnmarshalMsg(data)
   649  		return req, fromID, hash, err
   650  	case neighborsPacket:
   651  		req := new(Neighbors)
   652  		_, err = req.UnmarshalMsg(data)
   653  		return req, fromID, hash, err
   654  	default:
   655  		return nil, fromID, hash, fmt.Errorf("unknown type: %d", ptype)
   656  	}
   657  	//s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0)
   658  	//err = s.Decode(req)
   659  
   660  	//return req, fromID, hash, err
   661  	return nil, fromID, hash, err
   662  }
   663  
   664  func (req *Ping) handle(t *udp, from *net.UDPAddr, fromKey EncPubkey, mac []byte) error {
   665  	if expired(req.Expiration) {
   666  		return errExpired
   667  	}
   668  	key, err := decodePubkey(fromKey)
   669  	if err != nil {
   670  		return fmt.Errorf("invalid public key: %v", err)
   671  	}
   672  	pong := &Pong{
   673  		To:         makeEndpoint(from, req.From.TCP),
   674  		ReplyTok:   mac,
   675  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   676  	}
   677  	data, _ := pong.MarshalMsg(nil)
   678  	t.send(from, pongPacket, data, pong.name())
   679  	// no need to handle reply ,because we did'n add to pending
   680  	//t.handleReply(fromID, pingPacket,req,from)
   681  
   682  	// Add the node to the table. Before doing so, ensure that we have a recent enough pong
   683  	// recorded in the database so their findnode requests will be accepted later.
   684  	n := wrapNode(onode.NewV4(key, from.IP, int(req.From.TCP), from.Port))
   685  	if time.Since(t.db.LastPongReceived(n.ID())) > bondExpiration {
   686  		t.sendPing(n.ID(), from, func() { t.tab.addThroughPing(n) })
   687  	} else {
   688  		t.tab.addThroughPing(n)
   689  	}
   690  	t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
   691  	t.db.UpdateLastPingReceived(n.ID(), time.Now())
   692  	return nil
   693  }
   694  
   695  func (req *Ping) name() string { return "PING/v4" }
   696  
   697  func (req *Pong) handle(t *udp, from *net.UDPAddr, fromKey EncPubkey, mac []byte) error {
   698  	if expired(req.Expiration) {
   699  		return errExpired
   700  	}
   701  	fromID := fromKey.id()
   702  	if !t.handleReply(fromID, pongPacket, req) {
   703  		return errUnsolicitedReply
   704  	}
   705  	t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
   706  	t.db.UpdateLastPongReceived(fromID, time.Now())
   707  	return nil
   708  }
   709  
   710  func (req *Pong) name() string { return "PONG/v4" }
   711  
   712  func (req *Findnode) handle(t *udp, from *net.UDPAddr, fromKey EncPubkey, mac []byte) error {
   713  	if expired(req.Expiration) {
   714  		return errExpired
   715  	}
   716  	fromID := fromKey.id()
   717  	if time.Since(t.db.LastPongReceived(fromID)) > bondExpiration {
   718  		// No endpoint proof pong exists, we don't process the packet. This prevents an
   719  		// attack vector where the discovery protocol could be used to amplify traffic in a
   720  		// DDOS attack. A malicious actor would send a findnode request with the IP address
   721  		// and UDP port of the target as the source address. The recipient of the findnode
   722  		// packet would then send a neighbors packet (which is a much bigger packet than
   723  		// findnode) to the victim.
   724  		return errUnknownNode
   725  	}
   726  	target := onode.ID(ogcrypto2.Keccak256Hash(req.Target[:]).Bytes)
   727  	t.tab.mutex.Lock()
   728  	closest := t.tab.closest(target, bucketSize).entries
   729  	t.tab.mutex.Unlock()
   730  
   731  	p := Neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}
   732  	var sent bool
   733  	// Send neighbors in chunks with at most maxNeighbors per packet
   734  	// to stay below the 1280 byte limit.
   735  	for _, n := range closest {
   736  		if netutil.CheckRelayIP(from.IP, n.IP()) == nil {
   737  			p.Nodes = append(p.Nodes, nodeToRPC(n))
   738  		}
   739  		if len(p.Nodes) == maxNeighbors {
   740  			data, _ := p.MarshalMsg(nil)
   741  			t.send(from, neighborsPacket, data, p.name())
   742  			p.Nodes = p.Nodes[:0]
   743  			sent = true
   744  		}
   745  	}
   746  	if len(p.Nodes) > 0 || !sent {
   747  		data, _ := p.MarshalMsg(nil)
   748  		t.send(from, neighborsPacket, data, p.name())
   749  	}
   750  	return nil
   751  }
   752  
   753  func (req *Findnode) name() string { return "FINDNODE/v4" }
   754  
   755  func (req *Neighbors) handle(t *udp, from *net.UDPAddr, fromKey EncPubkey, mac []byte) error {
   756  	if expired(req.Expiration) {
   757  		return errExpired
   758  	}
   759  	if !t.handleReply(fromKey.id(), neighborsPacket, req) {
   760  		return errUnsolicitedReply
   761  	}
   762  	return nil
   763  }
   764  
   765  func (req *Neighbors) name() string { return "NEIGHBORS/v4" }
   766  
   767  func expired(ts uint64) bool {
   768  	return time.Unix(int64(ts), 0).Before(time.Now())
   769  }