github.com/annchain/OG@v0.0.9/p2p/discv5/udp.go (about)

     1  // Copyright 2016 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 discv5
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	"errors"
    23  	"fmt"
    24  	"github.com/annchain/OG/arefactor/common/goroutine"
    25  	"github.com/annchain/OG/arefactor/og/types"
    26  	ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto"
    27  	"net"
    28  	"time"
    29  
    30  	"github.com/annchain/OG/p2p/nat"
    31  	"github.com/annchain/OG/p2p/netutil"
    32  )
    33  
    34  //go:generate msgp
    35  const Version = 4
    36  
    37  // Errors
    38  var (
    39  	errPacketTooSmall = errors.New("too small")
    40  	errBadPrefix      = errors.New("bad prefix")
    41  	errTimeout        = errors.New("RPC timeout")
    42  )
    43  
    44  // Timeouts
    45  const (
    46  	respTimeout = 500 * time.Millisecond
    47  	expiration  = 20 * time.Second
    48  
    49  	driftThreshold = 10 * time.Second // Allowed clock drift before warning user
    50  )
    51  
    52  // RPC request structures
    53  
    54  type CommonHash [32]byte
    55  
    56  type (
    57  	//msgp:tuple Ping
    58  	Ping struct {
    59  		Version    uint
    60  		From, To   RpcEndpoint
    61  		Expiration uint64
    62  
    63  		// v5
    64  		//Topics []Topic
    65  		Topics []string
    66  		// Ignore additional fields (for forward compatibility).
    67  		Rest [][]byte `rlp:"tail"`
    68  	}
    69  
    70  	// pong is the reply to ping.
    71  	//msgp:tuple Pong
    72  	Pong struct {
    73  		// This field should mirror the UDP envelope address
    74  		// of the ping packet, which provides a way to discover the
    75  		// the external address (after NAT).
    76  		To RpcEndpoint
    77  
    78  		ReplyTok   []byte // This contains the hash of the ping packet.
    79  		Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
    80  
    81  		// v5
    82  		TopicHash    CommonHash
    83  		TicketSerial uint32
    84  		WaitPeriods  []uint32
    85  
    86  		// Ignore additional fields (for forward compatibility).
    87  		Rest [][]byte `rlp:"tail"`
    88  	}
    89  
    90  	// findnode is a query for nodes close to the given target.
    91  	//msgp:tuple Findnode
    92  	Findnode struct {
    93  		//Target     NodeID // doesn't need to be an actual public key
    94  		Target     [64]byte
    95  		Expiration uint64
    96  		// Ignore additional fields (for forward compatibility).
    97  		Rest [][]byte `rlp:"tail"`
    98  	}
    99  
   100  	// findnode is a query for nodes close to the given target.
   101  	//msgp:tuple FindnodeHash
   102  	FindnodeHash struct {
   103  		//Target     common.Hash
   104  		Target     CommonHash
   105  		Expiration uint64
   106  		// Ignore additional fields (for forward compatibility).
   107  		Rest [][]byte `rlp:"tail"`
   108  	}
   109  
   110  	// reply to findnode
   111  	//msgp:tuple Neighbors
   112  	Neighbors struct {
   113  		Nodes      []RpcNode
   114  		Expiration uint64
   115  		// Ignore additional fields (for forward compatibility).
   116  		Rest [][]byte `rlp:"tail"`
   117  	}
   118  	//msgp:tuple TopicRegister
   119  	TopicRegister struct {
   120  		//Topics []Topic
   121  		Topics []string
   122  		Idx    uint
   123  		Pong   []byte
   124  	}
   125  	//msgp:tuple TopicQuery
   126  	TopicQuery struct {
   127  		//Topic      Topic
   128  		Topic      string
   129  		Expiration uint64
   130  	}
   131  
   132  	// reply to topicQuery
   133  	//msgp:tuple TopicNodes
   134  	TopicNodes struct {
   135  		//Echo  common.Hash
   136  		Echo  CommonHash
   137  		Nodes []RpcNode
   138  	}
   139  	//msgp:tuple RpcNode
   140  	RpcNode struct {
   141  		//IP  net.IP // len 4 for IPv4 or 16 for IPv6
   142  		IP  []byte
   143  		UDP uint16 // for discovery protocol
   144  		TCP uint16 // for RLPx protocol
   145  		//ID  NodeID
   146  		ID [64]byte
   147  	}
   148  	//msgp:tuple RpcEndpoint
   149  	RpcEndpoint struct {
   150  		//IP  net.IP // len 4 for IPv4 or 16 for IPv6
   151  		IP  []byte
   152  		UDP uint16 // for discovery protocol
   153  		TCP uint16 // for RLPx protocol
   154  	}
   155  )
   156  
   157  var (
   158  	versionPrefix     = []byte("temporary discovery v5")
   159  	versionPrefixSize = len(versionPrefix)
   160  	sigSize           = 520 / 8
   161  	headSize          = versionPrefixSize + sigSize // space of packet frame data
   162  )
   163  
   164  // Neighbors replies are sent across multiple packets to
   165  // stay below the 1280 byte limit. We compute the maximum number
   166  // of entries by stuffing a packet until it grows too large.
   167  var maxNeighbors = func() int {
   168  	p := Neighbors{Expiration: ^uint64(0)}
   169  	maxSizeNode := RpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
   170  	for n := 0; ; n++ {
   171  		p.Nodes = append(p.Nodes, maxSizeNode)
   172  		data, err := p.MarshalMsg(nil)
   173  		//size, _, err := rlp.EncodeToReader(p)
   174  		if err != nil {
   175  			// If this ever happens, it will be caught by the unit tests.
   176  			panic("cannot encode: " + err.Error())
   177  		}
   178  		size := len(data)
   179  		if headSize+size+1 >= 1280 {
   180  			return n
   181  		}
   182  	}
   183  }()
   184  
   185  var maxTopicNodes = func() int {
   186  	p := TopicNodes{}
   187  	maxSizeNode := RpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
   188  	for n := 0; ; n++ {
   189  		p.Nodes = append(p.Nodes, maxSizeNode)
   190  		//size, _, err := rlp.EncodeToReader(p)
   191  		_, err := p.MarshalMsg(nil)
   192  
   193  		if err != nil {
   194  			// If this ever happens, it will be caught by the unit tests.
   195  			panic("cannot encode: " + err.Error())
   196  		}
   197  		size := p.Msgsize()
   198  		if headSize+size+1 >= 1280 {
   199  			return n
   200  		}
   201  	}
   202  }()
   203  
   204  func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) RpcEndpoint {
   205  	ip := addr.IP.To4()
   206  	if ip == nil {
   207  		ip = addr.IP.To16()
   208  	}
   209  	return RpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
   210  }
   211  
   212  func (e1 RpcEndpoint) equal(e2 RpcEndpoint) bool {
   213  	e1Ip := net.IP(e1.IP)
   214  	return e1.UDP == e2.UDP && e1.TCP == e2.TCP && e1Ip.Equal(e2.IP)
   215  }
   216  
   217  func nodeFromRPC(sender *net.UDPAddr, rn RpcNode) (*Node, error) {
   218  	if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
   219  		return nil, err
   220  	}
   221  	n := NewNode(rn.ID, rn.IP, rn.UDP, rn.TCP)
   222  	err := n.validateComplete()
   223  	return n, err
   224  }
   225  
   226  func nodeToRPC(n *Node) RpcNode {
   227  	return RpcNode{ID: n.ID, IP: n.IP, UDP: n.UDP, TCP: n.TCP}
   228  }
   229  
   230  type ingressPacket struct {
   231  	remoteID   NodeID
   232  	remoteAddr *net.UDPAddr
   233  	ev         nodeEvent
   234  	hash       []byte
   235  	data       interface{} // one of the RPC structs
   236  	rawData    []byte
   237  }
   238  
   239  type conn interface {
   240  	ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error)
   241  	WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error)
   242  	Close() error
   243  	LocalAddr() net.Addr
   244  }
   245  
   246  // udp implements the RPC protocol.
   247  type udp struct {
   248  	conn        conn
   249  	priv        *ecdsa.PrivateKey
   250  	ourEndpoint RpcEndpoint
   251  	nat         nat.Interface
   252  	net         *Network
   253  }
   254  
   255  // ListenUDP returns a new table that listens for UDP packets on laddr.
   256  func ListenUDP(priv *ecdsa.PrivateKey, conn conn, nodeDBPath string, netrestrict *netutil.Netlist) (*Network, error) {
   257  	realaddr := conn.LocalAddr().(*net.UDPAddr)
   258  	transport, err := listenUDP(priv, conn, realaddr)
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  	net, err := newNetwork(transport, priv.PublicKey, nodeDBPath, netrestrict)
   263  	if err != nil {
   264  		return nil, err
   265  	}
   266  	log.WithField("net", net.tab.self).Info("UDP listener up")
   267  	transport.net = net
   268  	goroutine.New(transport.readLoop)
   269  	return net, nil
   270  }
   271  
   272  func listenUDP(priv *ecdsa.PrivateKey, conn conn, realaddr *net.UDPAddr) (*udp, error) {
   273  	return &udp{conn: conn, priv: priv, ourEndpoint: makeEndpoint(realaddr, uint16(realaddr.Port))}, nil
   274  }
   275  
   276  func (t *udp) localAddr() *net.UDPAddr {
   277  	return t.conn.LocalAddr().(*net.UDPAddr)
   278  }
   279  
   280  func (t *udp) Close() {
   281  	t.conn.Close()
   282  }
   283  
   284  func (t *udp) send(remote *Node, ptype nodeEvent, data []byte) (hash []byte) {
   285  	hash, _ = t.sendPacket(remote.ID, remote.addr(), byte(ptype), data)
   286  	return hash
   287  }
   288  
   289  func (t *udp) sendPing(remote *Node, toaddr *net.UDPAddr, topics []Topic) (hash []byte) {
   290  	ping := Ping{
   291  		Version:    Version,
   292  		From:       t.ourEndpoint,
   293  		To:         makeEndpoint(toaddr, uint16(toaddr.Port)), // TODO: maybe use known TCP port from DB
   294  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   295  		Topics:     topicsToStrings(topics),
   296  	}
   297  	data, _ := ping.MarshalMsg(nil)
   298  	hash, _ = t.sendPacket(remote.ID, toaddr, byte(pingPacket), data)
   299  	return hash
   300  }
   301  
   302  func (t *udp) sendFindnode(remote *Node, target NodeID) {
   303  	f := Findnode{
   304  		Target:     target,
   305  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   306  	}
   307  	data, _ := f.MarshalMsg(nil)
   308  	t.sendPacket(remote.ID, remote.addr(), byte(findnodePacket), data)
   309  }
   310  
   311  func (t *udp) sendNeighbours(remote *Node, results []*Node) {
   312  	// Send neighbors in chunks with at most maxNeighbors per packet
   313  	// to stay below the 1280 byte limit.
   314  	p := Neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}
   315  	for i, result := range results {
   316  		p.Nodes = append(p.Nodes, nodeToRPC(result))
   317  		if len(p.Nodes) == maxNeighbors || i == len(results)-1 {
   318  			data, _ := p.MarshalMsg(nil)
   319  			t.sendPacket(remote.ID, remote.addr(), byte(neighborsPacket), data)
   320  			p.Nodes = p.Nodes[:0]
   321  		}
   322  	}
   323  }
   324  
   325  func (t *udp) sendFindnodeHash(remote *Node, target types.Hash) {
   326  	f := FindnodeHash{
   327  		Target:     target.Bytes,
   328  		Expiration: uint64(time.Now().Add(expiration).Unix()),
   329  	}
   330  	data, _ := f.MarshalMsg(nil)
   331  	t.sendPacket(remote.ID, remote.addr(), byte(findnodeHashPacket), data)
   332  }
   333  
   334  func (t *udp) sendTopicRegister(remote *Node, topics []Topic, idx int, pong []byte) {
   335  	tp := TopicRegister{
   336  		Topics: topicsToStrings(topics),
   337  		Idx:    uint(idx),
   338  		Pong:   pong,
   339  	}
   340  	data, _ := tp.MarshalMsg(nil)
   341  	t.sendPacket(remote.ID, remote.addr(), byte(topicRegisterPacket), data)
   342  }
   343  
   344  func (t *udp) sendTopicNodes(remote *Node, queryHash types.Hash, nodes []*Node) {
   345  	p := TopicNodes{Echo: queryHash.Bytes}
   346  	var sent bool
   347  	for _, result := range nodes {
   348  		IP := net.IP(result.IP)
   349  		if IP.Equal(t.net.tab.self.IP) || netutil.CheckRelayIP(remote.IP, result.IP) == nil {
   350  			p.Nodes = append(p.Nodes, nodeToRPC(result))
   351  		}
   352  		if len(p.Nodes) == maxTopicNodes {
   353  			data, _ := p.MarshalMsg(nil)
   354  			t.sendPacket(remote.ID, remote.addr(), byte(topicNodesPacket), data)
   355  			p.Nodes = p.Nodes[:0]
   356  			sent = true
   357  		}
   358  	}
   359  	if !sent || len(p.Nodes) > 0 {
   360  		data, _ := p.MarshalMsg(nil)
   361  		t.sendPacket(remote.ID, remote.addr(), byte(topicNodesPacket), data)
   362  	}
   363  }
   364  
   365  func (t *udp) sendPacket(toid NodeID, toaddr *net.UDPAddr, ptype byte, data []byte) (hash []byte, err error) {
   366  	//fmt.Println("sendPacket", nodeEvent(ptype), toaddr.String(), toid.String())
   367  	packet, hash, err := encodePacket(t.priv, ptype, data)
   368  	if err != nil {
   369  		//fmt.Println(err)
   370  		return hash, err
   371  	}
   372  	log.Trace(">>> %v to %x@%v", nodeEvent(ptype), toid[:8], toaddr)
   373  	if _, err := t.conn.WriteToUDP(packet, toaddr); err != nil {
   374  		log.WithError(err).Trace("UDP send failed")
   375  	} else {
   376  		//egressTrafficMeter.Mark(int64(nbytes))
   377  	}
   378  	//fmt.Println(err)
   379  	return hash, err
   380  }
   381  
   382  // zeroed padding space for encodePacket.
   383  var headSpace = make([]byte, headSize)
   384  
   385  func encodePacket(priv *ecdsa.PrivateKey, ptype byte, data []byte) (p, hash []byte, err error) {
   386  	b := new(bytes.Buffer)
   387  	b.Write(headSpace)
   388  	b.WriteByte(ptype)
   389  	b.Write(data)
   390  	packet := b.Bytes()
   391  	sig, err := ogcrypto2.Sign(ogcrypto2.Keccak256(packet[headSize:]), priv)
   392  	if err != nil {
   393  		log.WithError(err).Error("could not sign packet")
   394  		return nil, nil, err
   395  	}
   396  	copy(packet, versionPrefix)
   397  	copy(packet[versionPrefixSize:], sig)
   398  	hash = ogcrypto2.Keccak256(packet[versionPrefixSize:])
   399  	return packet, hash, nil
   400  }
   401  
   402  // readLoop runs in its own goroutine. it injects ingress UDP packets
   403  // into the network loop.
   404  func (t *udp) readLoop() {
   405  	defer t.conn.Close()
   406  	// Discovery packets are defined to be no larger than 1280 bytes.
   407  	// Packets larger than this size will be cut at the end and treated
   408  	// as invalid because their hash won't match.
   409  	buf := make([]byte, 1280)
   410  	for {
   411  		nbytes, from, err := t.conn.ReadFromUDP(buf)
   412  		//ingressTrafficMeter.Mark(int64(nbytes))
   413  		if netutil.IsTemporaryError(err) {
   414  			// Ignore temporary read errors.
   415  			log.WithError(err).Debug("Temporary read error")
   416  			continue
   417  		} else if err != nil {
   418  			// Shut down the loop for permament errors.
   419  			log.WithError(err).Debug("Read error")
   420  			return
   421  		}
   422  		t.handlePacket(from, buf[:nbytes])
   423  	}
   424  }
   425  
   426  func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error {
   427  	pkt := ingressPacket{remoteAddr: from}
   428  	if err := decodePacket(buf, &pkt); err != nil {
   429  		log.WithError(err).WithField("from", from).Debug("Bad packet")
   430  		//fmt.Println("bad packet", err)
   431  		return err
   432  	}
   433  	t.net.reqReadPacket(pkt)
   434  	return nil
   435  }
   436  
   437  func decodePacket(buffer []byte, pkt *ingressPacket) error {
   438  	if len(buffer) < headSize+1 {
   439  		return errPacketTooSmall
   440  	}
   441  	buf := make([]byte, len(buffer))
   442  	copy(buf, buffer)
   443  	prefix, sig, sigdata := buf[:versionPrefixSize], buf[versionPrefixSize:headSize], buf[headSize:]
   444  	if !bytes.Equal(prefix, versionPrefix) {
   445  		return errBadPrefix
   446  	}
   447  	fromID, err := recoverNodeID(ogcrypto2.Keccak256(buf[headSize:]), sig)
   448  	if err != nil {
   449  		return err
   450  	}
   451  	pkt.rawData = buf
   452  	pkt.hash = ogcrypto2.Keccak256(buf[versionPrefixSize:])
   453  	pkt.remoteID = fromID
   454  	data := sigdata[1:]
   455  	switch pkt.ev = nodeEvent(sigdata[0]); pkt.ev {
   456  	case pingPacket:
   457  		req := new(Ping)
   458  		_, err = req.UnmarshalMsg(data)
   459  		pkt.data = req
   460  	case pongPacket:
   461  		req := new(Pong)
   462  		_, err = req.UnmarshalMsg(data)
   463  		pkt.data = req
   464  	case findnodePacket:
   465  		req := new(Findnode)
   466  		_, err = req.UnmarshalMsg(data)
   467  		pkt.data = req
   468  	case neighborsPacket:
   469  		req := new(Neighbors)
   470  		_, err = req.UnmarshalMsg(data)
   471  		pkt.data = req
   472  	case findnodeHashPacket:
   473  		req := new(FindnodeHash)
   474  		_, err = req.UnmarshalMsg(data)
   475  		pkt.data = req
   476  	case topicRegisterPacket:
   477  		req := new(TopicRegister)
   478  		_, err = req.UnmarshalMsg(data)
   479  		pkt.data = req
   480  	case topicQueryPacket:
   481  		req := new(TopicQuery)
   482  		_, err = req.UnmarshalMsg(data)
   483  		pkt.data = req
   484  	case topicNodesPacket:
   485  		req := new(TopicNodes)
   486  		_, err = req.UnmarshalMsg(data)
   487  		pkt.data = req
   488  	default:
   489  		return fmt.Errorf("unknown packet type: %d", sigdata[0])
   490  	}
   491  	//s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0)
   492  	//err = s.Decode(pkt.data)
   493  	return err
   494  }