diff options
author | Felix Lange <fjl@twurst.com> | 2015-04-18 07:50:31 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-04-30 20:57:33 +0800 |
commit | fc747ef4a649cd90aec5193a8af6b7accb5eb03f (patch) | |
tree | b81f4b1fb00abd2bf05b4d586b0b3f08d2011cd5 /p2p/discover/node.go | |
parent | 3fef60190384106af390dd23a65384b9cc6e4a28 (diff) | |
download | dexon-fc747ef4a649cd90aec5193a8af6b7accb5eb03f.tar.gz dexon-fc747ef4a649cd90aec5193a8af6b7accb5eb03f.tar.zst dexon-fc747ef4a649cd90aec5193a8af6b7accb5eb03f.zip |
p2p/discover: new endpoint format
This commit changes the discovery protocol to use the new "v4" endpoint
format, which allows for separate UDP and TCP ports and makes it
possible to discover the UDP address after NAT.
Diffstat (limited to 'p2p/discover/node.go')
-rw-r--r-- | p2p/discover/node.go | 61 |
1 files changed, 22 insertions, 39 deletions
diff --git a/p2p/discover/node.go b/p2p/discover/node.go index e66ca37a4..cfb6ff552 100644 --- a/p2p/discover/node.go +++ b/p2p/discover/node.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "errors" "fmt" - "io" "math/big" "math/rand" "net" @@ -16,49 +15,45 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/secp256k1" - "github.com/ethereum/go-ethereum/rlp" ) const nodeIDBits = 512 // Node represents a host on the network. type Node struct { - ID NodeID - IP net.IP - - DiscPort int // UDP listening port for discovery protocol - TCPPort int // TCP listening port for RLPx + IP net.IP // len 4 for IPv4 or 16 for IPv6 + UDP, TCP uint16 // port numbers + ID NodeID } func newNode(id NodeID, addr *net.UDPAddr) *Node { + ip := addr.IP.To4() + if ip == nil { + ip = addr.IP.To16() + } return &Node{ - ID: id, - IP: addr.IP, - DiscPort: addr.Port, - TCPPort: addr.Port, + IP: ip, + UDP: uint16(addr.Port), + TCP: uint16(addr.Port), + ID: id, } } -func (n *Node) isValid() bool { - // TODO: don't accept localhost, LAN addresses from internet hosts - return !n.IP.IsMulticast() && !n.IP.IsUnspecified() && n.TCPPort != 0 && n.DiscPort != 0 -} - func (n *Node) addr() *net.UDPAddr { - return &net.UDPAddr{IP: n.IP, Port: n.DiscPort} + return &net.UDPAddr{IP: n.IP, Port: int(n.UDP)} } // The string representation of a Node is a URL. // Please see ParseNode for a description of the format. func (n *Node) String() string { - addr := net.TCPAddr{IP: n.IP, Port: n.TCPPort} + addr := net.TCPAddr{IP: n.IP, Port: int(n.TCP)} u := url.URL{ Scheme: "enode", User: url.User(fmt.Sprintf("%x", n.ID[:])), Host: addr.String(), } - if n.DiscPort != n.TCPPort { - u.RawQuery = "discport=" + strconv.Itoa(n.DiscPort) + if n.UDP != n.TCP { + u.RawQuery = "discport=" + strconv.Itoa(int(n.UDP)) } return u.String() } @@ -98,16 +93,20 @@ func ParseNode(rawurl string) (*Node, error) { if n.IP = net.ParseIP(ip); n.IP == nil { return nil, errors.New("invalid IP address") } - if n.TCPPort, err = strconv.Atoi(port); err != nil { + tcp, err := strconv.ParseUint(port, 10, 16) + if err != nil { return nil, errors.New("invalid port") } + n.TCP = uint16(tcp) qv := u.Query() if qv.Get("discport") == "" { - n.DiscPort = n.TCPPort + n.UDP = n.TCP } else { - if n.DiscPort, err = strconv.Atoi(qv.Get("discport")); err != nil { + udp, err := strconv.ParseUint(qv.Get("discport"), 10, 16) + if err != nil { return nil, errors.New("invalid discport in query") } + n.UDP = uint16(udp) } return &n, nil } @@ -121,22 +120,6 @@ func MustParseNode(rawurl string) *Node { return n } -func (n Node) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, rpcNode{IP: n.IP.String(), Port: uint16(n.TCPPort), ID: n.ID}) -} -func (n *Node) DecodeRLP(s *rlp.Stream) (err error) { - var ext rpcNode - if err = s.Decode(&ext); err == nil { - n.TCPPort = int(ext.Port) - n.DiscPort = int(ext.Port) - n.ID = ext.ID - if n.IP = net.ParseIP(ext.IP); n.IP == nil { - return errors.New("invalid IP string") - } - } - return err -} - // NodeID is a unique identifier for each node. // The node identifier is a marshaled elliptic curve public key. type NodeID [nodeIDBits / 8]byte |