From 6bdfa2d99e244d6fa88f2bda19e6c600db1f552f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 16 Oct 2025 23:25:34 +0800 Subject: [PATCH] Use a more conservative strategy for resolving with systemd-resolved for local DNS server --- dns/transport/local/local.go | 14 ++++---- dns/transport/local/local_resolved_linux.go | 36 +++++++++++++++------ dns/transport/local/local_resolved_stub.go | 4 +++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/dns/transport/local/local.go b/dns/transport/local/local.go index f1d67d163..51b8c18c5 100644 --- a/dns/transport/local/local.go +++ b/dns/transport/local/local.go @@ -53,13 +53,15 @@ func (t *Transport) Start(stage adapter.StartStage) error { switch stage { case adapter.StartStateInitialize: if !t.preferGo { - resolvedResolver, err := NewResolvedResolver(t.ctx, t.logger) - if err == nil { - err = resolvedResolver.Start() + if isSystemdResolvedManaged() { + resolvedResolver, err := NewResolvedResolver(t.ctx, t.logger) if err == nil { - t.resolved = resolvedResolver - } else { - t.logger.Warn(E.Cause(err, "initialize resolved resolver")) + err = resolvedResolver.Start() + if err == nil { + t.resolved = resolvedResolver + } else { + t.logger.Warn(E.Cause(err, "initialize resolved resolver")) + } } } } diff --git a/dns/transport/local/local_resolved_linux.go b/dns/transport/local/local_resolved_linux.go index 3c9bf0c4a..bac34c025 100644 --- a/dns/transport/local/local_resolved_linux.go +++ b/dns/transport/local/local_resolved_linux.go @@ -1,9 +1,11 @@ package local import ( + "bufio" "context" "errors" "os" + "strings" "sync" "sync/atomic" @@ -22,6 +24,25 @@ import ( mDNS "github.com/miekg/dns" ) +func isSystemdResolvedManaged() bool { + resolvContent, err := os.Open("/etc/resolv.conf") + if err != nil { + return false + } + defer resolvContent.Close() + scanner := bufio.NewScanner(resolvContent) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || line[0] != '#' { + return false + } + if strings.Contains(line, "systemd-resolved") { + return true + } + } + return false +} + type DBusResolvedResolver struct { ctx context.Context logger logger.ContextLogger @@ -188,7 +209,7 @@ func (t *DBusResolvedResolver) checkResolved(ctx context.Context) (*ResolvedObje int32(defaultInterface.Index), ) if call.Err != nil { - return nil, err + return nil, call.Err } var linkPath dbus.ObjectPath err = call.Store(&linkPath) @@ -214,15 +235,12 @@ func (t *DBusResolvedResolver) checkResolved(ctx context.Context) (*ResolvedObje return nil, E.New("No appropriate name servers or networks for name found") } } - return &ResolvedObject{ - BusObject: dbusObject, - }, nil - } else { - return &ResolvedObject{ - BusObject: dbusObject, - InterfaceIndex: int32(defaultInterface.Index), - }, nil + return nil, E.New("link has no DNS servers configured") } + return &ResolvedObject{ + BusObject: dbusObject, + InterfaceIndex: int32(defaultInterface.Index), + }, nil } func (t *DBusResolvedResolver) updateDefaultInterface(defaultInterface *control.Interface, flags int) { diff --git a/dns/transport/local/local_resolved_stub.go b/dns/transport/local/local_resolved_stub.go index ac23c4f3b..2e0118511 100644 --- a/dns/transport/local/local_resolved_stub.go +++ b/dns/transport/local/local_resolved_stub.go @@ -9,6 +9,10 @@ import ( "github.com/sagernet/sing/common/logger" ) +func isSystemdResolvedManaged() bool { + return false +} + func NewResolvedResolver(ctx context.Context, logger logger.ContextLogger) (ResolvedResolver, error) { return nil, os.ErrInvalid }