Merge branch 'master' into 6703-adguardhome-sync
This commit is contained in:
commit
32bd78347c
|
@ -102,6 +102,9 @@
|
||||||
the best way. For crashes, please provide a full failure log.
|
the best way. For crashes, please provide a full failure log.
|
||||||
'label': 'Action'
|
'label': 'Action'
|
||||||
'value': |
|
'value': |
|
||||||
|
Replace the following command with the one you're calling or a
|
||||||
|
description of the failing action:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nslookup -debug -type=a 'www.example.com' '$YOUR_AGH_ADDRESS'
|
nslookup -debug -type=a 'www.example.com' '$YOUR_AGH_ADDRESS'
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'name': 'build'
|
'name': 'build'
|
||||||
|
|
||||||
'env':
|
'env':
|
||||||
'GO_VERSION': '1.20.12'
|
'GO_VERSION': '1.21.7'
|
||||||
'NODE_VERSION': '16'
|
'NODE_VERSION': '16'
|
||||||
|
|
||||||
'on':
|
'on':
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'name': 'lint'
|
'name': 'lint'
|
||||||
|
|
||||||
'env':
|
'env':
|
||||||
'GO_VERSION': '1.20.12'
|
'GO_VERSION': '1.21.7'
|
||||||
|
|
||||||
'on':
|
'on':
|
||||||
'push':
|
'push':
|
||||||
|
|
78
CHANGELOG.md
78
CHANGELOG.md
|
@ -14,18 +14,68 @@ and this project adheres to
|
||||||
<!--
|
<!--
|
||||||
## [v0.108.0] - TBA
|
## [v0.108.0] - TBA
|
||||||
|
|
||||||
## [v0.107.44] - 2023-12-20 (APPROX.)
|
## [v0.107.45] - 2024-03-05 (APPROX.)
|
||||||
|
|
||||||
See also the [v0.107.44 GitHub milestone][ms-v0.107.44].
|
See also the [v0.107.45 GitHub milestone][ms-v0.107.45].
|
||||||
|
|
||||||
[ms-v0.107.44]: https://github.com/AdguardTeam/AdGuardHome/milestone/79?closed=1
|
[ms-v0.107.45]: https://github.com/AdguardTeam/AdGuardHome/milestone/80?closed=1
|
||||||
|
|
||||||
NOTE: Add new changes BELOW THIS COMMENT.
|
NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Go version has been updated to prevent the possibility of exploiting the Go
|
||||||
|
vulnerabilities fixed in Go 1.21.6 and Go 1.21.7.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Etc timezones to the timezone list ([#6568]).
|
- Context menu item in the Query Log to add a Client to the Persistent client
|
||||||
|
list ([#6679]).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Starting with this release our scripts are using Go's [forward compatibility
|
||||||
|
mechanism][go-toolchain] for updating the Go version.
|
||||||
|
|
||||||
|
**Important note for porters:** This change means that if your `go` version
|
||||||
|
is 1.21+ but is different from the one required by AdGuard Home, the `go` tool
|
||||||
|
will automatically download the required version.
|
||||||
|
|
||||||
|
If you want to use the version installed on your builder, run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get go@$YOUR_VERSION
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
|
and call `make` with `GOTOOLCHAIN=local`.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
- Go 1.21 support. Future versions will require at least Go 1.22 to build.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Go 1.20 support, as it has reached end of life.
|
||||||
|
|
||||||
|
[#6679]: https://github.com/AdguardTeam/AdGuardHome/issues/6679
|
||||||
|
|
||||||
|
[go-toolchain]: https://go.dev/blog/toolchain
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NOTE: Add new changes ABOVE THIS COMMENT.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [v0.107.44] - 2024-02-06
|
||||||
|
|
||||||
|
See also the [v0.107.44 GitHub milestone][ms-v0.107.44].
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Timezones in the Etc/ area to the timezone list ([#6568]).
|
||||||
- The schema version of the configuration file to the output of running
|
- The schema version of the configuration file to the output of running
|
||||||
`AdGuardHome` (or `AdGuardHome.exe`) with `-v --version` command-line options
|
`AdGuardHome` (or `AdGuardHome.exe`) with `-v --version` command-line options
|
||||||
([#6545]).
|
([#6545]).
|
||||||
|
@ -34,8 +84,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- The bootstrapped upstream addresses now updated according to the TTL of the
|
- The bootstrapped upstream addresses are now updated according to the TTL of
|
||||||
bootstrap DNS response ([#6321]).
|
the bootstrap DNS response ([#6321]).
|
||||||
- Logging level of timeout errors is now `error` instead of `debug` ([#6574]).
|
- Logging level of timeout errors is now `error` instead of `debug` ([#6574]).
|
||||||
- The field `"upstream_mode"` in `POST /control/dns_config` and
|
- The field `"upstream_mode"` in `POST /control/dns_config` and
|
||||||
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
|
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
|
||||||
|
@ -45,8 +95,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
|
||||||
|
|
||||||
In this release, the schema version has changed from 27 to 28.
|
In this release, the schema version has changed from 27 to 28.
|
||||||
|
|
||||||
- The new property `clients.persistent.*.uid`, which is unique identifier of the
|
- The new property `clients.persistent.*.uid`, which is a unique identifier of
|
||||||
persistent client.
|
the persistent client.
|
||||||
- The properties `dns.all_servers` and `dns.fastest_addr` were removed, their
|
- The properties `dns.all_servers` and `dns.fastest_addr` were removed, their
|
||||||
values migrated to newly added field `dns.upstream_mode` that describes the
|
values migrated to newly added field `dns.upstream_mode` that describes the
|
||||||
logic through which upstreams will be used. See also a [Wiki
|
logic through which upstreams will be used. See also a [Wiki
|
||||||
|
@ -100,12 +150,9 @@ In this release, the schema version has changed from 27 to 28.
|
||||||
[#6584]: https://github.com/AdguardTeam/AdGuardHome/issues/6584
|
[#6584]: https://github.com/AdguardTeam/AdGuardHome/issues/6584
|
||||||
[#6644]: https://github.com/AdguardTeam/AdGuardHome/issues/6644
|
[#6644]: https://github.com/AdguardTeam/AdGuardHome/issues/6644
|
||||||
|
|
||||||
|
[ms-v0.107.44]: https://github.com/AdguardTeam/AdGuardHome/milestone/79?closed=1
|
||||||
[wiki-config]: https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration
|
[wiki-config]: https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration
|
||||||
|
|
||||||
<!--
|
|
||||||
NOTE: Add new changes ABOVE THIS COMMENT.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [v0.107.43] - 2023-12-11
|
## [v0.107.43] - 2023-12-11
|
||||||
|
@ -2752,11 +2799,12 @@ See also the [v0.104.2 GitHub milestone][ms-v0.104.2].
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.44...HEAD
|
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.45...HEAD
|
||||||
[v0.107.44]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.43...v0.107.44
|
[v0.107.45]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.44...v0.107.45
|
||||||
-->
|
-->
|
||||||
|
|
||||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.43...HEAD
|
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.44...HEAD
|
||||||
|
[v0.107.44]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.43...v0.107.44
|
||||||
[v0.107.43]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.42...v0.107.43
|
[v0.107.43]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.42...v0.107.43
|
||||||
[v0.107.42]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.41...v0.107.42
|
[v0.107.42]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.41...v0.107.42
|
||||||
[v0.107.41]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.40...v0.107.41
|
[v0.107.41]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.40...v0.107.41
|
||||||
|
|
19
Makefile
19
Makefile
|
@ -8,7 +8,7 @@
|
||||||
# Makefile. Bump this number every time a significant change is made to
|
# Makefile. Bump this number every time a significant change is made to
|
||||||
# this Makefile.
|
# this Makefile.
|
||||||
#
|
#
|
||||||
# AdGuard-Project-Version: 2
|
# AdGuard-Project-Version: 4
|
||||||
|
|
||||||
# Don't name these macros "GO" etc., because GNU Make apparently makes
|
# Don't name these macros "GO" etc., because GNU Make apparently makes
|
||||||
# them exported environment variables with the literal value of
|
# them exported environment variables with the literal value of
|
||||||
|
@ -27,6 +27,7 @@ DIST_DIR = dist
|
||||||
GOAMD64 = v1
|
GOAMD64 = v1
|
||||||
GOPROXY = https://goproxy.cn|https://proxy.golang.org|direct
|
GOPROXY = https://goproxy.cn|https://proxy.golang.org|direct
|
||||||
GOSUMDB = sum.golang.google.cn
|
GOSUMDB = sum.golang.google.cn
|
||||||
|
GOTOOLCHAIN = go1.21.7
|
||||||
GPG_KEY = devteam@adguard.com
|
GPG_KEY = devteam@adguard.com
|
||||||
GPG_KEY_PASSPHRASE = not-a-real-password
|
GPG_KEY_PASSPHRASE = not-a-real-password
|
||||||
NPM = npm
|
NPM = npm
|
||||||
|
@ -56,15 +57,16 @@ BUILD_RELEASE_DEPS_0 = deps js-build
|
||||||
BUILD_RELEASE_DEPS_1 = go-deps
|
BUILD_RELEASE_DEPS_1 = go-deps
|
||||||
|
|
||||||
ENV = env\
|
ENV = env\
|
||||||
COMMIT='$(COMMIT)'\
|
|
||||||
CHANNEL='$(CHANNEL)'\
|
CHANNEL='$(CHANNEL)'\
|
||||||
GPG_KEY='$(GPG_KEY)'\
|
COMMIT='$(COMMIT)'\
|
||||||
GPG_KEY_PASSPHRASE='$(GPG_KEY_PASSPHRASE)'\
|
|
||||||
DIST_DIR='$(DIST_DIR)'\
|
DIST_DIR='$(DIST_DIR)'\
|
||||||
GO="$(GO.MACRO)"\
|
GO="$(GO.MACRO)"\
|
||||||
GOAMD64="$(GOAMD64)"\
|
GOAMD64="$(GOAMD64)"\
|
||||||
GOPROXY='$(GOPROXY)'\
|
GOPROXY='$(GOPROXY)'\
|
||||||
GOSUMDB='$(GOSUMDB)'\
|
GOSUMDB='$(GOSUMDB)'\
|
||||||
|
GOTOOLCHAIN='$(GOTOOLCHAIN)'\
|
||||||
|
GPG_KEY='$(GPG_KEY)'\
|
||||||
|
GPG_KEY_PASSPHRASE='$(GPG_KEY_PASSPHRASE)'\
|
||||||
PATH="$${PWD}/bin:$$( "$(GO.MACRO)" env GOPATH )/bin:$${PATH}"\
|
PATH="$${PWD}/bin:$$( "$(GO.MACRO)" env GOPATH )/bin:$${PATH}"\
|
||||||
RACE='$(RACE)'\
|
RACE='$(RACE)'\
|
||||||
SIGN='$(SIGN)'\
|
SIGN='$(SIGN)'\
|
||||||
|
@ -117,6 +119,8 @@ go-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-tools.sh
|
||||||
# targets.
|
# targets.
|
||||||
go-test: ; $(ENV) RACE='1' "$(SHELL)" ./scripts/make/go-test.sh
|
go-test: ; $(ENV) RACE='1' "$(SHELL)" ./scripts/make/go-test.sh
|
||||||
|
|
||||||
|
go-upd-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-upd-tools.sh
|
||||||
|
|
||||||
go-check: go-tools go-lint go-test
|
go-check: go-tools go-lint go-test
|
||||||
|
|
||||||
# A quick check to make sure that all supported operating systems can be
|
# A quick check to make sure that all supported operating systems can be
|
||||||
|
@ -132,10 +136,3 @@ openapi-lint: ; cd ./openapi/ && $(YARN) test
|
||||||
openapi-show: ; cd ./openapi/ && $(YARN) start
|
openapi-show: ; cd ./openapi/ && $(YARN) start
|
||||||
|
|
||||||
txt-lint: ; $(ENV) "$(SHELL)" ./scripts/make/txt-lint.sh
|
txt-lint: ; $(ENV) "$(SHELL)" ./scripts/make/txt-lint.sh
|
||||||
|
|
||||||
# TODO(a.garipov): Consider adding to scripts/ and the common project
|
|
||||||
# structure.
|
|
||||||
go-upd-tools:
|
|
||||||
cd ./internal/tools/ &&\
|
|
||||||
"$(GO.MACRO)" get -u &&\
|
|
||||||
"$(GO.MACRO)" mod tidy
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
# Make sure to sync any changes with the branch overrides below.
|
# Make sure to sync any changes with the branch overrides below.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'edge'
|
'channel': 'edge'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
|
|
||||||
'stages':
|
'stages':
|
||||||
- 'Build frontend':
|
- 'Build frontend':
|
||||||
|
@ -272,7 +272,7 @@
|
||||||
# need to build a few of these.
|
# need to build a few of these.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'beta'
|
'channel': 'beta'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
# release-vX.Y.Z branches are the branches from which the actual final
|
# release-vX.Y.Z branches are the branches from which the actual final
|
||||||
# release is built.
|
# release is built.
|
||||||
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
|
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
|
||||||
|
@ -287,4 +287,4 @@
|
||||||
# are the ones that actually get released.
|
# are the ones that actually get released.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'release'
|
'channel': 'release'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
# Make sure to sync any changes with the branch overrides below.
|
# Make sure to sync any changes with the branch overrides below.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'edge'
|
'channel': 'edge'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
'snapcraftChannel': 'edge'
|
'snapcraftChannel': 'edge'
|
||||||
|
|
||||||
'stages':
|
'stages':
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
# need to build a few of these.
|
# need to build a few of these.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'beta'
|
'channel': 'beta'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
'snapcraftChannel': 'beta'
|
'snapcraftChannel': 'beta'
|
||||||
# release-vX.Y.Z branches are the branches from which the actual final
|
# release-vX.Y.Z branches are the branches from which the actual final
|
||||||
# release is built.
|
# release is built.
|
||||||
|
@ -207,5 +207,5 @@
|
||||||
# are the ones that actually get released.
|
# are the ones that actually get released.
|
||||||
'variables':
|
'variables':
|
||||||
'channel': 'release'
|
'channel': 'release'
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
'snapcraftChannel': 'candidate'
|
'snapcraftChannel': 'candidate'
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
'key': 'AHBRTSPECS'
|
'key': 'AHBRTSPECS'
|
||||||
'name': 'AdGuard Home - Build and run tests'
|
'name': 'AdGuard Home - Build and run tests'
|
||||||
'variables':
|
'variables':
|
||||||
'dockerGo': 'adguard/golang-ubuntu:7.6'
|
'dockerGo': 'adguard/golang-ubuntu:8.0'
|
||||||
|
|
||||||
'stages':
|
'stages':
|
||||||
- 'Tests':
|
- 'Tests':
|
||||||
|
|
|
@ -236,6 +236,7 @@
|
||||||
"updated_upstream_dns_toast": "Upstream servers successfully saved",
|
"updated_upstream_dns_toast": "Upstream servers successfully saved",
|
||||||
"dns_test_ok_toast": "Specified DNS servers are working correctly",
|
"dns_test_ok_toast": "Specified DNS servers are working correctly",
|
||||||
"dns_test_not_ok_toast": "Server \"{{key}}\": could not be used, please check that you've written it correctly",
|
"dns_test_not_ok_toast": "Server \"{{key}}\": could not be used, please check that you've written it correctly",
|
||||||
|
"dns_test_parsing_error_toast": "Section {{section}}: line {{line}}: could not be used, please check that you've written it correctly",
|
||||||
"dns_test_warning_toast": "Upstream \"{{key}}\" does not respond to test requests and may not work properly",
|
"dns_test_warning_toast": "Upstream \"{{key}}\" does not respond to test requests and may not work properly",
|
||||||
"unblock": "Unblock",
|
"unblock": "Unblock",
|
||||||
"block": "Block",
|
"block": "Block",
|
||||||
|
@ -243,6 +244,7 @@
|
||||||
"allow_this_client": "Allow this client",
|
"allow_this_client": "Allow this client",
|
||||||
"block_for_this_client_only": "Block for this client only",
|
"block_for_this_client_only": "Block for this client only",
|
||||||
"unblock_for_this_client_only": "Unblock for this client only",
|
"unblock_for_this_client_only": "Unblock for this client only",
|
||||||
|
"add_persistent_client": "Add as persistent client",
|
||||||
"time_table_header": "Time",
|
"time_table_header": "Time",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"domain_name_table_header": "Domain name",
|
"domain_name_table_header": "Domain name",
|
||||||
|
@ -465,6 +467,7 @@
|
||||||
"form_add_id": "Add identifier",
|
"form_add_id": "Add identifier",
|
||||||
"form_client_name": "Enter client name",
|
"form_client_name": "Enter client name",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"client_name": "Client {{id}}",
|
||||||
"client_global_settings": "Use global settings",
|
"client_global_settings": "Use global settings",
|
||||||
"client_deleted": "Client \"{{key}}\" successfully deleted",
|
"client_deleted": "Client \"{{key}}\" successfully deleted",
|
||||||
"client_added": "Client \"{{key}}\" successfully added",
|
"client_added": "Client \"{{key}}\" successfully added",
|
||||||
|
|
|
@ -403,6 +403,11 @@ export const testUpstream = (
|
||||||
const message = upstreamResponse[key];
|
const message = upstreamResponse[key];
|
||||||
if (message.startsWith('WARNING:')) {
|
if (message.startsWith('WARNING:')) {
|
||||||
dispatch(addErrorToast({ error: i18next.t('dns_test_warning_toast', { key }) }));
|
dispatch(addErrorToast({ error: i18next.t('dns_test_warning_toast', { key }) }));
|
||||||
|
} else if (message.endsWith(': parsing error')) {
|
||||||
|
const info = message.substring(0, message.indexOf(':'));
|
||||||
|
const [sectionKey, line] = info.split(' ');
|
||||||
|
const section = i18next.t(sectionKey);
|
||||||
|
dispatch(addErrorToast({ error: i18next.t('dns_test_parsing_error_toast', { section, line }) }));
|
||||||
} else if (message !== 'OK') {
|
} else if (message !== 'OK') {
|
||||||
dispatch(addErrorToast({ error: i18next.t('dns_test_not_ok_toast', { key }) }));
|
dispatch(addErrorToast({ error: i18next.t('dns_test_not_ok_toast', { key }) }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ ReactModal.setAppElement('#root');
|
||||||
const MODAL_TYPE_TO_TITLE_TYPE_MAP = {
|
const MODAL_TYPE_TO_TITLE_TYPE_MAP = {
|
||||||
[MODAL_TYPE.EDIT_FILTERS]: 'edit',
|
[MODAL_TYPE.EDIT_FILTERS]: 'edit',
|
||||||
[MODAL_TYPE.ADD_FILTERS]: 'new',
|
[MODAL_TYPE.ADD_FILTERS]: 'new',
|
||||||
|
[MODAL_TYPE.EDIT_CLIENT]: 'edit',
|
||||||
|
[MODAL_TYPE.ADD_CLIENT]: 'new',
|
||||||
[MODAL_TYPE.SELECT_MODAL_TYPE]: 'new',
|
[MODAL_TYPE.SELECT_MODAL_TYPE]: 'new',
|
||||||
[MODAL_TYPE.CHOOSE_FILTERING_LIST]: 'choose',
|
[MODAL_TYPE.CHOOSE_FILTERING_LIST]: 'choose',
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
import propTypes from 'prop-types';
|
import propTypes from 'prop-types';
|
||||||
|
|
||||||
import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
|
import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
|
||||||
|
@ -25,12 +25,14 @@ const ClientCell = ({
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const history = useHistory();
|
||||||
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
|
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
|
||||||
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
|
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
|
||||||
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
const allowedСlients = useSelector((state) => state.access.allowed_clients, shallowEqual);
|
||||||
const [isOptionsOpened, setOptionsOpened] = useState(false);
|
const [isOptionsOpened, setOptionsOpened] = useState(false);
|
||||||
|
|
||||||
const autoClient = autoClients.find((autoClient) => autoClient.name === client);
|
const autoClient = autoClients.find((autoClient) => autoClient.name === client);
|
||||||
|
const clients = useSelector((state) => state.dashboard.clients);
|
||||||
const source = autoClient?.source;
|
const source = autoClient?.source;
|
||||||
const whoisAvailable = client_info && Object.keys(client_info.whois).length > 0;
|
const whoisAvailable = client_info && Object.keys(client_info.whois).length > 0;
|
||||||
const clientName = client_info?.name || client_id;
|
const clientName = client_info?.name || client_id;
|
||||||
|
@ -55,6 +57,8 @@ const ClientCell = ({
|
||||||
|
|
||||||
const isFiltered = checkFiltered(reason);
|
const isFiltered = checkFiltered(reason);
|
||||||
|
|
||||||
|
const clientIds = clients.map((c) => c.ids).flat();
|
||||||
|
|
||||||
const nameClass = classNames('w-90 o-hidden d-flex flex-column', {
|
const nameClass = classNames('w-90 o-hidden d-flex flex-column', {
|
||||||
'mt-2': isDetailed && !client_info?.name && !whoisAvailable,
|
'mt-2': isDetailed && !client_info?.name && !whoisAvailable,
|
||||||
'white-space--nowrap': isDetailed,
|
'white-space--nowrap': isDetailed,
|
||||||
|
@ -66,7 +70,6 @@ const ClientCell = ({
|
||||||
|
|
||||||
const renderBlockingButton = (isFiltered, domain) => {
|
const renderBlockingButton = (isFiltered, domain) => {
|
||||||
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
|
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
|
||||||
const clients = useSelector((state) => state.dashboard.clients);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
confirmMessage,
|
confirmMessage,
|
||||||
|
@ -118,6 +121,15 @@ const ClientCell = ({
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (!clientIds.includes(client)) {
|
||||||
|
BUTTON_OPTIONS.push({
|
||||||
|
name: 'add_persistent_client',
|
||||||
|
onClick: () => {
|
||||||
|
history.push(`/#clients?clientId=${client}`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const getOptions = (options) => {
|
const getOptions = (options) => {
|
||||||
if (options.length === 0) {
|
if (options.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import React, { useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { useHistory, useLocation } from 'react-router-dom';
|
||||||
import ReactTable from 'react-table';
|
import ReactTable from 'react-table';
|
||||||
|
|
||||||
import { getAllBlockedServices, getBlockedServices } from '../../../../actions/services';
|
import { getAllBlockedServices, getBlockedServices } from '../../../../actions/services';
|
||||||
|
@ -39,8 +40,12 @@ const ClientsTable = ({
|
||||||
}) => {
|
}) => {
|
||||||
const [t] = useTranslation();
|
const [t] = useTranslation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const location = useLocation();
|
||||||
|
const history = useHistory();
|
||||||
const services = useSelector((store) => store?.services);
|
const services = useSelector((store) => store?.services);
|
||||||
const globalSettings = useSelector((store) => store?.settings.settingsList) || {};
|
const globalSettings = useSelector((store) => store?.settings.settingsList) || {};
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const clientId = params.get('clientId');
|
||||||
|
|
||||||
const { safesearch } = globalSettings;
|
const { safesearch } = globalSettings;
|
||||||
|
|
||||||
|
@ -48,6 +53,12 @@ const ClientsTable = ({
|
||||||
dispatch(getAllBlockedServices());
|
dispatch(getAllBlockedServices());
|
||||||
dispatch(getBlockedServices());
|
dispatch(getBlockedServices());
|
||||||
dispatch(initSettings());
|
dispatch(initSettings());
|
||||||
|
|
||||||
|
if (clientId) {
|
||||||
|
toggleClientModal({
|
||||||
|
type: MODAL_TYPE.ADD_CLIENT,
|
||||||
|
});
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleFormAdd = (values) => {
|
const handleFormAdd = (values) => {
|
||||||
|
@ -85,11 +96,15 @@ const ClientsTable = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modalType === MODAL_TYPE.EDIT_FILTERS) {
|
if (modalType === MODAL_TYPE.EDIT_CLIENT) {
|
||||||
handleFormUpdate(config, modalClientName);
|
handleFormUpdate(config, modalClientName);
|
||||||
} else {
|
} else {
|
||||||
handleFormAdd(config);
|
handleFormAdd(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientId) {
|
||||||
|
history.push('/#clients');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOptionsWithLabels = (options) => (
|
const getOptionsWithLabels = (options) => (
|
||||||
|
@ -133,6 +148,14 @@ const ClientsTable = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
toggleClientModal();
|
||||||
|
|
||||||
|
if (clientId) {
|
||||||
|
history.push('/#clients');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
Header: t('table_client'),
|
Header: t('table_client'),
|
||||||
|
@ -298,7 +321,7 @@ const ClientsTable = ({
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-icon btn-outline-primary btn-sm mr-2"
|
className="btn btn-icon btn-outline-primary btn-sm mr-2"
|
||||||
onClick={() => toggleClientModal({
|
onClick={() => toggleClientModal({
|
||||||
type: MODAL_TYPE.EDIT_FILTERS,
|
type: MODAL_TYPE.EDIT_CLIENT,
|
||||||
name: clientName,
|
name: clientName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -371,12 +394,13 @@ const ClientsTable = ({
|
||||||
<Modal
|
<Modal
|
||||||
isModalOpen={isModalOpen}
|
isModalOpen={isModalOpen}
|
||||||
modalType={modalType}
|
modalType={modalType}
|
||||||
toggleClientModal={toggleClientModal}
|
handleClose={handleClose}
|
||||||
currentClientData={currentClientData}
|
currentClientData={currentClientData}
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
processingAdding={processingAdding}
|
processingAdding={processingAdding}
|
||||||
processingUpdating={processingUpdating}
|
processingUpdating={processingUpdating}
|
||||||
tagsOptions={tagsOptions}
|
tagsOptions={tagsOptions}
|
||||||
|
clientId={clientId}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -147,7 +147,7 @@ let Form = (props) => {
|
||||||
useGlobalSettings,
|
useGlobalSettings,
|
||||||
useGlobalServices,
|
useGlobalServices,
|
||||||
blockedServicesSchedule,
|
blockedServicesSchedule,
|
||||||
toggleClientModal,
|
handleClose,
|
||||||
processingAdding,
|
processingAdding,
|
||||||
processingUpdating,
|
processingUpdating,
|
||||||
invalid,
|
invalid,
|
||||||
|
@ -427,7 +427,7 @@ let Form = (props) => {
|
||||||
disabled={submitting}
|
disabled={submitting}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
reset();
|
reset();
|
||||||
toggleClientModal();
|
handleClose();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Trans>cancel_btn</Trans>
|
<Trans>cancel_btn</Trans>
|
||||||
|
@ -456,7 +456,7 @@ Form.propTypes = {
|
||||||
reset: PropTypes.func.isRequired,
|
reset: PropTypes.func.isRequired,
|
||||||
change: PropTypes.func.isRequired,
|
change: PropTypes.func.isRequired,
|
||||||
submitting: PropTypes.bool.isRequired,
|
submitting: PropTypes.bool.isRequired,
|
||||||
toggleClientModal: PropTypes.func.isRequired,
|
handleClose: PropTypes.func.isRequired,
|
||||||
useGlobalSettings: PropTypes.bool,
|
useGlobalSettings: PropTypes.bool,
|
||||||
useGlobalServices: PropTypes.bool,
|
useGlobalServices: PropTypes.bool,
|
||||||
blockedServicesSchedule: PropTypes.object,
|
blockedServicesSchedule: PropTypes.object,
|
||||||
|
|
|
@ -6,7 +6,9 @@ import ReactModal from 'react-modal';
|
||||||
import { MODAL_TYPE } from '../../../helpers/constants';
|
import { MODAL_TYPE } from '../../../helpers/constants';
|
||||||
import Form from './Form';
|
import Form from './Form';
|
||||||
|
|
||||||
const getInitialData = (initial) => {
|
const getInitialData = ({
|
||||||
|
initial, modalType, clientId, clientName,
|
||||||
|
}) => {
|
||||||
if (initial && initial.blocked_services) {
|
if (initial && initial.blocked_services) {
|
||||||
const { blocked_services } = initial;
|
const { blocked_services } = initial;
|
||||||
const blocked = {};
|
const blocked = {};
|
||||||
|
@ -21,46 +23,60 @@ const getInitialData = (initial) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modalType !== MODAL_TYPE.EDIT_CLIENT && clientId) {
|
||||||
|
return {
|
||||||
|
...initial,
|
||||||
|
name: clientName,
|
||||||
|
ids: [clientId],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return initial;
|
return initial;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Modal = (props) => {
|
const Modal = ({
|
||||||
const {
|
|
||||||
isModalOpen,
|
isModalOpen,
|
||||||
modalType,
|
modalType,
|
||||||
currentClientData,
|
currentClientData,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
toggleClientModal,
|
handleClose,
|
||||||
processingAdding,
|
processingAdding,
|
||||||
processingUpdating,
|
processingUpdating,
|
||||||
tagsOptions,
|
tagsOptions,
|
||||||
} = props;
|
clientId,
|
||||||
const initialData = getInitialData(currentClientData);
|
t,
|
||||||
|
}) => {
|
||||||
|
const initialData = getInitialData({
|
||||||
|
initial: currentClientData,
|
||||||
|
modalType,
|
||||||
|
clientId,
|
||||||
|
clientName: t('client_name', { id: clientId }),
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactModal
|
<ReactModal
|
||||||
className="Modal__Bootstrap modal-dialog modal-dialog-centered modal-dialog--clients"
|
className="Modal__Bootstrap modal-dialog modal-dialog-centered modal-dialog--clients"
|
||||||
closeTimeoutMS={0}
|
closeTimeoutMS={0}
|
||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
onRequestClose={() => toggleClientModal()}
|
onRequestClose={handleClose}
|
||||||
>
|
>
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h4 className="modal-title">
|
<h4 className="modal-title">
|
||||||
{modalType === MODAL_TYPE.EDIT_FILTERS ? (
|
{modalType === MODAL_TYPE.EDIT_CLIENT ? (
|
||||||
<Trans>client_edit</Trans>
|
<Trans>client_edit</Trans>
|
||||||
) : (
|
) : (
|
||||||
<Trans>client_new</Trans>
|
<Trans>client_new</Trans>
|
||||||
)}
|
)}
|
||||||
</h4>
|
</h4>
|
||||||
<button type="button" className="close" onClick={() => toggleClientModal()}>
|
<button type="button" className="close" onClick={handleClose}>
|
||||||
<span className="sr-only">Close</span>
|
<span className="sr-only">Close</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<Form
|
<Form
|
||||||
initialValues={{ ...initialData }}
|
initialValues={{ ...initialData }}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
toggleClientModal={toggleClientModal}
|
handleClose={handleClose}
|
||||||
processingAdding={processingAdding}
|
processingAdding={processingAdding}
|
||||||
processingUpdating={processingUpdating}
|
processingUpdating={processingUpdating}
|
||||||
tagsOptions={tagsOptions}
|
tagsOptions={tagsOptions}
|
||||||
|
@ -75,10 +91,12 @@ Modal.propTypes = {
|
||||||
modalType: PropTypes.string.isRequired,
|
modalType: PropTypes.string.isRequired,
|
||||||
currentClientData: PropTypes.object.isRequired,
|
currentClientData: PropTypes.object.isRequired,
|
||||||
handleSubmit: PropTypes.func.isRequired,
|
handleSubmit: PropTypes.func.isRequired,
|
||||||
toggleClientModal: PropTypes.func.isRequired,
|
handleClose: PropTypes.func.isRequired,
|
||||||
processingAdding: PropTypes.bool.isRequired,
|
processingAdding: PropTypes.bool.isRequired,
|
||||||
processingUpdating: PropTypes.bool.isRequired,
|
processingUpdating: PropTypes.bool.isRequired,
|
||||||
tagsOptions: PropTypes.array.isRequired,
|
tagsOptions: PropTypes.array.isRequired,
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
|
clientId: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTranslation()(Modal);
|
export default withTranslation()(Modal);
|
||||||
|
|
|
@ -182,6 +182,8 @@ export const MODAL_TYPE = {
|
||||||
EDIT_REWRITE: 'EDIT_REWRITE',
|
EDIT_REWRITE: 'EDIT_REWRITE',
|
||||||
EDIT_LEASE: 'EDIT_LEASE',
|
EDIT_LEASE: 'EDIT_LEASE',
|
||||||
ADD_LEASE: 'ADD_LEASE',
|
ADD_LEASE: 'ADD_LEASE',
|
||||||
|
ADD_CLIENT: 'ADD_CLIENT',
|
||||||
|
EDIT_CLIENT: 'EDIT_CLIENT',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CLIENT_ID = {
|
export const CLIENT_ID = {
|
||||||
|
|
28
go.mod
28
go.mod
|
@ -1,10 +1,10 @@
|
||||||
module github.com/AdguardTeam/AdGuardHome
|
module github.com/AdguardTeam/AdGuardHome
|
||||||
|
|
||||||
go 1.20
|
go 1.21.7
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/AdguardTeam/dnsproxy v0.63.1
|
github.com/AdguardTeam/dnsproxy v0.65.0
|
||||||
github.com/AdguardTeam/golibs v0.19.0
|
github.com/AdguardTeam/golibs v0.20.0
|
||||||
github.com/AdguardTeam/urlfilter v0.17.3
|
github.com/AdguardTeam/urlfilter v0.17.3
|
||||||
github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/ameshkov/dnscrypt/v2 v2.2.7
|
github.com/ameshkov/dnscrypt/v2 v2.2.7
|
||||||
|
@ -17,8 +17,8 @@ require (
|
||||||
github.com/google/go-cmp v0.6.0
|
github.com/google/go-cmp v0.6.0
|
||||||
github.com/google/gopacket v1.1.19
|
github.com/google/gopacket v1.1.19
|
||||||
github.com/google/renameio/v2 v2.0.0
|
github.com/google/renameio/v2 v2.0.0
|
||||||
github.com/google/uuid v1.5.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
|
github.com/insomniacslk/dhcp v0.0.0-20240204152450-ca2dc33955c1
|
||||||
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86
|
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86
|
||||||
github.com/kardianos/service v1.2.2
|
github.com/kardianos/service v1.2.2
|
||||||
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118
|
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118
|
||||||
|
@ -28,14 +28,14 @@ require (
|
||||||
// own code for that. Perhaps, use gopacket.
|
// own code for that. Perhaps, use gopacket.
|
||||||
github.com/mdlayher/raw v0.1.0
|
github.com/mdlayher/raw v0.1.0
|
||||||
github.com/miekg/dns v1.1.58
|
github.com/miekg/dns v1.1.58
|
||||||
github.com/quic-go/quic-go v0.40.1
|
github.com/quic-go/quic-go v0.41.0
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/ti-mo/netfilter v0.5.1
|
github.com/ti-mo/netfilter v0.5.1
|
||||||
go.etcd.io/bbolt v1.3.8
|
go.etcd.io/bbolt v1.3.8
|
||||||
golang.org/x/crypto v0.18.0
|
golang.org/x/crypto v0.19.0
|
||||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
|
||||||
golang.org/x/net v0.20.0
|
golang.org/x/net v0.21.0
|
||||||
golang.org/x/sys v0.16.0
|
golang.org/x/sys v0.17.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
howett.net/plist v1.0.1
|
howett.net/plist v1.0.1
|
||||||
|
@ -48,8 +48,7 @@ require (
|
||||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
|
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 // indirect
|
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect
|
||||||
// TODO(a.garipov): Upgrade to v0.5.0 once we switch to Go 1.21+.
|
|
||||||
github.com/mdlayher/socket v0.5.0 // indirect
|
github.com/mdlayher/socket v0.5.0 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||||
|
@ -57,10 +56,9 @@ require (
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/quic-go/qpack v0.4.0 // indirect
|
github.com/quic-go/qpack v0.4.0 // indirect
|
||||||
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
github.com/u-root/uio v0.0.0-20240207234124-abbebccef0fd // indirect
|
||||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
|
|
||||||
go.uber.org/mock v0.4.0 // indirect
|
go.uber.org/mock v0.4.0 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
golang.org/x/tools v0.17.0 // indirect
|
golang.org/x/tools v0.17.0 // indirect
|
||||||
|
|
70
go.sum
70
go.sum
|
@ -1,7 +1,7 @@
|
||||||
github.com/AdguardTeam/dnsproxy v0.63.1 h1:CilxSuLYcuYpbPCGB7w41UUqWRMu3dvj4c9TvkIrpBg=
|
github.com/AdguardTeam/dnsproxy v0.65.0 h1:mqJjVSkqoqPwThY3tTvnLHQ/AYBYrfWmK2ER91fu4FE=
|
||||||
github.com/AdguardTeam/dnsproxy v0.63.1/go.mod h1:dRRAFOjrq4QYM92jGs4lt4BoY0Dm3EY3HkaleoM2Feo=
|
github.com/AdguardTeam/dnsproxy v0.65.0/go.mod h1:AGYMLPk2zX+I3NIUYS12KUI296mkCyfoMF/luy2uqdk=
|
||||||
github.com/AdguardTeam/golibs v0.19.0 h1:y/x+Xn3pDg1ZfQ+QEZapPJqaeVYUIMp/EODMtVhn7PM=
|
github.com/AdguardTeam/golibs v0.20.0 h1:A9FIdYq7wUKhFYy3z+YZ/Aw5oFUYgW+xgaVAJ0pnnPY=
|
||||||
github.com/AdguardTeam/golibs v0.19.0/go.mod h1:3WunclLLfrVAq7fYQRhd6f168FHOEMssnipVXCxDL/w=
|
github.com/AdguardTeam/golibs v0.20.0/go.mod h1:3WunclLLfrVAq7fYQRhd6f168FHOEMssnipVXCxDL/w=
|
||||||
github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
|
github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
|
||||||
github.com/AdguardTeam/urlfilter v0.17.3/go.mod h1:Jru7jFfeH2CoDf150uDs+rRYcZBzHHBz05r9REyDKyE=
|
github.com/AdguardTeam/urlfilter v0.17.3/go.mod h1:Jru7jFfeH2CoDf150uDs+rRYcZBzHHBz05r9REyDKyE=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
|
@ -30,12 +30,15 @@ github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu9
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||||
|
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
|
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
|
||||||
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
|
@ -43,25 +46,27 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8=
|
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo=
|
||||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||||
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
|
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
|
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
|
github.com/insomniacslk/dhcp v0.0.0-20240204152450-ca2dc33955c1 h1:L3pm9Kf2G6gJVYawz2SrI5QnV1wzHYbqmKnSHHXJAb8=
|
||||||
|
github.com/insomniacslk/dhcp v0.0.0-20240204152450-ca2dc33955c1/go.mod h1:izxuNQZeFrbx2nK2fAyN5iNUB34Fe9j0nK4PwLzAkKw=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
|
||||||
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
|
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
|
||||||
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8=
|
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8=
|
||||||
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
|
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
|
||||||
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
|
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
|
||||||
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og=
|
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og=
|
||||||
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||||
|
@ -78,12 +83,13 @@ github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrG
|
||||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||||
|
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -92,16 +98,18 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k=
|
||||||
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA=
|
||||||
github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q=
|
|
||||||
github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
|
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
|
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
|
||||||
|
github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
@ -110,32 +118,35 @@ github.com/ti-mo/netfilter v0.2.0/go.mod h1:8GbBGsY/8fxtyIdfwy29JiluNcPK4K7wIT+x
|
||||||
github.com/ti-mo/netfilter v0.5.1 h1:cqamEd1c1zmpfpqvInLOro0Znq/RAfw2QL5wL2rAR/8=
|
github.com/ti-mo/netfilter v0.5.1 h1:cqamEd1c1zmpfpqvInLOro0Znq/RAfw2QL5wL2rAR/8=
|
||||||
github.com/ti-mo/netfilter v0.5.1/go.mod h1:h9UPQ3ZrTZGBitay+LETMxZvNgWGK/efTUcqES2YiLw=
|
github.com/ti-mo/netfilter v0.5.1/go.mod h1:h9UPQ3ZrTZGBitay+LETMxZvNgWGK/efTUcqES2YiLw=
|
||||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||||
|
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e h1:BA9O3BmlTmpjbvajAwzWx4Wo2TRVdpPXZEeemGQcajw=
|
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
github.com/u-root/uio v0.0.0-20240207234124-abbebccef0fd h1:BQJh5fdHsPa/YuMVrbcSxQKuowGCHYh0GD7hvLaHBK0=
|
||||||
|
github.com/u-root/uio v0.0.0-20240207234124-abbebccef0fd/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
|
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
|
||||||
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
|
||||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.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-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-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-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-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-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.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
|
@ -149,10 +160,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/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.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
@ -167,8 +177,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||||
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
|
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
|
||||||
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
|
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
|
||||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
|
|
|
@ -5,9 +5,9 @@ package aghalg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Coalesce returns the first non-zero value. It is named after function
|
// Coalesce returns the first non-zero value. It is named after function
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package aghalg_test
|
package aghalg_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// elements is a helper function that returns n elements of the buffer.
|
// elements is a helper function that returns n elements of the buffer.
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package aghnet
|
package aghnet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/urlfilter"
|
"github.com/AdguardTeam/urlfilter"
|
||||||
"github.com/AdguardTeam/urlfilter/filterlist"
|
"github.com/AdguardTeam/urlfilter/filterlist"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IgnoreEngine contains the list of rules for ignoring hostnames and matches
|
// IgnoreEngine contains the list of rules for ignoring hostnames and matches
|
||||||
|
|
|
@ -12,13 +12,13 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/mathutil"
|
"github.com/AdguardTeam/golibs/mathutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnsupportedError is returned by functions and methods when a particular
|
// UnsupportedError is returned by functions and methods when a particular
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Variables and functions to substitute in tests.
|
// Variables and functions to substitute in tests.
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -15,7 +16,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/google/renameio/v2/maybe"
|
"github.com/google/renameio/v2/maybe"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -13,7 +14,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/testutil"
|
"github.com/AdguardTeam/golibs/testutil"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||||
|
@ -19,7 +20,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type v4ServerConfJSON struct {
|
type v4ServerConfJSON struct {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -20,7 +21,6 @@ import (
|
||||||
"github.com/go-ping/ping"
|
"github.com/go-ping/ping"
|
||||||
"github.com/insomniacslk/dhcp/dhcpv4"
|
"github.com/insomniacslk/dhcp/dhcpv4"
|
||||||
"github.com/insomniacslk/dhcp/dhcpv4/server4"
|
"github.com/insomniacslk/dhcp/dhcpv4/server4"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// v4Server is a DHCPv4 server.
|
// v4Server is a DHCPv4 server.
|
||||||
|
|
|
@ -2,11 +2,11 @@ package dhcpsvc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is the configuration for the DHCP service.
|
// Config is the configuration for the DHCP service.
|
||||||
|
|
|
@ -2,9 +2,8 @@ package dhcpsvc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// netInterface is a common part of any network interface within the DHCP
|
// netInterface is a common part of any network interface within the DHCP
|
||||||
|
|
|
@ -4,9 +4,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lease is a DHCP lease.
|
// Lease is a DHCP lease.
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DHCPServer is a DHCP server for both IPv4 and IPv6 address families.
|
// DHCPServer is a DHCP server for both IPv4 and IPv6 address families.
|
||||||
|
@ -174,8 +174,8 @@ func (srv *DHCPServer) Reset() (err error) {
|
||||||
iface.reset()
|
iface.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
maps.Clear(srv.leaseByIP)
|
clear(srv.leaseByIP)
|
||||||
maps.Clear(srv.leaseByName)
|
clear(srv.leaseByName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IPv4Config is the interface-specific configuration for DHCPv4.
|
// IPv4Config is the interface-specific configuration for DHCPv4.
|
||||||
|
|
|
@ -3,12 +3,12 @@ package dhcpsvc
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IPv6Config is the interface-specific configuration for DHCPv6.
|
// IPv6Config is the interface-specific configuration for DHCPv6.
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -24,7 +25,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"github.com/AdguardTeam/golibs/timeutil"
|
"github.com/AdguardTeam/golibs/timeutil"
|
||||||
"github.com/ameshkov/dnscrypt/v2"
|
"github.com/ameshkov/dnscrypt/v2"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ClientsContainer provides information about preconfigured DNS clients.
|
// ClientsContainer provides information about preconfigured DNS clients.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package dnsforward
|
package dnsforward
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAnyNameMatches(t *testing.T) {
|
func TestAnyNameMatches(t *testing.T) {
|
||||||
|
|
|
@ -2,54 +2,56 @@ package dnsforward
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// upstreamConfigValidator parses the [*proxy.UpstreamConfig] and checks the
|
// upstreamConfigValidator parses each section of an upstream configuration into
|
||||||
// actual DNS availability of each upstream.
|
// a corresponding [*proxy.UpstreamConfig] and checks the actual DNS
|
||||||
|
// availability of each upstream.
|
||||||
type upstreamConfigValidator struct {
|
type upstreamConfigValidator struct {
|
||||||
// general is the general upstream configuration.
|
// generalUpstreamResults contains upstream results of a general section.
|
||||||
general []*upstreamResult
|
generalUpstreamResults map[string]*upstreamResult
|
||||||
|
|
||||||
// fallback is the fallback upstream configuration.
|
// fallbackUpstreamResults contains upstream results of a fallback section.
|
||||||
fallback []*upstreamResult
|
fallbackUpstreamResults map[string]*upstreamResult
|
||||||
|
|
||||||
// private is the private upstream configuration.
|
// privateUpstreamResults contains upstream results of a private section.
|
||||||
private []*upstreamResult
|
privateUpstreamResults map[string]*upstreamResult
|
||||||
|
|
||||||
|
// generalParseResults contains parsing results of a general section.
|
||||||
|
generalParseResults []*parseResult
|
||||||
|
|
||||||
|
// fallbackParseResults contains parsing results of a fallback section.
|
||||||
|
fallbackParseResults []*parseResult
|
||||||
|
|
||||||
|
// privateParseResults contains parsing results of a private section.
|
||||||
|
privateParseResults []*parseResult
|
||||||
}
|
}
|
||||||
|
|
||||||
// upstreamResult is a result of validation of an [upstream.Upstream] within an
|
// upstreamResult is a result of parsing of an [upstream.Upstream] within an
|
||||||
// [proxy.UpstreamConfig].
|
// [proxy.UpstreamConfig].
|
||||||
type upstreamResult struct {
|
type upstreamResult struct {
|
||||||
// server is the parsed upstream. It is nil when there was an error during
|
// server is the parsed upstream.
|
||||||
// parsing.
|
|
||||||
server upstream.Upstream
|
server upstream.Upstream
|
||||||
|
|
||||||
// err is the error either from parsing or from checking the upstream.
|
// err is the upstream check error.
|
||||||
err error
|
err error
|
||||||
|
|
||||||
// original is the piece of configuration that have either been turned to an
|
|
||||||
// upstream or caused an error.
|
|
||||||
original string
|
|
||||||
|
|
||||||
// isSpecific is true if the upstream is domain-specific.
|
// isSpecific is true if the upstream is domain-specific.
|
||||||
isSpecific bool
|
isSpecific bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// compare compares two [upstreamResult]s. It returns 0 if they are equal, -1
|
// parseResult contains a original piece of upstream configuration and a
|
||||||
// if ur should be sorted before other, and 1 otherwise.
|
// corresponding error.
|
||||||
//
|
type parseResult struct {
|
||||||
// TODO(e.burkov): Perhaps it makes sense to sort the results with errors near
|
err *proxy.ParseError
|
||||||
// the end.
|
original string
|
||||||
func (ur *upstreamResult) compare(other *upstreamResult) (res int) {
|
|
||||||
return strings.Compare(ur.original, other.original)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newUpstreamConfigValidator parses the upstream configuration and returns a
|
// newUpstreamConfigValidator parses the upstream configuration and returns a
|
||||||
|
@ -61,97 +63,99 @@ func newUpstreamConfigValidator(
|
||||||
private []string,
|
private []string,
|
||||||
opts *upstream.Options,
|
opts *upstream.Options,
|
||||||
) (cv *upstreamConfigValidator) {
|
) (cv *upstreamConfigValidator) {
|
||||||
cv = &upstreamConfigValidator{}
|
cv = &upstreamConfigValidator{
|
||||||
|
generalUpstreamResults: map[string]*upstreamResult{},
|
||||||
|
fallbackUpstreamResults: map[string]*upstreamResult{},
|
||||||
|
privateUpstreamResults: map[string]*upstreamResult{},
|
||||||
|
}
|
||||||
|
|
||||||
for _, line := range general {
|
conf, err := proxy.ParseUpstreamsConfig(general, opts)
|
||||||
cv.general = cv.insertLineResults(cv.general, line, opts)
|
cv.generalParseResults = collectErrResults(general, err)
|
||||||
}
|
insertConfResults(conf, cv.generalUpstreamResults)
|
||||||
for _, line := range fallback {
|
|
||||||
cv.fallback = cv.insertLineResults(cv.fallback, line, opts)
|
conf, err = proxy.ParseUpstreamsConfig(fallback, opts)
|
||||||
}
|
cv.fallbackParseResults = collectErrResults(fallback, err)
|
||||||
for _, line := range private {
|
insertConfResults(conf, cv.fallbackUpstreamResults)
|
||||||
cv.private = cv.insertLineResults(cv.private, line, opts)
|
|
||||||
}
|
conf, err = proxy.ParseUpstreamsConfig(private, opts)
|
||||||
|
cv.privateParseResults = collectErrResults(private, err)
|
||||||
|
insertConfResults(conf, cv.privateUpstreamResults)
|
||||||
|
|
||||||
return cv
|
return cv
|
||||||
}
|
}
|
||||||
|
|
||||||
// insertLineResults parses line and inserts the result into s. It can insert
|
// collectErrResults parses err and returns parsing results containing the
|
||||||
// multiple results as well as none.
|
// original upstream configuration line and the corresponding error. err can be
|
||||||
func (cv *upstreamConfigValidator) insertLineResults(
|
// nil.
|
||||||
s []*upstreamResult,
|
func collectErrResults(lines []string, err error) (results []*parseResult) {
|
||||||
line string,
|
if err == nil {
|
||||||
opts *upstream.Options,
|
return nil
|
||||||
) (result []*upstreamResult) {
|
|
||||||
upstreams, isSpecific, err := splitUpstreamLine(line)
|
|
||||||
if err != nil {
|
|
||||||
return cv.insert(s, &upstreamResult{
|
|
||||||
err: err,
|
|
||||||
original: line,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, upstreamAddr := range upstreams {
|
// limit is a maximum length for upstream configuration lines.
|
||||||
var res *upstreamResult
|
const limit = 80
|
||||||
if upstreamAddr != "#" {
|
|
||||||
res = cv.parseUpstream(upstreamAddr, opts)
|
wrapper, ok := err.(errors.WrapperSlice)
|
||||||
} else if !isSpecific {
|
if !ok {
|
||||||
res = &upstreamResult{
|
log.Debug("dnsforward: configvalidator: unwrapping: %s", err)
|
||||||
err: errNotDomainSpecific,
|
|
||||||
original: upstreamAddr,
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
errs := wrapper.Unwrap()
|
||||||
|
results = make([]*parseResult, 0, len(errs))
|
||||||
|
for i, e := range errs {
|
||||||
|
var parseErr *proxy.ParseError
|
||||||
|
if !errors.As(e, &parseErr) {
|
||||||
|
log.Debug("dnsforward: configvalidator: inserting unexpected error %d: %s", i, err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
res.isSpecific = isSpecific
|
idx := parseErr.Idx
|
||||||
s = cv.insert(s, res)
|
line := []rune(lines[idx])
|
||||||
|
if len(line) > limit {
|
||||||
|
line = line[:limit]
|
||||||
|
line[limit-1] = '…'
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
results = append(results, &parseResult{
|
||||||
|
original: string(line),
|
||||||
|
err: parseErr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert inserts r into slice in a sorted order, except duplicates. slice must
|
// insertConfResults parses conf and inserts the upstream result into results.
|
||||||
// not be nil.
|
// It can insert multiple results as well as none.
|
||||||
func (cv *upstreamConfigValidator) insert(
|
func insertConfResults(conf *proxy.UpstreamConfig, results map[string]*upstreamResult) {
|
||||||
s []*upstreamResult,
|
insertListResults(conf.Upstreams, results, false)
|
||||||
r *upstreamResult,
|
|
||||||
) (result []*upstreamResult) {
|
|
||||||
i, has := slices.BinarySearchFunc(s, r, (*upstreamResult).compare)
|
|
||||||
if has {
|
|
||||||
log.Debug("dnsforward: duplicate configuration %q", r.original)
|
|
||||||
|
|
||||||
return s
|
for _, ups := range conf.DomainReservedUpstreams {
|
||||||
|
insertListResults(ups, results, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return slices.Insert(s, i, r)
|
for _, ups := range conf.SpecifiedDomainUpstreams {
|
||||||
|
insertListResults(ups, results, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseUpstream parses addr and returns the result of parsing. It returns nil
|
// insertListResults constructs upstream results from the upstream list and
|
||||||
// if the specified server points at the default upstream server which is
|
// inserts them into results. It can insert multiple results as well as none.
|
||||||
// validated separately.
|
func insertListResults(ups []upstream.Upstream, results map[string]*upstreamResult, specific bool) {
|
||||||
func (cv *upstreamConfigValidator) parseUpstream(
|
for _, u := range ups {
|
||||||
addr string,
|
addr := u.Address()
|
||||||
opts *upstream.Options,
|
_, ok := results[addr]
|
||||||
) (r *upstreamResult) {
|
if ok {
|
||||||
// Check if the upstream has a valid protocol prefix.
|
continue
|
||||||
//
|
|
||||||
// TODO(e.burkov): Validate the domain name.
|
|
||||||
if proto, _, ok := strings.Cut(addr, "://"); ok {
|
|
||||||
if !slices.Contains(protocols, proto) {
|
|
||||||
return &upstreamResult{
|
|
||||||
err: fmt.Errorf("bad protocol %q", proto),
|
|
||||||
original: addr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ups, err := upstream.AddressToUpstream(addr, opts)
|
results[addr] = &upstreamResult{
|
||||||
|
server: u,
|
||||||
return &upstreamResult{
|
isSpecific: specific,
|
||||||
server: ups,
|
}
|
||||||
err: err,
|
|
||||||
original: addr,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,35 +191,30 @@ func (cv *upstreamConfigValidator) check() {
|
||||||
}
|
}
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(len(cv.general) + len(cv.fallback) + len(cv.private))
|
wg.Add(len(cv.generalUpstreamResults) +
|
||||||
|
len(cv.fallbackUpstreamResults) +
|
||||||
|
len(cv.privateUpstreamResults))
|
||||||
|
|
||||||
for _, res := range cv.general {
|
for _, res := range cv.generalUpstreamResults {
|
||||||
go cv.checkSrv(res, wg, commonChecker)
|
go checkSrv(res, wg, commonChecker)
|
||||||
}
|
}
|
||||||
for _, res := range cv.fallback {
|
for _, res := range cv.fallbackUpstreamResults {
|
||||||
go cv.checkSrv(res, wg, commonChecker)
|
go checkSrv(res, wg, commonChecker)
|
||||||
}
|
}
|
||||||
for _, res := range cv.private {
|
for _, res := range cv.privateUpstreamResults {
|
||||||
go cv.checkSrv(res, wg, arpaChecker)
|
go checkSrv(res, wg, arpaChecker)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkSrv runs hc on the server from res, if any, and stores any occurred
|
// checkSrv runs hc on the server from res, if any, and stores any occurred
|
||||||
// error in res. wg is always marked done in the end. It used to be called in
|
// error in res. wg is always marked done in the end. It is intended to be
|
||||||
// a separate goroutine.
|
// used as a goroutine.
|
||||||
func (cv *upstreamConfigValidator) checkSrv(
|
func checkSrv(res *upstreamResult, wg *sync.WaitGroup, hc *healthchecker) {
|
||||||
res *upstreamResult,
|
defer log.OnPanic(fmt.Sprintf("dnsforward: checking upstream %s", res.server.Address()))
|
||||||
wg *sync.WaitGroup,
|
|
||||||
hc *healthchecker,
|
|
||||||
) {
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
if res.server == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
res.err = hc.check(res.server)
|
res.err = hc.check(res.server)
|
||||||
if res.err != nil && res.isSpecific {
|
if res.err != nil && res.isSpecific {
|
||||||
res.err = domainSpecificTestError{Err: res.err}
|
res.err = domainSpecificTestError{Err: res.err}
|
||||||
|
@ -225,65 +224,126 @@ func (cv *upstreamConfigValidator) checkSrv(
|
||||||
// close closes all the upstreams that were successfully parsed. It enriches
|
// close closes all the upstreams that were successfully parsed. It enriches
|
||||||
// the results with deferred closing errors.
|
// the results with deferred closing errors.
|
||||||
func (cv *upstreamConfigValidator) close() {
|
func (cv *upstreamConfigValidator) close() {
|
||||||
for _, slice := range [][]*upstreamResult{cv.general, cv.fallback, cv.private} {
|
all := []map[string]*upstreamResult{
|
||||||
for _, r := range slice {
|
cv.generalUpstreamResults,
|
||||||
if r.server != nil {
|
cv.fallbackUpstreamResults,
|
||||||
|
cv.privateUpstreamResults,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range all {
|
||||||
|
for _, r := range m {
|
||||||
r.err = errors.WithDeferred(r.err, r.server.Close())
|
r.err = errors.WithDeferred(r.err, r.server.Close())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sections of the upstream configuration according to the text label of the
|
||||||
|
// localization.
|
||||||
|
//
|
||||||
|
// Keep in sync with client/src/__locales/en.json.
|
||||||
|
//
|
||||||
|
// TODO(s.chzhen): Refactor.
|
||||||
|
const (
|
||||||
|
generalTextLabel = "upstream_dns"
|
||||||
|
fallbackTextLabel = "fallback_dns_title"
|
||||||
|
privateTextLabel = "local_ptr_title"
|
||||||
|
)
|
||||||
|
|
||||||
// status returns all the data collected during parsing, healthcheck, and
|
// status returns all the data collected during parsing, healthcheck, and
|
||||||
// closing of the upstreams. The returned map is keyed by the original upstream
|
// closing of the upstreams. The returned map is keyed by the original upstream
|
||||||
// configuration piece and contains the corresponding error or "OK" if there was
|
// configuration piece and contains the corresponding error or "OK" if there was
|
||||||
// no error.
|
// no error.
|
||||||
func (cv *upstreamConfigValidator) status() (results map[string]string) {
|
func (cv *upstreamConfigValidator) status() (results map[string]string) {
|
||||||
result := map[string]string{}
|
// Names of the upstream configuration sections for logging.
|
||||||
|
const (
|
||||||
|
generalSection = "general"
|
||||||
|
fallbackSection = "fallback"
|
||||||
|
privateSection = "private"
|
||||||
|
)
|
||||||
|
|
||||||
for _, res := range cv.general {
|
results = map[string]string{}
|
||||||
resultToStatus("general", res, result)
|
|
||||||
|
for original, res := range cv.generalUpstreamResults {
|
||||||
|
upstreamResultToStatus(generalSection, string(original), res, results)
|
||||||
}
|
}
|
||||||
for _, res := range cv.fallback {
|
for original, res := range cv.fallbackUpstreamResults {
|
||||||
resultToStatus("fallback", res, result)
|
upstreamResultToStatus(fallbackSection, string(original), res, results)
|
||||||
}
|
}
|
||||||
for _, res := range cv.private {
|
for original, res := range cv.privateUpstreamResults {
|
||||||
resultToStatus("private", res, result)
|
upstreamResultToStatus(privateSection, string(original), res, results)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
parseResultToStatus(generalTextLabel, generalSection, cv.generalParseResults, results)
|
||||||
|
parseResultToStatus(fallbackTextLabel, fallbackSection, cv.fallbackParseResults, results)
|
||||||
|
parseResultToStatus(privateTextLabel, privateSection, cv.privateParseResults, results)
|
||||||
|
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
// resultToStatus puts "OK" or an error message from res into resMap. section
|
// upstreamResultToStatus puts "OK" or an error message from res into resMap.
|
||||||
// is the name of the upstream configuration section, i.e. "general",
|
// section is the name of the upstream configuration section, i.e. "general",
|
||||||
// "fallback", or "private", and only used for logging.
|
// "fallback", or "private", and only used for logging.
|
||||||
//
|
//
|
||||||
// TODO(e.burkov): Currently, the HTTP handler expects that all the results are
|
// TODO(e.burkov): Currently, the HTTP handler expects that all the results are
|
||||||
// put together in a single map, which may lead to collisions, see AG-27539.
|
// put together in a single map, which may lead to collisions, see AG-27539.
|
||||||
// Improve the results compilation.
|
// Improve the results compilation.
|
||||||
func resultToStatus(section string, res *upstreamResult, resMap map[string]string) {
|
func upstreamResultToStatus(
|
||||||
|
section string,
|
||||||
|
original string,
|
||||||
|
res *upstreamResult,
|
||||||
|
resMap map[string]string,
|
||||||
|
) {
|
||||||
val := "OK"
|
val := "OK"
|
||||||
if res.err != nil {
|
if res.err != nil {
|
||||||
val = res.err.Error()
|
val = res.err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
prevVal := resMap[res.original]
|
prevVal := resMap[original]
|
||||||
switch prevVal {
|
switch prevVal {
|
||||||
case "":
|
case "":
|
||||||
resMap[res.original] = val
|
resMap[original] = val
|
||||||
case val:
|
case val:
|
||||||
log.Debug("dnsforward: duplicating %s config line %q", section, res.original)
|
log.Debug("dnsforward: duplicating %s config line %q", section, original)
|
||||||
default:
|
default:
|
||||||
log.Debug(
|
log.Debug(
|
||||||
"dnsforward: warning: %s config line %q (%v) had different result %v",
|
"dnsforward: warning: %s config line %q (%v) had different result %v",
|
||||||
section,
|
section,
|
||||||
val,
|
val,
|
||||||
res.original,
|
original,
|
||||||
prevVal,
|
prevVal,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseResultToStatus puts parsing error messages from results into resMap.
|
||||||
|
// section is the name of the upstream configuration section, i.e. "general",
|
||||||
|
// "fallback", or "private", and only used for logging.
|
||||||
|
//
|
||||||
|
// Parsing error message has the following format:
|
||||||
|
//
|
||||||
|
// sectionTextLabel line: parsing error
|
||||||
|
//
|
||||||
|
// Where sectionTextLabel is a section text label of a localization and line is
|
||||||
|
// a line number.
|
||||||
|
func parseResultToStatus(
|
||||||
|
textLabel string,
|
||||||
|
section string,
|
||||||
|
results []*parseResult,
|
||||||
|
resMap map[string]string,
|
||||||
|
) {
|
||||||
|
for _, res := range results {
|
||||||
|
original := res.original
|
||||||
|
_, ok := resMap[original]
|
||||||
|
if ok {
|
||||||
|
log.Debug("dnsforward: duplicating %s parsing error %q", section, original)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resMap[original] = fmt.Sprintf("%s %d: parsing error", textLabel, res.err.Idx+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// domainSpecificTestError is a wrapper for errors returned by checkDNS to mark
|
// domainSpecificTestError is a wrapper for errors returned by checkDNS to mark
|
||||||
// the tested upstream domain-specific and therefore consider its errors
|
// the tested upstream domain-specific and therefore consider its errors
|
||||||
// non-critical.
|
// non-critical.
|
||||||
|
@ -342,7 +402,7 @@ func (h *healthchecker) check(u upstream.Upstream) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't communicate with upstream: %w", err)
|
return fmt.Errorf("couldn't communicate with upstream: %w", err)
|
||||||
} else if h.ansEmpty && len(reply.Answer) > 0 {
|
} else if h.ansEmpty && len(reply.Answer) > 0 {
|
||||||
return errWrongResponse
|
return errors.Error("wrong response")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -30,7 +31,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/netutil/sysresolv"
|
"github.com/AdguardTeam/golibs/netutil/sysresolv"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultTimeout is the default upstream timeout
|
// DefaultTimeout is the default upstream timeout
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/urlfilter/rules"
|
"github.com/AdguardTeam/urlfilter/rules"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// beforeRequestHandler is the handler that is called before any other
|
// beforeRequestHandler is the handler that is called before any other
|
||||||
|
|
|
@ -6,16 +6,17 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||||
|
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// jsonDNSConfig is the JSON representation of the DNS server configuration.
|
// jsonDNSConfig is the JSON representation of the DNS server configuration.
|
||||||
|
@ -294,7 +295,7 @@ func (req *jsonDNSConfig) checkFallbacks() (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ValidateUpstreams(*req.Fallbacks)
|
_, err = proxy.ParseUpstreamsConfig(*req.Fallbacks, &upstream.Options{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fallback servers: %w", err)
|
return fmt.Errorf("fallback servers: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -344,7 +345,7 @@ func (req *jsonDNSConfig) validate(privateNets netutil.SubnetSet) (err error) {
|
||||||
// validateUpstreamDNSServers returns an error if any field of req is invalid.
|
// validateUpstreamDNSServers returns an error if any field of req is invalid.
|
||||||
func (req *jsonDNSConfig) validateUpstreamDNSServers(privateNets netutil.SubnetSet) (err error) {
|
func (req *jsonDNSConfig) validateUpstreamDNSServers(privateNets netutil.SubnetSet) (err error) {
|
||||||
if req.Upstreams != nil {
|
if req.Upstreams != nil {
|
||||||
err = ValidateUpstreams(*req.Upstreams)
|
_, err = proxy.ParseUpstreamsConfig(*req.Upstreams, &upstream.Options{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("upstream servers: %w", err)
|
return fmt.Errorf("upstream servers: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -580,9 +581,6 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Upstreams = stringutil.FilterOut(req.Upstreams, IsCommentOrEmpty)
|
|
||||||
req.FallbackDNS = stringutil.FilterOut(req.FallbackDNS, IsCommentOrEmpty)
|
|
||||||
req.PrivateUpstreams = stringutil.FilterOut(req.PrivateUpstreams, IsCommentOrEmpty)
|
|
||||||
req.BootstrapDNS = stringutil.FilterOut(req.BootstrapDNS, IsCommentOrEmpty)
|
req.BootstrapDNS = stringutil.FilterOut(req.BootstrapDNS, IsCommentOrEmpty)
|
||||||
|
|
||||||
opts := &upstream.Options{
|
opts := &upstream.Options{
|
||||||
|
|
|
@ -223,8 +223,9 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
|
||||||
wantSet: "",
|
wantSet: "",
|
||||||
}, {
|
}, {
|
||||||
name: "upstream_dns_bad",
|
name: "upstream_dns_bad",
|
||||||
wantSet: `validating dns config: ` +
|
wantSet: `validating dns config: upstream servers: parsing error at index 0: ` +
|
||||||
`upstream servers: validating upstream "!!!": not an ip:port`,
|
`cannot prepare the upstream: invalid address !!!: bad hostname "!!!": ` +
|
||||||
|
`bad top-level domain name label "!!!": bad top-level domain name label rune '!'`,
|
||||||
}, {
|
}, {
|
||||||
name: "bootstraps_bad",
|
name: "bootstraps_bad",
|
||||||
wantSet: `validating dns config: checking bootstrap a: not a bootstrap: ParseAddr("a"): ` +
|
wantSet: `validating dns config: checking bootstrap a: not a bootstrap: ParseAddr("a"): ` +
|
||||||
|
@ -313,98 +314,6 @@ func TestIsCommentOrEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateUpstreams(t *testing.T) {
|
|
||||||
const sdnsStamp = `sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_J` +
|
|
||||||
`S3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczE` +
|
|
||||||
`uYWRndWFyZC5jb20`
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
name string
|
|
||||||
wantErr string
|
|
||||||
set []string
|
|
||||||
}{{
|
|
||||||
name: "empty",
|
|
||||||
wantErr: ``,
|
|
||||||
set: nil,
|
|
||||||
}, {
|
|
||||||
name: "comment",
|
|
||||||
wantErr: ``,
|
|
||||||
set: []string{"# comment"},
|
|
||||||
}, {
|
|
||||||
name: "no_default",
|
|
||||||
wantErr: `no default upstreams specified`,
|
|
||||||
set: []string{
|
|
||||||
"[/host.com/]1.1.1.1",
|
|
||||||
"[//]tls://1.1.1.1",
|
|
||||||
"[/www.host.com/]#",
|
|
||||||
"[/host.com/google.com/]8.8.8.8",
|
|
||||||
"[/host/]" + sdnsStamp,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
name: "with_default",
|
|
||||||
wantErr: ``,
|
|
||||||
set: []string{
|
|
||||||
"[/host.com/]1.1.1.1",
|
|
||||||
"[//]tls://1.1.1.1",
|
|
||||||
"[/www.host.com/]#",
|
|
||||||
"[/host.com/google.com/]8.8.8.8",
|
|
||||||
"[/host/]" + sdnsStamp,
|
|
||||||
"8.8.8.8",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
name: "invalid",
|
|
||||||
wantErr: `validating upstream "dhcp://fake.dns": bad protocol "dhcp"`,
|
|
||||||
set: []string{"dhcp://fake.dns"},
|
|
||||||
}, {
|
|
||||||
name: "invalid",
|
|
||||||
wantErr: `validating upstream "1.2.3.4.5": not an ip:port`,
|
|
||||||
set: []string{"1.2.3.4.5"},
|
|
||||||
}, {
|
|
||||||
name: "invalid",
|
|
||||||
wantErr: `validating upstream "123.3.7m": not an ip:port`,
|
|
||||||
set: []string{"123.3.7m"},
|
|
||||||
}, {
|
|
||||||
name: "invalid",
|
|
||||||
wantErr: `splitting upstream line "[/host.com]tls://dns.adguard.com": ` +
|
|
||||||
`missing separator`,
|
|
||||||
set: []string{"[/host.com]tls://dns.adguard.com"},
|
|
||||||
}, {
|
|
||||||
name: "invalid",
|
|
||||||
wantErr: `validating upstream "[host.ru]#": not an ip:port`,
|
|
||||||
set: []string{"[host.ru]#"},
|
|
||||||
}, {
|
|
||||||
name: "valid_default",
|
|
||||||
wantErr: ``,
|
|
||||||
set: []string{
|
|
||||||
"1.1.1.1",
|
|
||||||
"tls://1.1.1.1",
|
|
||||||
"https://dns.adguard.com/dns-query",
|
|
||||||
sdnsStamp,
|
|
||||||
"udp://dns.google",
|
|
||||||
"udp://8.8.8.8",
|
|
||||||
"[/host.com/]1.1.1.1",
|
|
||||||
"[//]tls://1.1.1.1",
|
|
||||||
"[/www.host.com/]#",
|
|
||||||
"[/host.com/google.com/]8.8.8.8",
|
|
||||||
"[/host/]" + sdnsStamp,
|
|
||||||
"[/пример.рф/]8.8.8.8",
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
name: "bad_domain",
|
|
||||||
wantErr: `splitting upstream line "[/!/]8.8.8.8": domain at index 0: ` +
|
|
||||||
`bad domain name "!": bad top-level domain name label "!": ` +
|
|
||||||
`bad top-level domain name label rune '!'`,
|
|
||||||
set: []string{"[/!/]8.8.8.8"},
|
|
||||||
}}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
err := ValidateUpstreams(tc.set)
|
|
||||||
testutil.AssertErrorMsg(t, tc.wantErr, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidateUpstreamsPrivate(t *testing.T) {
|
func TestValidateUpstreamsPrivate(t *testing.T) {
|
||||||
ss := netutil.SubnetSetFunc(netutil.IsLocallyServed)
|
ss := netutil.SubnetSetFunc(netutil.IsLocallyServed)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package dnsforward
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/urlfilter/rules"
|
"github.com/AdguardTeam/urlfilter/rules"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// makeResponse creates a DNS response by req and sets necessary flags. It also
|
// makeResponse creates a DNS response by req and sets necessary flags. It also
|
||||||
|
|
|
@ -2,10 +2,9 @@ package dnsforward
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||||
|
@ -16,29 +15,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// errNotDomainSpecific is returned when the upstream should be
|
|
||||||
// domain-specific, but isn't.
|
|
||||||
errNotDomainSpecific errors.Error = "not a domain-specific upstream"
|
|
||||||
|
|
||||||
// errMissingSeparator is returned when the domain-specific part of the
|
|
||||||
// upstream configuration line isn't closed.
|
|
||||||
errMissingSeparator errors.Error = "missing separator"
|
|
||||||
|
|
||||||
// errDupSeparator is returned when the domain-specific part of the upstream
|
|
||||||
// configuration line contains more than one ending separator.
|
|
||||||
errDupSeparator errors.Error = "duplicated separator"
|
|
||||||
|
|
||||||
// errNoDefaultUpstreams is returned when there are no default upstreams
|
|
||||||
// specified in the upstream configuration.
|
|
||||||
errNoDefaultUpstreams errors.Error = "no default upstreams specified"
|
|
||||||
|
|
||||||
// errWrongResponse is returned when the checked upstream replies in an
|
|
||||||
// unexpected way.
|
|
||||||
errWrongResponse errors.Error = "wrong response"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// loadUpstreams parses upstream DNS servers from the configured file or from
|
// loadUpstreams parses upstream DNS servers from the configured file or from
|
||||||
|
@ -199,84 +175,12 @@ func IsCommentOrEmpty(s string) (ok bool) {
|
||||||
return len(s) == 0 || s[0] == '#'
|
return len(s) == 0 || s[0] == '#'
|
||||||
}
|
}
|
||||||
|
|
||||||
// newUpstreamConfig validates upstreams and returns an appropriate upstream
|
|
||||||
// configuration or nil if it can't be built.
|
|
||||||
//
|
|
||||||
// TODO(e.burkov): Perhaps proxy.ParseUpstreamsConfig should validate upstreams
|
|
||||||
// slice already so that this function may be considered useless.
|
|
||||||
func newUpstreamConfig(upstreams []string) (conf *proxy.UpstreamConfig, err error) {
|
|
||||||
// No need to validate comments and empty lines.
|
|
||||||
upstreams = stringutil.FilterOut(upstreams, IsCommentOrEmpty)
|
|
||||||
if len(upstreams) == 0 {
|
|
||||||
// Consider this case valid since it means the default server should be
|
|
||||||
// used.
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validateUpstreamConfig(upstreams)
|
|
||||||
if err != nil {
|
|
||||||
// Don't wrap the error since it's informative enough as is.
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
conf, err = proxy.ParseUpstreamsConfig(
|
|
||||||
upstreams,
|
|
||||||
&upstream.Options{
|
|
||||||
Bootstrap: net.DefaultResolver,
|
|
||||||
Timeout: DefaultTimeout,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
// Don't wrap the error since it's informative enough as is.
|
|
||||||
return nil, err
|
|
||||||
} else if len(conf.Upstreams) == 0 {
|
|
||||||
return nil, errNoDefaultUpstreams
|
|
||||||
}
|
|
||||||
|
|
||||||
return conf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateUpstreamConfig validates each upstream from the upstream
|
|
||||||
// configuration and returns an error if any upstream is invalid.
|
|
||||||
//
|
|
||||||
// TODO(e.burkov): Merge with [upstreamConfigValidator] somehow.
|
|
||||||
func validateUpstreamConfig(conf []string) (err error) {
|
|
||||||
for _, u := range conf {
|
|
||||||
var ups []string
|
|
||||||
var isSpecific bool
|
|
||||||
ups, isSpecific, err = splitUpstreamLine(u)
|
|
||||||
if err != nil {
|
|
||||||
// Don't wrap the error since it's informative enough as is.
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range ups {
|
|
||||||
_, err = validateUpstream(addr, isSpecific)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("validating upstream %q: %w", addr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateUpstreams validates each upstream and returns an error if any
|
|
||||||
// upstream is invalid or if there are no default upstreams specified.
|
|
||||||
//
|
|
||||||
// TODO(e.burkov): Merge with [upstreamConfigValidator] somehow.
|
|
||||||
func ValidateUpstreams(upstreams []string) (err error) {
|
|
||||||
_, err = newUpstreamConfig(upstreams)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateUpstreamsPrivate validates each upstream and returns an error if any
|
// ValidateUpstreamsPrivate validates each upstream and returns an error if any
|
||||||
// upstream is invalid or if there are no default upstreams specified. It also
|
// upstream is invalid or if there are no default upstreams specified. It also
|
||||||
// checks each domain of domain-specific upstreams for being ARPA pointing to
|
// checks each domain of domain-specific upstreams for being ARPA pointing to
|
||||||
// a locally-served network. privateNets must not be nil.
|
// a locally-served network. privateNets must not be nil.
|
||||||
func ValidateUpstreamsPrivate(upstreams []string, privateNets netutil.SubnetSet) (err error) {
|
func ValidateUpstreamsPrivate(upstreams []string, privateNets netutil.SubnetSet) (err error) {
|
||||||
conf, err := newUpstreamConfig(upstreams)
|
conf, err := proxy.ParseUpstreamsConfig(upstreams, &upstream.Options{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("creating config: %w", err)
|
return fmt.Errorf("creating config: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -308,66 +212,3 @@ func ValidateUpstreamsPrivate(upstreams []string, privateNets netutil.SubnetSet)
|
||||||
|
|
||||||
return errors.Annotate(errors.Join(errs...), "checking domain-specific upstreams: %w")
|
return errors.Annotate(errors.Join(errs...), "checking domain-specific upstreams: %w")
|
||||||
}
|
}
|
||||||
|
|
||||||
// protocols are the supported URL schemes for upstreams.
|
|
||||||
var protocols = []string{"h3", "https", "quic", "sdns", "tcp", "tls", "udp"}
|
|
||||||
|
|
||||||
// validateUpstream returns an error if u alongside with domains is not a valid
|
|
||||||
// upstream configuration. useDefault is true if the upstream is
|
|
||||||
// domain-specific and is configured to point at the default upstream server
|
|
||||||
// which is validated separately. The upstream is considered domain-specific
|
|
||||||
// only if domains is at least not nil.
|
|
||||||
func validateUpstream(u string, isSpecific bool) (useDefault bool, err error) {
|
|
||||||
// The special server address '#' means that default server must be used.
|
|
||||||
if useDefault = u == "#" && isSpecific; useDefault {
|
|
||||||
return useDefault, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the upstream has a valid protocol prefix.
|
|
||||||
//
|
|
||||||
// TODO(e.burkov): Validate the domain name.
|
|
||||||
if proto, _, ok := strings.Cut(u, "://"); ok {
|
|
||||||
if !slices.Contains(protocols, proto) {
|
|
||||||
return false, fmt.Errorf("bad protocol %q", proto)
|
|
||||||
}
|
|
||||||
} else if _, err = netip.ParseAddr(u); err == nil {
|
|
||||||
return false, nil
|
|
||||||
} else if _, err = netip.ParseAddrPort(u); err == nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitUpstreamLine returns the upstreams and the specified domains. domains
|
|
||||||
// is nil when the upstream is not domains-specific. Otherwise it may also be
|
|
||||||
// empty.
|
|
||||||
func splitUpstreamLine(upstreamStr string) (upstreams []string, isSpecific bool, err error) {
|
|
||||||
if !strings.HasPrefix(upstreamStr, "[/") {
|
|
||||||
return []string{upstreamStr}, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() { err = errors.Annotate(err, "splitting upstream line %q: %w", upstreamStr) }()
|
|
||||||
|
|
||||||
doms, ups, found := strings.Cut(upstreamStr[2:], "/]")
|
|
||||||
if !found {
|
|
||||||
return nil, false, errMissingSeparator
|
|
||||||
} else if strings.Contains(ups, "/]") {
|
|
||||||
return nil, false, errDupSeparator
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, host := range strings.Split(doms, "/") {
|
|
||||||
if host == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err = netutil.ValidateDomainName(strings.TrimPrefix(host, "*."))
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, fmt.Errorf("domain at index %d: %w", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
isSpecific = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Fields(ups), isSpecific, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -100,8 +100,7 @@ func TestUpstreamConfigValidator(t *testing.T) {
|
||||||
name: "bad_specification",
|
name: "bad_specification",
|
||||||
general: []string{"[/domain.example/]/]1.2.3.4"},
|
general: []string{"[/domain.example/]/]1.2.3.4"},
|
||||||
want: map[string]string{
|
want: map[string]string{
|
||||||
"[/domain.example/]/]1.2.3.4": `splitting upstream line ` +
|
"[/domain.example/]/]1.2.3.4": generalTextLabel + " 1: parsing error",
|
||||||
`"[/domain.example/]/]1.2.3.4": duplicated separator`,
|
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "all_different",
|
name: "all_different",
|
||||||
|
@ -120,23 +119,9 @@ func TestUpstreamConfigValidator(t *testing.T) {
|
||||||
fallback: []string{"[/example/" + goodUps},
|
fallback: []string{"[/example/" + goodUps},
|
||||||
private: []string{"[/example//bad.123/]" + goodUps},
|
private: []string{"[/example//bad.123/]" + goodUps},
|
||||||
want: map[string]string{
|
want: map[string]string{
|
||||||
`[/example/]/]` + goodUps: `splitting upstream line ` +
|
"[/example/]/]" + goodUps: generalTextLabel + " 1: parsing error",
|
||||||
`"[/example/]/]` + goodUps + `": duplicated separator`,
|
"[/example/" + goodUps: fallbackTextLabel + " 1: parsing error",
|
||||||
`[/example/` + goodUps: `splitting upstream line ` +
|
"[/example//bad.123/]" + goodUps: privateTextLabel + " 1: parsing error",
|
||||||
`"[/example/` + goodUps + `": missing separator`,
|
|
||||||
`[/example//bad.123/]` + goodUps: `splitting upstream line ` +
|
|
||||||
`"[/example//bad.123/]` + goodUps + `": domain at index 2: ` +
|
|
||||||
`bad domain name "bad.123": ` +
|
|
||||||
`bad top-level domain name label "123": all octets are numeric`,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
name: "non-specific_default",
|
|
||||||
general: []string{
|
|
||||||
"#",
|
|
||||||
"[/example/]#",
|
|
||||||
},
|
|
||||||
want: map[string]string{
|
|
||||||
"#": "not a domain-specific upstream",
|
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "bad_proto",
|
name: "bad_proto",
|
||||||
|
@ -144,7 +129,15 @@ func TestUpstreamConfigValidator(t *testing.T) {
|
||||||
"bad://1.2.3.4",
|
"bad://1.2.3.4",
|
||||||
},
|
},
|
||||||
want: map[string]string{
|
want: map[string]string{
|
||||||
"bad://1.2.3.4": `bad protocol "bad"`,
|
"bad://1.2.3.4": generalTextLabel + " 1: parsing error",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "truncated_line",
|
||||||
|
general: []string{
|
||||||
|
"This is a very long line. It will cause a parsing error and will be truncated here.",
|
||||||
|
},
|
||||||
|
want: map[string]string{
|
||||||
|
"This is a very long line. It will cause a parsing error and will be truncated …": "upstream_dns 1: parsing error",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/schedule"
|
"github.com/AdguardTeam/AdGuardHome/internal/schedule"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/urlfilter/rules"
|
"github.com/AdguardTeam/urlfilter/rules"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// serviceRules maps a service ID to its filtering rules.
|
// serviceRules maps a service ID to its filtering rules.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,7 +16,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// filterDir is the subdirectory of a data directory to store downloaded
|
// filterDir is the subdirectory of a data directory to store downloaded
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -29,7 +30,6 @@ import (
|
||||||
"github.com/AdguardTeam/urlfilter/filterlist"
|
"github.com/AdguardTeam/urlfilter/filterlist"
|
||||||
"github.com/AdguardTeam/urlfilter/rules"
|
"github.com/AdguardTeam/urlfilter/rules"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The IDs of built-in filter lists.
|
// The IDs of built-in filter lists.
|
||||||
|
@ -1113,8 +1113,7 @@ func (d *DNSFilter) periodicallyRefreshFilters(ivl time.Duration) (nextIvl time.
|
||||||
ivl = maxInterval
|
ivl = maxInterval
|
||||||
} else if isNetErr {
|
} else if isNetErr {
|
||||||
ivl *= 2
|
ivl *= 2
|
||||||
// TODO(s.chzhen): Use built-in function max in Go 1.21.
|
ivl = max(ivl, maxInterval)
|
||||||
ivl = mathutil.Max(ivl, maxInterval)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl
|
return ivl
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -14,7 +15,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
"golang.org/x/net/publicsuffix"
|
"golang.org/x/net/publicsuffix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package hashprefix
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -15,7 +16,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// validateFilterURL validates the filter list URL or file name.
|
// validateFilterURL validates the filter list URL or file name.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package rewrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/AdguardTeam/urlfilter/filterlist"
|
"github.com/AdguardTeam/urlfilter/filterlist"
|
||||||
"github.com/AdguardTeam/urlfilter/rules"
|
"github.com/AdguardTeam/urlfilter/rules"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage is a storage for rewrite rules.
|
// Storage is a storage for rewrite rules.
|
||||||
|
|
|
@ -3,10 +3,10 @@ package filtering
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(d.kolyshev): Use [rewrite.Item] instead.
|
// TODO(d.kolyshev): Use [rewrite.Item] instead.
|
||||||
|
|
|
@ -3,13 +3,13 @@ package filtering
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/mathutil"
|
"github.com/AdguardTeam/golibs/mathutil"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Legacy DNS rewrites
|
// Legacy DNS rewrites
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parser is a filtering-rule parser that collects data, such as the checksum
|
// Parser is a filtering-rule parser that collects data, such as the checksum
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -16,7 +17,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UID is the type for the unique IDs of persistent clients.
|
// UID is the type for the unique IDs of persistent clients.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -23,7 +24,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DHCP is an interface for accessing DHCP lease data the [clientsContainer]
|
// DHCP is an interface for accessing DHCP lease data the [clientsContainer]
|
||||||
|
@ -613,7 +613,7 @@ func (clients *clientsContainer) check(c *persistentClient) (err error) {
|
||||||
// TODO(s.chzhen): Move to the constructor.
|
// TODO(s.chzhen): Move to the constructor.
|
||||||
slices.Sort(c.Tags)
|
slices.Sort(c.Tags)
|
||||||
|
|
||||||
err = dnsforward.ValidateUpstreams(c.Upstreams)
|
_, err = proxy.ParseUpstreamsConfig(c.Upstreams, &upstream.Options{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid upstream servers: %w", err)
|
return fmt.Errorf("invalid upstream servers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
@ -40,7 +41,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/netutil"
|
"github.com/AdguardTeam/golibs/netutil"
|
||||||
"github.com/AdguardTeam/golibs/osutil"
|
"github.com/AdguardTeam/golibs/osutil"
|
||||||
"github.com/AdguardTeam/golibs/stringutil"
|
"github.com/AdguardTeam/golibs/stringutil"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Global context
|
// Global context
|
||||||
|
|
|
@ -8,13 +8,13 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/configmigrate"
|
"github.com/AdguardTeam/AdGuardHome/internal/configmigrate"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/next/configmgr"
|
"github.com/AdguardTeam/AdGuardHome/internal/next/configmgr"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/version"
|
"github.com/AdguardTeam/AdGuardHome/internal/version"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// options contains all command-line options for the AdGuardHome(.exe) binary.
|
// options contains all command-line options for the AdGuardHome(.exe) binary.
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/timeutil"
|
"github.com/AdguardTeam/golibs/timeutil"
|
||||||
"github.com/google/renameio/v2/maybe"
|
"github.com/google/renameio/v2/maybe"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package querylog
|
package querylog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -9,7 +10,6 @@ import (
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
"golang.org/x/net/idna"
|
"golang.org/x/net/idna"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ package querylog
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// client finds the client info, if any, by its ClientID and IP address,
|
// client finds the client info, if any, by its ClientID and IP address,
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/AdguardTeam/golibs/mathutil"
|
|
||||||
"github.com/bluele/gcache"
|
"github.com/bluele/gcache"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,8 +87,7 @@ func (r *Default) Process(ip netip.Addr) (host string, changed bool) {
|
||||||
log.Debug("rdns: resolving %q: %s", ip, err)
|
log.Debug("rdns: resolving %q: %s", ip, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(s.chzhen): Use built-in function max in Go 1.21.
|
ttl = max(ttl, r.cacheTTL)
|
||||||
ttl = mathutil.Max(ttl, r.cacheTTL)
|
|
||||||
|
|
||||||
item := &cacheItem{
|
item := &cacheItem{
|
||||||
expiry: time.Now().Add(ttl),
|
expiry: time.Now().Add(ttl),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
module github.com/AdguardTeam/AdGuardHome/internal/tools
|
module github.com/AdguardTeam/AdGuardHome/internal/tools
|
||||||
|
|
||||||
go 1.20
|
go 1.21.7
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fzipp/gocyclo v0.6.0
|
github.com/fzipp/gocyclo v0.6.0
|
||||||
github.com/golangci/misspell v0.4.1
|
github.com/golangci/misspell v0.4.1
|
||||||
github.com/gordonklaus/ineffassign v0.1.0
|
github.com/gordonklaus/ineffassign v0.1.0
|
||||||
github.com/kisielk/errcheck v1.6.3
|
github.com/kisielk/errcheck v1.7.0
|
||||||
github.com/kyoh86/looppointer v0.2.1
|
github.com/kyoh86/looppointer v0.2.1
|
||||||
github.com/securego/gosec/v2 v2.18.2
|
github.com/securego/gosec/v2 v2.18.2
|
||||||
github.com/uudashr/gocognit v1.1.2
|
github.com/uudashr/gocognit v1.1.2
|
||||||
golang.org/x/tools v0.17.0
|
golang.org/x/tools v0.17.0
|
||||||
golang.org/x/vuln v1.0.3
|
golang.org/x/vuln v1.0.4
|
||||||
honnef.co/go/tools v0.4.6
|
honnef.co/go/tools v0.4.6
|
||||||
mvdan.cc/gofumpt v0.6.0
|
mvdan.cc/gofumpt v0.6.0
|
||||||
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14
|
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14
|
||||||
|
@ -26,9 +26,9 @@ require (
|
||||||
github.com/kyoh86/nolint v0.0.1 // indirect
|
github.com/kyoh86/nolint v0.0.1 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // 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 v0.0.0-20230321023759-10a507213a29 // indirect
|
||||||
golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a // indirect
|
golang.org/x/exp/typeparams v0.0.0-20240205201215-2c58cdc269a3 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.16.0 // indirect
|
golang.org/x/sys v0.17.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,39 +3,53 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
|
||||||
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
|
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/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 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 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 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g=
|
github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g=
|
||||||
github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI=
|
github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI=
|
||||||
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=
|
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=
|
||||||
|
github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||||
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||||
github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=
|
github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=
|
||||||
github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
|
github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
|
||||||
github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8=
|
github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0=
|
||||||
github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
|
github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kyoh86/looppointer v0.2.1 h1:Jx9fnkBj/JrIryBLMTYNTj9rvc2SrPS98Dg0w7fxdJg=
|
github.com/kyoh86/looppointer v0.2.1 h1:Jx9fnkBj/JrIryBLMTYNTj9rvc2SrPS98Dg0w7fxdJg=
|
||||||
github.com/kyoh86/looppointer v0.2.1/go.mod h1:q358WcM8cMWU+5vzqukvaZtnJi1kw/MpRHQm3xvTrjw=
|
github.com/kyoh86/looppointer v0.2.1/go.mod h1:q358WcM8cMWU+5vzqukvaZtnJi1kw/MpRHQm3xvTrjw=
|
||||||
github.com/kyoh86/nolint v0.0.1 h1:GjNxDEkVn2wAxKHtP7iNTrRxytRZ1wXxLV5j4XzGfRU=
|
github.com/kyoh86/nolint v0.0.1 h1:GjNxDEkVn2wAxKHtP7iNTrRxytRZ1wXxLV5j4XzGfRU=
|
||||||
github.com/kyoh86/nolint v0.0.1/go.mod h1:1ZiZZ7qqrZ9dZegU96phwVcdQOMKIqRzFJL3ewq9gtI=
|
github.com/kyoh86/nolint v0.0.1/go.mod h1:1ZiZZ7qqrZ9dZegU96phwVcdQOMKIqRzFJL3ewq9gtI=
|
||||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||||
github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA=
|
github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA=
|
||||||
|
github.com/onsi/gomega v1.28.1/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/securego/gosec/v2 v2.18.2 h1:DkDt3wCiOtAHf1XkiXZBhQ6m6mK/b9T/wD257R3/c+I=
|
github.com/securego/gosec/v2 v2.18.2 h1:DkDt3wCiOtAHf1XkiXZBhQ6m6mK/b9T/wD257R3/c+I=
|
||||||
github.com/securego/gosec/v2 v2.18.2/go.mod h1:xUuqSF6i0So56Y2wwohWAmB07EdBkUN6crbLlHwbyJs=
|
github.com/securego/gosec/v2 v2.18.2/go.mod h1:xUuqSF6i0So56Y2wwohWAmB07EdBkUN6crbLlHwbyJs=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
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 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI=
|
||||||
github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k=
|
github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k=
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||||
|
@ -49,14 +63,13 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
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 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a h1:8qmSSA8Gz/1kTrCe0nqR0R3Gb/NDhykzWw2q2mWZydM=
|
golang.org/x/exp/typeparams v0.0.0-20240205201215-2c58cdc269a3 h1:1hsZWSQgrpqFJbqlg8HNhQ2/U/7IQELXYWTjuCfHNcM=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
golang.org/x/exp/typeparams v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.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-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-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-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
@ -64,6 +77,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
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.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||||
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -79,24 +93,24 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-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.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
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-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.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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
|
||||||
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
||||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||||
golang.org/x/vuln v1.0.3 h1:k2wzzWGpdntQzNsCOLTabCFk76oTe69BPwad5H52F4w=
|
golang.org/x/vuln v1.0.4 h1:SP0mPeg2PmGCu03V+61EcQiOjmpri2XijexKdzv8Z1I=
|
||||||
golang.org/x/vuln v1.0.3/go.mod h1:NbJdUQhX8jY++FtuhrXs2Eyx0yePo9pF7nPlIjo9aaQ=
|
golang.org/x/vuln v1.0.4/go.mod h1:NbJdUQhX8jY++FtuhrXs2Eyx0yePo9pF7nPlIjo9aaQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/ioutil"
|
"github.com/AdguardTeam/golibs/ioutil"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(a.garipov): Make configurable.
|
// TODO(a.garipov): Make configurable.
|
||||||
|
|
|
@ -87,6 +87,22 @@ Optional environment:
|
||||||
* `VERSION`: release version. Will be set by `version.sh` if it is unset or
|
* `VERSION`: release version. Will be set by `version.sh` if it is unset or
|
||||||
if it has the default `Makefile` value of `v0.0.0`.
|
if it has the default `Makefile` value of `v0.0.0`.
|
||||||
|
|
||||||
|
We're using Go's [forward compatibility mechanism][go-toolchain] for updating
|
||||||
|
the Go version. This means that if your `go` version is 1.21+ but is different
|
||||||
|
from the one required by AdGuard Home, the `go` tool will automatically download
|
||||||
|
the required version.
|
||||||
|
|
||||||
|
If you want to use the version installed on your builder, run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get go@$YOUR_VERSION
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
|
and call `make` with `GOTOOLCHAIN=local`.
|
||||||
|
|
||||||
|
[go-toolchain]: https://go.dev/blog/toolchain
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### `clean.sh`: Cleanup
|
### `clean.sh`: Cleanup
|
||||||
|
|
|
@ -9,12 +9,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -6,7 +6,9 @@ set -e -f -u
|
||||||
# Bump this number every time a significant change is made to this
|
# Bump this number every time a significant change is made to this
|
||||||
# script.
|
# script.
|
||||||
#
|
#
|
||||||
# AdGuard-Project-Version: 1
|
# AdGuard-Project-Version: 2
|
||||||
|
|
||||||
|
# TODO(a.garipov): Add pre-merge-commit.
|
||||||
|
|
||||||
# Only show interactive prompts if there a terminal is attached to
|
# Only show interactive prompts if there a terminal is attached to
|
||||||
# stdout. While this technically doesn't guarantee that reading from
|
# stdout. While this technically doesn't guarantee that reading from
|
||||||
|
|
|
@ -30,33 +30,6 @@ set -f -u
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Warnings
|
|
||||||
|
|
||||||
go_version="$( "${GO:-go}" version )"
|
|
||||||
readonly go_version
|
|
||||||
|
|
||||||
go_min_version='go1.20.12'
|
|
||||||
go_version_msg="
|
|
||||||
warning: your go version (${go_version}) is different from the recommended minimal one (${go_min_version}).
|
|
||||||
if you have the version installed, please set the GO environment variable.
|
|
||||||
for example:
|
|
||||||
|
|
||||||
export GO='${go_min_version}'
|
|
||||||
"
|
|
||||||
readonly go_min_version go_version_msg
|
|
||||||
|
|
||||||
case "$go_version"
|
|
||||||
in
|
|
||||||
('go version'*"$go_min_version"*)
|
|
||||||
# Go on.
|
|
||||||
;;
|
|
||||||
(*)
|
|
||||||
echo "$go_version_msg" 1>&2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Simple analyzers
|
# Simple analyzers
|
||||||
|
|
||||||
# blocklist_imports is a simple check against unwanted packages. The following
|
# blocklist_imports is a simple check against unwanted packages. The following
|
||||||
|
@ -74,18 +47,22 @@ esac
|
||||||
#
|
#
|
||||||
# See https://github.com/golang/go/issues/45200.
|
# See https://github.com/golang/go/issues/45200.
|
||||||
#
|
#
|
||||||
# * Package sort is replaced by golang.org/x/exp/slices.
|
# * Package sort is replaced by package slices.
|
||||||
#
|
#
|
||||||
# * Package unsafe is… unsafe.
|
# * 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.
|
# * Package golang.org/x/net/context has been moved into stdlib.
|
||||||
#
|
#
|
||||||
# Currently, the only standard exception are files generated from protobuf
|
# Currently, the only standard exception are files generated from protobuf
|
||||||
# schemas, which use package reflect. If your project needs more exceptions,
|
# schemas, which use package reflect. If your project needs more exceptions,
|
||||||
# add and document them.
|
# add and document them.
|
||||||
#
|
#
|
||||||
# TODO(a.garipov): Add deprecated packages golang.org/x/exp/maps and
|
# TODO(a.garipov): Add goilbs/log.
|
||||||
# golang.org/x/exp/slices once all projects switch to Go 1.21.
|
#
|
||||||
|
# TODO(a.garipov): Add deprecated package golang.org/x/exp/maps once all
|
||||||
|
# projects switch to Go 1.22.
|
||||||
blocklist_imports() {
|
blocklist_imports() {
|
||||||
git grep\
|
git grep\
|
||||||
-e '[[:space:]]"errors"$'\
|
-e '[[:space:]]"errors"$'\
|
||||||
|
@ -94,6 +71,7 @@ blocklist_imports() {
|
||||||
-e '[[:space:]]"reflect"$'\
|
-e '[[:space:]]"reflect"$'\
|
||||||
-e '[[:space:]]"sort"$'\
|
-e '[[:space:]]"sort"$'\
|
||||||
-e '[[:space:]]"unsafe"$'\
|
-e '[[:space:]]"unsafe"$'\
|
||||||
|
-e '[[:space:]]"golang.org/x/exp/slices"$'\
|
||||||
-e '[[:space:]]"golang.org/x/net/context"$'\
|
-e '[[:space:]]"golang.org/x/net/context"$'\
|
||||||
-n\
|
-n\
|
||||||
-- '*.go'\
|
-- '*.go'\
|
||||||
|
@ -124,12 +102,10 @@ underscores() {
|
||||||
underscore_files="$(
|
underscore_files="$(
|
||||||
git ls-files '*_*.go'\
|
git ls-files '*_*.go'\
|
||||||
| grep -F\
|
| grep -F\
|
||||||
-e '_big.go'\
|
|
||||||
-e '_bsd.go'\
|
-e '_bsd.go'\
|
||||||
-e '_darwin.go'\
|
-e '_darwin.go'\
|
||||||
-e '_freebsd.go'\
|
-e '_freebsd.go'\
|
||||||
-e '_linux.go'\
|
-e '_linux.go'\
|
||||||
-e '_little.go'\
|
|
||||||
-e '_next.go'\
|
-e '_next.go'\
|
||||||
-e '_openbsd.go'\
|
-e '_openbsd.go'\
|
||||||
-e '_others.go'\
|
-e '_others.go'\
|
||||||
|
|
|
@ -51,9 +51,9 @@ readonly count_flags cover_flags shuffle_flags timeout_flags
|
||||||
"$go" test\
|
"$go" test\
|
||||||
"$count_flags"\
|
"$count_flags"\
|
||||||
"$cover_flags"\
|
"$cover_flags"\
|
||||||
"$shuffle_flags"\
|
|
||||||
"$race_flags"\
|
"$race_flags"\
|
||||||
|
"$shuffle_flags"\
|
||||||
"$timeout_flags"\
|
"$timeout_flags"\
|
||||||
"$x_flags"\
|
|
||||||
"$v_flags"\
|
"$v_flags"\
|
||||||
|
"$x_flags"\
|
||||||
./...
|
./...
|
||||||
|
|
|
@ -30,8 +30,6 @@ set -e -f -u
|
||||||
go="${GO:-go}"
|
go="${GO:-go}"
|
||||||
readonly go
|
readonly go
|
||||||
|
|
||||||
# TODO(a.garipov): Add goconst?
|
|
||||||
|
|
||||||
# Remove only the actual binaries in the bin/ directory, as developers may add
|
# Remove only the actual binaries in the bin/ directory, as developers may add
|
||||||
# their own scripts there. Most commonly, a script named “go” for tools that
|
# their own scripts there. Most commonly, a script named “go” for tools that
|
||||||
# call the go binary and need a particular version.
|
# call the go binary and need a particular version.
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
verbose="${VERBOSE:-0}"
|
||||||
|
readonly verbose
|
||||||
|
|
||||||
|
if [ "$verbose" -gt '1' ]
|
||||||
|
then
|
||||||
|
env
|
||||||
|
set -x
|
||||||
|
x_flags='-x=1'
|
||||||
|
elif [ "$verbose" -gt '0' ]
|
||||||
|
then
|
||||||
|
set -x
|
||||||
|
x_flags='-x=0'
|
||||||
|
else
|
||||||
|
set +x
|
||||||
|
x_flags='-x=0'
|
||||||
|
fi
|
||||||
|
readonly x_flags
|
||||||
|
|
||||||
|
set -e -f -u
|
||||||
|
|
||||||
|
go="${GO:-go}"
|
||||||
|
readonly go
|
||||||
|
|
||||||
|
cd ./internal/tools/
|
||||||
|
"$go" get -u
|
||||||
|
"$go" mod tidy
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,7 +16,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/ioutil"
|
"github.com/AdguardTeam/golibs/ioutil"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// download and save all translations.
|
// download and save all translations.
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -18,7 +19,6 @@ import (
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
Loading…
Reference in New Issue