mirror of
https://github.com/logos-messaging/go-discover.git
synced 2026-01-02 13:03:12 +00:00
fix: IP, Addr, AddrPort changes
This commit is contained in:
parent
68b48e88df
commit
7daed85191
@ -140,7 +140,7 @@ func (it *lookup) slowdown() {
|
||||
}
|
||||
|
||||
func (it *lookup) query(n *node, reply chan<- []*node) {
|
||||
fails := it.tab.db.FindFails(n.ID(), n.IP())
|
||||
fails := it.tab.db.FindFails(n.ID(), n.IPAddr())
|
||||
r, err := it.queryfunc(n)
|
||||
if errors.Is(err, errClosed) {
|
||||
// Avoid recording failures on shutdown.
|
||||
@ -148,7 +148,7 @@ func (it *lookup) query(n *node, reply chan<- []*node) {
|
||||
return
|
||||
} else if len(r) == 0 {
|
||||
fails++
|
||||
it.tab.db.UpdateFindFails(n.ID(), n.IP(), fails)
|
||||
it.tab.db.UpdateFindFails(n.ID(), n.IPAddr(), fails)
|
||||
// Remove the node from the local table if it fails to return anything useful too
|
||||
// many times, but only if there are enough other nodes in the bucket.
|
||||
if fails >= maxFindnodeFailures && it.tab.bucketLen(n.ID()) >= bucketSize/2 {
|
||||
@ -156,7 +156,7 @@ func (it *lookup) query(n *node, reply chan<- []*node) {
|
||||
}
|
||||
} else if fails > 0 {
|
||||
// Reset failure counter because it counts _consecutive_ failures.
|
||||
it.tab.db.UpdateFindFails(n.ID(), n.IP(), 0)
|
||||
it.tab.db.UpdateFindFails(n.ID(), n.IPAddr(), 0)
|
||||
}
|
||||
|
||||
// Grab as many nodes as possible. Some of them might not be alive anymore, but we'll
|
||||
|
||||
@ -44,7 +44,7 @@ type meteredUdpConn struct {
|
||||
|
||||
func newMeteredConn(conn UDPConn) UDPConn {
|
||||
// Short circuit if metrics are disabled
|
||||
if !metrics.Enabled {
|
||||
if !metrics.Enabled() {
|
||||
return conn
|
||||
}
|
||||
return &meteredUdpConn{UDPConn: conn}
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -34,6 +35,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||
|
||||
"github.com/waku-org/go-discover/discover/v4wire"
|
||||
)
|
||||
|
||||
@ -242,7 +244,7 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r
|
||||
return matched, matched
|
||||
})
|
||||
// Send the packet.
|
||||
t.localNode.UDPContact(toaddr)
|
||||
t.localNode.UDPContact(toaddr.AddrPort())
|
||||
t.write(toaddr, toid, req.Name(), packet)
|
||||
return rm
|
||||
}
|
||||
@ -560,15 +562,15 @@ 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, addr netip.Addr) bool {
|
||||
return time.Since(t.db.LastPongReceived(id, addr)) < 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 {
|
||||
tooOld := time.Since(t.db.LastPingReceived(toid, toaddr.AddrPort().Addr())) > bondExpiration
|
||||
if tooOld || t.db.FindFails(toid, toaddr.AddrPort().Addr()) > maxFindnodeFailures {
|
||||
rm := t.sendPing(toid, toaddr, nil)
|
||||
<-rm.errc
|
||||
// Wait for them to ping back and process our pong.
|
||||
@ -668,7 +670,7 @@ 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 := wrapNode(enode.NewV4(h.senderKey, from.IP, int(req.From.TCP), from.Port))
|
||||
if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration {
|
||||
if time.Since(t.db.LastPongReceived(n.ID(), from.AddrPort().Addr())) > bondExpiration {
|
||||
t.sendPing(fromID, from, func() {
|
||||
t.tab.addVerifiedNode(n)
|
||||
})
|
||||
@ -677,8 +679,8 @@ 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(), from.AddrPort().Addr(), time.Now())
|
||||
t.localNode.UDPEndpointStatement(from.AddrPort(), req.To.UDPAddrPort())
|
||||
}
|
||||
|
||||
// PONG/v4
|
||||
@ -692,8 +694,8 @@ func (t *UDPv4) verifyPong(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
||||
if !t.handleReply(fromID, from.IP, 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())
|
||||
t.localNode.UDPEndpointStatement(from.AddrPort(), req.To.UDPAddrPort())
|
||||
t.db.UpdateLastPongReceived(fromID, from.AddrPort().Addr(), time.Now())
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -705,7 +707,7 @@ func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.checkBond(fromID, from.IP) {
|
||||
if !t.checkBond(fromID, from.AddrPort().Addr()) {
|
||||
// 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
|
||||
@ -765,7 +767,7 @@ func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e
|
||||
if v4wire.Expired(req.Expiration) {
|
||||
return errExpired
|
||||
}
|
||||
if !t.checkBond(fromID, from.IP) {
|
||||
if !t.checkBond(fromID, from.AddrPort().Addr()) {
|
||||
return errUnknownNode
|
||||
}
|
||||
return nil
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
@ -151,13 +152,16 @@ 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
|
||||
return Endpoint{
|
||||
IP: addr.IP,
|
||||
UDP: uint16(addr.Port),
|
||||
TCP: tcpPort,
|
||||
}
|
||||
return Endpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
|
||||
}
|
||||
|
||||
func (ep *Endpoint) UDPAddrPort() netip.AddrPort {
|
||||
addr, _ := netip.AddrFromSlice(ep.IP)
|
||||
return netip.AddrPortFrom(addr, ep.UDP)
|
||||
}
|
||||
|
||||
type Packet interface {
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -761,7 +762,8 @@ 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)})
|
||||
toAddr, _ := netip.AddrFromSlice(p.ToIP)
|
||||
t.localNode.UDPEndpointStatement(fromAddr.AddrPort(), netip.AddrPortFrom(toAddr, p.ToPort))
|
||||
}
|
||||
case *v5wire.Findnode:
|
||||
t.handleFindnode(p, fromID, fromAddr)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user