mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-08-10 13:20:33 +02:00
all: support ipv6 for upstream bootstrap ip
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
+31
-14
@@ -51,23 +51,40 @@ func (p *prog) run() {
|
|||||||
if uc.BootstrapIP == "" {
|
if uc.BootstrapIP == "" {
|
||||||
// resolve it manually and set the bootstrap ip
|
// resolve it manually and set the bootstrap ip
|
||||||
c := new(dns.Client)
|
c := new(dns.Client)
|
||||||
m := new(dns.Msg)
|
for _, dnsType := range []uint16{dns.TypeAAAA, dns.TypeA} {
|
||||||
m.SetQuestion(uc.Domain+".", dns.TypeA)
|
if !supportsIPv6() && dnsType == dns.TypeAAAA {
|
||||||
m.RecursionDesired = true
|
continue
|
||||||
r, _, err := c.Exchange(m, net.JoinHostPort(bootstrapDNS, "53"))
|
}
|
||||||
if err != nil {
|
m := new(dns.Msg)
|
||||||
proxyLog.Error().Err(err).Msgf("could not resolve domain %s for upstream.%s", uc.Domain, n)
|
m.SetQuestion(uc.Domain+".", dnsType)
|
||||||
} else {
|
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 {
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
proxyLog.Error().Msgf("could not resolve domain return code: %d, upstream.%s", r.Rcode, n)
|
proxyLog.Error().Msgf("could not resolve domain return code: %d, upstream.%s", r.Rcode, n)
|
||||||
} else {
|
continue
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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()
|
uc.SetupTransport()
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package ctrld
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -145,8 +144,10 @@ func (uc *UpstreamConfig) SetupTransport() {
|
|||||||
}
|
}
|
||||||
Log(ctx, ProxyLog.Debug(), "debug dial context %s - %s - %s", addr, network, bootstrapDNS)
|
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 we have a bootstrap ip set, use it to avoid DNS lookup
|
||||||
if uc.BootstrapIP != "" && addr == fmt.Sprintf("%s:443", uc.Domain) {
|
if uc.BootstrapIP != "" {
|
||||||
addr = fmt.Sprintf("%s:443", uc.BootstrapIP)
|
if _, port, _ := net.SplitHostPort(addr); port != "" {
|
||||||
|
addr = net.JoinHostPort(uc.BootstrapIP, port)
|
||||||
|
}
|
||||||
Log(ctx, ProxyLog.Debug(), "sending doh request to: %s", addr)
|
Log(ctx, ProxyLog.Debug(), "sending doh request to: %s", addr)
|
||||||
}
|
}
|
||||||
return dialer.DialContext(ctx, network, addr)
|
return dialer.DialContext(ctx, network, addr)
|
||||||
|
|||||||
Reference in New Issue
Block a user