mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Provide better error message when self-check failed
By connecting to all upstreams when self-check failed, so it's clearer to users what causes self-check failed.
This commit is contained in:
committed by
Cuong Manh Le
parent
52954b8ceb
commit
1a8c1ec73d
@@ -369,7 +369,7 @@ func initCLI() {
|
||||
}
|
||||
// If ctrld service is running but selfCheckStatus failed, it could be related
|
||||
// to user's system firewall configuration, notice users about it.
|
||||
if status == service.StatusRunning {
|
||||
if status == service.StatusRunning && err == nil {
|
||||
_, _ = mainLog.Load().Write(marker)
|
||||
mainLog.Load().Write([]byte(`ctrld service was running, but a DNS query could not be sent to its listener`))
|
||||
mainLog.Load().Write([]byte(`Please check your system firewall if it is configured to block/intercept/redirect DNS queries`))
|
||||
@@ -1705,6 +1705,12 @@ func selfCheckStatus(s service.Service) (bool, service.Status, error) {
|
||||
bo.BackOff(ctx, fmt.Errorf("ExchangeContext: %w", exErr))
|
||||
}
|
||||
mainLog.Load().Debug().Msgf("self-check against %q failed", domain)
|
||||
// Ping all upstreams to provide better error message to users.
|
||||
for name, uc := range cfg.Upstream {
|
||||
if err := uc.ErrorPing(); err != nil {
|
||||
mainLog.Load().Err(err).Msgf("failed to connect to upstream.%s, endpoint: %s", name, uc.Endpoint)
|
||||
}
|
||||
}
|
||||
lc := cfg.FirstListener()
|
||||
addr := net.JoinHostPort(lc.IP, strconv.Itoa(lc.Port))
|
||||
marker := strings.Repeat("=", 32)
|
||||
|
||||
@@ -962,6 +962,7 @@ func isWanClient(na net.Addr) bool {
|
||||
// resolveInternalDomainTestQuery resolves internal test domain query, returning the answer to the caller.
|
||||
func resolveInternalDomainTestQuery(ctx context.Context, domain string, m *dns.Msg) *dns.Msg {
|
||||
ctrld.Log(ctx, mainLog.Load().Debug(), "internal domain test query")
|
||||
|
||||
q := m.Question[0]
|
||||
answer := new(dns.Msg)
|
||||
rrStr := fmt.Sprintf("%s A %s", domain, net.IPv4zero)
|
||||
|
||||
38
config.go
38
config.go
@@ -521,35 +521,55 @@ func (uc *UpstreamConfig) newDOHTransport(addrs []string) *http.Transport {
|
||||
|
||||
// Ping warms up the connection to DoH/DoH3 upstream.
|
||||
func (uc *UpstreamConfig) Ping() {
|
||||
_ = uc.ping()
|
||||
}
|
||||
|
||||
// ErrorPing is like Ping, but return an error if any.
|
||||
func (uc *UpstreamConfig) ErrorPing() error {
|
||||
return uc.ping()
|
||||
}
|
||||
|
||||
func (uc *UpstreamConfig) ping() error {
|
||||
switch uc.Type {
|
||||
case ResolverTypeDOH, ResolverTypeDOH3:
|
||||
default:
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
ping := func(t http.RoundTripper) {
|
||||
ping := func(t http.RoundTripper) error {
|
||||
if t == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
req, _ := http.NewRequestWithContext(ctx, "HEAD", uc.Endpoint, nil)
|
||||
resp, _ := t.RoundTrip(req)
|
||||
if resp == nil {
|
||||
return
|
||||
req, err := http.NewRequestWithContext(ctx, "HEAD", uc.Endpoint, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := t.RoundTrip(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
_, _ = io.Copy(io.Discard, resp.Body)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, typ := range []uint16{dns.TypeA, dns.TypeAAAA} {
|
||||
switch uc.Type {
|
||||
case ResolverTypeDOH:
|
||||
ping(uc.dohTransport(typ))
|
||||
|
||||
if err := ping(uc.dohTransport(typ)); err != nil {
|
||||
return err
|
||||
}
|
||||
case ResolverTypeDOH3:
|
||||
ping(uc.doh3Transport(typ))
|
||||
if err := ping(uc.doh3Transport(typ)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uc *UpstreamConfig) isControlD() bool {
|
||||
|
||||
Reference in New Issue
Block a user