mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
internal/controld: check if ipv4 is available before connect to API
Updates #53
This commit is contained in:
committed by
Cuong Manh Le
parent
45f827a2c5
commit
83b551fb2d
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/Control-D-Inc/ctrld"
|
||||
"github.com/Control-D-Inc/ctrld/internal/controld"
|
||||
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -105,7 +106,7 @@ func initCLI() {
|
||||
log.Fatalf("failed to unmarshal config: %v", err)
|
||||
}
|
||||
// Wait for network up.
|
||||
if !netUp() {
|
||||
if !ctrldnet.Up() {
|
||||
log.Fatal("network is not up yet")
|
||||
}
|
||||
processLogAndCacheFlags()
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/Control-D-Inc/ctrld"
|
||||
"github.com/Control-D-Inc/ctrld/internal/dnscache"
|
||||
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||
)
|
||||
|
||||
const staleTTL = 60 * time.Second
|
||||
@@ -55,7 +56,7 @@ func (p *prog) serveUDP(listenerNum string) error {
|
||||
|
||||
// On Windows, there's no easy way for disabling/removing IPv6 DNS resolver, so we check whether we can
|
||||
// listen on ::1, then spawn a listener for receiving DNS requests.
|
||||
if runtime.GOOS == "windows" && supportsIPv6ListenLocal() {
|
||||
if runtime.GOOS == "windows" && ctrldnet.SupportsIPv6() {
|
||||
go func() {
|
||||
s := &dns.Server{
|
||||
Addr: net.JoinHostPort("::1", strconv.Itoa(listenerConfig.Port)),
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"tailscale.com/logtail/backoff"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld/internal/controld"
|
||||
)
|
||||
|
||||
const (
|
||||
controldIPv6Test = "ipv6.controld.io"
|
||||
)
|
||||
|
||||
var (
|
||||
stackOnce sync.Once
|
||||
ipv6Enabled bool
|
||||
canListenIPv6Local bool
|
||||
hasNetworkUp bool
|
||||
)
|
||||
|
||||
func probeStack() {
|
||||
b := backoff.NewBackoff("probeStack", func(format string, args ...any) {}, time.Minute)
|
||||
for {
|
||||
if _, err := controld.Dialer.Dial("udp", net.JoinHostPort(bootstrapDNS, "53")); err == nil {
|
||||
hasNetworkUp = true
|
||||
break
|
||||
} else {
|
||||
b.BackOff(context.Background(), err)
|
||||
}
|
||||
}
|
||||
if _, err := controld.Dialer.Dial("tcp6", net.JoinHostPort(controldIPv6Test, "80")); err == nil {
|
||||
ipv6Enabled = true
|
||||
}
|
||||
if ln, err := net.Listen("tcp6", "[::1]:53"); err == nil {
|
||||
ln.Close()
|
||||
canListenIPv6Local = true
|
||||
}
|
||||
}
|
||||
|
||||
func netUp() bool {
|
||||
stackOnce.Do(probeStack)
|
||||
return hasNetworkUp
|
||||
}
|
||||
|
||||
func supportsIPv6() bool {
|
||||
stackOnce.Do(probeStack)
|
||||
return ipv6Enabled
|
||||
}
|
||||
|
||||
func supportsIPv6ListenLocal() bool {
|
||||
stackOnce.Do(probeStack)
|
||||
return canListenIPv6Local
|
||||
}
|
||||
|
||||
// isIPv6 checks if the provided IP is v6.
|
||||
//
|
||||
//lint:ignore U1000 use in os_windows.go
|
||||
func isIPv6(ip string) bool {
|
||||
parsedIP := net.ParseIP(ip)
|
||||
return parsedIP != nil && parsedIP.To4() == nil && parsedIP.To16() != nil
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"tailscale.com/util/dnsname"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld/internal/dns"
|
||||
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||
)
|
||||
|
||||
@@ -111,7 +112,7 @@ func resetDNS(iface *net.Interface) error {
|
||||
}
|
||||
|
||||
// TODO(cuonglm): handle DHCPv6 properly.
|
||||
if supportsIPv6() {
|
||||
if ctrldnet.SupportsIPv6() {
|
||||
c := client6.NewClient()
|
||||
conversation, err := c.Exchange(iface.Name)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"strconv"
|
||||
|
||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||
|
||||
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||
)
|
||||
|
||||
// TODO(cuonglm): implement.
|
||||
@@ -39,7 +41,7 @@ func setDNS(iface *net.Interface, nameservers []string) error {
|
||||
|
||||
// TODO(cuonglm): should we use system API?
|
||||
func resetDNS(iface *net.Interface) error {
|
||||
if supportsIPv6ListenLocal() {
|
||||
if ctrldnet.SupportsIPv6ListenLocal() {
|
||||
if output, err := netsh("interface", "ipv6", "set", "dnsserver", strconv.Itoa(iface.Index), "dhcp"); err != nil {
|
||||
mainLog.Warn().Err(err).Msgf("failed to reset ipv6 DNS: %s", string(output))
|
||||
}
|
||||
@@ -54,7 +56,7 @@ func resetDNS(iface *net.Interface) error {
|
||||
|
||||
func setPrimaryDNS(iface *net.Interface, dns string) error {
|
||||
ipVer := "ipv4"
|
||||
if isIPv6(dns) {
|
||||
if ctrldnet.IsIPv6(dns) {
|
||||
ipVer = "ipv6"
|
||||
}
|
||||
idx := strconv.Itoa(iface.Index)
|
||||
@@ -73,7 +75,7 @@ func setPrimaryDNS(iface *net.Interface, dns string) error {
|
||||
|
||||
func addSecondaryDNS(iface *net.Interface, dns string) error {
|
||||
ipVer := "ipv4"
|
||||
if isIPv6(dns) {
|
||||
if ctrldnet.IsIPv6(dns) {
|
||||
ipVer = "ipv6"
|
||||
}
|
||||
output, err := netsh("interface", ipVer, "add", "dns", strconv.Itoa(iface.Index), dns, "index=2")
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/Control-D-Inc/ctrld"
|
||||
"github.com/Control-D-Inc/ctrld/internal/dnscache"
|
||||
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||
)
|
||||
|
||||
var errWindowsAddrInUse = syscall.Errno(0x2740)
|
||||
@@ -64,7 +65,7 @@ func (p *prog) run() {
|
||||
// resolve it manually and set the bootstrap ip
|
||||
c := new(dns.Client)
|
||||
for _, dnsType := range []uint16{dns.TypeAAAA, dns.TypeA} {
|
||||
if !supportsIPv6() && dnsType == dns.TypeAAAA {
|
||||
if !ctrldnet.SupportsIPv6() && dnsType == dns.TypeAAAA {
|
||||
continue
|
||||
}
|
||||
m := new(dns.Msg)
|
||||
|
||||
Reference in New Issue
Block a user