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