mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
internal/net: improve IPv6 support detection with multiple common ports
Changed the IPv6 support detection to try multiple common ports (HTTP/HTTPS) instead of just testing against a DNS port. The function now returns both the IPv6 support status and the successful port that confirmed the connectivity. This makes the IPv6 detection more reliable by not depending solely on DNS port availability. Previously, the function only tested connectivity to a DNS port (53) over IPv6. Now it tries to connect to commonly available ports like HTTP (80) and HTTPS (443) until it finds a working one, making the detection more robust in environments where certain ports might be blocked.
This commit is contained in:
committed by
Cuong Manh Le
parent
b4faf82f76
commit
8dc34f8bf5
@@ -17,10 +17,17 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
v4BootstrapDNS = "76.76.2.22:53"
|
||||
v6BootstrapDNS = "[2606:1a40::22]:53"
|
||||
v4BootstrapDNS = "76.76.2.22:53"
|
||||
v6BootstrapDNS = "[2606:1a40::22]:53"
|
||||
v6BootstrapIP = "2606:1a40::22"
|
||||
defaultHTTPSPort = "443"
|
||||
defaultHTTPPort = "80"
|
||||
defaultDNSPort = "53"
|
||||
probeStackTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
var commonIPv6Ports = []string{defaultHTTPSPort, defaultHTTPPort, defaultDNSPort}
|
||||
|
||||
var Dialer = &net.Dialer{
|
||||
Resolver: &net.Resolver{
|
||||
PreferGo: true,
|
||||
@@ -33,8 +40,6 @@ var Dialer = &net.Dialer{
|
||||
},
|
||||
}
|
||||
|
||||
const probeStackTimeout = 2 * time.Second
|
||||
|
||||
var probeStackDialer = &net.Dialer{
|
||||
Resolver: Dialer.Resolver,
|
||||
Timeout: probeStackTimeout,
|
||||
@@ -50,12 +55,28 @@ func init() {
|
||||
stackOnce.Store(new(sync.Once))
|
||||
}
|
||||
|
||||
func supportIPv6(ctx context.Context) bool {
|
||||
c, err := probeStackDialer.DialContext(ctx, "tcp6", v6BootstrapDNS)
|
||||
// supportIPv6 checks for IPv6 connectivity by attempting to connect to predefined ports
|
||||
// on a specific IPv6 address.
|
||||
// Returns a boolean indicating if IPv6 is supported and the port on which the connection succeeded.
|
||||
// If no connection is successful, returns false and an empty string.
|
||||
func supportIPv6(ctx context.Context) (supported bool, successPort string) {
|
||||
for _, port := range commonIPv6Ports {
|
||||
if canConnectToIPv6Port(ctx, port) {
|
||||
return true, string(port)
|
||||
}
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// canConnectToIPv6Port attempts to establish a TCP connection to the specified port
|
||||
// using IPv6. Returns true if the connection was successful.
|
||||
func canConnectToIPv6Port(ctx context.Context, port string) bool {
|
||||
address := net.JoinHostPort(v6BootstrapIP, port)
|
||||
conn, err := probeStackDialer.DialContext(ctx, "tcp6", address)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
c.Close()
|
||||
_ = conn.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -110,7 +131,8 @@ func SupportsIPv6ListenLocal() bool {
|
||||
|
||||
// IPv6Available is like SupportsIPv6, but always do the check without caching.
|
||||
func IPv6Available(ctx context.Context) bool {
|
||||
return supportIPv6(ctx)
|
||||
hasV6, _ := supportIPv6(ctx)
|
||||
return hasV6
|
||||
}
|
||||
|
||||
// IsIPv6 checks if the provided IP is v6.
|
||||
|
||||
@@ -12,7 +12,12 @@ func TestProbeStackTimeout(t *testing.T) {
|
||||
go func() {
|
||||
defer close(done)
|
||||
close(started)
|
||||
supportIPv6(context.Background())
|
||||
hasV6, port := supportIPv6(context.Background())
|
||||
if hasV6 {
|
||||
t.Logf("connect to port %s using ipv6: %v", port, hasV6)
|
||||
} else {
|
||||
t.Log("ipv6 is not available")
|
||||
}
|
||||
}()
|
||||
|
||||
<-started
|
||||
|
||||
Reference in New Issue
Block a user