From f5a0c9d834da818d1cb070b2e35dedd4f87df30d Mon Sep 17 00:00:00 2001 From: battlmonstr Date: Thu, 24 Feb 2022 16:09:56 +0100 Subject: [PATCH] p2p: Disable port mapping task with --nat extip (#3612) If --nat extip:1.2.3.4 option is specified, the port mapping logic (AddMapping/DeleteMapping) does nothing. This optimization avoids running a goroutine for doing nothing. --- cmd/bootnode/main.go | 2 +- p2p/nat/nat.go | 10 ++++++++++ p2p/nat/natpmp.go | 4 ++++ p2p/nat/natupnp.go | 4 ++++ p2p/server.go | 4 ++-- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index c94a511bc..d889f925a 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -111,7 +111,7 @@ func main() { realaddr := conn.LocalAddr().(*net.UDPAddr) if natm != nil { - if !realaddr.IP.IsLoopback() { + if !realaddr.IP.IsLoopback() && natm.SupportsMapping() { go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") } if ext, err := natm.ExternalIP(); err == nil { diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index d1a6392d4..0b24a8700 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -41,6 +41,7 @@ type Interface interface { // the gateway when its lifetime ends. AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error DeleteMapping(protocol string, extport, intport int) error + SupportsMapping() bool // This method should return the external (Internet-facing) // address of the gateway device. @@ -98,6 +99,10 @@ const ( // Map adds a port mapping on m and keeps it alive until c is closed. // This function is typically invoked in its own goroutine. func Map(m Interface, c <-chan struct{}, protocol string, extport, intport int, name string) { + if !m.SupportsMapping() { + panic("Port mapping is not supported") + } + logger := log.New("proto", protocol, "extport", extport, "intport", intport, "interface", m) refresh := time.NewTimer(mapTimeout) defer func() { @@ -138,6 +143,7 @@ func (n ExtIP) String() string { return fmt.Sprintf("ExtIP(%v)", ne func (ExtIP) AddMapping(string, int, int, string, time.Duration) error { return nil } func (ExtIP) DeleteMapping(string, int, int) error { return nil } +func (ExtIP) SupportsMapping() bool { return false } // Any returns a port mapper that tries to discover any supported // mechanism on the local network. @@ -208,6 +214,10 @@ func (n *autodisc) DeleteMapping(protocol string, extport, intport int) error { return n.found.DeleteMapping(protocol, extport, intport) } +func (n *autodisc) SupportsMapping() bool { + return true +} + func (n *autodisc) ExternalIP() (net.IP, error) { if err := n.wait(); err != nil { return nil, err diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index 8bafdac9f..278e07cc5 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -63,6 +63,10 @@ func (n *pmp) DeleteMapping(protocol string, extport, intport int) (err error) { return err } +func (n *pmp) SupportsMapping() bool { + return true +} + func discoverPMP() Interface { // run external address lookups on all potential gateways gws := potentialGateways() diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index 837c83c8c..083ab90f6 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -123,6 +123,10 @@ func (n *upnp) DeleteMapping(protocol string, extport, intport int) error { }) } +func (n *upnp) SupportsMapping() bool { + return true +} + func (n *upnp) String() string { return "UPNP " + n.service } diff --git a/p2p/server.go b/p2p/server.go index a576e9244..7f93f2f83 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -581,7 +581,7 @@ func (srv *Server) setupDiscovery(ctx context.Context) error { realaddr := conn.LocalAddr().(*net.UDPAddr) srv.log.Trace("UDP listener up", "addr", realaddr) if srv.NAT != nil { - if !realaddr.IP.IsLoopback() { + if !realaddr.IP.IsLoopback() && srv.NAT.SupportsMapping() { srv.loopWG.Add(1) go func() { defer debug.LogPanic() @@ -693,7 +693,7 @@ func (srv *Server) setupListening() error { // Update the local node record and map the TCP listening port if NAT is configured. if tcp, ok := listener.Addr().(*net.TCPAddr); ok { srv.localnode.Set(enr.TCP(tcp.Port)) - if !tcp.IP.IsLoopback() && srv.NAT != nil { + if !tcp.IP.IsLoopback() && (srv.NAT != nil) && srv.NAT.SupportsMapping() { srv.loopWG.Add(1) go func() { defer debug.LogPanic()