mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
all: support ipv6 for upstream bootstrap ip
This commit is contained in:
committed by
Cuong Manh Le
parent
ebcc545547
commit
a7ae6c9853
23
cmd/ctrld/net.go
Normal file
23
cmd/ctrld/net.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
stackOnce sync.Once
|
||||
ipv6Enabled bool
|
||||
)
|
||||
|
||||
func probeStack() {
|
||||
if ln, err := net.Listen("tcp6", "[::]:0"); err == nil {
|
||||
ln.Close()
|
||||
ipv6Enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
func supportsIPv6() bool {
|
||||
stackOnce.Do(probeStack)
|
||||
return ipv6Enabled
|
||||
}
|
||||
@@ -51,23 +51,40 @@ func (p *prog) run() {
|
||||
if uc.BootstrapIP == "" {
|
||||
// resolve it manually and set the bootstrap ip
|
||||
c := new(dns.Client)
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(uc.Domain+".", dns.TypeA)
|
||||
m.RecursionDesired = true
|
||||
r, _, err := c.Exchange(m, net.JoinHostPort(bootstrapDNS, "53"))
|
||||
if err != nil {
|
||||
proxyLog.Error().Err(err).Msgf("could not resolve domain %s for upstream.%s", uc.Domain, n)
|
||||
} else {
|
||||
for _, dnsType := range []uint16{dns.TypeAAAA, dns.TypeA} {
|
||||
if !supportsIPv6() && dnsType == dns.TypeAAAA {
|
||||
continue
|
||||
}
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(uc.Domain+".", dnsType)
|
||||
m.RecursionDesired = true
|
||||
r, _, err := c.Exchange(m, net.JoinHostPort(bootstrapDNS, "53"))
|
||||
if err != nil {
|
||||
proxyLog.Error().Err(err).Msgf("could not resolve domain %s for upstream.%s", uc.Domain, n)
|
||||
continue
|
||||
}
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
proxyLog.Error().Msgf("could not resolve domain return code: %d, upstream.%s", r.Rcode, n)
|
||||
} else {
|
||||
for _, a := range r.Answer {
|
||||
if ar, ok := a.(*dns.A); ok {
|
||||
uc.BootstrapIP = ar.A.String()
|
||||
proxyLog.Info().Str("bootstrap_ip", uc.BootstrapIP).Msgf("Setting bootstrap IP for upstream.%s", n)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if len(r.Answer) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, a := range r.Answer {
|
||||
switch ar := a.(type) {
|
||||
case *dns.A:
|
||||
uc.BootstrapIP = ar.A.String()
|
||||
case *dns.AAAA:
|
||||
uc.BootstrapIP = ar.AAAA.String()
|
||||
default:
|
||||
continue
|
||||
}
|
||||
proxyLog.Info().Str("bootstrap_ip", uc.BootstrapIP).Msgf("Setting bootstrap IP for upstream.%s", n)
|
||||
// Stop if we reached here, because we got the bootstrap IP from r.Answer.
|
||||
break
|
||||
}
|
||||
// If we reached here, uc.BootstrapIP was set, nothing to do anymore.
|
||||
break
|
||||
}
|
||||
}
|
||||
uc.SetupTransport()
|
||||
|
||||
@@ -2,7 +2,6 @@ package ctrld
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -145,8 +144,10 @@ func (uc *UpstreamConfig) SetupTransport() {
|
||||
}
|
||||
Log(ctx, ProxyLog.Debug(), "debug dial context %s - %s - %s", addr, network, bootstrapDNS)
|
||||
// if we have a bootstrap ip set, use it to avoid DNS lookup
|
||||
if uc.BootstrapIP != "" && addr == fmt.Sprintf("%s:443", uc.Domain) {
|
||||
addr = fmt.Sprintf("%s:443", uc.BootstrapIP)
|
||||
if uc.BootstrapIP != "" {
|
||||
if _, port, _ := net.SplitHostPort(addr); port != "" {
|
||||
addr = net.JoinHostPort(uc.BootstrapIP, port)
|
||||
}
|
||||
Log(ctx, ProxyLog.Debug(), "sending doh request to: %s", addr)
|
||||
}
|
||||
return dialer.DialContext(ctx, network, addr)
|
||||
|
||||
Reference in New Issue
Block a user