From 6dbeb5b971a9aeabe9bd16f26d87c1907484f4b6 Mon Sep 17 00:00:00 2001
From: Eugene Burkov <e.burkov@adguard.com>
Date: Tue, 16 Jan 2024 13:18:22 +0300
Subject: [PATCH] Pull request 2125: 6321 upd proxy

Updates #6321.

Squashed commit of the following:

commit 033f4d427bc965c8c5b5fc452ddc938b71c8d4f4
Merge: febf5b568 f7995aa02
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jan 16 12:42:50 2024 +0300

    Merge branch 'master' into 6321-upd-proxy

commit febf5b568b012ccdce86c1d0dde710b99f5729b2
Merge: 7e4b247a4 58b47adaf
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jan 16 12:34:28 2024 +0300

    Merge branch 'master' into 6321-upd-proxy

commit 7e4b247a40263225dda3aaa77b823c056ae49541
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jan 12 14:37:28 2024 +0300

    all: upd proxy revision

commit 0e925c1fcfb5ea4b712360721b62ecef1c8355d8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jan 11 14:24:47 2024 +0300

    dnsforward: imp code

commit 6f5c271895f973f6b3ad842cb987cdc2c89856f8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jan 10 16:34:02 2024 +0300

    all: use caching resolver more, imp code

commit ce3f3137d2a2ed5da7829f9ecf49bab388d44852
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jan 10 16:00:08 2024 +0300

    all: log changes

commit ce90dbcda8586fda0d12d86ef609de505ae87164
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jan 10 13:01:25 2024 +0300

    dnsforward: use caching resolvers

commit 208fbaf0aa50df33f8482a441d361d106fc7b146
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jan 10 12:52:15 2024 +0300

    all: upd proxy
---
 CHANGELOG.md                     | 3 +++
 go.mod                           | 2 +-
 go.sum                           | 4 ++--
 internal/dnsforward/http.go      | 9 +++++++--
 internal/dnsforward/http_test.go | 4 ++--
 internal/dnsforward/upstreams.go | 2 +-
 internal/next/dnssvc/dnssvc.go   | 2 +-
 7 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b689ef2e..cdd34a4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
 
 ### Changed
 
+- The bootstrapped upstream addresses now updated according to the TTL of the
+  bootstrap DNS response ([#6321]).
 - Logging level of timeout errors is now `error` instead of `debug` ([#6574]).
 - The field `"upstream_mode"` in `POST /control/dns_config` and
   `GET /control/dns_info` HTTP APIs now accepts `load_balance` value.  Check
@@ -81,6 +83,7 @@ In this release, the schema version has changed from 27 to 28.
 - Omitted CNAME records in safe search results, which can cause YouTube to not
   work on iOS ([#6352]).
 
+[#6321]: https://github.com/AdguardTeam/AdGuardHome/issues/6321
 [#6352]: https://github.com/AdguardTeam/AdGuardHome/issues/6352
 [#6409]: https://github.com/AdguardTeam/AdGuardHome/issues/6409
 [#6480]: https://github.com/AdguardTeam/AdGuardHome/issues/6480
diff --git a/go.mod b/go.mod
index 81b0e582..50812877 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
 go 1.20
 
 require (
-	github.com/AdguardTeam/dnsproxy v0.61.1
+	github.com/AdguardTeam/dnsproxy v0.62.0
 	github.com/AdguardTeam/golibs v0.18.1
 	github.com/AdguardTeam/urlfilter v0.17.3
 	github.com/NYTimes/gziphandler v1.1.1
diff --git a/go.sum b/go.sum
index 3d98fdf8..ac3c236d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/AdguardTeam/dnsproxy v0.61.1 h1:RdGVTHZR8N6eAyae13ORSlvn9qNeHK/h2g9mbVM/VS4=
-github.com/AdguardTeam/dnsproxy v0.61.1/go.mod h1:IdmXdkpc+m+S2EajJkVZDZm//yQ4mQm2FCOugQpc/N8=
+github.com/AdguardTeam/dnsproxy v0.62.0 h1:IaWW+Ln4SJ4V+y8qyVlTlYDN3ATDkqWCufph+Gxz82c=
+github.com/AdguardTeam/dnsproxy v0.62.0/go.mod h1:IdmXdkpc+m+S2EajJkVZDZm//yQ4mQm2FCOugQpc/N8=
 github.com/AdguardTeam/golibs v0.18.1 h1:6u0fvrIj2qjUsRdbIGJ9AR0g5QRSWdKIo/DYl3tp5aM=
 github.com/AdguardTeam/golibs v0.18.1/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
 github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
diff --git a/internal/dnsforward/http.go b/internal/dnsforward/http.go
index d78d5833..d3d352df 100644
--- a/internal/dnsforward/http.go
+++ b/internal/dnsforward/http.go
@@ -267,17 +267,22 @@ func (req *jsonDNSConfig) checkBootstrap() (err error) {
 	}
 
 	var b string
-	defer func() { err = errors.Annotate(err, "checking bootstrap %s: invalid address: %w", b) }()
+	defer func() { err = errors.Annotate(err, "checking bootstrap %s: %w", b) }()
 
 	for _, b = range *req.Bootstraps {
 		if b == "" {
 			return errors.Error("empty")
 		}
 
-		if _, err = upstream.NewUpstreamResolver(b, nil); err != nil {
+		var resolver *upstream.UpstreamResolver
+		if resolver, err = upstream.NewUpstreamResolver(b, nil); err != nil {
 			// Don't wrap the error because it's informative enough as is.
 			return err
 		}
+
+		if err = resolver.Close(); err != nil {
+			return fmt.Errorf("closing %s: %w", b, err)
+		}
 	}
 
 	return nil
diff --git a/internal/dnsforward/http_test.go b/internal/dnsforward/http_test.go
index 0393ee30..2e28039f 100644
--- a/internal/dnsforward/http_test.go
+++ b/internal/dnsforward/http_test.go
@@ -227,8 +227,8 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
 			`upstream servers: validating upstream "!!!": not an ip:port`,
 	}, {
 		name: "bootstraps_bad",
-		wantSet: `validating dns config: checking bootstrap a: invalid address: not a bootstrap: ` +
-			`ParseAddr("a"): unable to parse IP`,
+		wantSet: `validating dns config: checking bootstrap a: not a bootstrap: ParseAddr("a"): ` +
+			`unable to parse IP`,
 	}, {
 		name:    "cache_bad_ttl",
 		wantSet: `validating dns config: cache_ttl_min must be less than or equal to cache_ttl_max`,
diff --git a/internal/dnsforward/upstreams.go b/internal/dnsforward/upstreams.go
index c9fc6834..d9644dec 100644
--- a/internal/dnsforward/upstreams.go
+++ b/internal/dnsforward/upstreams.go
@@ -180,7 +180,7 @@ func (s *Server) createBootstrap(
 
 	var parallel upstream.ParallelResolver
 	for _, b := range boots {
-		parallel = append(parallel, b)
+		parallel = append(parallel, upstream.NewCachingResolver(b))
 	}
 
 	if s.etcHosts != nil {
diff --git a/internal/next/dnssvc/dnssvc.go b/internal/next/dnssvc/dnssvc.go
index e0056dcb..68c2e7e7 100644
--- a/internal/next/dnssvc/dnssvc.go
+++ b/internal/next/dnssvc/dnssvc.go
@@ -110,7 +110,7 @@ func addressesToUpstreams(
 	// TODO(e.burkov):  Add system hosts resolver here.
 	var bootstrap upstream.ParallelResolver
 	for _, r := range boots {
-		bootstrap = append(bootstrap, r)
+		bootstrap = append(bootstrap, upstream.NewCachingResolver(r))
 	}
 
 	upstreams = make([]upstream.Upstream, len(upsStrs))