aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eth/backend.go4
-rw-r--r--p2p/discover/database_test.go10
-rw-r--r--p2p/discover/node.go61
-rw-r--r--p2p/discover/node_test.go26
-rw-r--r--p2p/discover/table.go9
-rw-r--r--p2p/discover/table_test.go4
-rw-r--r--p2p/discover/udp.go78
-rw-r--r--p2p/discover/udp_test.go81
-rw-r--r--p2p/handshake_test.go12
-rw-r--r--p2p/server.go2
-rw-r--r--p2p/server_test.go2
11 files changed, 160 insertions, 129 deletions
diff --git a/eth/backend.go b/eth/backend.go
index c5fa328b0..6a5792c46 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -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(),
}
diff --git a/p2p/discover/database_test.go b/p2p/discover/database_test.go
index f327cf73b..0cc0dec32 100644
--- a/p2p/discover/database_test.go
+++ b/p2p/discover/database_test.go
@@ -6,6 +6,7 @@ import (
"net"
"os"
"path/filepath"
+ "reflect"
"testing"
"time"
)
@@ -86,9 +87,10 @@ func TestNodeDBInt64(t *testing.T) {
func TestNodeDBFetchStore(t *testing.T) {
node := &Node{
- ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
- IP: net.IP([]byte{192, 168, 0, 1}),
- TCPPort: 30303,
+ ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
+ IP: net.IP([]byte{192, 168, 0, 1}),
+ 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)
}
}
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
diff --git a/p2p/discover/node_test.go b/p2p/discover/node_test.go
index 60b01b6ca..8ea9018c5 100644
--- a/p2p/discover/node_test.go
+++ b/p2p/discover/node_test.go
@@ -49,28 +49,28 @@ var parseNodeTests = []struct {
{
rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150",
wantResult: &Node{
- ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
- IP: net.ParseIP("127.0.0.1"),
- DiscPort: 52150,
- TCPPort: 52150,
+ ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
+ IP: net.ParseIP("127.0.0.1"),
+ UDP: 52150,
+ TCP: 52150,
},
},
{
rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150",
wantResult: &Node{
- ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
- IP: net.ParseIP("::"),
- DiscPort: 52150,
- TCPPort: 52150,
+ ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
+ IP: net.ParseIP("::"),
+ 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,
+ ID: MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
+ IP: net.ParseIP("127.0.0.1"),
+ UDP: 22334,
+ TCP: 52150,
},
},
}
diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index d3fe373f4..bbd40fde9 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -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)
}
diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go
index e2bd3c8ad..e7394756d 100644
--- a/p2p/discover/table_test.go
+++ b/p2p/discover/table_test.go
@@ -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
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index 65741b5f5..baff75a63 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -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 {
@@ -94,8 +111,9 @@ type conn interface {
// udp implements the RPC protocol.
type udp struct {
- conn conn
- priv *ecdsa.PrivateKey
+ 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])
- if err != nil {
- glog.V(logger.Debug).Infof("Bad packet from %v: %v\n", from, err)
- continue
- }
- status := "ok"
- 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)
+ 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)
+ return err
}
+ status := "ok"
+ 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
}
diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go
index 47e04b85a..378edaaa7 100644
--- a/p2p/discover/udp_test.go
+++ b/p2p/discover/udp_test.go
@@ -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})
@@ -147,10 +149,10 @@ func TestUDP_findnode(t *testing.T) {
nodes := &nodesByDistance{target: target}
for i := 0; i < bucketSize; i++ {
nodes.push(&Node{
- IP: net.IP{1, 2, 3, byte(i)},
- DiscPort: i + 2,
- TCPPort: i + 2,
- ID: randomID(test.table.self.ID, i+2),
+ IP: net.IP{1, 2, 3, byte(i)},
+ UDP: uint16(i + 2),
+ TCP: uint16(i + 3),
+ ID: randomID(test.table.self.ID, i+2),
}, bucketSize)
}
test.table.add(nodes.entries)
@@ -158,10 +160,10 @@ func TestUDP_findnode(t *testing.T) {
// ensure there's a bond with the test node,
// findnode won't be accepted otherwise.
test.table.db.updateNode(&Node{
- ID: PubkeyID(&test.remotekey.PublicKey),
- IP: test.remoteaddr.IP,
- DiscPort: test.remoteaddr.Port,
- TCPPort: 99,
+ ID: PubkeyID(&test.remotekey.PublicKey),
+ IP: test.remoteaddr.IP,
+ 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 {
diff --git a/p2p/handshake_test.go b/p2p/handshake_test.go
index c22af7a9c..f618ef20d 100644
--- a/p2p/handshake_test.go
+++ b/p2p/handshake_test.go
@@ -119,14 +119,14 @@ func TestSetupConn(t *testing.T) {
prv0, _ := crypto.GenerateKey()
prv1, _ := crypto.GenerateKey()
node0 := &discover.Node{
- ID: discover.PubkeyID(&prv0.PublicKey),
- IP: net.IP{1, 2, 3, 4},
- TCPPort: 33,
+ ID: discover.PubkeyID(&prv0.PublicKey),
+ IP: net.IP{1, 2, 3, 4},
+ TCP: 33,
}
node1 := &discover.Node{
- ID: discover.PubkeyID(&prv1.PublicKey),
- IP: net.IP{5, 6, 7, 8},
- TCPPort: 44,
+ ID: discover.PubkeyID(&prv1.PublicKey),
+ IP: net.IP{5, 6, 7, 8},
+ TCP: 44,
}
hs0 := &protoHandshake{
Version: baseProtocolVersion,
diff --git a/p2p/server.go b/p2p/server.go
index 5c5883ae8..e648c72c9 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -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 {
diff --git a/p2p/server_test.go b/p2p/server_test.go
index 53cc3c258..86514b650 100644
--- a/p2p/server_test.go
+++ b/p2p/server_test.go
@@ -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: