Skip to content

Commit

Permalink
p2p: add 0 port check in dialer (#21008)
Browse files Browse the repository at this point in the history
* p2p: add low port check in dialer

We already have a check like this for UDP ports, add a similar one in
the dialer. This prevents dials to port zero and it's also an extra
layer of protection against spamming HTTP servers.

* p2p/discover: use errLowPort in v4 code

* p2p: change port check

* p2p: add comment

* p2p/simulations/adapters: ensure assigned port is in all node records
  • Loading branch information
fjl committed May 11, 2020
1 parent 069a7e1 commit 6f54ae2
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
19 changes: 14 additions & 5 deletions p2p/dial.go
Expand Up @@ -78,6 +78,7 @@ var (
errAlreadyConnected = errors.New("already connected")
errRecentlyDialed = errors.New("recently dialed")
errNotWhitelisted = errors.New("not contained in netrestrict whitelist")
errNoPort = errors.New("node does not provide TCP port")
)

// dialer creates outbound connections and submits them into Server.
Expand Down Expand Up @@ -388,6 +389,12 @@ func (d *dialScheduler) checkDial(n *enode.Node) error {
if n.ID() == d.self {
return errSelf
}
if n.IP() != nil && n.TCP() == 0 {
// This check can trigger if a non-TCP node is found
// by discovery. If there is no IP, the node is a static
// node and the actual endpoint will be resolved later in dialTask.
return errNoPort
}
if _, ok := d.dialing[n.ID()]; ok {
return errAlreadyDialing
}
Expand Down Expand Up @@ -474,15 +481,13 @@ type dialError struct {
}

func (t *dialTask) run(d *dialScheduler) {
if t.dest.Incomplete() {
if !t.resolve(d) {
return
}
if t.needResolve() && !t.resolve(d) {
return
}

err := t.dial(d, t.dest)
if err != nil {
// Try resolving the ID of static nodes if dialing failed.
// For static nodes, resolve one more time if dialing fails.
if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 {
if t.resolve(d) {
t.dial(d, t.dest)
Expand All @@ -491,6 +496,10 @@ func (t *dialTask) run(d *dialScheduler) {
}
}

func (t *dialTask) needResolve() bool {
return t.flags&staticDialedConn != 0 && t.dest.IP() == nil
}

// resolve attempts to find the current endpoint for the destination
// using discovery.
//
Expand Down
2 changes: 1 addition & 1 deletion p2p/discover/v4_udp.go
Expand Up @@ -169,7 +169,7 @@ func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {

func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) {
if rn.UDP <= 1024 {
return nil, errors.New("low port")
return nil, errLowPort
}
if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion p2p/simulations/adapters/types.go
Expand Up @@ -300,5 +300,5 @@ func (n *NodeConfig) initEnode(ip net.IP, tcpport int, udpport int) error {
}

func (n *NodeConfig) initDummyEnode() error {
return n.initEnode(net.IPv4(127, 0, 0, 1), 0, 0)
return n.initEnode(net.IPv4(127, 0, 0, 1), int(n.Port), 0)
}

0 comments on commit 6f54ae2

Please sign in to comment.