mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 20:56:42 +00:00
Merge b34a8ef624 into 323216ed85
This commit is contained in:
commit
f99c960439
12 changed files with 162 additions and 131 deletions
|
|
@ -277,8 +277,8 @@ func (s *Ethereum) NodeInfo() *NodeInfo {
|
|||
NodeUrl: node.String(),
|
||||
NodeID: node.ID.String(),
|
||||
IP: node.IP.String(),
|
||||
DiscPort: node.DiscPort,
|
||||
TCPPort: node.TCPPort,
|
||||
DiscPort: int(node.UDP),
|
||||
TCPPort: int(node.TCP),
|
||||
ListenAddr: s.net.ListenAddr,
|
||||
Td: s.ChainManager().Td().String(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -88,7 +89,8 @@ func TestNodeDBFetchStore(t *testing.T) {
|
|||
node := &Node{
|
||||
ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
IP: net.IP([]byte{192, 168, 0, 1}),
|
||||
TCPPort: 30303,
|
||||
UDP: 30303,
|
||||
TCP: 30303,
|
||||
}
|
||||
inst := time.Now()
|
||||
|
||||
|
|
@ -124,7 +126,7 @@ func TestNodeDBFetchStore(t *testing.T) {
|
|||
}
|
||||
if stored := db.node(node.ID); stored == nil {
|
||||
t.Errorf("node: not found")
|
||||
} else if !bytes.Equal(stored.ID[:], node.ID[:]) || !stored.IP.Equal(node.IP) || stored.TCPPort != node.TCPPort {
|
||||
} else if !reflect.DeepEqual(stored, node) {
|
||||
t.Errorf("node: data mismatch: have %v, want %v", stored, node)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
IP net.IP // len 4 for IPv4 or 16 for IPv6
|
||||
UDP, TCP uint16 // port numbers
|
||||
ID NodeID
|
||||
IP net.IP
|
||||
|
||||
DiscPort int // UDP listening port for discovery protocol
|
||||
TCPPort int // TCP listening port for RLPx
|
||||
}
|
||||
|
||||
func newNode(id NodeID, addr *net.UDPAddr) *Node {
|
||||
ip := addr.IP.To4()
|
||||
if ip == nil {
|
||||
ip = addr.IP.To16()
|
||||
}
|
||||
return &Node{
|
||||
IP: ip,
|
||||
UDP: uint16(addr.Port),
|
||||
TCP: uint16(addr.Port),
|
||||
ID: id,
|
||||
IP: addr.IP,
|
||||
DiscPort: addr.Port,
|
||||
TCPPort: addr.Port,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ var parseNodeTests = []struct {
|
|||
wantResult: &Node{
|
||||
ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
IP: net.ParseIP("127.0.0.1"),
|
||||
DiscPort: 52150,
|
||||
TCPPort: 52150,
|
||||
UDP: 52150,
|
||||
TCP: 52150,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -60,17 +60,17 @@ var parseNodeTests = []struct {
|
|||
wantResult: &Node{
|
||||
ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
IP: net.ParseIP("::"),
|
||||
DiscPort: 52150,
|
||||
TCPPort: 52150,
|
||||
UDP: 52150,
|
||||
TCP: 52150,
|
||||
},
|
||||
},
|
||||
{
|
||||
rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=223344",
|
||||
rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334",
|
||||
wantResult: &Node{
|
||||
ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||
IP: net.ParseIP("127.0.0.1"),
|
||||
DiscPort: 223344,
|
||||
TCPPort: 52150,
|
||||
UDP: 22334,
|
||||
TCP: 52150,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ func (tab *Table) bondall(nodes []*Node) (result []*Node) {
|
|||
rc := make(chan *Node, len(nodes))
|
||||
for i := range nodes {
|
||||
go func(n *Node) {
|
||||
nn, _ := tab.bond(false, n.ID, n.addr(), uint16(n.TCPPort))
|
||||
nn, _ := tab.bond(false, n.ID, n.addr(), uint16(n.TCP))
|
||||
rc <- nn
|
||||
}(nodes[i])
|
||||
}
|
||||
|
|
@ -299,12 +299,7 @@ func (tab *Table) pingpong(w *bondproc, pinged bool, id NodeID, addr *net.UDPAdd
|
|||
tab.net.waitping(id)
|
||||
}
|
||||
// Bonding succeeded, update the node database
|
||||
w.n = &Node{
|
||||
ID: id,
|
||||
IP: addr.IP,
|
||||
DiscPort: addr.Port,
|
||||
TCPPort: int(tcpPort),
|
||||
}
|
||||
w.n = &Node{ID: id, IP: addr.IP, UDP: uint16(addr.Port), TCP: tcpPort}
|
||||
tab.db.updateNode(w.n)
|
||||
close(w.done)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,9 +261,9 @@ func (t findnodeOracle) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID
|
|||
panic("query to node at distance 0")
|
||||
default:
|
||||
// TODO: add more randomness to distances
|
||||
next := toaddr.Port - 1
|
||||
next := uint16(toaddr.Port) - 1
|
||||
for i := 0; i < bucketSize; i++ {
|
||||
result = append(result, &Node{ID: randomID(t.target, next), DiscPort: next})
|
||||
result = append(result, &Node{ID: randomID(t.target, int(next)), UDP: next})
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
const Version = 3
|
||||
const Version = 4
|
||||
|
||||
// Errors
|
||||
var (
|
||||
|
|
@ -49,16 +49,20 @@ const (
|
|||
// RPC request structures
|
||||
type (
|
||||
ping struct {
|
||||
Version uint // must match Version
|
||||
IP string // our IP
|
||||
Port uint16 // our port
|
||||
Version uint
|
||||
From, To rpcEndpoint
|
||||
Expiration uint64
|
||||
}
|
||||
|
||||
// reply to Ping
|
||||
// pong is the reply to ping.
|
||||
pong struct {
|
||||
ReplyTok []byte
|
||||
Expiration uint64
|
||||
// This field should mirror the UDP envelope address
|
||||
// of the ping packet, which provides a way to discover the
|
||||
// the external address (after NAT).
|
||||
To rpcEndpoint
|
||||
|
||||
ReplyTok []byte // This contains the hash of the ping packet.
|
||||
Expiration uint64 // Absolute timestamp at which the packet becomes invalid.
|
||||
}
|
||||
|
||||
findnode struct {
|
||||
|
|
@ -73,12 +77,25 @@ type (
|
|||
Nodes []*Node
|
||||
Expiration uint64
|
||||
}
|
||||
|
||||
rpcEndpoint struct {
|
||||
IP net.IP // len 4 for IPv4 or 16 for IPv6
|
||||
UDP uint16 // for discovery protocol
|
||||
TCP uint16 // for RLPx protocol
|
||||
}
|
||||
)
|
||||
|
||||
type rpcNode struct {
|
||||
IP string
|
||||
Port uint16
|
||||
ID NodeID
|
||||
func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {
|
||||
ip := addr.IP.To4()
|
||||
if ip == nil {
|
||||
ip = addr.IP.To16()
|
||||
}
|
||||
return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
|
||||
}
|
||||
|
||||
func validNode(n *Node) bool {
|
||||
// TODO: don't accept localhost, LAN addresses from internet hosts
|
||||
return !n.IP.IsMulticast() && !n.IP.IsUnspecified() && n.UDP != 0
|
||||
}
|
||||
|
||||
type packet interface {
|
||||
|
|
@ -96,6 +113,7 @@ type conn interface {
|
|||
type udp struct {
|
||||
conn conn
|
||||
priv *ecdsa.PrivateKey
|
||||
ourEndpoint rpcEndpoint
|
||||
|
||||
addpending chan *pending
|
||||
gotreply chan reply
|
||||
|
|
@ -176,6 +194,8 @@ func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath strin
|
|||
realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
|
||||
}
|
||||
}
|
||||
// TODO: separate TCP port
|
||||
udp.ourEndpoint = makeEndpoint(realaddr, uint16(realaddr.Port))
|
||||
udp.Table = newTable(udp, PubkeyID(&priv.PublicKey), realaddr, nodeDBPath)
|
||||
go udp.loop()
|
||||
go udp.readLoop()
|
||||
|
|
@ -194,8 +214,8 @@ func (t *udp) ping(toid NodeID, toaddr *net.UDPAddr) error {
|
|||
errc := t.pending(toid, pongPacket, func(interface{}) bool { return true })
|
||||
t.send(toaddr, pingPacket, ping{
|
||||
Version: Version,
|
||||
IP: t.self.IP.String(),
|
||||
Port: uint16(t.self.TCPPort),
|
||||
From: t.ourEndpoint,
|
||||
To: makeEndpoint(toaddr, 0), // TODO: maybe use known TCP port from DB
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
return <-errc
|
||||
|
|
@ -214,7 +234,7 @@ func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node
|
|||
reply := r.(*neighbors)
|
||||
for _, n := range reply.Nodes {
|
||||
nreceived++
|
||||
if n.isValid() {
|
||||
if validNode(n) {
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
}
|
||||
|
|
@ -374,17 +394,22 @@ func (t *udp) readLoop() {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
packet, fromID, hash, err := decodePacket(buf[:nbytes])
|
||||
t.handlePacket(from, buf[:nbytes])
|
||||
}
|
||||
}
|
||||
|
||||
func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error {
|
||||
packet, fromID, hash, err := decodePacket(buf)
|
||||
if err != nil {
|
||||
glog.V(logger.Debug).Infof("Bad packet from %v: %v\n", from, err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
status := "ok"
|
||||
if err := packet.handle(t, from, fromID, hash); err != nil {
|
||||
if err = packet.handle(t, from, fromID, hash); err != nil {
|
||||
status = err.Error()
|
||||
}
|
||||
glog.V(logger.Detail).Infof("<<< %v %T: %s\n", from, packet, status)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func decodePacket(buf []byte) (packet, NodeID, []byte, error) {
|
||||
|
|
@ -425,12 +450,13 @@ func (req *ping) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) er
|
|||
return errBadVersion
|
||||
}
|
||||
t.send(from, pongPacket, pong{
|
||||
To: makeEndpoint(from, req.From.TCP),
|
||||
ReplyTok: mac,
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
if !t.handleReply(fromID, pingPacket, req) {
|
||||
// Note: we're ignoring the provided IP address right now
|
||||
go t.bond(true, fromID, from, req.Port)
|
||||
go t.bond(true, fromID, from, req.From.TCP)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@ func init() {
|
|||
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, logpkg.LstdFlags, logger.ErrorLevel))
|
||||
}
|
||||
|
||||
// shared test variables
|
||||
var (
|
||||
futureExp = uint64(time.Now().Add(10 * time.Hour).Unix())
|
||||
testTarget = MustHexID("01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101")
|
||||
testRemote = rpcEndpoint{IP: net.ParseIP("1.1.1.1").To4(), UDP: 1, TCP: 2}
|
||||
testLocalAnnounced = rpcEndpoint{IP: net.ParseIP("2.2.2.2").To4(), UDP: 3, TCP: 4}
|
||||
testLocal = rpcEndpoint{IP: net.ParseIP("3.3.3.3").To4(), UDP: 5, TCP: 6}
|
||||
)
|
||||
|
||||
type udpTest struct {
|
||||
t *testing.T
|
||||
pipe *dgramPipe
|
||||
|
|
@ -52,8 +61,7 @@ func (test *udpTest) packetIn(wantError error, ptype byte, data packet) error {
|
|||
return test.errorf("packet (%d) encode error: %v", err)
|
||||
}
|
||||
test.sent = append(test.sent, enc)
|
||||
err = data.handle(test.udp, test.remoteaddr, PubkeyID(&test.remotekey.PublicKey), enc[:macSize])
|
||||
if err != wantError {
|
||||
if err = test.udp.handlePacket(test.remoteaddr, enc); err != wantError {
|
||||
return test.errorf("error mismatch: got %q, want %q", err, wantError)
|
||||
}
|
||||
return nil
|
||||
|
|
@ -90,18 +98,12 @@ func (test *udpTest) errorf(format string, args ...interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// shared test variables
|
||||
var (
|
||||
futureExp = uint64(time.Now().Add(10 * time.Hour).Unix())
|
||||
testTarget = MustHexID("01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101")
|
||||
)
|
||||
|
||||
func TestUDP_packetErrors(t *testing.T) {
|
||||
test := newUDPTest(t)
|
||||
defer test.table.Close()
|
||||
|
||||
test.packetIn(errExpired, pingPacket, &ping{IP: "foo", Port: 99, Version: Version})
|
||||
test.packetIn(errBadVersion, pingPacket, &ping{IP: "foo", Port: 99, Version: 99, Expiration: futureExp})
|
||||
test.packetIn(errExpired, pingPacket, &ping{From: testRemote, To: testLocalAnnounced, Version: Version})
|
||||
test.packetIn(errBadVersion, pingPacket, &ping{From: testRemote, To: testLocalAnnounced, Version: 99, Expiration: futureExp})
|
||||
test.packetIn(errUnsolicitedReply, pongPacket, &pong{ReplyTok: []byte{}, Expiration: futureExp})
|
||||
test.packetIn(errUnknownNode, findnodePacket, &findnode{Expiration: futureExp})
|
||||
test.packetIn(errUnsolicitedReply, neighborsPacket, &neighbors{Expiration: futureExp})
|
||||
|
|
@ -148,8 +150,8 @@ func TestUDP_findnode(t *testing.T) {
|
|||
for i := 0; i < bucketSize; i++ {
|
||||
nodes.push(&Node{
|
||||
IP: net.IP{1, 2, 3, byte(i)},
|
||||
DiscPort: i + 2,
|
||||
TCPPort: i + 2,
|
||||
UDP: uint16(i + 2),
|
||||
TCP: uint16(i + 3),
|
||||
ID: randomID(test.table.self.ID, i+2),
|
||||
}, bucketSize)
|
||||
}
|
||||
|
|
@ -160,8 +162,8 @@ func TestUDP_findnode(t *testing.T) {
|
|||
test.table.db.updateNode(&Node{
|
||||
ID: PubkeyID(&test.remotekey.PublicKey),
|
||||
IP: test.remoteaddr.IP,
|
||||
DiscPort: test.remoteaddr.Port,
|
||||
TCPPort: 99,
|
||||
UDP: uint16(test.remoteaddr.Port),
|
||||
TCP: 99,
|
||||
})
|
||||
// check that closest neighbors are returned.
|
||||
test.packetIn(nil, findnodePacket, &findnode{Target: testTarget, Expiration: futureExp})
|
||||
|
|
@ -204,9 +206,9 @@ func TestUDP_findnodeMultiReply(t *testing.T) {
|
|||
|
||||
// send the reply as two packets.
|
||||
list := []*Node{
|
||||
MustParseNode("enode://ba85011c70bcc5c04d8607d3a0ed29aa6179c092cbdda10d5d32684fb33ed01bd94f588ca8f91ac48318087dcb02eaf36773a7a453f0eedd6742af668097b29c@10.0.1.16:30303"),
|
||||
MustParseNode("enode://ba85011c70bcc5c04d8607d3a0ed29aa6179c092cbdda10d5d32684fb33ed01bd94f588ca8f91ac48318087dcb02eaf36773a7a453f0eedd6742af668097b29c@10.0.1.16:30303?discport=30304"),
|
||||
MustParseNode("enode://81fa361d25f157cd421c60dcc28d8dac5ef6a89476633339c5df30287474520caca09627da18543d9079b5b288698b542d56167aa5c09111e55acdbbdf2ef799@10.0.1.16:30303"),
|
||||
MustParseNode("enode://9bffefd833d53fac8e652415f4973bee289e8b1a5c6c4cbe70abf817ce8a64cee11b823b66a987f51aaa9fba0d6a91b3e6bf0d5a5d1042de8e9eeea057b217f8@10.0.1.36:30301"),
|
||||
MustParseNode("enode://9bffefd833d53fac8e652415f4973bee289e8b1a5c6c4cbe70abf817ce8a64cee11b823b66a987f51aaa9fba0d6a91b3e6bf0d5a5d1042de8e9eeea057b217f8@10.0.1.36:30301?discport=17"),
|
||||
MustParseNode("enode://1b5b4aa662d7cb44a7221bfba67302590b643028197a7d5214790f3bac7aaa4a3241be9e83c09cf1f6c69d007c634faae3dc1b1221793e8446c0b3a09de65960@10.0.1.16:30303"),
|
||||
}
|
||||
test.packetIn(nil, neighborsPacket, &neighbors{Expiration: futureExp, Nodes: list[:2]})
|
||||
|
|
@ -231,7 +233,8 @@ func TestUDP_successfulPing(t *testing.T) {
|
|||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
test.packetIn(nil, pingPacket, &ping{IP: "foo", Port: 99, Version: Version, Expiration: futureExp})
|
||||
// The remote side sends a ping packet to initiate the exchange.
|
||||
test.packetIn(nil, pingPacket, &ping{From: testRemote, To: testLocalAnnounced, Version: Version, Expiration: futureExp})
|
||||
close(done)
|
||||
}()
|
||||
|
||||
|
|
@ -239,12 +242,34 @@ func TestUDP_successfulPing(t *testing.T) {
|
|||
test.waitPacketOut(func(p *pong) {
|
||||
pinghash := test.sent[0][:macSize]
|
||||
if !bytes.Equal(p.ReplyTok, pinghash) {
|
||||
t.Errorf("got ReplyTok %x, want %x", p.ReplyTok, pinghash)
|
||||
t.Errorf("got pong.ReplyTok %x, want %x", p.ReplyTok, pinghash)
|
||||
}
|
||||
wantTo := rpcEndpoint{
|
||||
// The mirrored UDP address is the UDP packet sender
|
||||
IP: test.remoteaddr.IP, UDP: uint16(test.remoteaddr.Port),
|
||||
// The mirrored TCP port is the one from the ping packet
|
||||
TCP: testRemote.TCP,
|
||||
}
|
||||
if !reflect.DeepEqual(p.To, wantTo) {
|
||||
t.Errorf("got pong.To %v, want %v", p.To, wantTo)
|
||||
}
|
||||
})
|
||||
|
||||
// remote is unknown, the table pings back.
|
||||
test.waitPacketOut(func(p *ping) error { return nil })
|
||||
test.waitPacketOut(func(p *ping) error {
|
||||
if !reflect.DeepEqual(p.From, test.udp.ourEndpoint) {
|
||||
t.Errorf("got ping.From %v, want %v", p.From, test.udp.ourEndpoint)
|
||||
}
|
||||
wantTo := rpcEndpoint{
|
||||
// The mirrored UDP address is the UDP packet sender.
|
||||
IP: test.remoteaddr.IP, UDP: uint16(test.remoteaddr.Port),
|
||||
TCP: 0,
|
||||
}
|
||||
if !reflect.DeepEqual(p.To, wantTo) {
|
||||
t.Errorf("got ping.To %v, want %v", p.To, wantTo)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
test.packetIn(nil, pongPacket, &pong{Expiration: futureExp})
|
||||
|
||||
// ping should return shortly after getting the pong packet.
|
||||
|
|
@ -259,11 +284,11 @@ func TestUDP_successfulPing(t *testing.T) {
|
|||
if !bytes.Equal(rnode.IP, test.remoteaddr.IP) {
|
||||
t.Errorf("node has wrong IP: got %v, want: %v", rnode.IP, test.remoteaddr.IP)
|
||||
}
|
||||
if rnode.DiscPort != test.remoteaddr.Port {
|
||||
t.Errorf("node has wrong Port: got %v, want: %v", rnode.DiscPort, test.remoteaddr.Port)
|
||||
if int(rnode.UDP) != test.remoteaddr.Port {
|
||||
t.Errorf("node has wrong UDP port: got %v, want: %v", rnode.UDP, test.remoteaddr.Port)
|
||||
}
|
||||
if rnode.TCPPort != 99 {
|
||||
t.Errorf("node has wrong Port: got %v, want: %v", rnode.TCPPort, 99)
|
||||
if rnode.TCP != testRemote.TCP {
|
||||
t.Errorf("node has wrong TCP port: got %v, want: %v", rnode.TCP, testRemote.TCP)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +352,7 @@ func (c *dgramPipe) Close() error {
|
|||
}
|
||||
|
||||
func (c *dgramPipe) LocalAddr() net.Addr {
|
||||
return &net.UDPAddr{}
|
||||
return &net.UDPAddr{IP: testLocal.IP, Port: int(testLocal.UDP)}
|
||||
}
|
||||
|
||||
func (c *dgramPipe) waitPacketOut() []byte {
|
||||
|
|
|
|||
|
|
@ -121,12 +121,12 @@ func TestSetupConn(t *testing.T) {
|
|||
node0 := &discover.Node{
|
||||
ID: discover.PubkeyID(&prv0.PublicKey),
|
||||
IP: net.IP{1, 2, 3, 4},
|
||||
TCPPort: 33,
|
||||
TCP: 33,
|
||||
}
|
||||
node1 := &discover.Node{
|
||||
ID: discover.PubkeyID(&prv1.PublicKey),
|
||||
IP: net.IP{5, 6, 7, 8},
|
||||
TCPPort: 44,
|
||||
TCP: 44,
|
||||
}
|
||||
hs0 := &protoHandshake{
|
||||
Version: baseProtocolVersion,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
baseProtocolVersion = 3
|
||||
baseProtocolVersion = 4
|
||||
baseProtocolLength = uint64(16)
|
||||
baseProtocolMaxMsgSize = 10 * 1024 * 1024
|
||||
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ func (srv *Server) dialLoop() {
|
|||
}
|
||||
|
||||
func (srv *Server) dialNode(dest *discover.Node) {
|
||||
addr := &net.TCPAddr{IP: dest.IP, Port: dest.TCPPort}
|
||||
addr := &net.TCPAddr{IP: dest.IP, Port: int(dest.TCP)}
|
||||
glog.V(logger.Debug).Infof("Dialing %v\n", dest)
|
||||
conn, err := srv.Dialer.Dial("tcp", addr.String())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ func TestServerDial(t *testing.T) {
|
|||
|
||||
// tell the server to connect
|
||||
tcpAddr := listener.Addr().(*net.TCPAddr)
|
||||
srv.SuggestPeer(&discover.Node{IP: tcpAddr.IP, TCPPort: tcpAddr.Port})
|
||||
srv.SuggestPeer(&discover.Node{IP: tcpAddr.IP, TCP: uint16(tcpAddr.Port)})
|
||||
|
||||
select {
|
||||
case conn := <-accepted:
|
||||
|
|
|
|||
Loading…
Reference in a new issue