|
@@ -72,10 +72,10 @@ type UDPv4 struct {
|
|
|
netrestrict *netutil.Netlist
|
|
netrestrict *netutil.Netlist
|
|
|
priv *ecdsa.PrivateKey
|
|
priv *ecdsa.PrivateKey
|
|
|
localNode *enode.LocalNode
|
|
localNode *enode.LocalNode
|
|
|
- db *enode.DB
|
|
|
|
|
- tab *Table
|
|
|
|
|
- closeOnce sync.Once
|
|
|
|
|
- wg sync.WaitGroup
|
|
|
|
|
|
|
+ //db *enode.DB
|
|
|
|
|
+ tab *Table
|
|
|
|
|
+ closeOnce sync.Once
|
|
|
|
|
+ wg sync.WaitGroup
|
|
|
|
|
|
|
|
addReplyMatcher chan *replyMatcher
|
|
addReplyMatcher chan *replyMatcher
|
|
|
gotreply chan reply
|
|
gotreply chan reply
|
|
@@ -132,11 +132,11 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
|
|
|
cfg = cfg.withDefaults()
|
|
cfg = cfg.withDefaults()
|
|
|
closeCtx, cancel := context.WithCancel(context.Background())
|
|
closeCtx, cancel := context.WithCancel(context.Background())
|
|
|
t := &UDPv4{
|
|
t := &UDPv4{
|
|
|
- conn: c,
|
|
|
|
|
- priv: cfg.PrivateKey,
|
|
|
|
|
- netrestrict: cfg.NetRestrict,
|
|
|
|
|
- localNode: ln,
|
|
|
|
|
- db: ln.Database(),
|
|
|
|
|
|
|
+ conn: c,
|
|
|
|
|
+ priv: cfg.PrivateKey,
|
|
|
|
|
+ netrestrict: cfg.NetRestrict,
|
|
|
|
|
+ localNode: ln,
|
|
|
|
|
+ //db: ln.Database(),
|
|
|
gotreply: make(chan reply),
|
|
gotreply: make(chan reply),
|
|
|
addReplyMatcher: make(chan *replyMatcher),
|
|
addReplyMatcher: make(chan *replyMatcher),
|
|
|
closeCtx: closeCtx,
|
|
closeCtx: closeCtx,
|
|
@@ -144,7 +144,7 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
|
|
|
log: cfg.Log,
|
|
log: cfg.Log,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- tab, err := newTable(t, ln.Database(), cfg.Bootnodes, t.log)
|
|
|
|
|
|
|
+ tab, err := newTable(t, cfg.Bootnodes, t.log)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -302,7 +302,7 @@ func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup {
|
|
|
// findnode sends a findnode request to the given node and waits until
|
|
// findnode sends a findnode request to the given node and waits until
|
|
|
// the node has sent up to k neighbors.
|
|
// the node has sent up to k neighbors.
|
|
|
func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubkey) ([]*node, error) {
|
|
func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubkey) ([]*node, error) {
|
|
|
- t.ensureBond(toid, toaddr)
|
|
|
|
|
|
|
+ //t.ensureBond(toid, toaddr)
|
|
|
|
|
|
|
|
// Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is
|
|
// Add a matcher for 'neighbours' replies to the pending reply queue. The matcher is
|
|
|
// active until enough nodes have been received.
|
|
// active until enough nodes have been received.
|
|
@@ -340,7 +340,7 @@ func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubke
|
|
|
// RequestENR sends enrRequest to the given node and waits for a response.
|
|
// RequestENR sends enrRequest to the given node and waits for a response.
|
|
|
func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
|
func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
|
|
addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
|
|
addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()}
|
|
|
- t.ensureBond(n.ID(), addr)
|
|
|
|
|
|
|
+ //t.ensureBond(n.ID(), addr)
|
|
|
|
|
|
|
|
req := &v4wire.ENRRequest{
|
|
req := &v4wire.ENRRequest{
|
|
|
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
|
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
|
@@ -563,22 +563,22 @@ func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 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
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 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 {
|
|
|
|
|
- rm := t.sendPing(toid, toaddr, nil)
|
|
|
|
|
- <-rm.errc
|
|
|
|
|
- // Wait for them to ping back and process our pong.
|
|
|
|
|
- time.Sleep(respTimeout)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+//// 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
|
|
|
|
|
+//}
|
|
|
|
|
+//
|
|
|
|
|
+//// 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 {
|
|
|
|
|
+// rm := t.sendPing(toid, toaddr, nil)
|
|
|
|
|
+// <-rm.errc
|
|
|
|
|
+// // Wait for them to ping back and process our pong.
|
|
|
|
|
+// time.Sleep(respTimeout)
|
|
|
|
|
+// }
|
|
|
|
|
+//}
|
|
|
|
|
|
|
|
func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*node, error) {
|
|
func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn v4wire.Node) (*node, error) {
|
|
|
if rn.UDP <= 1024 {
|
|
if rn.UDP <= 1024 {
|
|
@@ -673,16 +673,16 @@ 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.
|
|
// 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))
|
|
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 {
|
|
|
|
|
- t.sendPing(fromID, from, func() {
|
|
|
|
|
- t.tab.addVerifiedNode(n)
|
|
|
|
|
- })
|
|
|
|
|
- } else {
|
|
|
|
|
- t.tab.addVerifiedNode(n)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //if time.Since(t.db.LastPongReceived(n.ID(), from.IP)) > bondExpiration {
|
|
|
|
|
+ // t.sendPing(fromID, from, func() {
|
|
|
|
|
+ // t.tab.addVerifiedNode(n)
|
|
|
|
|
+ // })
|
|
|
|
|
+ //} else {
|
|
|
|
|
+ t.tab.addVerifiedNode(n)
|
|
|
|
|
+ //}
|
|
|
|
|
|
|
|
// Update node database and endpoint predictor.
|
|
// Update node database and endpoint predictor.
|
|
|
- t.db.UpdateLastPingReceived(n.ID(), from.IP, time.Now())
|
|
|
|
|
|
|
+ //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.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -698,7 +698,7 @@ func (t *UDPv4) verifyPong(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
|
|
return errUnsolicitedReply
|
|
return errUnsolicitedReply
|
|
|
}
|
|
}
|
|
|
t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
|
|
t.localNode.UDPEndpointStatement(from, &net.UDPAddr{IP: req.To.IP, Port: int(req.To.UDP)})
|
|
|
- t.db.UpdateLastPongReceived(fromID, from.IP, time.Now())
|
|
|
|
|
|
|
+ //t.db.UpdateLastPongReceived(fromID, from.IP, time.Now())
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -710,15 +710,15 @@ func (t *UDPv4) verifyFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno
|
|
|
if v4wire.Expired(req.Expiration) {
|
|
if v4wire.Expired(req.Expiration) {
|
|
|
return errExpired
|
|
return errExpired
|
|
|
}
|
|
}
|
|
|
- if !t.checkBond(fromID, from.IP) {
|
|
|
|
|
- // 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
|
|
|
|
|
- // and UDP port of the target as the source address. The recipient of the findnode
|
|
|
|
|
- // packet would then send a neighbors packet (which is a much bigger packet than
|
|
|
|
|
- // findnode) to the victim.
|
|
|
|
|
- return errUnknownNode
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //if !t.checkBond(fromID, from.IP) {
|
|
|
|
|
+ // // 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
|
|
|
|
|
+ // // and UDP port of the target as the source address. The recipient of the findnode
|
|
|
|
|
+ // // packet would then send a neighbors packet (which is a much bigger packet than
|
|
|
|
|
+ // // findnode) to the victim.
|
|
|
|
|
+ // return errUnknownNode
|
|
|
|
|
+ //}
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -770,9 +770,9 @@ func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e
|
|
|
if v4wire.Expired(req.Expiration) {
|
|
if v4wire.Expired(req.Expiration) {
|
|
|
return errExpired
|
|
return errExpired
|
|
|
}
|
|
}
|
|
|
- if !t.checkBond(fromID, from.IP) {
|
|
|
|
|
- return errUnknownNode
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //if !t.checkBond(fromID, from.IP) {
|
|
|
|
|
+ // return errUnknownNode
|
|
|
|
|
+ //}
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|