From 184f476bdcf69a171ceec0396d3a9ed1e6769c01 Mon Sep 17 00:00:00 2001
From: Eugene Burkov <e.burkov@adguard.com>
Date: Tue, 20 Aug 2024 18:38:04 +0300
Subject: [PATCH] Pull request 2269: ADG-8932 Upd all

Squashed commit of the following:

commit 00fc45877776ed7d1c59be26330f6f16d784ead2
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 20 16:21:25 2024 +0300

    all: imp lint

commit b04d9cd334a92faf21787e7e1ebf20d5e5fd0bee
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 20 14:40:18 2024 +0300

    all: upd all

commit f151f8c3139a0d8ac8cc5cf4926710b8d3f98846
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Aug 16 13:12:36 2024 +0300

    all: upd proxy
---
 .github/workflows/build.yml                 |  2 +-
 .github/workflows/lint.yml                  |  2 +-
 CHANGELOG.md                                |  8 ++
 Makefile                                    | 44 ++++++----
 bamboo-specs/release.yaml                   |  6 +-
 bamboo-specs/test.yaml                      |  5 +-
 go.mod                                      | 22 ++---
 go.sum                                      | 40 ++++-----
 internal/dnsforward/config.go               |  2 -
 internal/dnsforward/http_test.go            |  2 +-
 internal/dnsforward/msg.go                  | 96 +++++++++++----------
 internal/dnsforward/process.go              |  2 +-
 internal/filtering/hashprefix/cache.go      |  5 --
 internal/filtering/hashprefix/hashprefix.go |  1 -
 internal/tools/doc.go                       |  5 --
 internal/tools/go.mod                       | 25 +++---
 internal/tools/go.sum                       | 68 ++++++---------
 internal/tools/tools.go                     |  4 +
 scripts/hooks/pre-commit                    | 26 ++++--
 scripts/make/go-build.sh                    |  3 +-
 scripts/make/go-lint.sh                     | 22 +++--
 scripts/make/go-tools.sh                    |  4 +-
 scripts/make/go-upd-tools.sh                |  5 +-
 scripts/make/md-lint.sh                     | 23 +++++
 scripts/make/sh-lint.sh                     | 39 +++++++++
 25 files changed, 267 insertions(+), 194 deletions(-)
 delete mode 100644 internal/tools/doc.go
 create mode 100644 scripts/make/md-lint.sh
 create mode 100644 scripts/make/sh-lint.sh

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5320febf..eb173124 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,7 +1,7 @@
 'name': 'build'
 
 'env':
-  'GO_VERSION': '1.22.5'
+  'GO_VERSION': '1.22.6'
   'NODE_VERSION': '16'
 
 'on':
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 1426768a..469396ce 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,7 +1,7 @@
 'name': 'lint'
 
 'env':
-  'GO_VERSION': '1.22.5'
+  'GO_VERSION': '1.22.6'
 
 'on':
   'push':
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad6a7b08..ac1da18c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,6 +32,12 @@ NOTE: Add new changes BELOW THIS COMMENT.
 - Support for 64-bit RISC-V architecture ([#5704]).
 - Ecosia search engine is now supported in safe search ([#5009]).
 
+### Changed
+
+- Upstream server URL domain names requirements has been relaxed and now follow
+  the same rules as their domain specifications.
+- Go version has been updated to [1.22.6][go-1.22.6].
+
 ### Fixed
 
 - Update Google safe search domains list ([#7155]).
@@ -43,6 +49,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
 [#7154]: https://github.com/AdguardTeam/AdGuardHome/pull/7154
 [#7155]: https://github.com/AdguardTeam/AdGuardHome/pull/7155
 
+[go-1.22.6]: https://groups.google.com/g/golang-announce/c/X4q_-Wf-5g4
+
 <!--
 NOTE: Add new changes ABOVE THIS COMMENT.
 -->
diff --git a/Makefile b/Makefile
index 142ebe86..dd7f2f1d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 # Makefile.  Bump this number every time a significant change is made to
 # this Makefile.
 #
-# AdGuard-Project-Version: 4
+# AdGuard-Project-Version: 6
 
 # Don't name these macros "GO" etc., because GNU Make apparently makes
 # them exported environment variables with the literal value of
@@ -25,9 +25,10 @@ CLIENT_DIR = client
 COMMIT = $$( git rev-parse --short HEAD )
 DIST_DIR = dist
 GOAMD64 = v1
-GOPROXY = https://goproxy.cn|https://proxy.golang.org|direct
+GOPROXY = https://proxy.golang.org|direct
 GOSUMDB = sum.golang.google.cn
-GOTOOLCHAIN = go1.22.5
+GOTOOLCHAIN = go1.22.6
+GOTELEMETRY = off
 GPG_KEY = devteam@adguard.com
 GPG_KEY_PASSPHRASE = not-a-real-password
 NPM = npm
@@ -61,9 +62,10 @@ ENV = env\
 	COMMIT='$(COMMIT)'\
 	DIST_DIR='$(DIST_DIR)'\
 	GO="$(GO.MACRO)"\
-	GOAMD64="$(GOAMD64)"\
+	GOAMD64='$(GOAMD64)'\
 	GOPROXY='$(GOPROXY)'\
 	GOSUMDB='$(GOSUMDB)'\
+	GOTELEMETRY='$(GOTELEMETRY)'\
 	GOTOOLCHAIN='$(GOTOOLCHAIN)'\
 	GPG_KEY='$(GPG_KEY)'\
 	GPG_KEY_PASSPHRASE='$(GPG_KEY_PASSPHRASE)'\
@@ -72,7 +74,12 @@ ENV = env\
 	SIGN='$(SIGN)'\
 	NEXTAPI='$(NEXTAPI)'\
 	VERBOSE="$(VERBOSE.MACRO)"\
-	VERSION='$(VERSION)'\
+	VERSION="$(VERSION)"\
+
+# Keep the line above blank.
+
+ENV_MISC = env\
+	VERBOSE="$(VERBOSE.MACRO)"\
 
 # Keep the line above blank.
 
@@ -101,23 +108,22 @@ js-deps:  ; $(NPM) $(NPM_INSTALL_FLAGS) ci
 js-lint:  ; $(NPM) $(NPM_FLAGS) run lint
 js-test:  ; $(NPM) $(NPM_FLAGS) run test
 
-go-bench: ; $(ENV) "$(SHELL)" ./scripts/make/go-bench.sh
-go-build: ; $(ENV) "$(SHELL)" ./scripts/make/go-build.sh
-go-deps:  ; $(ENV) "$(SHELL)" ./scripts/make/go-deps.sh
-go-fuzz:  ; $(ENV) "$(SHELL)" ./scripts/make/go-fuzz.sh
-go-lint:  ; $(ENV) "$(SHELL)" ./scripts/make/go-lint.sh
-go-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-tools.sh
-
+go-bench:     ; $(ENV) "$(SHELL)"    ./scripts/make/go-bench.sh
+go-build:     ; $(ENV) "$(SHELL)"    ./scripts/make/go-build.sh
+go-deps:      ; $(ENV) "$(SHELL)"    ./scripts/make/go-deps.sh
+go-env:       ; $(ENV) "$(GO.MACRO)" env
+go-fuzz:      ; $(ENV) "$(SHELL)"    ./scripts/make/go-fuzz.sh
+go-lint:      ; $(ENV) "$(SHELL)"    ./scripts/make/go-lint.sh
 # TODO(a.garipov): Think about making RACE='1' the default for all
 # targets.
-go-test:  ; $(ENV) RACE='1' "$(SHELL)" ./scripts/make/go-test.sh
-
-go-upd-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-upd-tools.sh
+go-test:      ; $(ENV) RACE='1' "$(SHELL)" ./scripts/make/go-test.sh
+go-tools:     ; $(ENV)          "$(SHELL)" ./scripts/make/go-tools.sh
+go-upd-tools: ; $(ENV)          "$(SHELL)" ./scripts/make/go-upd-tools.sh
 
 go-check: go-tools go-lint go-test
 
-# A quick check to make sure that all supported operating systems can be
-# typechecked and built successfully.
+# A quick check to make sure that all operating systems relevant to the
+# development of the project can be typechecked and built successfully.
 go-os-check:
 	env GOOS='darwin'  "$(GO.MACRO)" vet ./internal/...
 	env GOOS='freebsd' "$(GO.MACRO)" vet ./internal/...
@@ -125,7 +131,11 @@ go-os-check:
 	env GOOS='linux'   "$(GO.MACRO)" vet ./internal/...
 	env GOOS='windows' "$(GO.MACRO)" vet ./internal/...
 
+
 openapi-lint: ; cd ./openapi/ && $(YARN) test
 openapi-show: ; cd ./openapi/ && $(YARN) start
 
 txt-lint: ; $(ENV) "$(SHELL)" ./scripts/make/txt-lint.sh
+
+md-lint:  ; $(ENV_MISC) "$(SHELL)" ./scripts/make/md-lint.sh
+sh-lint:  ; $(ENV_MISC) "$(SHELL)" ./scripts/make/sh-lint.sh
diff --git a/bamboo-specs/release.yaml b/bamboo-specs/release.yaml
index 086c1d2d..77c8c099 100644
--- a/bamboo-specs/release.yaml
+++ b/bamboo-specs/release.yaml
@@ -8,7 +8,7 @@
 'variables':
     'channel': 'edge'
     'dockerFrontend': 'adguard/home-js-builder:2.0'
-    'dockerGo': 'adguard/go-builder:1.22.5--1'
+    'dockerGo': 'adguard/go-builder:1.22.6--1'
 
 'stages':
   - 'Build frontend':
@@ -266,7 +266,7 @@
         'variables':
             'channel': 'beta'
             'dockerFrontend': 'adguard/home-js-builder:2.0'
-            'dockerGo': 'adguard/go-builder:1.22.5--1'
+            'dockerGo': 'adguard/go-builder:1.22.6--1'
     # release-vX.Y.Z branches are the branches from which the actual final
     # release is built.
   - '^release-v[0-9]+\.[0-9]+\.[0-9]+':
@@ -282,4 +282,4 @@
         'variables':
             'channel': 'release'
             'dockerFrontend': 'adguard/home-js-builder:2.0'
-            'dockerGo': 'adguard/go-builder:1.22.5--1'
+            'dockerGo': 'adguard/go-builder:1.22.6--1'
diff --git a/bamboo-specs/test.yaml b/bamboo-specs/test.yaml
index d353ba55..bfbb934f 100644
--- a/bamboo-specs/test.yaml
+++ b/bamboo-specs/test.yaml
@@ -6,7 +6,7 @@
     'name': 'AdGuard Home - Build and run tests'
 'variables':
     'dockerFrontend': 'adguard/home-js-builder:2.0'
-    'dockerGo': 'adguard/go-builder:1.22.5--1'
+    'dockerGo': 'adguard/go-builder:1.22.6--1'
     'channel': 'development'
 
 'stages':
@@ -54,6 +54,7 @@
     'requirements':
       - 'adg-docker': 'true'
 
+# TODO(e.burkov):  Add the linting stage for markdown docs and shell scripts.
 'Test backend':
     'docker':
         'image': '${bamboo.dockerGo}'
@@ -195,5 +196,5 @@
         # may need to build a few of these.
         'variables':
             'dockerFrontend': 'adguard/home-js-builder:2.0'
-            'dockerGo': 'adguard/go-builder:1.22.5--1'
+            'dockerGo': 'adguard/go-builder:1.22.6--1'
             'channel': 'candidate'
diff --git a/go.mod b/go.mod
index f95ffd50..e0bddeaa 100644
--- a/go.mod
+++ b/go.mod
@@ -1,10 +1,10 @@
 module github.com/AdguardTeam/AdGuardHome
 
-go 1.22.5
+go 1.22.6
 
 require (
-	github.com/AdguardTeam/dnsproxy v0.72.3-0.20240806061520-4cc9af6704ef
-	github.com/AdguardTeam/golibs v0.25.2
+	github.com/AdguardTeam/dnsproxy v0.73.0
+	github.com/AdguardTeam/golibs v0.26.0
 	github.com/AdguardTeam/urlfilter v0.19.0
 	github.com/NYTimes/gziphandler v1.1.1
 	github.com/ameshkov/dnscrypt/v2 v2.3.0
@@ -32,10 +32,10 @@ require (
 	github.com/stretchr/testify v1.9.0
 	github.com/ti-mo/netfilter v0.5.2
 	go.etcd.io/bbolt v1.3.10
-	golang.org/x/crypto v0.25.0
-	golang.org/x/exp v0.0.0-20240707233637-46b078467d37
-	golang.org/x/net v0.27.0
-	golang.org/x/sys v0.22.0
+	golang.org/x/crypto v0.26.0
+	golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
+	golang.org/x/net v0.28.0
+	golang.org/x/sys v0.24.0
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 	gopkg.in/yaml.v3 v3.0.1
 	howett.net/plist v1.0.1
@@ -58,9 +58,9 @@ require (
 	github.com/quic-go/qpack v0.4.0 // indirect
 	github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
 	go.uber.org/mock v0.4.0 // indirect
-	golang.org/x/mod v0.19.0 // indirect
-	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
-	golang.org/x/tools v0.23.0 // indirect
+	golang.org/x/mod v0.20.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
+	golang.org/x/text v0.17.0 // indirect
+	golang.org/x/tools v0.24.0 // indirect
 	gonum.org/v1/gonum v0.15.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 09bf94b7..ef2f98a3 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
-github.com/AdguardTeam/dnsproxy v0.72.3-0.20240806061520-4cc9af6704ef h1:j6MtYGWnMOj5TdRFeLA/YmUuS4GKsatt1z3bmIJQtZ8=
-github.com/AdguardTeam/dnsproxy v0.72.3-0.20240806061520-4cc9af6704ef/go.mod h1:DCHTuklaAuvCgtZzpoA0TrqCdOBZJQnKjgKxbC9/kQ8=
-github.com/AdguardTeam/golibs v0.25.2 h1:4+c9LjAIdd9trRk71hXghJ5OL/VRosBm+/0dKH+H39U=
-github.com/AdguardTeam/golibs v0.25.2/go.mod h1:HaTyS2wCbxFudjht9N/+/Qf1b5cMad2BAYSwe7DPCXI=
+github.com/AdguardTeam/dnsproxy v0.73.0 h1:E1fxzosMqExZH8h7OJnKXLxyktcAFRJapLF4+nKULms=
+github.com/AdguardTeam/dnsproxy v0.73.0/go.mod h1:ZcvmyQY2EiX5B0yCTkiYTgtm+1lBWA0lajbEI9dOhW4=
+github.com/AdguardTeam/golibs v0.26.0 h1:uLL0XggEjB+87lL1tPpEAQNoKAlHDq5AyBUVWEgf63E=
+github.com/AdguardTeam/golibs v0.26.0/go.mod h1:iWdjXPCwmK2g2FKIb/OwEPnovSXeMqRhI8FWLxF5oxE=
 github.com/AdguardTeam/urlfilter v0.19.0 h1:q7eH13+yNETlpD/VD3u5rLQOripcUdEktqZFy+KiQLk=
 github.com/AdguardTeam/urlfilter v0.19.0/go.mod h1:+N54ZvxqXYLnXuvpaUhK2exDQW+djZBRSb6F6j0rkBY=
 github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
@@ -128,26 +128,26 @@ go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
 go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
-golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w=
-golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
+golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
-golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -158,19 +158,19 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
 golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
-golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
+golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
+golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ=
diff --git a/internal/dnsforward/config.go b/internal/dnsforward/config.go
index d0f2ca51..7b1fe1f7 100644
--- a/internal/dnsforward/config.go
+++ b/internal/dnsforward/config.go
@@ -427,8 +427,6 @@ func parseBogusNXDOMAIN(confBogusNXDOMAIN []string) (subnets []netip.Prefix, err
 	return subnets, nil
 }
 
-const defaultBlockedResponseTTL = 3600
-
 // initDefaultSettings initializes default settings if nothing
 // is configured
 func (s *Server) initDefaultSettings() {
diff --git a/internal/dnsforward/http_test.go b/internal/dnsforward/http_test.go
index 56daa4bf..e92da018 100644
--- a/internal/dnsforward/http_test.go
+++ b/internal/dnsforward/http_test.go
@@ -228,7 +228,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
 	}, {
 		name: "upstream_dns_bad",
 		wantSet: `validating dns config: upstream servers: parsing error at index 0: ` +
-			`cannot prepare the upstream: invalid address !!!: bad hostname "!!!": ` +
+			`cannot prepare the upstream: invalid address !!!: bad domain name "!!!": ` +
 			`bad top-level domain name label "!!!": bad top-level domain name label rune '!'`,
 	}, {
 		name: "bootstraps_bad",
diff --git a/internal/dnsforward/msg.go b/internal/dnsforward/msg.go
index f645ab90..e9f1f2d7 100644
--- a/internal/dnsforward/msg.go
+++ b/internal/dnsforward/msg.go
@@ -58,7 +58,7 @@ func (s *Server) genDNSFilterMessage(
 			return s.replyCompressed(req)
 		}
 
-		return s.newMsgNODATA(req)
+		return s.NewMsgNODATA(req)
 	}
 
 	switch res.Reason {
@@ -344,51 +344,6 @@ func (s *Server) makeResponseREFUSED(req *dns.Msg) *dns.Msg {
 	return s.reply(req, dns.RcodeRefused)
 }
 
-// newMsgNODATA returns a properly initialized NODATA response.
-//
-// See https://www.rfc-editor.org/rfc/rfc2308#section-2.2.
-func (s *Server) newMsgNODATA(req *dns.Msg) (resp *dns.Msg) {
-	resp = s.reply(req, dns.RcodeSuccess)
-	resp.Ns = s.genSOA(req)
-
-	return resp
-}
-
-func (s *Server) genSOA(request *dns.Msg) []dns.RR {
-	zone := ""
-	if len(request.Question) > 0 {
-		zone = request.Question[0].Name
-	}
-
-	soa := dns.SOA{
-		// values copied from verisign's nonexistent .com domain
-		// their exact values are not important in our use case because they are used for domain transfers between primary/secondary DNS servers
-		Refresh: 1800,
-		Retry:   900,
-		Expire:  604800,
-		Minttl:  86400,
-		// copied from AdGuard DNS
-		Ns:     "fake-for-negative-caching.adguard.com.",
-		Serial: 100500,
-		// rest is request-specific
-		Hdr: dns.RR_Header{
-			Name:   zone,
-			Rrtype: dns.TypeSOA,
-			Ttl:    s.dnsFilter.BlockedResponseTTL(),
-			Class:  dns.ClassINET,
-		},
-		Mbox: "hostmaster.", // zone will be appended later if it's not empty or "."
-	}
-	if soa.Hdr.Ttl == 0 {
-		soa.Hdr.Ttl = defaultBlockedResponseTTL
-	}
-	if len(zone) > 0 && zone[0] != '.' {
-		soa.Mbox += zone
-	}
-
-	return []dns.RR{&soa}
-}
-
 // type check
 var _ proxy.MessageConstructor = (*Server)(nil)
 
@@ -425,3 +380,52 @@ func (s *Server) NewMsgNOTIMPLEMENTED(req *dns.Msg) (resp *dns.Msg) {
 
 	return resp
 }
+
+// NewMsgNODATA implements the [proxy.MessageConstructor] interface for *Server.
+func (s *Server) NewMsgNODATA(req *dns.Msg) (resp *dns.Msg) {
+	resp = s.reply(req, dns.RcodeSuccess)
+	resp.Ns = s.genSOA(req)
+
+	return resp
+}
+
+func (s *Server) genSOA(req *dns.Msg) []dns.RR {
+	zone := ""
+	if len(req.Question) > 0 {
+		zone = req.Question[0].Name
+	}
+
+	const defaultBlockedResponseTTL = 3600
+
+	soa := dns.SOA{
+		// Values copied from verisign's nonexistent.com domain.
+		//
+		// Their exact values are not important in our use case because they are
+		// used for domain transfers between primary/secondary DNS servers.
+		Refresh: 1800,
+		Retry:   900,
+		Expire:  604800,
+		Minttl:  86400,
+		// copied from AdGuard DNS
+		Ns:     "fake-for-negative-caching.adguard.com.",
+		Serial: 100500,
+		// rest is request-specific
+		Hdr: dns.RR_Header{
+			Name:   zone,
+			Rrtype: dns.TypeSOA,
+			Ttl:    s.dnsFilter.BlockedResponseTTL(),
+			Class:  dns.ClassINET,
+		},
+		// zone will be appended later if it's not ".".
+		Mbox: "hostmaster.",
+	}
+	if soa.Hdr.Ttl == 0 {
+		soa.Hdr.Ttl = defaultBlockedResponseTTL
+	}
+
+	if zone != "." {
+		soa.Mbox += zone
+	}
+
+	return []dns.RR{&soa}
+}
diff --git a/internal/dnsforward/process.go b/internal/dnsforward/process.go
index 967956d0..1a3dbc2e 100644
--- a/internal/dnsforward/process.go
+++ b/internal/dnsforward/process.go
@@ -159,7 +159,7 @@ func (s *Server) processInitial(dctx *dnsContext) (rc resultCode) {
 	q := pctx.Req.Question[0]
 	qt := q.Qtype
 	if s.conf.AAAADisabled && qt == dns.TypeAAAA {
-		pctx.Res = s.newMsgNODATA(pctx.Req)
+		pctx.Res = s.NewMsgNODATA(pctx.Req)
 
 		return resultCodeFinish
 	}
diff --git a/internal/filtering/hashprefix/cache.go b/internal/filtering/hashprefix/cache.go
index 190f2116..7db2ae22 100644
--- a/internal/filtering/hashprefix/cache.go
+++ b/internal/filtering/hashprefix/cache.go
@@ -47,7 +47,6 @@ func fromCacheItem(item *cacheItem) (data []byte) {
 	data = binary.BigEndian.AppendUint64(data, uint64(expiry))
 
 	for _, v := range item.hashes {
-		// nolint:looppointer // The subslice of v is used for a copy.
 		data = append(data, v[:]...)
 	}
 
@@ -63,7 +62,6 @@ func (c *Checker) findInCache(
 
 	i := 0
 	for _, hash := range hashes {
-		// nolint:looppointer // The has subslice is used for a cache lookup.
 		data := c.cache.Get(hash[:prefixLen])
 		if data == nil {
 			hashes[i] = hash
@@ -98,7 +96,6 @@ func (c *Checker) storeInCache(hashesToRequest, respHashes []hostnameHash) {
 
 	for _, hash := range respHashes {
 		var pref prefix
-		// nolint:looppointer // The hash subslice is used for a copy.
 		copy(pref[:], hash[:])
 
 		hashToStore[pref] = append(hashToStore[pref], hash)
@@ -109,11 +106,9 @@ func (c *Checker) storeInCache(hashesToRequest, respHashes []hostnameHash) {
 	}
 
 	for _, hash := range hashesToRequest {
-		// nolint:looppointer // The hash subslice is used for a cache lookup.
 		val := c.cache.Get(hash[:prefixLen])
 		if val == nil {
 			var pref prefix
-			// nolint:looppointer // The hash subslice is used for a copy.
 			copy(pref[:], hash[:])
 
 			c.setCache(pref, nil)
diff --git a/internal/filtering/hashprefix/hashprefix.go b/internal/filtering/hashprefix/hashprefix.go
index fb1128e4..55795f9a 100644
--- a/internal/filtering/hashprefix/hashprefix.go
+++ b/internal/filtering/hashprefix/hashprefix.go
@@ -173,7 +173,6 @@ func (c *Checker) getQuestion(hashes []hostnameHash) (q string) {
 	b := &strings.Builder{}
 
 	for _, hash := range hashes {
-		// nolint:looppointer // The hash subslice is used for hex encoding.
 		stringutil.WriteToBuilder(b, hex.EncodeToString(hash[:prefixLen]), ".")
 	}
 
diff --git a/internal/tools/doc.go b/internal/tools/doc.go
deleted file mode 100644
index 422b3fef..00000000
--- a/internal/tools/doc.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Package tools and its main module are a nested internal module containing our
-// development tool dependencies.
-//
-// See https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module.
-package tools
diff --git a/internal/tools/go.mod b/internal/tools/go.mod
index 8376a908..e6cf3508 100644
--- a/internal/tools/go.mod
+++ b/internal/tools/go.mod
@@ -1,6 +1,6 @@
 module github.com/AdguardTeam/AdGuardHome/internal/tools
 
-go 1.22.4
+go 1.22.6
 
 require (
 	github.com/fzipp/gocyclo v0.6.0
@@ -9,27 +9,26 @@ require (
 	github.com/kisielk/errcheck v1.7.0
 	github.com/kyoh86/looppointer v0.2.1
 	github.com/securego/gosec/v2 v2.20.0
-	github.com/uudashr/gocognit v1.1.2
-	golang.org/x/tools v0.22.0
-	golang.org/x/vuln v1.1.2
-	honnef.co/go/tools v0.4.7
-	mvdan.cc/gofumpt v0.6.0
+	github.com/uudashr/gocognit v1.1.3
+	golang.org/x/tools v0.24.0
+	golang.org/x/vuln v1.1.3
+	honnef.co/go/tools v0.5.1
+	mvdan.cc/gofumpt v0.7.0
 	mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f
 )
 
 require (
-	github.com/BurntSushi/toml v1.4.0 // indirect
+	github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
 	github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
 	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/gookit/color v1.5.4 // indirect
 	github.com/kyoh86/nolint v0.0.1 // indirect
 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
-	golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
-	golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 // indirect
-	golang.org/x/mod v0.18.0 // indirect
-	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/sys v0.21.0 // indirect
-	golang.org/x/telemetry v0.0.0-20240701175443-4e29c7872ac1 // indirect
+	golang.org/x/exp/typeparams v0.0.0-20240808152545-0cdaa3abc0fa // indirect
+	golang.org/x/mod v0.20.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
+	golang.org/x/sys v0.24.0 // indirect
+	golang.org/x/telemetry v0.0.0-20240815150606-0693e6240b9b // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/internal/tools/go.sum b/internal/tools/go.sum
index 486bb004..1497c33e 100644
--- a/internal/tools/go.sum
+++ b/internal/tools/go.sum
@@ -1,15 +1,15 @@
-github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
-github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
 github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
 github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
 github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
 github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
 github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
 github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
+github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
 github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs=
@@ -50,69 +50,57 @@ github.com/securego/gosec/v2 v2.20.0 h1:z/d5qp1niWa2avgFyUIglYTYYuGq2LrJwNj1HRVX
 github.com/securego/gosec/v2 v2.20.0/go.mod h1:hkiArbBZLwK1cehBcg3oFWUlYPWTBffPwwJVWChu83o=
 github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI=
-github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k=
+github.com/uudashr/gocognit v1.1.3 h1:l+a111VcDbKfynh+airAy/DJQKaXh2m9vkoysMPSZyM=
+github.com/uudashr/gocognit v1.1.3/go.mod h1:aKH8/e8xbTRBwjbCkwZ8qt4l2EpKXl31KMHgSS+lZ2U=
 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
-golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8 h1:+ZJmEdDFzH5H0CnzOrwgbH3elHctfTecW9X0k2tkn5M=
-golang.org/x/exp/typeparams v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
+golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
+golang.org/x/exp/typeparams v0.0.0-20240808152545-0cdaa3abc0fa h1:54T+HVkPu4D3lltpEHyI3Fs2pG/GqjGkXLgyKOmifXk=
+golang.org/x/exp/typeparams v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
-golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
-golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
-golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/telemetry v0.0.0-20240701175443-4e29c7872ac1 h1:jveUVYFLPlIma1aZBg9rrUN+Dqk4e6QbVSGiZGwA/2Y=
-golang.org/x/telemetry v0.0.0-20240701175443-4e29c7872ac1/go.mod h1:n38mvGdgc4dA684EC4NwQwoPKSw4jyKw8/DgZHDA1Dk=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240815150606-0693e6240b9b h1:bqoSGda4GdIdppjxRPd2mhhJDviKUBPMaBDIZeHi4Po=
+golang.org/x/telemetry v0.0.0-20240815150606-0693e6240b9b/go.mod h1:m7R/r+o5h7UvF2JD9n2iLSGY4v8v+zNSyTJ6xynLrqs=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
 golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
-golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
-golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
-golang.org/x/vuln v1.1.2 h1:UkLxe+kAMcrNBpGrFbU0Mc5l7cX97P2nhy21wx5+Qbk=
-golang.org/x/vuln v1.1.2/go.mod h1:2o3fRKD8Uz9AraAL3lwd/grWBv+t+SeJnPcqBUJrY24=
+golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
+golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
+golang.org/x/vuln v1.1.3 h1:NPGnvPOTgnjBc9HTaUx+nj+EaUYxl5SJOWqaDYGaFYw=
+golang.org/x/vuln v1.1.3/go.mod h1:7Le6Fadm5FOqE9C926BCD0g12NWyhg7cxV4BwcPFuNY=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -120,9 +108,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
-honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0=
-mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=
-mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA=
+honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I=
+honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs=
+mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU=
+mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo=
 mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U=
 mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ=
diff --git a/internal/tools/tools.go b/internal/tools/tools.go
index a1a473ff..ff1c2b13 100644
--- a/internal/tools/tools.go
+++ b/internal/tools/tools.go
@@ -1,5 +1,9 @@
 //go:build tools
 
+// Package tools and its main module are a nested internal module containing our
+// development tool dependencies.
+//
+// See https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module.
 package tools
 
 import (
diff --git a/scripts/hooks/pre-commit b/scripts/hooks/pre-commit
index b0cce8d6..307f3ec6 100755
--- a/scripts/hooks/pre-commit
+++ b/scripts/hooks/pre-commit
@@ -6,7 +6,7 @@ set -e -f -u
 # Bump this number every time a significant change is made to this
 # script.
 #
-# AdGuard-Project-Version: 2
+# AdGuard-Project-Version: 3
 
 # TODO(a.garipov): Add pre-merge-commit.
 
@@ -56,13 +56,15 @@ prompt() {
 # Warn the programmer about unstaged changes and untracked files, but do
 # not fail the commit, because those changes might be temporary or for
 # a different branch.
+#
+# shellcheck disable=SC2016
 awk_prog='substr($2, 2, 1) != "." { print $9; } $1 == "?" { print $2; }'
 readonly awk_prog
 
 unstaged="$( git status --porcelain=2 | awk "$awk_prog" )"
 readonly unstaged
 
-if [ "$unstaged" != "" ]
+if [ "$unstaged" != '' ]
 then
 	printf 'WARNING: you have unstaged changes:\n\n%s\n\n' "$unstaged"
 	prompt
@@ -73,7 +75,7 @@ fi
 temp_todos="$( git grep -e 'TODO.*!!' -- ':!scripts/hooks/pre-commit' || : )"
 readonly temp_todos
 
-if [ "$temp_todos" != "" ]
+if [ "$temp_todos" != '' ]
 then
 	printf 'WARNING: you have temporary todos:\n\n%s\n\n' "$temp_todos"
 	prompt
@@ -82,22 +84,32 @@ fi
 verbose="${VERBOSE:-0}"
 readonly verbose
 
-if [ "$( git diff --cached --name-only -- 'client/*.js' )" ]
+if [ "$( git diff --cached --name-only -- 'client/*.js' || true )" != '' ]
 then
 	make VERBOSE="$verbose" js-lint js-test
 fi
 
-if [ "$( git diff --cached --name-only -- '*.go' '*.mod' '*.sh' 'Makefile' )" ]
+if [ "$( git diff --cached --name-only -- '*.go' '*.mod' 'Makefile' || true )" != '' ]
 then
 	make VERBOSE="$verbose" go-os-check go-lint go-test
 fi
 
-if [ "$( git diff --cached --name-only -- '*.md' '*.txt' '*.yaml' '*.yml' )" ]
+if [ "$( git diff --cached --name-only -- '*.md' || true )" != '' ]
+then
+	make VERBOSE="$verbose" md-lint
+fi
+
+if [ "$( git diff --cached --name-only -- '*.sh' || true )" != '' ]
+then
+	make VERBOSE="$verbose" sh-lint
+fi
+
+if [ "$( git diff --cached --name-only -- '*.md' '*.txt' '*.yaml' '*.yml' || true )" != '' ]
 then
 	make VERBOSE="$verbose" txt-lint
 fi
 
-if [ "$( git diff --cached --name-only -- './openapi/openapi.yaml' )" ]
+if [ "$( git diff --cached --name-only -- './openapi/openapi.yaml' || true )" != '' ]
 then
 	make VERBOSE="$verbose" openapi-lint
 fi
diff --git a/scripts/make/go-build.sh b/scripts/make/go-build.sh
index 48d68c00..71ccec87 100644
--- a/scripts/make/go-build.sh
+++ b/scripts/make/go-build.sh
@@ -91,6 +91,7 @@ elif [ "${GOMIPS:-}" != '' ]
 then
 	ldflags="${ldflags} -X ${version_pkg}.gomips=${GOMIPS}"
 fi
+readonly ldflags
 
 # Allow users to limit the build's parallelism.
 parallelism="${PARALLELISM:-}"
@@ -143,7 +144,7 @@ then
 fi
 
 "$go" build\
-	--ldflags "$ldflags"\
+	--ldflags="$ldflags"\
 	"$race_flags"\
 	"$tags_flags"\
 	--trimpath\
diff --git a/scripts/make/go-lint.sh b/scripts/make/go-lint.sh
index 83790fce..844b6278 100644
--- a/scripts/make/go-lint.sh
+++ b/scripts/make/go-lint.sh
@@ -3,7 +3,7 @@
 # This comment is used to simplify checking local copies of the script.  Bump
 # this number every time a significant change is made to this script.
 #
-# AdGuard-Project-Version: 5
+# AdGuard-Project-Version: 8
 
 verbose="${VERBOSE:-0}"
 readonly verbose
@@ -35,9 +35,12 @@ set -f -u
 # blocklist_imports is a simple check against unwanted packages.  The following
 # packages are banned:
 #
-#   *  Packages errors and log are replaced by our own packages in the
+#   *  Package errors is replaced by our own package in the
 #      github.com/AdguardTeam/golibs module.
 #
+#   *  Packages golang.org/x/exp/slices and golang.org/x/net/context have been
+#      moved into stdlib.
+#
 #   *  Package io/ioutil is soft-deprecated.
 #
 #   *  Package reflect is often an overkill, and for deep comparisons there are
@@ -51,10 +54,6 @@ set -f -u
 #
 #   *  Package unsafe is… unsafe.
 #
-#   *  Package golang.org/x/exp/slices has been moved into stdlib.
-#
-#   *  Package golang.org/x/net/context has been moved into stdlib.
-#
 # Currently, the only standard exception are files generated from protobuf
 # schemas, which use package reflect.  If your project needs more exceptions,
 # add and document them.
@@ -62,17 +61,17 @@ set -f -u
 # TODO(a.garipov): Add golibs/log.
 #
 # TODO(a.garipov): Add deprecated package golang.org/x/exp/maps once all
-# projects switch to Go 1.22.
+# projects switch to Go 1.23.
 blocklist_imports() {
 	git grep\
 		-e '[[:space:]]"errors"$'\
+		-e '[[:space:]]"golang.org/x/exp/slices"$'\
+		-e '[[:space:]]"golang.org/x/net/context"$'\
 		-e '[[:space:]]"io/ioutil"$'\
 		-e '[[:space:]]"log"$'\
 		-e '[[:space:]]"reflect"$'\
 		-e '[[:space:]]"sort"$'\
 		-e '[[:space:]]"unsafe"$'\
-		-e '[[:space:]]"golang.org/x/exp/slices"$'\
-		-e '[[:space:]]"golang.org/x/net/context"$'\
 		-n\
 		-- '*.go'\
 		':!*.pb.go'\
@@ -105,6 +104,7 @@ underscores() {
 			-e '_bsd.go'\
 			-e '_darwin.go'\
 			-e '_freebsd.go'\
+			-e '_generate.go'\
 			-e '_linux.go'\
 			-e '_next.go'\
 			-e '_openbsd.go'\
@@ -140,7 +140,7 @@ run_linter -e gofumpt --extra -e -l .
 
 # TODO(a.garipov): golint is deprecated, find a suitable replacement.
 
-run_linter "$GO" vet ./...
+run_linter "${GO:-go}" vet ./...
 
 run_linter govulncheck ./...
 
@@ -212,8 +212,6 @@ git ls-files -- 'Makefile' '*.conf' '*.go' '*.mod' '*.sh' '*.yaml' '*.yml'\
 	| xargs misspell --error\
 	| sed -e 's/^/misspell: /'
 
-run_linter looppointer ./...
-
 run_linter nilness ./...
 
 # TODO(a.garipov): Enable for all.
diff --git a/scripts/make/go-tools.sh b/scripts/make/go-tools.sh
index 9d705103..295659c9 100644
--- a/scripts/make/go-tools.sh
+++ b/scripts/make/go-tools.sh
@@ -3,7 +3,7 @@
 # This comment is used to simplify checking local copies of the script.  Bump
 # this number every time a significant change is made to this script.
 #
-# AdGuard-Project-Version: 3
+# AdGuard-Project-Version: 4
 
 verbose="${VERBOSE:-0}"
 readonly verbose
@@ -42,7 +42,6 @@ rm -f\
 	bin/gosec\
 	bin/govulncheck\
 	bin/ineffassign\
-	bin/looppointer\
 	bin/misspell\
 	bin/nilness\
 	bin/shadow\
@@ -66,7 +65,6 @@ env\
 	github.com/golangci/misspell/cmd/misspell\
 	github.com/gordonklaus/ineffassign\
 	github.com/kisielk/errcheck\
-	github.com/kyoh86/looppointer/cmd/looppointer\
 	github.com/securego/gosec/v2/cmd/gosec\
 	github.com/uudashr/gocognit/cmd/gocognit\
 	golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment\
diff --git a/scripts/make/go-upd-tools.sh b/scripts/make/go-upd-tools.sh
index 7486661d..787475ac 100644
--- a/scripts/make/go-upd-tools.sh
+++ b/scripts/make/go-upd-tools.sh
@@ -3,7 +3,7 @@
 # This comment is used to simplify checking local copies of the script.  Bump
 # this number every time a significant change is made to this script.
 #
-# AdGuard-Project-Version: 1
+# AdGuard-Project-Version: 2
 
 verbose="${VERBOSE:-0}"
 readonly verbose
@@ -29,5 +29,6 @@ go="${GO:-go}"
 readonly go
 
 cd ./internal/tools/
-"$go" get -u
+
+"$go" get -u "$x_flags"
 "$go" mod tidy
diff --git a/scripts/make/md-lint.sh b/scripts/make/md-lint.sh
new file mode 100644
index 00000000..4e2ca062
--- /dev/null
+++ b/scripts/make/md-lint.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# This comment is used to simplify checking local copies of the script.  Bump
+# this number every time a remarkable change is made to this script.
+#
+# AdGuard-Project-Version: 2
+
+verbose="${VERBOSE:-0}"
+readonly verbose
+
+set -e -f -u
+
+if [ "$verbose" -gt '0' ]
+then
+	set -x
+fi
+
+# NOTE: Adjust for your project.
+# markdownlint\
+# 	./README.md\
+# 	;
+
+# TODO(e.burkov):  Lint markdown documents within this project.
diff --git a/scripts/make/sh-lint.sh b/scripts/make/sh-lint.sh
new file mode 100644
index 00000000..ad0d5d9d
--- /dev/null
+++ b/scripts/make/sh-lint.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# This comment is used to simplify checking local copies of the script.  Bump
+# this number every time a remarkable change is made to this script.
+#
+# AdGuard-Project-Version: 2
+
+verbose="${VERBOSE:-0}"
+readonly verbose
+
+# Don't use -f, because we use globs in this script.
+set -e -u
+
+if [ "$verbose" -gt '0' ]
+then
+	set -x
+fi
+
+# NOTE: Adjust for your project.
+#
+# TODO(e.burkov):  Add build-docker.sh, build-release.sh and install.sh.
+shellcheck -e 'SC2250' -f 'gcc' -o 'all' -x --\
+	./scripts/hooks/*\
+	./scripts/snap/*\
+	./scripts/make/clean.sh\
+	./scripts/make/go-bench.sh\
+	./scripts/make/go-build.sh\
+	./scripts/make/go-deps.sh\
+	./scripts/make/go-fuzz.sh\
+	./scripts/make/go-lint.sh\
+	./scripts/make/go-test.sh\
+	./scripts/make/go-tools.sh\
+	./scripts/make/go-upd-tools.sh\
+	./scripts/make/helper.sh\
+	./scripts/make/md-lint.sh\
+	./scripts/make/sh-lint.sh\
+	./scripts/make/txt-lint.sh\
+	./scripts/make/version.sh\
+	;