Compare commits

..

20 Commits

Author SHA1 Message Date
Ainar Garipov
952d5f3a3d all: fix release script 2021-12-29 19:20:26 +03:00
Ainar Garipov
3f126c9ec9 all: prepare chlog 2021-12-29 16:22:14 +03:00
Ainar Garipov
0be58ef918 all: imp chlog 2021-12-29 16:16:40 +03:00
Ainar Garipov
8f9053e2fc all: backport, prepare release 2021-12-29 16:09:01 +03:00
Ainar Garipov
68452e5330 cherry-pick: client: upd i18n
Updates #2643.

Squashed commit of the following:

commit bc3de579e00762bc2c4b62fb1f7ba73837c10bff
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 29 15:37:29 2021 +0300

    client: upd si-lk i18n again

commit 2cd5436b6e8c1918855aff58dd0958fe47b47e90
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 29 15:08:21 2021 +0300

    client: upd i18n
2021-12-29 16:03:34 +03:00
Ainar Garipov
2eacc46eaa cherry-pick: all: opt log levels more
Updates #3929.

Squashed commit of the following:

commit 0d4aadeff1c4de1440795faf83eb072c46392ff3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Dec 28 16:34:44 2021 +0300

    all: opt log levels more
2021-12-29 16:03:23 +03:00
Ainar Garipov
74dcc91ea7 cherry-pick: all: imp uniq validation err msgs
Updates #3975.

Squashed commit of the following:

commit f8578c2afb1bb5786e7b855a1715e0757bc08510
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Dec 28 16:39:13 2021 +0300

    aghalgo: imp docs

commit d9fc625f7c4ede2cf4b0683ad5efd0ddf9b966b1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Dec 28 16:21:24 2021 +0300

    all: imp uniq validation err msgs
2021-12-29 16:03:03 +03:00
Ainar Garipov
dd7bf61323 cherry-pick: aghnet: fix ipset init errors
Updates #4027.

Squashed commit of the following:

commit 9ac0cc27ca94e630cc321c90b60b271499af4d9b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 20:26:22 2021 +0300

    aghnet: fix ipset init errors
2021-12-29 16:02:50 +03:00
Ainar Garipov
2819d6cace cherry-pick: filtering: fix rw to subdomain
Updates #4016.

Squashed commit of the following:

commit 83bb15c5a5098103cd17e76b49f456fb4fa73408
Merge: 81905503 313555b1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 19:36:44 2021 +0300

    Merge branch 'master' into 4016-rw-subdomain

commit 81905503c977c004d7ddca1d4e7537bf76443a6e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 19:35:51 2021 +0300

    filtering: fix self reqs

commit b706f481f00232d28dade0bd747a7496753c7deb
Merge: 29cf83de 661f4ece
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 19:13:08 2021 +0300

    Merge branch 'master' into 4016-rw-subdomain

commit 29cf83de8e3ff60ea1c471c2a161055b1377392d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 19:07:08 2021 +0300

    all: fix docs

commit 9213fd8ec2b81e65b1198ab241400065f14684b1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 27 18:44:06 2021 +0300

    filtering: fix rw to subdomain
2021-12-29 16:02:04 +03:00
Eugene Burkov
75355a6883 cherry-pick: 3868 log freebsd reload fix
Merge in DNS/adguard-home from 3868-changelog to master

Squashed commit of the following:

commit 92ccf7422c4c1342c160e4806cbf9fb17c22749b
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Dec 27 19:22:47 2021 +0300

    all: log more changes
2021-12-29 16:01:31 +03:00
Eugene Burkov
e9c007d56b cherry-pick: 3868 imp service uninstall
Merge in DNS/adguard-home from 3868-imp-uninstall to master

Closes #3868.
Updates #3457.

Squashed commit of the following:

commit 6f50713407980c27e5b14bef4dc8839e134ec5c8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Dec 27 19:06:13 2021 +0300

    all: imp openwrt

commit 59f058f8ec7f5ac8cb795bf837c396601652a6ff
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Dec 27 17:26:32 2021 +0300

    all: imp code && docs

commit bab95366b0ffa40d96de5bb8116ec14606e310ed
Merge: 92ebc210 52f36f20
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Dec 27 17:06:25 2021 +0300

    Merge branch 'master' into 3868-imp-uninstall

commit 92ebc210f04d5e02c3eef726017a0d5687f4bc4c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Dec 27 13:18:58 2021 +0300

    home: imp freebsd script & log changes

commit 583ffc256e9f87cf19da2eca8bbefc9e00ea86cc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 16 14:08:46 2021 +0300

    all: imp service uninstall
2021-12-29 16:01:09 +03:00
Ainar Garipov
84c9085516 cherry-pick: filtering: restore rewrite behavior with other question types
Updates #4008.

Squashed commit of the following:

commit babbc29331cfc2603c0c3b0987f5ba926690ec3e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Dec 24 18:46:20 2021 +0300

    filtering: restore rewrite behavior with other question types
2021-12-24 22:41:10 +03:00
Ainar Garipov
9f36e57c1e cherry-pick: all: opt log levels
Updates #3929.

Squashed commit of the following:

commit bfb2361d81a0667c36193484ca125d08e5638b21
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Dec 24 17:23:39 2021 +0300

    all: opt log levels
2021-12-24 22:41:10 +03:00
Eugene Burkov
7528699fc2 cherry-pick: 3987 Fix nil pointer dereference
Merge in DNS/adguard-home from 3987-fix-nil-deref to master

Updates #3987.
Updates #2846.

Squashed commit of the following:

commit d653e09ce88a8b10b2a17fea1563c419895c714c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 20:08:51 2021 +0300

    all: log changes

commit c47a4eeacf76fa7df2d01af166dee9d52528ac58
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 19:22:39 2021 +0300

    aghnet: fix windows tests

commit 9c91f14ccfe967ada3c00ddb86d673238e52c12d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 19:09:49 2021 +0300

    aghnet: imp code readability, docs

commit d3df15d1892e4ebfe7f8ea7144e39a0c712fce52
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 18:47:28 2021 +0300

    aghnet: fix nil pointer dereference
2021-12-24 22:41:10 +03:00
Eugene Burkov
d280151c18 cherry-pick: 3998 Make hosts rules match exactly
Merge in DNS/adguard-home from 3998-fix-hosts-gen to master

Closes #3998

Squashed commit of the following:

commit b565d51afb6c292dd16accd45b7d37ed386714e8
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 16:25:02 2021 +0300

    aghnet: make hosts rules match exactly
2021-12-24 22:41:10 +03:00
Ainar Garipov
b44c755d25 cherry-pick: all: upd dnsproxy
Updates #3977.

Squashed commit of the following:

commit 3aaaacac102cdea04ae46b36d2dd3a3be7d50147
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Dec 23 16:15:11 2021 +0300

    all: upd dnsproxy
2021-12-24 22:41:05 +03:00
Ainar Garipov
e4078e87a1 cherry-pick: 3945 log success
Updates #3945.

* commit 'ebe86ce00ebca3431a96a44c3616af3ac42250ab':
  home: imp auth
  Log successful login attempts in addition to failed ones
2021-12-24 22:23:22 +03:00
Eugene Burkov
be36204756 cherry-pick: Update miekg/dns
Merge in DNS/adguard-home from upd-dns-lib to master

Updates #2275.

Squashed commit of the following:

commit 54d0485157ac4f08830ad7d8ca9be49eef87d678
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 23 13:31:34 2021 +0300

    all: upd dns lib
2021-12-24 22:22:47 +03:00
Ainar Garipov
b5409d6d00 cherry-pick: client: imp en i18n
Merge in DNS/adguard-home from en-i18n-safe-browsing to master

Squashed commit of the following:

commit dd32a58c3761818a10386b4a1d9e6871da59c71e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 22 17:31:35 2021 +0300

    client: imp en i18n
2021-12-24 22:19:07 +03:00
Ainar Garipov
f3d6bce03e cherry-pick: scripts: add network-control plug
Updates #3976.

Squashed commit of the following:

commit 49d8a3a2d333c7896530c8a44c5ef06c396b5ae0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 22 16:20:45 2021 +0300

    scripts: add network-control plug
2021-12-24 22:18:19 +03:00
67 changed files with 862 additions and 1320 deletions

View File

@@ -1,7 +1,7 @@
'name': 'build'
'env':
'GO_VERSION': '1.17'
'GO_VERSION': '1.16'
'NODE_VERSION': '14'
'on':

View File

@@ -1,7 +1,7 @@
'name': 'lint'
'env':
'GO_VERSION': '1.17'
'GO_VERSION': '1.16'
'on':
'push':

View File

@@ -7,65 +7,38 @@ The format is based on
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
<!--
## [v0.108.0] - 2022-06-01 (APPROX.)
## [v0.108.0] - 2021-06-01 (APPROX.)
-->
### Added
- Support for a `$dnsrewrite` modifier with an empty `NOERROR` response
([#4133]).
- `windows/arm64` support ([#3057]).
### Deprecated
<!--
TODO(a.garipov): Remove this deprecation, if v0.108.0 is released before the Go
1.18 release.
TODO(a.garipov): Remove this deprecation, if v0.108.0 is released before
the Go 1.18 release.
-->
- Go 1.17 support. v0.109.0 will require at least Go 1.18 to build.
### Fixed
- Wrong set of ports checked for duplicates during the initial setup ([#4095]).
- Incorrectly invalidated service domains ([#4120]).
- Poor testing of domain-specific upstream servers ([#4074]).
- Omitted aliases of hosts specified by another line within the OS's hosts file
([#4079]).
### Removed
- Go 1.16 support.
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
[#4074]: https://github.com/AdguardTeam/AdGuardHome/issues/4074
[#4079]: https://github.com/AdguardTeam/AdGuardHome/issues/4079
[#4095]: https://github.com/AdguardTeam/AdGuardHome/issues/4095
[#4120]: https://github.com/AdguardTeam/AdGuardHome/issues/4120
[#4133]: https://github.com/AdguardTeam/AdGuardHome/issues/4133
<!--
## [v0.107.3] - 2022-02-08 (APPROX.)
## [v0.107.2] - 2021-01-19 (APPROX.)
-->
## [v0.107.2] - 2021-12-29
### Fixed
- Infinite loops when TCP connections time out ([#4042]).
[#4042]: https://github.com/AdguardTeam/AdGuardHome/issues/4042
## [v0.107.1] - 2021-12-29
### Changed
@@ -695,12 +668,11 @@ In this release, the schema version has changed from 10 to 12.
<!--
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.3...HEAD
[v0.107.3]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.2...v0.107.3
-->
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.2...HEAD
[v0.107.2]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.1...v0.107.2
-->
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.1...HEAD
[v0.107.1]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.0...v0.107.1
[v0.107.0]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.106.3...v0.107.0
[v0.106.3]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.106.2...v0.106.3

View File

@@ -185,7 +185,7 @@ Run `make init` to prepare the development environment.
You will need this to build AdGuard Home:
* [go](https://golang.org/dl/) v1.17 or later.
* [go](https://golang.org/dl/) v1.16 or later.
* [node.js](https://nodejs.org/en/download/) v10.16.2 or later.
* [npm](https://www.npmjs.com/) v6.14 or later (temporary requirement, TODO: remove when redesign is finished).
* [yarn](https://yarnpkg.com/) v1.22.5 or later.

View File

@@ -7,7 +7,7 @@
# Make sure to sync any changes with the branch overrides below.
'variables':
'channel': 'edge'
'dockerGo': 'adguard/golang-ubuntu:4.0'
'dockerGo': 'adguard/golang-ubuntu:3.8'
'stages':
- 'Make release':
@@ -266,7 +266,7 @@
# need to build a few of these.
'variables':
'channel': 'beta'
'dockerGo': 'adguard/golang-ubuntu:4.0'
'dockerGo': 'adguard/golang-ubuntu:3.8'
# release-vX.Y.Z branches are the branches from which the actual final release
# is built.
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
@@ -281,4 +281,4 @@
# are the ones that actually get released.
'variables':
'channel': 'release'
'dockerGo': 'adguard/golang-ubuntu:4.0'
'dockerGo': 'adguard/golang-ubuntu:3.8'

View File

@@ -5,7 +5,7 @@
'key': 'AHBRTSPECS'
'name': 'AdGuard Home - Build and run tests'
'variables':
'dockerGo': 'adguard/golang-ubuntu:4.0'
'dockerGo': 'adguard/golang-ubuntu:3.8'
'stages':
- 'Tests':

View File

@@ -163,8 +163,8 @@
"apply_btn": "Ужыць",
"disabled_filtering_toast": "Фільтрацыя выкл.",
"enabled_filtering_toast": "Фільтрацыя ўкл.",
"disabled_safe_browsing_toast": "Бяспечная навігацыя выключана",
"enabled_safe_browsing_toast": "Бяспечная навігацыя ўключана",
"disabled_safe_browsing_toast": "Бяспечная навігацыя выкл.",
"enabled_safe_browsing_toast": "Бяспечная навігацыя ўкл.",
"disabled_parental_toast": "Бацькоўскі кантроль выкл.",
"enabled_parental_toast": "Бацькоўскі кантроль укл.",
"disabled_safe_search_toast": "Бяспечны пошук выкл.",
@@ -200,7 +200,6 @@
"form_error_url_or_path_format": "Няслушны URL ці абсалютны шлях да спіса",
"custom_filter_rules": "Карыстацкае рэдагавала фільтрацыі",
"custom_filter_rules_hint": "Уводзьце па адным правіле на радок. Вы можаце выкарыстоўваць правілы блакавання ці сінтаксіс файлаў hosts.",
"system_host_files": "Сістэмныя hosts-файлы",
"examples_title": "Прыклады",
"example_meaning_filter_block": "заблакаваць доступ да дамена example.org і ўсім яго паддаменам",
"example_meaning_filter_whitelist": "адблакаваць доступ да дамена example.org і ўсім яго паддаменам",
@@ -587,8 +586,8 @@
"show_blocked_responses": "Заблакавана",
"show_whitelisted_responses": "Белы спіс",
"show_processed_responses": "Апрацавана",
"blocked_safebrowsing": "Заблакавана згодна базе дадзеных Safe Browsing",
"blocked_adult_websites": "Заблакавана Бацькоўскім кантролем",
"blocked_safebrowsing": "Заблакавана згодна базе дадзеных Safebrowsing",
"blocked_adult_websites": "Заблакаваныя \"дарослыя\" сайты",
"blocked_threats": "Заблакавана пагроз",
"allowed": "Дазволены",
"filtered": "Адфільтраваныя",
@@ -625,7 +624,5 @@
"last_rule_in_allowlist": "Няможна заблакаваць гэтага кліента, бо вынятак правіла «{{disallowed_rule}}» АДКЛЮЧЫЦЬ рэжым белага спіса.",
"experimental": "Эксперыментальны",
"use_saved_key": "Скарыстаць захаваны раней ключ",
"parental_control": "Бацькоўскі кантроль",
"safe_browsing": "Бяспечны інтэрнэт",
"served_from_cache": "{{value}} <i>(атрымана з кэша)</i>"
"parental_control": "Бацькоўскі кантроль"
}

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Neplatná adresa IPv6",
"form_error_ip_format": "Neplatná adresa IP",
"form_error_mac_format": "Neplatná adresa MAC",
"form_error_client_id_format": "ID klienta musí obsahovat pouze čísla, malá písmena a spojovníky",
"form_error_client_id_format": "Neplatné ID klienta",
"form_error_server_name": "Neplatný název serveru",
"form_error_subnet": "Podsíť \"{{cidr}}\" neobsahuje IP adresu \"{{ip}}\"",
"form_error_positive": "Musí být větší než 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Ugyldig IPv6-adresse",
"form_error_ip_format": "Ugyldig IP-adresse",
"form_error_mac_format": "Ugyldig MAC-adresse",
"form_error_client_id_format": "Klient-ID må kun indeholde cifre, minuskler og bindestreger",
"form_error_client_id_format": "Ugyldigt klient-ID",
"form_error_server_name": "Ugyldigt servernavn",
"form_error_subnet": "Subnet \"{{cidr}}\" indeholder ikke IP-adressen \"{{ip}}\"",
"form_error_positive": "Skal være større end 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Invalid IPv6 address",
"form_error_ip_format": "Invalid IP address",
"form_error_mac_format": "Invalid MAC address",
"form_error_client_id_format": "Client ID must contain only numbers, lowercase letters, and hyphens",
"form_error_client_id_format": "Invalid client ID",
"form_error_server_name": "Invalid server name",
"form_error_subnet": "Subnet \"{{cidr}}\" does not contain the IP address \"{{ip}}\"",
"form_error_positive": "Must be greater than 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Dirección IPv6 no válida",
"form_error_ip_format": "Dirección IP no válida",
"form_error_mac_format": "Dirección MAC no válida",
"form_error_client_id_format": "El ID de cliente debe contener solo números, letras minúsculas y guiones",
"form_error_client_id_format": "ID de cliente no válido",
"form_error_server_name": "Nombre de servidor no válido",
"form_error_subnet": "La subred \"{{cidr}}\" no contiene la dirección IP \"{{ip}}\"",
"form_error_positive": "Debe ser mayor que 0",

View File

@@ -17,7 +17,7 @@
"form_error_required": "فیلد مورد نیاز",
"form_error_ip4_format": "فرمت نامعتبر IPv4",
"form_error_ip6_format": "فرمت نامعتبر IPv6",
"form_error_ip_format": "آدرس آی پی نامعتبر است",
"form_error_ip_format": "فرمت IPv4 نامعتبر است",
"form_error_mac_format": "فرمت مَک نامعتبر است",
"form_error_client_id_format": "فرمت شناسه کلاینت نامعتبر است",
"form_error_positive": "باید بزرگتر از 0 باشد",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Virheellinen IPv6-osoite",
"form_error_ip_format": "Virheellinen IP-osoite",
"form_error_mac_format": "Virheellinen MAC-osoite",
"form_error_client_id_format": "Päätelaitteen tunniste voi sisältää ainoastaan numeroita, pieniä kirjaimia sekä yhdysviivoja",
"form_error_client_id_format": "Virheellinen päätelaitteen ID",
"form_error_server_name": "Virheellinen palvelimen nimi",
"form_error_subnet": "Aliverkko \"{{cidr}}\" ei sisällä IP-osoitetta \"{{ip}}\"",
"form_error_positive": "Oltava suurempi kuin 0",
@@ -603,9 +603,9 @@
"enter_cache_size": "Syötä välimuistin koko (tavuina)",
"enter_cache_ttl_min_override": "Syötä vähimmäis-TTL (sekunteina)",
"enter_cache_ttl_max_override": "Syötä enimmäis-TTL (sekunteina)",
"cache_ttl_min_override_desc": "Pidennä ylävirran palvelimelta vastaanotettuja, lyhyitä elinaika-arvoja (sekunteina) tallennettaessa DNS-vastauksia välimuistiin.",
"cache_ttl_max_override_desc": "Määritä DNS-välimuistin kohteiden suurin elinaika-arvo (sekunteina)",
"ttl_cache_validation": "Välimuistin elinajan vähimmäisarvon tulee olla pienempi tai sama kuin enimmäisarvon",
"cache_ttl_min_override_desc": "Pidennä ylävirran palvelimelta vastaanotettuja, lyhyitä time-to-live -arvoja (sekunteina) tallennettaessa DNS-vastauksia välimuistiin.",
"cache_ttl_max_override_desc": "Määritä DNS-välimuistin kohteiden suurin time-to-live -arvo (sekunteina)",
"ttl_cache_validation": "Välimuistin TTL-vähimmäisarvon tulee olla pienempi tai sama kuin enimmäisarvon",
"cache_optimistic": "Optimistinen välimuisti",
"cache_optimistic_desc": "Pakota AdGuard Home vastaamaan välimuistista vaikka sen tiedot olisivat vanhentuneet. Pyri samalla myös päivittämään tiedot.",
"filter_category_general": "Yleiset",

View File

@@ -163,7 +163,7 @@
"apply_btn": "Primijeni",
"disabled_filtering_toast": "Onemogućeno filtriranje",
"enabled_filtering_toast": "Omogućeno filtriranje",
"disabled_safe_browsing_toast": "Onemogućena Sigurna pretraga",
"disabled_safe_browsing_toast": "Onemogućena sigurna pretraga",
"enabled_safe_browsing_toast": "Omogućena sigurna pretraga",
"disabled_parental_toast": "Onemogućen roditeljski nadzor",
"enabled_parental_toast": "Omogućen roditeljski nadzor",

View File

@@ -36,7 +36,7 @@
"dhcp_ipv4_settings": "DHCP IPv4 Beállítások",
"dhcp_ipv6_settings": "DHCP IPv6 Beállítások",
"form_error_required": "Kötelező mező",
"form_error_ip4_format": "Érvénytelen IPv4 m",
"form_error_ip4_format": "Érvénytelen IPv4 formátum",
"form_error_ip6_format": "Érvénytelen IPv6 formátum",
"form_error_ip_format": "Érvénytelen IP-cím",
"form_error_mac_format": "Érvénytelen MAC formátum",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Indirizzo IPv6 non valido",
"form_error_ip_format": "Indirizzo IP non valido",
"form_error_mac_format": "Indirizzo MAC non valido",
"form_error_client_id_format": "Il client ID deve contenere solo numeri, lettere minuscole e trattini",
"form_error_client_id_format": "ID cliente non valido",
"form_error_server_name": "Nome server non valido",
"form_error_subnet": "La subnet \"{{cidr}}\" non contiene l'indirizzo IP \"{{ip}}\"",
"form_error_positive": "Deve essere maggiore di 0",
@@ -295,16 +295,16 @@
"blocking_mode_null_ip": "IP nullo: Rispondi con indirizzo IP zero (0.0.0.0 per A; :: per AAAA)",
"blocking_mode_custom_ip": "IP personalizzato: Rispondi con un indirizzo IP impostato manualmente",
"upstream_dns_client_desc": "Se lasci questo spazio vuoto, AdGuard Home utilizzerà i server configurati nelle <0>impostazioni DNS</0>.",
"tracker_source": "Origine del tracciatore",
"tracker_source": "Origine tracciante",
"source_label": "Fonte",
"found_in_known_domain_db": "Trovato nel database dei domini noti.",
"found_in_known_domain_db": "Trovato nel database dei domini conosciuti.",
"category_label": "Categoria",
"rule_label": "Regola(e)",
"list_label": "Elenco",
"unknown_filter": "Filtro sconosciuto {{filterId}}",
"known_tracker": "Tracciatore noto",
"known_tracker": "Tracciante noto",
"install_welcome_title": "Benvenuto nella Home di AdGuard!",
"install_welcome_desc": "AdGuard Home è un server DNS che blocca annunci e tracciatori a livello di rete. Il suo scopo è quello di permetterti il controllo dell'intera rete e di tutti i dispositivi, e non richiede l'utilizzo di un programma lato client.",
"install_welcome_desc": "AdGuard Home è un server DNS che blocca annunci e traccianti in tutta la rete. Il suo scopo è quello di consentire di controllare l'intera rete e tutti i dispositivi, e non richiede l'utilizzo di un programma sul lato client.",
"install_settings_title": "Interfaccia Web dell'Admin",
"install_settings_listen": "Interfaccia d'ascolto",
"install_settings_port": "Porta",
@@ -400,7 +400,7 @@
"dns_status_error": "Errore nel recupero dello stato del server DNS",
"down": "Spenta",
"fix": "Risolvi",
"dns_providers": "Qui c'è un <0>elenco di fornitori DNS noti</0> da cui scegliere.",
"dns_providers": "Qui c'è un <0>elenco di fornitori DNS conosciuti</0> da cui scegliere.",
"update_now": "Aggiorna ora",
"update_failed": "Aggiornamento automatico non riuscito. Ti suggeriamo di <a>seguire questi passaggi</a> per aggiornare manualmente.",
"processing_update": "Perfavore aspetta, AdGuard Home si sta aggiornando",
@@ -612,9 +612,9 @@
"filter_category_security": "Sicurezza",
"filter_category_regional": "Regionale",
"filter_category_other": "Altro",
"filter_category_general_desc": "Elenchi per il blocco dei tracciatori e degli annunci sulla maggioranza dei dispositivi",
"filter_category_general_desc": "Elenchi per il blocco dei traccianti e degli annunci sulla maggioranza dei dispositivi",
"filter_category_security_desc": "Elenchi progettati specificamente per bloccare domini malevoli, di phishing o truffa",
"filter_category_regional_desc": "Elenchi focalizzati su annunci regionali e server tracciatori",
"filter_category_regional_desc": "Elenchi focalizzati su annunci regionali e server traccianti",
"filter_category_other_desc": "Altre liste nere",
"setup_config_to_enable_dhcp_server": "Configurazione dell'installazione per l'attivazione del server DHCP",
"original_response": "Responso originale",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Ongeldig IPv6-adres",
"form_error_ip_format": "Ongeldig IP-adres",
"form_error_mac_format": "Ongeldig MAC-adres",
"form_error_client_id_format": "Client-ID mag alleen cijfers, kleine letters en koppeltekens bevatten",
"form_error_client_id_format": "Ongeldige cliënt-ID",
"form_error_server_name": "Ongeldige servernaam",
"form_error_subnet": "Subnet “{{cidr}}” bevat niet het IP-adres “{{ip}}”",
"form_error_positive": "Moet groter zijn dan 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Nieprawidłowy adres IPv6",
"form_error_ip_format": "Nieprawidłowy adres IP",
"form_error_mac_format": "Nieprawidłowy adres MAC",
"form_error_client_id_format": "ID klienta musi zawierać tylko cyfry, małe litery i myślniki",
"form_error_client_id_format": "Nieprawidłowy ID klienta",
"form_error_server_name": "Nieprawidłowa nazwa serwera",
"form_error_subnet": "Podsieć \"{{cidr}}\" nie zawiera adresu IP \"{{ip}}\"",
"form_error_positive": "Musi być większa niż 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Endereço de IPv6 inválido",
"form_error_ip_format": "Endereço de IP inválido",
"form_error_mac_format": "Endereço de MAC inválido",
"form_error_client_id_format": "O ID do cliente deve conter apenas números, letras minúsculas e hifens",
"form_error_client_id_format": "ID de cliente inválido",
"form_error_server_name": "Nome de servidor inválido",
"form_error_subnet": "A sub-rede \"{{cidr}}\" não contém o endereço IP \"{{ip}}\"",
"form_error_positive": "Deve ser maior que 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Endereço de IPv6 inválido",
"form_error_ip_format": "Endereço de IP inválido",
"form_error_mac_format": "Endereço de MAC inválido",
"form_error_client_id_format": "O ID do cliente deve conter apenas números, letras minúsculas e hifens",
"form_error_client_id_format": "ID de cliente inválido",
"form_error_server_name": "Nome de servidor inválido",
"form_error_subnet": "A sub-rede \"{{cidr}}\" não contém o endereço IP \"{{ip}}\"",
"form_error_positive": "Deve ser maior que 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Adresa IPv6 nevalidă",
"form_error_ip_format": "Adresă IP nevalidă",
"form_error_mac_format": "Adresă MAC nevalidă",
"form_error_client_id_format": "ID-ul clientului trebuie să conțină numai numere, litere minuscule și liniuțe.",
"form_error_client_id_format": "ID client nevalid",
"form_error_server_name": "Nume de server nevalid",
"form_error_subnet": "Subrețeaua „{{cidr}}” nu conține adresa IP „{{ip}}”",
"form_error_positive": "Trebuie să fie mai mare de 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Некорректный IPv6-адрес",
"form_error_ip_format": "Некорректный IP-адрес",
"form_error_mac_format": "Некорректный MAC-адрес",
"form_error_client_id_format": "ID клиента может содержать только цифры, строчные латинские буквы и дефисы",
"form_error_client_id_format": "Некорректный ID клиента",
"form_error_server_name": "Некорректное имя сервера",
"form_error_subnet": "Подсеть «{{cidr}}» не содержит IP-адрес «{{ip}}»",
"form_error_positive": "Должно быть больше 0",
@@ -587,7 +587,7 @@
"show_blocked_responses": "Заблокировано",
"show_whitelisted_responses": "В белом списке",
"show_processed_responses": "Обработан",
"blocked_safebrowsing": "Заблокировано согласно базе данных Safe Browsing",
"blocked_safebrowsing": "Заблокировано согласно базе данных Safebrowsing",
"blocked_adult_websites": "Заблокировано Родительским контролем",
"blocked_threats": "Заблокировано угроз",
"allowed": "Разрешённые",

View File

@@ -163,8 +163,8 @@
"apply_btn": "Použiť",
"disabled_filtering_toast": "Vypnutá filtrácia",
"enabled_filtering_toast": "Zapnutá filtrácia",
"disabled_safe_browsing_toast": "Bezpečné prehliadanie vypnuté",
"enabled_safe_browsing_toast": "Bezpečné prehliadanie zapnuté",
"disabled_safe_browsing_toast": "Vypnuté Bezpečné prehliadanie",
"enabled_safe_browsing_toast": "Zapnuté Bezpečné prehliadanie",
"disabled_parental_toast": "Vypnutá Rodičovská kontrola",
"enabled_parental_toast": "Zapnutá Rodičovská kontrola",
"disabled_safe_search_toast": "Vypnuté bezpečné vyhľadávanie",
@@ -588,7 +588,7 @@
"show_whitelisted_responses": "Obsiahnuté v bielej listine",
"show_processed_responses": "Spracované",
"blocked_safebrowsing": "Zablokované modulom Bezpečné prehliadanie",
"blocked_adult_websites": "Zablokovaná stránka pre dospelých",
"blocked_adult_websites": "Blokované Rodičovskou kontrolou",
"blocked_threats": "Zablokované hrozby",
"allowed": "Povolené",
"filtered": "Filtrované",

View File

@@ -16,8 +16,6 @@
"dhcp_static_leases": "Statiska DHCP-leases",
"dhcp_leases_not_found": "Ingen DHCP-lease hittad",
"form_error_required": "Obligatoriskt fält",
"form_error_ip4_format": "Ogiltig IPv4-adress",
"form_error_ip6_format": "Ogiltig IPv6-adress",
"form_error_ip_format": "Ogiltig IP-adress",
"form_error_mac_format": "Ogiltig MAC-adress",
"form_error_positive": "Måste vara större än noll",
@@ -353,7 +351,7 @@
"show_blocked_responses": "Blockerade",
"show_whitelisted_responses": "Vitlistade",
"show_processed_responses": "Utförda",
"blocked_adult_websites": "Blockerad av Föräldrakontroll",
"blocked_adult_websites": "Blockerad av Föräldrakontrollen",
"blocked_threats": "Blockerade hot",
"allowed": "Vitlistade",
"safe_search": "Säker surf",
@@ -361,5 +359,5 @@
"filter_category_security": "säkerhet",
"filter_category_other": "Övrigt",
"use_saved_key": "Använd den tidigare sparade nyckeln",
"parental_control": "Föräldrakontroll"
"parental_control": "Föräldrarkontroll"
}

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "IPv6 adresi geçersiz",
"form_error_ip_format": "IP adresi geçersiz",
"form_error_mac_format": "MAC adresi geçersiz",
"form_error_client_id_format": "İstemci kimliği yalnızca sayılar, küçük harfler ve kısa çizgiler içermelidir",
"form_error_client_id_format": "İstemci kimliği geçersiz",
"form_error_server_name": "Sunucu adı geçersiz",
"form_error_subnet": "\"{{cidr}}\" alt ağı, \"{{ip}}\" IP adresini içermiyor",
"form_error_positive": "0'dan büyük olmalıdır",
@@ -53,7 +53,7 @@
"greater_range_end_error": "Bitiş aralığından daha büyük olmalıdır",
"subnet_error": "Adresler bir alt ağda olmalıdır",
"gateway_or_subnet_invalid": "Alt ağ maskesi geçersiz",
"dhcp_form_gateway_input": "Ağ geçidi IP",
"dhcp_form_gateway_input": "Ağ Geçidi IP'si",
"dhcp_form_subnet_input": "Alt ağ maskesi",
"dhcp_form_range_title": "IP adresi aralığı",
"dhcp_form_range_start": "Başlangıç aralığı",
@@ -138,7 +138,7 @@
"average_processing_time": "Ortalama işlem süresi",
"average_processing_time_hint": "Bir DNS isteğinin milisaniye cinsinden ortalama işlem süresi",
"block_domain_use_filters_and_hosts": "Filtre ve ana bilgisayar listelerini kullanarak alan adlarını engelle",
"filters_block_toggle_hint": "<a>Filtreler</a> ayarlarında engelleme kuralları oluşturabilirsiniz.",
"filters_block_toggle_hint": "<a>Filtreler</a> sayfasından engelleme kurallarını ayarlayabilirsiniz.",
"use_adguard_browsing_sec": "AdGuard gezinti koruması web hizmetini kullan",
"use_adguard_browsing_sec_hint": "AdGuard Home, alan adının gezinti koruması web hizmeti tarafından engellenip engellenmediğini kontrol eder. Kontrolü gerçekleştirmek için gizlilik dostu arama API'sini kullanır: sunucuya yalnızca SHA256 karma alan adının kısa bir ön eki gönderilir.",
"use_adguard_parental": "AdGuard ebeveyn denetimi web hizmetini kullan",
@@ -165,10 +165,10 @@
"enabled_filtering_toast": "Filtreleme etkin",
"disabled_safe_browsing_toast": "Güvenli Gezinti devre dışı bırakıldı",
"enabled_safe_browsing_toast": "Güvenli Gezinti etkinleştirildi",
"disabled_parental_toast": "Ebeveyn denetimi devre dışı bırakıldı",
"enabled_parental_toast": "Ebeveyn denetimi etkinleştirildi",
"disabled_safe_search_toast": "Güvenli arama devre dışı bırakıldı",
"enabled_save_search_toast": "Güvenli arama etkinleştirildi",
"disabled_parental_toast": "Ebeveyn denetimi devre dışı",
"enabled_parental_toast": "Ebeveyn denetimi etkin",
"disabled_safe_search_toast": "Güvenli arama devre dışı",
"enabled_save_search_toast": "Güvenli arama etkin",
"enabled_table_header": "Etkin",
"name_table_header": "İsim",
"list_url_table_header": "Liste URL'si",
@@ -178,7 +178,7 @@
"request_table_header": "İstek",
"edit_table_action": "Düzenle",
"delete_table_action": "Sil",
"elapsed": "Geçen süre",
"elapsed": "Geçen zaman",
"filters_and_hosts_hint": "AdGuard Home, temel reklam engelleme kurallarını ve ana bilgisayar engelleme dosyalarının söz dizimini anlar.",
"no_blocklist_added": "Engel listesi eklenmedi",
"no_whitelist_added": "İzin listesi eklenmedi",
@@ -327,10 +327,10 @@
"install_submit_desc": "Yükleme işlemi tamamlandı ve artık AdGuard Home'u kullanmaya hazırsınız.",
"install_devices_router": "Yönlendirici",
"install_devices_router_desc": "Bu kurulum, ev yönlendiricinize bağlı tüm cihazları otomatik olarak kapsar ve her birini elle yapılandırmanıza gerek yoktur.",
"install_devices_address": "AdGuard Home DNS sunucusu aşağıdaki adresleri dinliyor",
"install_devices_address": "AdGuard Home DNS sunucusu şu adresi dinleyecektir",
"install_devices_router_list_1": "Yönlendiricinizin ayarlarına gidin. Genellikle tarayıcınızdan http://192.168.0.1/ veya http://192.168.1.1/ gibi bir URL aracılığıyla erişebilirsiniz. Bir parola girmeniz istenebilir. Hatırlamıyorsanız, genellikle yönlendiricinin üzerindeki bir düğmeye basarak parolayı sıfırlayabilirsiniz, ancak bu işlemin seçilmesi durumunda yüksek ihtimalle tüm yönlendirici yapılandırmasını kaybedeceğinizi unutmayın. Yönlendiricinizin kurulumu için bir uygulama gerekiyorsa, lütfen uygulamayı telefonunuza veya PC'nize yükleyin ve yönlendiricinin ayarlarına erişmek için kullanın.",
"install_devices_router_list_2": "DHCP/DNS ayarlarını bulun. DNS satırlarını arayın, genelde iki veya üç tanedir, üç rakam girilebilen dört ayrı grup içeren satırdır.",
"install_devices_router_list_3": "AdGuard Home sunucu adreslerinizi oraya girin.",
"install_devices_router_list_3": "AdGuard Home sunucusunun adresini o kısma yazın.",
"install_devices_router_list_4": "Bazı yönlendirici türlerinde özel bir DNS sunucusu ayarlanamaz. Bu durumda, AdGuard Home'u <0>DHCP sunucusu</0> olarak ayarlamak yardımcı olabilir. Aksi takdirde, yönlendirici modeliniz için DNS sunucularını nasıl ayarlayacağınız konusunda yönlendirici kılavuzuna bakmalısınız.",
"install_devices_windows_list_1": "Başlat menüsünden veya Windows araması aracılığıyla Denetim Masası'nıın.",
"install_devices_windows_list_2": "Ağ ve İnternet kategorisine girin ve ardından Ağ ve Paylaşım Merkezi'ne girin.",
@@ -339,15 +339,15 @@
"install_devices_windows_list_5": "Listede \"İnternet Protokolü Sürüm 4 (TCP/IPv4)\" (veya IPv6 için \"İnternet Protokolü Sürüm 6 (TCP/IPv6)\") öğesini bulun, seçin ve ardından tekrar Özellikler'e tıklayın.",
"install_devices_windows_list_6": "\"Aşağıdaki DNS sunucu adreslerini kullan\"ı seçin ve AdGuard Home sunucu adreslerinizi girin.",
"install_devices_macos_list_1": "Apple simgesinde bulunan Sistem Tercihleri'ne tıklayın.",
"install_devices_macos_list_2": "Ağ'a tıklayın.",
"install_devices_macos_list_2": "Ağ seçeneğine tıklayın.",
"install_devices_macos_list_3": "Listedeki ilk bağlantıyı seçin ve Gelişmiş öğesine tıklayın.",
"install_devices_macos_list_4": "DNS sekmesini seçin ve AdGuard Home sunucunuzun adreslerini girin.",
"install_devices_android_list_1": "Android Menüsü ana ekranından Ayarlar'a dokunun.",
"install_devices_android_list_1": "Android cihazınızda Ayarlar simgesine dokunun.",
"install_devices_android_list_2": "Menüde bulunan Wi-Fi seçeneğine dokunun. Mevcut tüm ağlar listelenecektir (mobil ağlar için özel DNS sunucusu ayarlanamaz).",
"install_devices_android_list_3": "Bağlı olduğunuz ağın üzerine basılı tutun ve Ağı Değiştir'e dokunun.",
"install_devices_android_list_4": "Bazı cihazlarda, diğer ayarları görmek için \"Gelişmiş\" seçeneğini seçmeniz gerekebilir. Android DNS ayarlarınızı yapmak için IP ayarlarını DHCP modundan Statik moda almanız gerekecektir.",
"install_devices_android_list_5": "DNS 1 ve DNS 2 değerlerini AdGuard Home sunucunuzun adresleriyle değiştirin.",
"install_devices_ios_list_1": "Ana ekrandan Ayarlar'a dokunun.",
"install_devices_ios_list_1": "Ana ekrandaki Ayarlar simgesine dokunun.",
"install_devices_ios_list_2": "Sol menüde bulunan Wi-Fi bölümüne girin (mobil ağlar için özel DNS sunucusu ayarlanamaz).",
"install_devices_ios_list_3": "Bağlı olduğunuz ağın ismine dokunun.",
"install_devices_ios_list_4": "DNS alanına AdGuard Home sunucunuzun adreslerini girin.",
@@ -386,8 +386,8 @@
"encryption_issuer": "Sağlayan",
"encryption_hostnames": "Ana bilgisayar adları",
"encryption_reset": "Şifreleme ayarlarını sıfırlamak istediğinizden emin misiniz?",
"topline_expiring_certificate": "SSL sertifikanızın süresi sona erdi. <0>Şifreleme ayarlarını</0> güncelleyin.",
"topline_expired_certificate": "SSL sertifikanızın süresi sona erdi. <0>Şifreleme ayarlarını</0> güncelleyin.",
"topline_expiring_certificate": "SSL sertifikanızın süresi dolmak üzere. <0>Şifreleme ayarlarını</0> güncelleyin.",
"topline_expired_certificate": "SSL sertifikanızın süresi doldu. <0>Şifreleme ayarlarını</0> güncelleyin.",
"form_error_port_range": "80-65535 aralığında geçerli bir bağlantı noktası değeri girin",
"form_error_port_unsafe": "Bu bağlantı noktası güvenli değil",
"form_error_equal": "Aynı olmamalı",
@@ -417,7 +417,7 @@
"client_identifier": "Tanımlayıcı",
"ip_address": "IP adresi",
"client_identifier_desc": "İstemciler IP adresi, CIDR, MAC adresi veya özel bir istemci kimliği ile tanımlanabilir (DoT/DoH/DoQ için kullanılabilir). İstemcileri nasıl tanımlayacağınız hakkında daha fazla bilgiyi <0>burada</0> bulabilirsiniz.",
"form_enter_ip": "IP girin",
"form_enter_ip": "IP adresi girin",
"form_enter_subnet_ip": "\"{{cidr}}\" alt ağına bir IP adresi girin",
"form_enter_mac": "MAC adresi girin",
"form_enter_id": "Tanımlayıcı girin",
@@ -439,7 +439,7 @@
"access_allowed_desc": "CIDR'lerin, IP adreslerinin veya istemci kimliklerinin listesi. Yapılandırılırsa, AdGuard Home yalnızca bu istemcilerden gelen istekleri kabul eder.",
"access_disallowed_title": "İzin verilmeyen istemciler",
"access_disallowed_desc": "CIDR'lerin, IP adreslerinin veya istemci kimliklerinin listesi. Yapılandırılırsa, AdGuard Home bu istemcilerden gelen istekleri keser. İzin verilen istemciler yapılandırılırsa, bu alan yok sayılır.",
"access_blocked_title": "İzin verilmeyen alan adları",
"access_blocked_title": "Engellenen alan adları",
"access_blocked_desc": "Bu işlem filtrelerle ilgili değildir. AdGuard Home, bu alan adlarından gelen DNS sorgularını yanıtsız bırakır ve bu sorgular sorgu günlüğünde görünmez. Tam alan adlarını, joker karakterleri veya URL filtre kurallarını belirtebilirsiniz, ör. \"example.org\", \"*.example.org\" veya \"||example.org^\".",
"access_settings_saved": "Erişim ayarları başarıyla kaydedildi!",
"updates_checked": "Güncelleme kontrolü başarılı",
@@ -601,8 +601,8 @@
"cache_ttl_min_override": "Minimum TTL'i değiştir",
"cache_ttl_max_override": "Maksimum TTL'i değiştir",
"enter_cache_size": "Önbellek boyutunu girin (bayt)",
"enter_cache_ttl_min_override": "Minimum TTL değerini girin (saniye olarak)",
"enter_cache_ttl_max_override": "Maksimum TTL değerini girin (saniye olarak)",
"enter_cache_ttl_min_override": "Minimum TTL değerini girin (saniye)",
"enter_cache_ttl_max_override": "Maksimum TTL değerini girin (saniye)",
"cache_ttl_min_override_desc": "DNS yanıtlarını önbelleğe alırken üst sunucudan alınan kullanım süresi değerini uzatın (saniye olarak)",
"cache_ttl_max_override_desc": "DNS önbelleğindeki girişler için maksimum kullanım süresi değerini ayarlayın (saniye olarak)",
"ttl_cache_validation": "Minimum önbellek TTL değeri, maksimum değerden küçük veya bu değere eşit olmalıdır",
@@ -626,6 +626,5 @@
"experimental": "Deneysel",
"use_saved_key": "Önceden kaydedilmiş anahtarı kullan",
"parental_control": "Ebeveyn Denetimi",
"safe_browsing": "Güvenli Gezinti",
"served_from_cache": "{{value}} <i>(önbellekten kullanıldı)</i>"
"safe_browsing": "Güvenli Gezinti"
}

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "Неправильна IPv6-адреса",
"form_error_ip_format": "Неправильна IP-адреса",
"form_error_mac_format": "Неправильна MAC-адреса",
"form_error_client_id_format": "ID клієнта має містити лише цифри, малі букви та дефіси",
"form_error_client_id_format": "Неправильний ID клієнта",
"form_error_server_name": "Неправильна назва сервера",
"form_error_subnet": "Підмережа «{{cidr}}» не містить IP-адресу «{{ip}}»",
"form_error_positive": "Повинно бути більше 0",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "无效的 IPv6 地址",
"form_error_ip_format": "无效的 IP 地址",
"form_error_mac_format": "无效的 MAC 地址",
"form_error_client_id_format": "无效的客户端 ID 格式客户 ID 必须只包含数字、小写字母和连字符",
"form_error_client_id_format": "无效的客户端 ID",
"form_error_server_name": "无效的服务器名",
"form_error_subnet": "子网 \"{{cidr}}\" 不包含 IP 地址 \"{{ip}}\"",
"form_error_positive": "必须大于 0",
@@ -588,7 +588,7 @@
"show_whitelisted_responses": "已列入白名单",
"show_processed_responses": "已处理",
"blocked_safebrowsing": "被安全浏览阻止",
"blocked_adult_websites": "家长控制阻止",
"blocked_adult_websites": "已由家长控制拦截",
"blocked_threats": "拦截的威胁",
"allowed": "允许项",
"filtered": "已过滤",

View File

@@ -43,7 +43,7 @@
"form_error_ip6_format": "無效的 IPv6 位址",
"form_error_ip_format": "無效的 IP 位址",
"form_error_mac_format": "無效的媒體存取控制MAC位址",
"form_error_client_id_format": "用戶端 ID 必須只包含數值、小寫字母和連字號",
"form_error_client_id_format": "無效的用戶端 ID",
"form_error_server_name": "無效的伺服器名稱",
"form_error_subnet": "子網路 \"{{cidr}}\" 不包含該 IP 位址 \"{{ip}}\"",
"form_error_positive": "必須大於 0",
@@ -146,7 +146,7 @@
"enforce_safe_search": "使用安全搜尋",
"enforce_save_search_hint": "AdGuard Home 將在下列的搜尋引擎Google、YouTube、Bing、DuckDuckGo、Yandex 和 Pixabay 中強制執行安全搜尋。",
"no_servers_specified": "無已明確指定的伺服器",
"general_settings": "一般設定",
"general_settings": "一般設定",
"dns_settings": "DNS 設定",
"dns_blocklists": "DNS 封鎖清單",
"dns_allowlists": "DNS 允許清單",

View File

@@ -4,7 +4,7 @@ import { Trans, withTranslation } from 'react-i18next';
import ReactTable from 'react-table';
import { MODAL_TYPE } from '../../../helpers/constants';
import { splitByNewLine, countClientsStatistics, sortIp } from '../../../helpers/helpers';
import { splitByNewLine, countClientsStatistics } from '../../../helpers/helpers';
import Card from '../../ui/Card';
import Modal from './Modal';
import CellWrap from '../../ui/CellWrap';
@@ -106,7 +106,6 @@ class ClientsTable extends Component {
</div>
);
},
sortMethod: sortIp,
},
{
Header: this.props.t('table_name'),

View File

@@ -13,12 +13,6 @@ const Version = () => {
checkUpdateFlag,
} = useSelector((state) => state?.dashboard ?? {}, shallowEqual);
const {
dnsVersion: installDnsVersion,
} = useSelector((state) => state?.install ?? {}, shallowEqual);
const version = dnsVersion || installDnsVersion;
const onClick = () => {
dispatch(getVersion(true));
};
@@ -26,12 +20,11 @@ const Version = () => {
return (
<div className="version">
<div className="version__text">
{version && (
<>
<Trans>version</Trans>:&nbsp;
<span className="version__value" title={version}>{version}</span>
</>
)}
{dnsVersion
&& <>
<Trans>version</Trans>:&nbsp;
<span className="version__value" title={dnsVersion}>{dnsVersion}</span>
</>}
{checkUpdateFlag && <button
type="button"
className="btn btn-icon btn-icon-sm btn-outline-primary btn-sm ml-2"

View File

@@ -754,10 +754,8 @@ const getAddressesComparisonBytes = (item) => {
*/
export const sortIp = (a, b) => {
try {
const comparisonBytesA = Array.isArray(a)
? getAddressesComparisonBytes(a[0]) : getAddressesComparisonBytes(a);
const comparisonBytesB = Array.isArray(b)
? getAddressesComparisonBytes(b[0]) : getAddressesComparisonBytes(b);
const comparisonBytesA = getAddressesComparisonBytes(a);
const comparisonBytesB = getAddressesComparisonBytes(b);
for (let i = 0; i < comparisonBytesA.length; i += 1) {
const byteA = comparisonBytesA[i];

View File

@@ -12,19 +12,13 @@ const install = handleActions({
[actions.getDefaultAddressesRequest]: (state) => ({ ...state, processingDefault: true }),
[actions.getDefaultAddressesFailure]: (state) => ({ ...state, processingDefault: false }),
[actions.getDefaultAddressesSuccess]: (state, { payload }) => {
const { interfaces, version } = payload;
const { interfaces } = payload;
const web = { ...state.web, port: payload.web_port };
const dns = { ...state.dns, port: payload.dns_port };
const newState = {
...state,
web,
dns,
interfaces,
processingDefault: false,
dnsVersion: version,
...state, web, dns, interfaces, processingDefault: false,
};
return newState;
},
@@ -70,7 +64,6 @@ const install = handleActions({
error: '',
},
interfaces: {},
dnsVersion: '',
});
export default combineReducers({

51
go.mod
View File

@@ -1,25 +1,25 @@
module github.com/AdguardTeam/AdGuardHome
go 1.17
go 1.16
require (
github.com/AdguardTeam/dnsproxy v0.40.5
github.com/AdguardTeam/golibs v0.10.4
github.com/AdguardTeam/urlfilter v0.15.2
github.com/AdguardTeam/dnsproxy v0.40.3-0.20211229125141-da9b0c6cf76a
github.com/AdguardTeam/golibs v0.10.3
github.com/AdguardTeam/urlfilter v0.15.1
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.3
github.com/digineo/go-ipset/v2 v2.2.1
github.com/fsnotify/fsnotify v1.5.1
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534
github.com/google/go-cmp v0.5.6
github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020
github.com/google/go-cmp v0.5.5
github.com/google/gopacket v1.1.19
github.com/google/renameio v1.0.1
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489
github.com/insomniacslk/dhcp v0.0.0-20210310193751-cfd4d47082c2
github.com/kardianos/service v1.2.0
github.com/lucas-clemente/quic-go v0.24.0
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
github.com/mdlayher/netlink v1.5.0
github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b
github.com/mdlayher/netlink v1.4.0
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf
github.com/miekg/dns v1.1.45
github.com/satori/go.uuid v1.2.0
github.com/stretchr/testify v1.7.0
@@ -30,36 +30,7 @@ require (
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v2 v2.4.0
howett.net/plist v1.0.0
howett.net/plist v0.0.0-20201203080718-1454fab16a06
)
require (
github.com/BurntSushi/toml v0.4.1 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
github.com/ameshkov/dnsstamps v1.0.3 // indirect
github.com/beefsack/go-rate v0.0.0-20200827232406-6cde80facd47 // indirect
github.com/cheekybits/genny v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.0 // indirect
github.com/mdlayher/socket v0.1.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.1.1 // indirect
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.8 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
honnef.co/go/tools v0.2.2 // indirect
)
require github.com/stretchr/objx v0.1.1 // indirect

87
go.sum
View File

@@ -7,19 +7,18 @@ 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.40.5 h1:727KSGRmzq2DB5dMm093g0Guhc3dzzzMbfB0C9hK0s8=
github.com/AdguardTeam/dnsproxy v0.40.5/go.mod h1:PZ9l22h3Er+5mxFQB7oHZMTvx+aa9R6LbzA/ikXQlS0=
github.com/AdguardTeam/dnsproxy v0.40.3-0.20211229125141-da9b0c6cf76a h1:m+84VGYbDBq55L5apbHj1UqbZOcK1lqmnZVlBvzycmk=
github.com/AdguardTeam/dnsproxy v0.40.3-0.20211229125141-da9b0c6cf76a/go.mod h1:+NlQl9lcVKjbecYlCumfjMzDk2BblySEX7WOHhQBbXk=
github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.9.2/go.mod h1:fCAMwPBJ8S7YMYbTWvYS+eeTLblP5E04IDtNAo7y7IY=
github.com/AdguardTeam/golibs v0.10.3 h1:FBgk17zf35ESVWQKIqEUiqqB2bDaCBC8X5vMU760yB4=
github.com/AdguardTeam/golibs v0.10.3/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.10.4 h1:TMBkablZC0IZOpRgg9fzAKlxxNhSN2YJq7qbgtuZ7PQ=
github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.15.2 h1:LZGgrm4l4Ys9eAqB+UUmZfiC6vHlDlYFhx0WXqo6LtQ=
github.com/AdguardTeam/urlfilter v0.15.2/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
github.com/AdguardTeam/urlfilter v0.15.1 h1:dP6S7J6eFAk8MN4IDpUq2fZoBo8K8fmc6pXpxNIv84M=
github.com/AdguardTeam/urlfilter v0.15.1/go.mod h1:EwXwrYhowP7bedqmOrmKKmQtpBYFyDNEBFQ+lxdUgQU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
@@ -41,8 +40,6 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -55,7 +52,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
@@ -65,8 +61,8 @@ github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 h1:dhy9OQKGBh4zVXbjwbxxHjRxMJtLXj3zfgpBYQaR4Q4=
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020 h1:mdi6AbCEoKCA1xKCmp7UtRB5fvGFlP92PvlhxgdvXEw=
github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020/go.mod h1:KmHOjTUmJh/l04ukqPoBWPEZr9jwN05h5NXQl5C+DyY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -95,9 +91,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
@@ -106,9 +101,6 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU=
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -117,8 +109,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpg
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 h1:jhdHqd7DxBrzfuFSoPxjD6nUVaV/1RIn9aHA0WCf/as=
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
github.com/insomniacslk/dhcp v0.0.0-20210310193751-cfd4d47082c2 h1:NpTIlXznCStsY88jU+Gh1Dy5dt/jYV4z4uU8h2TUOt4=
github.com/insomniacslk/dhcp v0.0.0-20210310193751-cfd4d47082c2/go.mod h1:TKl4jN3Voofo4UJIicyNhWGp/nlQqQkFxmwIFTvBkKI=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
@@ -131,10 +123,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b h1:c3NTyLNozICy8B4mlMXemD3z/gXgQzVXZS/HqT+i3do=
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo=
github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786 h1:N527AHMa793TP5z5GNAn/VLPzlc0ewzWdeP/25gDfgQ=
github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786/go.mod h1:v4hqbTdfQngbVSZJVWUhGE/lbTFf9jb+ygmNUDQMuOs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -142,7 +132,6 @@ github.com/kardianos/service v1.2.0 h1:bGuZ/epo3vrt8IPC7mnKQolqFeYJb7Cs8Rk4PSOBB
github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
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=
@@ -161,9 +150,8 @@ github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 h1:lez6TS6aAau+8wXUP3G9I3TGlmPFEq2CTxBaRqY6AGE=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY=
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
github.com/mdlayher/ethtool v0.0.0-20211028163843-288d040e9d60 h1:tHdB+hQRHU10CfcK0furo6rSNgZ38JT8uPh70c/pFD8=
github.com/mdlayher/ethtool v0.0.0-20211028163843-288d040e9d60/go.mod h1:aYbhishWc4Ai3I2U4Gaa2n3kHWSwzme6EsG/46HRQbE=
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
@@ -176,19 +164,12 @@ github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klX
github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
github.com/mdlayher/netlink v1.4.0 h1:n3ARR+Fm0dDv37dj5wSWZXDKcy+U0zwcXS3zKMnSiT0=
github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8=
github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqAS9cNgn6Q=
github.com/mdlayher/netlink v1.5.0 h1:r4fa439+SsMarM0rMONU3iSshSV3ArVqJl6H/zjrhh4=
github.com/mdlayher/netlink v1.5.0/go.mod h1:1Kr8BBFxGyUyNmztC9WLOayqYVAd2wsgOZm18nqGuzQ=
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b h1:MHcTarUMC4sFA7eiyR8IEJ6j2PgmgXR+B9X2IIMjh7A=
github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc=
github.com/mdlayher/socket v0.0.0-20211007213009-516dcbdf0267/go.mod h1:nFZ1EtZYK8Gi/k6QNu7z7CgO20i/4ExeQswwWuPmG/g=
github.com/mdlayher/socket v0.1.0/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
github.com/mdlayher/socket v0.1.1 h1:q3uOGirUPfAV2MUoaC7BavjQ154J7+JOkTWyiV+intI=
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf h1:InctQoB89TIkmgIFQeIL4KXNvWc1iebQXdZggqPSwL8=
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
@@ -276,14 +257,12 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 h1:XMAtQHwKjWHIRwg+8Nj/rzUomQY1q6cM3ncA0wP8GU4=
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
github.com/u-root/u-root v7.0.0+incompatible h1:u+KSS04pSxJGI5E7WE4Bs9+Zd75QjFv+REkjy/aoAc8=
github.com/u-root/u-root v7.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
@@ -329,6 +308,7 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -337,18 +317,13 @@ golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210908191846-a5e095526f91/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -393,33 +368,25 @@ golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -443,10 +410,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -489,7 +454,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXL
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -504,10 +468,7 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
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=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk=
honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
howett.net/plist v0.0.0-20201203080718-1454fab16a06 h1:QDxUo/w2COstK1wIBYpzQlHX/NqaQTcf9jyz347nI58=
howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -1,7 +1,7 @@
// Package aghalg contains common generic algorithms and data structures.
// Package aghalgo contains common generic algorithms and data structures.
//
// TODO(a.garipov): Update to use type parameters in Go 1.18.
package aghalg
package aghalgo
import (
"fmt"
@@ -14,20 +14,20 @@ import (
// TODO(a.garipov): Remove in Go 1.18.
type comparable = interface{}
// UniqChecker allows validating uniqueness of comparable items.
type UniqChecker map[comparable]int64
// UniquenessValidator allows validating uniqueness of comparable items.
type UniquenessValidator map[comparable]int64
// Add adds a value to the validator. v must not be nil.
func (uc UniqChecker) Add(elems ...comparable) {
func (v UniquenessValidator) Add(elems ...comparable) {
for _, e := range elems {
uc[e]++
v[e]++
}
}
// Merge returns a checker containing data from both uc and other.
func (uc UniqChecker) Merge(other UniqChecker) (merged UniqChecker) {
merged = make(UniqChecker, len(uc)+len(other))
for elem, num := range uc {
// Merge returns a validator containing data from both v and other.
func (v UniquenessValidator) Merge(other UniquenessValidator) (merged UniquenessValidator) {
merged = make(UniquenessValidator, len(v)+len(other))
for elem, num := range v {
merged[elem] += num
}
@@ -41,9 +41,9 @@ func (uc UniqChecker) Merge(other UniqChecker) (merged UniqChecker) {
// Validate returns an error enumerating all elements that aren't unique.
// isBefore is an optional sorting function to make the error message
// deterministic.
func (uc UniqChecker) Validate(isBefore func(a, b comparable) (less bool)) (err error) {
func (v UniquenessValidator) Validate(isBefore func(a, b comparable) (less bool)) (err error) {
var dup []comparable
for elem, num := range uc {
for elem, num := range v {
if num > 1 {
dup = append(dup, elem)
}
@@ -62,13 +62,13 @@ func (uc UniqChecker) Validate(isBefore func(a, b comparable) (less bool)) (err
return fmt.Errorf("duplicated values: %v", dup)
}
// IntIsBefore is a helper sort function for UniqChecker.Validate.
// IntIsBefore is a helper sort function for UniquenessValidator.Validate.
// a and b must be of type int.
func IntIsBefore(a, b comparable) (less bool) {
return a.(int) < b.(int)
}
// StringIsBefore is a helper sort function for UniqChecker.Validate.
// StringIsBefore is a helper sort function for UniquenessValidator.Validate.
// a and b must be of type string.
func StringIsBefore(a, b comparable) (less bool) {
return a.(string) < b.(string)

View File

@@ -19,8 +19,7 @@ import (
"github.com/insomniacslk/dhcp/iana"
)
// defaultDiscoverTime is the default timeout of checking another DHCP server
// response.
// defaultDiscoverTime is the
const defaultDiscoverTime = 3 * time.Second
func checkOtherDHCP(ifaceName string) (ok4, ok6 bool, err4, err6 error) {

View File

@@ -72,11 +72,7 @@ func (rm *requestMatcher) MatchRequest(
}
// Translate returns the source hosts-syntax rule for the generated dnsrewrite
// rule or an empty string if the last doesn't exist. The returned rules are in
// a processed format like:
//
// ip host1 host2 ...
//
// rule or an empty string if the last doesn't exist.
func (rm *requestMatcher) Translate(rule string) (hostRule string) {
rm.stateLock.RLock()
defer rm.stateLock.RUnlock()
@@ -183,7 +179,7 @@ func NewHostsContainer(
return nil, fmt.Errorf("adding path: %w", err)
}
log.Debug("%s: %s is expected to exist but doesn't", hostsContainerPref, p)
log.Debug("%s: file %q expected to exist but doesn't", hostsContainerPref, p)
}
}
@@ -203,7 +199,7 @@ func (hc *HostsContainer) Close() (err error) {
}
// Upd returns the channel into which the updates are sent. The receivable
// map's values are guaranteed to be of type of *aghnet.Hosts.
// map's values are guaranteed to be of type of *stringutil.Set.
func (hc *HostsContainer) Upd() (updates <-chan *netutil.IPMap) {
return hc.updates
}
@@ -232,9 +228,8 @@ func pathsToPatterns(fsys fs.FS, paths []string) (patterns []string, err error)
return patterns, nil
}
// handleEvents concurrently handles the file system events. It closes the
// update channel of HostsContainer when finishes. It's used to be called
// within a separate goroutine.
// handleEvents concurrently handles the events. It closes the update channel
// of HostsContainer when finishes. Used to be called within a goroutine.
func (hc *HostsContainer) handleEvents() {
defer log.OnPanic(fmt.Sprintf("%s: handling events", hostsContainerPref))
@@ -259,27 +254,17 @@ func (hc *HostsContainer) handleEvents() {
}
}
// ipRules is the pair of generated A/AAAA and PTR rules with related IP.
type ipRules struct {
// rule is the A/AAAA $dnsrewrite rule.
rule string
// rulePtr is the PTR $dnsrewrite rule.
rulePtr string
// ip is the IP address related to the rules.
ip net.IP
}
// hostsParser is a helper type to parse rules from the operating system's hosts
// file. It exists for only a single refreshing session.
type hostsParser struct {
// rulesBuilder builds the resulting rules list content.
// rulesBuilder builds the resulting rulesBuilder list content.
rulesBuilder *strings.Builder
// rules stores the rules for main hosts to generate translations.
rules []ipRules
// translations maps generated $dnsrewrite rules to the hosts-translations
// rules.
translations map[string]string
// cnameSet prevents duplicating cname rules, e.g. same hostname for
// different IP versions.
// cnameSet prevents duplicating cname rules.
cnameSet *stringutil.Set
// table stores only the unique IP-hostname pairs. It's also sent to the
@@ -287,16 +272,13 @@ type hostsParser struct {
table *netutil.IPMap
}
// newHostsParser creates a new *hostsParser with buffers of size taken from the
// previous parse.
func (hc *HostsContainer) newHostsParser() (hp *hostsParser) {
lastLen := hc.last.Len()
return &hostsParser{
rulesBuilder: &strings.Builder{},
rules: make([]ipRules, 0, lastLen),
// For A/AAAA and PTRs.
translations: make(map[string]string, hc.last.Len()*2),
cnameSet: stringutil.NewSet(),
table: netutil.NewIPMap(lastLen),
table: netutil.NewIPMap(hc.last.Len()),
}
}
@@ -304,7 +286,9 @@ func (hc *HostsContainer) newHostsParser() (hp *hostsParser) {
// never signs to stop walking and never returns any additional patterns.
//
// See man hosts(5).
func (hp *hostsParser) parseFile(r io.Reader) (patterns []string, cont bool, err error) {
func (hp *hostsParser) parseFile(
r io.Reader,
) (patterns []string, cont bool, err error) {
s := bufio.NewScanner(r)
for s.Scan() {
ip, hosts := hp.parseLine(s.Text())
@@ -355,79 +339,62 @@ func (hp *hostsParser) parseLine(line string) (ip net.IP, hosts []string) {
return ip, hosts
}
// Hosts is used to contain the main host and all it's aliases.
type Hosts struct {
// Aliases contains all the aliases for Main.
Aliases *stringutil.Set
// Main is the host itself.
Main string
}
// Equal returns true if h equals hh.
func (h *Hosts) Equal(hh *Hosts) (ok bool) {
if h == nil || hh == nil {
return h == hh
}
return h.Main == hh.Main && h.Aliases.Equal(hh.Aliases)
}
// Simple types of hosts in hosts database. Zero value isn't used to be able
// quizzaciously emulate nil with 0.
const (
_ = iota
hostAlias
hostMain
)
// add tries to add the ip-host pair. It returns:
//
// main host if the host is not the first one added for the ip.
// host itself if the host is the first one added for the ip.
// "" if the ip-host pair has already been added.
// hostAlias if the host is not the first one added for the ip.
// hostMain if the host is the first one added for the ip.
// 0 if the ip-host pair has already been added.
//
func (hp *hostsParser) add(ip net.IP, host string) (mainHost string) {
func (hp *hostsParser) add(ip net.IP, host string) (hostType int) {
v, ok := hp.table.Get(ip)
switch h, _ := v.(*Hosts); {
case !ok:
// This is the first host for the ip.
hp.table.Set(ip, &Hosts{Main: host})
switch hosts, _ := v.(*stringutil.Set); {
case ok && hosts.Has(host):
return 0
case hosts == nil:
hosts = stringutil.NewSet(host)
hp.table.Set(ip, hosts)
return host
case h.Main == host:
// This is a duplicate. Go on.
case h.Aliases == nil:
// This is the first alias.
h.Aliases = stringutil.NewSet(host)
return h.Main
case !h.Aliases.Has(host):
// This is a new alias.
h.Aliases.Add(host)
return h.Main
return hostMain
default:
// This is a duplicate. Go on.
}
hosts.Add(host)
return ""
return hostAlias
}
}
// addPair puts the pair of ip and host to the rules builder if needed. For
// each ip the first member of hosts will become the main one.
func (hp *hostsParser) addPairs(ip net.IP, hosts []string) {
// Put the rule in a processed format like:
//
// ip host1 host2 ...
//
hostsLine := strings.Join(append([]string{ip.String()}, hosts...), " ")
var mainHost string
for _, host := range hosts {
switch mainHost := hp.add(ip, host); mainHost {
case "":
// This host is a duplicate.
switch hp.add(ip, host) {
case 0:
continue
case host:
// This host is main.
added, addedPtr := hp.writeMainRule(host, ip)
hp.rules = append(hp.rules, ipRules{
rule: added,
rulePtr: addedPtr,
ip: ip,
})
default:
// This host is an alias.
case hostMain:
mainHost = host
added, addedPtr := hp.writeMainHostRule(host, ip)
hp.translations[added], hp.translations[addedPtr] = hostsLine, hostsLine
case hostAlias:
pair := fmt.Sprint(host, " ", mainHost)
if hp.cnameSet.Has(pair) {
continue
}
hp.writeAliasRule(host, mainHost)
// Since the hostAlias couldn't be returned from add before the
// hostMain the mainHost shouldn't appear empty.
hp.writeAliasHostRule(host, mainHost)
hp.cnameSet.Add(pair)
}
@@ -435,9 +402,9 @@ func (hp *hostsParser) addPairs(ip net.IP, hosts []string) {
}
}
// writeAliasRule writes the CNAME rule for the alias-host pair into internal
// builders.
func (hp *hostsParser) writeAliasRule(alias, host string) {
// writeAliasHostRule writes the CNAME rule for the alias-host pair into
// internal builders.
func (hp *hostsParser) writeAliasHostRule(alias, host string) {
const (
nl = "\n"
sc = ";"
@@ -450,9 +417,9 @@ func (hp *hostsParser) writeAliasRule(alias, host string) {
stringutil.WriteToBuilder(hp.rulesBuilder, rules.MaskPipe, alias, rwSuccess, host, nl)
}
// writeMainRule writes the actual rule for the qtype and the PTR for the
// writeMainHostRule writes the actual rule for the qtype and the PTR for the
// host-ip pair into internal builders.
func (hp *hostsParser) writeMainRule(host string, ip net.IP) (added, addedPtr string) {
func (hp *hostsParser) writeMainHostRule(host string, ip net.IP) (added, addedPtr string) {
arpa, err := netutil.IPToReversedAddr(ip)
if err != nil {
return
@@ -517,15 +484,12 @@ func (hp *hostsParser) equalSet(target *netutil.IPMap) (ok bool) {
return false
}
hp.table.Range(func(ip net.IP, b interface{}) (cont bool) {
hp.table.Range(func(ip net.IP, val interface{}) (cont bool) {
v, hasIP := target.Get(ip)
// ok is set to true if the target doesn't contain ip or if the
// appropriate hosts set isn't equal to the checked one, i.e. the main
// hosts differ or the maps have at least one discrepancy.
if a, hasIP := target.Get(ip); !hasIP {
ok = true
} else if hosts, aok := a.(*Hosts); aok {
ok = !hosts.Equal(b.(*Hosts))
}
// appropriate hosts set isn't equal to the checked one, i.e. the maps
// have at least one discrepancy.
ok = !hasIP || !v.(*stringutil.Set).Equal(val.(*stringutil.Set))
// Continue only if maps has no discrepancies.
return !ok
@@ -563,35 +527,6 @@ func (hp *hostsParser) newStrg(id int) (s *filterlist.RuleStorage, err error) {
}})
}
// translations generates the map to translate $dnsrewrite rules to
// hosts-syntax ones.
func (hp *hostsParser) translations() (trans map[string]string) {
l := len(hp.rules)
if l == 0 {
return nil
}
trans = make(map[string]string, l*2)
for _, r := range hp.rules {
v, ok := hp.table.Get(r.ip)
if !ok {
continue
}
var hosts *Hosts
hosts, ok = v.(*Hosts)
if !ok {
continue
}
strs := append([]string{r.ip.String(), hosts.Main}, hosts.Aliases.Values()...)
hostsLine := strings.Join(strs, " ")
trans[r.rule], trans[r.rulePtr] = hostsLine, hostsLine
}
return trans
}
// refresh gets the data from specified files and propagates the updates if
// needed.
//
@@ -605,7 +540,7 @@ func (hc *HostsContainer) refresh() (err error) {
}
if hp.equalSet(hc.last) {
log.Debug("%s: no changes detected", hostsContainerPref)
log.Debug("%s: no updates detected", hostsContainerPref)
return nil
}
@@ -618,7 +553,7 @@ func (hc *HostsContainer) refresh() (err error) {
return fmt.Errorf("initializing rules storage: %w", err)
}
hc.resetEng(rulesStrg, hp.translations())
hc.resetEng(rulesStrg, hp.translations)
return nil
}

View File

@@ -9,7 +9,6 @@ import (
"sync/atomic"
"testing"
"testing/fstest"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/golibs/errors"
@@ -130,13 +129,24 @@ func TestNewHostsContainer(t *testing.T) {
})
}
func TestHostsContainer_refresh(t *testing.T) {
// TODO(e.burkov): Test the case with no actual updates.
func TestHostsContainer_Refresh(t *testing.T) {
knownIP := net.IP{127, 0, 0, 1}
ip := net.IP{127, 0, 0, 1}
ipStr := ip.String()
const knownHost = "localhost"
const knownAlias = "hocallost"
testFS := fstest.MapFS{"dir/file1": &fstest.MapFile{Data: []byte(ipStr + ` hostname` + nl)}}
const dirname = "dir"
const filename1 = "file1"
const filename2 = "file2"
p1 := path.Join(dirname, filename1)
p2 := path.Join(dirname, filename2)
testFS := fstest.MapFS{
p1: &fstest.MapFile{
Data: []byte(strings.Join([]string{knownIP.String(), knownHost}, sp) + nl),
},
}
// event is a convenient alias for an empty struct{} to emit test events.
type event = struct{}
@@ -147,117 +157,119 @@ func TestHostsContainer_refresh(t *testing.T) {
w := &aghtest.FSWatcher{
OnEvents: func() (e <-chan event) { return eventsCh },
OnAdd: func(name string) (err error) {
assert.Equal(t, "dir", name)
assert.Equal(t, dirname, name)
return nil
},
OnClose: func() (err error) { panic("not implemented") },
}
hc, err := NewHostsContainer(0, testFS, w, "dir")
hc, err := NewHostsContainer(0, testFS, w, dirname)
require.NoError(t, err)
checkRefresh := func(t *testing.T, wantHosts Hosts) {
checkRefresh := func(t *testing.T, wantHosts *stringutil.Set) {
upd, ok := <-hc.Upd()
require.True(t, ok)
require.NotNil(t, upd)
assert.Equal(t, 1, upd.Len())
v, ok := upd.Get(ip)
v, ok := upd.Get(knownIP)
require.True(t, ok)
var hosts *Hosts
hosts, ok = v.(*Hosts)
var hosts *stringutil.Set
hosts, ok = v.(*stringutil.Set)
require.True(t, ok)
assert.Equal(t, wantHosts.Main, hosts.Main)
assert.True(t, hosts.Aliases.Equal(wantHosts.Aliases))
assert.True(t, hosts.Equal(wantHosts))
}
t.Run("initial_refresh", func(t *testing.T) {
checkRefresh(t, Hosts{Main: "hostname"})
checkRefresh(t, stringutil.NewSet(knownHost))
})
testFS[p2] = &fstest.MapFile{
Data: []byte(strings.Join([]string{knownIP.String(), knownAlias}, sp) + nl),
}
eventsCh <- event{}
t.Run("second_refresh", func(t *testing.T) {
testFS["dir/file2"] = &fstest.MapFile{Data: []byte(ipStr + ` alias` + nl)}
eventsCh <- event{}
checkRefresh(t, Hosts{Main: "hostname", Aliases: stringutil.NewSet("alias")})
checkRefresh(t, stringutil.NewSet(knownHost, knownAlias))
})
t.Run("double_refresh", func(t *testing.T) {
// Make a change once.
testFS["dir/file1"] = &fstest.MapFile{Data: []byte(ipStr + ` alias` + nl)}
eventsCh <- event{}
eventsCh <- event{}
// Require the changes are written.
require.Eventually(t, func() bool {
res, ok := hc.MatchRequest(urlfilter.DNSRequest{
Hostname: "hostname",
DNSType: dns.TypeA,
})
return !ok && res.DNSRewrites() == nil
}, 5*time.Second, time.Second/2)
// Make a change again.
testFS["dir/file2"] = &fstest.MapFile{Data: []byte(ipStr + ` hostname` + nl)}
eventsCh <- event{}
// Require the changes are written.
require.Eventually(t, func() bool {
res, ok := hc.MatchRequest(urlfilter.DNSRequest{
Hostname: "hostname",
DNSType: dns.TypeA,
})
return !ok && res.DNSRewrites() != nil
}, 5*time.Second, time.Second/2)
assert.Len(t, hc.Upd(), 1)
t.Run("no_changes_refresh", func(t *testing.T) {
assert.Empty(t, hc.Upd())
})
}
func TestHostsContainer_PathsToPatterns(t *testing.T) {
const (
dir0 = "dir"
dir1 = "dir_1"
fn1 = "file_1"
fn2 = "file_2"
fn3 = "file_3"
fn4 = "file_4"
)
fp1 := path.Join(dir0, fn1)
fp2 := path.Join(dir0, fn2)
fp3 := path.Join(dir0, dir1, fn3)
gsfs := fstest.MapFS{
"dir_0/file_1": &fstest.MapFile{Data: []byte{1}},
"dir_0/file_2": &fstest.MapFile{Data: []byte{2}},
"dir_0/dir_1/file_3": &fstest.MapFile{Data: []byte{3}},
fp1: &fstest.MapFile{Data: []byte{1}},
fp2: &fstest.MapFile{Data: []byte{2}},
fp3: &fstest.MapFile{Data: []byte{3}},
}
testCases := []struct {
name string
paths []string
want []string
name string
wantErr error
want []string
paths []string
}{{
name: "no_paths",
paths: nil,
want: nil,
name: "no_paths",
wantErr: nil,
want: nil,
paths: nil,
}, {
name: "single_file",
paths: []string{"dir_0/file_1"},
want: []string{"dir_0/file_1"},
name: "single_file",
wantErr: nil,
want: []string{fp1},
paths: []string{fp1},
}, {
name: "several_files",
paths: []string{"dir_0/file_1", "dir_0/file_2"},
want: []string{"dir_0/file_1", "dir_0/file_2"},
name: "several_files",
wantErr: nil,
want: []string{fp1, fp2},
paths: []string{fp1, fp2},
}, {
name: "whole_dir",
paths: []string{"dir_0"},
want: []string{"dir_0/*"},
name: "whole_dir",
wantErr: nil,
want: []string{path.Join(dir0, "*")},
paths: []string{dir0},
}, {
name: "file_and_dir",
paths: []string{"dir_0/file_1", "dir_0/dir_1"},
want: []string{"dir_0/file_1", "dir_0/dir_1/*"},
name: "file_and_dir",
wantErr: nil,
want: []string{fp1, path.Join(dir0, dir1, "*")},
paths: []string{fp1, path.Join(dir0, dir1)},
}, {
name: "non-existing",
paths: []string{path.Join("dir_0", "file_3")},
want: nil,
name: "non-existing",
wantErr: nil,
want: nil,
paths: []string{path.Join(dir0, "file_3")},
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
patterns, err := pathsToPatterns(gsfs, tc.paths)
if tc.wantErr != nil {
assert.ErrorIs(t, err, tc.wantErr)
return
}
require.NoError(t, err)
assert.Equal(t, tc.want, patterns)
@@ -278,158 +290,111 @@ func TestHostsContainer_PathsToPatterns(t *testing.T) {
})
}
func TestHostsContainer_Translate(t *testing.T) {
testdata := os.DirFS("./testdata")
stubWatcher := aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
OnClose: func() (err error) { panic("not implemented") },
}
hc, err := NewHostsContainer(0, testdata, &stubWatcher, "etc_hosts")
require.NoError(t, err)
testCases := []struct {
name string
rule string
wantTrans []string
}{{
name: "simplehost",
rule: "|simplehost^$dnsrewrite=NOERROR;A;1.0.0.1",
wantTrans: []string{"1.0.0.1", "simplehost"},
}, {
name: "hello",
rule: "|hello^$dnsrewrite=NOERROR;A;1.0.0.0",
wantTrans: []string{"1.0.0.0", "hello", "hello.world", "hello.world.again"},
}, {
name: "simplehost_v6",
rule: "|simplehost^$dnsrewrite=NOERROR;AAAA;::1",
wantTrans: []string{"::1", "simplehost"},
}, {
name: "hello_v6",
rule: "|hello^$dnsrewrite=NOERROR;AAAA;::",
wantTrans: []string{"::", "hello", "hello.world", "hello.world.again"},
}, {
name: "simplehost_ptr",
rule: "|1.0.0.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;simplehost.",
wantTrans: []string{"1.0.0.1", "simplehost"},
}, {
name: "hello_ptr",
rule: "|0.0.0.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;hello.",
wantTrans: []string{"1.0.0.0", "hello", "hello.world", "hello.world.again"},
}, {
name: "simplehost_ptr_v6",
rule: "|1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" +
"^$dnsrewrite=NOERROR;PTR;simplehost.",
wantTrans: []string{"::1", "simplehost"},
}, {
name: "hello_ptr_v6",
rule: "|0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" +
"^$dnsrewrite=NOERROR;PTR;hello.",
wantTrans: []string{"::", "hello", "hello.world", "hello.world.again"},
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
want := stringutil.NewSet(tc.wantTrans...)
got := stringutil.NewSet(strings.Fields(hc.Translate(tc.rule))...)
assert.True(t, want.Equal(got))
})
}
}
func TestHostsContainer(t *testing.T) {
const listID = 1234
testdata := os.DirFS("./testdata")
nRewrites := func(t *testing.T, res *urlfilter.DNSResult, n int) (rws []*rules.DNSRewrite) {
t.Helper()
rewrites := res.DNSRewrites()
assert.Len(t, rewrites, n)
for _, rewrite := range rewrites {
require.Equal(t, listID, rewrite.FilterListID)
rw := rewrite.DNSRewrite
require.NotNil(t, rw)
rws = append(rws, rw)
}
return rws
}
testCases := []struct {
want []*rules.DNSRewrite
name string
req urlfilter.DNSRequest
testTail func(t *testing.T, res *urlfilter.DNSResult)
name string
req urlfilter.DNSRequest
}{{
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
Value: net.IPv4(1, 0, 0, 1),
RRType: dns.TypeA,
}, {
RCode: dns.RcodeSuccess,
Value: net.IP(append((&[15]byte{})[:], byte(1))),
RRType: dns.TypeAAAA,
}},
name: "simple",
req: urlfilter.DNSRequest{
Hostname: "simplehost",
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
rws := nRewrites(t, res, 2)
v, ok := rws[0].Value.(net.IP)
require.True(t, ok)
assert.True(t, net.IP{1, 0, 0, 1}.Equal(v))
v, ok = rws[1].Value.(net.IP)
require.True(t, ok)
// It's ::1.
assert.True(t, net.IP(append((&[15]byte{})[:], byte(1))).Equal(v))
},
}, {
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
NewCNAME: "hello",
}},
name: "hello_alias",
req: urlfilter.DNSRequest{
Hostname: "hello.world",
DNSType: dns.TypeA,
},
}, {
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
NewCNAME: "hello",
}},
name: "other_line_alias",
req: urlfilter.DNSRequest{
Hostname: "hello.world.again",
DNSType: dns.TypeA,
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Equal(t, "hello", nRewrites(t, res, 1)[0].NewCNAME)
},
}, {
want: []*rules.DNSRewrite{},
name: "hello_subdomain",
req: urlfilter.DNSRequest{
Hostname: "say.hello",
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Empty(t, res.DNSRewrites())
},
}, {
want: []*rules.DNSRewrite{},
name: "hello_alias_subdomain",
req: urlfilter.DNSRequest{
Hostname: "say.hello.world",
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Empty(t, res.DNSRewrites())
},
}, {
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
NewCNAME: "a.whole",
}},
name: "lots_of_aliases",
req: urlfilter.DNSRequest{
Hostname: "for.testing",
DNSType: dns.TypeA,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
assert.Equal(t, "a.whole", nRewrites(t, res, 1)[0].NewCNAME)
},
}, {
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypePTR,
Value: "simplehost.",
}},
name: "reverse",
req: urlfilter.DNSRequest{
Hostname: "1.0.0.1.in-addr.arpa",
DNSType: dns.TypePTR,
},
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
rws := nRewrites(t, res, 1)
assert.Equal(t, dns.TypePTR, rws[0].RRType)
assert.Equal(t, "simplehost.", rws[0].Value)
},
}, {
want: []*rules.DNSRewrite{},
name: "non-existing",
req: urlfilter.DNSRequest{
Hostname: "nonexisting",
DNSType: dns.TypeA,
},
}, {
want: nil,
name: "bad_type",
req: urlfilter.DNSRequest{
Hostname: "1.0.0.1.in-addr.arpa",
DNSType: dns.TypeSRV,
testTail: func(t *testing.T, res *urlfilter.DNSResult) {
require.NotNil(t, res)
assert.Nil(t, res.DNSRewrites())
},
}}
@@ -446,33 +411,20 @@ func TestHostsContainer(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
res, ok := hc.MatchRequest(tc.req)
require.False(t, ok)
if tc.want == nil {
assert.Nil(t, res)
return
}
require.NotNil(t, res)
rewrites := res.DNSRewrites()
require.Len(t, rewrites, len(tc.want))
for i, rewrite := range rewrites {
require.Equal(t, listID, rewrite.FilterListID)
rw := rewrite.DNSRewrite
require.NotNil(t, rw)
assert.Equal(t, tc.want[i], rw)
}
tc.testTail(t, res)
})
}
}
func TestUniqueRules_ParseLine(t *testing.T) {
ip := net.IP{127, 0, 0, 1}
ipStr := ip.String()
const (
hostname = "localhost"
alias = "hocallost"
)
knownIP := net.IP{127, 0, 0, 1}
testCases := []struct {
name string
@@ -481,39 +433,39 @@ func TestUniqueRules_ParseLine(t *testing.T) {
wantHosts []string
}{{
name: "simple",
line: ipStr + ` hostname`,
wantIP: ip,
wantHosts: []string{"hostname"},
line: strings.Join([]string{knownIP.String(), hostname}, sp),
wantIP: knownIP,
wantHosts: []string{"localhost"},
}, {
name: "aliases",
line: ipStr + ` hostname alias`,
wantIP: ip,
wantHosts: []string{"hostname", "alias"},
line: strings.Join([]string{knownIP.String(), hostname, alias}, sp),
wantIP: knownIP,
wantHosts: []string{"localhost", "hocallost"},
}, {
name: "invalid_line",
line: ipStr,
line: knownIP.String(),
wantIP: nil,
wantHosts: nil,
}, {
name: "invalid_line_hostname",
line: ipStr + ` # hostname`,
wantIP: ip,
line: strings.Join([]string{knownIP.String(), "#" + hostname}, sp),
wantIP: knownIP,
wantHosts: nil,
}, {
name: "commented_aliases",
line: ipStr + ` hostname # alias`,
wantIP: ip,
wantHosts: []string{"hostname"},
line: strings.Join([]string{knownIP.String(), hostname, "#" + alias}, sp),
wantIP: knownIP,
wantHosts: []string{"localhost"},
}, {
name: "whole_comment",
line: `# ` + ipStr + ` hostname`,
line: strings.Join([]string{"#", knownIP.String(), hostname}, sp),
wantIP: nil,
wantHosts: nil,
}, {
name: "partial_comment",
line: ipStr + ` host#name`,
wantIP: ip,
wantHosts: []string{"host"},
line: strings.Join([]string{knownIP.String(), hostname[:4] + "#" + hostname[4:]}, sp),
wantIP: knownIP,
wantHosts: []string{hostname[:4]},
}, {
name: "empty",
line: ``,
@@ -524,8 +476,8 @@ func TestUniqueRules_ParseLine(t *testing.T) {
for _, tc := range testCases {
hp := hostsParser{}
t.Run(tc.name, func(t *testing.T) {
got, hosts := hp.parseLine(tc.line)
assert.True(t, tc.wantIP.Equal(got))
ip, hosts := hp.parseLine(tc.line)
assert.True(t, tc.wantIP.Equal(ip))
assert.Equal(t, tc.wantHosts, hosts)
})
}

View File

@@ -25,13 +25,6 @@ type NetIface interface {
// IfaceIPAddrs returns the interface's IP addresses.
func IfaceIPAddrs(iface NetIface, ipv IPVersion) (ips []net.IP, err error) {
switch ipv {
case IPVersion4, IPVersion6:
// Go on.
default:
return nil, fmt.Errorf("invalid ip version %d", ipv)
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
@@ -48,16 +41,20 @@ func IfaceIPAddrs(iface NetIface, ipv IPVersion) (ips []net.IP, err error) {
continue
}
// Assume that net.(*Interface).Addrs can only return valid IPv4 and
// IPv6 addresses. Thus, if it isn't an IPv4 address, it must be an
// IPv6 one.
ip4 := ip.To4()
if ipv == IPVersion4 {
if ip4 != nil {
// Assume that net.(*Interface).Addrs can only return valid IPv4
// and IPv6 addresses. Thus, if it isn't an IPv4 address, it
// must be an IPv6 one.
switch ipv {
case IPVersion4:
if ip4 := ip.To4(); ip4 != nil {
ips = append(ips, ip4)
}
} else if ip4 == nil {
ips = append(ips, ip)
case IPVersion6:
if ip6 := ip.To4(); ip6 == nil {
ips = append(ips, ip)
}
default:
return nil, fmt.Errorf("invalid ip version %d", ipv)
}
}
@@ -99,16 +96,16 @@ func IfaceDNSIPAddrs(
switch len(addrs) {
case 0:
// Don't return errors in case the users want to try and enable the DHCP
// server later.
// Don't return errors in case the users want to try and enable
// the DHCP server later.
t := time.Duration(n) * backoff
log.Error("dhcpv%d: no ip for iface after %d attempts and %s", ipv, n, t)
return nil, nil
case 1:
// Some Android devices use 8.8.8.8 if there is not a secondary DNS
// server. Fix that by setting the secondary DNS address to the same
// address.
// Some Android devices use 8.8.8.8 if there is not a secondary
// DNS server. Fix that by setting the secondary DNS address to
// the same address.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/1708.
log.Debug("dhcpv%d: setting secondary dns ip to itself", ipv)

View File

@@ -5,15 +5,13 @@ import (
"testing"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// fakeIface is a stub implementation of aghnet.NetIface to simplify testing.
type fakeIface struct {
err error
addrs []net.Addr
err error
}
// Addrs implements the NetIface interface for *fakeIface.
@@ -35,86 +33,61 @@ func TestIfaceIPAddrs(t *testing.T) {
addr6 := &net.IPNet{IP: ip6}
testCases := []struct {
iface NetIface
name string
wantErrMsg string
want []net.IP
ipv IPVersion
name string
iface NetIface
ipv IPVersion
want []net.IP
wantErr error
}{{
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
name: "ipv4_success",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
name: "ipv4_success",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
ipv: IPVersion4,
want: []net.IP{ip4},
wantErr: nil,
}, {
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
name: "ipv4_success_with_ipv6",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
name: "ipv4_success_with_ipv6",
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
ipv: IPVersion4,
want: []net.IP{ip4},
wantErr: nil,
}, {
iface: &fakeIface{addrs: []net.Addr{addr4}, err: errTest},
name: "ipv4_error",
wantErrMsg: errTest.Error(),
want: nil,
ipv: IPVersion4,
name: "ipv4_error",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: errTest},
ipv: IPVersion4,
want: nil,
wantErr: errTest,
}, {
iface: &fakeIface{addrs: []net.Addr{addr6}, err: nil},
name: "ipv6_success",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
name: "ipv6_success",
iface: &fakeIface{addrs: []net.Addr{addr6}, err: nil},
ipv: IPVersion6,
want: []net.IP{ip6},
wantErr: nil,
}, {
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
name: "ipv6_success_with_ipv4",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
name: "ipv6_success_with_ipv4",
iface: &fakeIface{addrs: []net.Addr{addr6, addr4}, err: nil},
ipv: IPVersion6,
want: []net.IP{ip6},
wantErr: nil,
}, {
iface: &fakeIface{addrs: []net.Addr{addr6}, err: errTest},
name: "ipv6_error",
wantErrMsg: errTest.Error(),
want: nil,
ipv: IPVersion6,
}, {
iface: &fakeIface{addrs: nil, err: nil},
name: "bad_proto",
wantErrMsg: "invalid ip version 10",
want: nil,
ipv: IPVersion6 + IPVersion4,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.IPAddr{IP: ip4}}, err: nil},
name: "ipaddr_v4",
wantErrMsg: "",
want: []net.IP{ip4},
ipv: IPVersion4,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.IPAddr{IP: ip6, Zone: ""}}, err: nil},
name: "ipaddr_v6",
wantErrMsg: "",
want: []net.IP{ip6},
ipv: IPVersion6,
}, {
iface: &fakeIface{addrs: []net.Addr{&net.UnixAddr{}}, err: nil},
name: "non-ipv4",
wantErrMsg: "",
want: nil,
ipv: IPVersion4,
name: "ipv6_error",
iface: &fakeIface{addrs: []net.Addr{addr6}, err: errTest},
ipv: IPVersion6,
want: nil,
wantErr: errTest,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := IfaceIPAddrs(tc.iface, tc.ipv)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
got, gotErr := IfaceIPAddrs(tc.iface, tc.ipv)
require.True(t, errors.Is(gotErr, tc.wantErr))
assert.Equal(t, tc.want, got)
})
}
}
type waitingFakeIface struct {
err error
addrs []net.Addr
err error
n int
}
@@ -143,11 +116,11 @@ func TestIfaceDNSIPAddrs(t *testing.T) {
addr6 := &net.IPNet{IP: ip6}
testCases := []struct {
iface NetIface
wantErr error
name string
want []net.IP
iface NetIface
ipv IPVersion
want []net.IP
wantErr error
}{{
name: "ipv4_success",
iface: &fakeIface{addrs: []net.Addr{addr4}, err: nil},
@@ -196,25 +169,12 @@ func TestIfaceDNSIPAddrs(t *testing.T) {
ipv: IPVersion6,
want: []net.IP{ip6, ip6},
wantErr: nil,
}, {
name: "empty",
iface: &fakeIface{addrs: nil, err: nil},
ipv: IPVersion4,
want: nil,
wantErr: nil,
}, {
name: "many",
iface: &fakeIface{addrs: []net.Addr{addr4, addr4}},
ipv: IPVersion4,
want: []net.IP{ip4, ip4},
wantErr: nil,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got, err := IfaceDNSIPAddrs(tc.iface, tc.ipv, 2, 0)
require.ErrorIs(t, err, tc.wantErr)
got, gotErr := IfaceDNSIPAddrs(tc.iface, tc.ipv, 2, 0)
require.True(t, errors.Is(gotErr, tc.wantErr))
assert.Equal(t, tc.want, got)
})
}

View File

@@ -1,44 +0,0 @@
package aghnet
import (
"net"
"testing"
"github.com/AdguardTeam/golibs/netutil"
"github.com/stretchr/testify/assert"
)
func TestIPMut(t *testing.T) {
testIPs := []net.IP{{
127, 0, 0, 1,
}, {
192, 168, 0, 1,
}, {
8, 8, 8, 8,
}}
t.Run("nil_no_mut", func(t *testing.T) {
ipmut := NewIPMut(nil)
ips := netutil.CloneIPs(testIPs)
for i := range ips {
ipmut.Load()(ips[i])
assert.True(t, ips[i].Equal(testIPs[i]))
}
})
t.Run("not_nil_mut", func(t *testing.T) {
ipmut := NewIPMut(func(ip net.IP) {
for i := range ip {
ip[i] = 0
}
})
want := netutil.IPv4Zero()
ips := netutil.CloneIPs(testIPs)
for i := range ips {
ipmut.Load()(ips[i])
assert.True(t, ips[i].Equal(want))
}
})
}

View File

@@ -42,7 +42,8 @@ func GatewayIP(ifaceName string) net.IP {
fields := strings.Fields(string(d))
// The meaningful "ip route" command output should contain the word
// "default" at first field and default gateway IP address at third field.
// "default" at first field and default gateway IP address at third
// field.
if len(fields) < 3 || fields[0] != "default" {
return nil
}
@@ -217,6 +218,28 @@ func IsAddrInUse(err error) (ok bool) {
return isAddrInUse(sysErr)
}
// SplitHost is a wrapper for net.SplitHostPort for the cases when the hostport
// does not necessarily contain a port.
func SplitHost(hostport string) (host string, err error) {
host, _, err = net.SplitHostPort(hostport)
if err != nil {
// Check for the missing port error. If it is that error, just
// use the host as is.
//
// See the source code for net.SplitHostPort.
const missingPort = "missing port in address"
addrErr := &net.AddrError{}
if !errors.As(err, &addrErr) || addrErr.Err != missingPort {
return "", err
}
host = hostport
}
return host, nil
}
// CollectAllIfacesAddrs returns the slice of all network interfaces IP
// addresses without port number.
func CollectAllIfacesAddrs() (addrs []string, err error) {

View File

@@ -15,20 +15,12 @@ func TestMain(m *testing.M) {
aghtest.DiscardLogOutput(m)
}
func TestGetInterfaceByIP(t *testing.T) {
func TestGetValidNetInterfacesForWeb(t *testing.T) {
ifaces, err := GetValidNetInterfacesForWeb()
require.NoError(t, err)
require.NotEmpty(t, ifaces)
require.NoErrorf(t, err, "cannot get net interfaces: %s", err)
require.NotEmpty(t, ifaces, "no net interfaces found")
for _, iface := range ifaces {
t.Run(iface.Name, func(t *testing.T) {
require.NotEmpty(t, iface.Addresses)
for _, ip := range iface.Addresses {
ifaceName := GetInterfaceByIP(ip)
require.Equal(t, iface.Name, ifaceName)
}
})
require.NotEmptyf(t, iface.Addresses, "no addresses found for %s", iface.Name)
}
}
@@ -81,47 +73,18 @@ func TestBroadcastFromIPNet(t *testing.T) {
}
func TestCheckPort(t *testing.T) {
t.Run("tcp_bound", func(t *testing.T) {
l, err := net.Listen("tcp", "127.0.0.1:")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
l, err := net.Listen("tcp", "127.0.0.1:")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
ipp := netutil.IPPortFromAddr(l.Addr())
require.NotNil(t, ipp)
require.NotNil(t, ipp.IP)
require.NotZero(t, ipp.Port)
ipp := netutil.IPPortFromAddr(l.Addr())
require.NotNil(t, ipp)
require.NotNil(t, ipp.IP)
require.NotZero(t, ipp.Port)
err = CheckPort("tcp", ipp.IP, ipp.Port)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
err = CheckPort("tcp", ipp.IP, ipp.Port)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("udp_bound", func(t *testing.T) {
conn, err := net.ListenPacket("udp", "127.0.0.1:")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, conn.Close)
ipp := netutil.IPPortFromAddr(conn.LocalAddr())
require.NotNil(t, ipp)
require.NotNil(t, ipp.IP)
require.NotZero(t, ipp.Port)
err = CheckPort("udp", ipp.IP, ipp.Port)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("bad_network", func(t *testing.T) {
err := CheckPort("bad_network", nil, 0)
assert.NoError(t, err)
})
t.Run("can_bind", func(t *testing.T) {
err := CheckPort("udp", net.IP{0, 0, 0, 0}, 0)
assert.NoError(t, err)
})
assert.Equal(t, "listen", target.Op)
}

View File

@@ -12,19 +12,9 @@
1.0.0.3 *
1.0.0.4 *.com
# See https://github.com/AdguardTeam/AdGuardHome/issues/4079.
1.0.0.0 hello.world.again
# Duplicates of a main host and an alias.
1.0.0.1 simplehost
1.0.0.0 hello.world
# Same for IPv6.
::1 simplehost
:: hello hello.world
::2 a.whole lot.of aliases for.testing
::3 *
::4 *.com
:: hello.world.again
::1 simplehost
:: hello.world

View File

@@ -130,19 +130,21 @@ func parseDHCPOption(s string) (opt dhcpv4.Option, err error) {
// prepareOptions builds the set of DHCP options according to host requirements
// document and values from conf.
func prepareOptions(conf V4ServerConf) (opts dhcpv4.Options) {
// Set default values for host configuration parameters listed in Appendix
// A of RFC-2131. Those parameters, if requested by client, should be
// returned with values defined by Host Requirements Document.
//
// See https://datatracker.ietf.org/doc/html/rfc2131#appendix-A.
//
// See also https://datatracker.ietf.org/doc/html/rfc1122,
// https://datatracker.ietf.org/doc/html/rfc1123, and
// https://datatracker.ietf.org/doc/html/rfc2132.
opts = dhcpv4.Options{
// IP-Layer Per Host
dhcpv4.OptionNonLocalSourceRouting.Code(): []byte{0},
// Set default values for host configuration parameters listed
// in Appendix A of RFC-2131. Those parameters, if requested by
// client, should be returned with values defined by Host
// Requirements Document.
//
// See https://datatracker.ietf.org/doc/html/rfc2131#appendix-A.
//
// See also https://datatracker.ietf.org/doc/html/rfc1122,
// https://datatracker.ietf.org/doc/html/rfc1123, and
// https://datatracker.ietf.org/doc/html/rfc2132.
// IP-Layer Per Host
dhcpv4.OptionNonLocalSourceRouting.Code(): []byte{0},
// Set the current recommended default time to live for the
// Internet Protocol which is 64, see
// https://datatracker.ietf.org/doc/html/rfc1700.

View File

@@ -27,6 +27,7 @@ type DHCPServer interface {
Start() (err error)
// Stop - stop server
Stop() (err error)
getLeasesRef() []*Lease
}

View File

@@ -7,7 +7,7 @@ import (
"net/http"
"strings"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
@@ -214,7 +214,7 @@ func validateAccessSet(list *accessListJSON) (err error) {
}
merged := allowed.Merge(disallowed)
err = merged.Validate(aghalg.StringIsBefore)
err = merged.Validate(aghalgo.StringIsBefore)
if err != nil {
return fmt.Errorf("items in allowed and disallowed clients intersect: %w", err)
}
@@ -223,13 +223,13 @@ func validateAccessSet(list *accessListJSON) (err error) {
}
// validateStrUniq returns an informative error if clients are not unique.
func validateStrUniq(clients []string) (uc aghalg.UniqChecker, err error) {
uc = make(aghalg.UniqChecker, len(clients))
func validateStrUniq(clients []string) (uv aghalgo.UniquenessValidator, err error) {
uv = make(aghalgo.UniquenessValidator, len(clients))
for _, c := range clients {
uc.Add(c)
uv.Add(c)
}
return uc, uc.Validate(aghalg.StringIsBefore)
return uv, uv.Validate(aghalgo.StringIsBefore)
}
func (s *Server) handleAccessSet(w http.ResponseWriter, r *http.Request) {

View File

@@ -352,22 +352,9 @@ func (s *Server) processRestrictLocal(ctx *dnsContext) (rc resultCode) {
ip, err := netutil.IPFromReversedAddr(q.Name)
if err != nil {
log.Debug("dns: parsing reversed addr: %s", err)
log.Debug("dns: reversed addr: %s", err)
// DNS-Based Service Discovery uses PTR records having not an ARPA
// format of the domain name in question. Those shouldn't be
// invalidated. See http://www.dns-sd.org/ServerStaticSetup.html and
// RFC 2782.
name := strings.TrimSuffix(q.Name, ".")
if err = netutil.ValidateSRVDomainName(name); err != nil {
log.Debug("dns: validating service domain: %s", err)
return resultCodeError
}
log.Debug("dns: request is for a service domain")
return resultCodeSuccess
return resultCodeError
}
// Restrict an access to local addresses for external clients. We also

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"net"
"net/http"
"strconv"
"strings"
"time"
@@ -191,23 +192,22 @@ func (req *dnsConfig) checkCacheTTL() bool {
func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
req := dnsConfig{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&req); err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "json Encode: %s", err)
return
}
if req.Upstreams != nil {
if err = ValidateUpstreams(*req.Upstreams); err != nil {
if err := ValidateUpstreams(*req.Upstreams); err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "wrong upstreams specification: %s", err)
return
}
}
var errBoot string
if errBoot, err = req.checkBootstrap(); err != nil {
if errBoot, err := req.checkBootstrap(); err != nil {
aghhttp.Error(
r,
w,
@@ -220,16 +220,19 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
return
}
switch {
case !req.checkBlockingMode():
if !req.checkBlockingMode() {
aghhttp.Error(r, w, http.StatusBadRequest, "blocking_mode: incorrect value")
return
case !req.checkUpstreamsMode():
}
if !req.checkUpstreamsMode() {
aghhttp.Error(r, w, http.StatusBadRequest, "upstream_mode: incorrect value")
return
case !req.checkCacheTTL():
}
if !req.checkCacheTTL() {
aghhttp.Error(
r,
w,
@@ -238,15 +241,13 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
)
return
default:
// Go on.
}
restart := s.setConfig(req)
s.conf.ConfigModified()
if restart {
if err = s.Reconfigure(nil); err != nil {
if err := s.Reconfigure(nil); err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)
}
}
@@ -386,14 +387,14 @@ func ValidateUpstreams(upstreams []string) (err error) {
var defaultUpstreamFound bool
for _, u := range upstreams {
var useDefault bool
useDefault, err = validateUpstream(u)
var ok bool
ok, err = validateUpstream(u)
if err != nil {
return err
}
if !defaultUpstreamFound {
defaultUpstreamFound = useDefault
defaultUpstreamFound = ok
}
}
@@ -406,62 +407,50 @@ func ValidateUpstreams(upstreams []string) (err error) {
var protocols = []string{"tls://", "https://", "tcp://", "sdns://", "quic://"}
func validateUpstream(u string) (useDefault bool, err error) {
func validateUpstream(u string) (bool, error) {
// Check if the user tries to specify upstream for domain.
var isDomainSpec bool
u, isDomainSpec, err = separateUpstream(u)
u, useDefault, err := separateUpstream(u)
if err != nil {
return !isDomainSpec, err
return useDefault, err
}
// The special server address '#' means that default server must be used.
if useDefault = !isDomainSpec; u == "#" && isDomainSpec {
// The special server address '#' means "use the default servers"
if u == "#" && !useDefault {
return useDefault, nil
}
// Check if the upstream has a valid protocol prefix.
//
// TODO(e.burkov): Validate the domain name.
// Check if the upstream has a valid protocol prefix
for _, proto := range protocols {
if strings.HasPrefix(u, proto) {
return useDefault, nil
}
}
// Return error if the upstream contains '://' without any valid protocol
if strings.Contains(u, "://") {
return useDefault, errors.Error("wrong protocol")
return useDefault, fmt.Errorf("wrong protocol")
}
// Check if upstream is either an IP or IP with port.
if net.ParseIP(u) != nil {
return useDefault, nil
} else if _, err = netutil.ParseIPPort(u); err != nil {
return useDefault, err
}
return useDefault, nil
// Check if upstream is valid plain DNS
return useDefault, checkPlainDNS(u)
}
// separateUpstream returns the upstream without the specified domains.
// isDomainSpec is true when the upstream is domains-specific.
func separateUpstream(upstreamStr string) (upstream string, isDomainSpec bool, err error) {
// useDefault is true when a default upstream must be used.
func separateUpstream(upstreamStr string) (upstream string, useDefault bool, err error) {
defer func() { err = errors.Annotate(err, "bad upstream for domain spec %q: %w", upstreamStr) }()
if !strings.HasPrefix(upstreamStr, "[/") {
return upstreamStr, false, nil
return upstreamStr, true, nil
}
defer func() { err = errors.Annotate(err, "bad upstream for domain %q: %w", upstreamStr) }()
parts := strings.Split(upstreamStr[2:], "/]")
switch len(parts) {
case 2:
// Go on.
case 1:
return "", false, errors.Error("missing separator")
default:
return "", true, errors.Error("duplicated separator")
if len(parts) != 2 {
return "", false, errors.Error("duplicated separator")
}
var domains string
domains, upstream = parts[0], parts[1]
domains := parts[0]
upstream = parts[1]
for i, host := range strings.Split(domains, "/") {
if host == "" {
continue
@@ -469,11 +458,36 @@ func separateUpstream(upstreamStr string) (upstream string, isDomainSpec bool, e
err = netutil.ValidateDomainName(host)
if err != nil {
return "", true, fmt.Errorf("domain at index %d: %w", i, err)
return "", false, fmt.Errorf("domain at index %d: %w", i, err)
}
}
return upstream, true, nil
return upstream, false, nil
}
// checkPlainDNS checks if host is plain DNS
func checkPlainDNS(upstream string) error {
// Check if host is ip without port
if net.ParseIP(upstream) != nil {
return nil
}
// Check if host is ip with port
ip, port, err := net.SplitHostPort(upstream)
if err != nil {
return err
}
if net.ParseIP(ip) == nil {
return fmt.Errorf("%s is not a valid IP", ip)
}
_, err = strconv.ParseInt(port, 0, 64)
if err != nil {
return fmt.Errorf("%s is not a valid port: %w", port, err)
}
return nil
}
// excFunc is a signature of function to check if upstream exchanges correctly.
@@ -501,8 +515,12 @@ func checkDNSUpstreamExc(u upstream.Upstream) (err error) {
if len(reply.Answer) != 1 {
return fmt.Errorf("wrong response")
} else if a, ok := reply.Answer[0].(*dns.A); !ok || !a.A.Equal(net.IP{8, 8, 8, 8}) {
return fmt.Errorf("wrong response")
}
if t, ok := reply.Answer[0].(*dns.A); ok {
if !net.IPv4(8, 8, 8, 8).Equal(t.A) {
return fmt.Errorf("wrong response")
}
}
return nil
@@ -537,7 +555,7 @@ func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFun
// Separate upstream from domains list.
var useDefault bool
if useDefault, err = validateUpstream(input); err != nil {
if input, useDefault, err = separateUpstream(input); err != nil {
return fmt.Errorf("wrong upstream format: %w", err)
}
@@ -546,7 +564,7 @@ func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFun
return nil
}
if input, _, err = separateUpstream(input); err != nil {
if _, err = validateUpstream(input); err != nil {
return fmt.Errorf("wrong upstream format: %w", err)
}
@@ -554,8 +572,7 @@ func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFun
bootstrap = defaultBootstrap
}
log.Debug("checking if upstream %s works", input)
log.Debug("checking if dns server %q works...", input)
var u upstream.Upstream
u, err = upstream.AddressToUpstream(input, &upstream.Options{
Bootstrap: bootstrap,
@@ -569,7 +586,7 @@ func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFun
return fmt.Errorf("upstream %q fails to exchange: %w", input, err)
}
log.Debug("upstream %s is ok", input)
log.Debug("dns %s works OK", input)
return nil
}
@@ -603,9 +620,9 @@ func (s *Server) handleTestUpstreamDNS(w http.ResponseWriter, r *http.Request) {
err = checkDNS(host, bootstraps, timeout, checkPrivateUpstreamExc)
if err != nil {
log.Info("%v", err)
// TODO(e.burkov): If passed upstream have already written an error
// above, we rewriting the error for it. These cases should be
// handled properly instead.
// TODO(e.burkov): If passed upstream have already
// written an error above, we rewriting the error for
// it. These cases should be handled properly instead.
result[host] = err.Error()
continue

View File

@@ -184,7 +184,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
wantSet: "",
}, {
name: "upstream_dns_bad",
wantSet: `wrong upstreams specification: bad ipport address "!!!": address !!!: ` +
wantSet: `wrong upstreams specification: address !!!: ` +
`missing port in address`,
}, {
name: "bootstraps_bad",
@@ -235,117 +235,107 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
}
func TestIsCommentOrEmpty(t *testing.T) {
for _, tc := range []struct {
want assert.BoolAssertionFunc
str string
}{{
want: assert.True,
str: "",
}, {
want: assert.True,
str: "# comment",
}, {
want: assert.False,
str: "1.2.3.4",
}} {
tc.want(t, IsCommentOrEmpty(tc.str))
}
assert.True(t, IsCommentOrEmpty(""))
assert.True(t, IsCommentOrEmpty("# comment"))
assert.False(t, IsCommentOrEmpty("1.2.3.4"))
}
// TODO(a.garipov): Rewrite to check the actual error messages.
func TestValidateUpstream(t *testing.T) {
testCases := []struct {
wantDef assert.BoolAssertionFunc
name string
upstream string
wantErr string
valid bool
wantDef bool
}{{
wantDef: assert.True,
name: "invalid",
upstream: "1.2.3.4.5",
wantErr: `bad ipport address "1.2.3.4.5": address 1.2.3.4.5: missing port in address`,
valid: false,
wantDef: false,
}, {
wantDef: assert.True,
name: "invalid",
upstream: "123.3.7m",
wantErr: `bad ipport address "123.3.7m": address 123.3.7m: missing port in address`,
valid: false,
wantDef: false,
}, {
wantDef: assert.True,
name: "invalid",
upstream: "htttps://google.com/dns-query",
wantErr: `wrong protocol`,
valid: false,
wantDef: false,
}, {
wantDef: assert.True,
name: "invalid",
upstream: "[/host.com]tls://dns.adguard.com",
wantErr: `bad upstream for domain "[/host.com]tls://dns.adguard.com": missing separator`,
valid: false,
wantDef: false,
}, {
wantDef: assert.True,
name: "invalid",
upstream: "[host.ru]#",
wantErr: `bad ipport address "[host.ru]#": address [host.ru]#: missing port in address`,
valid: false,
wantDef: false,
}, {
wantDef: assert.True,
name: "valid_default",
upstream: "1.1.1.1",
wantErr: ``,
valid: true,
wantDef: true,
}, {
wantDef: assert.True,
name: "valid_default",
upstream: "tls://1.1.1.1",
wantErr: ``,
valid: true,
wantDef: true,
}, {
wantDef: assert.True,
name: "valid_default",
upstream: "https://dns.adguard.com/dns-query",
wantErr: ``,
valid: true,
wantDef: true,
}, {
wantDef: assert.True,
name: "valid_default",
upstream: "sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20",
wantErr: ``,
valid: true,
wantDef: true,
}, {
wantDef: assert.False,
name: "valid",
upstream: "[/host.com/]1.1.1.1",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "valid",
upstream: "[//]tls://1.1.1.1",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "valid",
upstream: "[/www.host.com/]#",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "valid",
upstream: "[/host.com/google.com/]8.8.8.8",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "valid",
upstream: "[/host/]sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "idna",
upstream: "[/пример.рф/]8.8.8.8",
wantErr: ``,
valid: true,
wantDef: false,
}, {
wantDef: assert.False,
name: "bad_domain",
upstream: "[/!/]8.8.8.8",
wantErr: `bad upstream for domain "[/!/]8.8.8.8": domain at index 0: ` +
`bad domain name "!": bad domain name label "!": bad domain name label rune '!'`,
valid: false,
wantDef: false,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defaultUpstream, err := validateUpstream(tc.upstream)
testutil.AssertErrorMsg(t, tc.wantErr, err)
tc.wantDef(t, defaultUpstream)
require.Equal(t, tc.valid, err == nil)
if tc.valid {
assert.Equal(t, tc.wantDef, defaultUpstream)
}
})
}
}
@@ -353,19 +343,22 @@ func TestValidateUpstream(t *testing.T) {
func TestValidateUpstreamsSet(t *testing.T) {
testCases := []struct {
name string
wantErr string
msg string
set []string
wantNil bool
}{{
name: "empty",
wantErr: ``,
msg: "empty upstreams array should be valid",
set: nil,
wantNil: true,
}, {
name: "comment",
wantErr: ``,
msg: "comments should not be validated",
set: []string{"# comment"},
wantNil: true,
}, {
name: "valid_no_default",
wantErr: `no default upstreams specified`,
name: "valid_no_default",
msg: "there is no default upstream",
set: []string{
"[/host.com/]1.1.1.1",
"[//]tls://1.1.1.1",
@@ -373,9 +366,10 @@ func TestValidateUpstreamsSet(t *testing.T) {
"[/host.com/google.com/]8.8.8.8",
"[/host/]sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20",
},
wantNil: false,
}, {
name: "valid_with_default",
wantErr: ``,
name: "valid_with_default",
msg: "upstreams set is valid, but doesn't pass through validation cause: %s",
set: []string{
"[/host.com/]1.1.1.1",
"[//]tls://1.1.1.1",
@@ -384,16 +378,19 @@ func TestValidateUpstreamsSet(t *testing.T) {
"[/host/]sdns://AQMAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20",
"8.8.8.8",
},
wantNil: true,
}, {
name: "invalid",
wantErr: `cannot prepare the upstream dhcp://fake.dns ([]): unsupported URL scheme: dhcp`,
msg: "there is an invalid upstream in set, but it pass through validation",
set: []string{"dhcp://fake.dns"},
wantNil: false,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := ValidateUpstreams(tc.set)
testutil.AssertErrorMsg(t, tc.wantErr, err)
assert.Equalf(t, tc.wantNil, err == nil, tc.msg, err)
})
}
}

View File

@@ -783,17 +783,12 @@ func (clients *clientsContainer) addFromHostsFile(hosts *netutil.IPMap) {
n := 0
hosts.Range(func(ip net.IP, v interface{}) (cont bool) {
hosts, ok := v.(*aghnet.Hosts)
names, ok := v.(*stringutil.Set)
if !ok {
log.Error("dns: bad type %T in ipToRC for %s", v, ip)
return true
}
if clients.addHostLocked(ip, hosts.Main, ClientSourceHostsFile) {
n++
}
hosts.Aliases.Range(func(name string) (cont bool) {
names.Range(func(name string) (cont bool) {
if clients.addHostLocked(ip, name, ClientSourceHostsFile) {
n++
}

View File

@@ -7,7 +7,7 @@ import (
"path/filepath"
"sync"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
@@ -288,9 +288,9 @@ func parseConfig() (err error) {
return err
}
uc := aghalg.UniqChecker{}
uv := aghalgo.UniquenessValidator{}
addPorts(
uc,
uv,
config.BindPort,
config.BetaBindPort,
config.DNS.Port,
@@ -298,14 +298,14 @@ func parseConfig() (err error) {
if config.TLS.Enabled {
addPorts(
uc,
uv,
config.TLS.PortHTTPS,
config.TLS.PortDNSOverTLS,
config.TLS.PortDNSOverQUIC,
config.TLS.PortDNSCrypt,
)
}
if err = uc.Validate(aghalg.IntIsBefore); err != nil {
if err = uv.Validate(aghalgo.IntIsBefore); err != nil {
return fmt.Errorf("validating ports: %w", err)
}
@@ -321,10 +321,10 @@ func parseConfig() (err error) {
}
// addPorts is a helper for ports validation. It skips zero ports.
func addPorts(uc aghalg.UniqChecker, ports ...int) {
func addPorts(uv aghalgo.UniquenessValidator, ports ...int) {
for _, p := range ports {
if p != 0 {
uc.Add(p)
uv.Add(p)
}
}
}

View File

@@ -14,10 +14,9 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/version"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
)
@@ -25,23 +24,13 @@ import (
// getAddrsResponse is the response for /install/get_addresses endpoint.
type getAddrsResponse struct {
Interfaces map[string]*aghnet.NetInterface `json:"interfaces"`
// Version is the version of AdGuard Home.
//
// TODO(a.garipov): In the new API, rename this endpoint to something more
// general, since there will be more information here than just network
// interfaces.
Version string `json:"version"`
WebPort int `json:"web_port"`
DNSPort int `json:"dns_port"`
WebPort int `json:"web_port"`
DNSPort int `json:"dns_port"`
}
// handleInstallGetAddresses is the handler for /install/get_addresses endpoint.
func (web *Web) handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) {
data := getAddrsResponse{
Version: version.Version(),
WebPort: defaultPortHTTP,
DNSPort: defaultPortDNS,
}
@@ -73,19 +62,19 @@ func (web *Web) handleInstallGetAddresses(w http.ResponseWriter, r *http.Request
}
}
type checkConfReqEnt struct {
type checkConfigReqEnt struct {
IP net.IP `json:"ip"`
Port int `json:"port"`
Autofix bool `json:"autofix"`
}
type checkConfReq struct {
Web checkConfReqEnt `json:"web"`
DNS checkConfReqEnt `json:"dns"`
SetStaticIP bool `json:"set_static_ip"`
type checkConfigReq struct {
Web checkConfigReqEnt `json:"web"`
DNS checkConfigReqEnt `json:"dns"`
SetStaticIP bool `json:"set_static_ip"`
}
type checkConfRespEnt struct {
type checkConfigRespEnt struct {
Status string `json:"status"`
CanAutofix bool `json:"can_autofix"`
}
@@ -96,110 +85,79 @@ type staticIPJSON struct {
Error string `json:"error"`
}
type checkConfResp struct {
StaticIP staticIPJSON `json:"static_ip"`
Web checkConfRespEnt `json:"web"`
DNS checkConfRespEnt `json:"dns"`
type checkConfigResp struct {
StaticIP staticIPJSON `json:"static_ip"`
Web checkConfigRespEnt `json:"web"`
DNS checkConfigRespEnt `json:"dns"`
}
// validateWeb returns error is the web part if the initial configuration can't
// be set.
func (req *checkConfReq) validateWeb(uc aghalg.UniqChecker) (err error) {
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
port := req.Web.Port
addPorts(uc, config.BetaBindPort, port)
if err = uc.Validate(aghalg.IntIsBefore); err != nil {
// Avoid duplicating the error into the status of DNS.
uc[port] = 1
return err
}
switch port {
case 0, config.BindPort:
return nil
default:
// Go on and check the port binding only if it's not zero or won't be
// unbound after install.
}
return aghnet.CheckPort("tcp", req.Web.IP, port)
}
// validateDNS returns error if the DNS part of the initial configuration can't
// be set. canAutofix is true if the port can be unbound by AdGuard Home
// automatically.
func (req *checkConfReq) validateDNS(uc aghalg.UniqChecker) (canAutofix bool, err error) {
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
port := req.DNS.Port
addPorts(uc, port)
if err = uc.Validate(aghalg.IntIsBefore); err != nil {
return false, err
}
switch port {
case 0:
return false, nil
case config.BindPort:
// Go on and only check the UDP port since the TCP one is already bound
// by AdGuard Home for web interface.
default:
// Check TCP as well.
err = aghnet.CheckPort("tcp", req.DNS.IP, port)
if err != nil {
return false, err
}
}
err = aghnet.CheckPort("udp", req.DNS.IP, port)
if !aghnet.IsAddrInUse(err) {
return false, err
}
// Try to fix automatically.
canAutofix = checkDNSStubListener()
if canAutofix && req.DNS.Autofix {
if derr := disableDNSStubListener(); derr != nil {
log.Error("disabling DNSStubListener: %s", err)
}
err = aghnet.CheckPort("udp", req.DNS.IP, port)
canAutofix = false
}
return canAutofix, err
}
// handleInstallCheckConfig handles the /check_config endpoint.
// Check if ports are available, respond with results
func (web *Web) handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
req := &checkConfReq{}
reqData := checkConfigReq{}
respData := checkConfigResp{}
err := json.NewDecoder(r.Body).Decode(req)
err := json.NewDecoder(r.Body).Decode(&reqData)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "decoding the request: %s", err)
aghhttp.Error(r, w, http.StatusBadRequest, "Failed to parse 'check_config' JSON data: %s", err)
return
}
resp := &checkConfResp{}
uc := aghalg.UniqChecker{}
if err = req.validateWeb(uc); err != nil {
resp.Web.Status = err.Error()
uv := aghalgo.UniquenessValidator{}
addPorts(
uv,
config.BindPort,
config.BetaBindPort,
reqData.Web.Port,
)
if err = uv.Validate(aghalgo.IntIsBefore); err != nil {
err = fmt.Errorf("validating ports: %w", err)
respData.Web.Status = err.Error()
} else if reqData.Web.Port != 0 {
err = aghnet.CheckPort("tcp", reqData.Web.IP, reqData.Web.Port)
if err != nil {
respData.Web.Status = err.Error()
}
}
if resp.DNS.CanAutofix, err = req.validateDNS(uc); err != nil {
resp.DNS.Status = err.Error()
} else if !req.DNS.IP.IsUnspecified() {
resp.StaticIP = handleStaticIP(req.DNS.IP, req.SetStaticIP)
addPorts(uv, reqData.DNS.Port)
if err = uv.Validate(aghalgo.IntIsBefore); err != nil {
err = fmt.Errorf("validating ports: %w", err)
respData.DNS.Status = err.Error()
} else if reqData.DNS.Port != 0 {
err = aghnet.CheckPort("udp", reqData.DNS.IP, reqData.DNS.Port)
if aghnet.IsAddrInUse(err) {
canAutofix := checkDNSStubListener()
if canAutofix && reqData.DNS.Autofix {
err = disableDNSStubListener()
if err != nil {
log.Error("Couldn't disable DNSStubListener: %s", err)
}
err = aghnet.CheckPort("udp", reqData.DNS.IP, reqData.DNS.Port)
canAutofix = false
}
respData.DNS.CanAutofix = canAutofix
}
if err == nil {
err = aghnet.CheckPort("tcp", reqData.DNS.IP, reqData.DNS.Port)
}
if err != nil {
respData.DNS.Status = err.Error()
} else if !reqData.DNS.IP.IsUnspecified() {
respData.StaticIP = handleStaticIP(reqData.DNS.IP, reqData.SetStaticIP)
}
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(resp)
err = json.NewEncoder(w).Encode(respData)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding the response: %s", err)
aghhttp.Error(r, w, http.StatusInternalServerError, "Unable to marshal JSON: %s", err)
return
}
@@ -321,11 +279,10 @@ type applyConfigReqEnt struct {
}
type applyConfigReq struct {
Username string `json:"username"`
Password string `json:"password"`
Web applyConfigReqEnt `json:"web"`
DNS applyConfigReqEnt `json:"dns"`
Web applyConfigReqEnt `json:"web"`
DNS applyConfigReqEnt `json:"dns"`
Username string `json:"username"`
Password string `json:"password"`
}
// copyInstallSettings copies the installation parameters between two
@@ -525,13 +482,13 @@ func (web *Web) handleInstallCheckConfigBeta(w http.ResponseWriter, r *http.Requ
return
}
nonBetaReqData := checkConfReq{
Web: checkConfReqEnt{
nonBetaReqData := checkConfigReq{
Web: checkConfigReqEnt{
IP: reqData.Web.IP[0],
Port: reqData.Web.Port,
Autofix: reqData.Web.Autofix,
},
DNS: checkConfReqEnt{
DNS: checkConfigReqEnt{
IP: reqData.DNS.IP[0],
Port: reqData.DNS.Port,
Autofix: reqData.DNS.Autofix,
@@ -576,11 +533,10 @@ type applyConfigReqEntBeta struct {
// TODO(e.burkov): This should removed with the API v1 when the appropriate
// functionality will appear in default applyConfigReq.
type applyConfigReqBeta struct {
Username string `json:"username"`
Password string `json:"password"`
Web applyConfigReqEntBeta `json:"web"`
DNS applyConfigReqEntBeta `json:"dns"`
Web applyConfigReqEntBeta `json:"web"`
DNS applyConfigReqEntBeta `json:"dns"`
Username string `json:"username"`
Password string `json:"password"`
}
// handleInstallConfigureBeta is a substitution of /install/configure handler

View File

@@ -54,7 +54,7 @@ func initDNSServer() (err error) {
}
Context.stats, err = stats.New(statsConf)
if err != nil {
return fmt.Errorf("init stats: %w", err)
return fmt.Errorf("couldn't initialize statistics module")
}
conf := querylog.Config{

View File

@@ -19,7 +19,7 @@ import (
"syscall"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
@@ -296,23 +296,23 @@ func setupConfig(args options) (err error) {
Context.clients.Init(config.Clients, Context.dhcpServer, Context.etcHosts)
if args.bindPort != 0 {
uc := aghalg.UniqChecker{}
uv := aghalgo.UniquenessValidator{}
addPorts(
uc,
uv,
args.bindPort,
config.BetaBindPort,
config.DNS.Port,
)
if config.TLS.Enabled {
addPorts(
uc,
uv,
config.TLS.PortHTTPS,
config.TLS.PortDNSOverTLS,
config.TLS.PortDNSOverQUIC,
config.TLS.PortDNSCrypt,
)
}
if err = uc.Validate(aghalg.IntIsBefore); err != nil {
if err = uv.Validate(aghalgo.IntIsBefore); err != nil {
return fmt.Errorf("validating ports: %w", err)
}
@@ -393,9 +393,9 @@ func run(args options, clientBuildFS fs.FS) {
// Go memory hacks
memoryUsage(args)
// Print the first message after logger is configured.
// print the first message after logger is configured
log.Println(version.Full())
log.Debug("current working directory is %s", Context.workDir)
log.Debug("Current working directory is %s", Context.workDir)
if args.runningAsService {
log.Info("AdGuard Home is running as a service")
}
@@ -631,13 +631,13 @@ func configureLogger(args options) {
log.SetLevel(log.DEBUG)
}
// Make sure that we see the microseconds in logs, as networking stuff can
// happen pretty quickly.
// Make sure that we see the microseconds in logs, as networking stuff
// can happen pretty quickly.
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
if args.runningAsService && ls.LogFile == "" && runtime.GOOS == "windows" {
// When running as a Windows service, use eventlog by default if nothing
// else is configured. Otherwise, we'll simply lose the log output.
// When running as a Windows service, use eventlog by default if nothing else is configured
// Otherwise, we'll simply loose the log output
ls.LogFile = configSyslog
}

View File

@@ -82,12 +82,6 @@ func svcStatus(s service.Service) (status service.Status, err error) {
// On OpenWrt, the service utility may not exist. We use our service script
// directly in this case.
func svcAction(s service.Service, action string) (err error) {
if runtime.GOOS == "darwin" &&
action == "start" &&
!strings.HasPrefix(Context.workDir, "/Applications/") {
log.Info("warning: service must be started from within the /Applications directory")
}
err = service.Control(s, action)
if err != nil && service.Platform() == "unix-systemv" &&
(action == "start" || action == "stop" || action == "restart") {

View File

@@ -20,7 +20,7 @@ import (
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/golibs/errors"
@@ -251,9 +251,9 @@ func (t *TLSMod) handleTLSValidate(w http.ResponseWriter, r *http.Request) {
}
if setts.Enabled {
uc := aghalg.UniqChecker{}
uv := aghalgo.UniquenessValidator{}
addPorts(
uc,
uv,
config.BindPort,
config.BetaBindPort,
config.DNS.Port,
@@ -263,7 +263,7 @@ func (t *TLSMod) handleTLSValidate(w http.ResponseWriter, r *http.Request) {
setts.PortDNSCrypt,
)
err = uc.Validate(aghalg.IntIsBefore)
err = uv.Validate(aghalgo.IntIsBefore)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "validating ports: %s", err)
@@ -344,9 +344,9 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
}
if data.Enabled {
uc := aghalg.UniqChecker{}
uv := aghalgo.UniquenessValidator{}
addPorts(
uc,
uv,
config.BindPort,
config.BetaBindPort,
config.DNS.Port,
@@ -356,7 +356,7 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
data.PortDNSCrypt,
)
err = uc.Validate(aghalg.IntIsBefore)
err = uv.Validate(aghalgo.IntIsBefore)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)

View File

@@ -67,29 +67,7 @@ type unitDB struct {
TimeAvg uint32 // usec
}
// withRecovered turns the value recovered from panic if any into an error and
// combines it with the one pointed by orig. orig must be non-nil.
func withRecovered(orig *error) {
p := recover()
if p == nil {
return
}
var err error
switch p := p.(type) {
case error:
err = fmt.Errorf("panic: %w", p)
default:
err = fmt.Errorf("panic: recovered value of type %[1]T: %[1]v", p)
}
*orig = errors.WithDeferred(*orig, err)
}
// createObject creates s from conf and properly initializes it.
func createObject(conf Config) (s *statsCtx, err error) {
defer withRecovered(&err)
s = &statsCtx{
mu: &sync.Mutex{},
}

View File

@@ -1,32 +1,21 @@
module github.com/AdguardTeam/AdGuardHome/internal/tools
go 1.17
go 1.16
require (
github.com/fzipp/gocyclo v0.4.0
github.com/fzipp/gocyclo v0.3.1
github.com/golangci/misspell v0.3.5
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8
github.com/google/go-cmp v0.5.5 // indirect
github.com/gookit/color v1.4.2 // indirect
github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254
github.com/kisielk/errcheck v1.6.0
github.com/kyoh86/looppointer v0.1.7
github.com/securego/gosec/v2 v2.9.5
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/tools v0.1.8
honnef.co/go/tools v0.2.2
mvdan.cc/gofumpt v0.2.1
mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5
)
require (
github.com/BurntSushi/toml v0.4.1 // indirect
github.com/client9/misspell v0.3.4 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gookit/color v1.5.0 // indirect
github.com/kyoh86/nolint v0.0.1 // indirect
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
github.com/securego/gosec/v2 v2.7.0
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect
golang.org/x/tools v0.1.1
honnef.co/go/tools v0.1.4
mvdan.cc/gofumpt v0.1.1
mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7
)

View File

@@ -33,9 +33,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
@@ -77,7 +76,6 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -92,14 +90,12 @@ github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss=
github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
github.com/fzipp/gocyclo v0.4.0 h1:IykTnjwh2YLyYkGa0y92iTTEQcnyAz0r9zOo15EbJ7k=
github.com/fzipp/gocyclo v0.4.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/fzipp/gocyclo v0.3.1 h1:A9UeX3HJSXTBzvHzhqoYVuE0eAhe+aM8XBCCwsPMZOc=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -111,7 +107,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@@ -142,8 +137,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo=
github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -156,9 +149,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -173,15 +166,14 @@ github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEi
github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.3.8/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U=
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI=
github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -225,13 +217,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/kyoh86/looppointer v0.1.7 h1:q5sZOhFvmvQ6ZoZxvPB/Mjj2croWX7L49BBuI4XQWCM=
github.com/kyoh86/looppointer v0.1.7/go.mod h1:l0cRF49N6xDPx8IuBGC/imZo8Yn1BBLJY0vzI+4fepc=
@@ -241,7 +231,6 @@ github.com/kyoh86/nolint v0.0.1/go.mod h1:1ZiZZ7qqrZ9dZegU96phwVcdQOMKIqRzFJL3ew
github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -268,7 +257,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=
github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=
@@ -284,18 +273,15 @@ github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2f
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -319,14 +305,13 @@ github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/securego/gosec/v2 v2.9.5 h1:Wiyf78NNedu8RClwW0vPRgPKCY7LJX4WujjJcPV2Nwg=
github.com/securego/gosec/v2 v2.9.5/go.mod h1:lG831xFHrZofatyJb9Y5yMUE8Ws6z5U5CMHe9vYn1kM=
github.com/securego/gosec/v2 v2.7.0 h1:mOhJv5w6UyNLpSssQOQCc7eGkKLuicAxvf66Ey/X4xk=
github.com/securego/gosec/v2 v2.7.0/go.mod h1:xNbGArrGUspJLuz3LS5XCY1EBW/0vABAl/LWfSklmiM=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -349,10 +334,8 @@ github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
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/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -373,7 +356,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
@@ -401,7 +383,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -435,9 +417,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -473,11 +456,10 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -540,14 +522,11 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -555,9 +534,8 @@ 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=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -613,10 +591,11 @@ golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200710042808-f1c4188a97a1/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -700,8 +679,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -737,12 +714,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk=
honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
mvdan.cc/gofumpt v0.2.1 h1:7jakRGkQcLAJdT+C8Bwc9d0BANkVPSkHZkzNv07pJAs=
mvdan.cc/gofumpt v0.2.1/go.mod h1:a/rvZPhsNaedOJBzqRD9omnwVwHZsBdJirXHa9Gh9Ig=
mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 h1:Jh3LAeMt1eGpxomyu3jVkmVZWW2MxZ1qIIV2TZ/nRio=
mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5/go.mod h1:b8RRCBm0eeiWR8cfN88xeq2G5SG3VKGO+5UPWi5FSOY=
honnef.co/go/tools v0.1.4 h1:SadWOkti5uVN1FAMgxn165+Mw00fuQKyk4Gyn/inxNQ=
honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7 h1:HT3e4Krq+IE44tiN36RvVEb6tvqeIdtsVSsxmNPqlFU=
mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@@ -62,10 +62,18 @@ func Version() (v string) {
return version
}
// Common formatting constants.
const (
sp = " "
nl = "\n"
tb = "\t"
nltb = nl + tb
)
// Constants defining the format of module information string.
const (
modInfoAtSep = "@"
modInfoDevSep = " "
modInfoDevSep = sp
modInfoSumLeft = " (sum: "
modInfoSumRight = ")"
)
@@ -134,7 +142,6 @@ const (
func Verbose() (v string) {
b := &strings.Builder{}
const nl = "\n"
stringutil.WriteToBuilder(
b,
vFmtAGHHdr,
@@ -171,7 +178,7 @@ func Verbose() (v string) {
stringutil.WriteToBuilder(b, nl, vFmtDepsHdr)
for _, dep := range info.Deps {
if depStr := fmtModule(dep); depStr != "" {
stringutil.WriteToBuilder(b, "\n\t", depStr)
stringutil.WriteToBuilder(b, nltb, depStr)
}
}

View File

@@ -2,16 +2,9 @@
<!-- TODO(a.garipov): Reformat in accordance with the KeepAChangelog spec. -->
## v0.107.3: API changes
## v0.107: API changes
### The new field `"version"` in `AddressesInfo`
* The new field `"version"` in `GET /install/get_addresses` is the version of
the AdGuard Home instance.
## v0.107.0: API changes
### The new field `"cached"` in `QueryLogItem`
## The new field `"cached"` in `QueryLogItem`
* The new field `"cached"` in `GET /control/querylog` is true if the response is
served from cache instead of being resolved by an upstream server.

View File

@@ -123,9 +123,7 @@
'8.8.8.8': 'OK'
'8.8.4.4': 'OK'
'192.168.1.104:53535': >
upstream "192.168.1.104:1234" fails to exchange: couldn't
communicate with upstream: read udp
192.168.1.100:60675->8.8.8.8:1234: i/o timeout
Couldn't communicate with DNS server
'/version.json':
'post':
'tags':
@@ -1264,7 +1262,7 @@
'type': 'boolean'
'version':
'type': 'string'
'example': 'v0.123.4'
'example': '0.1'
'language':
'type': 'string'
'example': 'en'
@@ -2221,23 +2219,19 @@
'description': 'AdGuard Home addresses configuration'
'required':
- 'dns_port'
- 'interfaces'
- 'version'
- 'web_port'
- 'interfaces'
'properties':
'dns_port':
'type': 'integer'
'format': 'uint16'
'example': 53
'interfaces':
'$ref': '#/components/schemas/NetInterfaces'
'version':
'type': 'string'
'example': 'v0.123.4'
'web_port':
'type': 'integer'
'format': 'uint16'
'example': 80
'interfaces':
'$ref': '#/components/schemas/NetInterfaces'
'AddressesInfoBeta':
'type': 'object'
'description': 'AdGuard Home addresses configuration'

View File

@@ -272,12 +272,32 @@ fix_darwin() {
return 0
fi
if [ "$cpu" = 'arm64' ]
then
case "$channel"
in
('beta'|'development'|'edge')
# Everything is fine, we have Apple Silicon support on
# these channels.
;;
('release')
cpu='amd64'
log "use $cpu build on Mac M1 until the native ARM support is added."
;;
(*)
# Generally shouldn't happen, since the release channel
# has already been validated.
error_exit "invalid channel '$channel'"
;;
esac
fi
# Set the package extension.
pkg_ext='zip'
# It is important to install AdGuard Home into the /Applications directory
# on macOS. Otherwise, it may grant not enough privileges to the AdGuard
# Home.
# It is important to install AdGuard Home into the /Applications
# directory on macOS. Otherwise, it may not grant enough privileges to
# the AdGuard Home.
out_dir='/Applications'
}

View File

@@ -159,8 +159,7 @@ linux ppc64le 0 0 0
openbsd amd64 0 0 0
openbsd arm64 0 0 0
windows 386 0 0 0
windows amd64 0 0 0
windows arm64 0 0 0"
windows amd64 0 0 0"
readonly platforms
# Function build builds the release for one platform. It builds a binary, an

View File

@@ -49,10 +49,10 @@ trap not_found EXIT
# Warnings
go_version="$( "${GO:-go}" version )"
go_version="$( "$GO" version )"
readonly go_version
go_min_version='go1.17'
go_min_version='go1.16'
go_version_msg="
warning: your go version (${go_version}) is different from the recommended minimal one (${go_min_version}).
if you have the version installed, please set the GO environment variable.
@@ -62,6 +62,7 @@ for example:
"
readonly go_min_version go_version_msg
case "$go_version"
in
('go version'*"$go_min_version"*)
@@ -79,11 +80,11 @@ esac
# blocklist_imports is a simple check against unwanted packages. The following
# packages are banned:
#
# * Package io/ioutil is soft-deprecated.
#
# * Packages errors and log are replaced by our own packages in the
# github.com/AdguardTeam/golibs module.
#
# * Package io/ioutil is soft-deprecated.
#
# * Package reflect is often an overkill, and for deep comparisons there are
# much better functions in module github.com/google/go-cmp. Which is
# already our indirect dependency and which may or may not enter the stdlib
@@ -93,8 +94,6 @@ esac
#
# * Package unsafe is… unsafe.
#
# * Package golang.org/x/net/context has been moved into stdlib.
#
blocklist_imports() {
git grep\
-e '[[:space:]]"errors"$'\
@@ -102,55 +101,33 @@ blocklist_imports() {
-e '[[:space:]]"log"$'\
-e '[[:space:]]"reflect"$'\
-e '[[:space:]]"unsafe"$'\
-e '[[:space:]]"golang.org/x/net/context"$'\
-n\
-- '*.go'\
| sed -e 's/^\([^[:space:]]\+\)\(.*\)$/\1 blocked import:\2/'\
|| exit 0
-- '*.go' || exit 0;
}
# method_const is a simple check against the usage of some raw strings and
# numbers where one should use named constants.
method_const() {
git grep -F\
-e '"DELETE"'\
-e '"GET"'\
-e '"POST"'\
-e '"PUT"'\
-n\
-- '*.go'\
| sed -e 's/^\([^[:space:]]\+\)\(.*\)$/\1 http method literal:\2/'\
|| exit 0
git grep -F -e '"GET"' -e '"POST"' -- '*.go' || exit 0;
}
# underscores is a simple check against Go filenames with underscores. Add new
# build tags and OS as you go. The main goal of this check is to discourage the
# use of filenames like client_manager.go.
# underscores is a simple check against Go filenames with underscores.
underscores() {
underscore_files="$(
git ls-files '*_*.go'\
| grep -F\
-e '_big.go'\
-e '_bsd.go'\
-e '_darwin.go'\
-e '_freebsd.go'\
-e '_openbsd.go'\
-e '_linux.go'\
-e '_little.go'\
-e '_others.go'\
-e '_test.go'\
-e '_unix.go'\
-e '_windows.go' \
-v\
| sed -e 's/./\t\0/'
)"
readonly underscore_files
if [ "$underscore_files" != '' ]
then
echo 'found file names with underscores:'
echo "$underscore_files"
fi
git ls-files '*_*.go' | {
grep -F\
-e '_big.go'\
-e '_bsd.go'\
-e '_darwin.go'\
-e '_freebsd.go'\
-e '_openbsd.go'\
-e '_linux.go'\
-e '_little.go'\
-e '_others.go'\
-e '_test.go'\
-e '_unix.go'\
-e '_windows.go' \
-v\
|| exit 0
}
}
# TODO(a.garipov): Add an analyser to look for `fallthrough`, `goto`, and `new`?
@@ -174,7 +151,7 @@ exit_on_output() (
output="$( "$cmd" "$@" 2>&1 )"
exitcode="$?"
if [ "$exitcode" -ne '0' ]
if [ "$exitcode" != '0' ]
then
echo "'$cmd' failed with code $exitcode"
fi
@@ -183,9 +160,9 @@ exit_on_output() (
then
if [ "$*" != '' ]
then
echo "combined output of linter '$cmd $*':"
echo "combined output of '$cmd $*':"
else
echo "combined output of linter '$cmd':"
echo "combined output of '$cmd':"
fi
echo "$output"
@@ -201,6 +178,13 @@ exit_on_output() (
# Constants
go_files='./main.go ./internal/'
readonly go_files
# Checks
exit_on_output blocklist_imports
@@ -209,7 +193,7 @@ exit_on_output method_const
exit_on_output underscores
exit_on_output gofumpt --extra -e -l .
exit_on_output gofumpt --extra -l -s .
golint --set_exit_status ./...
@@ -224,6 +208,8 @@ gocyclo --over 10 ./internal/aghio/ ./internal/aghnet/ ./internal/aghos/\
./internal/aghtest/ ./internal/stats/ ./internal/tools/\
./internal/updater/ ./internal/version/ ./main.go
gosec --quiet $go_files
ineffassign ./...
unparam ./...
@@ -236,9 +222,6 @@ nilness ./...
exit_on_output shadow --strict ./...
# TODO(a.garipov): Enable in v0.108.0.
# gosec --quiet ./...
# TODO(a.garipov): Enable --blank?
errcheck --asserts ./...

View File

@@ -35,13 +35,10 @@ fi
readonly race_flags
go="${GO:-go}"
readonly go
count_flags='--count=1'
cover_flags='--coverprofile=./coverage.txt'
shuffle_flags='--shuffle=on'
timeout_flags="${TIMEOUT_FLAGS:---timeout=30s}"
readonly count_flags cover_flags shuffle_flags timeout_flags
readonly go timeout_flags cover_flags count_flags
"$go" test "$count_flags" "$cover_flags" "$race_flags" "$shuffle_flags" "$timeout_flags"\
"$x_flags" "$v_flags" ./...
"$go" test "$count_flags" "$cover_flags" "$race_flags" "$timeout_flags" "$x_flags" "$v_flags" ./...