mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
p2p/discover: WIP node refactoring part 2
This commit is contained in:
parent
b168d82446
commit
c0a1f1dfe1
8 changed files with 183 additions and 176 deletions
|
|
@ -22,6 +22,7 @@ import (
|
|||
"encoding/binary"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -34,8 +35,8 @@ import (
|
|||
|
||||
// UDPConn is a network connection on which discovery can operate.
|
||||
type UDPConn interface {
|
||||
ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error)
|
||||
WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error)
|
||||
ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error)
|
||||
WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (n int, err error)
|
||||
Close() error
|
||||
LocalAddr() net.Addr
|
||||
}
|
||||
|
|
@ -94,7 +95,7 @@ func ListenUDP(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
|
|||
// channel if configured.
|
||||
type ReadPacket struct {
|
||||
Data []byte
|
||||
Addr *net.UDPAddr
|
||||
Addr netip.AddrPort
|
||||
}
|
||||
|
||||
type randomSource interface {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package discover
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
)
|
||||
|
|
@ -59,15 +59,15 @@ func newMeteredConn(conn UDPConn) UDPConn {
|
|||
}
|
||||
|
||||
// ReadFromUDP delegates a network read to the underlying connection, bumping the udp ingress traffic meter along the way.
|
||||
func (c *meteredUdpConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) {
|
||||
n, addr, err = c.UDPConn.ReadFromUDP(b)
|
||||
func (c *meteredUdpConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
|
||||
n, addr, err = c.UDPConn.ReadFromUDPAddrPort(b)
|
||||
ingressTrafficMeter.Mark(int64(n))
|
||||
return n, addr, err
|
||||
}
|
||||
|
||||
// Write delegates a network write to the underlying connection, bumping the udp egress traffic meter along the way.
|
||||
func (c *meteredUdpConn) WriteToUDP(b []byte, addr *net.UDPAddr) (n int, err error) {
|
||||
n, err = c.UDPConn.WriteToUDP(b, addr)
|
||||
func (c *meteredUdpConn) WriteToUDP(b []byte, addr netip.AddrPort) (n int, err error) {
|
||||
n, err = c.UDPConn.WriteToUDPAddrPort(b, addr)
|
||||
egressTrafficMeter.Mark(int64(n))
|
||||
return n, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ type UDPv4 struct {
|
|||
type replyMatcher struct {
|
||||
// these fields must match in the reply.
|
||||
from enode.ID
|
||||
ip net.IP
|
||||
ip netip.Addr
|
||||
ptype byte
|
||||
|
||||
// time when the request must complete
|
||||
|
|
@ -121,7 +121,7 @@ type replyMatchFunc func(v4wire.Packet) (matched bool, requestDone bool)
|
|||
// reply is a reply packet from a certain node.
|
||||
type reply struct {
|
||||
from enode.ID
|
||||
ip net.IP
|
||||
ip netip.Addr
|
||||
data v4wire.Packet
|
||||
// loop indicates whether there was
|
||||
// a matching request by sending on this channel.
|
||||
|
|
@ -204,8 +204,8 @@ func (t *UDPv4) Resolve(n *enode.Node) *enode.Node {
|
|||
|
||||
func (t *UDPv4) ourEndpoint() v4wire.Endpoint {
|
||||
n := t.Self()
|
||||
a := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
|
||||
return v4wire.NewEndpoint(a, uint16(n.TCP()))
|
||||
addr, _ := n.UDPEndpoint()
|
||||
return v4wire.NewEndpoint(addr, uint16(n.TCP()))
|
||||
}
|
||||
|
||||
// Ping sends a ping message to the given node.
|
||||
|
|
@ -216,7 +216,11 @@ func (t *UDPv4) Ping(n *enode.Node) error {
|
|||
|
||||
// ping sends a ping message to the given node and waits for a reply.
|
||||
func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
|
||||
rm := t.sendPing(n.ID(), &net.UDPAddr{IP: n.IP(), Port: n.UDP()}, nil)
|
||||
addr, ok := n.UDPEndpoint()
|
||||
if !ok {
|
||||
return 0, errNoUDPEndpoint
|
||||
}
|
||||
rm := t.sendPing(n.ID(), addr, nil)
|
||||
if err = <-rm.errc; err == nil {
|
||||
seq = rm.reply.(*v4wire.Pong).ENRSeq
|
||||
}
|
||||
|
|
@ -225,7 +229,7 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
|
|||
|
||||
// sendPing sends a ping message to the given node and invokes the callback
|
||||
// when the reply arrives.
|
||||
func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher {
|
||||
func (t *UDPv4) sendPing(toid enode.ID, toaddr netip.AddrPort, callback func()) *replyMatcher {
|
||||
req := t.makePing(toaddr)
|
||||
packet, hash, err := v4wire.Encode(t.priv, req)
|
||||
if err != nil {
|
||||
|
|
@ -235,7 +239,7 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r
|
|||
}
|
||||
// Add a matcher for the reply to the pending reply queue. Pongs are matched if they
|
||||
// reference the ping we're about to send.
|
||||
rm := t.pending(toid, toaddr.IP, v4wire.PongPacket, func(p v4wire.Packet) (matched bool, requestDone bool) {
|
||||
rm := t.pending(toid, toaddr.Addr(), v4wire.PongPacket, func(p v4wire.Packet) (matched bool, requestDone bool) {
|
||||
matched = bytes.Equal(p.(*v4wire.Pong).ReplyTok, hash)
|
||||
if matched && callback != nil {
|
||||
callback()
|
||||
|
|
@ -243,12 +247,13 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r
|
|||
return matched, matched
|
||||
})
|
||||
// Send the packet.
|
||||
t.localNode.UDPContact(toaddr)
|
||||
udpAddr := &net.UDPAddr{IP: toaddr.Addr().AsSlice()}
|
||||
t.localNode.UDPContact(udpAddr)
|
||||
t.write(toaddr, toid, req.Name(), packet)
|
||||
return rm
|
||||
}
|
||||
|
||||
func (t *UDPv4) makePing(toaddr *net.UDPAddr) *v4wire.Ping {
|
||||
func (t *UDPv4) makePing(toaddr netip.AddrPort) *v4wire.Ping {
|
||||
return &v4wire.Ping{
|
||||
Version: 4,
|
||||
From: t.ourEndpoint(),
|
||||
|
|
@ -305,27 +310,26 @@ func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup {
|
|||
// findnode sends a findnode request to the given node and waits until
|
||||
// the node has sent up to k neighbors.
|
||||
func (t *UDPv4) findnode(toid enode.ID, toAddrPort netip.AddrPort, target v4wire.Pubkey) ([]*enode.Node, error) {
|
||||
toaddr := &net.UDPAddr{IP: toAddrPort.Addr().AsSlice(), Port: int(toAddrPort.Port())}
|
||||
t.ensureBond(toid, toaddr)
|
||||
t.ensureBond(toid, toAddrPort)
|
||||
|
||||
// Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is
|
||||
// active until enough nodes have been received.
|
||||
nodes := make([]*enode.Node, 0, bucketSize)
|
||||
nreceived := 0
|
||||
rm := t.pending(toid, toaddr.IP, v4wire.NeighborsPacket, func(r v4wire.Packet) (matched bool, requestDone bool) {
|
||||
rm := t.pending(toid, toAddrPort.Addr(), v4wire.NeighborsPacket, func(r v4wire.Packet) (matched bool, requestDone bool) {
|
||||
reply := r.(*v4wire.Neighbors)
|
||||
for _, rn := range reply.Nodes {
|
||||
nreceived++
|
||||
n, err := t.nodeFromRPC(toaddr, rn)
|
||||
n, err := t.nodeFromRPC(toAddrPort, rn)
|
||||
if err != nil {
|
||||
t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err)
|
||||
t.log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toAddrPort, "err", err)
|
||||
continue
|
||||
}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
return true, nreceived >= bucketSize
|
||||
})
|
||||
t.send(toaddr, toid, &v4wire.Findnode{
|
||||
t.send(toAddrPort, toid, &v4wire.Findnode{
|
||||
Target: target,
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
|
|
@ -343,7 +347,7 @@ func (t *UDPv4) findnode(toid enode.ID, toAddrPort netip.AddrPort, target v4wire
|
|||
|
||||
// RequestENR sends ENRRequest to the given node and waits for a response.
|
||||
func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
||||
addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
|
||||
addr, _ := n.UDPEndpoint()
|
||||
t.ensureBond(n.ID(), addr)
|
||||
|
||||
req := &v4wire.ENRRequest{
|
||||
|
|
@ -356,7 +360,7 @@ func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
|||
|
||||
// Add a matcher for the reply to the pending reply queue. Responses are matched if
|
||||
// they reference the request we're about to send.
|
||||
rm := t.pending(n.ID(), addr.IP, v4wire.ENRResponsePacket, func(r v4wire.Packet) (matched bool, requestDone bool) {
|
||||
rm := t.pending(n.ID(), addr.Addr(), v4wire.ENRResponsePacket, func(r v4wire.Packet) (matched bool, requestDone bool) {
|
||||
matched = bytes.Equal(r.(*v4wire.ENRResponse).ReplyTok, hash)
|
||||
return matched, matched
|
||||
})
|
||||
|
|
@ -376,7 +380,7 @@ func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
|||
if respN.Seq() < n.Seq() {
|
||||
return n, nil // response record is older
|
||||
}
|
||||
if err := netutil.CheckRelayIP(addr.IP, respN.IP()); err != nil {
|
||||
if err := netutil.CheckRelayIP(addr.Addr().AsSlice(), respN.IP()); err != nil {
|
||||
return nil, fmt.Errorf("invalid IP in response record: %v", err)
|
||||
}
|
||||
return respN, nil
|
||||
|
|
@ -388,7 +392,7 @@ func (t *UDPv4) TableBuckets() [][]BucketNode {
|
|||
|
||||
// pending adds a reply matcher to the pending reply queue.
|
||||
// see the documentation of type replyMatcher for a detailed explanation.
|
||||
func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchFunc) *replyMatcher {
|
||||
func (t *UDPv4) pending(id enode.ID, ip netip.Addr, ptype byte, callback replyMatchFunc) *replyMatcher {
|
||||
ch := make(chan error, 1)
|
||||
p := &replyMatcher{from: id, ip: ip, ptype: ptype, callback: callback, errc: ch}
|
||||
select {
|
||||
|
|
@ -402,7 +406,7 @@ func (t *UDPv4) pending(id enode.ID, ip net.IP, ptype byte, callback replyMatchF
|
|||
|
||||
// handleReply dispatches a reply packet, invoking reply matchers. It returns
|
||||
// whether any matcher considered the packet acceptable.
|
||||
func (t *UDPv4) handleReply(from enode.ID, fromIP net.IP, req v4wire.Packet) bool {
|
||||
func (t *UDPv4) handleReply(from enode.ID, fromIP netip.Addr, req v4wire.Packet) bool {
|
||||
matched := make(chan bool, 1)
|
||||
select {
|
||||
case t.gotreply <- reply{from, fromIP, req, matched}:
|
||||
|
|
@ -468,7 +472,7 @@ func (t *UDPv4) loop() {
|
|||
var matched bool // whether any replyMatcher considered the reply acceptable.
|
||||
for el := plist.Front(); el != nil; el = el.Next() {
|
||||
p := el.Value.(*replyMatcher)
|
||||
if p.from == r.from && p.ptype == r.data.Kind() && p.ip.Equal(r.ip) {
|
||||
if p.from == r.from && p.ptype == r.data.Kind() && p.ip == r.ip {
|
||||
ok, requestDone := p.callback(r.data)
|
||||
matched = matched || ok
|
||||
p.reply = r.data
|
||||
|
|
@ -507,7 +511,7 @@ func (t *UDPv4) loop() {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]byte, error) {
|
||||
func (t *UDPv4) send(toaddr netip.AddrPort, toid enode.ID, req v4wire.Packet) ([]byte, error) {
|
||||
packet, hash, err := v4wire.Encode(t.priv, req)
|
||||
if err != nil {
|
||||
return hash, err
|
||||
|
|
@ -515,8 +519,8 @@ func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]b
|
|||
return hash, t.write(toaddr, toid, req.Name(), packet)
|
||||
}
|
||||
|
||||
func (t *UDPv4) write(toaddr *net.UDPAddr, toid enode.ID, what string, packet []byte) error {
|
||||
_, err := t.conn.WriteToUDP(packet, toaddr)
|
||||
func (t *UDPv4) write(toaddr netip.AddrPort, toid enode.ID, what string, packet []byte) error {
|
||||
_, err := t.conn.WriteToUDPAddrPort(packet, toaddr)
|
||||
t.log.Trace(">> "+what, "id", toid, "addr", toaddr, "err", err)
|
||||
return err
|
||||
}
|
||||
|
|
@ -530,7 +534,7 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) {
|
|||
|
||||
buf := make([]byte, maxPacketSize)
|
||||
for {
|
||||
nbytes, from, err := t.conn.ReadFromUDP(buf)
|
||||
nbytes, from, err := t.conn.ReadFromUDPAddrPort(buf)
|
||||
if netutil.IsTemporaryError(err) {
|
||||
// Ignore temporary read errors.
|
||||
t.log.Debug("Temporary UDP read error", "err", err)
|
||||
|
|
@ -551,7 +555,7 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error {
|
||||
func (t *UDPv4) handlePacket(from netip.AddrPort, buf []byte) error {
|
||||
rawpacket, fromKey, hash, err := v4wire.Decode(buf)
|
||||
if err != nil {
|
||||
t.log.Debug("Bad discv4 packet", "addr", from, "err", err)
|
||||
|
|
@ -570,15 +574,16 @@ func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error {
|
|||
}
|
||||
|
||||
// checkBond checks if the given node has a recent enough endpoint proof.
|
||||
func (t *UDPv4) checkBond(id enode.ID, ip net.IP) bool {
|
||||
return time.Since(t.db.LastPongReceived(id, ip)) < bondExpiration
|
||||
func (t *UDPv4) checkBond(id enode.ID, ip netip.AddrPort) bool {
|
||||
return time.Since(t.db.LastPongReceived(id, ip.Addr().AsSlice())) < bondExpiration
|
||||
}
|
||||
|
||||
// ensureBond solicits a ping from a node if we haven't seen a ping from it for a while.
|
||||
// This ensures there is a valid endpoint proof on the remote end.
|
||||
func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) {
|
||||
tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.IP)) > bondExpiration
|
||||
if tooOld || t.db.FindFails(toid, toaddr.IP) > maxFindnodeFailures {
|
||||
func (t *UDPv4) ensureBond(toid enode.ID, toaddr netip.AddrPort) {
|
||||
ip := toaddr.Addr().AsSlice()
|
||||
tooOld := time.Since(t.db.LastPingReceived(toid, ip)) > bondExpiration
|
||||
if tooOld || t.db.FindFails(toid, ip) > maxFindnodeFailures {
|
||||
rm := t.sendPing(toid, toaddr, nil)
|
||||
<-rm.errc
|
||||
// Wait for them to ping back and process our pong.
|
||||
|
|
@ -586,11 +591,11 @@ func (t *UDPv4) ensureBond(toid enode.ID, toaddr *net.UDPAddr) {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*enode.Node, error) {
|
||||
func (t *UDPv4) nodeFromRPC(sender netip.AddrPort, rn v4wire.Node) (*enode.Node, error) {
|
||||
if rn.UDP <= 1024 {
|
||||
return nil, errLowPort
|
||||
}
|
||||
if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
|
||||
if err := netutil.CheckRelayIP(sender.Addr().AsSlice(), rn.IP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
|
||||
|
|
@ -644,14 +649,14 @@ type packetHandlerV4 struct {
|
|||
senderKey *ecdsa.PublicKey // used for ping
|
||||
|
||||
// preverify checks whether the packet is valid and should be handled at all.
|
||||
preverify func(p *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error
|
||||
preverify func(p *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error
|
||||
// handle handles the packet.
|
||||
handle func(req *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte)
|
||||
handle func(req *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte)
|
||||
}
|
||||
|
||||
// PING/v4
|
||||
|
||||
func (t *UDPv4) verifyPing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
func (t *UDPv4) verifyPing(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
req := h.Packet.(*v4wire.Ping)
|
||||
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
|
|
@ -665,7 +670,7 @@ func (t *UDPv4) verifyPing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
|
||||
func (t *UDPv4) handlePing(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) {
|
||||
req := h.Packet.(*v4wire.Ping)
|
||||
|
||||
// Reply.
|
||||
|
|
@ -677,8 +682,9 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
|||
})
|
||||
|
||||
// Ping back if our last pong on file is too far in the past.
|
||||
n := enode.NewV4(h.senderKey, from.IP, int(req.From.TCP), from.Port)
|
||||
if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration {
|
||||
ip := from.Addr().AsSlice()
|
||||
n := enode.NewV4(h.senderKey, ip, int(req.From.TCP), int(from.Port()))
|
||||
if time.Since(t.db.LastPongReceived(n.ID(), ip)) > bondExpiration {
|
||||
t.sendPing(fromID, from, func() {
|
||||
t.tab.addInboundNode(n)
|
||||
})
|
||||
|
|
@ -687,35 +693,40 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
|||
}
|
||||
|
||||
// Update node database and endpoint predictor.
|
||||
t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now())
|
||||
t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
|
||||
t.db.UpdateLastPingReceived(n.ID(), ip, time.Now())
|
||||
fromUDPAddr := &net.UDPAddr{IP: ip, Port: int(from.Port())}
|
||||
toUDPAddr := &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}
|
||||
t.localNode.UDPEndpointStatement(fromUDPAddr, toUDPAddr)
|
||||
}
|
||||
|
||||
// PONG/v4
|
||||
|
||||
func (t *UDPv4) verifyPong(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
func (t *UDPv4) verifyPong(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
req := h.Packet.(*v4wire.Pong)
|
||||
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.handleReply(fromID, from.IP, req) {
|
||||
if !t.handleReply(fromID, from.Addr(), req) {
|
||||
return errUnsolicitedReply
|
||||
}
|
||||
t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
|
||||
t.db.UpdateLastPongReceived(fromID, from.IP, time.Now())
|
||||
fromIP := from.Addr().AsSlice()
|
||||
fromUDPAddr := &net.UDPAddr{IP: fromIP, Port: int(from.Port())}
|
||||
toUDPAddr := &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)}
|
||||
t.localNode.UDPEndpointStatement(fromUDPAddr, toUDPAddr)
|
||||
t.db.UpdateLastPongReceived(fromID, fromIP, time.Now())
|
||||
return nil
|
||||
}
|
||||
|
||||
// FINDNODE/v4
|
||||
|
||||
func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
req := h.Packet.(*v4wire.Findnode)
|
||||
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.checkBond(fromID, from.IP) {
|
||||
if !t.checkBond(fromID, from) {
|
||||
// No endpoint proof pong exists, we don't process the packet. This prevents an
|
||||
// attack vector where the discovery protocol could be used to amplify traffic in a
|
||||
// DDOS attack. A malicious actor would send a findnode request with the IP address
|
||||
|
|
@ -727,7 +738,7 @@ func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
|
||||
func (t *UDPv4) handleFindnode(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) {
|
||||
req := h.Packet.(*v4wire.Findnode)
|
||||
|
||||
// Determine closest nodes.
|
||||
|
|
@ -739,7 +750,8 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
|
|||
p := v4wire.Neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}
|
||||
var sent bool
|
||||
for _, n := range closest {
|
||||
if netutil.CheckRelayIP(from.IP, n.IP()) == nil {
|
||||
fromIP := from.Addr().AsSlice()
|
||||
if netutil.CheckRelayIP(fromIP, n.IP()) == nil {
|
||||
p.Nodes = append(p.Nodes, nodeToRPC(n))
|
||||
}
|
||||
if len(p.Nodes) == v4wire.MaxNeighbors {
|
||||
|
|
@ -755,13 +767,13 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
|
|||
|
||||
// NEIGHBORS/v4
|
||||
|
||||
func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
req := h.Packet.(*v4wire.Neighbors)
|
||||
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.handleReply(fromID, from.IP, h.Packet) {
|
||||
if !t.handleReply(fromID, from.Addr(), h.Packet) {
|
||||
return errUnsolicitedReply
|
||||
}
|
||||
return nil
|
||||
|
|
@ -769,19 +781,19 @@ func (t *UDPv4) verifyNeighbors(h *packetHandlerV4, from *net.UDPAddr, fromID en
|
|||
|
||||
// ENRREQUEST/v4
|
||||
|
||||
func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
req := h.Packet.(*v4wire.ENRRequest)
|
||||
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.checkBond(fromID, from.IP) {
|
||||
if !t.checkBond(fromID, from) {
|
||||
return errUnknownNode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
|
||||
func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, mac []byte) {
|
||||
t.send(from, fromID, &v4wire.ENRResponse{
|
||||
ReplyTok: mac,
|
||||
Record: *t.localNode.Node().Record(),
|
||||
|
|
@ -790,8 +802,8 @@ func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e
|
|||
|
||||
// ENRRESPONSE/v4
|
||||
|
||||
func (t *UDPv4) verifyENRResponse(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
if !t.handleReply(fromID, from.IP, h.Packet) {
|
||||
func (t *UDPv4) verifyENRResponse(h *packetHandlerV4, from netip.AddrPort, fromID enode.ID, fromKey v4wire.Pubkey) error {
|
||||
if !t.handleReply(fromID, from.Addr(), h.Packet) {
|
||||
return errUnsolicitedReply
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func newUDPTest(t *testing.T) *udpTest {
|
|||
pipe: newpipe(),
|
||||
localkey: newkey(),
|
||||
remotekey: newkey(),
|
||||
remoteaddr: netip.AddrPortFrom(netip.MustParseAddr("10.0.1.99"), 30303),
|
||||
remoteaddr: netip.MustParseAddrPort("10.0.1.99:30303"),
|
||||
}
|
||||
|
||||
test.db, _ = enode.OpenDB("")
|
||||
|
|
@ -101,14 +101,13 @@ func (test *udpTest) packetInFrom(wantError error, key *ecdsa.PrivateKey, addr n
|
|||
test.t.Errorf("%s encode error: %v", data.Name(), err)
|
||||
}
|
||||
test.sent = append(test.sent, enc)
|
||||
udpaddr := &net.UDPAddr{IP: addr.Addr().AsSlice(), Port: int(addr.Port())}
|
||||
if err = test.udp.handlePacket(udpaddr, enc); err != wantError {
|
||||
if err = test.udp.handlePacket(addr, enc); err != wantError {
|
||||
test.t.Errorf("error mismatch: got %q, want %q", err, wantError)
|
||||
}
|
||||
}
|
||||
|
||||
// waits for a packet to be sent by the transport.
|
||||
// validate should have type func(X, *net.UDPAddr, []byte), where X is a packet type.
|
||||
// validate should have type func(X, netip.AddrPort, []byte), where X is a packet type.
|
||||
func (test *udpTest) waitPacketOut(validate interface{}) (closed bool) {
|
||||
test.t.Helper()
|
||||
|
||||
|
|
@ -130,7 +129,7 @@ func (test *udpTest) waitPacketOut(validate interface{}) (closed bool) {
|
|||
test.t.Errorf("sent packet type mismatch, got: %v, want: %v", reflect.TypeOf(p), exptype)
|
||||
return false
|
||||
}
|
||||
fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(&dgram.to), reflect.ValueOf(hash)})
|
||||
fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(dgram.to), reflect.ValueOf(hash)})
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +280,7 @@ func TestUDPv4_findnode(t *testing.T) {
|
|||
expected := test.table.findnodeByID(testTarget.ID(), bucketSize, true)
|
||||
test.packetIn(nil, &v4wire.Findnode{Target: testTarget, Expiration: futureExp})
|
||||
waitNeighbors := func(want []*enode.Node) {
|
||||
test.waitPacketOut(func(p *v4wire.Neighbors, to *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Neighbors, to netip.AddrPort, hash []byte) {
|
||||
if len(p.Nodes) != len(want) {
|
||||
t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), len(want))
|
||||
return
|
||||
|
|
@ -326,7 +325,7 @@ func TestUDPv4_findnodeMultiReply(t *testing.T) {
|
|||
|
||||
// wait for the findnode to be sent.
|
||||
// after it is sent, the transport is waiting for a reply
|
||||
test.waitPacketOut(func(p *v4wire.Findnode, to *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Findnode, to netip.AddrPort, hash []byte) {
|
||||
if p.Target != testTarget {
|
||||
t.Errorf("wrong target: got %v, want %v", p.Target, testTarget)
|
||||
}
|
||||
|
|
@ -369,8 +368,8 @@ func TestUDPv4_pingMatch(t *testing.T) {
|
|||
crand.Read(randToken)
|
||||
|
||||
test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp})
|
||||
test.waitPacketOut(func(*v4wire.Pong, *net.UDPAddr, []byte) {})
|
||||
test.waitPacketOut(func(*v4wire.Ping, *net.UDPAddr, []byte) {})
|
||||
test.waitPacketOut(func(*v4wire.Pong, netip.AddrPort, []byte) {})
|
||||
test.waitPacketOut(func(*v4wire.Ping, netip.AddrPort, []byte) {})
|
||||
test.packetIn(errUnsolicitedReply, &v4wire.Pong{ReplyTok: randToken, To: testLocalAnnounced, Expiration: futureExp})
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +379,7 @@ func TestUDPv4_pingMatchIP(t *testing.T) {
|
|||
defer test.close()
|
||||
|
||||
test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp})
|
||||
test.waitPacketOut(func(*v4wire.Pong, *net.UDPAddr, []byte) {})
|
||||
test.waitPacketOut(func(*v4wire.Pong, netip.AddrPort, []byte) {})
|
||||
|
||||
test.waitPacketOut(func(p *v4wire.Ping, to netip.AddrPort, hash []byte) {
|
||||
wrongAddr := netip.MustParseAddrPort("33.44.1.2:30000")
|
||||
|
|
@ -402,34 +401,26 @@ func TestUDPv4_successfulPing(t *testing.T) {
|
|||
go test.packetIn(nil, &v4wire.Ping{From: testRemote, To: testLocalAnnounced, Version: 4, Expiration: futureExp})
|
||||
|
||||
// The ping is replied to.
|
||||
test.waitPacketOut(func(p *v4wire.Pong, to *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Pong, to netip.AddrPort, hash []byte) {
|
||||
pinghash := test.sent[0][:32]
|
||||
if !bytes.Equal(p.ReplyTok, pinghash) {
|
||||
t.Errorf("got pong.ReplyTok %x, want %x", p.ReplyTok, pinghash)
|
||||
}
|
||||
wantTo := v4wire.Endpoint{
|
||||
// The mirrored UDP address is the UDP packet sender
|
||||
IP: test.remoteaddr.Addr().AsSlice(),
|
||||
UDP: test.remoteaddr.Port(),
|
||||
// The mirrored TCP port is the one from the ping packet
|
||||
TCP: testRemote.TCP,
|
||||
}
|
||||
// The mirrored UDP address is the UDP packet sender.
|
||||
// The mirrored TCP port is the one from the ping packet.
|
||||
wantTo := v4wire.NewEndpoint(test.remoteaddr, 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 *v4wire.Ping, to *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Ping, to netip.AddrPort, hash []byte) {
|
||||
if !reflect.DeepEqual(p.From, test.udp.ourEndpoint()) {
|
||||
t.Errorf("got ping.From %#v, want %#v", p.From, test.udp.ourEndpoint())
|
||||
}
|
||||
wantTo := v4wire.Endpoint{
|
||||
// The mirrored UDP address is the UDP packet sender.
|
||||
IP: test.remoteaddr.Addr().AsSlice(),
|
||||
UDP: test.remoteaddr.Port(),
|
||||
TCP: 0,
|
||||
}
|
||||
// The mirrored UDP address is the UDP packet sender.
|
||||
wantTo := v4wire.NewEndpoint(test.remoteaddr, 0)
|
||||
if !reflect.DeepEqual(p.To, wantTo) {
|
||||
t.Errorf("got ping.To %v, want %v", p.To, wantTo)
|
||||
}
|
||||
|
|
@ -448,7 +439,7 @@ func TestUDPv4_successfulPing(t *testing.T) {
|
|||
t.Errorf("node has wrong IP: got %v, want: %v", n.IP(), test.remoteaddr.Addr())
|
||||
}
|
||||
if n.UDP() != int(test.remoteaddr.Port()) {
|
||||
t.Errorf("node has wrong UDP port: got %v, want: %v", n.UDP(), test.remoteaddr.Port)
|
||||
t.Errorf("node has wrong UDP port: got %v, want: %v", n.UDP(), test.remoteaddr.Port())
|
||||
}
|
||||
if n.TCP() != int(testRemote.TCP) {
|
||||
t.Errorf("node has wrong TCP port: got %v, want: %v", n.TCP(), testRemote.TCP)
|
||||
|
|
@ -471,12 +462,12 @@ func TestUDPv4_EIP868(t *testing.T) {
|
|||
|
||||
// Perform endpoint proof and check for sequence number in packet tail.
|
||||
test.packetIn(nil, &v4wire.Ping{Expiration: futureExp})
|
||||
test.waitPacketOut(func(p *v4wire.Pong, addr *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Pong, addr netip.AddrPort, hash []byte) {
|
||||
if p.ENRSeq != wantNode.Seq() {
|
||||
t.Errorf("wrong sequence number in pong: %d, want %d", p.ENRSeq, wantNode.Seq())
|
||||
}
|
||||
})
|
||||
test.waitPacketOut(func(p *v4wire.Ping, addr *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.Ping, addr netip.AddrPort, hash []byte) {
|
||||
if p.ENRSeq != wantNode.Seq() {
|
||||
t.Errorf("wrong sequence number in ping: %d, want %d", p.ENRSeq, wantNode.Seq())
|
||||
}
|
||||
|
|
@ -485,7 +476,7 @@ func TestUDPv4_EIP868(t *testing.T) {
|
|||
|
||||
// Request should work now.
|
||||
test.packetIn(nil, &v4wire.ENRRequest{Expiration: futureExp})
|
||||
test.waitPacketOut(func(p *v4wire.ENRResponse, addr *net.UDPAddr, hash []byte) {
|
||||
test.waitPacketOut(func(p *v4wire.ENRResponse, addr netip.AddrPort, hash []byte) {
|
||||
n, err := enode.New(enode.ValidSchemes, &p.Record)
|
||||
if err != nil {
|
||||
t.Fatalf("invalid record: %v", err)
|
||||
|
|
@ -600,7 +591,7 @@ func newpipe() *dgramPipe {
|
|||
}
|
||||
|
||||
// WriteToUDP queues a datagram.
|
||||
func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) {
|
||||
func (c *dgramPipe) WriteToUDPAddrPort(b []byte, to netip.AddrPort) (n int, err error) {
|
||||
msg := make([]byte, len(b))
|
||||
copy(msg, b)
|
||||
c.mu.Lock()
|
||||
|
|
@ -608,20 +599,15 @@ func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) {
|
|||
if c.closed {
|
||||
return 0, errors.New("closed")
|
||||
}
|
||||
addr, ok := netip.AddrFromSlice(to.IP)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("invalid destination IP addr %v", to.IP))
|
||||
}
|
||||
addrPort := netip.AddrPortFrom(addr, uint16(to.Port))
|
||||
c.queue = append(c.queue, dgram{addrPort, b})
|
||||
c.queue = append(c.queue, dgram{to, b})
|
||||
c.cond.Signal()
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// ReadFromUDP just hangs until the pipe is closed.
|
||||
func (c *dgramPipe) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) {
|
||||
func (c *dgramPipe) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
|
||||
<-c.closing
|
||||
return 0, nil, io.EOF
|
||||
return 0, netip.AddrPort{}, io.EOF
|
||||
}
|
||||
|
||||
func (c *dgramPipe) Close() error {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
|
|
@ -150,14 +151,15 @@ type Endpoint struct {
|
|||
}
|
||||
|
||||
// NewEndpoint creates an endpoint.
|
||||
func NewEndpoint(addr *net.UDPAddr, tcpPort uint16) Endpoint {
|
||||
ip := net.IP{}
|
||||
if ip4 := addr.IP.To4(); ip4 != nil {
|
||||
ip = ip4
|
||||
} else if ip6 := addr.IP.To16(); ip6 != nil {
|
||||
ip = ip6
|
||||
func NewEndpoint(addr netip.AddrPort, tcpPort uint16) Endpoint {
|
||||
var ip net.IP
|
||||
if addr.Addr().Is4() || addr.Addr().Is4In6() {
|
||||
ip4 := addr.Addr().As4()
|
||||
ip = ip4[:]
|
||||
} else {
|
||||
ip = addr.Addr().AsSlice()
|
||||
}
|
||||
return Endpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
|
||||
return Endpoint{IP: ip, UDP: addr.Port(), TCP: tcpPort}
|
||||
}
|
||||
|
||||
type Packet interface {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package discover
|
|||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -70,7 +71,7 @@ func (t *talkSystem) register(protocol string, handler TalkRequestHandler) {
|
|||
}
|
||||
|
||||
// handleRequest handles a talk request.
|
||||
func (t *talkSystem) handleRequest(id enode.ID, addr *net.UDPAddr, req *v5wire.TalkRequest) {
|
||||
func (t *talkSystem) handleRequest(id enode.ID, addr netip.AddrPort, req *v5wire.TalkRequest) {
|
||||
t.mutex.Lock()
|
||||
handler, ok := t.handlers[req.Protocol]
|
||||
t.mutex.Unlock()
|
||||
|
|
@ -88,7 +89,8 @@ func (t *talkSystem) handleRequest(id enode.ID, addr *net.UDPAddr, req *v5wire.T
|
|||
case <-t.slots:
|
||||
go func() {
|
||||
defer func() { t.slots <- struct{}{} }()
|
||||
respMessage := handler(id, addr, req.Message)
|
||||
udpAddr := &net.UDPAddr{IP: addr.Addr().AsSlice(), Port: int(addr.Port())}
|
||||
respMessage := handler(id, udpAddr, req.Message)
|
||||
resp := &v5wire.TalkResponse{ReqID: req.ReqID, Message: respMessage}
|
||||
t.transport.sendFromAnotherThread(id, addr, resp)
|
||||
}()
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -101,14 +102,14 @@ type UDPv5 struct {
|
|||
|
||||
type sendRequest struct {
|
||||
destID enode.ID
|
||||
destAddr *net.UDPAddr
|
||||
destAddr netip.AddrPort
|
||||
msg v5wire.Packet
|
||||
}
|
||||
|
||||
// callV5 represents a remote procedure call against another node.
|
||||
type callV5 struct {
|
||||
id enode.ID
|
||||
addr *net.UDPAddr
|
||||
addr netip.AddrPort
|
||||
node *enode.Node // This is required to perform handshakes.
|
||||
|
||||
packet v5wire.Packet
|
||||
|
|
@ -266,7 +267,7 @@ func (t *UDPv5) TalkRequest(n *enode.Node, protocol string, request []byte) ([]b
|
|||
}
|
||||
|
||||
// TalkRequestToID sends a talk request to a node and waits for a response.
|
||||
func (t *UDPv5) TalkRequestToID(id enode.ID, addr *net.UDPAddr, protocol string, request []byte) ([]byte, error) {
|
||||
func (t *UDPv5) TalkRequestToID(id enode.ID, addr netip.AddrPort, protocol string, request []byte) ([]byte, error) {
|
||||
req := &v5wire.TalkRequest{Protocol: protocol, Message: request}
|
||||
resp := t.callToID(id, addr, v5wire.TalkResponseMsg, req)
|
||||
defer t.callDone(resp)
|
||||
|
|
@ -427,7 +428,7 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := netutil.CheckRelayIP(c.addr.IP, node.IP()); err != nil {
|
||||
if err := netutil.CheckRelayIP(c.addr.Addr().AsSlice(), node.IP()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t.netrestrict != nil && !t.netrestrict.Contains(node.IP()) {
|
||||
|
|
@ -452,14 +453,14 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s
|
|||
// callToNode sends the given call and sets up a handler for response packets (of message
|
||||
// type responseType). Responses are dispatched to the call's response channel.
|
||||
func (t *UDPv5) callToNode(n *enode.Node, responseType byte, req v5wire.Packet) *callV5 {
|
||||
addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
|
||||
addr, _ := n.UDPEndpoint()
|
||||
c := &callV5{id: n.ID(), addr: addr, node: n}
|
||||
t.initCall(c, responseType, req)
|
||||
return c
|
||||
}
|
||||
|
||||
// callToID is like callToNode, but for cases where the node record is not available.
|
||||
func (t *UDPv5) callToID(id enode.ID, addr *net.UDPAddr, responseType byte, req v5wire.Packet) *callV5 {
|
||||
func (t *UDPv5) callToID(id enode.ID, addr netip.AddrPort, responseType byte, req v5wire.Packet) *callV5 {
|
||||
c := &callV5{id: id, addr: addr}
|
||||
t.initCall(c, responseType, req)
|
||||
return c
|
||||
|
|
@ -619,12 +620,12 @@ func (t *UDPv5) sendCall(c *callV5) {
|
|||
|
||||
// sendResponse sends a response packet to the given node.
|
||||
// This doesn't trigger a handshake even if no keys are available.
|
||||
func (t *UDPv5) sendResponse(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet) error {
|
||||
func (t *UDPv5) sendResponse(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet) error {
|
||||
_, err := t.send(toID, toAddr, packet, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet) {
|
||||
func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet) {
|
||||
select {
|
||||
case t.sendCh <- sendRequest{toID, toAddr, packet}:
|
||||
case <-t.closeCtx.Done():
|
||||
|
|
@ -632,7 +633,7 @@ func (t *UDPv5) sendFromAnotherThread(toID enode.ID, toAddr *net.UDPAddr, packet
|
|||
}
|
||||
|
||||
// send sends a packet to the given node.
|
||||
func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet, c *v5wire.Whoareyou) (v5wire.Nonce, error) {
|
||||
func (t *UDPv5) send(toID enode.ID, toAddr netip.AddrPort, packet v5wire.Packet, c *v5wire.Whoareyou) (v5wire.Nonce, error) {
|
||||
addr := toAddr.String()
|
||||
t.logcontext = append(t.logcontext[:0], "id", toID, "addr", addr)
|
||||
t.logcontext = packet.AppendLogInfo(t.logcontext)
|
||||
|
|
@ -644,7 +645,7 @@ func (t *UDPv5) send(toID enode.ID, toAddr *net.UDPAddr, packet v5wire.Packet, c
|
|||
return nonce, err
|
||||
}
|
||||
|
||||
_, err = t.conn.WriteToUDP(enc, toAddr)
|
||||
_, err = t.conn.WriteToUDPAddrPort(enc, toAddr)
|
||||
t.log.Trace(">> "+packet.Name(), t.logcontext...)
|
||||
return nonce, err
|
||||
}
|
||||
|
|
@ -655,7 +656,7 @@ func (t *UDPv5) readLoop() {
|
|||
|
||||
buf := make([]byte, maxPacketSize)
|
||||
for range t.readNextCh {
|
||||
nbytes, from, err := t.conn.ReadFromUDP(buf)
|
||||
nbytes, from, err := t.conn.ReadFromUDPAddrPort(buf)
|
||||
if netutil.IsTemporaryError(err) {
|
||||
// Ignore temporary read errors.
|
||||
t.log.Debug("Temporary UDP read error", "err", err)
|
||||
|
|
@ -672,7 +673,7 @@ func (t *UDPv5) readLoop() {
|
|||
}
|
||||
|
||||
// dispatchReadPacket sends a packet into the dispatch loop.
|
||||
func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool {
|
||||
func (t *UDPv5) dispatchReadPacket(from netip.AddrPort, content []byte) bool {
|
||||
select {
|
||||
case t.packetInCh <- ReadPacket{content, from}:
|
||||
return true
|
||||
|
|
@ -682,7 +683,7 @@ func (t *UDPv5) dispatchReadPacket(from *net.UDPAddr, content []byte) bool {
|
|||
}
|
||||
|
||||
// handlePacket decodes and processes an incoming packet from the network.
|
||||
func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error {
|
||||
func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr netip.AddrPort) error {
|
||||
addr := fromAddr.String()
|
||||
fromID, fromNode, packet, err := t.codec.Decode(rawpacket, addr)
|
||||
if err != nil {
|
||||
|
|
@ -712,13 +713,13 @@ func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr *net.UDPAddr) error {
|
|||
}
|
||||
|
||||
// handleCallResponse dispatches a response packet to the call waiting for it.
|
||||
func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr *net.UDPAddr, p v5wire.Packet) bool {
|
||||
func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr netip.AddrPort, p v5wire.Packet) bool {
|
||||
ac := t.activeCallByNode[fromID]
|
||||
if ac == nil || !bytes.Equal(p.RequestID(), ac.reqid) {
|
||||
t.log.Debug(fmt.Sprintf("Unsolicited/late %s response", p.Name()), "id", fromID, "addr", fromAddr)
|
||||
return false
|
||||
}
|
||||
if !fromAddr.IP.Equal(ac.addr.IP) || fromAddr.Port != ac.addr.Port {
|
||||
if fromAddr != ac.addr {
|
||||
t.log.Debug(fmt.Sprintf("%s from wrong endpoint", p.Name()), "id", fromID, "addr", fromAddr)
|
||||
return false
|
||||
}
|
||||
|
|
@ -743,7 +744,7 @@ func (t *UDPv5) getNode(id enode.ID) *enode.Node {
|
|||
}
|
||||
|
||||
// handle processes incoming packets according to their message type.
|
||||
func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr) {
|
||||
func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||
switch p := p.(type) {
|
||||
case *v5wire.Unknown:
|
||||
t.handleUnknown(p, fromID, fromAddr)
|
||||
|
|
@ -753,7 +754,9 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr)
|
|||
t.handlePing(p, fromID, fromAddr)
|
||||
case *v5wire.Pong:
|
||||
if t.handleCallResponse(fromID, fromAddr, p) {
|
||||
t.localNode.UDPEndpointStatement(fromAddr, &net.UDPAddr{IP: p.ToIP, Port: int(p.ToPort)})
|
||||
fromUDPAddr := &net.UDPAddr{IP: fromAddr.Addr().AsSlice(), Port: int(fromAddr.Port())}
|
||||
toUDPAddr := &net.UDPAddr{IP: p.ToIP, Port: int(p.ToPort)}
|
||||
t.localNode.UDPEndpointStatement(fromUDPAddr, toUDPAddr)
|
||||
}
|
||||
case *v5wire.Findnode:
|
||||
t.handleFindnode(p, fromID, fromAddr)
|
||||
|
|
@ -767,7 +770,7 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr *net.UDPAddr)
|
|||
}
|
||||
|
||||
// handleUnknown initiates a handshake by responding with WHOAREYOU.
|
||||
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr *net.UDPAddr) {
|
||||
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||
challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
|
||||
crand.Read(challenge.IDNonce[:])
|
||||
if n := t.getNode(fromID); n != nil {
|
||||
|
|
@ -783,7 +786,7 @@ var (
|
|||
)
|
||||
|
||||
// handleWhoareyou resends the active call as a handshake packet.
|
||||
func (t *UDPv5) handleWhoareyou(p *v5wire.Whoareyou, fromID enode.ID, fromAddr *net.UDPAddr) {
|
||||
func (t *UDPv5) handleWhoareyou(p *v5wire.Whoareyou, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||
c, err := t.matchWithCall(fromID, p.Nonce)
|
||||
if err != nil {
|
||||
t.log.Debug("Invalid "+p.Name(), "addr", fromAddr, "err", err)
|
||||
|
|
@ -817,32 +820,35 @@ func (t *UDPv5) matchWithCall(fromID enode.ID, nonce v5wire.Nonce) (*callV5, err
|
|||
}
|
||||
|
||||
// handlePing sends a PONG response.
|
||||
func (t *UDPv5) handlePing(p *v5wire.Ping, fromID enode.ID, fromAddr *net.UDPAddr) {
|
||||
remoteIP := fromAddr.IP
|
||||
// Handle IPv4 mapped IPv6 addresses in the
|
||||
// event the local node is binded to an
|
||||
// ipv6 interface.
|
||||
if remoteIP.To4() != nil {
|
||||
remoteIP = remoteIP.To4()
|
||||
func (t *UDPv5) handlePing(p *v5wire.Ping, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||
var remoteIP net.IP
|
||||
// Handle IPv4 mapped IPv6 addresses in the event the local node is binded
|
||||
// to an ipv6 interface.
|
||||
if fromAddr.Addr().Is4() || fromAddr.Addr().Is4In6() {
|
||||
ip4 := fromAddr.Addr().As4()
|
||||
remoteIP = ip4[:]
|
||||
} else {
|
||||
remoteIP = fromAddr.Addr().AsSlice()
|
||||
}
|
||||
t.sendResponse(fromID, fromAddr, &v5wire.Pong{
|
||||
ReqID: p.ReqID,
|
||||
ToIP: remoteIP,
|
||||
ToPort: uint16(fromAddr.Port),
|
||||
ToPort: fromAddr.Port(),
|
||||
ENRSeq: t.localNode.Node().Seq(),
|
||||
})
|
||||
}
|
||||
|
||||
// handleFindnode returns nodes to the requester.
|
||||
func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr *net.UDPAddr) {
|
||||
nodes := t.collectTableNodes(fromAddr.IP, p.Distances, findnodeResultLimit)
|
||||
func (t *UDPv5) handleFindnode(p *v5wire.Findnode, fromID enode.ID, fromAddr netip.AddrPort) {
|
||||
nodes := t.collectTableNodes(fromAddr.Addr(), p.Distances, findnodeResultLimit)
|
||||
for _, resp := range packNodes(p.ReqID, nodes) {
|
||||
t.sendResponse(fromID, fromAddr, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// collectTableNodes creates a FINDNODE result set for the given distances.
|
||||
func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*enode.Node {
|
||||
func (t *UDPv5) collectTableNodes(rip netip.Addr, distances []uint, limit int) []*enode.Node {
|
||||
ripSlice := rip.AsSlice()
|
||||
var bn []*enode.Node
|
||||
var nodes []*enode.Node
|
||||
var processed = make(map[uint]struct{})
|
||||
|
|
@ -857,7 +863,7 @@ func (t *UDPv5) collectTableNodes(rip net.IP, distances []uint, limit int) []*en
|
|||
for _, n := range t.tab.appendLiveNodes(dist, bn[:0]) {
|
||||
// Apply some pre-checks to avoid sending invalid nodes.
|
||||
// Note liveness is checked by appendLiveNodes.
|
||||
if netutil.CheckRelayIP(rip, n.IP()) != nil {
|
||||
if netutil.CheckRelayIP(ripSlice, n.IP()) != nil {
|
||||
continue
|
||||
}
|
||||
nodes = append(nodes, n)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ func TestUDPv5_pingHandling(t *testing.T) {
|
|||
defer test.close()
|
||||
|
||||
test.packetIn(&v5wire.Ping{ReqID: []byte("foo")})
|
||||
test.waitPacketOut(func(p *v5wire.Pong, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Pong, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if !bytes.Equal(p.ReqID, []byte("foo")) {
|
||||
t.Error("wrong request ID in response:", p.ReqID)
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ func TestUDPv5_unknownPacket(t *testing.T) {
|
|||
|
||||
// Unknown packet from unknown node.
|
||||
test.packetIn(&v5wire.Unknown{Nonce: nonce})
|
||||
test.waitPacketOut(func(p *v5wire.Whoareyou, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
check(p, 0)
|
||||
})
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ func TestUDPv5_unknownPacket(t *testing.T) {
|
|||
test.table.addFoundNode(n, false)
|
||||
|
||||
test.packetIn(&v5wire.Unknown{Nonce: nonce})
|
||||
test.waitPacketOut(func(p *v5wire.Whoareyou, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Whoareyou, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
check(p, n.Seq())
|
||||
})
|
||||
}
|
||||
|
|
@ -200,7 +200,7 @@ func (test *udpV5Test) expectNodes(wantReqID []byte, wantTotal uint8, wantNodes
|
|||
}
|
||||
|
||||
for {
|
||||
test.waitPacketOut(func(p *v5wire.Nodes, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Nodes, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if !bytes.Equal(p.ReqID, wantReqID) {
|
||||
test.t.Fatalf("wrong request ID %v in response, want %v", p.ReqID, wantReqID)
|
||||
}
|
||||
|
|
@ -239,7 +239,7 @@ func TestUDPv5_pingCall(t *testing.T) {
|
|||
_, err := test.udp.ping(remote)
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {})
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {})
|
||||
if err := <-done; err != errTimeout {
|
||||
t.Fatalf("want errTimeout, got %q", err)
|
||||
}
|
||||
|
|
@ -249,7 +249,7 @@ func TestUDPv5_pingCall(t *testing.T) {
|
|||
_, err := test.udp.ping(remote)
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
test.packetInFrom(test.remotekey, test.remoteaddr, &v5wire.Pong{ReqID: p.ReqID})
|
||||
})
|
||||
if err := <-done; err != nil {
|
||||
|
|
@ -261,8 +261,8 @@ func TestUDPv5_pingCall(t *testing.T) {
|
|||
_, err := test.udp.ping(remote)
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
wrongAddr := &net.UDPAddr{IP: net.IP{33, 44, 55, 22}, Port: 10101}
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
wrongAddr := netip.MustParseAddrPort("33.44.55.22:10101")
|
||||
test.packetInFrom(test.remotekey, wrongAddr, &v5wire.Pong{ReqID: p.ReqID})
|
||||
})
|
||||
if err := <-done; err != errTimeout {
|
||||
|
|
@ -292,7 +292,7 @@ func TestUDPv5_findnodeCall(t *testing.T) {
|
|||
}()
|
||||
|
||||
// Serve the responses:
|
||||
test.waitPacketOut(func(p *v5wire.Findnode, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Findnode, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if !reflect.DeepEqual(p.Distances, distances) {
|
||||
t.Fatalf("wrong distances in request: %v", p.Distances)
|
||||
}
|
||||
|
|
@ -338,15 +338,15 @@ func TestUDPv5_callResend(t *testing.T) {
|
|||
}()
|
||||
|
||||
// Ping answered by WHOAREYOU.
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) {
|
||||
test.packetIn(&v5wire.Whoareyou{Nonce: nonce})
|
||||
})
|
||||
// Ping should be re-sent.
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
test.packetIn(&v5wire.Pong{ReqID: p.ReqID})
|
||||
})
|
||||
// Answer the other ping.
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
test.packetIn(&v5wire.Pong{ReqID: p.ReqID})
|
||||
})
|
||||
if err := <-done; err != nil {
|
||||
|
|
@ -371,11 +371,11 @@ func TestUDPv5_multipleHandshakeRounds(t *testing.T) {
|
|||
}()
|
||||
|
||||
// Ping answered by WHOAREYOU.
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) {
|
||||
test.packetIn(&v5wire.Whoareyou{Nonce: nonce})
|
||||
})
|
||||
// Ping answered by WHOAREYOU again.
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr *net.UDPAddr, nonce v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Ping, addr netip.AddrPort, nonce v5wire.Nonce) {
|
||||
test.packetIn(&v5wire.Whoareyou{Nonce: nonce})
|
||||
})
|
||||
if err := <-done; err != errTimeout {
|
||||
|
|
@ -402,7 +402,7 @@ func TestUDPv5_callTimeoutReset(t *testing.T) {
|
|||
}()
|
||||
|
||||
// Serve two responses, slowly.
|
||||
test.waitPacketOut(func(p *v5wire.Findnode, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Findnode, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
time.Sleep(respTimeout - 50*time.Millisecond)
|
||||
test.packetIn(&v5wire.Nodes{
|
||||
ReqID: p.ReqID,
|
||||
|
|
@ -440,7 +440,7 @@ func TestUDPv5_talkHandling(t *testing.T) {
|
|||
Protocol: "test",
|
||||
Message: []byte("test request"),
|
||||
})
|
||||
test.waitPacketOut(func(p *v5wire.TalkResponse, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.TalkResponse, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if !bytes.Equal(p.ReqID, []byte("foo")) {
|
||||
t.Error("wrong request ID in response:", p.ReqID)
|
||||
}
|
||||
|
|
@ -459,7 +459,7 @@ func TestUDPv5_talkHandling(t *testing.T) {
|
|||
Protocol: "wrong",
|
||||
Message: []byte("test request"),
|
||||
})
|
||||
test.waitPacketOut(func(p *v5wire.TalkResponse, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.TalkResponse, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if !bytes.Equal(p.ReqID, []byte("2")) {
|
||||
t.Error("wrong request ID in response:", p.ReqID)
|
||||
}
|
||||
|
|
@ -486,7 +486,7 @@ func TestUDPv5_talkRequest(t *testing.T) {
|
|||
_, err := test.udp.TalkRequest(remote, "test", []byte("test request"))
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) {})
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) {})
|
||||
if err := <-done; err != errTimeout {
|
||||
t.Fatalf("want errTimeout, got %q", err)
|
||||
}
|
||||
|
|
@ -496,7 +496,7 @@ func TestUDPv5_talkRequest(t *testing.T) {
|
|||
_, err := test.udp.TalkRequest(remote, "test", []byte("test request"))
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if p.Protocol != "test" {
|
||||
t.Errorf("wrong protocol ID in talk request: %q", p.Protocol)
|
||||
}
|
||||
|
|
@ -517,7 +517,7 @@ func TestUDPv5_talkRequest(t *testing.T) {
|
|||
_, err := test.udp.TalkRequestToID(remote.ID(), test.remoteaddr, "test", []byte("test request 2"))
|
||||
done <- err
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.TalkRequest, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if p.Protocol != "test" {
|
||||
t.Errorf("wrong protocol ID in talk request: %q", p.Protocol)
|
||||
}
|
||||
|
|
@ -584,7 +584,8 @@ func TestUDPv5_lookup(t *testing.T) {
|
|||
for d, nn := range lookupTestnet.dists {
|
||||
for i, key := range nn {
|
||||
n := lookupTestnet.node(d, i)
|
||||
test.getNode(key, &net.UDPAddr{IP: n.IP(), Port: n.UDP()})
|
||||
addr, _ := n.UDPEndpoint()
|
||||
test.getNode(key, addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -653,11 +654,8 @@ func TestUDPv5_PingWithIPV4MappedAddress(t *testing.T) {
|
|||
test := newUDPV5Test(t)
|
||||
defer test.close()
|
||||
|
||||
rawIP := net.IPv4(0xFF, 0x12, 0x33, 0xE5)
|
||||
test.remoteaddr = &net.UDPAddr{
|
||||
IP: rawIP.To16(),
|
||||
Port: 0,
|
||||
}
|
||||
rawIP := netip.AddrFrom4([4]byte{0xFF, 0x12, 0x33, 0xE5})
|
||||
test.remoteaddr = netip.AddrPortFrom(netip.AddrFrom16(rawIP.As16()), 0)
|
||||
remote := test.getNode(test.remotekey, test.remoteaddr).Node()
|
||||
done := make(chan struct{}, 1)
|
||||
|
||||
|
|
@ -666,14 +664,14 @@ func TestUDPv5_PingWithIPV4MappedAddress(t *testing.T) {
|
|||
test.udp.handlePing(&v5wire.Ping{ENRSeq: 1}, remote.ID(), test.remoteaddr)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
test.waitPacketOut(func(p *v5wire.Pong, addr *net.UDPAddr, _ v5wire.Nonce) {
|
||||
test.waitPacketOut(func(p *v5wire.Pong, addr netip.AddrPort, _ v5wire.Nonce) {
|
||||
if len(p.ToIP) == net.IPv6len {
|
||||
t.Error("Received untruncated ip address")
|
||||
}
|
||||
if len(p.ToIP) != net.IPv4len {
|
||||
t.Errorf("Received ip address with incorrect length: %d", len(p.ToIP))
|
||||
}
|
||||
if !p.ToIP.Equal(rawIP) {
|
||||
if !p.ToIP.Equal(rawIP.AsSlice()) {
|
||||
t.Errorf("Received incorrect ip address: wanted %s but received %s", rawIP.String(), p.ToIP.String())
|
||||
}
|
||||
})
|
||||
|
|
@ -751,9 +749,9 @@ func newUDPV5Test(t *testing.T) *udpV5Test {
|
|||
pipe: newpipe(),
|
||||
localkey: newkey(),
|
||||
remotekey: newkey(),
|
||||
remoteaddr: &net.UDPAddr{IP: net.IP{10, 0, 1, 99}, Port: 30303},
|
||||
remoteaddr: netip.MustParseAddrPort("10.0.1.99:30303"),
|
||||
nodesByID: make(map[enode.ID]*enode.LocalNode),
|
||||
nodesByIP: make(map[string]*enode.LocalNode),
|
||||
nodesByIP: make(map[netip.Addr]*enode.LocalNode),
|
||||
}
|
||||
test.db, _ = enode.OpenDB("")
|
||||
ln := enode.NewLocalNode(test.db, test.localkey)
|
||||
|
|
@ -804,12 +802,12 @@ func (test *udpV5Test) getNode(key *ecdsa.PrivateKey, addr netip.AddrPort) *enod
|
|||
ln.Set(enr.UDP(addr.Port()))
|
||||
test.nodesByID[id] = ln
|
||||
}
|
||||
test.nodesByIP[string(addr.Addr().String())] = ln
|
||||
test.nodesByIP[addr.Addr()] = ln
|
||||
return ln
|
||||
}
|
||||
|
||||
// waitPacketOut waits for the next output packet and handles it using the given 'validate'
|
||||
// function. The function must be of type func (X, *net.UDPAddr, v5wire.Nonce) where X is
|
||||
// function. The function must be of type func (X, netip.AddrPort, v5wire.Nonce) where X is
|
||||
// assignable to packetV5.
|
||||
func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) {
|
||||
test.t.Helper()
|
||||
|
|
@ -825,7 +823,7 @@ func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) {
|
|||
test.t.Fatalf("timed out waiting for %v", exptype)
|
||||
return false
|
||||
}
|
||||
ln := test.nodesByIP[string(dgram.to.IP)]
|
||||
ln := test.nodesByIP[dgram.to.Addr()]
|
||||
if ln == nil {
|
||||
test.t.Fatalf("attempt to send to non-existing node %v", &dgram.to)
|
||||
return false
|
||||
|
|
@ -840,7 +838,7 @@ func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) {
|
|||
test.t.Errorf("sent packet type mismatch, got: %v, want: %v", reflect.TypeOf(p), exptype)
|
||||
return false
|
||||
}
|
||||
fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(&dgram.to), reflect.ValueOf(frame.AuthTag)})
|
||||
fn.Call([]reflect.Value{reflect.ValueOf(p), reflect.ValueOf(dgram.to), reflect.ValueOf(frame.AuthTag)})
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue