Compare commits

..

47 Commits

Author SHA1 Message Date
Ainar Garipov
13f708b483 Pull request: * querylog: fix end of log handling
Merge in DNS/adguard-home from 2229-query-log to master

Closes #2229.

Squashed commit of the following:

commit 32508a3f3b1e098869e1649a2774f1f17d14d41f
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 10 16:51:25 2020 +0300

    * querylog: add test

commit 774159cc313a0284a8bb8327489671e5d7a3e4eb
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 10 15:26:26 2020 +0300

    * querylog: better errors

commit 27b13a4dcaff9e8f9b08aec81c0c03f62ebd3fa5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 10 15:18:51 2020 +0300

    * querylog: fix end of log handling
2020-11-10 19:00:55 +03:00
Ainar Garipov
979874c92b Pull request: * all: update dnsproxy
Merge in DNS/adguard-home from update-dnsproxy to master

Closes #2252.

Squashed commit of the following:

commit e66b2a0a2555d8ae75b42fd64b83b654810a65c2
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 10 11:56:22 2020 +0300

    * all: update dnsproxy
2020-11-10 15:19:25 +03:00
Ainar Garipov
3cc5bf210d Pull request: * dhcpd: send secondary dns as well
Merge in DNS/adguard-home from 1708-secondary-dns to master

Updates #1708.

Squashed commit of the following:

commit 4529452e31131763f00c9c834cc95638f1a3d142
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Nov 9 18:12:57 2020 +0300

    * dhcpd: send secondary dns as well
2020-11-09 19:27:04 +03:00
Ainar Garipov
1e583315a8 Pull request: * all: update dnsproxy
Merge in DNS/adguard-home from update-dnsproxy to master

Squashed commit of the following:

commit 6ed03c2131b93e3882e8f820e110696a41223267
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Nov 9 13:13:36 2020 +0300

    * all: update dnsproxy
2020-11-09 14:44:21 +03:00
Andrey Meshkov
ee8a033472 Merge branch 'master' of git://github.com/gontazaka/AdGuardHome into gontazaka-master 2020-11-09 11:55:45 +03:00
Andrey Meshkov
b85c0b3bf7 Merge branch 'docker-workflow' of git://github.com/crazy-max/AdGuardHome into crazy-max-docker-workflow 2020-11-09 11:28:27 +03:00
CrazyMax
859ed209a0 Update docker workflow 2020-11-08 23:06:52 +01:00
CrazyMax
c6a6f05b1b Use zoneinfo from Go 2020-11-08 22:57:47 +01:00
gontazaka
5bf330bf14 Fix link address 2020-11-07 13:28:19 +09:00
Ainar Garipov
eefa553100 Pull request: - isdelve: remove unused package
Merge in DNS/adguard-home from remove-isdelve to master

Squashed commit of the following:

commit aa305fa46713b39a8299754e8fd557cbadcb7cc3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Nov 6 18:06:07 2020 +0300

    - isdelve: remove unused package
2020-11-06 20:20:15 +03:00
Ainar Garipov
298f74ba81 Pull request: * all: allow multiple hosts in reverse lookups
Merge in DNS/adguard-home from 2269-multiple-hosts to master

For #2269.

Squashed commit of the following:

commit f8ae452540b106f2d5b130b8edb08c4e76b003f4
Merge: 8dd06f7cc 3e1f92225
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Nov 6 17:28:12 2020 +0300

    Merge branch 'master' into 2269-multiple-hosts

commit 8dd06f7cca27ec32a4690e2673603b166f82af0a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Nov 5 20:28:33 2020 +0300

    * all: allow multiple hosts in reverse lookups
2020-11-06 17:34:40 +03:00
Eugene Burkov
3e1f922252 Pull request:* all: fix all staticcheck simplification and unused warnings
Merge in DNS/adguard-home from 2270-fix-s-u-warnings to master

Squashed commit of the following:

commit 03e0f78bd471057007c2d4042ee26eda2bbc9b29
Merge: 50dc3ef5c 7e16fda57
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Nov 6 11:54:09 2020 +0300

    Merge branch 'master' into 2270-fix-s-u-warnings

commit 50dc3ef5c44a5fdc941794c26784b0c44d7b5aa0
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 19:48:54 2020 +0300

    * all: improve code quality

commit d6d804f759ce3e47154a389b427550e72c4b9090
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 18:03:35 2020 +0300

    * all: fix all staticcheck simplification and unused warnings

    Closes #2270.
2020-11-06 12:15:08 +03:00
Andrey Meshkov
7e16fda57b Change the default for max_goroutines #2257
Closes #2257

* commit '84ca2f58a8b4379a3ee6d0bd9f754be20a3ecaea':
  Added a more detailed comment
  Change the default for max_goroutines #2257
2020-11-05 21:14:05 +03:00
Ainar Garipov
11e794f554 Pull request: * .goreleaser: use a different snap plug for cap_net_raw
Merge in DNS/adguard-home from 2228-new-plug to master

For #2228.

Squashed commit of the following:

commit a073c8e033b1dfbdbd3fff8d773c6a2406b6211b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Nov 5 17:02:56 2020 +0300

    * .goreleaser: use a different snap plug for cap_net_raw
2020-11-05 17:52:03 +03:00
Eugene Burkov
2baa33fb1f Pull request:* all: remove github.com/joomcode/errorx dependency
Merge in DNS/adguard-home from 2240-removing-errorx-dependency to master

Squashed commit of the following:

commit 5bbe0567356f06e3b9ee5b3dc38d357b472cacb1
Merge: a6040850d 02d16a0b4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 14:32:22 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit a6040850da3cefb131208097477b0956e80063fb
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 14:23:36 2020 +0300

    * dhcpd: convert some abbreviations to lowercase.

commit d05bd51b994906b0ff52c5a8e779bd1f512f4bb7
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Nov 5 12:47:20 2020 +0300

    * agherr: last final fixes

commit 164bca55035ff44e50b0abb33e129a0d24ffe87c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 19:11:10 2020 +0300

    * all: final fixes again

commit a0ac26f409c0b28a176cf2861d52c2f471b59484
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 18:51:39 2020 +0300

    * all: final fixes

commit 6147b02d402b513323b07e85856b348884f3a088
Merge: 9fd3af1a3 62cc334f4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 18:26:03 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit 9fd3af1a39a3189b5c41315a8ad1568ae5cb4fc9
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 18:23:08 2020 +0300

    * all: remove useless helper

commit 7cd9aeae639762b28b25f354d69c5cf74f670211
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 17:19:26 2020 +0300

    * agherr: improved code tidiness

commit a74a49236e9aaace070646dac710de9201105262
Merge: dc9dedbf2 df34ee5c0
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 16:54:29 2020 +0300

    Merge branch 'master' into 2240-removing-errorx-dependency

commit dc9dedbf205756e3adaa3bc776d349bf3d8c69a5
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 16:40:08 2020 +0300

    * agherr: improve and cover by tests

commit fd6bfe9e282156cc60e006cb7cd46cce4d3a07a8
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 14:06:27 2020 +0300

    * all: improve code quality

commit ea00c2f8c5060e9611f9a80cfd0e4a039526d0c4
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 13:03:57 2020 +0300

    * all: fix linter style warnings

commit 8e75e1a681a7218c2b4c69adfa2b7e1e2966f9ac
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Nov 3 12:29:26 2020 +0300

    * all: remove github.com/joomcode/errorx dependency

    Closes #2240.
2020-11-05 15:20:57 +03:00
Ainar Garipov
02d16a0b40 Pull request: * home, openapi: improve docs and responses
Merge in DNS/adguard-home from 2243-better-docs to master

Closes #2243.

Squashed commit of the following:

commit 26c655a0e4339528870633c2cdf39c3b5c486b1d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Nov 5 12:51:43 2020 +0300

    * openapi: improve more

commit dc0ab9857787d14eb0686814a4f3c8f917698bee
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 20:40:32 2020 +0300

    * home, openapi: improve docs and responses
2020-11-05 13:59:57 +03:00
Andrey Meshkov
84ca2f58a8 Added a more detailed comment 2020-11-05 13:26:13 +03:00
Andrey Meshkov
bc20917840 Change the default for max_goroutines #2257 2020-11-04 13:41:40 +03:00
Artem Baskal
62cc334f46 + client: 2241 Add DNS-over-QUIC string
Close #2241

* commit '3d19f91bede4aee8ee44a4b0a31c4c7b91405785':
  + client: 2241 Add DNS-over-QUIC string
2020-11-03 18:05:14 +03:00
Ainar Garipov
d398e4b01c Pull request: 2250 config reload fix
Merge in DNS/adguard-home from 2250-config-reload-fix to master

Closes #2250.

Squashed commit of the following:

commit 928f28a0732c14f24576de02d0a9fcd34f484c63
Author: Vladislav Alekseev <vldrus@gmail.com>
Date:   Mon Nov 2 02:53:51 2020 +0300

    TLS: use correct config on reload after receiving SIGHUP

commit 9e10d84cf9fbf3298d7f426903dfa4f20f39024b
Author: Vladislav Alekseev <vldrus@gmail.com>
Date:   Mon Nov 2 02:52:32 2020 +0300

    Service: reload config (-s reload): fix for parsing application pid if 'ps' return space padded value
2020-11-03 17:44:03 +03:00
ArtemBaskal
3d19f91bed + client: 2241 Add DNS-over-QUIC string 2020-11-03 17:32:56 +03:00
Ainar Garipov
df34ee5c09 Pull request: * dnsforward, querylog: set client_proto for logs correctly
Merge in DNS/adguard-home from 2241-doq-logs to master

Squashed commit of the following:

commit a15cab05358e3c0b97f8257f8b9628fa590e7e7d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 14:22:25 2020 +0300

    * all: update dnsproxy

commit 5fb0919a7528dc6ee7a433a8096b550f3691771c
Merge: b22b1dff4 64c1a68fb
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 14:22:15 2020 +0300

    Merge branch 'master' into 2241-doq-logs

commit b22b1dff43e541d77160fd5c234483bbf0f6d8de
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Nov 3 12:37:23 2020 +0300

    * dnsforward, querylog: set client_proto for logs correctly
2020-11-03 15:39:55 +03:00
Artem Baskal
64c1a68fb9 - client: 2254 Fix textarea with comments fonts
Close #2254

* commit 'd747185b45e9300b771c69dd27a2757fc40b52f6':
  - client: 2254 Fix textarea with comments fonts
2020-11-03 12:36:57 +03:00
ArtemBaskal
d747185b45 - client: 2254 Fix textarea with comments fonts 2020-11-03 12:07:01 +03:00
Eugene Burkov
8afdc049ef Pull request:* all: replace our pprof fork with net/http/pprof
Merge in DNS/adguard-home from 2239-remove-pprof-fork to master

Squashed commit of the following:

commit eefcaae015292768b26a70a27d352d3e2aa3f9ef
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Oct 30 20:00:05 2020 +0300

    * all: replace our pprof fork with net/http/pprof

    Closes #2239.
2020-11-02 16:32:33 +03:00
Eugene Burkov
812b43a4b3 Pull request:* all: fix all staticcheck SA warnings
Merge in DNS/adguard-home from 2238-fix-static-analisys-warnings to master

Squashed commit of the following:

commit 721ca6fa1cbfdfe9d414e6ed52fec4a64653fb52
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Oct 30 15:48:10 2020 +0300

    * all: fix all staticcheck SA warnings

    Closes #2238.
2020-10-30 19:18:51 +03:00
Ainar Garipov
ae8de95d89 Pull request: * all: move internal Go packages to internal/
Merge in DNS/adguard-home from 2234-move-to-internal to master

Squashed commit of the following:

commit d26a288cabeac86f9483fab307677b1027c78524
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Oct 30 12:44:18 2020 +0300

    * all: move internal Go packages to internal/

    Closes #2234.
2020-10-30 13:32:02 +03:00
Ainar Garipov
df3fa595a2 Pull request: * home: improve naming in mobileconfig handlers
Merge in DNS/adguard-home from 2235-mobileconfig-server-name to master

* commit '98f6843aab8ff69606f44f6a5721d5f2a5707a0f':
  * home: improve naming in mobileconfig handlers
2020-10-30 12:41:34 +03:00
Ainar Garipov
98f6843aab * home: improve naming in mobileconfig handlers
Updates #2235.
2020-10-29 19:42:25 +03:00
Ainar Garipov
9761f13399 Pull request: .goreleaser: add a new snap plug to bind to devices
Merge in DNS/adguard-home from 2228-linux-caps to master

* commit 'a376bf915a397e71763bed9e86ab2767d5467e85':
  .goreleaser: add a new snap plug to bind to devices
2020-10-29 18:57:38 +03:00
Ainar Garipov
a376bf915a .goreleaser: add a new snap plug to bind to devices
Closes #2228.
2020-10-29 17:27:14 +03:00
Ainar Garipov
da5c1ebbbf Pull request: * querylog: use the vanilla errors package
Merge in DNS/adguard-home from remove-pkg-errors to master

* commit '40ebccaab415f957c8234ad2c3a9615225ddae68':
  * querylog: use the vanilla errors package
2020-10-29 12:22:33 +03:00
Ainar Garipov
40ebccaab4 * querylog: use the vanilla errors package 2020-10-28 19:34:29 +03:00
Andrey Meshkov
d1e55c31af Update locales 2020-10-28 14:19:29 +03:00
Andrey Meshkov
6b64bfac00 * (ui): update translations 2020-10-22 23:36:18 +03:00
Andrey Meshkov
e37ccdbb70 - (dnsforward): fix ipset race
https://github.com/AdguardTeam/AdGuardHome/pull/2182#issuecomment-707807737
2020-10-22 23:31:51 +03:00
Andrey Meshkov
0b43bf4cd9 * (dnsfilter): urlfilter v0.12.3 - $client modifier and CIDR 2020-10-22 23:26:35 +03:00
Andrey Meshkov
fe87bdc9cd * (documentation): added privacy to readme
Closes: #1960
2020-10-22 23:21:10 +03:00
Andrey Meshkov
f75a0f8719 - (ui): wrong link
Closes: #2209
2020-10-22 18:33:51 +03:00
Andrey Meshkov
2ba85ba8e1 - (ui): API requests don't work when reverse proxy is in use
Closes: #2197
2020-10-22 18:29:52 +03:00
Andrey Meshkov
052a9ae196 - (home): test upstream shouldn't fail with upstreams file
Closes: #2212
2020-10-22 18:20:16 +03:00
Artem Baskal
32b24ce093 + dnsfilter, client: Add qq to blocked services
Squashed commit of the following:

commit ffb2a1065fc9edd2b840cccbb96a0a2c1334bf00
Merge: 0f966d5b 3acfaa16
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Oct 20 11:19:39 2020 +0300

    Merge branch 'master' into dnsfilter/update_blocked_services

commit 0f966d5b00f96c93bf778e944d68f62ebcdeaa50
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Oct 19 20:47:22 2020 +0300

    Add qq icon to blocked services

commit f9c42551bbb442f83c6354314fc42ea174aacf4b
Author: ifurther <55025025+ifurther@users.noreply.github.com>
Date:   Sun Jun 7 12:19:05 2020 +0000

    Add qq to blocked services
2020-10-20 11:26:39 +03:00
Andrey Meshkov
3acfaa162f Pull reques: dnsfilter/blocked_services: update netflix with nflxso.net SLD
Merge in DNS/adguard-home from blocked-service-netflix-nflxso to master

* commit 'e0ddb1c0eacb6b60e61a6bac9e028ffc64debf04':
  dnsfilter/blocked_services: update netflix with nflxso.net SLD
2020-10-15 11:23:08 +03:00
Andrey Meshkov
345a97c4af Pull request: + client: Update dns examples
Merge in DNS/adguard-home from client/update-dns-examples to master

* commit 'a7cf717116a78dbbad086ec149584c7f3c45d33f':
  Update DNS
  Update DNS examples
2020-10-15 11:22:49 +03:00
KizunaH
a7cf717116 Update DNS 2020-10-14 18:59:42 +03:00
KizunaH
8315b46f30 Update DNS examples 2020-10-14 18:59:42 +03:00
David Sheets
e0ddb1c0ea dnsfilter/blocked_services: update netflix with nflxso.net SLD 2020-10-13 16:42:43 +01:00
153 changed files with 1339 additions and 1251 deletions

View File

@@ -134,23 +134,21 @@ jobs:
runs-on: ubuntu-latest
needs: test
steps:
-
name: Set up Docker Buildx
uses: crazy-max/ghaction-docker-buildx@v1
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Docker Buildx (build)
run: |
make docker-multi-arch
-
name: Clear
if: always() && startsWith(github.ref, 'refs/tags/v')
run: |
rm -f ${HOME}/.docker/config.json
notify:
needs: [app, docker]

View File

@@ -90,7 +90,13 @@ snapcrafts:
apps:
adguard-home:
command: AdGuardHome -w $SNAP_DATA --no-check-update
plugs: [ network-bind ]
plugs:
# Add the "netrwork-bind" plug to bind to interfaces.
- network-bind
# Add the "netrwork-control" plug to be able to bind to ports below
# 1024 (cap_net_bind_service) and also to bind to a particular
# interface using SO_BINDTODEVICE (cap_net_raw).
- network-control
daemon: simple
adguard-home-web:
command: adguard-home-web.sh

View File

@@ -1587,7 +1587,7 @@ Response:
"upstream":"...", // Upstream URL starting with tcp://, tls://, https://, or with an IP address
"answer_dnssec": true,
"client":"127.0.0.1",
"client_proto": "" (plain) | "doh" | "dot",
"client_proto": "" (plain) | "doh" | "dot" | "doq",
"elapsedMs":"0.098403",
"filterId":1,
"question":{

View File

@@ -59,7 +59,6 @@ RUN apk --update --no-cache add \
ca-certificates \
libcap \
libressl \
tzdata \
&& rm -rf /tmp/* /var/cache/apk/*
COPY --from=builder --chown=nobody:nogroup /app/AdGuardHome /opt/adguardhome/AdGuardHome

View File

@@ -109,7 +109,7 @@ $(error DOCKER_IMAGE_NAME value is not set)
endif
# OS-specific flags
TEST_FLAGS := -race
TEST_FLAGS := --race -v
ifeq ($(OS),Windows_NT)
TEST_FLAGS :=
endif
@@ -160,11 +160,13 @@ lint-go:
@echo Running go linter
golangci-lint run
test:
@echo Running JS unit-tests
test: test-js test-go
test-js:
npm run test --prefix client
@echo Running Go unit-tests
go test $(TEST_FLAGS) -v -coverprofile=coverage.txt -covermode=atomic ./...
test-go:
go test $(TEST_FLAGS) --coverprofile coverage.txt ./...
ci: client_with_deps
go mod download

View File

@@ -60,6 +60,7 @@ It operates as a DNS server that re-routes tracking domains to a "black hole," t
* [Other](#help-other)
* [Projects that use AdGuardHome](#uses)
* [Acknowledgments](#acknowledgments)
* [Privacy](#privacy)
<a id="getting-started"></a>
## Getting Started
@@ -292,7 +293,7 @@ Here is a link to AdGuard Home project: https://crowdin.com/project/adguard-appl
Here's what you can also do to contribute:
1. [Look for issues](https://github.com/AdguardTeam/AdGuardHome/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) marked as "help wanted".
2. Actualize the list of *Blocked services*. It it can be found in [dnsfilter/blocked_services.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/dnsfilter/blocked_services.go).
2. Actualize the list of *Blocked services*. It it can be found in [dnsfilter/blocked_services.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/internal/dnsfilter/blocked_services.go).
3. Actualize the list of known *trackers*. It it can be found in [client/src/helpers/trackers/adguard.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/trackers/adguard.json).
4. Actualize the list of vetted *blocklists*. It it can be found in [client/src/helpers/filters/filters.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/filters/filters.json).
@@ -326,3 +327,8 @@ This software wouldn't have been possible without:
You might have seen that [CoreDNS](https://coredns.io) was mentioned here before — we've stopped using it in AdGuardHome. While we still use it on our servers for [AdGuard DNS](https://adguard.com/adguard-dns/overview.html) service, it seemed like an overkill for Home as it impeded with Home features that we plan to implement.
For a full list of all node.js packages in use, please take a look at [client/package.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/package.json) file.
<a id="privacy"></a>
## Privacy
Our main idea is that you are the one, who should be in control of your data. So it is only natural, that AdGuard Home does not collect any usage statistics, and does not use any web services unless you configure it to do so. Full policy with every bit that _could in theory be_ sent by AdGuard Home is available [here](https://adguard.com/en/privacy/home.html).

2
client/constants.js vendored
View File

@@ -3,7 +3,7 @@ const BUILD_ENVS = {
prod: 'production',
};
const BASE_URL = '/control';
const BASE_URL = 'control';
module.exports = {
BUILD_ENVS,

View File

@@ -249,6 +249,7 @@
"blocking_ipv6": "Blocking IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"dns_over_quic": "DNS-over-QUIC",
"download_mobileconfig_doh": "Download .mobileconfig for DNS-over-HTTPS",
"download_mobileconfig_dot": "Download .mobileconfig for DNS-over-TLS",
"plain_dns": "Plain DNS",
@@ -587,4 +588,4 @@
"adg_will_drop_dns_queries": "AdGuard Home will be dropping all DNS queries from this client.",
"client_not_in_allowed_clients": "The client is not allowed because it is not in the \"Allowed clients\" list.",
"experimental": "Experimental"
}
}

View File

@@ -1,7 +1,7 @@
{
"client_settings": "Configuración de clientes",
"example_upstream_reserved": "puedes especificar el DNS de subida <0>para un dominio específico</0>",
"example_upstream_comment": "Puedes especificar el comentario",
"example_upstream_comment": "puedes especificar el comentario",
"upstream_parallel": "Usar peticiones paralelas para acelerar la resolución al consultar simultáneamente a todos los servidores de subida",
"parallel_requests": "Peticiones paralelas",
"load_balancing": "Balanceo de carga",

View File

@@ -1,12 +1,13 @@
{
"client_settings": "Kliens beállítások",
"example_upstream_reserved": "Megadhat egy DNS kiszolgálót <0>egy adott domainhez vagy domainekhez</0>",
"example_upstream_comment": "Megadhat egy megjegyzést",
"upstream_parallel": "Használjon párhuzamos lekéréseket a domainek feloldásának felgyorsításához az összes upstream kiszolgálóra való egyidejű lekérdezéssel",
"parallel_requests": "Párhuzamos lekérések",
"load_balancing": "Terheléselosztás",
"load_balancing_desc": "Egyszerre csak egy szerverről történjen lekérdezés. Az AdGuard Home egy súlyozott, véletlenszerű algoritmust fog használni a megfelelő szerver kiválasztására, így a leggyorsabb szervert gyakrabban fogja használni.",
"bootstrap_dns": "Bootstrap DNS kiszolgálók",
"bootstrap_dns_desc": "Bootstrap DNS szerverek feloldják a megadott DoH/DoT feloldók IP-címeit.",
"bootstrap_dns_desc": "A Bootstrap DNS szerverek a DoH/DoT feloldók IP-címeinek feloldására szolgálnak.",
"check_dhcp_servers": "DHCP szerverek keresése",
"save_config": "Konfiguráció mentése",
"enabled_dhcp": "DHCP szerver engedélyezve",
@@ -89,10 +90,10 @@
"disable_protection": "Védelem letiltása",
"disabled_protection": "Letiltott védelem",
"refresh_statics": "Statisztikák frissítése",
"dns_query": "DNS lekérdezések",
"dns_query": "DNS lekérdezés",
"blocked_by": "<0>Szűrők által blokkolt</0>",
"stats_malware_phishing": "Blokkolt kártevő/adathalászat",
"stats_adult": "Blokkolva a felnőtt tartalmak által",
"stats_adult": "Blokkolt felnőtt tartalom",
"stats_query_domain": "Leglátogatottabb domainek",
"for_last_24_hours": "az utóbbi 24 órában",
"for_last_days": "az utóbbi {{count}} napban",
@@ -132,6 +133,8 @@
"encryption_settings": "Titkosítási beállítások",
"dhcp_settings": "DHCP beállítások",
"upstream_dns": "Upstream DNS-kiszolgálók",
"upstream_dns_help": "Adja meg a szerverek címeit soronként. <a>Tudjon meg többet</a> a DNS szerverek bekonfigurálásáról.",
"upstream_dns_configured_in_file": "Beállítva itt: {{path}}",
"test_upstream_btn": "Upstreamek tesztelése",
"upstreams": "Upstream-ek",
"apply_btn": "Alkalmaz",
@@ -185,6 +188,7 @@
"example_upstream_regular": "hagyományos DNS (UDP felett)",
"example_upstream_dot": "titkosított <0>DNS-over-TLS</0>",
"example_upstream_doh": "titkosított <0>DNS-over-HTTPS</0>",
"example_upstream_doq": "titkosított <0>DNS-over-QUIC</0>",
"example_upstream_sdns": "használhatja a <0> DNS Stamps</0>-ot a <1>DNSCrypt</1> vagy a <2>DNS-over-HTTPS</2> feloldások érdekében",
"example_upstream_tcp": "hagyományos DNS (TCP felett)",
"all_lists_up_to_date_toast": "Már minden lista naprakész",
@@ -193,6 +197,10 @@
"dns_test_not_ok_toast": "Szerver \"{{key}}\": nem használható, ellenőrizze, hogy helyesen írta-e be",
"unblock": "Feloldás",
"block": "Blokkolás",
"disallow_this_client": "Tiltás ennek a kliensnek",
"allow_this_client": "Engedélyezés ennek a kliensnek",
"block_for_this_client_only": "Tiltás csak ennek a kliensnek",
"unblock_for_this_client_only": "Feloldás csak ennek a kliensnek",
"time_table_header": "Idő",
"date": "Dátum",
"domain_name_table_header": "Domain név",
@@ -234,19 +242,25 @@
"blocking_mode": "Blokkolás módja",
"default": "Alapértelmezett",
"nxdomain": "NXDOMAIN",
"refused": "REFUSED",
"null_ip": "Null IP-cím",
"custom_ip": "Egyedi IP",
"blocking_ipv4": "IPv4 blokkolása",
"blocking_ipv6": "IPv6 blokkolása",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"download_mobileconfig_doh": ".mobileconfig letöltése DNS-over-HTTPS-hez",
"download_mobileconfig_dot": ".mobileconfig letöltése DNS-over-TLS-hez",
"plain_dns": "Egyszerű DNS",
"form_enter_rate_limit": "Adja meg a kérések maximális számát",
"rate_limit": "Kérések korlátozása",
"edns_enable": "EDNS kliens alhálózat engedélyezése",
"edns_cs_desc": "Ha engedélyezve van, az AdGuard Home a kliensek alhálózatait küldi el a DNS-kiszolgálóknak.",
"rate_limit_desc": "Maximálisan hány kérést küldhet egy kliens másodpercenként (0: korlátlan)",
"blocking_ipv4_desc": "A blokkolt A kéréshez visszaadandó IP-cím",
"blocking_ipv6_desc": "A blokkolt AAAA kéréshez visszaadandó IP-cím",
"blocking_mode_default": "Alapértelmezés: Válaszoljon nulla IP-címmel (vagyis 0.0.0.0 az A-hoz, :: pedig az AAAA-hoz), amikor a blokkolás egy adblock-stílusú szabállyal történik; illetve válaszoljon egy, a szabály által meghatározott IP címmel, amikor a blokkolás egy /etc/hosts stílusú szabállyal történik",
"blocking_mode_refused": "REFUSED: Válaszoljon REFUSED kóddal",
"blocking_mode_nxdomain": "NXDOMAIN: Az NXDOMAIN kóddal fog válaszolni",
"blocking_mode_null_ip": "Null IP: Nullákból álló IP-címmel válaszol (0.0.0.0 for A; :: for AAAA)",
"blocking_mode_custom_ip": "Egyedi IP: Válasz egy kézzel beállított IP címmel",
@@ -260,7 +274,7 @@
"unknown_filter": "Ismeretlen szűrő: {{filterId}}",
"known_tracker": "Ismert követő",
"install_welcome_title": "Üdvözli az AdGuard Home!",
"install_welcome_desc": "Az AdGuard Home egy, a teljes hálózatot lefedő hirdetés és követő blokkoló DNS szerver. Az a célja, hogy lehetővé tegye a teljes hálózat és az összes eszköz vezérlését, és nem igényel kliensoldali programot.",
"install_welcome_desc": "Az AdGuard Home egy, a teljes hálózatot lefedő DNS szerver, amely blokkolja a hirdetéseket és a nyomkövető rendszereket. Az a célja, hogy lehetővé tegye a teljes hálózat és az összes eszköz felügyeletét, emellett pedig nem igényel kliensoldali programot.",
"install_settings_title": "Webes admin felület",
"install_settings_listen": "Figyelő felület",
"install_settings_port": "Port",
@@ -323,6 +337,8 @@
"encryption_https_desc": "Ha a HTTPS port konfigurálva van, akkor az AdGuard Home admin felülete elérhető lesz a HTTPS-en keresztül, és ezenkívül DNS-over-HTTPS-t is biztosít a '/dns-query' helyen.",
"encryption_dot": "DNS-over-TLS port",
"encryption_dot_desc": "Ha ez a port be van állítva, az AdGuard Home DNS-over-TLS szerverként tud futni ezen a porton.",
"encryption_doq": "DNS-over-TLS port",
"encryption_doq_desc": "Ha ez a port be van állítva, akkor az AdGuard Home egy DNS-over-QUIC szerverként fog futni ezen a porton. Ez egy kísérleti funkció és nem biztos, hogy megbízható. Emellett nincs sok olyan kliens, ami támogatná ezt jelenleg.",
"encryption_certificates": "Tanúsítványok",
"encryption_certificates_desc": "A titkosítás használatához érvényes SSL tanúsítványláncot kell megadnia a domainjéhez. Ingyenes tanúsítványt kaphat a <0>{{link}}</0> webhelyen, vagy megvásárolhatja az egyik megbízható tanúsítványkibocsátó hatóságtól.",
"encryption_certificates_input": "Másolja be ide a PEM-kódolt tanúsítványt.",
@@ -401,6 +417,8 @@
"dns_privacy": "DNS Adatvédelem",
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> Használja a(z) <1>{{address}}</1> szöveget.",
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> Használja a(z) <1>{{address}}</1> szöveget.",
"setup_dns_privacy_3": "<0>Azon szoftverek listája, amelyeket használhat.</0>",
"setup_dns_privacy_4": "Az iOS14-en vagy a macOS Big Sur eszközökön le tud tölteni egy speciális, '.mobileconfig' nevű fájlt, ami hozzáadja a <highlight>DNS-over-HTTPS</highlight> vagy a <highlight>DNS-over-TLS</highlight> szervereket a DNS beállításokhoz.",
"setup_dns_privacy_android_1": "Az Android 9 natív módon támogatja a DNS-over-TLS-t. A beállításához menjen a Beállítások → Hálózat & internet → Speciális → Privát DNS menübe, és adja meg itt a domaint.",
"setup_dns_privacy_android_2": "Az <0>AdGuard for Android</0> támogatja a <1>DNS-over-HTTPS</1>-t és a <1>DNS-over-TLS</1>-t.",
"setup_dns_privacy_android_3": "Az <0>Intra</0> hozzáadja a <1>DNS-over-HTTPS</1> támogatást az Androidhoz.",
@@ -513,6 +531,7 @@
"check_reason": "Indok: {{reason}}",
"check_rule": "Szabály: {{rule}}",
"check_service": "Szolgáltatás neve: {{service}}",
"service_name": "Szolgáltatás neve",
"check_not_found": "Nem található az Ön szűrőlistái között",
"client_confirm_block": "Biztosan blokkolni szeretné a(z) \"{{ip}}\" klienst?",
"client_confirm_unblock": "Biztosan fel szeretné oldani a(z) \"{{ip}}\" kliens blokkolását?",
@@ -545,6 +564,14 @@
"milliseconds_abbreviation": "ms",
"cache_size": "Gyorsítótár mérete",
"cache_size_desc": "DNS gyorsítótár mérete (bájtokban)",
"cache_ttl_min_override": "A minimális TTL felülírása",
"cache_ttl_max_override": "A maximális TTL felülírása",
"enter_cache_size": "Adja meg a gyorsítótár méretét",
"enter_cache_ttl_min_override": "Adja meg a minimális TTL-t (másodpercben)",
"enter_cache_ttl_max_override": "Adja meg a maximális TTL-t (másodpercben)",
"cache_ttl_min_override_desc": "Megnöveli a DNS kiszolgálótól kapott rövid TTL értékeket (másodpercben), ha gyorsítótárazza a DNS kéréseket",
"cache_ttl_max_override_desc": "Állítson be egy maximális TTL értéket (másodpercben) a DNS gyorsítótár bejegyzéseihez",
"ttl_cache_validation": "A minimális gyorsítótár TTL értéknek kisebbnek vagy egyenlőnek kell lennie a maximum értékkel",
"filter_category_general": "Általános",
"filter_category_security": "Biztonság",
"filter_category_regional": "Regionális",
@@ -556,5 +583,8 @@
"setup_config_to_enable_dhcp_server": "Konfiguráció beállítása a DHCP-kiszolgáló engedélyezéséhez",
"original_response": "Eredeti válasz",
"click_to_view_queries": "Kattintson a lekérésekért",
"port_53_faq_link": "Az 53-as portot gyakran a \"DNSStubListener\" vagy a \"systemd-resolved\" (rendszer által feloldott) szolgáltatások használják. Kérjük, olvassa el <0>ezt az útmutatót</0> a probléma megoldásához."
"port_53_faq_link": "Az 53-as portot gyakran a \"DNSStubListener\" vagy a \"systemd-resolved\" (rendszer által feloldott) szolgáltatások használják. Kérjük, olvassa el <0>ezt az útmutatót</0> a probléma megoldásához.",
"adg_will_drop_dns_queries": "Az AdGuard Home eldobja az összes DNS kérést erről a kliensről.",
"client_not_in_allowed_clients": "Ez a kliens nincs engedélyezve, mivel nincs rajta az \"Engedélyezett kliensek\" listáján.",
"experimental": "Kísérleti"
}

View File

@@ -1,6 +1,7 @@
{
"client_settings": "Klientinnstillinger",
"example_upstream_reserved": "du kan bestemme en oppstrøms-DNS <0>for et spesifikt domene(r)</0>",
"example_upstream_comment": "Du kan spesifisere kommentaren",
"upstream_parallel": "Bruk parallele forespørsler for å få oppfarten på behandlinger, ved å forespørre til alle oppstrømstjenerne samtidig",
"parallel_requests": "Parallelle forespørsler",
"load_balancing": "Pågangstrykk-utjevning",
@@ -248,6 +249,8 @@
"blocking_ipv6": "IPv6-blokkering",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"download_mobileconfig_doh": "Last ned .mobileconfig for DNS-over-HTTPS",
"download_mobileconfig_dot": "Last ned .mobileconfig for DNS-over-TLS",
"plain_dns": "Ordinær DNS",
"form_enter_rate_limit": "Skriv inn forespørselsfrekvensgrense",
"rate_limit": "Forespørselsfrekvensgrense",
@@ -525,6 +528,7 @@
"check_reason": "Årsak: {{reason}}",
"check_rule": "Oppføring: {{rule}}",
"check_service": "Tjenestenavn: {{service}}",
"service_name": "Tjenestenavn",
"check_not_found": "Ikke funnet i filterlistene dine",
"client_confirm_block": "Er du sikker på at du vil blokkere klienten «{{ip}}»?",
"client_confirm_unblock": "Er du sikker på at du vil oppheve blokkeringen av klienten «{{ip}}»?",
@@ -578,5 +582,6 @@
"click_to_view_queries": "Klikk for å vise forespørsler",
"port_53_faq_link": "Port 53 er ofte opptatt av «DNSStubListener»- eller «systemd-resolved»-tjenestene. Vennligst les <0>denne instruksjonen</0> om hvordan man løser dette.",
"adg_will_drop_dns_queries": "AdGuard Home vil droppe alle DNS-forespørsler fra denne klienten.",
"client_not_in_allowed_clients": "Klienten er ikke tillatt, fordi den ikke er i «Tillatte klienter»-listen.",
"experimental": "Eksperimentell"
}

View File

@@ -9,7 +9,7 @@
"bootstrap_dns": "Servidores DNS de inicialização",
"bootstrap_dns_desc": "Servidores DNS de inicialização são usados para resolver endereços IP dos resolvedores DoH/DoT que especifica como upstreams.",
"check_dhcp_servers": "Verificar por servidores DHCP",
"save_config": "Guardar configuração",
"save_config": "Guardar definição",
"enabled_dhcp": "Servidor DHCP activado",
"disabled_dhcp": "Servidor DHCP desactivado",
"unavailable_dhcp": "DHCP não está disponível",
@@ -57,7 +57,7 @@
"dhcp_new_static_lease": "Nova concessão estática",
"dhcp_static_leases_not_found": "Nenhuma concessão DHCP estática foi encontrada",
"dhcp_add_static_lease": "Adicionar nova concessão estática",
"dhcp_reset": "Tem a certeza de que deseja redefinir a configuração DHCP?",
"dhcp_reset": "Tem a certeza de que deseja repor a definição de DHCP?",
"country": "País",
"city": "Cidade",
"delete_confirm": "Tem a certeza de que deseja excluir \"{{key}}\"?",
@@ -133,7 +133,7 @@
"encryption_settings": "Configurações de criptografia",
"dhcp_settings": "Configurações de DHCP",
"upstream_dns": "Servidores DNS upstream",
"upstream_dns_help": "Insira os endereços dos servidores, um por linha. <a>Saber mais</a> sobre a configuração de servidores DNS primários.",
"upstream_dns_help": "Insira os endereços dos servidores, um por linha. <a>Saber mais</a> sobre a definição de servidores DNS primários.",
"upstream_dns_configured_in_file": "Configurado em {{path}}",
"test_upstream_btn": "Testar upstreams",
"upstreams": "Upstreams",
@@ -236,8 +236,8 @@
"query_log_retention_confirm": "Tem a certeza de que deseja alterar a retenção do registo de consulta? Se diminuir o valor do intervalo, alguns dados serão perdidos",
"anonymize_client_ip": "Tornar anônimo o IP do cliente",
"anonymize_client_ip_desc": "Não salva o endereço de IP completo do cliente em registros e estatísticas",
"dns_config": "Configuração do servidor DNS",
"dns_cache_config": "Configuração de cache DNS",
"dns_config": "Definição do servidor DNS",
"dns_cache_config": "Definição de cache DNS",
"dns_cache_config_desc": "Aqui você pode configurar o cache do DNS",
"blocking_mode": "Modo de bloqueio",
"default": "Padrão",
@@ -294,11 +294,11 @@
"install_devices_title": "Configure os seus dispositivos",
"install_devices_desc": "Para que o AdGuard Home comece a funcionar, precisa de configurar os seus dispositivos para o poder usar.",
"install_submit_title": "Parabéns!",
"install_submit_desc": "O procedimento de configuração está concluído e está pronto para começar a usar o AdGuard Home.",
"install_submit_desc": "O procedimento de definição está concluído e está pronto para começar a usar o AdGuard Home.",
"install_devices_router": "Router",
"install_devices_router_desc": "Esta configuração cobrirá automaticamente todos os dispositivos ligados ao seu router doméstico e não irá precisar de configurar cada um deles manualmente.",
"install_devices_router_desc": "Esta definição cobrirá automaticamente todos os dispositivos ligados ao seu router doméstico e não irá precisar de configurar cada um deles manualmente.",
"install_devices_address": "O servidor de DNS do AdGuard Home está a capturar os seguintes endereços",
"install_devices_router_list_1": "Abra as configurações do seu router. No navegador insira o IP do router, o padrão é (http://192.168.0.1/ ou http://192.168.1.1/), e o login e a palavra-passe é admin/admin; Se não se lembra da palavra-passe, pode redefinir a palavra-passe rapidamente pressionando um botão no próprio router. Alguns routers têm um aplicação específica que já deve estar instalada no seu computador/telefone.",
"install_devices_router_list_1": "Abra as configurações do seu router. No navegador insira o IP do router, o padrão é (http://192.168.0.1/ ou http://192.168.1.1/), e o login e a palavra-passe é admin/admin; Se não se lembra da palavra-passe, pode repor a palavra-passe rapidamente pressionando um botão no próprio router. Alguns routers têm um aplicação específica que já deve estar instalada no seu computador/telefone.",
"install_devices_router_list_2": "Encontre as configurações de DNS. Procure as letras DNS ao lado de um campo que permite dois ou três conjuntos de números, cada um dividido em quatro grupos de um a três números.",
"install_devices_router_list_3": "Insira aqui seu servidor do AdGuard Home.",
"install_devices_router_list_4": "Você não pode definir um servidor DNS personalizado em alguns tipos de roteadores. Nesse caso, pode ajudar se você configurar o AdGuard Home como um <0>servidor DHCP</0>. Caso contrário, você deve procurar o manual sobre como personalizar os servidores DNS para o seu modelo de roteador específico.",
@@ -327,7 +327,7 @@
"install_saved": "Guardado com sucesso",
"encryption_title": "Encriptação",
"encryption_desc": "Suporta a criptografia (HTTPS/TLS) para DNS e interface de administração web",
"encryption_config_saved": "Configuração de criptografia guardada",
"encryption_config_saved": "Definição de criptografia guardada",
"encryption_server": "Nome do servidor",
"encryption_server_enter": "Insira o seu nome de domínio",
"encryption_server_desc": "Para usar o protocolo HTTPS, precisa de inserir o nome do servidor que corresponde ao seu certificado SSL.",
@@ -355,14 +355,14 @@
"encryption_subject": "Assunto",
"encryption_issuer": "Emissor",
"encryption_hostnames": "Nomes dos servidores",
"encryption_reset": "Tem a certeza de que deseja redefinir a configuração de criptografia?",
"encryption_reset": "Tem a certeza de que deseja repor a definição de criptografia?",
"topline_expiring_certificate": "O seu certificado SSL está prestes a expirar. Actualize as suas <0>definições de criptografia</0>.",
"topline_expired_certificate": "O seu certificado SSL está expirado. Actualize as suas <0>definições de criptografia</0>.",
"form_error_port_range": "Digite um porta entre 80 e 65535",
"form_error_port_unsafe": "Esta porta não é segura",
"form_error_equal": "Não deve ser igual",
"form_error_password": "As palavras-passe não coincidem",
"reset_settings": "Redefinir configurações",
"reset_settings": "Repor configurações",
"update_announcement": "AdGuard Home {{version}} está disponível!<0>Clique aqui</0> para mais informações.",
"setup_guide": "Guia de instalação",
"dns_addresses": "Endereços DNS",
@@ -401,7 +401,7 @@
"client_confirm_delete": "Tem a certeza de que deseja excluir o cliente \"{{key}}\"?",
"list_confirm_delete": "Você tem certeza de que deseja excluir essa lista?",
"auto_clients_title": "Clientes (tempo de execução)",
"auto_clients_desc": "Dados dos clientes que usam o AdGuard Home, que não são armazenados na configuração",
"auto_clients_desc": "Dados dos clientes que usam o AdGuard Home, que não são armazenados na definição",
"access_title": "Configurações de acesso",
"access_desc": "Aqui pode configurar as regras de acesso para o servidores de DNS do AdGuard Home.",
"access_allowed_title": "Clientes permitidos",
@@ -423,7 +423,7 @@
"setup_dns_privacy_android_2": "O <0>AdGuard para Android</0> suporta <1>DNS-sobre-HTTPS</1> e <1>DNS-sobre-TLS</1>.",
"setup_dns_privacy_android_3": "<0>Intra</0> adiciona o suporte <1>DNS-sobre-HTTPS</1> para o Android.",
"setup_dns_privacy_ios_1": "<0>DNSCloak</0> suporta <1>DNS-sobre-HTTPS</1>, mas para o configurar para usar o seu próprio servidor, precisará de gerar um <2>DNS Stamp</2>.",
"setup_dns_privacy_ios_2": "O <0>AdGuard para iOS</0> suporta a configuração do <1>DNS-sobre-HTTPS</1> e <1>DNS-sobre-TLS</1>.",
"setup_dns_privacy_ios_2": "O <0>AdGuard para iOS</0> suporta a definição do <1>DNS-sobre-HTTPS</1> e <1>DNS-sobre-TLS</1>.",
"setup_dns_privacy_other_title": "Outras implementações",
"setup_dns_privacy_other_1": "O próprio AdGuard Home pode ser usado como um cliente DNS seguro em qualquer plataforma.",
"setup_dns_privacy_other_2": "<0>dnsproxy</0> suporta todos os protocolos de DNS seguros conhecidos.",
@@ -460,8 +460,8 @@
"encryption_certificates_source_content": "Colar o conteúdo dos certificados",
"encryption_key_source_path": "Definir um arquivo de chave privada",
"encryption_key_source_content": "Colar o conteúdo da chave privada",
"stats_params": "Configuração de estatísticas",
"config_successfully_saved": "Configuração guardada com sucesso",
"stats_params": "Definição de estatísticas",
"config_successfully_saved": "Definição guardada com sucesso",
"interval_24_hour": "24 horas",
"interval_days": "{{count}} dias",
"interval_days_plural": "{{count}} dias",
@@ -470,7 +470,7 @@
"filter_added_successfully": "O filtro foi adicionado com sucesso",
"filter_removed_successfully": "A lista foi removida com sucesso",
"filter_updated": "O filtro atualizado com sucesso",
"statistics_configuration": "Configuração das estatísticas",
"statistics_configuration": "Definição das estatísticas",
"statistics_retention": "Retenção de estatísticas",
"statistics_retention_desc": "Se diminuir o valor do intervalo, alguns dados serão perdidos",
"statistics_clear": " Limpar estatísticas",
@@ -479,7 +479,7 @@
"statistics_cleared": "As estatísticas foram apagadas com sucesso",
"interval_hours": "{{count}} hora",
"interval_hours_plural": "{{count}} horas",
"filters_configuration": "Configuração dos filtros",
"filters_configuration": "Definição dos filtros",
"filters_enable": "Activar filtros",
"filters_interval": "Intervalo de actualização de filtros",
"disabled": "Desactivado",
@@ -576,11 +576,11 @@
"filter_category_security": "Segurança",
"filter_category_regional": "Regional",
"filter_category_other": "Outro",
"filter_category_general_desc": "Listas que bloqueiam o rastreamento e a publicidade na maioria dos dispositivos",
"filter_category_general_desc": "Listas que bloqueiam o monitorização e a publicidade na maioria dos dispositivos",
"filter_category_security_desc": "Listas especializadas em bloquear domínios de malware, phishing ou fraude",
"filter_category_regional_desc": "Listas focadas em anúncios regionais e servidores de rastreamento",
"filter_category_regional_desc": "Listas focadas em anúncios regionais e servidores de monitorização",
"filter_category_other_desc": "Outras listas negras",
"setup_config_to_enable_dhcp_server": "Configure a configuração para habilitar o servidor DHCP",
"setup_config_to_enable_dhcp_server": "Defina a definição para habilitar o servidor DHCP",
"original_response": "Resposta original",
"click_to_view_queries": "Clique para ver as consultas",
"port_53_faq_link": "A porta 53 é frequentemente ocupada por serviços \"DNSStubListener\" ou \"systemd-resolved\". Por favor leia <0>essa instrução</0> para resolver isso.",

View File

@@ -105,8 +105,8 @@
"custom_filtering_rules": "අභිරුචි පෙරීමේ නීති",
"encryption_settings": "සංකේතාංකන සැකසුම්",
"dhcp_settings": "DHCP සැකසුම්",
"upstream_dns": "Upstream ව.නා.ප. (DNS) සේවාදායකයන්",
"upstream_dns_help": "පේළියකට එක් සේවාදායක ලිපිනය බැගින් ඇතුළත් කරන්න. upstream ව.නා.ප. සේවාදායකයන් වින්‍යාසගත කිරීම ගැන <a>තව දැනගන්න</a>.",
"upstream_dns": "Upstream ව.නා.ප. සේවාදායකයන්",
"upstream_dns_help": "පේළියකට එක් සේවාදායක ලිපිනය බැගින් ඇතුළත් කරන්න. upstream ව.නා.ප. (DNS) \n සේවාදායකයන් වින්‍යාසගත කිරීම ගැන <a>තව දැනගන්න</a>.",
"apply_btn": "යොදන්න",
"disabled_filtering_toast": "පෙරීම අබල කර ඇත",
"enabled_filtering_toast": "පෙරීම සබල කර ඇත",

View File

@@ -87,7 +87,7 @@
"refresh_statics": "İstatistikleri yenile",
"dns_query": "DNS Sorguları",
"blocked_by": "<0>Filtreler tarafından engellendi</0>",
"stats_malware_phishing": "Zararlı yazılım/kimlik hırsızlığı engellendi",
"stats_malware_phishing": "Kötü amaçlı yazılım/kimlik avı engellendi",
"stats_adult": "Yetişkin içerikli site engellendi",
"stats_query_domain": "En fazla sorgulanan alan adları",
"for_last_24_hours": "son 24 saat içindekiler",

View File

@@ -89,7 +89,7 @@
"enabled_protection": "保护已启用",
"disable_protection": "禁用保护",
"disabled_protection": "保护已禁用",
"refresh_statics": "刷新状态",
"refresh_statics": "刷新统计数据",
"dns_query": "DNS查询",
"blocked_by": "<0>已被过滤器拦截</0>",
"stats_malware_phishing": "被拦截的恶意/钓鱼网站",
@@ -199,7 +199,7 @@
"block": "拦截",
"disallow_this_client": "不允许这个客户端",
"allow_this_client": "允许这个客户端",
"block_for_this_client_only": "仅拦截这个客户端",
"block_for_this_client_only": "仅对此客户端拦截",
"unblock_for_this_client_only": "仅解除对此客户端的拦截",
"time_table_header": "时间",
"date": "日期",
@@ -316,7 +316,7 @@
"install_devices_android_list_2": "点击菜单上的 ”无线局域网“ 选项。在屏幕上将列出所有可用的网络(蜂窝移动网络不支持修改 DNS )。",
"install_devices_android_list_3": "长按当前已连接的网络,然后点击 ”修改网络设置“ 。",
"install_devices_android_list_4": "在某些设备上,您可能需要选中 ”高级“ 复选框以查看进一步的设置。您可能需要调整您安卓设备的 DNS 设置,或是需要将 IP 设置从 DHCP 切换到静态。",
"install_devices_android_list_5": "将 \"DNS 1 / 主 DNS\"DNS 2 / 副 DNS“ 的值改为您的 AdGuard Home 服务器地址。",
"install_devices_android_list_5": "将 DNS 1 和 DNS 2 的值改为您的 AdGuard Home 服务器地址。",
"install_devices_ios_list_1": "从主屏幕中点击 ”设置“ 。",
"install_devices_ios_list_2": "从左侧目录中选择 ”无线局域网“(移动数据网络环境下不支持修改 DNS )。",
"install_devices_ios_list_3": "点击当前已连接网络的名称。",

View File

@@ -1,6 +1,7 @@
{
"client_settings": "用戶端設定",
"example_upstream_reserved": "您可以<0>指定網域</0>使用特定 DNS 查詢",
"example_upstream_comment": "您可以指定註解",
"upstream_parallel": "使用平行查詢,同時查詢所有上游伺服器來來加速解析結果",
"parallel_requests": "平行處理",
"load_balancing": "負載平衝",
@@ -132,6 +133,8 @@
"encryption_settings": "加密設定",
"dhcp_settings": "DHCP 設定",
"upstream_dns": "上游 DNS 伺服器",
"upstream_dns_help": "每行輸入一個伺服器位址。<a>了解更多</a>有關配置上遊 DNS 伺服器的內容",
"upstream_dns_configured_in_file": "被配置在 {{path}}",
"test_upstream_btn": "測試上游 DNS",
"upstreams": "上游",
"apply_btn": "套用",
@@ -194,6 +197,10 @@
"dns_test_not_ok_toast": "設定中的 \"{{key}}\" DNS 出現錯誤,請檢察拼字",
"unblock": "解除封鎖",
"block": "封鎖",
"disallow_this_client": "不允許此用戶端",
"allow_this_client": "允許此用戶端",
"block_for_this_client_only": "僅為此用戶端封鎖",
"unblock_for_this_client_only": "僅為此用戶端解除封鎖",
"time_table_header": "時間",
"date": "日期",
"domain_name_table_header": "域名",
@@ -235,12 +242,15 @@
"blocking_mode": "封鎖模式",
"default": "預設",
"nxdomain": "NXDOMAIN",
"refused": "REFUSED",
"null_ip": "Null IP",
"custom_ip": "自訂 IP 位址",
"blocking_ipv4": "封鎖 IPv4",
"blocking_ipv6": "封鎖 IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"download_mobileconfig_doh": "下載適用於 DNS-over-HTTPS 的 .mobileconfig",
"download_mobileconfig_dot": "下載適用於 DNS-over-TLS 的 .mobileconfig",
"plain_dns": "一般未加密 DNS",
"form_enter_rate_limit": "輸入速率限制",
"rate_limit": "速率限制",
@@ -249,6 +259,8 @@
"rate_limit_desc": "限制單一裝置每秒發出的查詢次數(設定為 0 即表示無限制)",
"blocking_ipv4_desc": "回覆指定 IPv4 位址給被封鎖的網域的 A 紀錄查詢",
"blocking_ipv6_desc": "回覆指定 IPv6 位址給被封鎖的網域的 AAAA 紀錄查詢",
"blocking_mode_default": "預設:被 Adblock 規則封鎖時回應零值的 IP 位址A 紀錄回應 0.0.0.0 AAAA 紀錄回應 ::);被 /etc/hosts 規則封鎖時回應規則中指定 IP 位址",
"blocking_mode_refused": "REFUSED以 REFUSED 碼回應",
"blocking_mode_nxdomain": "NXDOMAIN回應 NXDOMAIN 狀態碼",
"blocking_mode_null_ip": "Null IP回應零值的 IP 位址A 紀錄回應 0.0.0.0 AAAA 紀錄回應 ::",
"blocking_mode_custom_ip": "自訂 IP 位址:回應一個自訂的 IP 位址",
@@ -405,6 +417,8 @@
"dns_privacy": "DNS 隱私",
"setup_dns_privacy_1": "<0>DNS-over-TLS</0>使用 <1>{{address}}</1>。",
"setup_dns_privacy_2": "<0>DNS-over-HTTPS</0>使用 <1>{{address}}</1>。",
"setup_dns_privacy_3": "<0>以下是您可以使用軟體的列表</0>",
"setup_dns_privacy_4": "在 iOS 14 或 macOS Big Sur 裝置上,您可以下載特定的 '.mobileconfig' 檔案。此檔案將<highlight>DNS-over-HTTPS</highlight> 或 <highlight>DNS-over-TLS</highlight> 伺服器添加至 DNS 設定。",
"setup_dns_privacy_android_1": "Android 9 原生支援 DNS-over-TLS。前網「設定」→「網路 & 網際網路」→「進階」→「私人 DNS」設定。",
"setup_dns_privacy_android_2": "<0>AdGuard for Android</0> 支援 <1>DNS-over-HTTPS</1> 與 <1>DNS-over-TLS</1>。",
"setup_dns_privacy_android_3": "<0>Intra</0> 對 Android 新增支援 <1>DNS-over-HTTPS</1>。",
@@ -517,6 +531,7 @@
"check_reason": "原因:{{reason}}",
"check_rule": "規則:{{rule}}",
"check_service": "服務名稱:{{service}}",
"service_name": "服務名稱",
"check_not_found": "未在您的過濾清單中找到",
"client_confirm_block": "您確定要封鎖「{{ip}}」用戶端?",
"client_confirm_unblock": "您確定要將「{{ip}}」解除封鎖嗎?",
@@ -551,6 +566,12 @@
"cache_size_desc": "DNS 快取大小bytes",
"cache_ttl_min_override": "覆寫最小 TTL 值",
"cache_ttl_max_override": "覆寫最大 TTL 值",
"enter_cache_size": "輸入快取大小bytes",
"enter_cache_ttl_min_override": "輸入最小 TTL 值(秒)",
"enter_cache_ttl_max_override": "輸入最大 TTL 值(秒)",
"cache_ttl_min_override_desc": "快取 DNS 回應時,延長從上遊伺服器收到的 TTL 值 (秒)",
"cache_ttl_max_override_desc": "設定 DNS 快取條目的最大 TTL 值(秒)",
"ttl_cache_validation": "最小快取 TTL 值必須小於或等於最大值",
"filter_category_general": "一般",
"filter_category_security": "安全性",
"filter_category_regional": "區域性",
@@ -563,5 +584,7 @@
"original_response": "原始回應",
"click_to_view_queries": "按一下以檢視查詢結果",
"port_53_faq_link": "連接埠 53 經常被「DNSStubListener」或「systemd-resolved」服務佔用。請閱讀下列有關解決<0>這個問題</0>的說明",
"adg_will_drop_dns_queries": "AdGuard Home 將要終止所有來自此用戶端的 DNS 查詢。",
"client_not_in_allowed_clients": "此用戶端不被允許,它不在\"允許的用戶端\"列表中。",
"experimental": "實驗性"
}

View File

@@ -264,7 +264,7 @@
"blocking_mode_nxdomain": "不存在的網域NXDOMAIN以 NXDOMAIN 碼回覆",
"blocking_mode_null_ip": "無效的 IP以零值 IP 位址0.0.0.0 供 A:: 供 AAAA回覆",
"blocking_mode_custom_ip": "自訂的 IP以一組手動地被設定的 IP 位址回覆",
"upstream_dns_client_desc": "如果您將欄位留空AdGuard Home 將使用在 <0>DNS 設定</0>中被配置的伺服器。",
"upstream_dns_client_desc": "如果您將欄位留空AdGuard Home 將使用在 <0>DNS 設定</0>中被配置的伺服器。",
"tracker_source": "追蹤器來源",
"source_label": "來源",
"found_in_known_domain_db": "在已知的域名資料庫中被發現。",
@@ -338,7 +338,7 @@
"encryption_dot": "DNS-over-TLS 連接埠",
"encryption_dot_desc": "如果該連接埠被配置AdGuard Home 將於此連接埠上運行 DNS-over-TLS 伺服器。",
"encryption_doq": "DNS-over-QUIC 連接埠",
"encryption_doq_desc": "如果此連接埠被配置AdGuard Home 將於此連接埠上行 DNS-over-QUIC 伺服器。它是實驗性的並可能為不可靠的。再者,此刻沒有太多支援它的用戶端。",
"encryption_doq_desc": "如果此連接埠被配置AdGuard Home 將於此連接埠上行 DNS-over-QUIC 伺服器。它是實驗性的並可能為不可靠的。再者,此刻沒有太多支援它的用戶端。",
"encryption_certificates": "憑證",
"encryption_certificates_desc": "為了使用加密您需要提供有效的安全通訊端層SSL憑證鏈結供您的網域。於 <0>{{link}}</0> 上您可取得免費的憑證或您可從受信任的憑證授權單位之一購買它。",
"encryption_certificates_input": "於此複製/貼上您的隱私增強郵件編碼之PEM-encoded憑證。",

View File

@@ -8,10 +8,10 @@ const Examples = (props) => (
<Trans>examples_title</Trans>:
<ol className="leading-loose">
<li>
<code>9.9.9.9</code> - {props.t('example_upstream_regular')}
<code>94.140.14.140</code> - {props.t('example_upstream_regular')}
</li>
<li>
<code>tls://dns.quad9.net</code> &nbsp;
<code>tls://dns-unfiltered.adguard.com</code> &nbsp;
<span>
<Trans
components={[
@@ -30,7 +30,7 @@ const Examples = (props) => (
</span>
</li>
<li>
<code>https://dns.quad9.net/dns-query</code> &nbsp;
<code>https://dns-unfiltered.adguard.com/dns-query</code> &nbsp;
<span>
<Trans
components={[
@@ -70,7 +70,7 @@ const Examples = (props) => (
</span>
</li>
<li>
<code>tcp://9.9.9.9</code> <Trans>example_upstream_tcp</Trans>
<code>tcp://94.140.14.140</code> <Trans>example_upstream_tcp</Trans>
</li>
<li>
<code>sdns://...</code> &nbsp;
@@ -108,7 +108,7 @@ const Examples = (props) => (
</span>
</li>
<li>
<code>[/example.local/]9.9.9.9</code> &nbsp;
<code>[/example.local/]94.140.14.140</code> &nbsp;
<span>
<Trans
components={[

View File

@@ -134,7 +134,7 @@ const dnsPrivacyList = [{
components: [
{
key: 0,
href: 'https://github.com/jedisct1/dnscrypt-proxy',
href: 'https://support.mozilla.org/kb/firefox-dns-over-https',
},
<code key="1">text</code>,
],

View File

@@ -245,6 +245,16 @@ const Icons = () => (
d="M41 4H9C6.243 4 4 6.243 4 9v32c0 2.757 2.243 5 5 5h32c2.757 0 5-2.243 5-5V9c0-2.757-2.243-5-5-5zm-3.994 18.323a7.482 7.482 0 0 1-.69.035 7.492 7.492 0 0 1-6.269-3.388v11.537a8.527 8.527 0 1 1-8.527-8.527c.178 0 .352.016.527.027v4.202c-.175-.021-.347-.053-.527-.053a4.351 4.351 0 1 0 0 8.704c2.404 0 4.527-1.894 4.527-4.298l.042-19.594h4.016a7.488 7.488 0 0 0 6.901 6.685v4.67z" />
</symbol>
<symbol id="service_qq" viewBox="0 0 32 32" >
<g fill="none" fillRule="evenodd">
<path d="M0 0h32v32H0z" />
<g fill="currentColor" fillRule="nonzero">
<path d="M11.25 32C8.342 32 6 30.74 6 29.242c0-1.497 2.342-2.757 5.25-2.757s5.25 1.26 5.25 2.757S14.158 32 11.25 32zM27 29.242c0-1.497-2.342-2.757-5.25-2.757s-5.25 1.26-5.25 2.757S18.842 32 21.75 32 27 30.74 27 29.242zM14.885 7.182c0 .63-.323 1.182-.808 1.182-.485 0-.808-.552-.808-1.182 0-.63.323-1.182.808-1.182.485 0 .808.552.808 1.182zM18.923 6c-.485 0-.808.552-.808 1.182 0 .63.323-.394.808-.394.485 0 .808 1.024.808.394S19.408 6 18.923 6z" />
<path d="M6.653 12.638s4.685 2.465 9.926 2.465c5.242 0 9.927-2.465 9.927-2.465.112-.09.217-.161.316-.212-.002-1.088-.078-2.026-.078-2.808C26.744 4.292 22.138 0 16.5 0S6.176 4.292 6.176 9.618v2.78c.146.042.3.113.477.24zm12.626-8.664c1.112 0 1.986 1.272 1.986 2.782s-.874 2.782-1.986 2.782c-1.111 0-1.985-1.271-1.985-2.782 0-1.51.874-2.782 1.985-2.782zm-5.558 0c1.111 0 1.985 1.272 1.985 2.782s-.874 2.782-1.985 2.782c-1.112 0-1.986-1.271-1.986-2.782 0-1.51.874-2.782 1.986-2.782zm2.779 6.624c2.912 0 5.294.464 5.294.994s-2.382 1.656-5.294 1.656c-2.912 0-5.294-1.126-5.294-1.656s2.382-.994 5.294-.994zm11.374 5.182c-.058.038-.108.076-.177.117-.159.08-5.241 3.18-11.038 3.18-1.43 0-2.7-.239-3.97-.477-.239 1.67-.239 3.259-.239 3.974 0 1.272-1.032 1.193-2.303 1.272-1.27 0-2.223.16-2.303-1.033 0-.16-.08-2.782.397-5.564-1.588-.716-2.62-1.272-2.7-1.352a3.293 3.293 0 01-.335-.216C4.012 17.55 3 19.598 3 21.223c0 3.815 1.112 3.418 1.112 3.418.476 0 1.27-.795 1.985-1.67C7.765 27.662 11.735 31 16.5 31c4.765 0 8.735-3.338 10.403-8.028.715.874 1.509 1.669 1.985 1.669 0 0 1.112.397 1.112-3.418 0-1.588-.968-3.631-2.126-5.443z" />
</g>
</g>
</symbol>
<symbol id="question" width="20px" height="20px">
<g transform="translate(-982.000000, -454.000000) translate(416.000000, 440.000000) translate(564.000000, 12.000000)"
fill="none" fillRule="evenodd">

View File

@@ -279,6 +279,10 @@ export const SERVICES = [
id: 'tiktok',
name: 'TikTok',
},
{
id: 'qq',
name: 'QQ',
},
];
export const SERVICES_ID_NAME_MAP = SERVICES.reduce((acc, { id, name }) => {
@@ -471,6 +475,7 @@ export const BLOCK_ACTIONS = {
export const SCHEME_TO_PROTOCOL_MAP = {
doh: 'dns_over_https',
dot: 'dns_over_tls',
doq: 'dns_over_quic',
'': 'plain_dns',
};

View File

@@ -17,7 +17,7 @@ export const getTextareaCommentsHighlight = (
) => {
const renderLine = (line, idx) => renderHighlightedLine(line, idx, commentLineTokens);
return <code className={classnames('text-output', className)} ref={ref}>{lines?.split('\n').map(renderLine)}</code>;
return <code className={classnames('text-output font-monospace', className)} ref={ref}>{lines?.split('\n').map(renderLine)}</code>;
};
export const syncScroll = (e, ref) => {

25
go.mod
View File

@@ -3,34 +3,35 @@ module github.com/AdguardTeam/AdGuardHome
go 1.14
require (
github.com/AdguardTeam/dnsproxy v0.32.6
github.com/AdguardTeam/dnsproxy v0.33.2
github.com/AdguardTeam/golibs v0.4.2
github.com/AdguardTeam/urlfilter v0.12.2
github.com/AdguardTeam/urlfilter v0.12.3
github.com/NYTimes/gziphandler v1.1.1
github.com/beefsack/go-rate v0.0.0-20200827232406-6cde80facd47 // indirect
github.com/fsnotify/fsnotify v1.4.9
github.com/gobuffalo/packr v1.30.1
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714
github.com/insomniacslk/dhcp v0.0.0-20200621044212-d74cd86ad5b8
github.com/joomcode/errorx v1.0.3
github.com/joomcode/errorx v1.0.3 // indirect
github.com/kardianos/service v1.1.0
github.com/marten-seemann/qtls-go1-15 v0.1.1 // indirect
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
github.com/miekg/dns v1.1.31
github.com/pkg/errors v0.9.1
github.com/miekg/dns v1.1.35
github.com/rogpeppe/go-internal v1.5.2 // indirect
github.com/satori/go.uuid v1.2.0
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c
github.com/stretchr/testify v1.5.1
github.com/stretchr/testify v1.6.1
github.com/u-root/u-root v6.0.0+incompatible
go.etcd.io/bbolt v1.3.4
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/net v0.0.0-20200904194848-62affa334b73
golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20
golang.org/x/text v0.3.3 // indirect
google.golang.org/protobuf v1.25.0 // indirect
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
golang.org/x/sys v0.0.0-20201109165425-215b40eba54c
golang.org/x/text v0.3.4 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v2 v2.3.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5
)

62
go.sum
View File

@@ -7,14 +7,16 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AdguardTeam/dnsproxy v0.32.6 h1:HCKQFUvyvIP3lrJxP8t8+mE/DJwLk2HDmzI/af5PUu4=
github.com/AdguardTeam/dnsproxy v0.32.6/go.mod h1:ZLDrKIypYxBDz2N9FQHgeehuHrwTbuhZXdGwNySshbw=
github.com/AdguardTeam/dnsproxy v0.33.1 h1:rEAS1fBEQ3JslzsfkcyMRV96OeBWFnKzXvksduI0ous=
github.com/AdguardTeam/dnsproxy v0.33.1/go.mod h1:kLi6lMpErnZThy5haiRSis4q0KTB8uPWO4JQsU1EDJA=
github.com/AdguardTeam/dnsproxy v0.33.2 h1:k5aMcsw3TA/G2DR8EjIkwutDPuuRkKh8xij4cFWC6Fk=
github.com/AdguardTeam/dnsproxy v0.33.2/go.mod h1:kLi6lMpErnZThy5haiRSis4q0KTB8uPWO4JQsU1EDJA=
github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.4.2 h1:7M28oTZFoFwNmp8eGPb3ImmYbxGaJLyQXeIFVHjME0o=
github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.12.2 h1:5ZkH/+AWNBK8cCfbcgOL1MIrpPJ2NJXDs00KjYJr2WE=
github.com/AdguardTeam/urlfilter v0.12.2/go.mod h1:1fcCQx5TGJANrQN6sHNNM9KPBl7qx7BJml45ko6vru0=
github.com/AdguardTeam/urlfilter v0.12.3 h1:FMjQG0eTgrr8xA3z2zaLVcCgGdpzoECPGWwgPjtwPNs=
github.com/AdguardTeam/urlfilter v0.12.3/go.mod h1:1fcCQx5TGJANrQN6sHNNM9KPBl7qx7BJml45ko6vru0=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
@@ -25,10 +27,12 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
github.com/ameshkov/dnscrypt v1.1.0 h1:2vAt5dD6ZmqlAxEAfzRcLBnkvdf8NI46Kn9InSwQbSI=
github.com/ameshkov/dnscrypt v1.1.0/go.mod h1:ikduAxNLCTEfd1AaCgpIA5TgroIVQ8JY3Vb095fiFJg=
github.com/ameshkov/dnscrypt/v2 v2.0.0 h1:i83G8MeGLrAFgUL8GSu98TVhtFDEifF7SIS7Qi/RZ3U=
github.com/ameshkov/dnscrypt/v2 v2.0.0/go.mod h1:nbZnxJt4edIPx2Haa8n2XtC2g5AWcsdQiSuXkNH8eDI=
github.com/ameshkov/dnsstamps v1.0.1 h1:LhGvgWDzhNJh+kBQd/AfUlq1vfVe109huiXw4JhnPug=
github.com/ameshkov/dnsstamps v1.0.1/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beefsack/go-rate v0.0.0-20180408011153-efa7637bb9b6 h1:KXlsf+qt/X5ttPGEjR0tPH1xaWWoKBEg9Q1THAj2h3I=
@@ -98,6 +102,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
@@ -152,8 +158,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lucas-clemente/quic-go v0.18.0 h1:JhQDdqxdwdmGdKsKgXi1+coHRoGhvU6z0rNzOJqZ/4o=
github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys=
github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -173,8 +179,9 @@ github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZ
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.34/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -209,6 +216,8 @@ github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
@@ -261,6 +270,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/u-root/u-root v6.0.0+incompatible h1:YqPGmRoRyYmeg17KIWFRSyVq6LX5T6GSzawyA6wG6EE=
github.com/u-root/u-root v6.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
@@ -284,12 +295,13 @@ golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -312,8 +324,11 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -327,6 +342,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -351,8 +368,12 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ix
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 h1:4X356008q5SA3YXu8PiRap39KFmy4Lf6sGlceJKZQsU=
golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf h1:kt3wY1Lu5MJAnKTfoMR52Cu4gwvna4VTzNOiT8tY73s=
golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201109165425-215b40eba54c h1:+B+zPA6081G5cEb2triOIJpcvSW4AYzmIyWAqMn2JAc=
golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -360,6 +381,8 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -376,6 +399,8 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
@@ -427,6 +452,11 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

67
internal/agherr/agherr.go Normal file
View File

@@ -0,0 +1,67 @@
// Package agherr contains the extended error type, and the function for
// wrapping several errors.
package agherr
import (
"fmt"
"strings"
)
// Error is the constant error type.
type Error string
// Error implements the error interface for Error.
func (err Error) Error() (msg string) {
return string(err)
}
// manyError is an error containing several wrapped errors. It is created to be
// a simpler version of the API provided by github.com/joomcode/errorx.
type manyError struct {
message string
underlying []error
}
// Many wraps several errors and returns a single error.
func Many(message string, underlying ...error) error {
err := &manyError{
message: message,
underlying: underlying,
}
return err
}
// Error implements the error interface for *manyError.
func (e *manyError) Error() string {
switch len(e.underlying) {
case 0:
return e.message
case 1:
return fmt.Sprintf("%s: %s", e.message, e.underlying[0])
default:
b := &strings.Builder{}
// Ignore errors, since strings.(*Buffer).Write never returns
// errors.
_, _ = fmt.Fprintf(b, "%s: %s (hidden: %s", e.message, e.underlying[0], e.underlying[1])
for _, u := range e.underlying[2:] {
// See comment above.
_, _ = fmt.Fprintf(b, ", %s", u)
}
// See comment above.
_, _ = b.WriteString(")")
return b.String()
}
}
// Unwrap implements the hidden errors.wrapper interface for *manyError.
func (e *manyError) Unwrap() error {
if len(e.underlying) == 0 {
return nil
}
return e.underlying[0]
}

View File

@@ -0,0 +1,73 @@
package agherr
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestError_Error(t *testing.T) {
testCases := []struct {
name string
want string
err error
}{{
name: "simple",
want: "a",
err: Many("a"),
}, {
name: "wrapping",
want: "a: b",
err: Many("a", errors.New("b")),
}, {
name: "wrapping several",
want: "a: b (hidden: c, d)",
err: Many("a", errors.New("b"), errors.New("c"), errors.New("d")),
}, {
name: "wrapping wrapper",
want: "a: b: c (hidden: d)",
err: Many("a", Many("b", errors.New("c"), errors.New("d"))),
}}
for _, tc := range testCases {
assert.Equal(t, tc.want, tc.err.Error(), tc.name)
}
}
func TestError_Unwrap(t *testing.T) {
const (
errSimple = iota
errWrapped
errNil
)
errs := []error{
errSimple: errors.New("a"),
errWrapped: fmt.Errorf("%w", errors.New("nested")),
errNil: nil,
}
testCases := []struct {
name string
want error
wrapped error
}{{
name: "simple",
want: errs[errSimple],
wrapped: Many("a", errs[errSimple]),
}, {
name: "nested",
want: errs[errWrapped],
wrapped: Many("b", errs[errWrapped]),
}, {
name: "nil passed",
want: errs[errNil],
wrapped: Many("c", errs[errNil]),
}, {
name: "nil not passed",
want: nil,
wrapped: Many("d"),
}}
for _, tc := range testCases {
assert.Equal(t, tc.want, errors.Unwrap(tc.wrapped), tc.name)
}
}

View File

@@ -10,7 +10,7 @@ import (
"runtime"
"time"
"github.com/AdguardTeam/AdGuardHome/dhcpd/nclient4"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd/nclient4"
"github.com/AdguardTeam/golibs/log"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv6"
@@ -23,15 +23,19 @@ import (
func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return false, wrapErrPrint(err, "Couldn't find interface by name %s", ifaceName)
return false, fmt.Errorf("couldn't find interface by name %s: %w", ifaceName, err)
}
// get ipv4 address of an interface
ifaceIPNet := getIfaceIPv4(*iface)
ifaceIPNet, err := ifaceIPv4Addrs(iface)
if err != nil {
return false, fmt.Errorf("getting ipv4 addrs for iface %s: %w", ifaceName, err)
}
if len(ifaceIPNet) == 0 {
return false, fmt.Errorf("couldn't find IPv4 address of interface %s %+v", ifaceName, iface)
return false, fmt.Errorf("interface %s has no ipv4 addresses", ifaceName)
}
// TODO(a.garipov): Find out what this is about. Perhaps this
// information is outdated or at least incomplete.
if runtime.GOOS == "darwin" {
return false, fmt.Errorf("can't find DHCP server: not supported on macOS")
}
@@ -44,7 +48,7 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
req, err := dhcpv4.NewDiscovery(iface.HardwareAddr)
if err != nil {
return false, fmt.Errorf("dhcpv4.NewDiscovery: %s", err)
return false, fmt.Errorf("dhcpv4.NewDiscovery: %w", err)
}
req.Options.Update(dhcpv4.OptClientIdentifier(iface.HardwareAddr))
req.Options.Update(dhcpv4.OptHostName(hostname))
@@ -52,24 +56,24 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
// resolve 0.0.0.0:68
udpAddr, err := net.ResolveUDPAddr("udp4", src)
if err != nil {
return false, wrapErrPrint(err, "Couldn't resolve UDP address %s", src)
return false, fmt.Errorf("couldn't resolve UDP address %s: %w", src, err)
}
if !udpAddr.IP.To4().Equal(srcIP) {
return false, wrapErrPrint(err, "Resolved UDP address is not %s", src)
return false, fmt.Errorf("resolved UDP address is not %s: %w", src, err)
}
// resolve 255.255.255.255:67
dstAddr, err := net.ResolveUDPAddr("udp4", dst)
if err != nil {
return false, wrapErrPrint(err, "Couldn't resolve UDP address %s", dst)
return false, fmt.Errorf("couldn't resolve UDP address %s: %w", dst, err)
}
// bind to 0.0.0.0:68
log.Tracef("Listening to udp4 %+v", udpAddr)
c, err := nclient4.NewRawUDPConn(ifaceName, 68)
if err != nil {
return false, wrapErrPrint(err, "Couldn't listen on :68")
return false, fmt.Errorf("couldn't listen on :68: %w", err)
}
if c != nil {
defer c.Close()
@@ -78,61 +82,84 @@ func CheckIfOtherDHCPServersPresentV4(ifaceName string) (bool, error) {
// send to 255.255.255.255:67
_, err = c.WriteTo(req.ToBytes(), dstAddr)
if err != nil {
return false, wrapErrPrint(err, "Couldn't send a packet to %s", dst)
return false, fmt.Errorf("couldn't send a packet to %s: %w", dst, err)
}
for {
// wait for answer
log.Tracef("Waiting %v for an answer", defaultDiscoverTime)
// TODO: replicate dhclient's behaviour of retrying several times with progressively bigger timeouts
b := make([]byte, 1500)
_ = c.SetReadDeadline(time.Now().Add(defaultDiscoverTime))
n, _, err := c.ReadFrom(b)
if isTimeout(err) {
// timed out -- no DHCP servers
log.Debug("DHCPv4: didn't receive DHCP response")
return false, nil
}
if err != nil {
return false, wrapErrPrint(err, "Couldn't receive packet")
}
log.Tracef("Received packet (%v bytes)", n)
response, err := dhcpv4.FromBytes(b[:n])
if err != nil {
log.Debug("DHCPv4: dhcpv4.FromBytes: %s", err)
ok, next, err := tryConn(req, c, iface)
if next {
continue
}
log.Debug("DHCPv4: received message from server: %s", response.Summary())
if !(response.OpCode == dhcpv4.OpcodeBootReply &&
response.HWType == iana.HWTypeEthernet &&
bytes.Equal(response.ClientHWAddr, iface.HardwareAddr) &&
bytes.Equal(response.TransactionID[:], req.TransactionID[:]) &&
response.Options.Has(dhcpv4.OptionDHCPMessageType)) {
log.Debug("DHCPv4: received message from server doesn't match our request")
continue
if ok {
return true, nil
}
if err != nil {
log.Debug("%s", err)
}
log.Tracef("The packet is from an active DHCP server")
// that's a DHCP server there
return true, nil
}
}
// TODO(a.garipov): Refactor further. Inspect error handling, remove the next
// parameter, address the TODO, etc.
func tryConn(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, next bool, err error) {
// TODO: replicate dhclient's behavior of retrying several times with
// progressively longer timeouts.
log.Tracef("waiting %v for an answer", defaultDiscoverTime)
b := make([]byte, 1500)
_ = c.SetReadDeadline(time.Now().Add(defaultDiscoverTime))
n, _, err := c.ReadFrom(b)
if err != nil {
if isTimeout(err) {
log.Debug("dhcpv4: didn't receive dhcp response")
return false, false, nil
}
return false, false, fmt.Errorf("receiving packet: %w", err)
}
log.Tracef("received packet, %d bytes", n)
response, err := dhcpv4.FromBytes(b[:n])
if err != nil {
log.Debug("dhcpv4: encoding: %s", err)
return false, true, err
}
log.Debug("dhcpv4: received message from server: %s", response.Summary())
if !(response.OpCode == dhcpv4.OpcodeBootReply &&
response.HWType == iana.HWTypeEthernet &&
bytes.Equal(response.ClientHWAddr, iface.HardwareAddr) &&
bytes.Equal(response.TransactionID[:], req.TransactionID[:]) &&
response.Options.Has(dhcpv4.OptionDHCPMessageType)) {
log.Debug("dhcpv4: received message from server doesn't match our request")
return false, true, nil
}
log.Tracef("the packet is from an active dhcp server")
return true, false, nil
}
// CheckIfOtherDHCPServersPresentV6 sends a DHCP request to the specified network interface,
// and waits for a response for a period defined by defaultDiscoverTime
func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return false, fmt.Errorf("DHCPv6: net.InterfaceByName: %s: %s", ifaceName, err)
return false, fmt.Errorf("dhcpv6: net.InterfaceByName: %s: %w", ifaceName, err)
}
ifaceIPNet := getIfaceIPv6(*iface)
ifaceIPNet, err := ifaceIPv6Addrs(iface)
if err != nil {
return false, fmt.Errorf("getting ipv6 addrs for iface %s: %w", ifaceName, err)
}
if len(ifaceIPNet) == 0 {
return false, fmt.Errorf("DHCPv6: couldn't find IPv6 address of interface %s %+v", ifaceName, iface)
return false, fmt.Errorf("interface %s has no ipv6 addresses", ifaceName)
}
srcIP := ifaceIPNet[0]
@@ -141,27 +168,27 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
req, err := dhcpv6.NewSolicit(iface.HardwareAddr)
if err != nil {
return false, fmt.Errorf("DHCPv6: dhcpv6.NewSolicit: %s", err)
return false, fmt.Errorf("dhcpv6: dhcpv6.NewSolicit: %w", err)
}
udpAddr, err := net.ResolveUDPAddr("udp6", src)
if err != nil {
return false, wrapErrPrint(err, "DHCPv6: Couldn't resolve UDP address %s", src)
return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", src, err)
}
if !udpAddr.IP.To16().Equal(srcIP) {
return false, wrapErrPrint(err, "DHCPv6: Resolved UDP address is not %s", src)
return false, fmt.Errorf("dhcpv6: Resolved UDP address is not %s: %w", src, err)
}
dstAddr, err := net.ResolveUDPAddr("udp6", dst)
if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't resolve UDP address %s: %s", dst, err)
return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", dst, err)
}
log.Debug("DHCPv6: Listening to udp6 %+v", udpAddr)
c, err := nclient6.NewIPv6UDPConn(ifaceName, dhcpv6.DefaultClientPort)
if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't listen on :546: %s", err)
return false, fmt.Errorf("dhcpv6: Couldn't listen on :546: %w", err)
}
if c != nil {
defer c.Close()
@@ -169,7 +196,7 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
_, err = c.WriteTo(req.ToBytes(), dstAddr)
if err != nil {
return false, fmt.Errorf("DHCPv6: Couldn't send a packet to %s: %s", dst, err)
return false, fmt.Errorf("dhcpv6: Couldn't send a packet to %s: %w", dst, err)
}
for {
@@ -182,7 +209,7 @@ func CheckIfOtherDHCPServersPresentV6(ifaceName string) (bool, error) {
return false, nil
}
if err != nil {
return false, wrapErrPrint(err, "Couldn't receive packet")
return false, fmt.Errorf("couldn't receive packet: %w", err)
}
log.Debug("DHCPv6: Received packet (%v bytes)", n)

View File

@@ -10,7 +10,7 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/jsonutil"
"github.com/AdguardTeam/golibs/log"
@@ -175,7 +175,7 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
v6conf.InterfaceName = newconfig.InterfaceName
v6conf.notify = s.onNotify
s6, err = v6Create(v6conf)
if s6 == nil {
if err != nil {
httpError(r, w, http.StatusBadRequest, "Invalid DHCPv6 configuration: %s", err)
return
}
@@ -302,17 +302,17 @@ func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
errorText := fmt.Sprintf("failed to read request body: %s", err)
log.Error(errorText)
http.Error(w, errorText, http.StatusBadRequest)
msg := fmt.Sprintf("failed to read request body: %s", err)
log.Error(msg)
http.Error(w, msg, http.StatusBadRequest)
return
}
interfaceName := strings.TrimSpace(string(body))
if interfaceName == "" {
errorText := fmt.Sprintf("empty interface name specified")
log.Error(errorText)
http.Error(w, errorText, http.StatusBadRequest)
msg := "empty interface name specified"
log.Error(msg)
http.Error(w, msg, http.StatusBadRequest)
return
}
@@ -335,7 +335,7 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
foundVal := "no"
if found4 {
foundVal = "yes"
} else if err != nil {
} else if err4 != nil {
foundVal = "error"
othSrv["error"] = err4.Error()
}
@@ -370,7 +370,6 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
}
func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
lj := staticLeaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj)
if err != nil {
@@ -424,7 +423,6 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
}
func (s *Server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
lj := staticLeaseJSON{}
err := json.NewDecoder(r.Body).Decode(&lj)
if err != nil {

View File

@@ -9,7 +9,7 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log"
)

View File

@@ -12,12 +12,6 @@ import (
"github.com/stretchr/testify/assert"
)
func check(t *testing.T, result bool, msg string) {
if !result {
t.Fatal(msg)
}
}
func testNotify(flags uint32) {
}
@@ -83,7 +77,6 @@ func TestIsValidSubnetMask(t *testing.T) {
func TestNormalizeLeases(t *testing.T) {
dynLeases := []*Lease{}
staticLeases := []*Lease{}
leases := []*Lease{}
lease := &Lease{}
lease.HWAddr = []byte{1, 2, 3, 4}
@@ -100,7 +93,7 @@ func TestNormalizeLeases(t *testing.T) {
lease.HWAddr = []byte{2, 2, 3, 4}
staticLeases = append(staticLeases, lease)
leases = normalizeLeases(staticLeases, dynLeases)
leases := normalizeLeases(staticLeases, dynLeases)
assert.True(t, len(leases) == 3)
assert.True(t, bytes.Equal(leases[0].HWAddr, []byte{1, 2, 3, 4}))

View File

@@ -4,9 +4,6 @@ import (
"encoding/binary"
"fmt"
"net"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
)
func isTimeout(err error) bool {
@@ -17,37 +14,6 @@ func isTimeout(err error) bool {
return operr.Timeout()
}
// Get IPv4 address list
func getIfaceIPv4(iface net.Interface) []net.IP {
addrs, err := iface.Addrs()
if err != nil {
return nil
}
var res []net.IP
for _, a := range addrs {
ipnet, ok := a.(*net.IPNet)
if !ok {
continue
}
if ipnet.IP.To4() != nil {
res = append(res, ipnet.IP.To4())
}
}
return res
}
func wrapErrPrint(err error, message string, args ...interface{}) error {
var errx error
if err == nil {
errx = fmt.Errorf(message, args...)
} else {
errx = errorx.Decorate(err, message, args...)
}
log.Println(errx.Error())
return errx
}
func parseIPv4(text string) (net.IP, error) {
result := net.ParseIP(text)
if result == nil {

View File

@@ -48,14 +48,12 @@ const (
ServerPort = 67
)
var (
// DefaultServers is the address of all link-local DHCP servers and
// relay agents.
DefaultServers = &net.UDPAddr{
IP: net.IPv4bcast,
Port: ServerPort,
}
)
// DefaultServers is the address of all link-local DHCP servers and
// relay agents.
var DefaultServers = &net.UDPAddr{
IP: net.IPv4bcast,
Port: ServerPort,
}
var (
// ErrNoResponse is returned when no response packet is received.
@@ -375,14 +373,6 @@ func WithHWAddr(hwAddr net.HardwareAddr) ClientOpt {
}
}
// nolint
func withBufferCap(n int) ClientOpt {
return func(c *Client) (err error) {
c.bufferCap = n
return
}
}
// WithRetry configures the number of retransmissions to attempt.
//
// Default is 3.

View File

@@ -122,6 +122,13 @@ func newPacket(op dhcpv4.OpcodeType, xid dhcpv4.TransactionID) *dhcpv4.DHCPv4 {
return p
}
func withBufferCap(n int) ClientOpt {
return func(c *Client) (err error) {
c.bufferCap = n
return
}
}
func TestSendAndRead(t *testing.T) {
for _, tt := range []struct {
desc string

View File

@@ -10,7 +10,7 @@ import (
"runtime"
"strings"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/file"
@@ -73,7 +73,6 @@ func hasStaticIPDhcpcdConf(dhcpConf, ifaceName string) bool {
// we found our interface
withinInterfaceCtx = true
}
} else {
if strings.HasPrefix(line, "interface ") {
// we found another interface - reset our state
@@ -240,7 +239,7 @@ func getNetworkSetupHardwareReports() map[string]string {
return nil
}
m := make(map[string]string, 0)
m := make(map[string]string)
matches := re.FindAllStringSubmatch(out, -1)
for i := range matches {

View File

@@ -163,7 +163,7 @@ func (ra *raCtx) Init() error {
return nil
}
log.Debug("DHCPv6 RA: source IP address: %s DNS IP address: %s",
log.Debug("dhcpv6 ra: source IP address: %s DNS IP address: %s",
ra.ipAddr, ra.dnsIPAddr)
params := icmpv6RA{
@@ -183,7 +183,7 @@ func (ra *raCtx) Init() error {
ipAndScope := ra.ipAddr.String() + "%" + ra.ifaceName
ra.conn, err = icmp.ListenPacket("ip6:ipv6-icmp", ipAndScope)
if err != nil {
return fmt.Errorf("DHCPv6 RA: icmp.ListenPacket: %s", err)
return fmt.Errorf("dhcpv6 ra: icmp.ListenPacket: %w", err)
}
success := false
defer func() {
@@ -195,11 +195,11 @@ func (ra *raCtx) Init() error {
con6 := ra.conn.IPv6PacketConn()
if err := con6.SetHopLimit(255); err != nil {
return fmt.Errorf("DHCPv6 RA: SetHopLimit: %s", err)
return fmt.Errorf("dhcpv6 ra: SetHopLimit: %w", err)
}
if err := con6.SetMulticastHopLimit(255); err != nil {
return fmt.Errorf("DHCPv6 RA: SetMulticastHopLimit: %s", err)
return fmt.Errorf("dhcpv6 ra: SetMulticastHopLimit: %w", err)
}
msg := &ipv6.ControlMessage{
@@ -212,15 +212,15 @@ func (ra *raCtx) Init() error {
}
go func() {
log.Debug("DHCPv6 RA: starting to send periodic RouterAdvertisement packets")
log.Debug("dhcpv6 ra: starting to send periodic RouterAdvertisement packets")
for ra.stop.Load() == 0 {
_, err = con6.WriteTo(data, msg, addr)
if err != nil {
log.Error("DHCPv6 RA: WriteTo: %s", err)
log.Error("dhcpv6 ra: WriteTo: %s", err)
}
time.Sleep(ra.packetSendPeriod)
}
log.Debug("DHCPv6 RA: loop exit")
log.Debug("dhcpv6 ra: loop exit")
}()
success = true
@@ -229,7 +229,7 @@ func (ra *raCtx) Init() error {
// Close - close module
func (ra *raCtx) Close() {
log.Debug("DHCPv6 RA: closing")
log.Debug("dhcpv6 ra: closing")
ra.stop.Store(1)

View File

@@ -36,7 +36,7 @@ func (s *v4Server) WriteDiskConfig6(c *V6ServerConf) {
}
// Return TRUE if IP address is within range [start..stop]
func ip4InRange(start net.IP, stop net.IP, ip net.IP) bool {
func ip4InRange(start, stop, ip net.IP) bool {
if len(start) != 4 || len(stop) != 4 {
return false
}
@@ -55,7 +55,7 @@ func (s *v4Server) ResetLeases(leases []*Lease) {
if l.Expiry.Unix() != leaseExpireStatic &&
!ip4InRange(s.conf.ipStart, s.conf.ipEnd, l.IP) {
log.Debug("DHCPv4: skipping a lease with IP %v: not within current IP range", l.IP)
log.Debug("dhcpv4: skipping a lease with IP %v: not within current IP range", l.IP)
continue
}
@@ -124,7 +124,7 @@ func (s *v4Server) blacklistLease(lease *Lease) {
// Remove (swap) lease by index
func (s *v4Server) leaseRemoveSwapByIndex(i int) {
s.ipAddrs[s.leases[i].IP[3]] = 0
log.Debug("DHCPv4: removed lease %s", s.leases[i].HWAddr)
log.Debug("dhcpv4: removed lease %s", s.leases[i].HWAddr)
n := len(s.leases)
if i != n-1 {
@@ -168,7 +168,7 @@ func (s *v4Server) rmDynamicLease(lease Lease) error {
func (s *v4Server) addLease(l *Lease) {
s.leases = append(s.leases, l)
s.ipAddrs[l.IP[3]] = 1
log.Debug("DHCPv4: added lease %s <-> %s", l.IP, l.HWAddr)
log.Debug("dhcpv4: added lease %s <-> %s", l.IP, l.HWAddr)
}
// Remove a lease with the same properties
@@ -178,8 +178,7 @@ func (s *v4Server) rmLease(lease Lease) error {
if !bytes.Equal(l.HWAddr, lease.HWAddr) ||
l.Hostname != lease.Hostname {
return fmt.Errorf("Lease not found")
return fmt.Errorf("lease not found")
}
s.leaseRemoveSwapByIndex(i)
@@ -238,7 +237,6 @@ func (s *v4Server) RemoveStaticLease(l Lease) error {
// Send ICMP to the specified machine
// Return TRUE if it doesn't reply, which probably means that the IP is available
func (s *v4Server) addrAvailable(target net.IP) bool {
if s.conf.ICMPTimeout == 0 {
return true
}
@@ -256,15 +254,15 @@ func (s *v4Server) addrAvailable(target net.IP) bool {
pinger.OnRecv = func(pkt *ping.Packet) {
reply = true
}
log.Debug("DHCPv4: Sending ICMP Echo to %v", target)
log.Debug("dhcpv4: Sending ICMP Echo to %v", target)
pinger.Run()
if reply {
log.Info("DHCPv4: IP conflict: %v is already used by another device", target)
log.Info("dhcpv4: IP conflict: %v is already used by another device", target)
return false
}
log.Debug("DHCPv4: ICMP procedure is complete: %v", target)
log.Debug("dhcpv4: ICMP procedure is complete: %v", target)
return true
}
@@ -337,7 +335,7 @@ func (s *v4Server) commitLease(l *Lease) {
}
// Process Discover request and return lease
func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lease {
func (s *v4Server) processDiscover(req, resp *dhcpv4.DHCPv4) *Lease {
mac := req.ClientHWAddr
s.leasesLock.Lock()
@@ -349,7 +347,7 @@ func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lea
for lease == nil {
lease = s.reserveLease(mac)
if lease == nil {
log.Debug("DHCPv4: No more IP addresses")
log.Debug("dhcpv4: No more IP addresses")
if toStore {
s.conf.notify(LeaseChangedDBStore)
}
@@ -372,7 +370,7 @@ func (s *v4Server) processDiscover(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) *Lea
reqIP := req.Options.Get(dhcpv4.OptionRequestedIPAddress)
if len(reqIP) != 0 &&
!bytes.Equal(reqIP, lease.IP) {
log.Debug("DHCPv4: different RequestedIP: %v != %v", reqIP, lease.IP)
log.Debug("dhcpv4: different RequestedIP: %v != %v", reqIP, lease.IP)
}
}
@@ -407,12 +405,11 @@ func (o *optFQDN) ToBytes() []byte {
copy(b[i:], []byte(o.name))
return b
}
// Process Request request and return lease
// Return false if we don't need to reply
func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lease, bool) {
func (s *v4Server) processRequest(req, resp *dhcpv4.DHCPv4) (*Lease, bool) {
var lease *Lease
mac := req.ClientHWAddr
hostname := req.Options.Get(dhcpv4.OptionHostName)
@@ -424,12 +421,12 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
sid := req.Options.Get(dhcpv4.OptionServerIdentifier)
if len(sid) != 0 &&
!bytes.Equal(sid, s.conf.dnsIPAddrs[0]) {
log.Debug("DHCPv4: Bad OptionServerIdentifier in Request message for %s", mac)
log.Debug("dhcpv4: Bad OptionServerIdentifier in Request message for %s", mac)
return nil, false
}
if len(reqIP) != 4 {
log.Debug("DHCPv4: Bad OptionRequestedIPAddress in Request message for %s", mac)
log.Debug("dhcpv4: Bad OptionRequestedIPAddress in Request message for %s", mac)
return nil, false
}
@@ -438,7 +435,7 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
if bytes.Equal(l.HWAddr, mac) {
if !bytes.Equal(l.IP, reqIP) {
s.leasesLock.Unlock()
log.Debug("DHCPv4: Mismatched OptionRequestedIPAddress in Request message for %s", mac)
log.Debug("dhcpv4: Mismatched OptionRequestedIPAddress in Request message for %s", mac)
return nil, true
}
@@ -449,7 +446,7 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
s.leasesLock.Unlock()
if lease == nil {
log.Debug("DHCPv4: No lease for %s", mac)
log.Debug("dhcpv4: No lease for %s", mac)
return nil, true
}
@@ -475,8 +472,7 @@ func (s *v4Server) processRequest(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) (*Lea
// Return 1: OK
// Return 0: error; reply with Nak
// Return -1: error; don't reply
func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
func (s *v4Server) process(req, resp *dhcpv4.DHCPv4) int {
var lease *Lease
resp.UpdateOption(dhcpv4.OptServerIdentifier(s.conf.dnsIPAddrs[0]))
@@ -519,7 +515,7 @@ func (s *v4Server) process(req *dhcpv4.DHCPv4, resp *dhcpv4.DHCPv4) int {
// client(0.0.0.0:68) -> (Request:ClientMAC,Type=Request,ClientID,ReqIP||ClientIP,HostName,ServerID,ParamReqList) -> server(255.255.255.255:67)
// client(255.255.255.255:68) <- (Reply:YourIP,ClientMAC,Type=ACK,ServerID,SubnetMask,LeaseTime) <- server(<IP>:67)
func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4.DHCPv4) {
log.Debug("DHCPv4: received message: %s", req.Summary())
log.Debug("dhcpv4: received message: %s", req.Summary())
switch req.MessageType() {
case dhcpv4.MessageTypeDiscover,
@@ -527,18 +523,18 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
//
default:
log.Debug("DHCPv4: unsupported message type %d", req.MessageType())
log.Debug("dhcpv4: unsupported message type %d", req.MessageType())
return
}
resp, err := dhcpv4.NewReplyFromRequest(req)
if err != nil {
log.Debug("DHCPv4: dhcpv4.New: %s", err)
log.Debug("dhcpv4: dhcpv4.New: %s", err)
return
}
if len(req.ClientHWAddr) != 6 {
log.Debug("DHCPv4: Invalid ClientHWAddr")
log.Debug("dhcpv4: Invalid ClientHWAddr")
return
}
@@ -549,33 +545,74 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak))
}
log.Debug("DHCPv4: sending: %s", resp.Summary())
log.Debug("dhcpv4: sending: %s", resp.Summary())
_, err = conn.WriteTo(resp.ToBytes(), peer)
if err != nil {
log.Error("DHCPv4: conn.Write to %s failed: %s", peer, err)
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
return
}
}
// Start - start server
// ifaceIPv4Addrs returns the interface's IPv4 addresses.
func ifaceIPv4Addrs(iface *net.Interface) (ips []net.IP, err error) {
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, a := range addrs {
ipnet, ok := a.(*net.IPNet)
if !ok {
continue
}
if ip := ipnet.IP.To4(); ip != nil {
ips = append(ips, ip)
}
}
return ips, nil
}
// Start starts the IPv4 DHCP server.
func (s *v4Server) Start() error {
if !s.conf.Enabled {
return nil
}
iface, err := net.InterfaceByName(s.conf.InterfaceName)
ifaceName := s.conf.InterfaceName
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return fmt.Errorf("DHCPv4: Couldn't find interface by name %s: %s", s.conf.InterfaceName, err)
return fmt.Errorf("dhcpv4: finding interface %s by name: %w", ifaceName, err)
}
log.Debug("DHCPv4: starting...")
s.conf.dnsIPAddrs = getIfaceIPv4(*iface)
if len(s.conf.dnsIPAddrs) == 0 {
log.Debug("DHCPv4: no IPv6 address for interface %s", iface.Name)
return nil
log.Debug("dhcpv4: starting...")
dnsIPAddrs, err := ifaceIPv4Addrs(iface)
if err != nil {
return fmt.Errorf("dhcpv4: getting ipv4 addrs for iface %s: %w", ifaceName, err)
}
switch len(dnsIPAddrs) {
case 0:
log.Debug("dhcpv4: no ipv4 address for interface %s", iface.Name)
return nil
case 1:
// Some Android devices use 8.8.8.8 if there is no secondary DNS
// server. Fix that by setting the secondary DNS address to our
// address as well.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/1708.
log.Debug("dhcpv4: setting secondary dns ip to iself for interface %s", iface.Name)
dnsIPAddrs = append(dnsIPAddrs, dnsIPAddrs[0])
default:
// Go on.
}
s.conf.dnsIPAddrs = dnsIPAddrs
laddr := &net.UDPAddr{
IP: net.ParseIP("0.0.0.0"),
Port: dhcpv4.ServerPort,
@@ -585,12 +622,13 @@ func (s *v4Server) Start() error {
return err
}
log.Info("DHCPv4: listening")
log.Info("dhcpv4: listening")
go func() {
err = s.srv.Serve()
log.Debug("DHCPv4: srv.Serve: %s", err)
log.Debug("dhcpv4: srv.Serve: %s", err)
}()
return nil
}
@@ -600,10 +638,10 @@ func (s *v4Server) Stop() {
return
}
log.Debug("DHCPv4: stopping")
log.Debug("dhcpv4: stopping")
err := s.srv.Close()
if err != nil {
log.Error("DHCPv4: srv.Close: %s", err)
log.Error("dhcpv4: srv.Close: %s", err)
}
// now s.srv.Serve() will return
s.srv = nil
@@ -621,31 +659,31 @@ func v4Create(conf V4ServerConf) (DHCPServer, error) {
var err error
s.conf.routerIP, err = parseIPv4(s.conf.GatewayIP)
if err != nil {
return s, fmt.Errorf("DHCPv4: %s", err)
return s, fmt.Errorf("dhcpv4: %w", err)
}
subnet, err := parseIPv4(s.conf.SubnetMask)
if err != nil || !isValidSubnetMask(subnet) {
return s, fmt.Errorf("DHCPv4: invalid subnet mask: %s", s.conf.SubnetMask)
return s, fmt.Errorf("dhcpv4: invalid subnet mask: %s", s.conf.SubnetMask)
}
s.conf.subnetMask = make([]byte, 4)
copy(s.conf.subnetMask, subnet)
s.conf.ipStart, err = parseIPv4(conf.RangeStart)
if s.conf.ipStart == nil {
return s, fmt.Errorf("DHCPv4: %s", err)
return s, fmt.Errorf("dhcpv4: %w", err)
}
if s.conf.ipStart[0] == 0 {
return s, fmt.Errorf("DHCPv4: invalid range start IP")
return s, fmt.Errorf("dhcpv4: invalid range start IP")
}
s.conf.ipEnd, err = parseIPv4(conf.RangeEnd)
if s.conf.ipEnd == nil {
return s, fmt.Errorf("DHCPv4: %s", err)
return s, fmt.Errorf("dhcpv4: %w", err)
}
if !net.IP.Equal(s.conf.ipStart[:3], s.conf.ipEnd[:3]) ||
s.conf.ipStart[3] > s.conf.ipEnd[3] {
return s, fmt.Errorf("DHCPv4: range end IP should match range start IP")
return s, fmt.Errorf("dhcpv4: range end IP should match range start IP")
}
if conf.LeaseDuration == 0 {
@@ -658,7 +696,7 @@ func v4Create(conf V4ServerConf) (DHCPServer, error) {
for _, o := range conf.Options {
code, val := parseOptionString(o)
if code == 0 {
log.Debug("DHCPv4: bad option string: %s", o)
log.Debug("dhcpv4: bad option string: %s", o)
continue
}

View File

@@ -41,10 +41,11 @@ func (s *v6Server) WriteDiskConfig6(c *V6ServerConf) {
// Return TRUE if IP address is within range [start..0xff]
// nolint(staticcheck)
func ip6InRange(start net.IP, ip net.IP) bool {
func ip6InRange(start, ip net.IP) bool {
if len(start) != 16 {
return false
}
//lint:ignore SA1021 TODO(e.burkov): Ignore this for now, think about using masks.
if !bytes.Equal(start[:15], ip[:15]) {
return false
}
@@ -72,12 +73,10 @@ func (s *v6Server) GetLeases(flags int) []Lease {
var result []Lease
s.leasesLock.Lock()
for _, lease := range s.leases {
if lease.Expiry.Unix() == leaseExpireStatic {
if (flags & LeasesStatic) != 0 {
result = append(result, *lease)
}
} else {
if (flags & LeasesDynamic) != 0 {
result = append(result, *lease)
@@ -214,8 +213,7 @@ func (s *v6Server) rmLease(lease Lease) error {
if !bytes.Equal(l.HWAddr, lease.HWAddr) ||
l.Hostname != lease.Hostname {
return fmt.Errorf("Lease not found")
return fmt.Errorf("lease not found")
}
s.leaseRemoveSwapByIndex(i)
@@ -302,7 +300,7 @@ func (s *v6Server) commitDynamicLease(l *Lease) {
// Check Client ID
func (s *v6Server) checkCID(msg *dhcpv6.Message) error {
if msg.Options.ClientID() == nil {
return fmt.Errorf("DHCPv6: no ClientID option in request")
return fmt.Errorf("dhcpv6: no ClientID option in request")
}
return nil
}
@@ -317,7 +315,7 @@ func (s *v6Server) checkSID(msg *dhcpv6.Message) error {
dhcpv6.MessageTypeRebind:
if sid != nil {
return fmt.Errorf("DHCPv6: drop packet: ServerID option in message %s", msg.Type().String())
return fmt.Errorf("dhcpv6: drop packet: ServerID option in message %s", msg.Type().String())
}
case dhcpv6.MessageTypeRequest,
@@ -326,10 +324,10 @@ func (s *v6Server) checkSID(msg *dhcpv6.Message) error {
dhcpv6.MessageTypeDecline:
if sid == nil {
return fmt.Errorf("DHCPv6: drop packet: no ServerID option in message %s", msg.Type().String())
return fmt.Errorf("dhcpv6: drop packet: no ServerID option in message %s", msg.Type().String())
}
if !sid.Equal(s.sid) {
return fmt.Errorf("DHCPv6: drop packet: mismatched ServerID option in message %s: %s",
return fmt.Errorf("dhcpv6: drop packet: mismatched ServerID option in message %s: %s",
msg.Type().String(), sid.String())
}
}
@@ -371,7 +369,7 @@ func (s *v6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration
//
case dhcpv6.MessageTypeConfirm:
lifetime = lease.Expiry.Sub(time.Now())
lifetime = time.Until(lease.Expiry)
case dhcpv6.MessageTypeRequest,
dhcpv6.MessageTypeRenew,
@@ -385,7 +383,7 @@ func (s *v6Server) commitLease(msg *dhcpv6.Message, lease *Lease) time.Duration
}
// Find a lease associated with MAC and prepare response
func (s *v6Server) process(msg *dhcpv6.Message, req dhcpv6.DHCPv6, resp dhcpv6.DHCPv6) bool {
func (s *v6Server) process(msg *dhcpv6.Message, req, resp dhcpv6.DHCPv6) bool {
switch msg.Type() {
case dhcpv6.MessageTypeSolicit,
dhcpv6.MessageTypeRequest,
@@ -539,24 +537,25 @@ func (s *v6Server) packetHandler(conn net.PacketConn, peer net.Addr, req dhcpv6.
}
}
// Get IPv6 address list
func getIfaceIPv6(iface net.Interface) []net.IP {
// ifaceIPv6Addrs returns the interface's IPv6 addresses.
func ifaceIPv6Addrs(iface *net.Interface) (ips []net.IP, err error) {
addrs, err := iface.Addrs()
if err != nil {
return nil
return nil, err
}
var res []net.IP
for _, a := range addrs {
ipnet, ok := a.(*net.IPNet)
if !ok {
continue
}
if ipnet.IP.To4() == nil {
res = append(res, ipnet.IP)
if ip := ipnet.IP.To16(); ip != nil {
ips = append(ips, ip)
}
}
return res
return ips, nil
}
// initialize RA module
@@ -580,23 +579,40 @@ func (s *v6Server) initRA(iface *net.Interface) error {
return s.ra.Init()
}
// Start - start server
// Start starts the IPv6 DHCP server.
func (s *v6Server) Start() error {
if !s.conf.Enabled {
return nil
}
iface, err := net.InterfaceByName(s.conf.InterfaceName)
ifaceName := s.conf.InterfaceName
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName)
return fmt.Errorf("dhcpv6: finding interface %s by name: %w", ifaceName, err)
}
s.conf.dnsIPAddrs = getIfaceIPv6(*iface)
if len(s.conf.dnsIPAddrs) == 0 {
log.Debug("DHCPv6: no IPv6 address for interface %s", iface.Name)
return nil
log.Debug("dhcpv4: starting...")
dnsIPAddrs, err := ifaceIPv6Addrs(iface)
if err != nil {
return fmt.Errorf("dhcpv6: getting ipv6 addrs for iface %s: %w", ifaceName, err)
}
switch len(dnsIPAddrs) {
case 0:
log.Debug("dhcpv6: no ipv6 address for interface %s", iface.Name)
return nil
case 1:
// See the comment in (*v4Server).Start.
log.Debug("dhcpv6: setting secondary dns ip to iself for interface %s", iface.Name)
dnsIPAddrs = append(dnsIPAddrs, dnsIPAddrs[0])
default:
// Go on.
}
s.conf.dnsIPAddrs = dnsIPAddrs
err = s.initRA(iface)
if err != nil {
return err
@@ -611,7 +627,7 @@ func (s *v6Server) Start() error {
log.Debug("DHCPv6: starting...")
if len(iface.HardwareAddr) != 6 {
return fmt.Errorf("DHCPv6: invalid MAC %s", iface.HardwareAddr)
return fmt.Errorf("dhcpv6: invalid MAC %s", iface.HardwareAddr)
}
s.sid = dhcpv6.Duid{
Type: dhcpv6.DUID_LLT,
@@ -666,7 +682,7 @@ func v6Create(conf V6ServerConf) (DHCPServer, error) {
s.conf.ipStart = net.ParseIP(conf.RangeStart)
if s.conf.ipStart == nil || s.conf.ipStart.To16() == nil {
return s, fmt.Errorf("DHCPv6: invalid range-start IP: %s", conf.RangeStart)
return s, fmt.Errorf("dhcpv6: invalid range-start IP: %s", conf.RangeStart)
}
if conf.LeaseDuration == 0 {

View File

@@ -22,12 +22,12 @@ func main() {
res, err := filter.CheckHost(host)
if err != nil {
// temporary failure
log.Fatalf("Failed to check host '%s': %s", host, err)
log.Fatalf("Failed to check host %q: %s", host, err)
}
if res.IsFiltered {
log.Printf("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule)
log.Printf("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
} else {
log.Printf("Host %s is not filtered, reason - '%s'", host, res.Reason)
log.Printf("Host %s is not filtered, reason - %q", host, res.Reason)
}
}
```
@@ -59,12 +59,12 @@ func main() {
res, err := filter.CheckHost(host)
if err != nil {
// temporary failure
log.Fatalf("Failed to check host '%s': %s", host, err)
log.Fatalf("Failed to check host %q: %s", host, err)
}
if res.IsFiltered {
log.Printf("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule)
log.Printf("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
} else {
log.Printf("Host %s is not filtered, reason - '%s'", host, res.Reason)
log.Printf("Host %s is not filtered, reason - %q", host, res.Reason)
}
}
```

View File

@@ -43,7 +43,7 @@ var serviceRulesArray = []svc{
"||youtube",
}},
{"twitch", []string{"||twitch.tv^", "||ttvnw.net^", "||jtvnw.net^", "||twitchcdn.net^"}},
{"netflix", []string{"||nflxext.com^", "||netflix.com^", "||nflximg.net^", "||nflxvideo.net^"}},
{"netflix", []string{"||nflxext.com^", "||netflix.com^", "||nflximg.net^", "||nflxvideo.net^", "||nflxso.net^"}},
{"instagram", []string{"||instagram.com^", "||cdninstagram.com^"}},
{"snapchat", []string{
"||snapchat.com^",
@@ -161,6 +161,7 @@ var serviceRulesArray = []svc{
"||douyin.com^",
"||tiktokv.com^",
}},
{"qq", []string{"||qq.com^", "||qqzaixian.com^"}},
}
// convert array to map

View File

@@ -1,3 +1,4 @@
// Package dnsfilter implements a DNS filter.
package dnsfilter
import (
@@ -11,7 +12,7 @@ import (
"strings"
"sync"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/log"
@@ -199,7 +200,7 @@ func (d *Dnsfilter) WriteDiskConfig(c *Config) {
// SetFilters - set new filters (synchronously or asynchronously)
// When filters are set asynchronously, the old filters continue working until the new filters are ready.
// In this case the caller must ensure that the old filter files are intact.
func (d *Dnsfilter) SetFilters(blockFilters []Filter, allowFilters []Filter, async bool) error {
func (d *Dnsfilter) SetFilters(blockFilters, allowFilters []Filter, async bool) error {
if async {
params := filtersInitializerParams{
allowFilters: allowFilters,
@@ -281,7 +282,7 @@ type Result struct {
CanonName string `json:",omitempty"` // CNAME value
// for RewriteEtcHosts:
ReverseHost string `json:",omitempty"`
ReverseHosts []string `json:",omitempty"`
// for ReasonRewrite & RewriteEtcHosts:
IPList []net.IP `json:",omitempty"` // list of IP addresses
@@ -325,18 +326,9 @@ func (d *Dnsfilter) CheckHost(host string, qtype uint16, setts *RequestFiltering
// Now check the hosts file -- do we have any rules for it?
// just like DNS rewrites, it has higher priority than filtering rules.
if d.Config.AutoHosts != nil {
ips := d.Config.AutoHosts.Process(host, qtype)
if ips != nil {
result.Reason = RewriteEtcHosts
result.IPList = ips
return result, nil
}
revHost := d.Config.AutoHosts.ProcessReverse(host, qtype)
if len(revHost) != 0 {
result.Reason = RewriteEtcHosts
result.ReverseHost = revHost + "."
return result, nil
matched, err := d.checkAutoHosts(host, qtype, &result)
if matched {
return result, err
}
}
@@ -401,6 +393,31 @@ func (d *Dnsfilter) CheckHost(host string, qtype uint16, setts *RequestFiltering
return Result{}, nil
}
func (d *Dnsfilter) checkAutoHosts(host string, qtype uint16, result *Result) (matched bool, err error) {
ips := d.Config.AutoHosts.Process(host, qtype)
if ips != nil {
result.Reason = RewriteEtcHosts
result.IPList = ips
return true, nil
}
revHosts := d.Config.AutoHosts.ProcessReverse(host, qtype)
if len(revHosts) != 0 {
result.Reason = RewriteEtcHosts
// TODO(a.garipov): Optimize this with a buffer.
result.ReverseHosts = make([]string, len(revHosts))
for i := range revHosts {
result.ReverseHosts[i] = revHosts[i] + "."
}
return true, nil
}
return false, nil
}
// Process rewrites table
// . Find CNAME for a domain name (exact match or by wildcard)
// . if found and CNAME equals to domain name - this is an exception; exit
@@ -481,13 +498,10 @@ func matchBlockedServicesRules(host string, svcs []ServiceEntry) Result {
// Adding rule and matching against the rules
//
// Return TRUE if file exists
// fileExists returns true if file exists.
func fileExists(fn string) bool {
_, err := os.Stat(fn)
if err != nil {
return false
}
return true
return err == nil
}
func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilter.DNSEngine, error) {
@@ -501,19 +515,18 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
RulesText: string(f.Data),
IgnoreCosmetic: true,
}
} else if !fileExists(f.FilePath) {
list = &filterlist.StringRuleList{
ID: int(f.ID),
IgnoreCosmetic: true,
}
} else if runtime.GOOS == "windows" {
// On Windows we don't pass a file to urlfilter because
// it's difficult to update this file while it's being used.
// it's difficult to update this file while it's being
// used.
data, err := ioutil.ReadFile(f.FilePath)
if err != nil {
return nil, nil, fmt.Errorf("ioutil.ReadFile(): %s: %s", f.FilePath, err)
return nil, nil, fmt.Errorf("ioutil.ReadFile(): %s: %w", f.FilePath, err)
}
list = &filterlist.StringRuleList{
ID: int(f.ID),
@@ -525,7 +538,7 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
var err error
list, err = filterlist.NewFileRuleList(int(f.ID), f.FilePath, true)
if err != nil {
return nil, nil, fmt.Errorf("filterlist.NewFileRuleList(): %s: %s", f.FilePath, err)
return nil, nil, fmt.Errorf("filterlist.NewFileRuleList(): %s: %w", f.FilePath, err)
}
}
listArray = append(listArray, list)
@@ -533,13 +546,13 @@ func createFilteringEngine(filters []Filter) (*filterlist.RuleStorage, *urlfilte
rulesStorage, err := filterlist.NewRuleStorage(listArray)
if err != nil {
return nil, nil, fmt.Errorf("filterlist.NewRuleStorage(): %s", err)
return nil, nil, fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
}
filteringEngine := urlfilter.NewDNSEngine(rulesStorage)
return rulesStorage, filteringEngine, nil
}
// Initialize urlfilter objects
// Initialize urlfilter objects.
func (d *Dnsfilter) initFiltering(allowFilters, blockFilters []Filter) error {
rulesStorage, filteringEngine, err := createFilteringEngine(blockFilters)
if err != nil {
@@ -565,7 +578,8 @@ func (d *Dnsfilter) initFiltering(allowFilters, blockFilters []Filter) error {
return nil
}
// matchHost is a low-level way to check only if hostname is filtered by rules, skipping expensive safebrowsing and parental lookups
// matchHost is a low-level way to check only if hostname is filtered by rules,
// skipping expensive safebrowsing and parental lookups.
func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringSettings) (Result, error) {
d.engineLock.RLock()
// Keep in mind that this lock must be held no just when calling Match()
@@ -590,7 +604,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
rule = rr.HostRulesV6[0]
}
log.Debug("Filtering: found whitelist rule for host '%s': '%s' list_id: %d",
log.Debug("Filtering: found whitelist rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, NotFilteredWhiteList)
return res, nil
@@ -607,7 +621,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
}
if rr.NetworkRule != nil {
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d",
log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rr.NetworkRule.Text(), rr.NetworkRule.GetFilterListID())
reason := FilteredBlackList
if rr.NetworkRule.Whitelist {
@@ -619,7 +633,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
if qtype == dns.TypeA && rr.HostRulesV4 != nil {
rule := rr.HostRulesV4[0] // note that we process only 1 matched rule
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d",
log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList)
res.IP = rule.IP.To4()
@@ -628,7 +642,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
if qtype == dns.TypeAAAA && rr.HostRulesV6 != nil {
rule := rr.HostRulesV6[0] // note that we process only 1 matched rule
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d",
log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList)
res.IP = rule.IP
@@ -644,7 +658,7 @@ func (d *Dnsfilter) matchHost(host string, qtype uint16, setts RequestFilteringS
} else if rr.HostRulesV6 != nil {
rule = rr.HostRulesV6[0]
}
log.Debug("Filtering: found rule for host '%s': '%s' list_id: %d",
log.Debug("Filtering: found rule for host %q: %q list_id: %d",
host, rule.Text(), rule.GetFilterListID())
res := makeResult(rule, FilteredBlackList)
res.IP = net.IP{}
@@ -666,21 +680,18 @@ func makeResult(rule rules.Rule, reason Reason) Result {
return res
}
// InitModule() - manually initialize blocked services map
// InitModule manually initializes blocked services map.
func InitModule() {
initBlockedServices()
}
// New creates properly initialized DNS Filter that is ready to be used
// New creates properly initialized DNS Filter that is ready to be used.
func New(c *Config, blockFilters []Filter) *Dnsfilter {
if c != nil {
cacheConf := cache.Config{
EnableLRU: true,
}
// initialize objects only once
if gctx.safebrowsingCache == nil {
cacheConf.MaxSize = c.SafeBrowsingCacheSize
gctx.safebrowsingCache = cache.New(cacheConf)
@@ -713,7 +724,7 @@ func New(c *Config, blockFilters []Filter) *Dnsfilter {
bsvcs := []string{}
for _, s := range d.BlockedServices {
if !BlockedSvcKnown(s) {
log.Debug("skipping unknown blocked-service '%s'", s)
log.Debug("skipping unknown blocked-service %q", s)
continue
}
bsvcs = append(bsvcs, s)
@@ -750,7 +761,7 @@ func (d *Dnsfilter) Start() {
// stats
//
// GetStats return dns filtering stats since startup
// GetStats return dns filtering stats since startup.
func (d *Dnsfilter) GetStats() Stats {
return gctx.stats
}

View File

@@ -3,9 +3,6 @@ package dnsfilter
import (
"fmt"
"net"
"os"
"path"
"runtime"
"testing"
"github.com/AdguardTeam/urlfilter/rules"
@@ -36,13 +33,6 @@ func purgeCaches() {
}
}
func _Func() string {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
return path.Base(f.Name())
}
func NewForTest(c *Config, filters []Filter) *Dnsfilter {
setts = RequestFilteringSettings{}
setts.FilteringEnabled = true
@@ -71,7 +61,7 @@ func (d *Dnsfilter) checkMatch(t *testing.T, hostname string) {
}
}
func (d *Dnsfilter) checkMatchIP(t *testing.T, hostname string, ip string, qtype uint16) {
func (d *Dnsfilter) checkMatchIP(t *testing.T, hostname, ip string, qtype uint16) {
t.Helper()
ret, err := d.CheckHost(hostname, qtype, &setts)
if err != nil {
@@ -107,7 +97,7 @@ func TestEtcHostsMatching(t *testing.T) {
::1 host2
`,
addr, addr6)
filters := []Filter{Filter{
filters := []Filter{{
ID: 0, Data: []byte(text),
}}
d := NewForTest(nil, filters)
@@ -351,11 +341,15 @@ func TestParentalControl(t *testing.T) {
// FILTERING
var blockingRules = "||example.org^\n"
var whitelistRules = "||example.org^\n@@||test.example.org\n"
var importantRules = "@@||example.org^\n||test.example.org^$important\n"
var regexRules = "/example\\.org/\n@@||test.example.org^\n"
var maskRules = "test*.example.org^\nexam*.com\n"
const nl = "\n"
const (
blockingRules = `||example.org^` + nl
whitelistRules = `||example.org^` + nl + `@@||test.example.org` + nl
importantRules = `@@||example.org^` + nl + `||test.example.org^$important` + nl
regexRules = `/example\.org/` + nl + `@@||test.example.org^` + nl
maskRules = `test*.example.org^` + nl + `exam*.com` + nl
)
var tests = []struct {
testname string
@@ -406,7 +400,7 @@ var tests = []struct {
func TestMatching(t *testing.T) {
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.testname, test.hostname), func(t *testing.T) {
filters := []Filter{Filter{
filters := []Filter{{
ID: 0, Data: []byte(test.rules),
}}
d := NewForTest(nil, filters)
@@ -430,14 +424,14 @@ func TestWhitelist(t *testing.T) {
rules := `||host1^
||host2^
`
filters := []Filter{Filter{
filters := []Filter{{
ID: 0, Data: []byte(rules),
}}
whiteRules := `||host1^
||host3^
`
whiteFilters := []Filter{Filter{
whiteFilters := []Filter{{
ID: 0, Data: []byte(whiteRules),
}}
d := NewForTest(nil, filters)
@@ -455,7 +449,6 @@ func TestWhitelist(t *testing.T) {
assert.True(t, err == nil)
assert.True(t, ret.IsFiltered && ret.Reason == FilteredBlackList)
assert.True(t, ret.Rule == "||host2^")
}
// CLIENT SETTINGS
@@ -476,7 +469,7 @@ func applyClientSettings(setts *RequestFilteringSettings) {
// then apply per-client settings and check behaviour once again
func TestClientSettings(t *testing.T) {
var r Result
filters := []Filter{Filter{
filters := []Filter{{
ID: 0, Data: []byte("||example.org^\n"),
}}
d := NewForTest(&Config{ParentalEnabled: true, SafeBrowsingEnabled: false}, filters)
@@ -532,13 +525,6 @@ func TestClientSettings(t *testing.T) {
assert.True(t, r.IsFiltered && r.Reason == FilteredBlockedService)
}
func prepareTestDir() string {
const dir = "./agh-test"
_ = os.RemoveAll(dir)
_ = os.MkdirAll(dir, 0755)
return dir
}
// BENCHMARKS
func BenchmarkSafeBrowsing(b *testing.B) {

View File

@@ -22,8 +22,7 @@ func (d *Dnsfilter) setCacheResult(cache cache.Cache, host string, res Result) i
var buf bytes.Buffer
expire := uint(time.Now().Unix()) + d.Config.CacheTime*60
var exp []byte
exp = make([]byte, 4)
exp := make([]byte, 4)
binary.BigEndian.PutUint32(exp, uint32(expire))
_, _ = buf.Write(exp)

View File

@@ -22,11 +22,13 @@ import (
"golang.org/x/net/publicsuffix"
)
const dnsTimeout = 3 * time.Second
const defaultSafebrowsingServer = "https://dns-family.adguard.com/dns-query"
const defaultParentalServer = "https://dns-family.adguard.com/dns-query"
const sbTXTSuffix = "sb.dns.adguard.com."
const pcTXTSuffix = "pc.dns.adguard.com."
const (
dnsTimeout = 3 * time.Second
defaultSafebrowsingServer = `https://dns-family.adguard.com/dns-query`
defaultParentalServer = `https://dns-family.adguard.com/dns-query`
sbTXTSuffix = `sb.dns.adguard.com.`
pcTXTSuffix = `pc.dns.adguard.com.`
)
func (d *Dnsfilter) initSecurityServices() error {
var err error
@@ -60,7 +62,7 @@ expire byte[4]
hash byte[32]
...
*/
func (c *sbCtx) setCache(prefix []byte, hashes []byte) {
func (c *sbCtx) setCache(prefix, hashes []byte) {
d := make([]byte, 4+len(hashes))
expire := uint(time.Now().Unix()) + c.cacheTime*60
binary.BigEndian.PutUint32(d[:4], uint32(expire))
@@ -158,16 +160,28 @@ func hostnameToHashes(host string) map[[32]byte]string {
// convert hash array to string
func (c *sbCtx) getQuestion() string {
q := ""
b := &strings.Builder{}
encoder := hex.NewEncoder(b)
for hash := range c.hashToHost {
q += fmt.Sprintf("%s.", hex.EncodeToString(hash[0:2]))
// Ignore errors, since strings.(*Buffer).Write never returns
// errors.
//
// TODO(e.burkov, a.garipov): Find out and document why exactly
// this slice.
_, _ = encoder.Write(hash[0:2])
_, _ = b.WriteRune('.')
}
if c.svc == "SafeBrowsing" {
q += sbTXTSuffix
} else {
q += pcTXTSuffix
// See comment above.
_, _ = b.WriteString(sbTXTSuffix)
return b.String()
}
return q
// See comment above.
_, _ = b.WriteString(pcTXTSuffix)
return b.String()
}
// Find the target hash in TXT response

View File

@@ -23,16 +23,16 @@ func TestSafeBrowsingHash(t *testing.T) {
assert.False(t, ok)
c := &sbCtx{
svc: "SafeBrowsing",
svc: "SafeBrowsing",
hashToHost: hashes,
}
// test getQuestion()
c.hashToHost = hashes
q := c.getQuestion()
assert.True(t, strings.Index(q, "7a1b.") >= 0)
assert.True(t, strings.Index(q, "af5a.") >= 0)
assert.True(t, strings.Index(q, "eb11.") >= 0)
assert.True(t, strings.Index(q, "sb.dns.adguard.com.") > 0)
assert.True(t, strings.Contains(q, "7a1b."))
assert.True(t, strings.Contains(q, "af5a."))
assert.True(t, strings.Contains(q, "eb11."))
assert.True(t, strings.HasSuffix(q, "sb.dns.adguard.com."))
}
func TestSafeBrowsingCache(t *testing.T) {

View File

@@ -51,7 +51,7 @@ func (a *accessCtx) Init(allowedClients, disallowedClients, blockedHosts []strin
listArray = append(listArray, list)
rulesStorage, err := filterlist.NewRuleStorage(listArray)
if err != nil {
return fmt.Errorf("filterlist.NewRuleStorage(): %s", err)
return fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
}
a.blockedHostsEngine = urlfilter.NewDNSEngine(rulesStorage)

View File

@@ -10,12 +10,11 @@ import (
"net/http"
"sort"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
)
// FilteringConfig represents the DNS filtering configuration of AdGuard Home
@@ -252,14 +251,14 @@ func (s *Server) prepareUpstreamSettings() error {
upstreams = filterOutComments(upstreams)
upstreamConfig, err := proxy.ParseUpstreamsConfig(upstreams, s.conf.BootstrapDNS, DefaultTimeout)
if err != nil {
return fmt.Errorf("DNS: proxy.ParseUpstreamsConfig: %s", err)
return fmt.Errorf("dns: proxy.ParseUpstreamsConfig: %w", err)
}
if len(upstreamConfig.Upstreams) == 0 {
log.Info("Warning: no default upstream servers specified, using %v", defaultDNS)
uc, err := proxy.ParseUpstreamsConfig(defaultDNS, s.conf.BootstrapDNS, DefaultTimeout)
if err != nil {
return fmt.Errorf("DNS: failed to parse default upstreams: %v", err)
return fmt.Errorf("dns: failed to parse default upstreams: %v", err)
}
upstreamConfig.Upstreams = uc.Upstreams
}
@@ -300,13 +299,13 @@ func (s *Server) prepareTLS(proxyConfig *proxy.Config) error {
var err error
s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
if err != nil {
return errorx.Decorate(err, "Failed to parse TLS keypair")
return fmt.Errorf("failed to parse TLS keypair: %w", err)
}
if s.conf.StrictSNICheck {
x, err := x509.ParseCertificate(s.conf.cert.Certificate[0])
if err != nil {
return errorx.Decorate(err, "x509.ParseCertificate(): %s", err)
return fmt.Errorf("x509.ParseCertificate(): %w", err)
}
if len(x.DNSNames) != 0 {
s.conf.dnsNames = x.DNSNames

View File

@@ -1,3 +1,4 @@
// Package dnsforward contains a DNS forwarding server.
package dnsforward
import (
@@ -8,13 +9,12 @@ import (
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/querylog"
"github.com/AdguardTeam/AdGuardHome/stats"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
"github.com/miekg/dns"
)
@@ -181,12 +181,9 @@ func (s *Server) Prepare(config *ServerConfig) error {
s.conf.BlockingIPAddrv4 = net.ParseIP(s.conf.BlockingIPv4)
s.conf.BlockingIPAddrv6 = net.ParseIP(s.conf.BlockingIPv6)
if s.conf.BlockingIPAddrv4 == nil || s.conf.BlockingIPAddrv6 == nil {
return fmt.Errorf("DNS: invalid custom blocking IP address specified")
return fmt.Errorf("dns: invalid custom blocking IP address specified")
}
}
if s.conf.MaxGoroutines == 0 {
s.conf.MaxGoroutines = 50
}
}
// Set default values in the case if nothing is configured
@@ -249,7 +246,7 @@ func (s *Server) stopInternal() error {
if s.dnsProxy != nil {
err := s.dnsProxy.Stop()
if err != nil {
return errorx.Decorate(err, "could not stop the DNS server properly")
return fmt.Errorf("could not stop the DNS server properly: %w", err)
}
}
@@ -272,7 +269,7 @@ func (s *Server) Reconfigure(config *ServerConfig) error {
log.Print("Start reconfiguring the server")
err := s.stopInternal()
if err != nil {
return errorx.Decorate(err, "could not reconfigure the server")
return fmt.Errorf("could not reconfigure the server: %w", err)
}
// It seems that net.Listener.Close() doesn't close file descriptors right away.
@@ -281,12 +278,12 @@ func (s *Server) Reconfigure(config *ServerConfig) error {
err = s.Prepare(config)
if err != nil {
return errorx.Decorate(err, "could not reconfigure the server")
return fmt.Errorf("could not reconfigure the server: %w", err)
}
err = s.startInternal()
if err != nil {
return errorx.Decorate(err, "could not reconfigure the server")
return fmt.Errorf("could not reconfigure the server: %w", err)
}
return nil

View File

@@ -17,7 +17,7 @@ import (
func httpError(r *http.Request, w http.ResponseWriter, code int, format string, args ...interface{}) {
text := fmt.Sprintf(format, args...)
log.Info("DNS: %s %s: %s", r.Method, r.URL, text)
log.Info("dns: %s %s: %s", r.Method, r.URL, text)
http.Error(w, text, code)
}
@@ -102,7 +102,7 @@ func checkBootstrap(addr string) error {
}
_, err := upstream.NewResolver(addr, 0)
if err != nil {
return fmt.Errorf("invalid bootstrap server address: %s", err)
return fmt.Errorf("invalid bootstrap server address: %w", err)
}
return nil
}
@@ -322,7 +322,7 @@ func separateUpstream(upstream string) (string, bool, error) {
// split domains and upstream string
domainsAndUpstream := strings.Split(strings.TrimPrefix(upstream, "[/"), "/]")
if len(domainsAndUpstream) != 2 {
return "", defaultUpstream, fmt.Errorf("wrong DNS upstream per domain specification: %s", upstream)
return "", defaultUpstream, fmt.Errorf("wrong dns upstream per domain specification: %s", upstream)
}
// split domains list and validate each one
@@ -357,7 +357,7 @@ func checkPlainDNS(upstream string) error {
_, err = strconv.ParseInt(port, 0, 64)
if err != nil {
return fmt.Errorf("%s is not a valid port: %s", port, err)
return fmt.Errorf("%s is not a valid port: %w", port, err)
}
return nil
@@ -371,11 +371,6 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
return
}
if len(req.Upstreams) == 0 {
httpError(r, w, http.StatusBadRequest, "No servers specified")
return
}
result := map[string]string{}
for _, host := range req.Upstreams {
@@ -410,7 +405,7 @@ func checkDNS(input string, bootstrap []string) error {
// separate upstream from domains list
input, defaultUpstream, err := separateUpstream(input)
if err != nil {
return fmt.Errorf("wrong upstream format: %s", err)
return fmt.Errorf("wrong upstream format: %w", err)
}
// No need to check this DNS server
@@ -419,17 +414,17 @@ func checkDNS(input string, bootstrap []string) error {
}
if _, err := validateUpstream(input); err != nil {
return fmt.Errorf("wrong upstream format: %s", err)
return fmt.Errorf("wrong upstream format: %w", err)
}
if len(bootstrap) == 0 {
bootstrap = defaultBootstrap
}
log.Debug("Checking if DNS %s works...", input)
log.Debug("checking if dns %s works...", input)
u, err := upstream.AddressToUpstream(input, upstream.Options{Bootstrap: bootstrap, Timeout: DefaultTimeout})
if err != nil {
return fmt.Errorf("failed to choose upstream for %s: %s", input, err)
return fmt.Errorf("failed to choose upstream for %s: %w", input, err)
}
req := dns.Msg{}
@@ -440,18 +435,18 @@ func checkDNS(input string, bootstrap []string) error {
}
reply, err := u.Exchange(&req)
if err != nil {
return fmt.Errorf("couldn't communicate with DNS server %s: %s", input, err)
return fmt.Errorf("couldn't communicate with dns server %s: %w", input, err)
}
if len(reply.Answer) != 1 {
return fmt.Errorf("DNS server %s returned wrong answer", input)
return fmt.Errorf("dns server %s returned wrong answer", input)
}
if t, ok := reply.Answer[0].(*dns.A); ok {
if !net.IPv4(8, 8, 8, 8).Equal(t.A) {
return fmt.Errorf("DNS server %s returned wrong answer: %v", input, t.A)
return fmt.Errorf("dns server %s returned wrong answer: %v", input, t.A)
}
}
log.Debug("DNS %s works OK", input)
log.Debug("dns %s works OK", input)
return nil
}
@@ -467,7 +462,7 @@ func (s *Server) handleDOH(w http.ResponseWriter, r *http.Request) {
}
if !s.IsRunning() {
httpError(r, w, http.StatusInternalServerError, "DNS server is not running")
httpError(r, w, http.StatusInternalServerError, "dns server is not running")
return
}

View File

@@ -18,10 +18,10 @@ import (
"testing"
"time"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/miekg/dns"
@@ -815,12 +815,12 @@ func sendTestMessageAsync(t *testing.T, conn *dns.Conn, g *sync.WaitGroup) {
req := createGoogleATestMessage()
err := conn.WriteMsg(req)
if err != nil {
t.Fatalf("cannot write message: %s", err)
panic(fmt.Sprintf("cannot write message: %s", err))
}
res, err := conn.ReadMsg()
if err != nil {
t.Fatalf("cannot read response to message: %s", err)
panic(fmt.Sprintf("cannot read response to message: %s", err))
}
assertGoogleAResponse(t, res)
}
@@ -916,20 +916,23 @@ func publicKey(priv interface{}) interface{} {
}
func TestValidateUpstream(t *testing.T) {
invalidUpstreams := []string{"1.2.3.4.5",
invalidUpstreams := []string{
"1.2.3.4.5",
"123.3.7m",
"htttps://google.com/dns-query",
"[/host.com]tls://dns.adguard.com",
"[host.ru]#",
}
validDefaultUpstreams := []string{"1.1.1.1",
validDefaultUpstreams := []string{
"1.1.1.1",
"tls://1.1.1.1",
"https://dns.adguard.com/dns-query",
"sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20",
}
validUpstreams := []string{"[/host.com/]1.1.1.1",
validUpstreams := []string{
"[/host.com/]1.1.1.1",
"[//]tls://1.1.1.1",
"[/www.host.com/]#",
"[/host.com/google.com/]8.8.8.8",
@@ -975,7 +978,8 @@ func TestValidateUpstreamsSet(t *testing.T) {
assert.Nil(t, err, "comments should not be validated")
// Set of valid upstreams. There is no default upstream specified
upstreamsSet = []string{"[/host.com/]1.1.1.1",
upstreamsSet = []string{
"[/host.com/]1.1.1.1",
"[//]tls://1.1.1.1",
"[/www.host.com/]#",
"[/host.com/google.com/]8.8.8.8",
@@ -1029,9 +1033,7 @@ func (d *testDHCP) Leases(flags int) []dhcpd.Lease {
l.Hostname = "localhost"
return []dhcpd.Lease{l}
}
func (d *testDHCP) SetOnLeaseChanged(onLeaseChanged dhcpd.OnLeaseChangedT) {
return
}
func (d *testDHCP) SetOnLeaseChanged(onLeaseChanged dhcpd.OnLeaseChangedT) {}
func TestPTRResponseFromDHCPLeases(t *testing.T) {
dhcp := &testDHCP{}

View File

@@ -1,12 +1,13 @@
package dnsforward
import (
"fmt"
"strings"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
"github.com/miekg/dns"
)
@@ -49,29 +50,32 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {
res, err := s.dnsFilter.CheckHost(host, d.Req.Question[0].Qtype, ctx.setts)
if err != nil {
// Return immediately if there's an error
return nil, errorx.Decorate(err, "dnsfilter failed to check host '%s'", host)
return nil, fmt.Errorf("dnsfilter failed to check host %q: %w", host, err)
} else if res.IsFiltered {
log.Tracef("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule)
log.Tracef("Host %s is filtered, reason - %q, matched rule: %q", host, res.Reason, res.Rule)
d.Res = s.genDNSFilterMessage(d, &res)
} else if res.Reason == dnsfilter.ReasonRewrite && len(res.CanonName) != 0 && len(res.IPList) == 0 {
ctx.origQuestion = d.Req.Question[0]
// resolve canonical name, not the original host name
d.Req.Question[0].Name = dns.Fqdn(res.CanonName)
} else if res.Reason == dnsfilter.RewriteEtcHosts && len(res.ReverseHost) != 0 {
} else if res.Reason == dnsfilter.RewriteEtcHosts && len(res.ReverseHosts) != 0 {
resp := s.makeResponse(req)
ptr := &dns.PTR{}
ptr.Hdr = dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypePTR,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
for _, h := range res.ReverseHosts {
hdr := dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypePTR,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
}
ptr := &dns.PTR{
Hdr: hdr,
Ptr: h,
}
resp.Answer = append(resp.Answer, ptr)
}
ptr.Ptr = res.ReverseHost
resp.Answer = append(resp.Answer, ptr)
d.Res = resp
} else if res.Reason == dnsfilter.ReasonRewrite || res.Reason == dnsfilter.RewriteEtcHosts {
resp := s.makeResponse(req)
@@ -136,7 +140,6 @@ func (s *Server) filterDNSResponse(ctx *dnsContext) (*dnsfilter.Result, error) {
if err != nil {
return nil, err
} else if res.IsFiltered {
d.Res = s.genDNSFilterMessage(d, &res)
log.Debug("DNSFwd: Matched %s by response: %s", d.Req.Question[0].Name, host)

View File

@@ -5,9 +5,9 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"

View File

@@ -3,8 +3,9 @@ package dnsforward
import (
"net"
"strings"
"sync"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"
)
@@ -12,7 +13,9 @@ import (
type ipsetCtx struct {
ipsetList map[string][]string // domain -> []ipset_name
ipsetCache map[[4]byte]bool // cache for IP[] to prevent duplicate calls to ipset program
ipset6Cache map[[16]byte]bool // cache for IP[] to prevent duplicate calls to ipset program
ipsetMutex *sync.Mutex
ipset6Cache map[[16]byte]bool // cache for IP[] to prevent duplicate calls to ipset program
ipset6Mutex *sync.Mutex
}
// Convert configuration settings to an internal map
@@ -20,19 +23,21 @@ type ipsetCtx struct {
func (c *ipsetCtx) init(ipsetConfig []string) {
c.ipsetList = make(map[string][]string)
c.ipsetCache = make(map[[4]byte]bool)
c.ipsetMutex = &sync.Mutex{}
c.ipset6Cache = make(map[[16]byte]bool)
c.ipset6Mutex = &sync.Mutex{}
for _, it := range ipsetConfig {
it = strings.TrimSpace(it)
hostsAndNames := strings.Split(it, "/")
if len(hostsAndNames) != 2 {
log.Debug("IPSET: invalid value '%s'", it)
log.Debug("IPSET: invalid value %q", it)
continue
}
ipsetNames := strings.Split(hostsAndNames[1], ",")
if len(ipsetNames) == 0 {
log.Debug("IPSET: invalid value '%s'", it)
log.Debug("IPSET: invalid value %q", it)
continue
}
bad := false
@@ -44,7 +49,7 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
}
}
if bad {
log.Debug("IPSET: invalid value '%s'", it)
log.Debug("IPSET: invalid value %q", it)
continue
}
@@ -53,7 +58,7 @@ func (c *ipsetCtx) init(ipsetConfig []string) {
host = strings.TrimSpace(host)
host = strings.ToLower(host)
if len(host) == 0 {
log.Debug("IPSET: invalid value '%s'", it)
log.Debug("IPSET: invalid value %q", it)
continue
}
c.ipsetList[host] = ipsetNames
@@ -67,6 +72,8 @@ func (c *ipsetCtx) getIP(rr dns.RR) net.IP {
case *dns.A:
var ip4 [4]byte
copy(ip4[:], a.A.To4())
c.ipsetMutex.Lock()
defer c.ipsetMutex.Unlock()
_, found := c.ipsetCache[ip4]
if found {
return nil // this IP was added before
@@ -77,6 +84,8 @@ func (c *ipsetCtx) getIP(rr dns.RR) net.IP {
case *dns.AAAA:
var ip6 [16]byte
copy(ip6[:], a.AAAA)
c.ipset6Mutex.Lock()
defer c.ipset6Mutex.Unlock()
_, found := c.ipset6Cache[ip6]
if found {
return nil // this IP was added before
@@ -122,7 +131,7 @@ func (c *ipsetCtx) process(ctx *dnsContext) int {
continue
}
if code != 0 {
log.Info("IPSET: ipset add: code:%d output:'%s'", code, out)
log.Info("IPSET: ipset add: code:%d output:%q", code, out)
continue
}
log.Debug("IPSET: added %s(%s) -> %s", host, ipStr, name)

View File

@@ -5,7 +5,7 @@ import (
"net"
"time"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/miekg/dns"
)
@@ -46,7 +46,6 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
if s.conf.BlockingMode == "null_ip" {
// it means that we should return 0.0.0.0 or :: for any blocked request
return s.makeResponseNullIP(m)
} else if s.conf.BlockingMode == "custom_ip" {
// means that we should return custom IP for any blocked request
@@ -56,12 +55,10 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
case dns.TypeAAAA:
return s.genAAAARecord(m, s.conf.BlockingIPAddrv6)
}
} else if s.conf.BlockingMode == "nxdomain" {
// means that we should return NXDOMAIN for any blocked request
return s.genNXDomain(m)
} else if s.conf.BlockingMode == "refused" {
// means that we should return NXDOMAIN for any blocked request
@@ -148,7 +145,6 @@ func (s *Server) makeResponseNullIP(req *dns.Msg) *dns.Msg {
}
func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg {
ip := net.ParseIP(newAddr)
if ip != nil {
return s.genResponseWithIP(request, ip)
@@ -168,7 +164,7 @@ func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSCo
err := s.dnsProxy.Resolve(newContext)
if err != nil {
log.Printf("Couldn't look up replacement host '%s': %s", newAddr, err)
log.Printf("Couldn't look up replacement host %q: %s", newAddr, err)
return s.genServerFailure(request)
}

View File

@@ -5,12 +5,11 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/querylog"
"github.com/miekg/dns"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/stats"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/miekg/dns"
)
// Write Stats data and logs
@@ -40,10 +39,16 @@ func processQueryLogsAndStats(ctx *dnsContext) int {
ClientIP: getIP(d.Addr),
}
if d.Proto == "https" {
p.ClientProto = "doh"
} else if d.Proto == "tls" {
p.ClientProto = "dot"
switch d.Proto {
case proxy.ProtoHTTPS:
p.ClientProto = querylog.ClientProtoDOH
case proxy.ProtoQUIC:
p.ClientProto = querylog.ClientProtoDOQ
case proxy.ProtoTLS:
p.ClientProto = querylog.ClientProtoDOT
default:
// Consider this a plain DNS-over-UDP or DNS-over-TCL
// request.
}
if d.Upstream != nil {

View File

@@ -27,7 +27,7 @@ func stringArrayDup(a []string) []string {
// Get IP address from net.Addr object
// Note: we can't use net.SplitHostPort(a.String()) because of IPv6 zone:
// https://github.com/AdguardTeam/AdGuardHome/issues/1261
// https://github.com/AdguardTeam/AdGuardHome/internal/issues/1261
func ipFromAddr(a net.Addr) string {
switch addr := a.(type) {
case *net.UDPAddr:

View File

@@ -17,22 +17,22 @@ import (
"golang.org/x/crypto/bcrypt"
)
const cookieTTL = 365 * 24 // in hours
const sessionCookieName = "agh_session"
const (
cookieTTL = 365 * 24 // in hours
sessionCookieName = "agh_session"
)
type session struct {
userName string
expire uint32 // expiration time (in seconds)
}
/*
expire byte[4]
name_len byte[2]
name byte[]
*/
func (s *session) serialize() []byte {
var data []byte
data = make([]byte, 4+2+len(s.userName))
const (
expireLen = 4
nameLen = 2
)
data := make([]byte, expireLen+nameLen+len(s.userName))
binary.BigEndian.PutUint32(data[0:4], s.expire)
binary.BigEndian.PutUint16(data[4:6], uint16(len(s.userName)))
copy(data[6:], []byte(s.userName))
@@ -78,11 +78,11 @@ func InitAuth(dbFilename string, users []User, sessionTTL uint32) *Auth {
a.sessions = make(map[string]*session)
rand.Seed(time.Now().UTC().Unix())
var err error
a.db, err = bbolt.Open(dbFilename, 0644, nil)
a.db, err = bbolt.Open(dbFilename, 0o644, nil)
if err != nil {
log.Error("Auth: open DB: %s: %s", dbFilename, err)
if err.Error() == "invalid argument" {
log.Error("AdGuard Home cannot be initialized due to an incompatible file system.\nPlease read the explanation here: https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started#limitations")
log.Error("AdGuard Home cannot be initialized due to an incompatible file system.\nPlease read the explanation here: https://github.com/AdguardTeam/AdGuardHome/internal/wiki/Getting-Started#limitations")
}
return nil
}
@@ -318,7 +318,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
cookie := Context.auth.httpCookie(req)
if len(cookie) == 0 {
log.Info("Auth: invalid user name or password: name='%s'", req.Name)
log.Info("Auth: invalid user name or password: name=%q", req.Name)
time.Sleep(1 * time.Second)
http.Error(w, "invalid user name or password", http.StatusBadRequest)
return
@@ -372,7 +372,6 @@ func parseCookie(cookie string) string {
// nolint(gocyclo)
func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/login.html" {
// redirect to dashboard if already authenticated
authRequired := Context.auth != nil && Context.auth.AuthRequired()
@@ -424,7 +423,6 @@ func optionalAuth(handler func(http.ResponseWriter, *http.Request)) func(http.Re
if r.URL.Path == "/" || r.URL.Path == "/index.html" {
if glProcessRedirect(w, r) {
log.Debug("Auth: redirected to login page by GL-Inet submodule")
} else {
w.Header().Set("Location", "/login.html")
w.WriteHeader(http.StatusFound)
@@ -474,7 +472,7 @@ func (a *Auth) UserAdd(u *User, password string) {
}
// UserFind - find a user
func (a *Auth) UserFind(login string, password string) User {
func (a *Auth) UserFind(login, password string) User {
a.lock.Lock()
defer a.lock.Unlock()
for _, u := range a.users {

View File

@@ -13,10 +13,10 @@ import (
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/utils"
)
@@ -126,7 +126,6 @@ func (clients *clientsContainer) Start() {
}
go clients.periodicUpdate()
}
}
// Reload - reload auto-clients
@@ -173,7 +172,7 @@ func (clients *clientsContainer) addFromConfig(objects []clientObject) {
for _, s := range cy.BlockedServices {
if !dnsfilter.BlockedSvcKnown(s) {
log.Debug("Clients: skipping unknown blocked-service '%s'", s)
log.Debug("Clients: skipping unknown blocked-service %q", s)
continue
}
cli.BlockedServices = append(cli.BlockedServices, s)
@@ -181,7 +180,7 @@ func (clients *clientsContainer) addFromConfig(objects []clientObject) {
for _, t := range cy.Tags {
if !clients.tagKnown(t) {
log.Debug("Clients: skipping unknown tag '%s'", t)
log.Debug("Clients: skipping unknown tag %q", t)
continue
}
cli.Tags = append(cli.Tags, t)
@@ -377,7 +376,7 @@ func (clients *clientsContainer) check(c *Client) error {
}
if len(c.IDs) == 0 {
return fmt.Errorf("ID required")
return fmt.Errorf("id required")
}
for i, id := range c.IDs {
@@ -409,7 +408,7 @@ func (clients *clientsContainer) check(c *Client) error {
err := dnsforward.ValidateUpstreams(c.Upstreams)
if err != nil {
return fmt.Errorf("invalid upstream servers: %s", err)
return fmt.Errorf("invalid upstream servers: %w", err)
}
return nil
@@ -448,7 +447,7 @@ func (clients *clientsContainer) Add(c Client) (bool, error) {
clients.idIndex[id] = &c
}
log.Debug("Clients: added '%s': ID:%v [%d]", c.Name, c.IDs, len(clients.list))
log.Debug("Clients: added %q: ID:%v [%d]", c.Name, c.IDs, len(clients.list))
return true, nil
}
@@ -590,7 +589,7 @@ func (clients *clientsContainer) addHost(ip, host string, source clientSource) (
}
clients.ipHost[ip] = ch
}
log.Debug("Clients: added '%s' -> '%s' [%d]", ip, host, len(clients.ipHost))
log.Debug("Clients: added %q -> %q [%d]", ip, host, len(clients.ipHost))
return true, nil
}
@@ -607,22 +606,25 @@ func (clients *clientsContainer) rmHosts(source clientSource) int {
return n
}
// Fill clients array from system hosts-file
// addFromHostsFile fills the clients hosts list from the system's hosts files.
func (clients *clientsContainer) addFromHostsFile() {
hosts := clients.autoHosts.List()
clients.lock.Lock()
defer clients.lock.Unlock()
_ = clients.rmHosts(ClientSourceHostsFile)
n := 0
for ip, name := range hosts {
ok, err := clients.addHost(ip, name, ClientSourceHostsFile)
if err != nil {
log.Debug("Clients: %s", err)
}
if ok {
n++
for ip, names := range hosts {
for _, name := range names {
ok, err := clients.addHost(ip, name, ClientSourceHostsFile)
if err != nil {
log.Debug("Clients: %s", err)
}
if ok {
n++
}
}
}

View File

@@ -6,7 +6,7 @@ import (
"testing"
"time"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/stretchr/testify/assert"
)

View File

@@ -6,11 +6,11 @@ import (
"path/filepath"
"sync"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/querylog"
"github.com/AdguardTeam/AdGuardHome/stats"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/golibs/file"
"github.com/AdguardTeam/golibs/log"
yaml "gopkg.in/yaml.v2"
@@ -120,6 +120,12 @@ var config = configuration{
Ratelimit: 20,
RefuseAny: true,
AllServers: false,
// set default maximum concurrent queries to 300
// we introduced a default limit due to this:
// https://github.com/AdguardTeam/AdGuardHome/issues/2015#issuecomment-674041912
// was later increased to 300 due to https://github.com/AdguardTeam/AdGuardHome/issues/2257
MaxGoroutines: 300,
},
FilteringEnabled: true, // whether or not use filter lists
FiltersUpdateIntervalHours: 24,

View File

@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/golibs/log"
"github.com/NYTimes/gziphandler"
)

View File

@@ -12,7 +12,7 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"
)
@@ -26,10 +26,10 @@ func isValidURL(rawurl string) bool {
url, err := url.ParseRequestURI(rawurl)
if err != nil {
return false //Couldn't even parse the rawurl
return false // Couldn't even parse the rawurl
}
if len(url.Scheme) == 0 {
return false //No Scheme found
return false // No Scheme found
}
return true
}
@@ -95,44 +95,57 @@ func (f *Filtering) handleFilteringAddURL(w http.ResponseWriter, r *http.Request
}
func (f *Filtering) handleFilteringRemoveURL(w http.ResponseWriter, r *http.Request) {
type request struct {
URL string `json:"url"`
Whitelist bool `json:"whitelist"`
}
req := request{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
httpError(w, http.StatusBadRequest, "Failed to parse request body json: %s", err)
httpError(w, http.StatusBadRequest, "failed to parse request body json: %s", err)
return
}
// go through each element and delete if url matches
config.Lock()
newFilters := []filter{}
filters := &config.Filters
if req.Whitelist {
filters = &config.WhitelistFilters
}
for _, filter := range *filters {
if filter.URL != req.URL {
newFilters = append(newFilters, filter)
} else {
err := os.Rename(filter.Path(), filter.Path()+".old")
if err != nil {
log.Error("os.Rename: %s: %s", filter.Path(), err)
}
var deleted filter
var newFilters []filter
for _, f := range *filters {
if f.URL != req.URL {
newFilters = append(newFilters, f)
continue
}
deleted = f
path := f.Path()
err = os.Rename(path, path+".old")
if err != nil {
log.Error("deleting filter %q: %s", path, err)
}
}
// Update the configuration after removing filter files
*filters = newFilters
config.Unlock()
onConfigModified()
enableFilters(true)
// Note: the old files "filter.txt.old" aren't deleted - it's not really necessary,
// but will require the additional code to run after enableFilters() is finished: i.e. complicated
// NOTE: The old files "filter.txt.old" aren't deleted. It's not really
// necessary, but will require the additional complicated code to run
// after enableFilters is done.
//
// TODO(a.garipov): Make sure the above comment is true.
_, err = fmt.Fprintf(w, "OK %d rules\n", deleted.RulesCount)
if err != nil {
httpError(w, http.StatusInternalServerError, "couldn't write body: %s", err)
}
}
type filterURLJSON struct {

View File

@@ -13,9 +13,9 @@ import (
"runtime"
"strconv"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/golibs/log"
)
@@ -71,6 +71,7 @@ type checkConfigReqEnt struct {
IP string `json:"ip"`
Autofix bool `json:"autofix"`
}
type checkConfigReq struct {
Web checkConfigReqEnt `json:"web"`
DNS checkConfigReqEnt `json:"dns"`
@@ -81,11 +82,13 @@ type checkConfigRespEnt struct {
Status string `json:"status"`
CanAutofix bool `json:"can_autofix"`
}
type staticIPJSON struct {
Static string `json:"static"`
IP string `json:"ip"`
Error string `json:"error"`
}
type checkConfigResp struct {
Web checkConfigRespEnt `json:"web"`
DNS checkConfigRespEnt `json:"dns"`
@@ -214,31 +217,33 @@ func checkDNSStubListener() bool {
return true
}
const resolvedConfPath = "/etc/systemd/resolved.conf.d/adguardhome.conf"
const resolvedConfData = `[Resolve]
const (
resolvedConfPath = "/etc/systemd/resolved.conf.d/adguardhome.conf"
resolvedConfData = `[Resolve]
DNS=127.0.0.1
DNSStubListener=no
`
)
const resolvConfPath = "/etc/resolv.conf"
// Deactivate DNSStubListener
func disableDNSStubListener() error {
dir := filepath.Dir(resolvedConfPath)
err := os.MkdirAll(dir, 0755)
err := os.MkdirAll(dir, 0o755)
if err != nil {
return fmt.Errorf("os.MkdirAll: %s: %s", dir, err)
return fmt.Errorf("os.MkdirAll: %s: %w", dir, err)
}
err = ioutil.WriteFile(resolvedConfPath, []byte(resolvedConfData), 0644)
err = ioutil.WriteFile(resolvedConfPath, []byte(resolvedConfData), 0o644)
if err != nil {
return fmt.Errorf("ioutil.WriteFile: %s: %s", resolvedConfPath, err)
return fmt.Errorf("ioutil.WriteFile: %s: %w", resolvedConfPath, err)
}
_ = os.Rename(resolvConfPath, resolvConfPath+".backup")
err = os.Symlink("/run/systemd/resolve/resolv.conf", resolvConfPath)
if err != nil {
_ = os.Remove(resolvedConfPath) // remove the file we've just created
return fmt.Errorf("os.Symlink: %s: %s", resolvConfPath, err)
return fmt.Errorf("os.Symlink: %s: %w", resolvConfPath, err)
}
cmd := exec.Command("systemctl", "reload-or-restart", "systemd-resolved")
@@ -259,6 +264,7 @@ type applyConfigReqEnt struct {
IP string `json:"ip"`
Port int `json:"port"`
}
type applyConfigReq struct {
Web applyConfigReqEnt `json:"web"`
DNS applyConfigReqEnt `json:"dns"`

View File

@@ -10,8 +10,8 @@ import (
"strings"
"syscall"
"github.com/AdguardTeam/AdGuardHome/update"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/update"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/golibs/log"
)
@@ -46,7 +46,7 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
Context.controlLock.Unlock()
if err != nil && strings.HasSuffix(err.Error(), "i/o timeout") {
// This case may happen while we're restarting DNS server
// https://github.com/AdguardTeam/AdGuardHome/issues/934
// https://github.com/AdguardTeam/AdGuardHome/internal/issues/934
continue
}
break

View File

@@ -53,10 +53,10 @@ func TestDoUpdate(t *testing.T) {
updateDir: Context.workDir + "/agh-update-" + newver,
backupDir: Context.workDir + "/agh-backup",
configName: Context.workDir + "/AdGuardHome.yaml",
updateConfigName: Context.workDir + "/agh-update-" + newver + "/AdGuardHome/AdGuardHome.yaml",
updateConfigName: Context.workDir + "/agh-update-" + newver + "/AdGuardHome/internal/AdGuardHome.yaml",
curBinName: Context.workDir + "/AdGuardHome",
bkpBinName: Context.workDir + "/agh-backup/AdGuardHome",
newBinName: Context.workDir + "/agh-update-" + newver + "/AdGuardHome/AdGuardHome",
newBinName: Context.workDir + "/agh-update-" + newver + "/AdGuardHome/internal/AdGuardHome",
}
assert.Equal(t, uu.pkgURL, u.pkgURL)

View File

@@ -5,14 +5,13 @@ import (
"net"
"path/filepath"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/querylog"
"github.com/AdguardTeam/AdGuardHome/stats"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/joomcode/errorx"
)
// Called by other modules when configuration is changed
@@ -75,7 +74,7 @@ func initDNSServer() error {
err = Context.dnsServer.Prepare(&dnsConfig)
if err != nil {
closeDNSServer()
return fmt.Errorf("dnsServer.Prepare: %s", err)
return fmt.Errorf("dnsServer.Prepare: %w", err)
}
Context.rdns = InitRDNS(Context.dnsServer, &Context.clients)
@@ -96,41 +95,41 @@ func isPublicIP(ip net.IP) bool {
if ip4 != nil {
switch ip4[0] {
case 0:
return false //software
return false // software
case 10:
return false //private network
return false // private network
case 127:
return false //loopback
return false // loopback
case 169:
if ip4[1] == 254 {
return false //link-local
return false // link-local
}
case 172:
if ip4[1] >= 16 && ip4[1] <= 31 {
return false //private network
return false // private network
}
case 192:
if (ip4[1] == 0 && ip4[2] == 0) || //private network
(ip4[1] == 0 && ip4[2] == 2) || //documentation
(ip4[1] == 88 && ip4[2] == 99) || //reserved
(ip4[1] == 168) { //private network
if (ip4[1] == 0 && ip4[2] == 0) || // private network
(ip4[1] == 0 && ip4[2] == 2) || // documentation
(ip4[1] == 88 && ip4[2] == 99) || // reserved
(ip4[1] == 168) { // private network
return false
}
case 198:
if (ip4[1] == 18 || ip4[2] == 19) || //private network
(ip4[1] == 51 || ip4[2] == 100) { //documentation
if (ip4[1] == 18 || ip4[2] == 19) || // private network
(ip4[1] == 51 || ip4[2] == 100) { // documentation
return false
}
case 203:
if ip4[1] == 0 && ip4[2] == 113 { //documentation
if ip4[1] == 0 && ip4[2] == 113 { // documentation
return false
}
case 224:
if ip4[1] == 0 && ip4[2] == 0 { //multicast
if ip4[1] == 0 && ip4[2] == 0 { // multicast
return false
}
case 255:
if ip4[1] == 255 && ip4[2] == 255 && ip4[3] == 255 { //subnet
if ip4[1] == 255 && ip4[2] == 255 && ip4[3] == 255 { // subnet
return false
}
}
@@ -313,7 +312,7 @@ func startDNSServer() error {
err := Context.dnsServer.Start()
if err != nil {
return errorx.Decorate(err, "Couldn't start forwarding DNS server")
return fmt.Errorf("couldn't start forwarding DNS server: %w", err)
}
Context.dnsFilter.Start()
@@ -340,7 +339,7 @@ func reconfigureDNSServer() error {
newconfig := generateServerConfig()
err := Context.dnsServer.Reconfigure(&newconfig)
if err != nil {
return errorx.Decorate(err, "Couldn't start forwarding DNS server")
return fmt.Errorf("couldn't start forwarding DNS server: %w", err)
}
return nil
@@ -353,7 +352,7 @@ func stopDNSServer() error {
err := Context.dnsServer.Stop()
if err != nil {
return errorx.Decorate(err, "Couldn't stop forwarding DNS server")
return fmt.Errorf("couldn't stop forwarding DNS server: %w", err)
}
closeDNSServer()

View File

@@ -15,14 +15,11 @@ import (
"sync/atomic"
"time"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/golibs/log"
)
var (
nextFilterID = time.Now().Unix() // semi-stable way to generate an unique ID
)
var nextFilterID = time.Now().Unix() // semi-stable way to generate an unique ID
// Filtering - module object
type Filtering struct {
@@ -35,7 +32,7 @@ type Filtering struct {
// Init - initialize the module
func (f *Filtering) Init() {
f.filterTitleRegexp = regexp.MustCompile(`^! Title: +(.*)$`)
_ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0755)
_ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0o755)
f.loadFilters(config.Filters)
f.loadFilters(config.WhitelistFilters)
deduplicateFilters()
@@ -466,7 +463,6 @@ func (f *Filtering) parseFilterContents(file io.Reader) (int, uint32, string) {
line = strings.TrimSpace(line)
if len(line) == 0 {
//
} else if line[0] == '!' {
m := f.filterTitleRegexp.FindAllStringSubmatch(line, -1)
if len(m) > 0 && len(m[0]) >= 2 && !seenTitle {
@@ -476,7 +472,6 @@ func (f *Filtering) parseFilterContents(file io.Reader) (int, uint32, string) {
} else if line[0] == '#' {
//
} else {
rulesCount++
}
@@ -521,7 +516,7 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
if filepath.IsAbs(filter.URL) {
f, err := os.Open(filter.URL)
if err != nil {
return false, fmt.Errorf("open file: %s", err)
return false, fmt.Errorf("open file: %w", err)
}
defer f.Close()
reader = f
@@ -552,8 +547,10 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
total += n
if htmlTest {
// gather full buffer firstChunk and perform its data tests
num := util.MinInt(n, len(firstChunk)-firstChunkLen)
num := len(firstChunk) - firstChunkLen
if n < num {
num = n
}
copied := copy(firstChunk[firstChunkLen:], buf[:num])
firstChunkLen += copied
@@ -563,8 +560,7 @@ func (f *Filtering) updateIntl(filter *filter) (bool, error) {
}
s := strings.ToLower(string(firstChunk))
if strings.Index(s, "<html") >= 0 ||
strings.Index(s, "<!doctype") >= 0 {
if strings.Contains(s, "<html") || strings.Contains(s, "<!doctype") {
return false, fmt.Errorf("data is HTML, not plain text")
}

View File

@@ -1,3 +1,4 @@
// Package home contains AdGuard Home's HTTP API methods.
package home
import (
@@ -8,6 +9,7 @@ import (
"io/ioutil"
"net"
"net/http"
"net/http/pprof"
"net/url"
"os"
"os/signal"
@@ -20,18 +22,15 @@ import (
"gopkg.in/natefinch/lumberjack.v2"
"github.com/AdguardTeam/AdGuardHome/update"
"github.com/AdguardTeam/AdGuardHome/util"
"github.com/AdguardTeam/AdGuardHome/internal/agherr"
"github.com/AdguardTeam/AdGuardHome/internal/update"
"github.com/AdguardTeam/AdGuardHome/internal/util"
"github.com/joomcode/errorx"
"github.com/AdguardTeam/AdGuardHome/isdelve"
"github.com/AdguardTeam/AdGuardHome/dhcpd"
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/querylog"
"github.com/AdguardTeam/AdGuardHome/stats"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/golibs/log"
)
@@ -95,7 +94,7 @@ func (c *homeContext) getDataDir() string {
var Context homeContext
// Main is the entry point
func Main(version string, channel string, armVer string) {
func Main(version, channel, armVer string) {
// Init update-related global variables
versionString = version
updateChannel = channel
@@ -111,7 +110,7 @@ func Main(version string, channel string, armVer string) {
go func() {
for {
sig := <-Context.appSignalChannel
log.Info("Received signal '%s'", sig)
log.Info("Received signal %q", sig)
switch sig {
case syscall.SIGHUP:
Context.clients.Reload()
@@ -264,7 +263,11 @@ func run(args options) {
if config.DebugPProf {
mux := http.NewServeMux()
util.PProfRegisterWebHandlers(mux)
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
go func() {
log.Info("pprof: listening on localhost:6060")
err := http.ListenAndServe("localhost:6060", mux)
@@ -273,7 +276,7 @@ func run(args options) {
}
}
err := os.MkdirAll(Context.getDataDir(), 0755)
err := os.MkdirAll(Context.getDataDir(), 0o755)
if err != nil {
log.Fatalf("Cannot create DNS data dir at %s: %s", Context.getDataDir(), err)
}
@@ -352,10 +355,7 @@ func checkPermissions() {
// On Windows we need to have admin rights to run properly
admin, _ := util.HaveAdminRights()
if //noinspection ALL
admin || isdelve.Enabled {
// Don't forget that for this to work you need to add "delve" tag explicitly
// https://stackoverflow.com/questions/47879070/how-can-i-see-if-the-goland-debugger-is-running-in-the-program
if admin {
return
}
@@ -381,7 +381,7 @@ Please note, that this is crucial for a server to be able to use privileged port
You have two options:
1. Run AdGuard Home with root privileges
2. On Linux you can grant the CAP_NET_BIND_SERVICE capability:
https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started#running-without-superuser`
https://github.com/AdguardTeam/AdGuardHome/internal/wiki/Getting-Started#running-without-superuser`
log.Fatal(msg)
}
@@ -398,7 +398,7 @@ Please note, that this is crucial for a DNS server to be able to use that port.`
// Write PID to a file
func writePIDFile(fn string) bool {
data := fmt.Sprintf("%d", os.Getpid())
err := ioutil.WriteFile(fn, []byte(data), 0644)
err := ioutil.WriteFile(fn, []byte(data), 0o644)
if err != nil {
log.Error("Couldn't write PID to file %s: %v", fn, err)
return false
@@ -481,7 +481,7 @@ func configureLogger(args options) {
logFilePath = ls.LogFile
}
_, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
_, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o644)
if err != nil {
log.Fatalf("cannot create a log file: %s", err)
}
@@ -492,7 +492,7 @@ func configureLogger(args options) {
LocalTime: ls.LogLocalTime,
MaxBackups: ls.LogMaxBackups,
MaxSize: ls.LogMaxSize, // megabytes
MaxAge: ls.LogMaxAge, //days
MaxAge: ls.LogMaxAge, // days
})
}
}
@@ -611,11 +611,7 @@ func detectFirstRun() bool {
configfile = filepath.Join(Context.workDir, Context.configFilename)
}
_, err := os.Stat(configfile)
if !os.IsNotExist(err) {
// do nothing, file exists
return false
}
return true
return os.IsNotExist(err)
}
// Connect to a remote server resolving hostname using our own DNS server
@@ -656,7 +652,7 @@ func customDialContext(ctx context.Context, network, addr string) (net.Conn, err
}
return con, err
}
return nil, errorx.DecorateMany(fmt.Sprintf("couldn't dial to %s", addr), dialErrs...)
return nil, agherr.Many(fmt.Sprintf("couldn't dial to %s", addr), dialErrs...)
}
func getHTTPProxy(req *http.Request) (*url.URL, error) {

View File

@@ -58,9 +58,9 @@ func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
log.Printf("config.Language is %s", config.Language)
_, err := fmt.Fprintf(w, "%s\n", config.Language)
if err != nil {
errorText := fmt.Sprintf("Unable to write response json: %s", err)
log.Println(errorText)
http.Error(w, errorText, http.StatusInternalServerError)
msg := fmt.Sprintf("Unable to write response json: %s", err)
log.Println(msg)
http.Error(w, msg, http.StatusInternalServerError)
return
}
}
@@ -68,23 +68,23 @@ func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
func handleI18nChangeLanguage(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
errorText := fmt.Sprintf("failed to read request body: %s", err)
log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest)
msg := fmt.Sprintf("failed to read request body: %s", err)
log.Println(msg)
http.Error(w, msg, http.StatusBadRequest)
return
}
language := strings.TrimSpace(string(body))
if language == "" {
errorText := fmt.Sprintf("empty language specified")
log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest)
msg := "empty language specified"
log.Println(msg)
http.Error(w, msg, http.StatusBadRequest)
return
}
if !isLanguageAllowed(language) {
errorText := fmt.Sprintf("unknown language specified: %s", language)
log.Println(errorText)
http.Error(w, errorText, http.StatusBadRequest)
msg := fmt.Sprintf("unknown language specified: %s", language)
log.Println(msg)
http.Error(w, msg, http.StatusBadRequest)
return
}

View File

@@ -11,7 +11,7 @@ import (
// memoryUsage implements a couple of not really beautiful hacks which purpose is to
// make OS reclaim the memory freed by AdGuard Home as soon as possible.
// See this for the details on the performance hits & gains:
// https://github.com/AdguardTeam/AdGuardHome/issues/2044#issuecomment-687042211
// https://github.com/AdguardTeam/AdGuardHome/internal/issues/2044#issuecomment-687042211
func memoryUsage(args options) {
if args.disableMemoryOptimization {
log.Info("Memory optimization is disabled")
@@ -32,13 +32,9 @@ func memoryUsage(args options) {
// that the OS could reclaim the free memory
go func() {
ticker := time.NewTicker(5 * time.Minute)
for {
select {
case t := <-ticker.C:
t.Second()
log.Debug("Free OS memory")
debug.FreeOSMemory()
}
for range ticker.C {
log.Debug("free os memory")
debug.FreeOSMemory()
}
}()
}

View File

@@ -2,6 +2,7 @@ package home
import (
"fmt"
"net"
"net/http"
uuid "github.com/satori/go.uuid"
@@ -14,7 +15,7 @@ type DNSSettings struct {
ServerName string `plist:",omitempty"`
}
type PayloadContent = struct {
type PayloadContent struct {
Name string
PayloadDescription string
PayloadDisplayName string
@@ -25,7 +26,7 @@ type PayloadContent = struct {
DNSSettings DNSSettings
}
type MobileConfig = struct {
type MobileConfig struct {
PayloadContent []PayloadContent
PayloadDescription string
PayloadDisplayName string
@@ -40,8 +41,21 @@ func genUUIDv4() string {
return uuid.NewV4().String()
}
func getMobileConfig(r *http.Request, d DNSSettings) ([]byte, error) {
name := fmt.Sprintf("%s DNS over %s", r.Host, d.DNSProtocol)
const (
dnsProtoHTTPS = "HTTPS"
dnsProtoTLS = "TLS"
)
func getMobileConfig(d DNSSettings) ([]byte, error) {
var name string
switch d.DNSProtocol {
case dnsProtoHTTPS:
name = fmt.Sprintf("%s DoH", d.ServerName)
case dnsProtoTLS:
name = fmt.Sprintf("%s DoT", d.ServerName)
default:
return nil, fmt.Errorf("bad dns protocol %q", d.DNSProtocol)
}
data := MobileConfig{
PayloadContent: []PayloadContent{{
@@ -66,9 +80,8 @@ func getMobileConfig(r *http.Request, d DNSSettings) ([]byte, error) {
return plist.MarshalIndent(data, plist.XMLFormat, "\t")
}
func handleMobileConfig(w http.ResponseWriter, r *http.Request, d DNSSettings) {
mobileconfig, err := getMobileConfig(r, d)
func handleMobileConfig(w http.ResponseWriter, d DNSSettings) {
mobileconfig, err := getMobileConfig(d)
if err != nil {
httpError(w, http.StatusInternalServerError, "plist.MarshalIndent: %s", err)
}
@@ -78,15 +91,23 @@ func handleMobileConfig(w http.ResponseWriter, r *http.Request, d DNSSettings) {
}
func handleMobileConfigDoh(w http.ResponseWriter, r *http.Request) {
handleMobileConfig(w, r, DNSSettings{
DNSProtocol: "HTTPS",
handleMobileConfig(w, DNSSettings{
DNSProtocol: dnsProtoHTTPS,
ServerURL: fmt.Sprintf("https://%s/dns-query", r.Host),
})
}
func handleMobileConfigDot(w http.ResponseWriter, r *http.Request) {
handleMobileConfig(w, r, DNSSettings{
DNSProtocol: "TLS",
ServerName: r.Host,
var err error
var host string
host, _, err = net.SplitHostPort(r.Host)
if err != nil {
httpError(w, http.StatusBadRequest, "getting host: %s", err)
}
handleMobileConfig(w, DNSSettings{
DNSProtocol: dnsProtoTLS,
ServerName: host,
})
}

View File

@@ -0,0 +1,33 @@
package home
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"howett.net/plist"
)
func TestHandleMobileConfigDot(t *testing.T) {
var err error
var r *http.Request
r, err = http.NewRequest(http.MethodGet, "https://example.com:12345/apple/dot.mobileconfig", nil)
assert.Nil(t, err)
w := httptest.NewRecorder()
handleMobileConfigDot(w, r)
assert.Equal(t, http.StatusOK, w.Code)
var mc MobileConfig
_, err = plist.Unmarshal(w.Body.Bytes(), &mc)
assert.Nil(t, err)
if assert.Equal(t, 1, len(mc.PayloadContent)) {
assert.Equal(t, "example.com DoT", mc.PayloadContent[0].Name)
assert.Equal(t, "example.com DoT", mc.PayloadContent[0].PayloadDisplayName)
assert.Equal(t, "example.com", mc.PayloadContent[0].DNSSettings.ServerName)
}
}

View File

@@ -106,7 +106,7 @@ var portArg = arg{
var p int
minPort, maxPort := 0, 1<<16-1
if p, err = strconv.Atoi(v); err != nil {
err = fmt.Errorf("port '%s' is not a number", v)
err = fmt.Errorf("port %q is not a number", v)
} else if p < minPort || p > maxPort {
err = fmt.Errorf("port %d not in range %d - %d", p, minPort, maxPort)
} else {

View File

@@ -5,7 +5,7 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/log"
"github.com/miekg/dns"
@@ -116,8 +116,7 @@ func (r *RDNS) resolve(ip string) string {
// Add the hostname:IP pair to "Clients" array
func (r *RDNS) workerLoop() {
for {
var ip string
ip = <-r.ipChannel
ip := <-r.ipChannel
host := r.resolve(ip)
if len(host) == 0 {

Some files were not shown because too many files have changed in this diff Show More