From 712d38b9aa560b9dee2016a219894d4139921a82 Mon Sep 17 00:00:00 2001 From: Stanislav Chzhen Date: Fri, 27 Dec 2024 17:29:04 +0300 Subject: [PATCH] Pull request 386: 430-fix-system-hosts-file-path Closes #430. Squashed commit of the following: commit 9f9870f3aae45bff7c30fb8446e0a02f4443b190 Author: Stanislav Chzhen Date: Fri Dec 27 17:16:17 2024 +0300 handler: imp docs commit f80639a7302f24a915993af5d47122d587655860 Author: Stanislav Chzhen Date: Fri Dec 27 16:49:41 2024 +0300 handler: imp tests commit ef2dd46814801145cc20e8757b560982c520b520 Author: Stanislav Chzhen Date: Fri Dec 27 16:37:59 2024 +0300 handler: imp code commit 0f4241dbeace9eee1ef8316592773da57d61264c Author: Stanislav Chzhen Date: Fri Dec 27 16:00:08 2024 +0300 handler: fix ptr commit 64cc5916e18d3675093b1cf2b4405301720b58af Author: Stanislav Chzhen Date: Fri Dec 27 14:22:15 2024 +0300 all: imp code commit d16be8a6a4523f64c5745748ce50b29a7f313e77 Author: Stanislav Chzhen Date: Thu Dec 26 22:01:30 2024 +0300 all: fix system hosts file path --- internal/cmd/proxy.go | 3 +-- internal/handler/constructor.go | 9 +++++---- internal/handler/default_internal_test.go | 16 ++++++++-------- internal/handler/hosts.go | 2 +- internal/netutil/paths.go | 9 +++++++++ internal/netutil/paths_unix.go | 21 +++++++++++++++++++++ internal/netutil/paths_windows.go | 22 ++++++++++++++++++++++ 7 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 internal/netutil/paths.go create mode 100644 internal/netutil/paths_unix.go create mode 100644 internal/netutil/paths_windows.go diff --git a/internal/cmd/proxy.go b/internal/cmd/proxy.go index 578ee163c..14e6bc567 100644 --- a/internal/cmd/proxy.go +++ b/internal/cmd/proxy.go @@ -18,7 +18,6 @@ import ( "github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/upstream" "github.com/AdguardTeam/golibs/errors" - "github.com/AdguardTeam/golibs/hostsfile" "github.com/AdguardTeam/golibs/logutil/slogutil" "github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/osutil" @@ -518,7 +517,7 @@ func (conf *configuration) hostsFiles(ctx context.Context, l *slog.Logger) (path return conf.HostsFiles, nil } - paths, err = hostsfile.DefaultHostsPaths() + paths, err = proxynetutil.DefaultHostsPaths() if err != nil { return nil, fmt.Errorf("getting default hosts files: %w", err) } diff --git a/internal/handler/constructor.go b/internal/handler/constructor.go index 3e9d86180..a01a989f4 100644 --- a/internal/handler/constructor.go +++ b/internal/handler/constructor.go @@ -17,8 +17,9 @@ type messageConstructor interface { NewCompressedResponse(req *dns.Msg, code int) (resp *dns.Msg) // NewPTRAnswer creates a new resource record for PTR response with the - // given FQDN and PTR domain. - NewPTRAnswer(fqdn, ptrDomain string) (ans *dns.PTR) + // given FQDN and PTR domain. Arguments must be fully qualified domain + // names. + NewPTRAnswer(fqdn, ptrFQDN string) (ans *dns.PTR) // NewIPResponse creates a new A/AAAA response message for req with the // given IP addresses. All IP addresses must be of the same family. @@ -48,10 +49,10 @@ func (defaultConstructor) NewCompressedResponse(req *dns.Msg, code int) (resp *d // NewPTRAnswer implements the [messageConstructor] interface for // [defaultConstructor]. -func (defaultConstructor) NewPTRAnswer(fqdn, ptrDomain string) (ans *dns.PTR) { +func (defaultConstructor) NewPTRAnswer(fqdn, ptrFQDN string) (ans *dns.PTR) { return &dns.PTR{ Hdr: hdr(fqdn, dns.TypePTR), - Ptr: ptrDomain, + Ptr: dns.Fqdn(ptrFQDN), } } diff --git a/internal/handler/default_internal_test.go b/internal/handler/default_internal_test.go index d48856a66..e5ed4070b 100644 --- a/internal/handler/default_internal_test.go +++ b/internal/handler/default_internal_test.go @@ -98,8 +98,8 @@ func TestDefault_resolveFromHosts(t *testing.T) { }) const ( - domainV4 = "ipv4.domain.example" - domainV6 = "ipv6.domain.example" + fqdnV4 = "ipv4.domain.example." + fqdnV6 = "ipv6.domain.example." ) var ( @@ -118,26 +118,26 @@ func TestDefault_resolveFromHosts(t *testing.T) { }{{ wantAns: &dns.A{ Hdr: dns.RR_Header{ - Name: domainV4, + Name: fqdnV4, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 10, }, A: addrV4.AsSlice(), }, - req: (&dns.Msg{}).SetQuestion(domainV4, dns.TypeA), + req: (&dns.Msg{}).SetQuestion(fqdnV4, dns.TypeA), name: "success_a", }, { wantAns: &dns.AAAA{ Hdr: dns.RR_Header{ - Name: domainV6, + Name: fqdnV6, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 10, }, AAAA: addrV6.AsSlice(), }, - req: (&dns.Msg{}).SetQuestion(domainV6, dns.TypeAAAA), + req: (&dns.Msg{}).SetQuestion(fqdnV6, dns.TypeAAAA), name: "success_aaaa", }, { wantAns: &dns.PTR{ @@ -147,7 +147,7 @@ func TestDefault_resolveFromHosts(t *testing.T) { Class: dns.ClassINET, Ttl: 10, }, - Ptr: domainV4, + Ptr: fqdnV4, }, req: (&dns.Msg{}).SetQuestion(reversedV4, dns.TypePTR), name: "success_ptr_v4", @@ -159,7 +159,7 @@ func TestDefault_resolveFromHosts(t *testing.T) { Class: dns.ClassINET, Ttl: 10, }, - Ptr: domainV6, + Ptr: fqdnV6, }, req: (&dns.Msg{}).SetQuestion(reversedV6, dns.TypePTR), name: "success_ptr_v6", diff --git a/internal/handler/hosts.go b/internal/handler/hosts.go index 34bee3706..6b4f4140a 100644 --- a/internal/handler/hosts.go +++ b/internal/handler/hosts.go @@ -117,7 +117,7 @@ func (h *Default) resolveFromHosts(ctx context.Context, req *dns.Msg) (resp *dns resp = h.messages.NewCompressedResponse(req, dns.RcodeSuccess) name = req.Question[0].Name for _, ptr := range ptrs { - resp.Answer = append(resp.Answer, h.messages.NewPTRAnswer(name, ptr)) + resp.Answer = append(resp.Answer, h.messages.NewPTRAnswer(name, dns.Fqdn(ptr))) } default: h.logger.DebugContext(ctx, "no hosts records found", "name", name, "qtype", q.Qtype) diff --git a/internal/netutil/paths.go b/internal/netutil/paths.go new file mode 100644 index 000000000..8e1c6d43c --- /dev/null +++ b/internal/netutil/paths.go @@ -0,0 +1,9 @@ +package netutil + +// DefaultHostsPaths returns the slice of default paths to system hosts files. +// +// TODO(s.chzhen): Since [fs.FS] is no longer needed, update the +// [hostsfile.DefaultHostsPaths] from golibs. +func DefaultHostsPaths() (paths []string, err error) { + return defaultHostsPaths() +} diff --git a/internal/netutil/paths_unix.go b/internal/netutil/paths_unix.go new file mode 100644 index 000000000..f7833d3b2 --- /dev/null +++ b/internal/netutil/paths_unix.go @@ -0,0 +1,21 @@ +//go:build unix + +package netutil + +import "github.com/AdguardTeam/golibs/hostsfile" + +// defaultHostsPaths returns default paths to hosts files for UNIX. +func defaultHostsPaths() (paths []string, err error) { + paths, err = hostsfile.DefaultHostsPaths() + if err != nil { + // Should not happen because error is always nil. + panic(err) + } + + res := make([]string, 0, len(paths)) + for _, p := range paths { + res = append(res, "/"+p) + } + + return res, nil +} diff --git a/internal/netutil/paths_windows.go b/internal/netutil/paths_windows.go new file mode 100644 index 000000000..fc6ac6482 --- /dev/null +++ b/internal/netutil/paths_windows.go @@ -0,0 +1,22 @@ +//go:build windows + +package netutil + +import ( + "fmt" + "path" + + "golang.org/x/sys/windows" +) + +// defaultHostsPaths returns default paths to hosts files for Windows. +func defaultHostsPaths() (paths []string, err error) { + sysDir, err := windows.GetSystemDirectory() + if err != nil { + return []string{}, fmt.Errorf("getting system directory: %w", err) + } + + p := path.Join(sysDir, "drivers", "etc", "hosts") + + return []string{p}, nil +}