nettest: fix tests on dragonfly and js/wasm

CL 458096 changes probeStack to use a better approach for checking
network stack capability, by checking for routable ipv4/ipv6. However,
the NewLocalListener needs check for listenable instead.

This CL adds to probestack the listenable on loopback and use that
condition instead.

Fixes golang/go#57623

Change-Id: I8b5b7798ccf3826881e5ef9f7d2d998d8e52eba5
Reviewed-on: https://go-review.googlesource.com/c/net/+/460735
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: David Chase <drchase@google.com>
diff --git a/nettest/nettest.go b/nettest/nettest.go
index 3d970bf..510555a 100644
--- a/nettest/nettest.go
+++ b/nettest/nettest.go
@@ -20,11 +20,13 @@
 )
 
 var (
-	stackOnce          sync.Once
-	ipv4Enabled        bool
-	ipv6Enabled        bool
-	unStrmDgramEnabled bool
-	rawSocketSess      bool
+	stackOnce               sync.Once
+	ipv4Enabled             bool
+	canListenTCP4OnLoopback bool
+	ipv6Enabled             bool
+	canListenTCP6OnLoopback bool
+	unStrmDgramEnabled      bool
+	rawSocketSess           bool
 
 	aLongTimeAgo = time.Unix(233431200, 0)
 	neverTimeout = time.Time{}
@@ -37,9 +39,17 @@
 	if _, err := RoutedInterface("ip4", net.FlagUp); err == nil {
 		ipv4Enabled = true
 	}
+	if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
+		ln.Close()
+		canListenTCP4OnLoopback = true
+	}
 	if _, err := RoutedInterface("ip6", net.FlagUp); err == nil {
 		ipv6Enabled = true
 	}
+	if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
+		ln.Close()
+		canListenTCP6OnLoopback = true
+	}
 	rawSocketSess = supportsRawSocket()
 	switch runtime.GOOS {
 	case "aix":
@@ -152,22 +162,23 @@
 // The provided network must be "tcp", "tcp4", "tcp6", "unix" or
 // "unixpacket".
 func NewLocalListener(network string) (net.Listener, error) {
+	stackOnce.Do(probeStack)
 	switch network {
 	case "tcp":
-		if SupportsIPv4() {
+		if canListenTCP4OnLoopback {
 			if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
 				return ln, nil
 			}
 		}
-		if SupportsIPv6() {
+		if canListenTCP6OnLoopback {
 			return net.Listen("tcp6", "[::1]:0")
 		}
 	case "tcp4":
-		if SupportsIPv4() {
+		if canListenTCP4OnLoopback {
 			return net.Listen("tcp4", "127.0.0.1:0")
 		}
 	case "tcp6":
-		if SupportsIPv6() {
+		if canListenTCP6OnLoopback {
 			return net.Listen("tcp6", "[::1]:0")
 		}
 	case "unix", "unixpacket":
@@ -185,22 +196,23 @@
 //
 // The provided network must be "udp", "udp4", "udp6" or "unixgram".
 func NewLocalPacketListener(network string) (net.PacketConn, error) {
+	stackOnce.Do(probeStack)
 	switch network {
 	case "udp":
-		if SupportsIPv4() {
+		if canListenTCP4OnLoopback {
 			if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
 				return c, nil
 			}
 		}
-		if SupportsIPv6() {
+		if canListenTCP6OnLoopback {
 			return net.ListenPacket("udp6", "[::1]:0")
 		}
 	case "udp4":
-		if SupportsIPv4() {
+		if canListenTCP4OnLoopback {
 			return net.ListenPacket("udp4", "127.0.0.1:0")
 		}
 	case "udp6":
-		if SupportsIPv6() {
+		if canListenTCP6OnLoopback {
 			return net.ListenPacket("udp6", "[::1]:0")
 		}
 	case "unixgram":