Compare commits
133 Commits
v0.108.0-b
...
release-v0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e73605c4c5 | ||
|
|
c7017d49aa | ||
|
|
191d3bde49 | ||
|
|
18876a8e5c | ||
|
|
aa4a0d9880 | ||
|
|
d03d731d65 | ||
|
|
33b58a42fe | ||
|
|
2e9e708647 | ||
|
|
8ad22841ab | ||
|
|
32cf02264c | ||
|
|
0e8445b38f | ||
|
|
cb27ecd6c0 | ||
|
|
535220b3df | ||
|
|
7b9cfa94f8 | ||
|
|
b3f2e88e9c | ||
|
|
aa7a8d45e4 | ||
|
|
49cdef3d6a | ||
|
|
fecd146552 | ||
|
|
b01efd8c98 | ||
|
|
bd4dfb261c | ||
|
|
e754e4d2f6 | ||
|
|
b220e35c99 | ||
|
|
4f5131f423 | ||
|
|
dcb043df5f | ||
|
|
86e5756262 | ||
|
|
ba0cf5739b | ||
|
|
c4a13b92d2 | ||
|
|
723279121a | ||
|
|
3ad7649f7d | ||
|
|
2898a49d86 | ||
|
|
1547f9d35e | ||
|
|
adadd55c42 | ||
|
|
33b0225aa4 | ||
|
|
97d4058d80 | ||
|
|
86207e719d | ||
|
|
113f94ff46 | ||
|
|
5673deb391 | ||
|
|
3548a393ed | ||
|
|
254515f274 | ||
|
|
bccbecc6ea | ||
|
|
66f53803af | ||
|
|
faef005ce7 | ||
|
|
941cd2a562 | ||
|
|
6a4a9a0239 | ||
|
|
b9dbe6f1b6 | ||
|
|
7fec111ef8 | ||
|
|
5e1bd99718 | ||
|
|
9d75f72ceb | ||
|
|
d98d96db1a | ||
|
|
6a0ef2df15 | ||
|
|
75c2eb4c8a | ||
|
|
d021a67d66 | ||
|
|
4ed97cab12 | ||
|
|
a38742eed7 | ||
|
|
5efa95ed26 | ||
|
|
04db7db607 | ||
|
|
d17c6c6bb3 | ||
|
|
b2052f2ef1 | ||
|
|
cddcf852c2 | ||
|
|
1def426b45 | ||
|
|
b114fd5279 | ||
|
|
d27c3284f6 | ||
|
|
ba24a26b53 | ||
|
|
3e6678b6b4 | ||
|
|
83fd6f9782 | ||
|
|
52bc1b3f10 | ||
|
|
dd2153b7ac | ||
|
|
dd96a34861 | ||
|
|
daf26ee25a | ||
|
|
7e140eaaac | ||
|
|
d07a712988 | ||
|
|
95863288bf | ||
|
|
ea12be658b | ||
|
|
faa7c9aae5 | ||
|
|
e3653e8c25 | ||
|
|
b40cb24822 | ||
|
|
74004c1aa0 | ||
|
|
3e240741f1 | ||
|
|
6cfdbef1a5 | ||
|
|
d9bde6425b | ||
|
|
e2ae9e1591 | ||
|
|
5ebcbfa9ad | ||
|
|
e276bd7a31 | ||
|
|
659b2529bf | ||
|
|
97b3ed43ab | ||
|
|
767d6d3f28 | ||
|
|
31fc9bfc52 | ||
|
|
3f06b02409 | ||
|
|
5bf958ec6b | ||
|
|
959d9ff9a0 | ||
|
|
4813b4de25 | ||
|
|
119100924c | ||
|
|
bd584de4ee | ||
|
|
ede85ab2f2 | ||
|
|
12c20288e4 | ||
|
|
5bbbf89c10 | ||
|
|
d55393ecd5 | ||
|
|
2b5927306f | ||
|
|
4f016b6ed7 | ||
|
|
3a2a6d10ec | ||
|
|
2491426b09 | ||
|
|
5ebdd1390e | ||
|
|
b7f0247575 | ||
|
|
e28186a28a | ||
|
|
de1a7ce48f | ||
|
|
48480fb33b | ||
|
|
f41332fe6b | ||
|
|
1f8b340b8f | ||
|
|
fdaf1d09d3 | ||
|
|
b9682c4f10 | ||
|
|
69dcb4effd | ||
|
|
d50fd0ba91 | ||
|
|
c2c7b4c731 | ||
|
|
952d5f3a3d | ||
|
|
3f126c9ec9 | ||
|
|
0be58ef918 | ||
|
|
8f9053e2fc | ||
|
|
68452e5330 | ||
|
|
2eacc46eaa | ||
|
|
74dcc91ea7 | ||
|
|
dd7bf61323 | ||
|
|
2819d6cace | ||
|
|
75355a6883 | ||
|
|
e9c007d56b | ||
|
|
84c9085516 | ||
|
|
9f36e57c1e | ||
|
|
7528699fc2 | ||
|
|
d280151c18 | ||
|
|
b44c755d25 | ||
|
|
e4078e87a1 | ||
|
|
be36204756 | ||
|
|
b5409d6d00 | ||
|
|
f3d6bce03e |
1
.github/stale.yml
vendored
1
.github/stale.yml
vendored
@@ -8,6 +8,7 @@
|
||||
- 'documentation'
|
||||
- 'enhancement'
|
||||
- 'feature request'
|
||||
- 'help wanted'
|
||||
- 'localization'
|
||||
- 'needs investigation'
|
||||
- 'recurrent'
|
||||
|
||||
329
CHANGELOG.md
329
CHANGELOG.md
@@ -12,25 +12,109 @@ and this project adheres to
|
||||
## [Unreleased]
|
||||
|
||||
<!--
|
||||
## [v0.108.0] - 2022-06-01 (APPROX.)
|
||||
## [v0.108.0] - 2022-10-01 (APPROX.)
|
||||
-->
|
||||
|
||||
### Security
|
||||
|
||||
- Weaker cipher suites that use the CBC (cipher block chaining) mode of
|
||||
operation have been disabled ([#2993]).
|
||||
|
||||
### Added
|
||||
|
||||
- The ability to customize the set of networks considered private through the
|
||||
new `private_networks` setting ([#3142]).
|
||||
- Support for Discovery of Designated Resolvers (DDR) according to the [RFC
|
||||
draft][ddr-draft] ([#4463]).
|
||||
- `windows/arm64` support ([#3057]).
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Go 1.17 support. v0.109.0 will require at least Go 1.18 to build.
|
||||
|
||||
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
|
||||
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
|
||||
|
||||
[ddr-draft]: https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-08
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
## [v0.107.9] - 2022-08-23 (APPROX.)
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## [v0.107.8] - 2022-07-13
|
||||
|
||||
See also the [v0.107.8 GitHub milestone][ms-v0.107.8].
|
||||
|
||||
### Security
|
||||
|
||||
- Go version was updated to prevent the possibility of exploiting the
|
||||
CVE-2022-1705, CVE-2022-32148, CVE-2022-30631, and other Go vulnerabilities
|
||||
fixed in [Go 1.17.12][go-1.17.12].
|
||||
|
||||
<!--
|
||||
TODO(a.garipov): Use the above format in all similar announcements below.
|
||||
-->
|
||||
|
||||
### Fixed
|
||||
|
||||
- DHCP lease validation incorrectly letting users assign the IP address of the
|
||||
gateway as the address of the lease ([#4698]).
|
||||
- Updater no longer expects a hardcoded name for `AdGuardHome` executable
|
||||
([#4219]).
|
||||
- Inconsistent names of runtime clients from hosts files ([#4683]).
|
||||
- PTR requests for addresses leased by DHCP will now be resolved into hostnames
|
||||
under `dhcp.local_domain_name` ([#4699]).
|
||||
- Broken service installation on OpenWrt ([#4677]).
|
||||
|
||||
[#4219]: https://github.com/AdguardTeam/AdGuardHome/issues/4219
|
||||
[#4677]: https://github.com/AdguardTeam/AdGuardHome/issues/4677
|
||||
[#4683]: https://github.com/AdguardTeam/AdGuardHome/issues/4683
|
||||
[#4698]: https://github.com/AdguardTeam/AdGuardHome/issues/4698
|
||||
[#4699]: https://github.com/AdguardTeam/AdGuardHome/issues/4699
|
||||
|
||||
[go-1.17.12]: https://groups.google.com/g/golang-announce/c/nqrv9fbR0zE
|
||||
[ms-v0.107.8]: https://github.com/AdguardTeam/AdGuardHome/milestone/44?closed=1
|
||||
|
||||
|
||||
|
||||
## [v0.107.7] - 2022-06-06
|
||||
|
||||
See also the [v0.107.7 GitHub milestone][ms-v0.107.7].
|
||||
|
||||
### Security
|
||||
|
||||
- Go version was updated to prevent the possibility of exploiting the
|
||||
[CVE-2022-29526], [CVE-2022-30634], [CVE-2022-30629], [CVE-2022-30580], and
|
||||
[CVE-2022-29804] Go vulnerabilities.
|
||||
- Enforced password strength policy ([#3503]).
|
||||
|
||||
### Added
|
||||
|
||||
- Support for the final DNS-over-QUIC standard, [RFC 9250][rfc-9250] ([#4592]).
|
||||
- Support upstreams for subdomains of a domain only ([#4503]).
|
||||
- The ability to control each source of runtime clients separately via
|
||||
`clients.runtime_sources` configuration object ([#3020]).
|
||||
- The ability to customize the set of networks that are considered private
|
||||
through the new `dns.private_networks` property in the configuration file
|
||||
([#3142]).
|
||||
- EDNS Client-Subnet information in the request details section of a query log
|
||||
record ([#3978]).
|
||||
- Support for hostnames for plain UDP upstream servers using the `udp://` scheme
|
||||
([#4166]).
|
||||
- Logs are now collected by default on FreeBSD and OpenBSD when AdGuard Home is
|
||||
installed as a service ([#4213]).
|
||||
- `windows/arm64` support ([#3057]).
|
||||
|
||||
### Changed
|
||||
|
||||
- On OpenBSD, the daemon script now uses the recommended `/bin/ksh` shell
|
||||
instead of the `/bin/sh` one ([#4533]). To apply this change, backup your
|
||||
data and run `AdGuardHome -s uninstall && AdGuardHome -s install`.
|
||||
- The default DNS-over-QUIC port number is now `853` instead of `754` in
|
||||
accordance with [RFC 9250][rfc-9250] ([#4276]).
|
||||
- Reverse DNS now has a greater priority as the source of runtime clients'
|
||||
informmation than ARP neighborhood.
|
||||
information than ARP neighborhood.
|
||||
- Improved detection of runtime clients through more resilient ARP processing
|
||||
([#3597]).
|
||||
- The TTL of responses served from the optimistic cache is now lowered to 10
|
||||
@@ -47,16 +131,44 @@ and this project adheres to
|
||||
of the commit from which the binary was built ([#4221]). This should simplify
|
||||
reproducible builds for package maintainers and those who compile their own
|
||||
AdGuard Home.
|
||||
- The setting `local_domain_name` is now in the `dhcp` block in the
|
||||
- The property `local_domain_name` is now in the `dhcp` object in the
|
||||
configuration file to avoid confusion ([#3367]).
|
||||
- The `dns.bogus_nxdomain` configuration file parameter now supports CIDR
|
||||
- The `dns.bogus_nxdomain` property in the configuration file now supports CIDR
|
||||
notation alongside IP addresses ([#1730]).
|
||||
|
||||
#### Configuration Changes
|
||||
|
||||
In this release, the schema version has changed from 12 to 13.
|
||||
In this release, the schema version has changed from 12 to 14.
|
||||
|
||||
- Parameter `local_domain_name`, which in schema versions 12 and earlier used to
|
||||
- Object `clients`, which in schema versions 13 and earlier was an array of
|
||||
actual persistent clients, is now consist of `persistent` and
|
||||
`runtime_sources` properties:
|
||||
|
||||
```yaml
|
||||
# BEFORE:
|
||||
'clients':
|
||||
- name: client-name
|
||||
# …
|
||||
|
||||
# AFTER:
|
||||
'clients':
|
||||
'persistent':
|
||||
- name: client-name
|
||||
# …
|
||||
'runtime_sources':
|
||||
whois: true
|
||||
arp: true
|
||||
rdns: true
|
||||
dhcp: true
|
||||
hosts: true
|
||||
```
|
||||
|
||||
The value for `clients.runtime_sources.rdns` field is taken from
|
||||
`dns.resolve_clients` property. To rollback this change, remove the
|
||||
`runtime_sources` property, move the contents of `persistent` into the
|
||||
`clients` itself, the value of `clients.runtime_sources.rdns` into the
|
||||
`dns.resolve_clients`, and change the `schema_version` back to `13`.
|
||||
- Property `local_domain_name`, which in schema versions 12 and earlier used to
|
||||
be a part of the `dns` object, is now a part of the `dhcp` object:
|
||||
|
||||
```yaml
|
||||
@@ -71,28 +183,28 @@ In this release, the schema version has changed from 12 to 13.
|
||||
'local_domain_name': 'lan'
|
||||
```
|
||||
|
||||
To rollback this change, move the parameter back into `dns` and change the
|
||||
`schema_version` back to `12`.
|
||||
To rollback this change, move the property back into the `dns` object and
|
||||
change the `schema_version` back to `12`.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Go 1.17 support. v0.109.0 will require at least Go 1.18 to build.
|
||||
- The `--no-etc-hosts` option. Its functionality is now controlled by
|
||||
`clients.runtime_sources.hosts` configuration property. v0.109.0 will remove
|
||||
the flag completely.
|
||||
|
||||
### Removed
|
||||
### Fixed
|
||||
|
||||
- Go 1.16 support.
|
||||
|
||||
### Security
|
||||
|
||||
- `User-Agent` HTTP header removed from outcoming DNS-over-HTTPS requests.
|
||||
- Enforced password strength policy ([#3503]).
|
||||
- Weaker cipher suites that use the CBC (cipher block chaining) mode of
|
||||
operation have been disabled ([#2993]).
|
||||
- Query log occasionally going into an infinite loop ([#4591]).
|
||||
- Service startup on boot on systems using SysV-init ([#4480]).
|
||||
- Detection of the stopped service status on macOS and Linux ([#4273]).
|
||||
- Case-sensitive ClientID ([#4542]).
|
||||
- Slow version update queries making other HTTP APIs unresponsive ([#4499]).
|
||||
- ARP tables refreshing process causing excessive PTR requests ([#3157]).
|
||||
|
||||
[#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730
|
||||
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
|
||||
[#3057]: https://github.com/AdguardTeam/AdGuardHome/issues/3057
|
||||
[#3020]: https://github.com/AdguardTeam/AdGuardHome/issues/3020
|
||||
[#3142]: https://github.com/AdguardTeam/AdGuardHome/issues/3142
|
||||
[#3157]: https://github.com/AdguardTeam/AdGuardHome/issues/3157
|
||||
[#3367]: https://github.com/AdguardTeam/AdGuardHome/issues/3367
|
||||
[#3381]: https://github.com/AdguardTeam/AdGuardHome/issues/3381
|
||||
[#3503]: https://github.com/AdguardTeam/AdGuardHome/issues/3503
|
||||
@@ -100,21 +212,94 @@ In this release, the schema version has changed from 12 to 13.
|
||||
[#3978]: https://github.com/AdguardTeam/AdGuardHome/issues/3978
|
||||
[#4166]: https://github.com/AdguardTeam/AdGuardHome/issues/4166
|
||||
[#4213]: https://github.com/AdguardTeam/AdGuardHome/issues/4213
|
||||
[#4216]: https://github.com/AdguardTeam/AdGuardHome/issues/4216
|
||||
[#4221]: https://github.com/AdguardTeam/AdGuardHome/issues/4221
|
||||
[#4238]: https://github.com/AdguardTeam/AdGuardHome/issues/4238
|
||||
[#4273]: https://github.com/AdguardTeam/AdGuardHome/issues/4273
|
||||
[#4276]: https://github.com/AdguardTeam/AdGuardHome/issues/4276
|
||||
[#4480]: https://github.com/AdguardTeam/AdGuardHome/issues/4480
|
||||
[#4499]: https://github.com/AdguardTeam/AdGuardHome/issues/4499
|
||||
[#4503]: https://github.com/AdguardTeam/AdGuardHome/issues/4503
|
||||
[#4533]: https://github.com/AdguardTeam/AdGuardHome/issues/4533
|
||||
[#4542]: https://github.com/AdguardTeam/AdGuardHome/issues/4542
|
||||
[#4591]: https://github.com/AdguardTeam/AdGuardHome/issues/4591
|
||||
[#4592]: https://github.com/AdguardTeam/AdGuardHome/issues/4592
|
||||
|
||||
[repr]: https://reproducible-builds.org/docs/source-date-epoch/
|
||||
[CVE-2022-29526]: https://www.cvedetails.com/cve/CVE-2022-29526
|
||||
[CVE-2022-29804]: https://www.cvedetails.com/cve/CVE-2022-29804
|
||||
[CVE-2022-30580]: https://www.cvedetails.com/cve/CVE-2022-30580
|
||||
[CVE-2022-30629]: https://www.cvedetails.com/cve/CVE-2022-30629
|
||||
[CVE-2022-30634]: https://www.cvedetails.com/cve/CVE-2022-30634
|
||||
[ms-v0.107.7]: https://github.com/AdguardTeam/AdGuardHome/milestone/43?closed=1
|
||||
[rfc-9250]: https://datatracker.ietf.org/doc/html/rfc9250
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
## [v0.107.5] - 2022-04-04 (APPROX.)
|
||||
## [v0.107.6] - 2022-04-13
|
||||
|
||||
See also the [v0.107.5 GitHub milestone][ms-v0.107.5].
|
||||
See also the [v0.107.6 GitHub milestone][ms-v0.107.6].
|
||||
|
||||
[ms-v0.107.5]: https://github.com/AdguardTeam/AdGuardHome/milestone/42?closed=1
|
||||
-->
|
||||
### Security
|
||||
|
||||
- `User-Agent` HTTP header removed from outgoing DNS-over-HTTPS requests.
|
||||
- Go version was updated to prevent the possibility of exploiting the
|
||||
[CVE-2022-24675], [CVE-2022-27536], and [CVE-2022-28327] Go vulnerabilities.
|
||||
|
||||
### Added
|
||||
|
||||
- Support for SVCB/HTTPS parameter `dohpath` in filtering rules with
|
||||
the `dnsrewrite` modifier according to the [RFC draft][dns-draft-02]
|
||||
([#4463]).
|
||||
|
||||
### Changed
|
||||
|
||||
- Filtering rules with the `dnsrewrite` modifier that create SVCB or HTTPS
|
||||
responses should use `ech` instead of `echconfig` to conform with the [latest
|
||||
drafts][svcb-draft-08].
|
||||
|
||||
### Deprecated
|
||||
|
||||
- SVCB/HTTPS parameter name `echconfig` in filtering rules with the `dnsrewrite`
|
||||
modifier. Use `ech` instead. v0.109.0 will remove support for the outdated
|
||||
name `echconfig`.
|
||||
- Obsolete `--no-mem-optimization` option ([#4437]). v0.109.0 will remove the
|
||||
flag completely.
|
||||
|
||||
### Fixed
|
||||
|
||||
- I/O timeout errors when checking for the presence of another DHCP server.
|
||||
- Network interfaces being incorrectly labeled as down during installation.
|
||||
- Rules for blocking the QQ service ([#3717]).
|
||||
|
||||
### Removed
|
||||
|
||||
- Go 1.16 support, since that branch of the Go compiler has reached end of life
|
||||
and doesn't receive security updates anymore.
|
||||
|
||||
[#3717]: https://github.com/AdguardTeam/AdGuardHome/issues/3717
|
||||
[#4437]: https://github.com/AdguardTeam/AdGuardHome/issues/4437
|
||||
[#4463]: https://github.com/AdguardTeam/AdGuardHome/issues/4463
|
||||
|
||||
[CVE-2022-24675]: https://www.cvedetails.com/cve/CVE-2022-24675
|
||||
[CVE-2022-27536]: https://www.cvedetails.com/cve/CVE-2022-27536
|
||||
[CVE-2022-28327]: https://www.cvedetails.com/cve/CVE-2022-28327
|
||||
[dns-draft-02]: https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02#section-5.1
|
||||
[ms-v0.107.6]: https://github.com/AdguardTeam/AdGuardHome/milestone/42?closed=1
|
||||
[repr]: https://reproducible-builds.org/docs/source-date-epoch/
|
||||
[svcb-draft-08]: https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html
|
||||
|
||||
|
||||
|
||||
## [v0.107.5] - 2022-03-04
|
||||
|
||||
This is a security update. There is no GitHub milestone, since no GitHub issues
|
||||
were resolved.
|
||||
|
||||
### Security
|
||||
|
||||
- Go version was updated to prevent the possibility of exploiting the
|
||||
[CVE-2022-24921] Go vulnerability.
|
||||
|
||||
[CVE-2022-24921]: https://www.cvedetails.com/cve/CVE-2022-24921
|
||||
|
||||
|
||||
|
||||
@@ -122,6 +307,11 @@ See also the [v0.107.5 GitHub milestone][ms-v0.107.5].
|
||||
|
||||
See also the [v0.107.4 GitHub milestone][ms-v0.107.4].
|
||||
|
||||
### Security
|
||||
|
||||
- Go version was updated to prevent the possibility of exploiting the
|
||||
[CVE-2022-23806], [CVE-2022-23772], and [CVE-2022-23773] Go vulnerabilities.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Optimistic cache now responds with expired items even if those can't be
|
||||
@@ -129,11 +319,6 @@ See also the [v0.107.4 GitHub milestone][ms-v0.107.4].
|
||||
- Unnecessarily complex hosts-related logic leading to infinite recursion in
|
||||
some cases ([#4216]).
|
||||
|
||||
### Security
|
||||
|
||||
- Go version was updated to prevent the possibility of exploiting
|
||||
[CVE-2022-23806], [CVE-2022-23772], and [CVE-2022-23773].
|
||||
|
||||
[#4216]: https://github.com/AdguardTeam/AdGuardHome/issues/4216
|
||||
[#4254]: https://github.com/AdguardTeam/AdGuardHome/issues/4254
|
||||
|
||||
@@ -150,7 +335,7 @@ See also the [v0.107.3 GitHub milestone][ms-v0.107.3].
|
||||
|
||||
### Added
|
||||
|
||||
- Support for a `$dnsrewrite` modifier with an empty `NOERROR` response
|
||||
- Support for a `dnsrewrite` modifier with an empty `NOERROR` response
|
||||
([#4133]).
|
||||
|
||||
### Fixed
|
||||
@@ -231,15 +416,15 @@ See also the [v0.107.0 GitHub milestone][ms-v0.107.0].
|
||||
through the new `fastest_timeout` field in the configuration file ([#1992]).
|
||||
- Static IP address detection on FreeBSD ([#3289]).
|
||||
- Optimistic cache ([#2145]).
|
||||
- New possible value of `6h` for `querylog_interval` setting ([#2504]).
|
||||
- New possible value of `6h` for `querylog_interval` property ([#2504]).
|
||||
- Blocking access using ClientIDs ([#2624], [#3162]).
|
||||
- `source` directives support in `/etc/network/interfaces` on Linux ([#3257]).
|
||||
- RFC 9000 support in DNS-over-QUIC.
|
||||
- [RFC 9000][rfc-9000] support in QUIC.
|
||||
- Completely disabling statistics by setting the statistics interval to zero
|
||||
([#2141]).
|
||||
- The ability to completely purge DHCP leases ([#1691]).
|
||||
- Settable timeouts for querying the upstream servers ([#2280]).
|
||||
- Configuration file parameters to change group and user ID on startup on Unix
|
||||
- Configuration file properties to change group and user ID on startup on Unix
|
||||
([#2763]).
|
||||
- Experimental OpenBSD support for AMD64 and 64-bit ARM CPUs ([#2439], [#3225],
|
||||
[#3226]).
|
||||
@@ -266,7 +451,7 @@ See also the [v0.107.0 GitHub milestone][ms-v0.107.0].
|
||||
- Better error message for ED25519 private keys, which are not widely supported
|
||||
([#3737]).
|
||||
- Cache now follows RFC more closely for negative answers ([#3707]).
|
||||
- `$dnsrewrite` rules and other DNS rewrites will now be applied even when the
|
||||
- `dnsrewrite` rules and other DNS rewrites will now be applied even when the
|
||||
protection is disabled ([#1558]).
|
||||
- DHCP gateway address, subnet mask, IP address range, and leases validations
|
||||
([#3529]).
|
||||
@@ -282,22 +467,22 @@ See also the [v0.107.0 GitHub milestone][ms-v0.107.0].
|
||||
proxy ([#2799]).
|
||||
- Clients who are blocked by access settings now receive a `REFUSED` response
|
||||
when a protocol other than DNS-over-UDP and DNSCrypt is used.
|
||||
- `querylog_interval` setting is now formatted in hours.
|
||||
- `dns.querylog_interval` property is now formatted in hours.
|
||||
- Query log search now supports internationalized domains ([#3012]).
|
||||
- Internationalized domains are now shown decoded in the query log with the
|
||||
original encoded version shown in request details ([#3013]).
|
||||
- When /etc/hosts-type rules have several IPs for one host, all IPs are now
|
||||
returned instead of only the first one ([#1381]).
|
||||
- The setting `rlimit_nofile` is now in the `os` block of the configuration
|
||||
file, together with the new `group` and `user` settings ([#2763]).
|
||||
- Property `rlimit_nofile` is now in the `os` object of the configuration
|
||||
file, together with the new `group` and `user` properties ([#2763]).
|
||||
- Permissions on filter files are now `0o644` instead of `0o600` ([#3198]).
|
||||
|
||||
#### Configuration Changes
|
||||
|
||||
In this release, the schema version has changed from 10 to 12.
|
||||
|
||||
- Parameter `dns.querylog_interval`, which in schema versions 11 and earlier
|
||||
used to be an integer number of days, is now a string with a human-readable
|
||||
- Property `dns.querylog_interval`, which in schema versions 11 and earlier used
|
||||
to be an integer number of days, is now a string with a human-readable
|
||||
duration:
|
||||
|
||||
```yaml
|
||||
@@ -312,10 +497,10 @@ In this release, the schema version has changed from 10 to 12.
|
||||
'querylog_interval': '2160h'
|
||||
```
|
||||
|
||||
To rollback this change, convert the parameter back into days and change the
|
||||
To rollback this change, convert the property back into days and change the
|
||||
`schema_version` back to `11`.
|
||||
|
||||
- Parameter `rlimit_nofile`, which in schema versions 10 and earlier used to be
|
||||
- Property `rlimit_nofile`, which in schema versions 10 and earlier used to be
|
||||
on the top level, is now moved to the new `os` object:
|
||||
|
||||
```yaml
|
||||
@@ -329,7 +514,7 @@ In this release, the schema version has changed from 10 to 12.
|
||||
'user': ''
|
||||
```
|
||||
|
||||
To rollback this change, move the parameter on the top level and change the
|
||||
To rollback this change, move the property on the top level and change the
|
||||
`schema_version` back to `10`.
|
||||
|
||||
### Deprecated
|
||||
@@ -339,7 +524,7 @@ In this release, the schema version has changed from 10 to 12.
|
||||
### Fixed
|
||||
|
||||
- EDNS0 TCP keepalive option handling ([#3778]).
|
||||
- Rules with the `$denyallow` modifier applying to IP addresses when they
|
||||
- Rules with the `denyallow` modifier applying to IP addresses when they
|
||||
shouldn't ([#3175]).
|
||||
- The length of the EDNS0 client subnet option appearing too long for some
|
||||
upstream servers ([#3887]).
|
||||
@@ -347,8 +532,8 @@ In this release, the schema version has changed from 10 to 12.
|
||||
settings ([#3558]).
|
||||
- Incomplete propagation of the client's IP anonymization setting to the
|
||||
statistics ([#3890]).
|
||||
- Incorrect `$dnsrewrite` results for entries from the operating system's hosts
|
||||
file ([#3815]).
|
||||
- Incorrect results with the `dnsrewrite` modifier for entries from the
|
||||
operating system's hosts file ([#3815]).
|
||||
- Matching against rules with `|` at the end of the domain name ([#3371]).
|
||||
- Incorrect assignment of explicitly configured DHCP options ([#3744]).
|
||||
- Occasional panic during shutdown ([#3655]).
|
||||
@@ -375,8 +560,8 @@ In this release, the schema version has changed from 10 to 12.
|
||||
- Letter case mismatches in `CNAME` filtering ([#3335]).
|
||||
- Occasional breakages on network errors with DNS-over-HTTP upstreams ([#3217]).
|
||||
- Errors when setting static IP on Linux ([#3257]).
|
||||
- Treatment of domain names and FQDNs in custom rules with `$dnsrewrite` that
|
||||
use the `PTR` type ([#3256]).
|
||||
- Treatment of domain names and FQDNs in custom rules with the `dnsrewrite`
|
||||
modifier that use the `PTR` type ([#3256]).
|
||||
- Redundant hostname generating while loading static leases with empty hostname
|
||||
([#3166]).
|
||||
- Domain name case in responses ([#3194]).
|
||||
@@ -459,6 +644,7 @@ In this release, the schema version has changed from 10 to 12.
|
||||
[#3933]: https://github.com/AdguardTeam/AdGuardHome/pull/3933
|
||||
|
||||
[ms-v0.107.0]: https://github.com/AdguardTeam/AdGuardHome/milestone/23?closed=1
|
||||
[rfc-9000]: https://datatracker.ietf.org/doc/html/rfc9000
|
||||
|
||||
|
||||
|
||||
@@ -539,7 +725,7 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0].
|
||||
|
||||
- The ability to block user for login after configurable number of unsuccessful
|
||||
attempts for configurable time ([#2826]).
|
||||
- `$denyallow` modifier for filters ([#2923]).
|
||||
- `denyallow` modifier for filters ([#2923]).
|
||||
- Hostname uniqueness validation in the DHCP server ([#2952]).
|
||||
- Hostname generating for DHCP clients which don't provide their own ([#2723]).
|
||||
- New flag `--no-etc-hosts` to disable client domain name lookups in the
|
||||
@@ -554,7 +740,8 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0].
|
||||
network ([#2393], [#2961]).
|
||||
- The ability to serve DNS queries on multiple hosts and interfaces ([#1401]).
|
||||
- `ips` and `text` DHCP server options ([#2385]).
|
||||
- `SRV` records support in `$dnsrewrite` filters ([#2533]).
|
||||
- `SRV` records support in filtering rules with the `dnsrewrite` modifier
|
||||
([#2533]).
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -568,7 +755,8 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0].
|
||||
([#2704]).
|
||||
- Stricter validation of the IP addresses of static leases in the DHCP server
|
||||
with regards to the netmask ([#2838]).
|
||||
- Stricter validation of `$dnsrewrite` filter modifier parameters ([#2498]).
|
||||
- Stricter validation of `dnsrewrite` filtering rule modifier parameters
|
||||
([#2498]).
|
||||
- New, more correct versioning scheme ([#2412]).
|
||||
|
||||
### Deprecated
|
||||
@@ -577,7 +765,7 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0].
|
||||
|
||||
### Fixed
|
||||
|
||||
- Multiple answers for `$dnsrewrite` rule matching requests with repeating
|
||||
- Multiple answers for a `dnsrewrite` rule matching requests with repeating
|
||||
patterns in it ([#2981]).
|
||||
- Root server resolving when custom upstreams for hosts are specified ([#2994]).
|
||||
- Inconsistent resolving of DHCP clients when the DHCP server is disabled
|
||||
@@ -629,6 +817,10 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0].
|
||||
|
||||
## [v0.105.2] - 2021-03-10
|
||||
|
||||
### Security
|
||||
|
||||
- Session token doesn't contain user's information anymore ([#2470]).
|
||||
|
||||
See also the [v0.105.2 GitHub milestone][ms-v0.105.2].
|
||||
|
||||
### Fixed
|
||||
@@ -642,10 +834,6 @@ See also the [v0.105.2 GitHub milestone][ms-v0.105.2].
|
||||
- Incomplete DNS upstreams validation ([#2674]).
|
||||
- Wrong parsing of DHCP options of the `ip` type ([#2688]).
|
||||
|
||||
### Security
|
||||
|
||||
- Session token doesn't contain user's information anymore ([#2470]).
|
||||
|
||||
[#2470]: https://github.com/AdguardTeam/AdGuardHome/issues/2470
|
||||
[#2582]: https://github.com/AdguardTeam/AdGuardHome/issues/2582
|
||||
[#2600]: https://github.com/AdguardTeam/AdGuardHome/issues/2600
|
||||
@@ -681,8 +869,8 @@ See also the [v0.105.1 GitHub milestone][ms-v0.105.1].
|
||||
- Occasional crashes during startup.
|
||||
- The field `"range_start"` in the `GET /control/dhcp/status` HTTP API response
|
||||
is now correctly named again ([#2678]).
|
||||
- DHCPv6 server's `ra_slaac_only` and `ra_allow_slaac` settings aren't reset to
|
||||
`false` on update anymore ([#2653]).
|
||||
- DHCPv6 server's `ra_slaac_only` and `ra_allow_slaac` properties aren't reset
|
||||
to `false` on update anymore ([#2653]).
|
||||
- The `Vary` header is now added along with `Access-Control-Allow-Origin` to
|
||||
prevent cache-related and other issues in browsers ([#2658]).
|
||||
- The request body size limit is now set for HTTPS requests as well.
|
||||
@@ -716,7 +904,7 @@ See also the [v0.105.0 GitHub milestone][ms-v0.105.0].
|
||||
- `ipset` subdomain matching, just like `dnsmasq` does ([#2179]).
|
||||
- ClientID support for DNS-over-HTTPS, DNS-over-QUIC, and DNS-over-TLS
|
||||
([#1383]).
|
||||
- `$dnsrewrite` modifier for filters ([#2102]).
|
||||
- The new `dnsrewrite` modifier for filters ([#2102]).
|
||||
- The host checking API and the query logs API can now return multiple matched
|
||||
rules ([#2102]).
|
||||
- Detecting of network interface configured to have static IP address via
|
||||
@@ -724,7 +912,7 @@ See also the [v0.105.0 GitHub milestone][ms-v0.105.0].
|
||||
- DNSCrypt protocol support ([#1361]).
|
||||
- A 5 second wait period until a DHCP server's network interface gets an IP
|
||||
address ([#2304]).
|
||||
- `$dnstype` modifier for filters ([#2337]).
|
||||
- `dnstype` modifier for filters ([#2337]).
|
||||
- HTTP API request body size limit ([#2305]).
|
||||
|
||||
### Changed
|
||||
@@ -857,13 +1045,16 @@ See also the [v0.104.2 GitHub milestone][ms-v0.104.2].
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.5...HEAD
|
||||
[v0.107.5]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.4...v0.107.5
|
||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.9...HEAD
|
||||
[v0.107.9]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.8...v0.107.9
|
||||
-->
|
||||
|
||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.4...HEAD
|
||||
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.8...HEAD
|
||||
[v0.107.8]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.7...v0.107.8
|
||||
[v0.107.7]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.6...v0.107.7
|
||||
[v0.107.6]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.5...v0.107.6
|
||||
[v0.107.5]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.4...v0.107.5
|
||||
[v0.107.4]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.3...v0.107.4
|
||||
[v0.107.3]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.2...v0.107.3
|
||||
[v0.107.2]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.1...v0.107.2
|
||||
|
||||
2
Makefile
2
Makefile
@@ -17,6 +17,7 @@ DIST_DIR = dist
|
||||
# See https://unix.stackexchange.com/q/646255/105635.
|
||||
GO.MACRO = $${GO:-go}
|
||||
GOPROXY = https://goproxy.cn|https://proxy.golang.org|direct
|
||||
GOSUMDB = sum.golang.google.cn
|
||||
GPG_KEY = devteam@adguard.com
|
||||
GPG_KEY_PASSPHRASE = not-a-real-password
|
||||
NPM = npm
|
||||
@@ -56,6 +57,7 @@ ENV = env\
|
||||
DIST_DIR='$(DIST_DIR)'\
|
||||
GO="$(GO.MACRO)"\
|
||||
GOPROXY='$(GOPROXY)'\
|
||||
GOSUMDB='$(GOSUMDB)'\
|
||||
PATH="$${PWD}/bin:$$( "$(GO.MACRO)" env GOPATH )/bin:$${PATH}"\
|
||||
RACE='$(RACE)'\
|
||||
SIGN='$(SIGN)'\
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# Make sure to sync any changes with the branch overrides below.
|
||||
'variables':
|
||||
'channel': 'edge'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.2'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.5'
|
||||
|
||||
'stages':
|
||||
- 'Make release':
|
||||
@@ -183,8 +183,27 @@
|
||||
|
||||
cd ./dist/
|
||||
|
||||
channel="${bamboo.channel}"
|
||||
readonly channel
|
||||
case "$channel"
|
||||
in
|
||||
('release')
|
||||
snapchannel='candidate'
|
||||
;;
|
||||
('beta')
|
||||
snapchannel='beta'
|
||||
;;
|
||||
('edge')
|
||||
snapchannel='edge'
|
||||
;;
|
||||
(*)
|
||||
echo "invalid channel '$channel'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
env\
|
||||
SNAPCRAFT_CHANNEL=edge\
|
||||
SNAPCRAFT_CHANNEL="$snapchannel"\
|
||||
SNAPCRAFT_EMAIL="${bamboo.snapcraftEmail}"\
|
||||
SNAPCRAFT_MACAROON="${bamboo.snapcraftMacaroonPassword}"\
|
||||
SNAPCRAFT_UBUNTU_DISCHARGE="${bamboo.snapcraftUbuntuDischargePassword}"\
|
||||
@@ -266,7 +285,7 @@
|
||||
# need to build a few of these.
|
||||
'variables':
|
||||
'channel': 'beta'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.2'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.5'
|
||||
# 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 +300,4 @@
|
||||
# are the ones that actually get released.
|
||||
'variables':
|
||||
'channel': 'release'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.2'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.5'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'key': 'AHBRTSPECS'
|
||||
'name': 'AdGuard Home - Build and run tests'
|
||||
'variables':
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.2'
|
||||
'dockerGo': 'adguard/golang-ubuntu:4.5'
|
||||
|
||||
'stages':
|
||||
- 'Tests':
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Няслушнае імя сервера",
|
||||
"form_error_subnet": "Падсетка «{{cidr}}» не ўтрымвае IP-адраса «{{ip}}»",
|
||||
"form_error_positive": "Павінна быць больш 0",
|
||||
"form_error_gateway_ip": "Арэнда не можа мець IP-адрас шлюза",
|
||||
"out_of_range_error": "Павінна быць па-за дыяпазонам «{{start}}»-«{{end}}»",
|
||||
"lower_range_start_error": "Павінна быць менш за пачатак дыяпазону",
|
||||
"greater_range_start_error": "Павінна быць больш за пачатак дыяпазону",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "звычайны DNS (праз UDP, імя хаста);",
|
||||
"example_upstream_dot": "зашыфраваны <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "зашыфраваны <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "зашыфраваны <0>DNS-over-QUIC (эксперыментальны)</0>;",
|
||||
"example_upstream_doq": "зашыфраваны <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> для <1>DNSCrypt</1> ці <2>DNS-over-HTTPS</2> рэзалвераў;",
|
||||
"example_upstream_tcp": "звычайны DNS (наўзверх TCP);",
|
||||
"example_upstream_tcp_hostname": "звычайны DNS (праз TCP, імя хаста);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Калі порт HTTPS наладжаны, ўэб-інтэрфейс адміністравання AdGuard Home будзе даступны праз HTTPS, а таксама DNS-over-HTTPS сервер будзе даступны па шляху '/dns-query'.",
|
||||
"encryption_dot": "Порт DNS-over-TLS",
|
||||
"encryption_dot_desc": "Калі гэты порт наладжаны, AdGuard Home запусціць DNS-over-TLS-сервер на гэтаму порту.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC (эксперыментальны)",
|
||||
"encryption_doq_desc": "Калі гэты порт наладжаны, AdGuard Home запусціць сервер DNS-over-QUIC на гэтым порце. Гэта эксперыментальна і можа быць ненадзейна. Апроч таго, не так шмат кліентаў падтрымвае гэты спосаб цяпер.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Калі гэты порт наладжаны, AdGuard Home запусціць сервер DNS-over-QUIC на гэтым порце.",
|
||||
"encryption_certificates": "Сертыфікаты",
|
||||
"encryption_certificates_desc": "Для выкарыстання шыфравання вам трэба падаць валідны ланцужок SSL-сертыфікатаў для вашага дамена. Вы можаце атрымаць дармовы сертыфікат на <0>{{link}}</0> ці вы можаце купіць яго ў аднаго з давераных Цэнтраў Сертыфікацыі.",
|
||||
"encryption_certificates_input": "Скапіюйце сюды сертыфікаты ў PEM-кадоўцы.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Заблакаваныя дамены",
|
||||
"access_blocked_desc": "Не блытайце гэта з фільтрамі. AdGuard Home будзе ігнараваць DNS-запыты з гэтымі даменамі.",
|
||||
"access_settings_saved": "Налады доступу паспяхова захаваны",
|
||||
"updates_checked": "Праверка абнаўленняў прайшла паспяхова",
|
||||
"updates_checked": "Даступная новая версія AdGuard Home",
|
||||
"updates_version_equal": "Версія AdGuard Home актуальная",
|
||||
"check_updates_now": "Праверыць абнаўленні",
|
||||
"dns_privacy": "Зашыфраваны DNS",
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
{
|
||||
"client_settings": "Kлиентски настройки",
|
||||
"example_upstream_comment": "Можете да поставите коментар",
|
||||
"load_balancing": "Балансиране на натоварването",
|
||||
"check_dhcp_servers": "Проверка за активен DHCP сървър",
|
||||
"save_config": "Запиши настройките",
|
||||
"enabled_dhcp": "DHCP е разрешен",
|
||||
"disabled_dhcp": "DHCP е забранен",
|
||||
"dhcp_title": "DHCP сървър (тестови!)",
|
||||
"dhcp_description": "Ако рутера ви не раздава DHCP адреси, може да използвате вградения в AdGuard DHCP сървър.",
|
||||
"dhcp_enable": "Рзреши DHCP сървъра",
|
||||
"dhcp_disable": "Забрани DHCP сървъра",
|
||||
"dhcp_not_found": "Вашата мрежа няма активен DHCP сървър. Безопасно е ползването на вградения DHCP сървър.",
|
||||
"dhcp_found": "Вашата мрежа вече има активен DHCP сървър. Не е безопасно ползването на втори!",
|
||||
"dhcp_leases": "DHCP раздадени адреси",
|
||||
"dhcp_leases_not_found": "Няма намерени активни DHCP адреси",
|
||||
"dhcp_config_saved": "Запиши конфигурацията на DHCP сървъра",
|
||||
"form_error_required": "Задължително поле",
|
||||
"form_error_ip_format": "Невалиден IP адрес",
|
||||
"form_error_ip_format": "Невалиден IPv4 адрес",
|
||||
"form_error_positive": "Проверете дали е положително число",
|
||||
"dhcp_form_gateway_input": "IP шлюз",
|
||||
"dhcp_form_subnet_input": "Мрежова маска",
|
||||
@@ -24,15 +30,21 @@
|
||||
"dhcp_ip_addresses": "IP адреси",
|
||||
"dhcp_table_hostname": "Име на устройство",
|
||||
"dhcp_table_expires": "История",
|
||||
"dhcp_warning": "Ако искате да използвате вградения DHCP сървър, трябва да няма друг активен DHCP в мрежата Ви!",
|
||||
"country": "Държава",
|
||||
"city": "Град",
|
||||
"delete_confirm": "Наистина ли искате да изтриете \"{{key}}\"?",
|
||||
"error_details": "Подробности за грешка",
|
||||
"response_details": "Подробности за отговора",
|
||||
"request_details": "Поискайте подробности",
|
||||
"details": "Детайли",
|
||||
"back": "Назад",
|
||||
"dashboard": "Табло",
|
||||
"settings": "Настройки",
|
||||
"filters": "Филтри",
|
||||
"filter": "Филтър",
|
||||
"query_log": "История на заявките",
|
||||
"compact": "Compact",
|
||||
"faq": "ЧЗВ",
|
||||
"version": "версия",
|
||||
"address": "Адрес",
|
||||
@@ -60,7 +72,12 @@
|
||||
"top_clients": "Най-активни IP адреси",
|
||||
"no_clients_found": "Нямa намерени адреси",
|
||||
"general_statistics": "Обща статисика",
|
||||
"number_of_dns_query_24_hours": "Сума на DNS заявки за последните 24 часа",
|
||||
"number_of_dns_query_blocked_24_hours": "Сума на блокирани DNS заявки от филтрите за реклама и местни",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "Сума на блокирани DNS заявки от AdGuard свързани със сигурността",
|
||||
"number_of_dns_query_blocked_24_hours_adult": "Сума на блокирани сайтове за възрастни",
|
||||
"enforced_save_search": "Активирано Безопасно Търсене",
|
||||
"number_of_dns_query_to_safe_search": "Сума на DNS заявки при който е приложено Безопасно Търсене",
|
||||
"average_processing_time": "Средно време за обработка",
|
||||
"average_processing_time_hint": "Средно време за обработка на DNS заявки в милисекунди",
|
||||
"block_domain_use_filters_and_hosts": "Блокирани домейни - общи и местни филтри",
|
||||
@@ -70,6 +87,7 @@
|
||||
"use_adguard_parental": "Включи AdGuard Родителски Надзор",
|
||||
"use_adguard_parental_hint": "Модул XXX в AdGuard Home ще провери дали страницата има материали за възвъстни. Използва се същия API за анонимност като при модула за Сигурност.",
|
||||
"enforce_safe_search": "Включи Безопасно Търсене",
|
||||
"enforce_save_search_hint": "AdGuard Home прилага Безопасно Търсене в следните търсачки и сайтове: Google, Youtube, Bing, и Yandex.",
|
||||
"no_servers_specified": "Няма избрани услуги",
|
||||
"general_settings": "Общи настройки",
|
||||
"custom_filtering_rules": "Местни правила за филтриране",
|
||||
@@ -106,10 +124,13 @@
|
||||
"example_comment_hash": "# Това е също коментар",
|
||||
"example_regex_meaning": "блокирай достъп до домейни който съвпадат със следното",
|
||||
"example_upstream_regular": "класически DNS (UDP протокол)",
|
||||
"example_upstream_udp": "обикновен DNS (върху UDP, име на хост);",
|
||||
"example_upstream_dot": "криптиран <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-върху-TLS</a>",
|
||||
"example_upstream_doh": "криптиран <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-върху-HTTPS</a>",
|
||||
"example_upstream_sdns": "може да ползвате <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Подписване</a> за <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> или <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-върху-HTTPS</a> сървъри",
|
||||
"example_upstream_tcp": "класически DNS (TCP протокол)",
|
||||
"example_upstream_tcp_hostname": "обикновен DNS (върху TCP, име на хост);",
|
||||
"updated_upstream_dns_toast": "Глобалните DNS сървъри са обновени",
|
||||
"dns_test_ok_toast": "Въведените DNS сървъри работят коректно",
|
||||
"dns_test_not_ok_toast": "Сървър \"{{key}}\": не работи, моля проверете дали е въведен коректно",
|
||||
"unblock": "Отблокирай",
|
||||
@@ -135,11 +156,13 @@
|
||||
"rule_added_to_custom_filtering_toast": "Добавено до местни правила за филтриране: {{rule}}",
|
||||
"default": "По подразбиране",
|
||||
"custom_ip": "Персонализиран IP",
|
||||
"dns_over_https": "DNS-пред-HTTPS",
|
||||
"dns_over_quic": "DNS-over-QUIC",
|
||||
"plain_dns": "Обикновен DNS",
|
||||
"source_label": "Източник",
|
||||
"found_in_known_domain_db": "Намерен в списъците с домейни.",
|
||||
"category_label": "Категория",
|
||||
"rule_label": "Правило",
|
||||
"unknown_filter": "Непознат филтър {{filterId}}",
|
||||
"install_welcome_title": "Добре дошли в AdGuard Home!",
|
||||
"install_welcome_desc": "AdGuard Home e мрежово решение за блокиране на реклами и тракери на DNS ниво. Създадено е за да ви даде пълен контрол над мрежата и всичките ви устройства, без да е необходимо допълнително инсталиране на друг софтуер.",
|
||||
@@ -147,6 +170,7 @@
|
||||
"install_settings_listen": "Активни интерфейси",
|
||||
"install_settings_port": "Порт",
|
||||
"install_settings_interface_link": "Вашата AdGuard Home страница за администрация ще е достъпна на този адрес:",
|
||||
"form_error_port": "Моля въведете валиден порт",
|
||||
"install_settings_dns": "DNS сървър",
|
||||
"install_settings_dns_desc": "За да работи, ще трябва да настроите вашият рутер или устройства да ползват DNS сървър с адрес:",
|
||||
"install_settings_all_interfaces": "Всички интерфейси",
|
||||
@@ -165,6 +189,7 @@
|
||||
"install_devices_router": "Рутер",
|
||||
"install_devices_router_desc": "Ако настроите вашият рутер няма нужда ръчно да настройвате всяко едно от устрйствата в мрежата.",
|
||||
"install_devices_address": "AdGuard Home DNS сървърът е на следния адрес",
|
||||
"install_devices_router_list_1": "Отворете страницата за настройки на вашия рутер. Обикновено тя се намира на URL (тук http://192.168.0.1/ или тук http://192.168.1.1/). За достъп може да ви трябва парола. Ако сте забравили паролата може да я ресетнете като натиснета скрития ресет бутон - внимание това ще ресетне всички настройки на рутера до фабрични! Някой рутери могат да бъдате администрирани от софтуер или приложение, който би трябвало да е вече инсталиран на компютъра/телефона ви.",
|
||||
"install_devices_router_list_2": "Намерета DHCP/DNS настройки. В под раздел DHCP рзгледайте и намерете къде е полето за DNS настройка в което може да въведете персонализирани настройки за DNS сървъри.",
|
||||
"install_devices_router_list_3": "Въведете адресът на AdGuard Home сървъра.",
|
||||
"install_devices_windows_list_1": "Отворете Контролния Панел през Старт меню или чрез функция търсене на Windows.",
|
||||
@@ -192,8 +217,10 @@
|
||||
"install_saved": "Успешно записано",
|
||||
"encryption_title": "Криптиране",
|
||||
"encryption_desc": "Подържа се сигурна връзка (HTTPS/TLS) включително за DNS и страницата за администрация",
|
||||
"encryption_config_saved": "Конфигурацията е успешно записана",
|
||||
"encryption_server": "Име на сървъра",
|
||||
"encryption_server_enter": "Въведете име на домейна",
|
||||
"encryption_server_desc": "За да използвате HTTPS, трябва името на сървъра да съвпада с това на SSL сертификата.",
|
||||
"encryption_redirect": "Автоматично пренасочване към HTTPS",
|
||||
"encryption_redirect_desc": "Служи за автоматично пренасочване от HTTP към HTTPS на страницата за Администрация в AdGuard Home.",
|
||||
"encryption_https": "HTTPS порт",
|
||||
@@ -219,7 +246,9 @@
|
||||
"encryption_reset": "Сигурни ли сте че искате да изтриете настройките за криптиране?",
|
||||
"topline_expiring_certificate": "Вашият SSL сертификат изтича. Обнови <0>Настройки за криптиране</0>.",
|
||||
"topline_expired_certificate": "Вашият SSL сертификат е изтекъл. Обнови <0>Настройки за криптиране</0>.",
|
||||
"form_error_port_range": "Въведете порт в диапазона 80-65535",
|
||||
"form_error_port_unsafe": "Не е безопасно да използвате този порт",
|
||||
"form_error_equal": "Не трябва да съвпада",
|
||||
"form_error_password": "Паролата не съвпада",
|
||||
"reset_settings": "Изтрий всички настройки",
|
||||
"update_announcement": "Има нова AdGuard Home {{version}}! <0>Цъкни тук</0> за повече информация.",
|
||||
@@ -230,7 +259,11 @@
|
||||
"name": "Име",
|
||||
"clients_not_found": "Нямa намерени адреси",
|
||||
"check_updates_now": "Провери за актуализации",
|
||||
"interval_6_hour": "6 часа",
|
||||
"interval_24_hour": "24 часа",
|
||||
"domain": "Домейн",
|
||||
"ecs": "ECS",
|
||||
"statistics_clear": "Нулирай статистиката",
|
||||
"disabled": "Деактивиран",
|
||||
"username_label": "Потребител",
|
||||
"username_placeholder": "Въведете потребител",
|
||||
@@ -238,11 +271,14 @@
|
||||
"password_placeholder": "Въведете парола",
|
||||
"network": "Мрежа",
|
||||
"descr": "Описание",
|
||||
"try_again": "Опитай пак",
|
||||
"disable_ipv6": "Изключете IPv6 протокола",
|
||||
"show_blocked_responses": "Блокирано",
|
||||
"show_whitelisted_responses": "В белия списък",
|
||||
"show_processed_responses": "Обработен",
|
||||
"allowed": "В белия списък",
|
||||
"safe_search": "Безопасно търсене",
|
||||
"blocklist": "Черен списък",
|
||||
"filter_category_general": "General",
|
||||
"filter_category_security": "Сигурност",
|
||||
"port_53_faq_link": "Порт 53 често е зает от \"DNSStubListener\" или \"systemd-resolved\" услуги. Моля, прочетете <0>тази инструкция</0> как да решите това.",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS servery",
|
||||
"bootstrap_dns_desc": "Servery Bootstrap DNS se používají k řešení IP adres DoH/DoT, které zadáváte jako upstreamy.",
|
||||
"local_ptr_title": "Soukromé reverzní DNS servery",
|
||||
"local_ptr_desc": "Servery DNS, které AdGuard Home používá pro lokální dotazy PTR. Tyto servery se používají k rozlišení názvů hostitelů klientů se soukromými adresami IP, například \"192.168.12.34\" pomocí rDNS. Pokud není nastaveno, AdGuard Home automaticky použije výchozí řešitele vašeho OS s výjimkou adres samotného AdGuard Home.",
|
||||
"local_ptr_desc": "Servery DNS, které AdGuard Home používá pro lokální dotazy PTR. Tyto servery se používají k řešení požadavků PTR na adresy v soukromých rozmezích IP, například \"192.168.12.34\", pomocí reverzního DNS. Pokud není nastaveno, AdGuard Home automaticky použije výchozí řešitele vašeho OS s výjimkou adres samotného AdGuard Home.",
|
||||
"local_ptr_default_resolver": "Ve výchozím nastavení používá AdGuard Home následující reverzní DNS řešitele: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home nemohl určit vhodné soukromé reverzní DNS řešitele pro tento systém.",
|
||||
"local_ptr_placeholder": "Zadejte jednu adresu serveru na řádek",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Pronájem nemůže mít IP adresu brány",
|
||||
"out_of_range_error": "Musí být mimo rozsah \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Musí být menší než začátek rozsahu",
|
||||
"greater_range_start_error": "Musí být větší než začátek rozsahu",
|
||||
@@ -85,7 +86,7 @@
|
||||
"form_enter_hostname": "Zadejte název hostitele",
|
||||
"error_details": "Podrobnosti chyby",
|
||||
"response_details": "Detail odpovědi",
|
||||
"request_details": "Detail požadavku",
|
||||
"request_details": "Detaily požadavku",
|
||||
"client_details": "Detaily klienta",
|
||||
"details": "Detaily",
|
||||
"back": "Zpět",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "obvyklý DNS (skrze UDP, název hostitele);",
|
||||
"example_upstream_dot": "šifrovaný <0>DNS skrze TLS</0>;",
|
||||
"example_upstream_doh": "šifrovaný <0>DNS skrze HTTPS</0>;",
|
||||
"example_upstream_doq": "šifrovaný <0>DNS skrze QUIC</0> (experimentální);",
|
||||
"example_upstream_doq": "šifrovaný <0>DNS skrze QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS razítka</0> pro <1>DNSCrypt</1> nebo <2>DNS skrze HTTPS</2> řešitele;",
|
||||
"example_upstream_tcp": "obvyklý DNS (přes TCP);",
|
||||
"example_upstream_tcp_hostname": "obvyklý DNS (skrze TCP, název hostitele);",
|
||||
@@ -283,7 +284,7 @@
|
||||
"download_mobileconfig_doh": "Stáhnout .mobileconfig pro DNS skrze HTTPS",
|
||||
"download_mobileconfig_dot": "Stáhnout .mobileconfig pro DNS skrze TLS",
|
||||
"download_mobileconfig": "Stáhnout konfigurační soubor",
|
||||
"plain_dns": "Čisté DNS",
|
||||
"plain_dns": "Běžný DNS",
|
||||
"form_enter_rate_limit": "Zadejte rychlostní limit",
|
||||
"rate_limit": "Rychlostní limit",
|
||||
"edns_enable": "Povolit klientskou podsíť EDNS",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Pokud je nakonfigurován port HTTPS, AdGuard Home administrátorské rozhraní bude přístupné přes HTTPS a bude také poskytovat DNS skrze HTTPS na '/dns-query'.",
|
||||
"encryption_dot": "DNS skrze TLS port",
|
||||
"encryption_dot_desc": "Pokud je tento port nakonfigurován, AdGuard Home bude na tomto portu spouštět DNS skrze TLS server.",
|
||||
"encryption_doq": "Port DNS skrze QUIC (experimentální)",
|
||||
"encryption_doq_desc": "Pokud je tento port nakonfigurován, AdGuard Home spustí na tomto portu server DNS skrze QUIC. Je to experimentální a nemusí být spolehlivé. V současnosti také není příliš mnoho klientů, kteří to podporují.",
|
||||
"encryption_doq": "Port DNS skrze QUIC",
|
||||
"encryption_doq_desc": "Pokud je tento port nakonfigurován, AdGuard Home bude na tomto portu spouštět DNS skrze QUIC server.",
|
||||
"encryption_certificates": "Certifikáty",
|
||||
"encryption_certificates_desc": "Chcete-li používat šifrování, musíte pro svou doménu poskytnout platný řetězec certifikátů SSL. Certifikát můžete získat bezplatně na adrese <0>{{link}}</ 0>, nebo jej můžete zakoupit od jednoho z důvěryhodných certifikačních úřadů.",
|
||||
"encryption_certificates_input": "Zde můžete nakopírovat/vložit certifikáty PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Blokované domény",
|
||||
"access_blocked_desc": "Nezaměňujte to s filtry. AdGuard Home zruší dotazy DNS odpovídající těmto doménám a tyto dotazy se neobjeví ani v protokolu dotazů. Zde můžete určit přesné názvy domén, zástupné znaky a pravidla filtrování URL adres, např. \"example.org\", \"*.example.org\" nebo \"||example.org^\".",
|
||||
"access_settings_saved": "Nastavení přístupu bylo úspěšně uloženo",
|
||||
"updates_checked": "Aktualizace úspěšně zkontrolovány",
|
||||
"updates_checked": "Nová verze AdGuard Home je k dispozici\n",
|
||||
"updates_version_equal": "AdGuard Home je aktuální",
|
||||
"check_updates_now": "Zkontrolovat aktualizace nyní",
|
||||
"dns_privacy": "Soukromí DNS",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS-servere",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS-servere bruges til at fortolke IP-adresser for de DoH-/DoT-resolvere, du angiver som upstream.",
|
||||
"local_ptr_title": "Private reverse DNS-servere",
|
||||
"local_ptr_desc": "De DNS-servere, som AdGuard Home bruger til lokale PTR-forespørgsler. Disse servere bruges til at opløse klientværtsnavne med private IP-adresser, f.eks. \"192.168.12.34\", vha. rDNS. Hvis ikke indstillet, bruger AdGuard Home dit operativsystems standard DNS-opløsere undtagen for sine egne adresser.",
|
||||
"local_ptr_desc": "DNS-servere brugt af AdGuard Home til lokale PTR-forespørgsler. Disse servere bruges til at opløse PTR-forespørgsler fra private IP-adresseområder, f.eks. \"192.168.12.34\", vha. reverse DNS. Hvis ikke opsat, bruger AdGuard Home operativsystems standard DNS-opløsere undtagen for sine egne adresser.",
|
||||
"local_ptr_default_resolver": "AdGuard Home bruger som standard flg. reverse DNS-opløsere: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home kunne ikke fastslå egnede private reverse DNS-opløsere for dette system.",
|
||||
"local_ptr_placeholder": "Indtast en serveradresse pr. Linje",
|
||||
@@ -213,7 +213,7 @@
|
||||
"example_upstream_udp": "almindelig DNS (over UDP, værtsnavn);",
|
||||
"example_upstream_dot": "krypteret <0>DNS-over-TLS</0>",
|
||||
"example_upstream_doh": "krypteret <0>DNS-over-HTTPS</0>",
|
||||
"example_upstream_doq": "krypteret <0>DNS-over-QUIC</0>(eksperimentel);",
|
||||
"example_upstream_doq": "krypteret <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> til <1>DNSCrypt</1> eller <2>DNS-over-HTTPS</2>-opløsere;",
|
||||
"example_upstream_tcp": "almindelig DNS (over TCP)",
|
||||
"example_upstream_tcp_hostname": "almindelig DNS (over TCP, værtsnavn);",
|
||||
@@ -351,7 +351,7 @@
|
||||
"install_devices_android_list_5": "Skift de aktuelle DNS 1- og DNS 2-værdier til dine AdGuard Home-serveradresser.",
|
||||
"install_devices_ios_list_1": "Tryk på Indstillinger på Hjem-skærmen.",
|
||||
"install_devices_ios_list_2": "Vælg Wi-Fi i menuen til venstre (det er umuligt at opsætte DNS for mobilnetværker).",
|
||||
"install_devices_ios_list_3": "Tryk på navnet på det aktuelt aktive netværk.",
|
||||
"install_devices_ios_list_3": "Tryk på navnet for det aktuelt aktive netværk.",
|
||||
"install_devices_ios_list_4": "Angiv dine AdGuard Home-serveradresser i DNS-feltet.",
|
||||
"get_started": "Komme I Gang",
|
||||
"next": "Næste",
|
||||
@@ -369,8 +369,8 @@
|
||||
"encryption_https_desc": "Er HTTPS-porten opsat, vil AdGuard Home admin grænsefladen være tilgængelig via HTTPS, og den vil muliggøre DNS-over-HTTPS på '/dns-query' placeringen.",
|
||||
"encryption_dot": "DNS-over-TLS port",
|
||||
"encryption_dot_desc": "Er denne port opsat, vil AdGuard Home køre en DNS-over-TLS server på denne port.",
|
||||
"encryption_doq": "DNS-over-QUIC port (eksperimentel)",
|
||||
"encryption_doq_desc": "Er denne port opsat, vil AdGuard Home køre en DNS-over-QUIC server på denne port. Den er eksperimentel og er måske ikke pålidelig. Derudover understøttes den pt. heller ikke af ret mange klienter.",
|
||||
"encryption_doq": "DNS-over-QUIC port",
|
||||
"encryption_doq_desc": "Er denne port opsat, vil AdGuard Home køre en DNS-over-QUIC server på denne port. ",
|
||||
"encryption_certificates": "Certifikater",
|
||||
"encryption_certificates_desc": "For at kunne bruge kryptering skal du angive en gyldig SSL-certifikatkæde til dit domæne. Du kan få et gratis certifikat via <0>{{link}}</ 0>, eller du kan købe det via en af de betroede Certifikatmyndigheder.",
|
||||
"encryption_certificates_input": "Kopiér/indsæt dine PEM-kodede certifikater hér.",
|
||||
@@ -445,7 +445,7 @@
|
||||
"access_blocked_title": "Ikke tilladte domæner",
|
||||
"access_blocked_desc": "Ikke at forveksle med filtre. AdGuard Home dropper DNS-forespørgsler matchende disse domæner, ej heller vil forespørgslerne optræde i forespørgselsloggen. Der kan angives præcise domænenavne, jokertegn eller URL-filterregler, f.eks. \"eksempel.org\", \"*.eksempel.org\", \"||eksempel.org^\" eller tilsvarende.",
|
||||
"access_settings_saved": "Adgangsindstillinger gemt",
|
||||
"updates_checked": "Opdateringstjek foretaget",
|
||||
"updates_checked": "En ny version af AdGuard Home er tilgængelig\n",
|
||||
"updates_version_equal": "AdGuard Home er opdateret",
|
||||
"check_updates_now": "Søg efter opdateringer nu",
|
||||
"dns_privacy": "DNS-fortrolighed",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Ungültiger Servername",
|
||||
"form_error_subnet": "Subnetz „{{cidr}}“ enthält nicht die IP-Adresse „{{ip}}“",
|
||||
"form_error_positive": "Muss größer als 0 sein",
|
||||
"form_error_gateway_ip": "Lease kann nicht die IP-Adresse des Gateways haben",
|
||||
"out_of_range_error": "Muss außerhalb des Bereichs „{{start}}“-„{{end}}“ liegen",
|
||||
"lower_range_start_error": "Muss niedriger als der Bereichsbeginn sein",
|
||||
"greater_range_start_error": "Muss größer als der Bereichsbeginn sein",
|
||||
@@ -149,9 +150,9 @@
|
||||
"general_settings": "Allgemeine Einstellungen",
|
||||
"dns_settings": "DNS-Einstellungen",
|
||||
"dns_blocklists": "DNS-Sperrliste",
|
||||
"dns_allowlists": "DNS-Freigabelisten",
|
||||
"dns_allowlists": "DNS-Positivlisten",
|
||||
"dns_blocklists_desc": "AdGuard Home sperrt Domains, die in den Sperrlisten enthalten sind.",
|
||||
"dns_allowlists_desc": "Domains aus DNS-Freigabelisten werden auch dann zugelassen, wenn sie in einer der Sperrlisten enthalten sind.",
|
||||
"dns_allowlists_desc": "Domains aus DNS-Positivlisten werden auch dann zugelassen, wenn sie in einer der Sperrlisten enthalten sind.",
|
||||
"custom_filtering_rules": "Benutzerdefinierte Filterregeln",
|
||||
"encryption_settings": "Verschlüsselungseinstellungen",
|
||||
"dhcp_settings": "DHCP-Einstellungen",
|
||||
@@ -181,21 +182,21 @@
|
||||
"elapsed": "Verstrichen",
|
||||
"filters_and_hosts_hint": "AdGuard Home versteht grundlegende Werbefilterregeln und Host-Datei-Syntax.",
|
||||
"no_blocklist_added": "Keine Sperrliste hinzugefügt",
|
||||
"no_whitelist_added": "Keine Freigabeliste hinzugefügt",
|
||||
"no_whitelist_added": "Keine Positivliste hinzugefügt",
|
||||
"add_blocklist": "Sperrliste hinzufügen",
|
||||
"add_allowlist": "Freigabeliste hinzufügen",
|
||||
"add_allowlist": "Positivliste hinzufügen",
|
||||
"cancel_btn": "Abbrechen",
|
||||
"enter_name_hint": "Name eingeben",
|
||||
"enter_url_or_path_hint": "URL oder absoluten Pfad der Liste eingeben",
|
||||
"check_updates_btn": "Nach Aktualisierungen suchen",
|
||||
"new_blocklist": "Neue Sperrliste",
|
||||
"new_allowlist": "Neue Freigabeliste",
|
||||
"new_allowlist": "Neue Positivliste",
|
||||
"edit_blocklist": "Sperrliste bearbeiten",
|
||||
"edit_allowlist": "Freigabeliste bearbeiten",
|
||||
"edit_allowlist": "Positivliste bearbeiten",
|
||||
"choose_blocklist": "Sperrliste wählen",
|
||||
"choose_allowlist": "Freigabeliste wählen",
|
||||
"choose_allowlist": "Positivliste wählen",
|
||||
"enter_valid_blocklist": "Gültige Webadresse zur Sperrliste eingeben.",
|
||||
"enter_valid_allowlist": "Gültige Webadresse zur Freigabeliste eingeben.",
|
||||
"enter_valid_allowlist": "Gültige Webadresse zur Positivliste eingeben.",
|
||||
"form_error_url_format": "Ungültiges URL-Format",
|
||||
"form_error_url_or_path_format": "Ungültige URL oder absoluter Pfad der Liste",
|
||||
"custom_filter_rules": "Benutzerdefinierte Filterregeln",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "normales DNS (über UDP, Hostname);",
|
||||
"example_upstream_dot": "verschlüsseltes <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "verschlüsseltes <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "verschlüsseltes <0>DNS-over-QUIC</0> (experimentell);",
|
||||
"example_upstream_doq": "verschlüsseltes <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS-Stempel</0> für <1>DNSCrypt</1> oder <2>DNS-over-HTTPS</2> Resolver;",
|
||||
"example_upstream_tcp": "reguläres DNS (over TCP);",
|
||||
"example_upstream_tcp_hostname": "normales DNS (über TCP, Hostname);",
|
||||
@@ -274,8 +275,8 @@
|
||||
"blocking_ipv4": "IPv4-Sperren",
|
||||
"blocking_ipv6": "IPv6-Sperren",
|
||||
"dnscrypt": "DNSCrypt",
|
||||
"dns_over_https": "DNS-over-HTTPS (DNS-Abfrage über HTTPS)",
|
||||
"dns_over_tls": "DNS-over-TLS (DNS-Abfrage über TLS)",
|
||||
"dns_over_https": "DNS-over-HTTPS",
|
||||
"dns_over_tls": "DNS-over-TLS",
|
||||
"dns_over_quic": "DNS-over-QUIC",
|
||||
"client_id": "Client-ID",
|
||||
"client_id_placeholder": "Client-ID eingeben",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Wenn der HTTPS-Port konfiguriert ist, ist die AdGuard Home-Administrationsschnittstelle über HTTPS zugänglich und bietet auch DNS-over-HTTPS am Server „/dns-query“.",
|
||||
"encryption_dot": "DNS-over-TLS",
|
||||
"encryption_dot_desc": "Wenn dieser Port konfiguriert ist, führt AdGuard Home auf diesem Port einen DNS-over-TLS-Server aus.",
|
||||
"encryption_doq": "Port für DNS-over-QUIC (experimentell)",
|
||||
"encryption_doq_desc": "Wenn dieser Port eingerichtet ist, wird AdGuard Home einen DNS-over-QUIC-Server auf diesem Port ausführen. Es ist experimentell und möglicherweise nicht zuverlässig. Außerdem gibt es im Moment nicht allzu viele Clients, die ihn unterstützen.",
|
||||
"encryption_doq": "Port für DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Wenn dieser Port eingerichtet ist, wird AdGuard Home einen DNS-over-QUIC-Server auf diesem Port ausführen. ",
|
||||
"encryption_certificates": "Zertifikate",
|
||||
"encryption_certificates_desc": "Um die Verschlüsselung verwenden zu können, müssen Sie eine gültige SSL-Zertifikatskette für Ihre Domain angeben. Sie können ein kostenloses Zertifikat für <0>{{link}}</0> erhalten oder es bei einer der vertrauenswürdigen Zertifizierungsstellen kaufen.",
|
||||
"encryption_certificates_input": "Kopieren Sie Ihre PEM-codierten Zertifikate und fügen Sie sie hier ein.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Nicht zugelassene Domains",
|
||||
"access_blocked_desc": "Verwechseln Sie dies nicht mit Filtern. AdGuard Home verwirft DNS-Abfragen, die mit diesen Domänen übereinstimmen, und diese Abfragen erscheinen nicht einmal im Abfrageprotokoll. Hier können Sie die genauen Domain-Namen, Wildcards und URL-Filter-Regeln angeben, z.B. 'beispiel.org', '*.beispiel.org' oder '||beispiel.org^'.",
|
||||
"access_settings_saved": "Zugriffseinstellungen erfolgreich gespeichert",
|
||||
"updates_checked": "Erfolgreich auf Aktualisierungen geprüft",
|
||||
"updates_checked": "Neue Version von AdGuard Home ist jetzt verfügbar",
|
||||
"updates_version_equal": "AdGuard Home ist aktuell",
|
||||
"check_updates_now": "Jetzt nach Aktualisierungen suchen",
|
||||
"dns_privacy": "DNS-Datenschutz",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS servers",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams.",
|
||||
"local_ptr_title": "Private reverse DNS servers",
|
||||
"local_ptr_desc": "The DNS servers that AdGuard Home uses for local PTR queries. These servers are used to resolve the hostnames of clients with private IP addresses, for example \"192.168.12.34\", using reverse DNS. If not set, AdGuard Home uses the addresses of the default DNS resolvers of your OS except for the addresses of AdGuard Home itself.",
|
||||
"local_ptr_desc": "The DNS servers that AdGuard Home uses for local PTR queries. These servers are used to resolve PTR requests for addresses in private IP ranges, for example \"192.168.12.34\", using reverse DNS. If not set, AdGuard Home uses the addresses of the default DNS resolvers of your OS except for the addresses of AdGuard Home itself.",
|
||||
"local_ptr_default_resolver": "By default, AdGuard Home uses the following reverse DNS resolvers: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home could not determine suitable private reverse DNS resolvers for this system.",
|
||||
"local_ptr_placeholder": "Enter one server address per line",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Lease can't have the IP address of the gateway",
|
||||
"out_of_range_error": "Must be out of range \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Must be lower than range start",
|
||||
"greater_range_start_error": "Must be greater than range start",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "regular DNS (over UDP, hostname);",
|
||||
"example_upstream_dot": "encrypted <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "encrypted <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "encrypted <0>DNS-over-QUIC</0> (experimental);",
|
||||
"example_upstream_doq": "encrypted <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> for <1>DNSCrypt</1> or <2>DNS-over-HTTPS</2> resolvers;",
|
||||
"example_upstream_tcp": "regular DNS (over TCP);",
|
||||
"example_upstream_tcp_hostname": "regular DNS (over TCP, hostname);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "If HTTPS port is configured, AdGuard Home admin interface will be accessible via HTTPS, and it will also provide DNS-over-HTTPS on '/dns-query' location.",
|
||||
"encryption_dot": "DNS-over-TLS port",
|
||||
"encryption_dot_desc": "If this port is configured, AdGuard Home will run a DNS-over-TLS server on this port.",
|
||||
"encryption_doq": "DNS-over-QUIC port (experimental)",
|
||||
"encryption_doq_desc": "If this port is configured, AdGuard Home will run a DNS-over-QUIC server on this port. It's experimental and may not be reliable. Also, there are not too many clients that support it at the moment.",
|
||||
"encryption_doq": "DNS-over-QUIC port",
|
||||
"encryption_doq_desc": "If this port is configured, AdGuard Home will run a DNS-over-QUIC server on this port.",
|
||||
"encryption_certificates": "Certificates",
|
||||
"encryption_certificates_desc": "In order to use encryption, you need to provide a valid SSL certificates chain for your domain. You can get a free certificate on <0>{{link}}</0> or you can buy it from one of the trusted Certificate Authorities.",
|
||||
"encryption_certificates_input": "Copy/paste your PEM-encoded certificates here.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Disallowed domains",
|
||||
"access_blocked_desc": "Not to be confused with filters. AdGuard Home drops DNS queries matching these domains, and these queries don't even appear in the query log. You can specify exact domain names, wildcards, or URL filter rules, e.g. \"example.org\", \"*.example.org\", or \"||example.org^\" correspondingly.",
|
||||
"access_settings_saved": "Access settings successfully saved",
|
||||
"updates_checked": "Updates successfully checked",
|
||||
"updates_checked": "A new version of AdGuard Home is available",
|
||||
"updates_version_equal": "AdGuard Home is up-to-date",
|
||||
"check_updates_now": "Check for updates now",
|
||||
"dns_privacy": "DNS Privacy",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Servidores DNS de arranque",
|
||||
"bootstrap_dns_desc": "Los servidores DNS de arranque se utilizan para resolver las direcciones IP de los resolutores DoH/DoT que especifiques como DNS de subida.",
|
||||
"local_ptr_title": "Servidores DNS inversos y privados",
|
||||
"local_ptr_desc": "Los servidores DNS que AdGuard Home utiliza para las consultas PTR locales. Estos servidores se utilizan para resolver los nombres de hosts de los clientes a direcciones IP privadas, por ejemplo \"192.168.12.34\", utilizando DNS inverso. Si no está establecido, AdGuard Home utilizará los resolutores DNS predeterminados de tu sistema operativo, excepto las direcciones del propio AdGuard Home.",
|
||||
"local_ptr_desc": "Los servidores DNS que AdGuard Home utiliza para las consultas PTR locales. Estos servidores se utilizan para resolver las peticiones PTR de direcciones en rangos de IP privadas, por ejemplo \"192.168.12.34\", utilizando DNS inverso. Si no está establecido, AdGuard Home utilizará los resolutores DNS predeterminados de tu sistema operativo, excepto las direcciones del propio AdGuard Home.",
|
||||
"local_ptr_default_resolver": "Por defecto, AdGuard Home utiliza los siguientes resolutores DNS inversos: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home no pudo determinar los resolutores DNS inversos y privados adecuados para este sistema.",
|
||||
"local_ptr_placeholder": "Ingresa una dirección de servidor por línea",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Asignación no puede tener la dirección IP de la puerta de enlace",
|
||||
"out_of_range_error": "Debe estar fuera del rango \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Debe ser inferior que el inicio de rango",
|
||||
"greater_range_start_error": "Debe ser mayor que el inicio de rango",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "DNS regular (mediante UDP, nombre del host).",
|
||||
"example_upstream_dot": "cifrado <0>DNS mediante TLS</0>.",
|
||||
"example_upstream_doh": "cifrado <0>DNS mediante HTTPS</0>.",
|
||||
"example_upstream_doq": "cifrado <0>DNS mediante QUIC</0> (experimental).",
|
||||
"example_upstream_doq": "cifrado <0>DNS mediante QUIC</0>.",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> para <1>DNSCrypt</1> o resolutores <2>DNS mediante HTTPS</2>.",
|
||||
"example_upstream_tcp": "DNS regular (mediante TCP).",
|
||||
"example_upstream_tcp_hostname": "DNS regular (mediante TCP, nombre del host).",
|
||||
@@ -351,7 +352,7 @@
|
||||
"install_devices_android_list_5": "Cambia los valores de DNS 1 y DNS 2 a las direcciones de tu servidor AdGuard Home.",
|
||||
"install_devices_ios_list_1": "En la pantalla de inicio, pulsa en Configuración.",
|
||||
"install_devices_ios_list_2": "Elige Wi-Fi en el menú de la izquierda (es imposible configurar DNS para redes móviles).",
|
||||
"install_devices_ios_list_3": "Pulsa sobre el nombre de la red activa en ese momento.",
|
||||
"install_devices_ios_list_3": "Pulsa sobre el nombre de la red actualmente activa.",
|
||||
"install_devices_ios_list_4": "En el campo DNS ingresa las direcciones de tu servidor AdGuard Home.",
|
||||
"get_started": "Comenzar",
|
||||
"next": "Siguiente",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Si el puerto HTTPS está configurado, la interfaz de administración de AdGuard Home será accesible a través de HTTPS, y también proporcionará DNS mediante HTTPS en la ubicación '/dns-query'.",
|
||||
"encryption_dot": "Puerto DNS mediante TLS",
|
||||
"encryption_dot_desc": "Si este puerto está configurado, AdGuard Home ejecutará un servidor DNS mediante TLS en este puerto.",
|
||||
"encryption_doq": "Puerto DNS mediante QUIC (experimental)",
|
||||
"encryption_doq_desc": "Si este puerto está configurado, AdGuard Home ejecutará un servidor DNS mediante QUIC en este puerto. Es experimental y puede no ser confiable. Además, no hay muchos clientes que lo soporten por el momento.",
|
||||
"encryption_doq": "Puerto DNS mediante QUIC",
|
||||
"encryption_doq_desc": "Si este puerto está configurado, AdGuard Home ejecutará un servidor DNS mediante QUIC en este puerto.",
|
||||
"encryption_certificates": "Certificados",
|
||||
"encryption_certificates_desc": "Para utilizar el cifrado, debes proporcionar una cadena de certificado SSL válida para tu dominio. Puedes obtener un certificado gratuito en <0>{{link}}</0> o puedes comprarlo en una de las autoridades de certificación de confianza.",
|
||||
"encryption_certificates_input": "Copia/pega aquí tu certificado codificado PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Dominios no permitidos",
|
||||
"access_blocked_desc": "No debe confundirse con filtros. AdGuard Home descartará las consultas DNS que coincidan con estos dominios, y estas consultas ni siquiera aparecerán en el registro de consultas. Puedes especificar nombres de dominio exactos, comodines o reglas de filtrado de URL, por ejemplo: \"ejemplo.org\", \"*.ejemplo.org\" o \"||ejemplo.org^\" correspondientemente.",
|
||||
"access_settings_saved": "Configuración de acceso guardado correctamente",
|
||||
"updates_checked": "Actualizaciones comprobadas correctamente",
|
||||
"updates_checked": "La nueva versión de AdGuard Home está disponible",
|
||||
"updates_version_equal": "AdGuard Home está actualizado",
|
||||
"check_updates_now": "Buscar actualizaciones ahora",
|
||||
"dns_privacy": "DNS cifrado",
|
||||
|
||||
@@ -1,26 +1,49 @@
|
||||
{
|
||||
"client_settings": "تنظیمات کلاینت",
|
||||
"example_upstream_reserved": "میتوانید جریان ارسالی DNS <0> را برای یک دامنه مشخص تعیین کنید </0>",
|
||||
"upstream_parallel": "استفاده از جستار موازی برای سرعت دادن به تفکیک با جستار همزمان همه جریان های ارسالی",
|
||||
"parallel_requests": "درخواست های موازی",
|
||||
"bootstrap_dns": "خودراه انداز سرورهای DNS",
|
||||
"bootstrap_dns_desc": "خودراه انداز سرورهای DNS برای تفکیک آدرس آی پی تفکیک کننده های DoH/DoT که شما بعنوان جریان ارسالی تعیین کردید استفاده میشود.",
|
||||
"local_ptr_title": "سرورهای خصوصی DNS",
|
||||
"local_ptr_default_resolver": "به طور پیش فرض، AdGuard Home از تعیین کننده های DNS معکوس زیر استفاده می کند: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home نتوانست برای این دستگاه تعیین کننده های DNS معکوس محرمانه مناسب را معین کند.",
|
||||
"local_ptr_placeholder": "در هر خط یک آدرس سرور را وارد کنید",
|
||||
"resolve_clients_title": "فعال سازی تعیین نام های سرویس دهنده ی سرویس گیرندگان",
|
||||
"resolve_clients_desc": "در صورت فعال بودن،AdGuard Home به طور خودکار اقدام به تعیین نام های سرویس دهنده ی سرویس گیرندگان از آدرس های آی پی با ارسال یک درخواست PTR به یک تعیین کننده ی همتا خواهد کرد (سرور خصوصی DNS برای سرویس گیرندگان محلی،سرور مادر برای سرویس گیرندگان با آی پی عمومی).",
|
||||
"use_private_ptr_resolvers_title": "از تعیین کننده های rDNS محرمانه استفاده کنید",
|
||||
"use_private_ptr_resolvers_desc": "داده گیری های دی ان اس معکوس را برای آدرس های اینترنتی خدمات منظقه ای با استفاده از سرور های مادر اجرا کنید. چنانچه غیر فعال باشد،AdGuard Home با NXDOMAIN به همه چنین درخواست های PTR پاسخ می دهد به استثناء خدمات گیرنده های شناخته شده از طرف DHCP،/و غیره/هوست ها، و سایر.",
|
||||
"check_dhcp_servers": "بررسی برای سرورهای DHCP",
|
||||
"save_config": "ذخیره پیکربندی",
|
||||
"enabled_dhcp": "سرور DHCP فعال شده است",
|
||||
"disabled_dhcp": "سرور DHCP غیرفعال شده است",
|
||||
"dhcp_title": "سرور DHCP",
|
||||
"dhcp_description": "اگر روتر شما تنظیمات DHCP ارائه نمی کند،میتوانید از سرور DHCP تو-کار خود AdGuard استفاده کنید.",
|
||||
"dhcp_enable": "فعالسازی سرور DHCP",
|
||||
"dhcp_disable": "غیرفعالسازی سرور DHCP",
|
||||
"dhcp_not_found": "سرورهای فعال DHCP در شبکه یافت نشد.فعالسازی سرور DHCP تو-کار اَمن است.",
|
||||
"dhcp_found": "تعدادی سرور DHCP فعال در شبکه یافت شد.فعالسازی سرور DHCP توکار اَمن نیست.",
|
||||
"dhcp_leases": "اجاره DHCP",
|
||||
"dhcp_static_leases": "اجاره DHCP ایستا",
|
||||
"dhcp_leases_not_found": "اجاره DHCP یافت نشد",
|
||||
"dhcp_config_saved": "پیکربندی سرور DHCP ذخیره شده است",
|
||||
"form_error_required": "فیلد مورد نیاز",
|
||||
"form_error_ip4_format": "فرمت نامعتبر IPv4",
|
||||
"form_error_ip4_range_start_format": "قالب IPv4 شروع دامنه نامعتبر است",
|
||||
"form_error_ip4_range_end_format": "قالب IPv4 پایان دامنه نامعتبر است",
|
||||
"form_error_ip4_gateway_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_subnet": "زیرشبکه\"{{cidr}}\"آدرس آی پی {{ip}} را در بر ندارد",
|
||||
"form_error_positive": "باید بزرگتر از 0 باشد",
|
||||
"out_of_range_error": "باید خارج از دامنه باشد\"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "باید کمتر از شروع دامنه باشد",
|
||||
"greater_range_start_error": "باید بیشتر از شروع دامنه باشد",
|
||||
"greater_range_end_error": "باید بیشتر از پایان دامنه باشد",
|
||||
"subnet_error": "آدرس ها باید در یک زیرشبکه باشند",
|
||||
"gateway_or_subnet_invalid": "پوشش زیرشبکه نامعتبر است",
|
||||
"dhcp_form_gateway_input": "آی پی دروازه",
|
||||
"dhcp_form_subnet_input": "ماسک زیر شبکه",
|
||||
"dhcp_form_range_title": "دامنه آدرس های آی پی",
|
||||
@@ -34,11 +57,19 @@
|
||||
"ip": "IP",
|
||||
"dhcp_table_hostname": "نام میزبان",
|
||||
"dhcp_table_expires": "انقضاء",
|
||||
"dhcp_warning": "اگر میخواهید DHCP سرور توکار را فعال کنید،مطمئن شوید DHCP سرور دیگری فعال نباشد.در غیر اینصورت،آن دسترسی به اینترنت را برای دستگاه های وصل شده قطع می کند!",
|
||||
"dhcp_error": "ما نمیتوانیم تشخیص دهیم آیا یک سرور DHCP دیگر در شبکه موجود است یا نه.",
|
||||
"dhcp_static_ip_error": "به منظور استفاده از سرور DHCP یک آدرس آی پی ثابت باید تنظیم شود.ما موفق به تشخیص اینکه آیا رابط این شبکه برای استفاده از آی پی ثابت تنظیم شده است یا نه موفق نشدیم.لطفا آدرس آی پی ثابت را دستی تنظیم کنید.",
|
||||
"dhcp_dynamic_ip_found": "سیستم شما آدرس آی پی متغییر برای این رابط استفاده می کند <0>{{interfaceName}}</0>. به منظور استفاده از سرور DHCP آدرس ثابت باید تعیین شود. آدرس آی پی فعلی شما هست <0>{{ipAddress}}</0>. اگر شما دکمه DHCP را فشار دهید ما این آدرس آی پی را بعنوان ثابت تنظیم می کنیم.",
|
||||
"dhcp_lease_added": "اجاره ایستا \"{{key}}\" با موفقیت اضافه شد",
|
||||
"dhcp_lease_deleted": "اجاره ایستا \"{{key}}\" با موفقیت حذف شد",
|
||||
"dhcp_new_static_lease": "اجاره ایستا جدید",
|
||||
"dhcp_static_leases_not_found": "هیچ اجاره DHCP ایستا یافت نشد",
|
||||
"dhcp_add_static_lease": "افزودن اجاره ایستا",
|
||||
"dhcp_reset_leases": "بازگردانی همه مجوزهای منابع",
|
||||
"dhcp_reset_leases_confirm": "آیا می خواهید تمام مجوزهای منابع را بازگردانی کنید؟",
|
||||
"dhcp_reset_leases_success": "مجوزهای منابع DHCP با موفقیت بازگردانی شد",
|
||||
"dhcp_reset": "آیا میخواهید پیکربندی DHCP را ریست کنید؟",
|
||||
"country": "کشور",
|
||||
"city": "شهر",
|
||||
"delete_confirm": "آیا میخواهید \"{{key}}\" را حذف کنید؟",
|
||||
@@ -54,6 +85,7 @@
|
||||
"filters": "فيلترها",
|
||||
"filter": "فیلتر",
|
||||
"query_log": "جستار وقایع",
|
||||
"compact": "فشرده",
|
||||
"nothing_found": "هیچ چیز یافت نشد",
|
||||
"faq": "پرسش و پاسخ",
|
||||
"version": "نسخه",
|
||||
@@ -78,13 +110,22 @@
|
||||
"for_last_24_hours": "برای 24 ساعت گذشته",
|
||||
"for_last_days": "برای {{count}} روز آخر",
|
||||
"for_last_days_plural": "برای {{count}} روز گذشته",
|
||||
"stats_disabled": "آمار غیرفعال شده است. شما می توانید از قسمت <0>صفحه تنظیمات</0> آن را روشن نمایید.",
|
||||
"stats_disabled_short": "آمار غیرفعال شده است",
|
||||
"no_domains_found": "دامنه یافت نشد",
|
||||
"requests_count": "تعداد درخواست ها",
|
||||
"top_blocked_domains": "دامنه های بیشتر مسدود شده",
|
||||
"top_clients": "بالاترین کلاینت ها",
|
||||
"no_clients_found": "کلاینتی یافت نشد",
|
||||
"general_statistics": "آمار عمومی",
|
||||
"number_of_dns_query_days": "تعداد جستار DNS پردازش شده در {{count}} روز آخر",
|
||||
"number_of_dns_query_days_plural": "تعداد جستار DNS پردازش شده در {{count}} روز گذشته",
|
||||
"number_of_dns_query_24_hours": "تعداد جستار DNS پردازش شده در 24 ساعت گذشته",
|
||||
"number_of_dns_query_blocked_24_hours": "تعداد درخواست DNS مسدود شده با فیلترهای مسدودساز تبلیغ و لیست سیاه میزبان",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "تعداد درخواست DNS مسدود شده با مدل امنیت وب گردی AdGuard",
|
||||
"number_of_dns_query_blocked_24_hours_adult": "تعداد وبسایت های غیر اخلاقی مسدود شده",
|
||||
"enforced_save_search": "جستجوی اَمن اجبار شده",
|
||||
"number_of_dns_query_to_safe_search": "تعداد درخواست های DNS برای موتور جستجو که جستجوی اَمن اجبار شده",
|
||||
"average_processing_time": "میانگین زمان پردازش",
|
||||
"average_processing_time_hint": "زمان میانگین بر هزارم ثانیه در پردازش درخواست DNS",
|
||||
"block_domain_use_filters_and_hosts": "مسدودسازی دامنه ها توسط فیلترها و فایل های میزبان",
|
||||
@@ -94,6 +135,7 @@
|
||||
"use_adguard_parental": "از سرویس وب نظارت والدین AdGuard استفاده کن",
|
||||
"use_adguard_parental_hint": "AdGuard Home بررسی می کند اگر دامنه حاوی موارد غیر اخلاقی است.آن از همان اِی پی آی دارای حریم خصوصی سرویس وب امنیت وب گردی استفاده می کند.",
|
||||
"enforce_safe_search": "اجبار جستجوی اَمن",
|
||||
"enforce_save_search_hint": "AdGuard Home میتواند جستجوی اَمن را در موتور جستجوهای زیر اعمال کند:گوگل،یوتوب،بینگ و یاندکس",
|
||||
"no_servers_specified": "سروری تعیین نشده است",
|
||||
"general_settings": "تنظیمات عمومی",
|
||||
"dns_settings": "تنظیمات DNS",
|
||||
@@ -145,6 +187,7 @@
|
||||
"form_error_url_or_path_format": "آدرس نامعتبر یا یک مسیر کامل لیست",
|
||||
"custom_filter_rules": "دستورات فیلترینگ دستی",
|
||||
"custom_filter_rules_hint": "یک دستور در خط وارد کنید.میتوانید از دستورات مسدودساز تبلیغ یا نحو فایل های میزبان استفاده کنید.",
|
||||
"system_host_files": "فایل های هوست سیستم",
|
||||
"examples_title": "مثال ها",
|
||||
"example_meaning_filter_block": "مسدودسازی دسترسی به دامنه example.org و همه زیر دامنه ها آن",
|
||||
"example_meaning_filter_whitelist": "بازکردن دسترسی به دامنه example.org و همه زیر دامنه ها آن",
|
||||
@@ -159,6 +202,7 @@
|
||||
"example_upstream_sdns": "شما میتوانید از <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> برای <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> یا <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> resolvers استفاده کنید",
|
||||
"example_upstream_tcp": "DNS عادی (بر TCP)",
|
||||
"all_lists_up_to_date_toast": "همه لیست ها از قبل بروز اند",
|
||||
"updated_upstream_dns_toast": "سرورهای DNS جریان ارسالی بروز رسانی شده است",
|
||||
"dns_test_ok_toast": "سرورهای DNS تعیین شده بدرستی کار می کنند",
|
||||
"dns_test_not_ok_toast": "سرور \"{{key}}\": نمیتواند مورد استفاده قرار گیرد،لطفا بررسی کنید آن را بدرستی نوشته اید",
|
||||
"unblock": "رفع انسداد",
|
||||
@@ -169,6 +213,7 @@
|
||||
"domain_or_client": "دامنه یا کلاینت",
|
||||
"type_table_header": "نوع",
|
||||
"response_table_header": "پاسخ",
|
||||
"response_code": "کد پاسخ",
|
||||
"client_table_header": "کلاینت",
|
||||
"empty_response_status": "خالی",
|
||||
"show_all_filter_type": "نمایش همه",
|
||||
@@ -187,6 +232,7 @@
|
||||
"query_log_filtered": "فیلتر شده با {{filter}}",
|
||||
"query_log_confirm_clear": "آیا واقعا میخواهید کل وقایع جستار را پاک کنید؟",
|
||||
"query_log_cleared": "وقایع جستار با موفقیت پاک شد",
|
||||
"query_log_updated": "فیلتر با موفقیت بروز رسانی شد",
|
||||
"query_log_clear": "پاکسازی وقایع جستار",
|
||||
"query_log_retention": "حفظ وقایع جستار برای",
|
||||
"query_log_enable": "فعالسازی وقایع",
|
||||
@@ -212,15 +258,19 @@
|
||||
"rate_limit": "میزان محدودیت",
|
||||
"edns_enable": "فعالسازی زیرشبکه کلاینت EDNS",
|
||||
"edns_cs_desc": "اگر فعال باشد،AdGuard Home زیرشبکه های کلاینت ها را به سرورهای DNS می فرستد.",
|
||||
"rate_limit_desc": "تعداد درخواست های بر ثانیه مجازی که یک کلاینت میتواند بسازد (0: نامحدود)",
|
||||
"blocking_ipv4_desc": "آدرس آی پی برگشت داده شده برای درخواست مسدود شده A",
|
||||
"blocking_ipv6_desc": "آدرس آی پی برگشت داده شده برای درخواست مسدود شده AAAA",
|
||||
"blocking_mode_default": "پیش فرض: وقتی مسدود شود با دستور سبک-مسدودساز تبلیغ REFUSED پاسخ میدهد،پاسخ با آدرس آی پی تعیین شده در دستور وقتی با دستور /etc/hosts-style rule مسدود شود",
|
||||
"blocking_mode_nxdomain": "NXDOMAIN: پاسخ با کُد NXDOMAIN",
|
||||
"blocking_mode_null_ip": "Null IP: پاسخ با آدرس آی پی صفر(0.0.0.0 برای A; :: برای AAAA)",
|
||||
"blocking_mode_custom_ip": "آی پی دستی: پاسخ با آدرس آی پی دستی تنظیم شده",
|
||||
"upstream_dns_client_desc": "اگر این فیلد را خالی نگه دارید، AdGuard Home از سرور پیکربندی شده در <0> تنظیماتDNS </0> استفاده می کند.",
|
||||
"tracker_source": "منبع ردیاب",
|
||||
"source_label": "منبع",
|
||||
"found_in_known_domain_db": "در پایگاه داده دامنه های شناخته شده پیدا شد",
|
||||
"category_label": "دسته بندی",
|
||||
"rule_label": "دستور",
|
||||
"list_label": "لیست",
|
||||
"unknown_filter": "فیلتر ناشناخته {{filterId}}",
|
||||
"known_tracker": "ردیاب های شناخته شده",
|
||||
@@ -230,6 +280,7 @@
|
||||
"install_settings_listen": "رابط گوش دادن",
|
||||
"install_settings_port": "پورت",
|
||||
"install_settings_interface_link": "رابط صفحه وب آدمین AdGuard Home شما در این آدرس قابل دسترسی خواهد بود:",
|
||||
"form_error_port": "مقدار پورت معتبر وارد کنید",
|
||||
"install_settings_dns": "سرور DNS",
|
||||
"install_settings_dns_desc": "نیاز است شما دستگاه یا روتر خود را برای استفاده از سرور DNS روی آدرس های زیر پیکربندی کنید:",
|
||||
"install_settings_all_interfaces": "همه رابط ها",
|
||||
@@ -248,8 +299,10 @@
|
||||
"install_devices_router": "روتر",
|
||||
"install_devices_router_desc": "این راه انداز خودکار همه دستگاه های متصل شده به روتر خانه را پوشش میدهد و نیازی نیست شما هر یک از آنها را دستی پیکربندی کنید.",
|
||||
"install_devices_address": "DNS سرور AdGuard Home به آدرس های زیر گوش میدهد",
|
||||
"install_devices_router_list_1": "اولویت ها را برای روتر خود باز کنید.معمولا میتوانید آن را ز طریق مرورگر از طریق آدرسی مانند ( http://192.168.0.1/ یا http://192.168.1.1/) دسترسی داشته باشید.ممکن است رمزعبور پرسیده شود،اگر آن را بخاطر ندارید،غالبا میتوان رمزعبور را با فشردن دکمه پشت روتر ریست کرد.برخی روترها برنامه خاصی نیاز دارد که باید در رایانه/گوشی نصب شده باشد.",
|
||||
"install_devices_router_list_2": "تنظیمات DHCP/DNS را بیابید.دنبال حروف DNS بگردید در فیلدی که اجازه دو یا سه گروه عدد را میدهد و هر کدام در چهار گروه سه عددی شکسته شده است",
|
||||
"install_devices_router_list_3": "آدرس سرور AdGuard Home خود را آنجا وارد کنید",
|
||||
"install_devices_router_list_4": "شما نمیتوانید DNS سرور سفارشی در برخی از روترها تنظیم کنید. در این مورد اگر شما AdGuard Home را بعنوان DHCP سرور راه اندازی کنید میتواند کمک کند. در غیر اینصورت باید راهنمای سفارشی سازی DNS سرورها برای مدل خاص روتر خود را انتخاب کنید.",
|
||||
"install_devices_windows_list_1": "کنترل پنل را از طریق استارت منو یا جستجوی ویندوز باز کنید.",
|
||||
"install_devices_windows_list_2": "بروید به شبکه و دسته اینترنت و سپس به شبکه و مرکز اشتراک گذاری",
|
||||
"install_devices_windows_list_3": "در سمت چپ صفحه تنظیمات آداپتور را تغییر داده و روی آن کلیک کنید",
|
||||
@@ -267,7 +320,6 @@
|
||||
"install_devices_android_list_5": "گروه مقادیر DNS 1 و DNS 2 را به آدرس سرور AdGuard Home خود تغییر دهید.",
|
||||
"install_devices_ios_list_1": "از صفحه خانه،تنظیمات را فشار دهید.",
|
||||
"install_devices_ios_list_2": "وای فای را از منوی چپ انتخاب کنید (پیکربندی DNS دستی برای ارتباط موبایلی غیرممکن است).",
|
||||
"install_devices_ios_list_3": "روی نام شبکه فعال فعلی کلیک کنید.",
|
||||
"install_devices_ios_list_4": "در فیلد DNS آدرس سرور AdGuard Home را وارد کنید",
|
||||
"get_started": "شروع به کار",
|
||||
"next": "بعدی",
|
||||
@@ -275,8 +327,10 @@
|
||||
"install_saved": "با موفقیت ذخیره نشد",
|
||||
"encryption_title": "رمزگُذاری",
|
||||
"encryption_desc": "پشتیبانی رمزگُذاری (HTTPS/TLS) برای DNS و رابط آدمین وب",
|
||||
"encryption_config_saved": "پیکربندی رمزگذاری ذخیره شد",
|
||||
"encryption_server": "نام سرور",
|
||||
"encryption_server_enter": "نام دامنه خود را وارد کنید",
|
||||
"encryption_server_desc": "به منظور استفاده از HTTPS،شما باید نام سرور مطابق با گواهینامه اِس اِس اِل را وارد کنید.",
|
||||
"encryption_redirect": "تغییر مسیر خودکار به HTTPS",
|
||||
"encryption_redirect_desc": "اگر انتخاب شده باشد،AdGuard Home خودکار شما را از آدرس HTTP به HTTPS منتقل می کند",
|
||||
"encryption_https": "پورت HTTPS",
|
||||
@@ -302,10 +356,13 @@
|
||||
"encryption_reset": "آیا میخواهید تنظیمات رمزگُذاری به پیش فرض بازگردد؟",
|
||||
"topline_expiring_certificate": "گواهینامه اِس اِس اِل شما در صدد انقضاء است. <0>تنظیمات رمزگُذاری</0> را بروز رسانی کنید.",
|
||||
"topline_expired_certificate": "گواهینامه اِس اِس اِل شما منقضی شده است. <0>تنظیمات رمزگُذاری</0> را بروز رسانی کنید.",
|
||||
"form_error_port_range": "مقدار پورت را در محدوده 80-65535 وارد کنید",
|
||||
"form_error_port_unsafe": "این پورت غیر ایمن است",
|
||||
"form_error_equal": "نباید برابر باشد",
|
||||
"form_error_password": "رمزعبور تطبیق ندارد",
|
||||
"reset_settings": "ریست تنظیمات",
|
||||
"update_announcement": "AdGuard Home {{version}} در دسترس است! <0>اینجا کلیک</0> کنید برای اطلاعات بیشتر.",
|
||||
"setup_guide": "راهنمای راه اندازی",
|
||||
"dns_addresses": "آدرس های DNS",
|
||||
"dns_start": "سرور DNS در حال شروع است",
|
||||
"dns_status_error": "خطا در دریافت وضعیت DNS",
|
||||
@@ -314,6 +371,7 @@
|
||||
"dns_providers": "در اینجا یک <0>لیست از سرویس های ارائه دهنده DNS</0> برای انتخاب هست.",
|
||||
"update_now": "حالا بروز رسانی",
|
||||
"update_failed": "بروز رسانی خودکار موفق نشد. لطفا <a>مراحل را دنبال کرده</a> تا بطور دستی بروز رسانی کنید.",
|
||||
"manual_update": "لطفا<a>این مراحل را دنبال کنید</a>تا به طور دستی بروزرسانی نمایید.",
|
||||
"processing_update": "منتظر بمانید،AdGuard Home در حال بروز رسانی است",
|
||||
"clients_title": "کلاینت ها",
|
||||
"clients_desc": "پیکربندی دستگاه های متصل شده به AdGuard Home",
|
||||
@@ -327,7 +385,9 @@
|
||||
"client_edit": "ویرایش کلاینت",
|
||||
"client_identifier": "احراز با",
|
||||
"ip_address": "آدرس آی پی",
|
||||
"client_identifier_desc": "کلاینت میتواند با آدرس آی پی یا آدرس مَک احراز شود. لطفا توجه کنید،که استفاده از مَک بعنوان عامل احراز زمانی امکان دارد که AdGuard Home نیز <0>سرور DHCP </0> باشد",
|
||||
"form_enter_ip": "آی پی را وارد کنید",
|
||||
"form_enter_subnet_ip": "یک آدرس آی پی در زیر شبکه \"{{cidr}}\" وارد کنید",
|
||||
"form_enter_mac": "مَک را وارد کنید",
|
||||
"form_enter_id": "خطای احرازکننده",
|
||||
"form_add_id": "افزودن احرازکننده",
|
||||
@@ -349,13 +409,15 @@
|
||||
"access_disallowed_title": "کلاینت های غیرمجاز",
|
||||
"access_disallowed_desc": "یک لیست از CIDR یا آدرس های IP.اگر پیکربندی شود،AdGuard Home درخواست ها را از این آدرس های IP نمی پذیرد.",
|
||||
"access_blocked_title": "دامنه های مسدود شده",
|
||||
"access_blocked_desc": "این را با فیلتر ها به اشتباه نگیرید.AdGuard Home جستار DNS را با این دامنه ها در جستار سوال ها نمی پذیرد.",
|
||||
"access_settings_saved": "تنظیمات دسترسی با موفقیت ذخیره شد",
|
||||
"updates_checked": "بروز رسانی با موفقیت بررسی شد",
|
||||
"updates_checked": "نسخه جدیدی از AdGuard Home در دسترس است",
|
||||
"updates_version_equal": "AdGuard Home بروز است",
|
||||
"check_updates_now": "حالا بررسی برای بروز رسانی",
|
||||
"dns_privacy": "حریم خصوصی DNS",
|
||||
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> استفاده از<1>{{address}}</1> .",
|
||||
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> استفاده از <1>{{address}}</1> .",
|
||||
"setup_dns_privacy_3": "<0>لطفا توجه کنید که پروتکل های رمزگذاری شده DNS فقط در آندروئید 9 پشتیبانی می شود. پس برای سیستم عامل های دیگر نیاز است که برنامه دیگری نصب کنید.</0><0>در اینجا میتوانید لیست نرم افزارهای قابل استفاده را ببینید.</0>",
|
||||
"setup_dns_privacy_android_1": "آندروئید 9 بطور پیش فرض از DNS-over-TLS پشتیبانی می کند. برای پیکربندی آن، بروید به تنظیمات → شبکه & اینترنت → پیشرفته → DNS خصوصی و نام دامنه را آنجا وارد کنید.",
|
||||
"setup_dns_privacy_android_2": "<0>AdGuard for Android</0> پشتیبانی از <1>DNS-over-HTTPS</1> و <1>DNS-over-TLS</1>.",
|
||||
"setup_dns_privacy_android_3": "<0>Intra</0> قابلیت <1>DNS-over-HTTPS</1> را به آندروئید اضافه می کند.",
|
||||
@@ -410,10 +472,11 @@
|
||||
"statistics_configuration": "پیکربندی آمارها",
|
||||
"statistics_retention": "مدت حفظ آمارها",
|
||||
"statistics_retention_desc": "اگر مقدار فاصله را کاهش دهید،برخی داده ها از بین خواهد رفت",
|
||||
"statistics_clear": "بازنشانی آمار",
|
||||
"statistics_clear": " پاکسازی آمار",
|
||||
"statistics_clear_confirm": "آیا واقعا میخواهید آمار را پاک کنید؟",
|
||||
"statistics_retention_confirm": "آیا واقعا میخواهید مدت حفظ آمار را تغییر دهید؟ اگر فاصله را کاهش دهید، برخی داده ها حذف میشود",
|
||||
"statistics_cleared": "آمارها با موفقیت حذف شد",
|
||||
"statistics_enable": "فعالسازی داده های آماری",
|
||||
"interval_hours": "{{count}} ساعت",
|
||||
"interval_hours_plural": "{{count}} ساعت",
|
||||
"filters_configuration": "پیکربندی فیلترها",
|
||||
@@ -440,7 +503,10 @@
|
||||
"domain_desc": "نامه دامنه یا علامت تطبیقی را برای بازنویسی وارد کنید.",
|
||||
"example_rewrite_domain": "فقط بازنویسی پاسخ برای این دامنه.",
|
||||
"example_rewrite_wildcard": "بازنویسی پاسخ ها برای همه زیردامنه های <0>example.org</0>.",
|
||||
"disable_ipv6": "غیرفعالسازی IPv6",
|
||||
"disable_ipv6_desc": "اگر این ویژگی فعال شده، همه جستارهای DNS برای آدرس های IPv6 (نوع AAAA) رها میشود.",
|
||||
"fastest_addr": "سریعترین آدرس آی پی",
|
||||
"fastest_addr_desc": "جستار همه سرورهای DNS و بازگرداندن سریعترین آدرس IP از میان همه پاسخ ها",
|
||||
"autofix_warning_text": "اگر روی \"تعمیر\" کلیک کنید، AdGuardHome سیستم شما را برای استفاده از DNS سرور AdGuardHome پیکربندی می کند.",
|
||||
"autofix_warning_list": "این وظایف را اجرا میکند: <0>غیرفعالسازی DNSStubListener سیستم</0> <0>تنظیم آدرس DNS 127.0.0.1</0> سرور به <0>جایگزینی لینک نمادی هدف /etc/resolv.conf به/run/systemd/resolve/resolv.conf</0> <0>توقف DNSStubListener (بارگیری مجدد سرویس systemd-resolved)</0>",
|
||||
"autofix_warning_result": "در نتیجه همه درخواست های DNS از سیستم شما بطور پیش فرض با AdGuardHome پردازش خواهد شد.",
|
||||
@@ -467,6 +533,7 @@
|
||||
"set_static_ip": "تنظیم یک آدرس آی پی ثابت",
|
||||
"install_static_ok": "خبر خوب! آدرس آی پی ثابت از قبل پیکربندی شده است",
|
||||
"install_static_error": "AdGuard Home نمیتواند رابط این شبکه را خودکار پیکربندی کند. لطفا دستورالعمل چگونگی انجام دستی آن را مطالعه کنید.",
|
||||
"install_static_configure": "ما تشخیص دادیم از آدرس آی پی پویا استفاده شده است — <0>{{ip}}</0>. آیا میخواهید از آن بعنوان آدرس ثابت استفاده کنید؟",
|
||||
"confirm_static_ip": "AdGuard Home {{ip}} بعنوان آدرس آی پی ثابت شما پیکربندی می کند. ادامه میدهید؟",
|
||||
"list_updated": "{{count}} لیست بروز رسانی شد",
|
||||
"list_updated_plural": "{{count}} لیست بروز رسانی شد",
|
||||
@@ -477,16 +544,21 @@
|
||||
"show_whitelisted_responses": "لیست سفید",
|
||||
"show_processed_responses": "پردازش شده",
|
||||
"blocked_safebrowsing": "بستن وب گردی اَمن",
|
||||
"blocked_adult_websites": "مسدود شده با نظارت والدین",
|
||||
"blocked_adult_websites": "وبسایت غیراخلاقی مسدود شده",
|
||||
"blocked_threats": "تهدیدات مسدود شده",
|
||||
"allowed": "اجازه داده شده",
|
||||
"filtered": "فیلتر شده",
|
||||
"rewritten": "بازنویسی شده",
|
||||
"safe_search": "فعالسازی جستجوی اَمن",
|
||||
"safe_search": "جستجوی اَمن",
|
||||
"blocklist": "لیست سیاه",
|
||||
"milliseconds_abbreviation": "هـ ثـ",
|
||||
"cache_optimistic": "حالت ویژه پردازش",
|
||||
"cache_optimistic_desc": "AdGuard Home را وادار می کند که از سمت حافظه پنهان پاسخ دهد حتی وقتی که موارد وارد شده منقضی شده باشد و همچنین سعی بر تازه کردن آنها می کند.",
|
||||
"filter_category_general": "General",
|
||||
"filter_category_security": "مسدودسازی بدافزار و فیشینگ",
|
||||
"filter_category_other": "ساير",
|
||||
"parental_control": "نظارت والدین"
|
||||
"use_saved_key": "از کلید ذخیره شده قبلی استفاده کنید",
|
||||
"parental_control": "نظارت والدین",
|
||||
"safe_browsing": "وب گردی اَمن",
|
||||
"form_error_password_length": "رمزعبور باید حداقل {{value}} کاراکتر باشد."
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS-palvelimet",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS-palvelimia käytetään ylävirroiksi määritettyjen DoH/DoT-resolvereiden IP-osoitteiden selvitykseen.",
|
||||
"local_ptr_title": "Yksityiset käänteiset DNS-palvelimet",
|
||||
"local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-pyynnöille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien päätelaitteiden osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteisen DNS:n avulla. Jos ei käytössä, käyttää AdGuard Home käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.",
|
||||
"local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-kyselyille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien PTR-kyselyiden osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteisen DNS:n avulla. Jos ei käytössä, AdGuard Home käyttää käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.",
|
||||
"local_ptr_default_resolver": "Oletusarvoisesti AdGuard Home käyttää seuraavia käänteisiä DNS-resolvereita: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home ei voinut määrittää tälle järjestelmälle sopivaa yksityistä käänteistä DNS-resolveria.",
|
||||
"local_ptr_placeholder": "Syötä yksi palvelimen osoite per rivi",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Lainalla ei voi olla yhdyskäytävän IP-osoitetta",
|
||||
"out_of_range_error": "Oltava alueen \"{{start}}\" - \"{{end}}\" ulkopuolella",
|
||||
"lower_range_start_error": "Oltava alueen aloitusarvoa pienempi",
|
||||
"greater_range_start_error": "Oltava alueen aloitusarvoa suurempi",
|
||||
@@ -70,7 +71,7 @@
|
||||
"dhcp_error": "AdGuard Home ei voinut tunnistaa, onko verkossa toista aktiivista DHCP-palvelinta",
|
||||
"dhcp_static_ip_error": "Jotta DHCP-palvelinta voidaan käyttää, on määritettävä kiinteä IP-osoite. AdGuard Home ei voinut tunnistaa, onko tälle verkkosovittimelle määritetty IP-osoite kiinteä. Määritä kiinteä IP-osoite itse.",
|
||||
"dhcp_dynamic_ip_found": "Järjestelmäsi käyttää verkkosovittimelle <0>{{interfaceName}}</0> dynaamista IP-osoitetta. Jotta voit käyttää DHCP-palvelinta, on sovittimelle määritettävä kiinteä IP-osoite. Nykyinen IP-osoitteesi on <0>{{ipAddress}}</0>. Tämä osoite määritetään automaattisesti kiinteäksi, jos painat \"Ota DHCP-palvelin käyttöön\" -painiketta.",
|
||||
"dhcp_lease_added": "Kiinteä laina \"{{key}}\" on lisätty",
|
||||
"dhcp_lease_added": "Kiinteä laina \"{{key}}\" lisättiin",
|
||||
"dhcp_lease_deleted": "Kiinteä laina \"{{key}}\" poistettiin",
|
||||
"dhcp_new_static_lease": "Uusi kiinteä laina",
|
||||
"dhcp_static_leases_not_found": "Kiinteitä DHCP-lainoja ei löytynyt",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "tavallinen DNS (UDP, isäntänimi);",
|
||||
"example_upstream_dot": "salattu <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "salattu <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "salattu <0>DNS-over-QUIC</0> (kokeellinen);",
|
||||
"example_upstream_doq": "salattu <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamp</0> -merkinnät <1>DNSCrypt</1> tai <2>DNS-over-HTTPS</2> -resolvereille;",
|
||||
"example_upstream_tcp": "tavallinen DNS (TCP:n välityksellä);",
|
||||
"example_upstream_tcp_hostname": "tavallinen DNS (TCP, isäntänimi);",
|
||||
@@ -338,20 +339,20 @@
|
||||
"install_devices_windows_list_2": "Avaa \"Verkko ja Internet\" -ryhmä ja sitten \"Verkko ja jakamiskeskus\".",
|
||||
"install_devices_windows_list_3": "Paina ikkunan vasemmasta laidasta \"Muuta sovittimen asetuksia\".",
|
||||
"install_devices_windows_list_4": "Paina aktiivista yhteyttäsi hiiren kakkospainikkeella ja valitse \"Ominaisuudet\".",
|
||||
"install_devices_windows_list_5": "Etsi listasta \"Internet protokolla versio 4 (TCP/IP)\", valitse se ja paina jälleen \"Ominaisuudet\".",
|
||||
"install_devices_windows_list_5": "Etsi listasta \"Internet Protocol Version 4 (TCP/IPv4)\" (tai IPv6:lle \"Internet Protocol Version 6 (TCP/IPv6)\"), valitse se ja paina jälleen \"Ominaisuudet\".",
|
||||
"install_devices_windows_list_6": "Valitse \"Käytä seuraavia DNS-palvelinten osoitteita\" ja syötä AdGuard Home -palvelimesi osoitteet.",
|
||||
"install_devices_macos_list_1": "Paina Omena-kuvaketta ja valitse \"Järjestelmäasetukset\".",
|
||||
"install_devices_macos_list_2": "Paina \"Verkko\".",
|
||||
"install_devices_macos_list_3": "Valitse listan ensimmäinen yhteys ja paina \"Lisävalinnat\".",
|
||||
"install_devices_macos_list_4": "Valitse DNS-välilehti ja syötä AdGuard Home -palvelimesi osoitteet.",
|
||||
"install_devices_android_list_1": "Napauta Android-laitteesi aloitusnäytöstä tai sovellusvalikosta \"Asetukset\".",
|
||||
"install_devices_android_list_2": "Napauta \"Yhteydet\" ja sitten \"Wi-Fi\". Näytetään kaikki käytettävissä olevat langattomat verkot (mobiiliverkolle ei ole mahdollista määrittää omaa DNS-palvelinta).",
|
||||
"install_devices_android_list_3": "Napauta yhdistetyn verkon vieressä olevaa asetuskuvaketta tai paina verkkoa pitkään ja valitse \"Muokkaa verkkoa\".",
|
||||
"install_devices_android_list_4": "Saatat joutua napauttamaan \"Lisäasetukset\" nähdäksesi lisää valintoja. Muuttaaksesi DNS-asetuksia, on \"IP-asetukset\" -kohdan \"DHCP\" -valinta vaihdettava \"Staattinen\" -valintaan.",
|
||||
"install_devices_android_list_1": "Paina Android-laitteesi aloitusnäytöstä tai sovellusvalikosta \"Asetukset\".",
|
||||
"install_devices_android_list_2": "Paina \"Yhteydet\" ja sitten \"Wi-Fi\". Kaikki käytettävissä olevat langattomat verkot näytetään (mobiiliverkolle ei ole mahdollista määrittää omaa DNS-palvelinta).",
|
||||
"install_devices_android_list_3": "Paina yhdistetyn verkon vieressä olevaa asetuskuvaketta tai paina verkkoa pitkään ja valitse \"Muokkaa verkkoa\".",
|
||||
"install_devices_android_list_4": "Saatat joutua painamaan \"Lisäasetukset\" nähdäksesi enemmän valintoja. Muuttaaksesi DNS-asetuksia, on \"IP-asetukset\" -kohdan \"DHCP\" -valinta vaihdettava \"Staattinen\" -valintaan.",
|
||||
"install_devices_android_list_5": "Syötä \"DNS 1\" ja \"DNS 2\" -kenttiin AdGuard Home -palvelimesi osoitteet.",
|
||||
"install_devices_ios_list_1": "Napauta aloitusnäytöstä \"Asetukset\".",
|
||||
"install_devices_ios_list_1": "Paina aloitusnäytöstä \"Asetukset\".",
|
||||
"install_devices_ios_list_2": "Valitse vasemmalta \"Wi-Fi\" (mobiiliverkolle ei ole mahdollista määrittää omaa DNS-palvelinta).",
|
||||
"install_devices_ios_list_3": "Valitse yhdistetty verkko.",
|
||||
"install_devices_ios_list_3": "Valitse tällä hetkellä aktiivinen verkko.",
|
||||
"install_devices_ios_list_4": "Syötä \"DNS\" -kenttään AdGuard Home -palvelimesi osoitteet.",
|
||||
"get_started": "Aloita",
|
||||
"next": "Seuraava",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Jos HTTPS-portti on määritetty, on AdGuard Homen hallintapaneeli käytettävissä HTTPS-yhteydellä ja lisäksi tämä mahdollistaa myös DNS-over-HTTPS -yhteyden '/dns-query' -kohteessa.",
|
||||
"encryption_dot": "DNS-over-TLS -portti",
|
||||
"encryption_dot_desc": "Jos portti on määritetty, AdGuard Home suorittaa DNS-over-TLS -palvelimen tässä portissa.",
|
||||
"encryption_doq": "DNS-over-QUIC -portti (kokeellinen)",
|
||||
"encryption_doq_desc": "Jos portti on määritetty, AdGuard Home suorittaa DNS-over-QUIC -palvelimen tässä portissa. Ominaisuus on kokeellinen, eikä välttämättä luotettava. Lisäksi tätä tukevia päätelaitteita ei vielä ole kovin paljon.",
|
||||
"encryption_doq": "DNS-over-QUIC-portti",
|
||||
"encryption_doq_desc": "Jos portti on määritetty, AdGuard Home suorittaa DNS-over-QUIC-palvelimen tässä portissa.",
|
||||
"encryption_certificates": "Varmenteet",
|
||||
"encryption_certificates_desc": "Salauksen käyttämiseksi, on syötettävä verkkotunnuksellesi myönnetty, aito SSL-varmenneketju. Voit hankkia ilmaisen varmenteen osoitteesta <0>{{link}}</0> tai ostaa sellaisen joltakin luotetulta varmentajalta.",
|
||||
"encryption_certificates_input": "Kopioi/liitä PEM-koodatut varmenteesi tähän.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Kielletyt verkkotunnukset",
|
||||
"access_blocked_desc": "Ei pidä sekoittaa suodattimiin. AdGuard Home hylkää näiden verkkotunnusten DNS-pyynnöt, eivätkä nämä pyynnöt näy edes pyyntöhistoriassa. Tähän voidaan syöttää tarkkoja verkkotunnuksia, jokerimerkkejä tai URL-suodatussääntöjä, kuten \"example.org\", \"*.example.org\" tai \"||example.org^\".",
|
||||
"access_settings_saved": "Käytön asetukset tallennettiin",
|
||||
"updates_checked": "Päivitykset tarkastettiin",
|
||||
"updates_checked": "Uusi versio AdGuard Home -ohjelmasta on saatavana\n",
|
||||
"updates_version_equal": "AdGuard Home on ajan tasalla",
|
||||
"check_updates_now": "Tarkista päivitykset nyt",
|
||||
"dns_privacy": "DNS-tietosuoja",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Nom de serveur invalide",
|
||||
"form_error_subnet": "Le sous-réseau « {{cidr}} » ne contient pas l'adresse IP « {{ip}} »",
|
||||
"form_error_positive": "Doit être supérieur à 0",
|
||||
"form_error_gateway_ip": "Le bail ne peut pas avoir d'adresse IP de la passerelle",
|
||||
"out_of_range_error": "Doit être hors plage « {{start}} » - « {{end}} »",
|
||||
"lower_range_start_error": "Doit être inférieur au début de plage",
|
||||
"greater_range_start_error": "Doit être supérieur au début de plage",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "DNS normal (sur UDP, nom d’hôte) ;",
|
||||
"example_upstream_dot": "<0>DNS-over-TLS</0> chiffré ;",
|
||||
"example_upstream_doh": "<0>DNS-over-HTTPS</0> chiffré ;",
|
||||
"example_upstream_doq": "<0>DNS-over-QUIC</0> chiffré (expérimental) ;",
|
||||
"example_upstream_doq": "<0>DNS-over-QUIC</0> chiffré;",
|
||||
"example_upstream_sdns": "vous pouvez utiliser <0>DNS Stamps</0> pour <1>DNSCrypt</1> ou les résolveurs <2>DNS_over_HTTPS</2> ;",
|
||||
"example_upstream_tcp": "DNS classique (au-dessus de TCP) ;",
|
||||
"example_upstream_tcp_hostname": "DNS normal (sur TCP, nom d’hôte) ;",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Si le port HTTPS est configuré, l'interface administrateur de AdGuard Home sera accessible via HTTPS et fournira aussi un service DNS-over-HTTPS sur l'emplacement '/dns-query'.",
|
||||
"encryption_dot": "Port DNS-over-TLS",
|
||||
"encryption_dot_desc": "Si ce port est configuré, AdGuard Home exécutera un serveur DNS-over-TLS sur ce port.",
|
||||
"encryption_doq": "Port DNS sur QUIC (expérimental)",
|
||||
"encryption_doq_desc": "Si ce port est configuré, AdGuard Home exécutera un serveur DNS sur QUIC sur ce port. Ceci est expérimental et possiblement pas entièrement fiable. Peu de clients le prennent en charge actuellement.",
|
||||
"encryption_doq": "Port DNS sur QUIC",
|
||||
"encryption_doq_desc": "Si ce port est configuré, AdGuard Home exécutera un serveur DNS sur QUIC sur ce port. ",
|
||||
"encryption_certificates": "Certificats",
|
||||
"encryption_certificates_desc": "Pour utiliser le chiffrement, vous devez fournir une chaîne de certificats SSL valide pour votre domaine. Vous pouvez en obtenir une gratuitement sur <0>{{link}}</0> ou vous pouvez en acheter une via les Autorités de Certification de confiance.",
|
||||
"encryption_certificates_input": "Copiez/coller vos certificats encodés PEM ici.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Domaines interdits",
|
||||
"access_blocked_desc": "A ne pas confondre avec les filtres. AdGuard Home rejette les requêtes DNS correspondant à ces domaines, et ces requêtes n'apparaissent même pas dans le journal des requêtes. Vous pouvez spécifier des noms de domaine exacts, des caractères génériques ou des règles de filtrage d'URL, par exemple « exemple.org », « *.exemple.org » ou « ||example.org^ » de manière correspondante.",
|
||||
"access_settings_saved": "Paramètres d'accès enregistrés avec succès",
|
||||
"updates_checked": "Mises à jour vérifiées",
|
||||
"updates_checked": "Une nouvelle version de AdGuard Home est disponible",
|
||||
"updates_version_equal": "AdGuard Home est à jour",
|
||||
"check_updates_now": "Vérifier les mises à jour",
|
||||
"dns_privacy": "Confidentialité DNS",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Nevažeće ime poslužitelja",
|
||||
"form_error_subnet": "Podmrežu \"{{cidr}}\" ne sadrži IP adresu \"{{ip}}\"",
|
||||
"form_error_positive": "Mora biti veće od 0",
|
||||
"form_error_gateway_ip": "Najam ne može imati IP adresu pristupnika",
|
||||
"out_of_range_error": "Mora biti izvan ranga \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Mora biti niže od početnog ranga",
|
||||
"greater_range_start_error": "Mora biti veće od krajnjeg ranga",
|
||||
@@ -370,7 +371,7 @@
|
||||
"encryption_dot": "DNS-over-TLS port",
|
||||
"encryption_dot_desc": "Ako je ovaj port postavljen, AdGuard Home će pokrenuti DNS-over-TLS poslužitelj na ovom portu.",
|
||||
"encryption_doq": "DNS-over-QUIC port (eksperimentalno)",
|
||||
"encryption_doq_desc": "Ako je ovaj port postavljen, AdGuard Home će na ovom portu pokrenuti DNS-over-QUIC poslužitelj. Eksperimentalno je i možda nije pouzdano. Također, trenutno nema previše klijenata koji to podržavaju.",
|
||||
"encryption_doq_desc": "Ako je ovaj priključak konfiguriran, AdGuard Home će na ovom priključku pokretati DNS-over-QUIC poslužitelj.",
|
||||
"encryption_certificates": "Certifikati",
|
||||
"encryption_certificates_desc": "Da biste koristili šifriranje, za svoju domenu morate osigurati važeći lanac SSL certifikata. Besplatan certifikat možete dobiti na <0>{{link}}</0> ili ga možete kupiti od jednog od pouzdanih izdavatelja certifikata.",
|
||||
"encryption_certificates_input": "Zalijepite svoje PEM-kodirane certifikate ovdje.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Nedopuštene domene",
|
||||
"access_blocked_desc": "Ne smije se miješati s filterima. AdGuard Home ispušta DNS upite koji odgovaraju tim domenama, a ti se upiti čak i ne pojavljuju u zapisniku upita. Možete navesti točne nazive domena, zamjenske znakove ili pravila filtriranja URL-a, npr || example.org example.org. example.org^\" u skladu s tim.",
|
||||
"access_settings_saved": "Postavke pristupa su uspješno spremljene",
|
||||
"updates_checked": "Uspješna provjera ažuriranja",
|
||||
"updates_checked": "Dostupna je nova verzija AdGuard Home-a",
|
||||
"updates_version_equal": "AdGuard Home je ažuriran",
|
||||
"check_updates_now": "Provjeri ažuriranja sada",
|
||||
"dns_privacy": "DNS privatnost",
|
||||
@@ -511,7 +512,7 @@
|
||||
"statistics_configuration": "Postavke statistike",
|
||||
"statistics_retention": "Spremanje statistike",
|
||||
"statistics_retention_desc": "Ako smanjite vrijednost intervala, neki će podaci biti izgubljeni",
|
||||
"statistics_clear": " Poništi statistiku",
|
||||
"statistics_clear": "Poništi statistiku",
|
||||
"statistics_clear_confirm": "Jeste li sigurni da želite poništiti statistiku?",
|
||||
"statistics_retention_confirm": "Jeste li sigurni da želite promijeniti zadržavanje statistike? Ako smanjite vrijednost intervala, neki će podaci biti izgubljeni",
|
||||
"statistics_cleared": "Statistika je uspješno uklonjenja",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS kiszolgálók",
|
||||
"bootstrap_dns_desc": "A Bootstrap DNS szerverek a DoH/DoT feloldók IP-címeinek feloldására szolgálnak.",
|
||||
"local_ptr_title": "Privát DNS szerverek",
|
||||
"local_ptr_desc": "Azok a DNS szerverek, amiket az AdGuard Home a helyi PTR kérésekhez használ. Ezeket a szervereket arra használjuk, hogy reverse DNS által feloldjuk a kliensek hosztneveit privát IP címekre, például \"192.168.12.34\". Ha nincs beállítva, akkor az AdGuard Home, kivéve az ő saját címét, az operációs rendszer alapértelmezett DNS feloldók címeit fogja használni.",
|
||||
"local_ptr_desc": "Azok a DNS szerverek, amiket az AdGuard Home a helyi PTR kérésekhez használ. ",
|
||||
"local_ptr_default_resolver": "Alapesetben az AdGuard Home a következő reverse DNS feloldókat használja: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "Az AdGuard Home nem tudta meghatározni a privát reverse DNS feloldókat ehhez a rendszerhez.",
|
||||
"local_ptr_placeholder": "Adjon meg soronként egy kiszolgáló címet",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Érvénytelen szervernév",
|
||||
"form_error_subnet": "A(z) \"{{cidr}}\" alhálózat nem tartalmazza a(z) \"{{ip}}\" IP címet",
|
||||
"form_error_positive": "0-nál nagyobbnak kell lennie",
|
||||
"form_error_gateway_ip": "A bérleti szerződés nem tartalmazhatja az átjáró IP-címét",
|
||||
"out_of_range_error": "A következő tartományon kívül legyen: \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Kisebb legyen, mint a tartomány kezdete",
|
||||
"greater_range_start_error": "Nagyobbnak kell lennie, mint a tartomány kezdete",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "normál DNS (UDP felett, hostnév);",
|
||||
"example_upstream_dot": "titkosított <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "titkosított <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "titkosított <0>DNS-over-QUIC</0> (kísérleti);",
|
||||
"example_upstream_doq": "titkosított <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> a <1>DNSCrypt</1> vagy <2>DNS-over-HTTPS</2> feloldókhoz;",
|
||||
"example_upstream_tcp": "hagyományos DNS (TCP felett);",
|
||||
"example_upstream_tcp_hostname": "normál DNS (TCP felett, hostnév);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Ha a HTTPS port konfigurálva van, akkor az AdGuard Home admin felülete elérhető lesz a HTTPS-en keresztül, és ezenkívül DNS-over-HTTPS-t is biztosít a '/dns-query' helyen.",
|
||||
"encryption_dot": "DNS-over-TLS port",
|
||||
"encryption_dot_desc": "Ha ez a port be van állítva, az AdGuard Home DNS-over-TLS szerverként tud futni ezen a porton.",
|
||||
"encryption_doq": "DNS-over-QUIC port (kísérleti)",
|
||||
"encryption_doq_desc": "Ha ez a port be van állítva, akkor az AdGuard Home egy DNS-over-QUIC szerverként fog futni ezen a porton. Ez egy kísérleti funkció és nem biztos, hogy megbízható. Emellett nincs sok olyan kliens, ami támogatná ezt jelenleg.",
|
||||
"encryption_doq": "DNS-over-QUIC port",
|
||||
"encryption_doq_desc": "Ha ez a port be van állítva, akkor az AdGuard Home egy DNS-over-QUIC szerverként fog futni ezen a porton. ",
|
||||
"encryption_certificates": "Tanúsítványok",
|
||||
"encryption_certificates_desc": "A titkosítás használatához érvényes SSL tanúsítványláncot kell megadnia a domainjéhez. Ingyenes tanúsítványt kaphat a <0>{{link}}</0> webhelyen, vagy megvásárolhatja az egyik megbízható tanúsítványkibocsátó hatóságtól.",
|
||||
"encryption_certificates_input": "Másolja be ide a PEM-kódolt tanúsítványt.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Nem engedélyezett domainek",
|
||||
"access_blocked_desc": "Ne keverje össze ezt a szűrőkkel. Az AdGuard Home az összes DNS kérést el fogja dobni, ami ezekkel a domainekkel megegyezik, és ezek a lekérések nem is fognak megjelenni a lekérdezési naplóban sem. Megadhatja a pontos domain neveket, a helyettesítő karaktereket vagy az URL szűrési szabályokat, pl. ennek megfelelően \"example.org\", \"*.example.org\", vagy \"||example.org^\".",
|
||||
"access_settings_saved": "A hozzáférési beállítások sikeresen mentésre kerültek",
|
||||
"updates_checked": "A frissítések sikeresen ellenőrizve lettek",
|
||||
"updates_checked": "Elérhető az AdGuard Home új verziója",
|
||||
"updates_version_equal": "Az AdGuard Home naprakész",
|
||||
"check_updates_now": "Frissítések ellenőrzése most",
|
||||
"dns_privacy": "DNS Adatvédelem",
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
"example_upstream_udp": "DNS biasa (lebih dari UDP, nama host);",
|
||||
"example_upstream_dot": "terenkripsi <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "terenkripsi <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "terenkripsi <0>DNS-over-QUIC</0> (eksperimental);",
|
||||
"example_upstream_doq": "terenkripsi <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>Stempel DNS</0> untuk <1>DNSCrypt</1> atau pengarah <2>DNS-over-HTTPS</2>;",
|
||||
"example_upstream_tcp": "DNS reguler (melalui TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS biasa (lebih dari TCP, nama host);",
|
||||
@@ -369,8 +369,8 @@
|
||||
"encryption_https_desc": "Jika port HTTPS dikonfigurasi, antarmuka admin Home AdGuard akan dapat diakses melalui HTTPS, dan itu juga akan memberikan DNS-over-HTTPS di lokasi '/ dns-query'.",
|
||||
"encryption_dot": "Port DNS-over-TLS",
|
||||
"encryption_dot_desc": "Jika port ini terkonfigurasi, AdGuard Home akan menjalankan server DNS-over-TLS dalam port ini",
|
||||
"encryption_doq": "Port DNS-over-QUIC (eksperimental)",
|
||||
"encryption_doq_desc": "Jika port ini diatur secara sepesifik, AdGuard Home akan menjalankan server DNS-lewat-QUIC pada port ini. Ini adalah eksperimental dan mungkin tidak dapat diandalkan. Juga, tidak banyak klien yang mendukungnya saat ini.",
|
||||
"encryption_doq": "Port DNS-over-QUIC ",
|
||||
"encryption_doq_desc": "Jika port ini diatur secara sepesifik, AdGuard Home akan menjalankan server DNS-lewat-QUIC pada port ini.",
|
||||
"encryption_certificates": "Sertifikat",
|
||||
"encryption_certificates_desc": "Untuk menggunakan enkripsi, Anda perlu memberikan rantai sertifikat SSL yang valid untuk domain Anda. Anda bisa mendapatkan sertifikat gratis di <0>{{link}}</0> atau Anda dapat membelinya dari salah satu Otoritas Sertifikat tepercaya.",
|
||||
"encryption_certificates_input": "Salin / rekatkan sertifikat PEM yang disandikan di sini.",
|
||||
@@ -445,7 +445,7 @@
|
||||
"access_blocked_title": "Domain yang diblokir",
|
||||
"access_blocked_desc": "Jangan bingung dengan filter. AdGuard Home menghapus kueri DNS yang cocok dengan domain ini, dan kueri ini bahkan tidak muncul di log kueri. Anda dapat menentukan nama domain, karakter pengganti, atau aturan filter URL yang tepat, mis. \"example.org\", \"*.example.org\", atau \"||example.org^\" yang sesuai.",
|
||||
"access_settings_saved": "Pengaturan akses berhasil disimpan",
|
||||
"updates_checked": "Pembaruan berhasil dicek",
|
||||
"updates_checked": "Versi baru AdGuard Home tersedia\n",
|
||||
"updates_version_equal": "AdGuard Home sudah tebaru",
|
||||
"check_updates_now": "Periksa pembaruan sekarang",
|
||||
"dns_privacy": "DNS Privasi",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Nome server non valido",
|
||||
"form_error_subnet": "Il subnet \"{{cidr}}\" non contiene l'indirizzo IP \"{{ip}}\"",
|
||||
"form_error_positive": "Deve essere maggiore di 0",
|
||||
"form_error_gateway_ip": "Il leasing non può avere l'indirizzo IP del gateway",
|
||||
"out_of_range_error": "Deve essere fuori intervallo \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Deve essere inferiore dell'intervallo di inizio",
|
||||
"greater_range_start_error": "Deve essere maggiore dell'intervallo di inizio",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "DNS regolare (over UDP, nome host);",
|
||||
"example_upstream_dot": "<0>DNS su TLS</0> crittografato;",
|
||||
"example_upstream_doh": "<0>DNS su HTTPS</0> crittografato;",
|
||||
"example_upstream_doq": "<0>DNS su QUIC</0> crittografato (sperimentale);",
|
||||
"example_upstream_doq": "<0>DNS su QUIC</0> crittografato;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> per <1>DNSCrypt</1> oppure i risolutori <2>DNS su HTTPS</2>;",
|
||||
"example_upstream_tcp": "DNS regolare (over TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS regolare (over TCP, nome host);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Se la porta HTTPS è configurata, l'interfaccia di amministrazione di AdGuard Home sarà accessibile tramite HTTPS e fornirà anche DNS su HTTPS nella posizione \"/ dns-query\".",
|
||||
"encryption_dot": "DNS su porta TLS",
|
||||
"encryption_dot_desc": "Se questa porta è configurata, AdGuard Home eseguirà un server DNS su TLS su questa porta.",
|
||||
"encryption_doq": "Porta DNS su QUIC (sperimentale)",
|
||||
"encryption_doq_desc": "Se questa porta è configurata, AdGuard Home eseguirà un server DNS su porta QUIC. Questa opzione è sperimentale e potrebbe non risultare affidabile. Inoltre, al momento non sono molti i client a supportarla.",
|
||||
"encryption_doq": "Porta DNS su QUIC",
|
||||
"encryption_doq_desc": "Se questa porta è configurata, AdGuard Home eseguirà un server DNS su porta QUIC. ",
|
||||
"encryption_certificates": "Certificati",
|
||||
"encryption_certificates_desc": "Per utilizzare la crittografia, è necessario fornire una catena di certificati SSL valida per il proprio dominio. Puoi ottenere un certificato gratuito su <0> {{link}} </ 0> o puoi acquistarlo da una delle Autorità di certificazione attendibili.",
|
||||
"encryption_certificates_input": "Copia / incolla qui i certificati codificati PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Domini bloccati",
|
||||
"access_blocked_desc": "Da non confondere con i filtri. AdGuard Home eliminerà le richieste DNS corrispondenti a questi domini e queste richieste non verranno visualizzate nel relativo registro. Puoi specificare nomi di dominio esatti, caratteri jolly o regole di filtraggio URL, ad esempio \"esempio.org\", \"*.esempio.org\" o \"||esempio.org^\".",
|
||||
"access_settings_saved": "Impostazioni di accesso salvate correttamente",
|
||||
"updates_checked": "Verifica aggiornamenti riuscita",
|
||||
"updates_checked": "Nuova versione di AdGuard Home è disponibile",
|
||||
"updates_version_equal": "AdGuard Home è aggiornato",
|
||||
"check_updates_now": "Ricerca aggiornamenti ora",
|
||||
"dns_privacy": "Privacy DNS",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "サーバー名が無効です",
|
||||
"form_error_subnet": "IPアドレス「{{ip}}」がサブネット「{{cidr}}」に含まれていません",
|
||||
"form_error_positive": "0より大きい値でなければなりません",
|
||||
"form_error_gateway_ip": "リースはゲートウェイのIPアドレスになっていることができません",
|
||||
"out_of_range_error": "\"{{start}}\"〜\"{{end}}\" の範囲外である必要があります",
|
||||
"lower_range_start_error": "範囲開始よりも低い値である必要があります",
|
||||
"greater_range_start_error": "範囲開始値より大きい値でなければなりません",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "通常のDNS(over UDP, ホスト名)。",
|
||||
"example_upstream_dot": "暗号化されている <0>DNS-over-TLS</0>。",
|
||||
"example_upstream_doh": "暗号化されている <0>DNS-over-HTTPS</0>。",
|
||||
"example_upstream_doq": "暗号化 <0>DNS-over-QUIC</0>(実験的)。",
|
||||
"example_upstream_doq": "暗号化 <0>DNS-over-QUIC</0>。",
|
||||
"example_upstream_sdns": "<1>DNSCrypt</1> または <2>DNS-over-HTTPS</2> リゾルバのための <0>DNS Stamps</0>。",
|
||||
"example_upstream_tcp": "通常のDNS(over TCP)。",
|
||||
"example_upstream_tcp_hostname": "通常のDNS(over TCP, ホスト名)。",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "HTTPSポートが設定されていると、AdGuard Home 管理インターフェースはHTTPS経由でアクセス可能になり、そして「/dns-query」の場所にDNS-over-HTTPSも提供されます。",
|
||||
"encryption_dot": "DNS-over-TLS ポート",
|
||||
"encryption_dot_desc": "このポートが設定されていると、AdGuard HomeはこのポートでDNS-over-TLSサーバを実行します。",
|
||||
"encryption_doq": "DNS-over-QUIC ポート (実験的)",
|
||||
"encryption_doq_desc": "このポートが設定されていると、AdGuard HomeはこのポートにてDNS-over-QUICサーバーを実行します。これは実験的なものであり、頼りにならない可能性があります。また、現時点ではこのサーバーをサポートするクライアントも少ないです。",
|
||||
"encryption_doq": "DNS-over-QUIC ポート",
|
||||
"encryption_doq_desc": "このポートが設定されていると、AdGuard HomeはこのポートにてDNS-over-QUICサーバーを実行します。",
|
||||
"encryption_certificates": "証明書",
|
||||
"encryption_certificates_desc": "暗号化を使用するには、ドメインに有効なSSL証明書チェーンを提供する必要があります。無料の証明書は<0> {{link}} </0>で入手できます。または、信頼できる認証局のいずれかから購入することもできます。",
|
||||
"encryption_certificates_input": "ここにPEM形式の証明書をコピー/ペーストしてください。",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "拒否するドメイン",
|
||||
"access_blocked_desc": "こちらをフィルタと混同しないでください。AdGuard Homeは、ここで入力されたドメインに一致するDNSクエリをドロップし、そういったクエリはクエリログにも表示されません。ここでは、「example.org」、「*.example.org」、「 ||example.org^ 」など、特定のドメイン名、ワイルドカード、URLフィルタルールを入力できます。",
|
||||
"access_settings_saved": "アクセス設定の保存に成功しました",
|
||||
"updates_checked": "アップデートの確認に成功しました",
|
||||
"updates_checked": "AdGuard Homeの新バージョンが利用可能です。",
|
||||
"updates_version_equal": "AdGuard Homeは既に最新です",
|
||||
"check_updates_now": "今すぐアップデートを確認する",
|
||||
"dns_privacy": "DNSプライバシー",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "유효하지 않은 서버 이름",
|
||||
"form_error_subnet": "서브넷 \"{{cidr}}\"에 \"{{ip}}\" IP 주소가 없습니다",
|
||||
"form_error_positive": "0보다 커야 합니다",
|
||||
"form_error_gateway_ip": "임대는 게이트웨이의 IP 주소를 가질 수 없습니다",
|
||||
"out_of_range_error": "\"{{start}}\"-\"{{end}}\" 범위 밖이어야 합니다",
|
||||
"lower_range_start_error": "범위 시작보다 작은 값이어야 합니다",
|
||||
"greater_range_start_error": "범위 시작보다 큰 값이어야 합니다",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "일반 DNS (UDP를 통한, 호스트명);",
|
||||
"example_upstream_dot": "암호화된 <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "암호화된 <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "암호화된 <0>DNS-over-QUIC</0> (실험);",
|
||||
"example_upstream_doq": "암호화된 <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<1>DNSCrypt</1> 또는 <2>DNS-over-HTTPS</2> 리졸버를 위한 <0>DNS 스탬프</0>;",
|
||||
"example_upstream_tcp": "일반 DNS (TCP를 통한 접속);",
|
||||
"example_upstream_tcp_hostname": "일반 DNS (TCP를 통한, 호스트명);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "HTTPS 포트가 구성되면 HTTPS를 통해 AdGuard Home 관리자 인터페이스에 액세스할 수 있으며, '/dns-query' 위치에 DNS-over-HTTPS도 제공합니다.",
|
||||
"encryption_dot": "DNS-over-TLS 포트",
|
||||
"encryption_dot_desc": "이 포트가 구성된 경우 AdGuard Home 이 포트에서 DNS-over-TLS 서버를 실행합니다.",
|
||||
"encryption_doq": "DNS-over-QUIC 포트 (실험)",
|
||||
"encryption_doq_desc": "이 포트가 설정된 경우 AdGuard Home은 해당 포트에서 DNS-over-QUIC 서버를 실행합니다. 이것은 실험적이며 신뢰할 수 없습니다. 또한 현재 이를 지원하는 클라이언트가 많지 않습니다.",
|
||||
"encryption_doq": "DNS-over-QUIC 포트",
|
||||
"encryption_doq_desc": "이 포트가 설정된 경우 AdGuard Home은 해당 포트에서 DNS-over-QUIC 서버를 실행합니다. ",
|
||||
"encryption_certificates": "인증서",
|
||||
"encryption_certificates_desc": "암호화를 사용하려면 도메인에 대해 올바른 SSL 인증서 체인을 제공해야 합니다. <0>{{link}}</0>에서 무료 증명서를 받을 수도 있고, 신뢰할 수있는 인증 기관에서 구입할 수 있습니다.",
|
||||
"encryption_certificates_input": "PEM으로 인코딩된 인증서 여기에 복사/붙여넣기하세요.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "차단된 도메인",
|
||||
"access_blocked_desc": "이 기능을 필터와 혼동하지 마세요. AdGuard Home은 이 도메인에 대한 DNS 요청을 무시합니다. 여기에서는 'example.org' '*. example.org', '|| example.org ^'와 같은 특정 도메인 이름, 와일드 카드, URL 필터 규칙을 지정할 수 있습니다.",
|
||||
"access_settings_saved": "액세스 설정이 성공적으로 저장되었습니다.",
|
||||
"updates_checked": "업데이트가 성공적으로 확인되었습니다",
|
||||
"updates_checked": "AdGuard Home의 새 버전을 사용할 수 있습니다",
|
||||
"updates_version_equal": "AdGuard Home 최신 상태입니다.",
|
||||
"check_updates_now": "지금 업데이트 확인",
|
||||
"dns_privacy": "DNS 프라이버시",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Bootstrap DNS-servers",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS-servers worden gebruikt om IP-adressen op te lossen van de DoH / DoT-resolvers die u opgeeft als upstreams.",
|
||||
"local_ptr_title": "Private omgekeerde DNS-servers",
|
||||
"local_ptr_desc": "De DNS-servers die AdGuard Home zal gebruiken voor lokale PTR zoekopdrachten. Deze server wordt gebruikt om de hostnamen van de clients met private IP-adressen, bijvoorbeeld \"192.168.12.34\", dmv. rDNS. Indien niet ingesteld, gebruikt AdGuard Home automatisch je standaard DNS-resolver.",
|
||||
"local_ptr_desc": "De DNS-servers die AdGuard Home gebruikt voor lokale PTR-zoekopdrachten. Deze servers worden gebruikt om PTR-verzoeken voor adressen in privé-IP-bereiken op te lossen, bijvoorbeeld \"192.168.12.34\", met behulp van reverse DNS. Indien niet ingesteld, gebruikt AdGuard Home de adressen van de standaard DNS-resolvers van uw besturingssysteem, behalve de adressen van AdGuard Home zelf.",
|
||||
"local_ptr_default_resolver": "Standaard gebruikt AdGuard Home de volgende omgekeerde DNS-resolvers: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home kon voor dit systeem geen geschikte private omgekeerde DNS-resolvers bepalen.",
|
||||
"local_ptr_placeholder": "Voer één serveradres per regel in",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Lease kan niet het IP-adres van de gateway hebben",
|
||||
"out_of_range_error": "Moet buiten bereik zijn \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Moet lager zijn dan begin reeks",
|
||||
"greater_range_start_error": "Moet groter zijn dan begin reeks",
|
||||
@@ -126,7 +127,7 @@
|
||||
"top_blocked_domains": "Top geblokkeerde domeinen",
|
||||
"top_clients": "Top gebruikers",
|
||||
"no_clients_found": "Geen gebruikers gevonden",
|
||||
"general_statistics": "Generieke statistieken",
|
||||
"general_statistics": "Algemene statistieken",
|
||||
"number_of_dns_query_days": "Aantal verwerkte DNS aanvragen van de laatste {{count}} dag",
|
||||
"number_of_dns_query_days_plural": "Aantal verwerkte DNS aanvragen van de laatste {{count}} dagen",
|
||||
"number_of_dns_query_24_hours": "Aantal verwerkte DNS aanvragen van de laatste 24 uur",
|
||||
@@ -137,7 +138,7 @@
|
||||
"number_of_dns_query_to_safe_search": "Aantal DNS aanvragen in zoekmachines dmv geforceerd veilig zoeken",
|
||||
"average_processing_time": "Gemiddelde procestijd",
|
||||
"average_processing_time_hint": "Gemiddelde verwerkingstijd in milliseconden van een DNS aanvraag",
|
||||
"block_domain_use_filters_and_hosts": "Blokkeerd domeinen dmv filters en host bestanden",
|
||||
"block_domain_use_filters_and_hosts": "Domeinen blokkeren d.m.v. filters en host-bestanden",
|
||||
"filters_block_toggle_hint": "Je kan blokkeringsregels toevoegen in de <a>Filters</a> instellingen.",
|
||||
"use_adguard_browsing_sec": "Gebruik AdGuardBrowsing Security web service",
|
||||
"use_adguard_browsing_sec_hint": "AdGuard Home controleert of het domein in de blokkeerlijst voorkomt dmv Browsing Security web service. Dit gebeurt dmv een privacy vriendelijk API verzoek:een korte prefix van de domein naam met SHA256 hash wordt verzonden naar de server.",
|
||||
@@ -146,15 +147,15 @@
|
||||
"enforce_safe_search": "Veilig zoeken gebruiken",
|
||||
"enforce_save_search_hint": "AdGuard Home kan veilig zoeken forceren voor de volgende zoekmachines: Google, Youtube, Bing, en DuckDuckGo, Yandex, Pixabay.",
|
||||
"no_servers_specified": "Geen servers gespecificeerd",
|
||||
"general_settings": "Generieke instellingen",
|
||||
"dns_settings": "DNS Instellingen",
|
||||
"general_settings": "Algemene instellingen",
|
||||
"dns_settings": "DNS instellingen",
|
||||
"dns_blocklists": "DNS blokkeerlijsten",
|
||||
"dns_allowlists": "DNS toestemmingslijsten",
|
||||
"dns_blocklists_desc": "AdGuard Home zal domeinen blokkeren die voorkomen in de blokkeerlijsten.",
|
||||
"dns_allowlists_desc": "Domeinen in de DNS toestemmingslijsten worden toegestaan zelfs al komen ze voor in de blokkeerlijsten.",
|
||||
"custom_filtering_rules": "Aangepaste filter regels",
|
||||
"encryption_settings": "Encryptie Instellingen",
|
||||
"dhcp_settings": "DHCP Instellingen",
|
||||
"encryption_settings": "Encryptie instellingen",
|
||||
"dhcp_settings": "DHCP instellingen",
|
||||
"upstream_dns": "Upstream DNS-servers",
|
||||
"upstream_dns_help": "Een server-adres per regel invoeren. <a>Meer weten</a> over het configureren van upstream DNS-servers.",
|
||||
"upstream_dns_configured_in_file": "Geconfigureerd in {{path}}",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "standaard DNS (via UDP, hostnaam);",
|
||||
"example_upstream_dot": "versleutelde <0>DNS-via-TLS</0>;",
|
||||
"example_upstream_doh": "versleutelde <0>DNS-via-HTTPS</0>;",
|
||||
"example_upstream_doq": "versleutelde <0>DNS-via-QUIC</0> (experimenteel);",
|
||||
"example_upstream_doq": "versleutelde <0>DNS-via-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> voor <1>DNSCrypt</1> of <2>DNS-via-HTTPS</2> oplossingen;",
|
||||
"example_upstream_tcp": "standaard DNS (over TCP);",
|
||||
"example_upstream_tcp_hostname": "standaard DNS (via TCP, hostnaam);",
|
||||
@@ -225,8 +226,8 @@
|
||||
"block": "Blokkeren",
|
||||
"disallow_this_client": "Toepassing/systeem niet toelaten",
|
||||
"allow_this_client": "Toepassing/systeem toelaten",
|
||||
"block_for_this_client_only": "Alleen voor deze toepassing/dit systeem blokkeren",
|
||||
"unblock_for_this_client_only": "Alleen voor deze toepassing/dit systeem deblokkeren",
|
||||
"block_for_this_client_only": "Alleen voor deze cliënt blokkeren",
|
||||
"unblock_for_this_client_only": "Alleen voor deze cliënt deblokkeren",
|
||||
"time_table_header": "Tijd",
|
||||
"date": "Datum",
|
||||
"domain_name_table_header": "Domein naam",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Als de HTTPS-poort is geconfigureerd, is de AdGuard Home beheerders interface toegankelijk via HTTPS en biedt deze ook DNS-via-HTTPS op de locatie '/ dns-query'.",
|
||||
"encryption_dot": "DNS-via-TLS poort",
|
||||
"encryption_dot_desc": "Indien deze poort is geconfigureerd, zal AdGuard Home gebruik maken van een DNS-via-TLS server via deze poort.",
|
||||
"encryption_doq": "DNS-via-QUIC poort (experimenteel)",
|
||||
"encryption_doq_desc": "Als deze poort is geconfigureerd, zal AdGuard Home een DNS-via-QUIC server gebruiken via deze poort. Dit is experimenteel en kan onbetrouwbaar zijn. Er zijn overigens nog niet veel systemen die dit nu al ondersteunen.",
|
||||
"encryption_doq": "DNS-over-QUIC poort",
|
||||
"encryption_doq_desc": "Als deze poort is geconfigureerd, zal AdGuard Home een DNS-via-QUIC server gebruiken via deze poort.",
|
||||
"encryption_certificates": "Certificaten",
|
||||
"encryption_certificates_desc": "Om encryptie te gebruiken, moet u een geldige SSL certificaat voor uw domein opgeven. U kunt een gratis certificaat krijgen op <0> {{link}} </0> of u kunt het kopen bij een van de vertrouwde certificaatautoriteiten.",
|
||||
"encryption_certificates_input": "Kopieër en plak je PEM-gecodeerde certificaten hier.",
|
||||
@@ -403,12 +404,12 @@
|
||||
"down": "Uitgeschakeld",
|
||||
"fix": "Los op",
|
||||
"dns_providers": "hier is een <0>lijst of gekende DNS providers</0> waarvan je kan kiezen.",
|
||||
"update_now": "Update nu",
|
||||
"update_now": "Nu bijwerken",
|
||||
"update_failed": "Automatisch bijwerken is mislukt. <a>Volg deze stappen</a> om handmatig bij te werken.",
|
||||
"manual_update": "<a>Volg deze stappen</a> om handmatig bij te werken.",
|
||||
"processing_update": "Even geduld, AdGuard Home wordt bijgewerkt",
|
||||
"clients_title": "Permanente clients",
|
||||
"clients_desc": "Permanente client-records configureren voor apparaten verboden met AdGuard Home",
|
||||
"clients_desc": "Permanente client-records configureren voor apparaten verbonden met AdGuard Home",
|
||||
"settings_global": "Globaal",
|
||||
"settings_custom": "Aangepast",
|
||||
"table_client": "Gebruiker",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Niet toegelaten domeinen",
|
||||
"access_blocked_desc": "Verwar dit niet met filters. AdGuard Home zal deze DNS-zoekopdrachten niet uitvoeren die deze domeinen in de zoekopdracht bevatten. Hier kan je de exacte domeinnamen, wildcards en URL-filter-regels specifiëren, bijv. \"example.org\", \"*.example.org\" of \"||example.org^\".",
|
||||
"access_settings_saved": "Toegangsinstellingen succesvol opgeslagen",
|
||||
"updates_checked": "Met succes op updates gecontroleerd",
|
||||
"updates_checked": "Een nieuwe versie van AdGuard Home is beschikbaar\n",
|
||||
"updates_version_equal": "AdGuard Home is actueel",
|
||||
"check_updates_now": "Controleer op updates",
|
||||
"dns_privacy": "DNS Privacy",
|
||||
@@ -624,7 +625,7 @@
|
||||
"original_response": "Oorspronkelijke reactie",
|
||||
"click_to_view_queries": "Klik om queries te bekijken",
|
||||
"port_53_faq_link": "Poort 53 wordt vaak gebruikt door services als DNSStubListener- of de systeem DNS-resolver. Lees a.u.b. <0>deze instructie</0> hoe dit is op te lossen.",
|
||||
"adg_will_drop_dns_queries": "AdGuard Home zal alle DNS verzoeken van deze toepassing/dit systeem negeren.",
|
||||
"adg_will_drop_dns_queries": "AdGuard Home zal alle DNS-verzoeken van deze cliënt laten vervallen.",
|
||||
"filter_allowlist": "WAARSCHUWING: Deze actie zal ook de regel \"{{disallowed_rule}}\" uitsluiten van de lijst met toegestane clients.",
|
||||
"last_rule_in_allowlist": "Kan deze client niet weigeren omdat het uitsluiten van de regel \"{{disallowed_rule}}\" de lijst \"Toegestane clients\" zal UITSCHAKELEN.",
|
||||
"use_saved_key": "De eerder opgeslagen sleutel gebruiken",
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
"bootstrap_dns_desc": "Bootstrap-DNS-tjenere brukes til å oppklare IP-adressene til DoH/DoT-oppklarerene som du har valgt som oppstrømstjenere.",
|
||||
"local_ptr_title": "Private DNS-tjenere",
|
||||
"local_ptr_desc": "DNS-tjenerne som AdGuard Home bruker for lokale PTR-spørringer. Disse tjenerne brukes til å løse vertsnavnene til klienter med private IP-adresser, for eksempel \"192.168.12.34\", ved bruk av omvendt DNS. Hvis det ikke er angitt, bruker AdGuard Home adressene til standard-DNS-løserne til operativsystemet ditt, bortsett fra adressene til selve AdGuard Home.",
|
||||
"local_ptr_default_resolver": "Som standard, bruker AdGuard Home følgende revers-DNS-oppletere: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home klarte ikke å finne egnede private revers-DNS-oppletere for dette systemet.",
|
||||
"local_ptr_placeholder": "Skriv inn én tjeneradresse per linje",
|
||||
"resolve_clients_title": "Skru på revers-oppleting av klienters IP-adresser",
|
||||
"use_private_ptr_resolvers_title": "Bruk private omvendte DNS-løsere",
|
||||
"check_dhcp_servers": "Se etter DHCP-tjenere",
|
||||
"save_config": "Lagre oppsettet",
|
||||
@@ -21,20 +25,24 @@
|
||||
"dhcp_description": "Dersom ruteren din ikke har DHCP-innstillinger, kan du bruke AdGuard Home sin egen innebygde DHCP-tjener.",
|
||||
"dhcp_enable": "Skru på DHCP-tjeneren",
|
||||
"dhcp_disable": "Skru av DHCP-tjeneren",
|
||||
"dhcp_not_found": "Det er trygt å skru på den innebygde DHCP-tjeneren - vi kunne ikke finne noen aktive DHCP-tjenere i nettverket. Men vi oppfordrer deg til å dobbeltsjekke manuelt, siden vår automatiske test ikke gir 100% sikre svar ennå.",
|
||||
"dhcp_found": "En aktiv DHCP-tjener ble oppdaget i nettverket. Det er ikke trygt å bruke den innebygde DHCP-tjeneren.",
|
||||
"dhcp_leases": "DHCP-leieavtaler",
|
||||
"dhcp_static_leases": "Statiske DHCP-leieavtaler",
|
||||
"dhcp_leases_not_found": "Ingen DHCP-leieavtaler ble funnet",
|
||||
"dhcp_config_saved": "Lagret DHCP-tjeneroppsettet",
|
||||
"dhcp_ipv4_settings": "DHCP IPv4-innstillinger",
|
||||
"dhcp_ipv6_settings": "DHCP IPv6-innstillinger",
|
||||
"form_error_required": "Påkrevd felt",
|
||||
"form_error_ip4_format": "Ugyldig IPv4-format",
|
||||
"form_error_ip6_format": "Ugyldig IPv6-format",
|
||||
"form_error_ip_format": "Ugyldig IP-adresse",
|
||||
"form_error_ip_format": "Ugyldig IPv4-format",
|
||||
"form_error_mac_format": "Ugyldig MAC-format",
|
||||
"form_error_client_id_format": "Ugyldig ID-klientformat",
|
||||
"form_error_server_name": "Ugyldig tjenernavn",
|
||||
"form_error_subnet": "Undernettet «{{cidr}}» inneholder ikke IP-adressen «{{ip}}»",
|
||||
"form_error_positive": "Må være høyere enn 0",
|
||||
"greater_range_start_error": "Må være høyere enn rekkeviddens start",
|
||||
"dhcp_form_gateway_input": "Gateway-IP",
|
||||
"dhcp_form_subnet_input": "Nettverksmaske",
|
||||
"dhcp_form_range_title": "Spennvidden til IP-adressene",
|
||||
@@ -48,11 +56,16 @@
|
||||
"ip": "IP-adresse",
|
||||
"dhcp_table_hostname": "Vertsnavn",
|
||||
"dhcp_table_expires": "Utløper",
|
||||
"dhcp_warning": "Hvis du vil aktivere DHCP-tjeneren likevel, så sørg for at det ikke er noen andre aktive DHCP-tjenere i nettverket ditt. Ellers kan det knekke internettilgangen til tilkoblede enheter!",
|
||||
"dhcp_error": "Vi klarte ikke å fastslå om det er en annen DHCP-tjener i nettverket ditt eller ikke.",
|
||||
"dhcp_static_ip_error": "For å kunne bruke DHCP-tjeneren, må det være satt en statisk IP-adresse. Vi klarte ikke å finne ut om dette nettverksgrensesnittet har blitt satt opp med en statisk IP-adresse. Vennligst sett opp en statisk IP-adresse manuelt.",
|
||||
"dhcp_dynamic_ip_found": "Systemet ditt bruker et oppsett med dynamisk IP-adresse for grensesnittet <0>{{interfaceName}}</0>. For å kunne bruke DHCP-tjeneren, må en statisk IP-adresse ha blitt satt opp. Din nåværende IP-adresse er <0>{{ipAddress}}</0>. Vi vil automatisk gjøre denne IP-adressen statisk hvis du trykker på «Skru på DHCP»-knappen.",
|
||||
"dhcp_lease_added": "Den statiske leieavtalen «{{key}}» ble vellykket lagt til",
|
||||
"dhcp_lease_deleted": "Den statiske leieavtalen «{{key}}» ble vellykket lagt slettet",
|
||||
"dhcp_new_static_lease": "Ny statisk leieavtale",
|
||||
"dhcp_static_leases_not_found": "Ingen statiske DHCP-leieavtaler ble funnet",
|
||||
"dhcp_add_static_lease": "Legg til statisk leieavtale",
|
||||
"dhcp_reset": "Er du sikker på at du vil tilbakestille DHCP-oppsettet?",
|
||||
"country": "Land",
|
||||
"city": "By",
|
||||
"delete_confirm": "Er du sikker på at du vil slette «{{key}}»?",
|
||||
@@ -91,15 +104,24 @@
|
||||
"stats_adult": "Blokkerte voksennettsteder",
|
||||
"stats_query_domain": "Mest forespurte domener",
|
||||
"for_last_24_hours": "de siste 24 timene",
|
||||
"for_last_days": "det siste døgnet",
|
||||
"for_last_days": "for den siste {{count}} dagen",
|
||||
"for_last_days_plural": "de siste {{count}} dagene",
|
||||
"stats_disabled": "Statistikkene har blitt skrudd av. Du kan skru den på fra <0>innstillingssiden</0>.",
|
||||
"stats_disabled_short": "Statistikkene har blitt skrudd av",
|
||||
"no_domains_found": "Ingen domener ble funnet",
|
||||
"requests_count": "Antall forespørsler",
|
||||
"top_blocked_domains": "Mest blokkerte domener",
|
||||
"top_clients": "Vanligste klienter",
|
||||
"no_clients_found": "Ingen klienter ble funnet",
|
||||
"general_statistics": "Generelle statistikker",
|
||||
"number_of_dns_query_days": "Antall DNS-spørringer behandlet for de siste {{count}} dagene",
|
||||
"number_of_dns_query_days_plural": "Antall DNS-forespørsler som ble behandlet de siste {{count}} dagene",
|
||||
"number_of_dns_query_24_hours": "Antall DNS-forespørsler som ble behandlet de siste 24 timene",
|
||||
"number_of_dns_query_blocked_24_hours": "Antall DNS-forespørsler som ble blokkert av adblock-filtre, hosts-lister, og domene-lister",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "Antall DNS-forespørsler som ble blokkert av AdGuard sin nettlesersikkerhetsmodul",
|
||||
"number_of_dns_query_blocked_24_hours_adult": "Antall voksennettsteder som ble blokkert",
|
||||
"enforced_save_search": "Påtvungede barnevennlige søk",
|
||||
"number_of_dns_query_to_safe_search": "Antall DNS-forespørsler til søkemotorer der \"Safe Search\" ble fremtvunget",
|
||||
"average_processing_time": "Gjennomsnittlig behandlingstid",
|
||||
"average_processing_time_hint": "Gjennomsnittstid for behandling av DNS-forespørsler i millisekunder",
|
||||
"block_domain_use_filters_and_hosts": "Blokker domener ved hjelp av filtre, «hosts»-filer, og rå domener",
|
||||
@@ -177,10 +199,11 @@
|
||||
"example_upstream_regular": "vanlig DNS (over UDP)",
|
||||
"example_upstream_dot": "kryptert <0>DNS-over-TLS</0>",
|
||||
"example_upstream_doh": "kryptert <0>DNS-over-HTTPS</0>",
|
||||
"example_upstream_doq": "kryptert <0>DNS-over-QUIC</0>",
|
||||
"example_upstream_doq": "kryptert <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "du kan bruke <0>DNS-stempler</0> med <1>DNSCrypt</1> eller <2>DNS-over-HTTPS</2>-behandlere",
|
||||
"example_upstream_tcp": "vanlig DNS (over TCP)",
|
||||
"all_lists_up_to_date_toast": "Alle listene er allerede oppdatert",
|
||||
"updated_upstream_dns_toast": "Oppdaterte oppstrøms-DNS-tjenerne",
|
||||
"dns_test_ok_toast": "De spesifiserte DNS-tjenerne fungerer riktig",
|
||||
"dns_test_not_ok_toast": "Tjeneren «{{key}}» kunne ikke brukes, vennligst dobbeltsjekk at du har skrevet den riktig",
|
||||
"unblock": "Tillat",
|
||||
@@ -241,13 +264,16 @@
|
||||
"dns_over_quic": "DNS-over-QUIC",
|
||||
"client_id": "Klient-ID",
|
||||
"client_id_placeholder": "Skriv inn klient-ID",
|
||||
"client_id_desc": "Forskjellige klienter kan identifiserer med en spesiell klient-ID. <a>Her</a> kan du lære mer om hvordan man identifiserer klienter.",
|
||||
"download_mobileconfig_doh": "Last ned .mobileconfig for DNS-over-HTTPS",
|
||||
"download_mobileconfig_dot": "Last ned .mobileconfig for DNS-over-TLS",
|
||||
"download_mobileconfig": "Last ned oppsettsfil",
|
||||
"plain_dns": "Ordinær DNS",
|
||||
"form_enter_rate_limit": "Skriv inn forespørselsfrekvensgrense",
|
||||
"rate_limit": "Forespørselsfrekvensgrense",
|
||||
"edns_enable": "Aktiver EDNS-klientundernett",
|
||||
"edns_cs_desc": "Hvis det er skrudd på, vil AdGuard Home sende klientenes undernett til DNS-tjenerne.",
|
||||
"rate_limit_desc": "Antallet forespørsler per sekund som én enkelt klient har lov til å be om (0: ubegrenset)",
|
||||
"blocking_ipv4_desc": "IP-adressen som det skal svares med for blokkerte A-forespørsler",
|
||||
"blocking_ipv6_desc": "IP-adressen som det skal svares med for blokkerte AAAA-forespørsler",
|
||||
"blocking_mode_default": "Standard: Svar med null-IP-adresse (0.0.0.0 for A; :: for AAAA) når den blokkeres av adblock-aktige oppføringer; svar med IP-adressen som er spesifisert i oppføringen når den blokkeres av /etc/hosts-typeoppføringer",
|
||||
@@ -289,8 +315,10 @@
|
||||
"install_devices_router": "Ruter",
|
||||
"install_devices_router_desc": "Dette oppsettet vil automatisk dekke alle enhetene som er koblet til hjemmeruteren din, og du vil ikke måtte sette opp hver av dem manuelt.",
|
||||
"install_devices_address": "AdGuard Home-DNS-tjeneren lytter til de følgende adressene",
|
||||
"install_devices_router_list_1": "Åpne innstillingene til ruteren din. Vanligvis kan du få tilgang til den på nettleseren din gjennom en URL (f.eks. http://192.168.0.1/ eller http://192.168.1.1/). Du kan bli spurt om å skrive inn passordet ditt. Hvis du ikke husker det, kan du som oftest tilbakestille passordet ditt ved å trykke på knapp på selve ruteren. Noen rutere krever et spesifikt program, som i så fall er ment å allerede ha blitt installert på din PC/mobil.",
|
||||
"install_devices_router_list_2": "Finn DHCP-/DNS-innstillingene. Se etter DNS-bokstavene ved siden av et felt som tillater to eller tre sett med sifre, som hver er delt opp i fire grupper på 1-3 sifre.",
|
||||
"install_devices_router_list_3": "Skriv inn din AdGuard Home-tjeners adresser her.",
|
||||
"install_devices_router_list_4": "På noen rutertyper, f.eks. Altibox sine hjemmesentraler, kan man ikke velge en selvvalgt DNS-tjener. I så fall kan det hjelpe på saken om du setter opp AdGuard Home som en <0>DHCP-tjener</0>. Alternativt, burde du se i bruksanvisningen til din spesifikke rutermodell om hvordan man tilpasser DNS-tjenerne.",
|
||||
"install_devices_windows_list_1": "Åpne «Kontrollpanel» gjennom Start-menyen eller et Windows-søk.",
|
||||
"install_devices_windows_list_2": "Gå til «Nettverk og internett»-kategorien, og så til «Nettverks- og delingssenter».",
|
||||
"install_devices_windows_list_3": "På den venstre siden av skjermen, finn «Endre innstillinger for nettverkskort» og klikk på den.",
|
||||
@@ -316,6 +344,7 @@
|
||||
"install_saved": "Lagringen var vellykket",
|
||||
"encryption_title": "Kryptering",
|
||||
"encryption_desc": "Krypteringsstøtte (HTTPS/TLS) for både DNS og admin-nettgrensesnittet",
|
||||
"encryption_config_saved": "Krypteringsoppsettet ble lagret",
|
||||
"encryption_server": "Tjenerens navn",
|
||||
"encryption_server_enter": "Skriv inn domenenavnet ditt",
|
||||
"encryption_server_desc": "For å kunne bruke HTTPS, må du skrive inn tjenernavnet som samsvarer med ditt SSL-sertifikat eller jokertegnsertifikat. Hvis feltet er tomt, vil den akseptere TLS-tilkoblinger til ethvert domene.",
|
||||
@@ -325,8 +354,8 @@
|
||||
"encryption_https_desc": "Dersom HTTPS-porten er satt opp, vil AdGuard Home sitt admin-grensesnitt være tilgjengelig gjennom HTTPS, og vil også sørge for DNS-over-HTTPS på «/dns-query»-plasseringen.",
|
||||
"encryption_dot": "'DNS-over-TLS'-port",
|
||||
"encryption_dot_desc": "Dersom denne porten er satt opp, vil AdGuard Home kjøre en 'DNS-over-TLS'-tjener på denne porten.",
|
||||
"encryption_doq": "'DNS-over-QUIC'-port",
|
||||
"encryption_doq_desc": "Dersom denne porten er satt opp, vil AdGuard Home kjøre en DNS-over-QUIC-tjener på denne porten. Den er eksperimentell og vil kanskje ikke være pålitelig. I tillegg er det ikke så altfor mange klienter som støtter det for øyeblikket.",
|
||||
"encryption_doq": "DNS-over-QUIC-port",
|
||||
"encryption_doq_desc": "Dersom denne porten er satt opp, vil AdGuard Home kjøre en DNS-over-QUIC-tjener på denne porten. ",
|
||||
"encryption_certificates": "Sertifikater",
|
||||
"encryption_certificates_desc": "For å bruke kryptering, må du skrive inn et gyldig SSL-sertifikatkjede for domenet ditt. Du kan få et gratis sertifikat hos <0>{{link}}</0>, eller kjøpe et fra en av de troverdige sertifikatsautoritetene.",
|
||||
"encryption_certificates_input": "Kopier / lim inn dine PEM-kodede sertifikater her.",
|
||||
@@ -346,7 +375,9 @@
|
||||
"encryption_reset": "Er du sikker på at du vil tilbakestille krypteringsinnstillingene?",
|
||||
"topline_expiring_certificate": "Ditt SSL-sertifikat er i ferd med å utløpe. Oppdater <0>Krypteringsinnstillinger</0>.",
|
||||
"topline_expired_certificate": "SSL-sertifikatet har utløpt. Oppdater <0>Krypteringsinnstillinger</0>.",
|
||||
"form_error_port_range": "Skriv inn et portnummer i området 80-65535",
|
||||
"form_error_port_unsafe": "Denne porten er ikke trygg",
|
||||
"form_error_equal": "Burde ikke være de samme",
|
||||
"form_error_password": "Passordet samsvarer ikke",
|
||||
"reset_settings": "Tilbakestill innstillinger",
|
||||
"update_announcement": "AdGuard Home {{version}} er nå tilgjengelig! <0>Klikk her</0> for mere informasjon.",
|
||||
@@ -374,6 +405,7 @@
|
||||
"ip_address": "IP-adresse",
|
||||
"client_identifier_desc": "Klienter kan bli identifisert gjennom IP-adressen, CIDR, MAC-adressen, eller en spesiell klient-ID (kan også brukes for DoT/DoH/DoQ). <0>Her</0> kan du lære mer om å identifisere klienter.",
|
||||
"form_enter_ip": "Skriv inn IP",
|
||||
"form_enter_subnet_ip": "Skriv inn en IP-adresse i undernettet «{{cidr}}»",
|
||||
"form_enter_mac": "Skriv inn MAC",
|
||||
"form_enter_id": "Skriv inn identifikator",
|
||||
"form_add_id": "Legg til identifikator",
|
||||
@@ -397,7 +429,7 @@
|
||||
"access_blocked_title": "Blokkerte domener",
|
||||
"access_blocked_desc": "Ikke forveksle dette med filtre. AdGuard Home vil nekte å behandle DNS-forespørsler som har disse domenene, og disse forespørslene dukker ikke engang opp i forespørselsloggen. Du kan spesifisere nøyaktige domene navn, jokertegn, eller URL-filterregler, f.eks. «example.org», «*.example.log» eller «||example.org^» derav.",
|
||||
"access_settings_saved": "Tilgangsinnstillingene ble vellykket lagret",
|
||||
"updates_checked": "Oppdateringene ble vellykket sett etter",
|
||||
"updates_checked": "En ny versjon av AdGuard Home er tilgjengelig",
|
||||
"updates_version_equal": "AdGuard Home er fullt oppdatert",
|
||||
"check_updates_now": "Se etter oppdateringer nå",
|
||||
"dns_privacy": "DNS-privatliv",
|
||||
@@ -416,6 +448,7 @@
|
||||
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> støtter <1>DNS-over-HTTPS</1>.",
|
||||
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> støtter <1>DNS-over-HTTPS</1>.",
|
||||
"setup_dns_privacy_other_5": "Du finner flere implementeringer <0>her</0> og <1>her</1>.",
|
||||
"setup_dns_privacy_ioc_mac": "iOS- og macOS-oppsett",
|
||||
"setup_dns_notice": "For å benytte <1>DNS-over-HTTPS</1> eller <1>DNS-over-TLS</1>, må du <0>sette opp Kryptering</0> i AdGuard Home-innstillingene.",
|
||||
"rewrite_added": "DNS-omdirigeringen for «{{key}}» ble vellykket lagt til",
|
||||
"rewrite_deleted": "DNS-omdirigeringen for «{{key}}» ble vellykket slettet",
|
||||
@@ -453,6 +486,7 @@
|
||||
"interval_days": "{{count}} dag",
|
||||
"interval_days_plural": "{{count}} dager",
|
||||
"domain": "Domene",
|
||||
"punycode": "Punycode",
|
||||
"answer": "Svar",
|
||||
"filter_added_successfully": "Filteret har blitt vellykket lagt til",
|
||||
"filter_removed_successfully": "Listen ble vellykket fjernet",
|
||||
@@ -499,6 +533,7 @@
|
||||
"disable_ipv6": "Skru av IPv6",
|
||||
"disable_ipv6_desc": "Hvis dette er skrudd på, vil alle DNS-forespørslene til IPv6-adresser (AAAA-type) bli droppet.",
|
||||
"fastest_addr": "Raskeste IP-adresse",
|
||||
"fastest_addr_desc": "Forespør alle DNS-tjenerne og hent den raskeste IP-adressen blant alle svarene. Dette vil gjøre DNS-forespørslene tregere, siden vi må vente på svar fra alle DNS-tjenerne, men det vil forbedre tilkoblingen generelt.",
|
||||
"autofix_warning_text": "Hvis du klikker på «Fiks», vil AdGuard Home sette opp systemet ditt til å bruke 'AdGuard Home'-DNS-tjeneren.",
|
||||
"autofix_warning_list": "Den vil utføre disse handlingene: <0>Skru av systemets DNSStubListener</0> <0>Sette DNS-tjeneradressen til 127.0.0.1</0> <0>Bytte ut det symbolske lenkemålet til /etc/resolv.conf med /run/systemd/resolve/resolv.conf</0> <0>Stoppe DNSStubListener (gjeninnlast 'systemd-resolved'-tjenesten)</0>",
|
||||
"autofix_warning_result": "Som følge av det vil alle DNS-forespørsler fra systemet ditt bli behandlet av AdGuard Home som standard.",
|
||||
@@ -528,6 +563,7 @@
|
||||
"set_static_ip": "Velg en statisk IP-adresse",
|
||||
"install_static_ok": "Gode nyheter! Den statiske IP-adressen er allerede satt opp",
|
||||
"install_static_error": "AdGuard Home kan ikke sette opp automatisk i dette nettverksgrensesnitt. Vennligst let opp anvisningen for hvordan man gjør det manuellt.",
|
||||
"install_static_configure": "Vi har oppdaget at det brukes en dynamisk IP-adresse — <0>{{ip}}</0>. Vil du bruke det som din statiske adresse?",
|
||||
"confirm_static_ip": "AdGuard Home vil sette opp {{ip}} til å bli din statiske IP-adresse. Vil du fortsette?",
|
||||
"list_updated": "{{count}} liste oppdatert",
|
||||
"list_updated_plural": "{{count}} lister oppdatert",
|
||||
@@ -539,12 +575,12 @@
|
||||
"show_whitelisted_responses": "Hvitelistet",
|
||||
"show_processed_responses": "Bearbeidet",
|
||||
"blocked_safebrowsing": "Blokkert av barnevennlig nettlesing",
|
||||
"blocked_adult_websites": "Blokkert av foreldrekontroll",
|
||||
"blocked_adult_websites": "Blokkerte voksennettsteder",
|
||||
"blocked_threats": "Blokkerte trusler",
|
||||
"allowed": "Unntak",
|
||||
"filtered": "Filtrert",
|
||||
"rewritten": "Omskrevet",
|
||||
"safe_search": "Aktivert sikkert søk",
|
||||
"safe_search": "Trygge søk",
|
||||
"blocklist": "Blokkeringsliste",
|
||||
"milliseconds_abbreviation": "ms",
|
||||
"cache_size": "Mellomlagerstørrelse",
|
||||
@@ -564,13 +600,16 @@
|
||||
"filter_category_regional": "Regional",
|
||||
"filter_category_other": "Andre",
|
||||
"filter_category_general_desc": "Lister som blokkerer sporing og reklamer på de fleste enheter",
|
||||
"filter_category_security_desc": "Lister som spesialiserer seg på å blokkere skadevare-, phishing- eller svindeldomener",
|
||||
"filter_category_regional_desc": "Lister som fokuserer på regionale reklamer og sporingstjenere",
|
||||
"filter_category_other_desc": "Andre blokkeringslister",
|
||||
"setup_config_to_enable_dhcp_server": "Oppsett for å skru på DHCP-tjeneren",
|
||||
"original_response": "Opprinnelig svar",
|
||||
"click_to_view_queries": "Klikk for å vise forespørsler",
|
||||
"port_53_faq_link": "Port 53 er ofte opptatt av «DNSStubListener»- eller «systemd-resolved»-tjenestene. Vennligst les <0>denne instruksjonen</0> om hvordan man løser dette.",
|
||||
"adg_will_drop_dns_queries": "AdGuard Home vil droppe alle DNS-forespørsler fra denne klienten.",
|
||||
"use_saved_key": "Bruk den tidligere lagrede nøkkelen",
|
||||
"parental_control": "Foreldrekontroll",
|
||||
"safe_browsing": "Sikker surfing",
|
||||
"served_from_cache": "{{value}} <i>(formidlet fra mellomlageret)</i>"
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Lease nie może mieć adresu IP bramy",
|
||||
"out_of_range_error": "Musi być spoza zakresu \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Musi być niższy niż początek zakresu",
|
||||
"greater_range_start_error": "Musi być większy niż początek zakresu",
|
||||
@@ -117,7 +118,7 @@
|
||||
"stats_adult": "Zablokowane witryny dla dorosłych",
|
||||
"stats_query_domain": "Najczęściej wyszukiwane domeny",
|
||||
"for_last_24_hours": "przez ostatnie 24 godziny",
|
||||
"for_last_days": "z ostatniego dnia",
|
||||
"for_last_days": "za ostatni dzień {{count}}",
|
||||
"for_last_days_plural": "z ostatnich {{count}} dni",
|
||||
"stats_disabled": "Statystyki zostały wyłączone. Można je włączyć na <0>stronie ustawień</0>.",
|
||||
"stats_disabled_short": "Statystyki zostały wyłączone",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "zwykły DNS (przez UDP, nazwa hosta);",
|
||||
"example_upstream_dot": "zaszyfrowany <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "zaszyfrowany <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "zaszyfrowany <0>DNS-over-QUIC</0> (eksperymentalny);",
|
||||
"example_upstream_doq": "zaszyfrowany <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>Stempel DNS</0> dla resolwerów <1>DNSCrypt</1> lub <2>DNS-over-HTTPS</2>;",
|
||||
"example_upstream_tcp": "zwykły DNS (przez TCP);",
|
||||
"example_upstream_tcp_hostname": "zwykły DNS (przez TCP, nazwa hosta);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Jeśli port HTTPS jest skonfigurowany, interfejs administratora AdGuard Home będzie dostępny za pośrednictwem protokołu HTTPS i zapewni DNS przez HTTPS w lokalizacji zapytania '/dns-query'.",
|
||||
"encryption_dot": "Port DNS-over-TLS",
|
||||
"encryption_dot_desc": "Jeśli ten port jest skonfigurowany, AdGuard Home uruchomi serwer DNS-over-TLS na tym porcie.",
|
||||
"encryption_doq": "Port DNS-over-QUIC (eksperymentalny)",
|
||||
"encryption_doq_desc": "Jeśli ten port jest skonfigurowany, AdGuard Home uruchomi serwer DNS-over-QUIC na tym porcie. Jest to funkcja eksperymentalna i może nie być stabilna. Ponadto, w tej chwili nie ma zbyt wielu klientów, którzy go obsługują.",
|
||||
"encryption_doq": "Port DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Jeśli ten port jest skonfigurowany, AdGuard Home uruchomi serwer DNS-over-QUIC na tym porcie.",
|
||||
"encryption_certificates": "Certyfikaty",
|
||||
"encryption_certificates_desc": "Aby korzystać z szyfrowania, musisz podać prawidłowy łańcuch certyfikatów SSL dla swojej domeny. Możesz uzyskać bezpłatny certyfikat na <0>{{link}}</0> lub możesz go kupić od jednego z zaufanych urzędów certyfikacji.",
|
||||
"encryption_certificates_input": "Kopiuj/wklej tutaj swoje zakodowane certyfikaty PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Niedozwolone domeny",
|
||||
"access_blocked_desc": "Nie należy ich mylić z filtrami. AdGuard Home usuwa zapytania DNS pasujące do tych domen, a zapytania te nie pojawiają się nawet w dzienniku zapytań. Możesz określić dokładne nazwy domen, symbole wieloznaczne lub reguły filtrowania adresów URL, np. \"example.org\", \"*.example.org\" lub \"||example.org^\".",
|
||||
"access_settings_saved": "Ustawienia dostępu zostały pomyślnie zapisane",
|
||||
"updates_checked": "Aktualizacje pomyślnie sprawdzone",
|
||||
"updates_checked": "Dostępna jest nowa wersja programu AdGuard Home\n",
|
||||
"updates_version_equal": "AdGuard Home jest aktualny",
|
||||
"check_updates_now": "Sprawdź aktualizacje teraz",
|
||||
"dns_privacy": "Prywatny DNS",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Servidores DNS de inicialização",
|
||||
"bootstrap_dns_desc": "Servidores DNS de inicialização são usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams.",
|
||||
"local_ptr_title": "Servidores DNS reversos privados",
|
||||
"local_ptr_desc": "Os servidores DNS que o AdGuard Home usa para consultas PTR locais. Esses servidores são usados para resolver os nomes de host de clientes com endereços IP privados, por exemplo \"192.168.12.34\", usando DNS reverso. Se não for definido, o AdGuard Home usa os endereços dos resolvedores DNS padrão do seu sistema operacional, exceto os endereços do AdGuard Home.",
|
||||
"local_ptr_desc": "Os servidores DNS que o AdGuard Home usa para consultas PTR locais. Esses servidores são usados para resolver solicitações de PTR para endereços em intervalos de IP privados, por exemplo \"192.168.12.34\", usando DNS reverso. Se não estiver definido, o AdGuard Home usa os endereços dos resolvedores de DNS padrão do seu sistema operacional, exceto os endereços do próprio AdGuard Home.",
|
||||
"local_ptr_default_resolver": "Por padrão, o AdGuard Home usa os seguintes resolvedores de DNS reverso: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "A página inicial do AdGuard não conseguiu determinar resolvedores DNS reversos privados adequados para este sistema.",
|
||||
"local_ptr_placeholder": "Insira um endereço de servidor por linha",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "A concessão não pode ter o endereço IP do gateway",
|
||||
"out_of_range_error": "Deve estar fora do intervalo \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Deve ser inferior ao início do intervalo",
|
||||
"greater_range_start_error": "Deve ser maior que o início do intervalo",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "DNS normal (através do UDP, nome do servidor);",
|
||||
"example_upstream_dot": "<0>DNS-sobre-TLS</0> criptografado;",
|
||||
"example_upstream_doh": "<0>DNS-sobre-HTTPS</0> criptografado;",
|
||||
"example_upstream_doq": "<0>DNS-sobre-QUIC</0> criptografado (experimental);",
|
||||
"example_upstream_doq": "<0>DNS-sobre-QUIC</0> criptografado;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> para o <1>DNSCrypt</1> ou usar os resolvedores <2>DNS-sobre-HTTPS</2>;",
|
||||
"example_upstream_tcp": "DNS regular (através do TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS normal (através do TCP, nome do servidor);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Se a porta HTTPS estiver configurada, a interface administrativa do AdGuard Home será acessível via HTTPS e também fornecerá o DNS-sobre-HTTPS no local '/dns-query'.",
|
||||
"encryption_dot": "Porta DNS-sobre-TLS",
|
||||
"encryption_dot_desc": "Se essa porta estiver configurada, o AdGuard Home irá executar o servidor DNS-sobre- TSL nesta porta.",
|
||||
"encryption_doq": "Porta DNS-sobre-QUIC (experimental)",
|
||||
"encryption_doq_desc": "Se esta porta estiver configurada, o AdGuard Home executará um servidor DNS-sobre-QUIC nesta porta. É experimental e pode não ser confiável. Além disso, não há muitos clientes que ofereçam suporte no momento.",
|
||||
"encryption_doq": "Porta DNS-sobre-QUIC",
|
||||
"encryption_doq_desc": "Se esta porta estiver configurada, o AdGuard Home executará um servidor DNS-sobre-QUIC nesta porta. ",
|
||||
"encryption_certificates": "Certificados",
|
||||
"encryption_certificates_desc": "Para usar criptografia, você precisa fornecer uma cadeia de certificados SSL válida para seu domínio. Você pode obter um certificado gratuito em <0> {{link}}</0> ou pode comprá-lo de uma das autoridades de certificação confiáveis.",
|
||||
"encryption_certificates_input": "Copie/cole aqui seu certificado codificado em PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Domínios bloqueados",
|
||||
"access_blocked_desc": "Não deve ser confundido com filtros. O AdGuard Home elimina as consultas DNS que correspondem a esses domínios, e essas consultas nem aparecem no registro de consultas. Você pode especificar nomes de domínio exatos, caracteres curinga ou regras de filtro de URL, por exemplo \"exemplo.org\", \"*.exemplo.org\", ou \"||exemplo.org^\" correspondentemente.",
|
||||
"access_settings_saved": "Configurações de acesso foram salvas com sucesso",
|
||||
"updates_checked": "Atualizações verificadas com sucesso",
|
||||
"updates_checked": "Uma nova versão do AdGuard Home está disponível\n",
|
||||
"updates_version_equal": "O AdGuard Home está atualizado.",
|
||||
"check_updates_now": "Verificar atualizações",
|
||||
"dns_privacy": "Privacidade de DNS",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Servidores DNS de arranque",
|
||||
"bootstrap_dns_desc": "Servidores DNS de inicialização são usados para resolver endereços IP dos resolvedores DoH/DoT que especifica como upstreams.",
|
||||
"local_ptr_title": "Servidores DNS reversos privados",
|
||||
"local_ptr_desc": "Os servidores DNS que o AdGuard Home usa para consultas PTR locais. Esses servidores são usados para resolver os nomes de host de clientes com endereços IP privados, por exemplo \"192.168.12.34\", usando DNS reverso. Se não for definido, o AdGuard Home usa os endereços dos resolvedores DNS padrão do seu sistema operacional, exceto os endereços do AdGuard Home.",
|
||||
"local_ptr_desc": "Os servidores DNS que o AdGuard Home usa para consultas PTR locais. Esses servidores são usados para resolver solicitações de PTR para endereços em intervalos de IP privados, por exemplo \"192.168.12.34\", usando DNS reverso. Se não estiver definido, o AdGuard Home usa os endereços dos resolvedores de DNS padrão do seu sistema operacional, exceto os endereços do próprio AdGuard Home.",
|
||||
"local_ptr_default_resolver": "Por predefinição, o AdGuard Home usa os seguintes resolvedores de DNS reverso: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "A página inicial do AdGuard não conseguiu determinar resolvedores DNS reversos privados adequados para este sistema.",
|
||||
"local_ptr_placeholder": "Insira um endereço de servidor por linha",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "A concessão não pode ter o endereço IP do gateway",
|
||||
"out_of_range_error": "Deve estar fora do intervalo \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Deve ser inferior ao início do intervalo",
|
||||
"greater_range_start_error": "Deve ser maior que o início do intervalo",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "DNS normal (através do UDP, nome do servidor);",
|
||||
"example_upstream_dot": "<0>DNS-sobre-TLS</0> criptografado;",
|
||||
"example_upstream_doh": "<0>DNS-sobre-HTTPS</0> criptografado;",
|
||||
"example_upstream_doq": "<0>DNS-sobre-QUIC</0> criptografado (experimental);",
|
||||
"example_upstream_doq": "<0>DNS-sobre-QUIC</0> criptografado;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> para o <1>DNSCrypt</1> ou usar os resolvedores <2>DNS-sobre-HTTPS</2>;",
|
||||
"example_upstream_tcp": "DNS regular (através do TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS normal (através do TCP, nome do servidor);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Se a porta HTTPS estiver configurada, a interface administrativa do AdGuard Home será acessível via HTTPS e também fornecerá o DNS-sobre-HTTPS no local '/dns-query'.",
|
||||
"encryption_dot": "Porta DNS-sobre-TLS",
|
||||
"encryption_dot_desc": "Se essa porta estiver configurada, o AdGuard Home irá executar o servidor DNS-sobre- TSL nesta porta.",
|
||||
"encryption_doq": "Porta DNS-sobre-QUIC (experimental)",
|
||||
"encryption_doq_desc": "Se esta porta estiver configurada, o AdGuard Home executará um servidor DNS-sobre-QUIC nesta porta. É experimental e pode não ser confiável. Além disso, não há demasiados clientes que ofereçam suporte no momento.",
|
||||
"encryption_doq": "Porta DNS-sobre-QUIC",
|
||||
"encryption_doq_desc": "Se esta porta estiver configurada, o AdGuard Home executará um servidor DNS-sobre-QUIC nesta porta. ",
|
||||
"encryption_certificates": "Certificados",
|
||||
"encryption_certificates_desc": "Para usar criptografia, precisa de fornecer uma cadeia de certificados SSL válida para o seu domínio. Pode obter um certificado gratuito em <0> {{link}}</0> ou pode comprá-lo numa das autoridades de certificação confiáveis.",
|
||||
"encryption_certificates_input": "Copie/cole aqui o seu certificado codificado em PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Domínios bloqueados",
|
||||
"access_blocked_desc": "Não deve ser confundido com filtros. O AdGuard Home elimina as consultas DNS que correspondem a esses domínios, e essas consultas nem aparecem no registro de consultas. Você pode especificar nomes de domínio exatos, caracteres curinga ou regras de filtro de URL, por exemplo \"exemplo.org\", \"*.exemplo.org\", ou \"||exemplo.org^\" correspondentemente.",
|
||||
"access_settings_saved": "Definições de acesso foram guardadas com sucesso",
|
||||
"updates_checked": "Atualizações verificadas com sucesso",
|
||||
"updates_checked": "Uma nova versão do AdGuard Home está disponível\n",
|
||||
"updates_version_equal": "O AdGuard Home está atualizado",
|
||||
"check_updates_now": "Verificar atualizações",
|
||||
"dns_privacy": "Privacidade de DNS",
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
"load_balancing": "Echilibrare-sarcini",
|
||||
"load_balancing_desc": "Interoghează câte un server în amonte la un moment dat. AdGuard Home utilizează un algoritm de randomizare ponderat pentru a alege serverul, astfel încât cel mai rapid server să fie utilizat mai des.",
|
||||
"bootstrap_dns": "Serverele DNS Bootstrap",
|
||||
"bootstrap_dns_desc": "Serverele DNS Bootstrap sunt folosite pentru a rezolva adresele IP ale resolverelor DoH/DoT indicate ca upstreams.",
|
||||
"bootstrap_dns_desc": "Serverele DNS Bootstrap sunt folosite pentru a rezolva adresele IP ale rezolvatorilor DoH/DoT indicați ca upstreams.",
|
||||
"local_ptr_title": "Servere DNS inverse private",
|
||||
"local_ptr_desc": "Servere DNS pe care AdGuard Home le utilizează pentru interogări PTR locale. Aceste servere sunt folosite pentru a rezolva numele gazdelor de clienți cu adrese IP private, cum ar fi \"192.168.12.34\", folosind DNS inversat. Dacă nu este setat, AdGuard Home utilizează adresele resolverelor DNS implicite ale SO al dvs., cu excepția adreselor AdGuard Home înseși.",
|
||||
"local_ptr_default_resolver": "În mod implicit, AdGuard Home utilizează următoarele resolvere DNS inverse: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home nu a putut determina resolvere DNS private adecvate pentru acest sistem.",
|
||||
"local_ptr_desc": "Serverele DNS pe care AdGuard Home le utilizează pentru interogările PTR locale. Aceste servere sunt utilizate pentru a rezolva solicitările PTR pentru adrese din intervale IP private, de exemplu „192.168.12.34”, utilizând DNS invers. Dacă nu este configurat, AdGuard Home utilizează adresele rezolvatorilor DNS impliciți ai sistemului dvs. de operare, cu excepția adreselor AdGuard Home în sine.",
|
||||
"local_ptr_default_resolver": "În mod implicit, AdGuard Home utilizează următorii rezolvatori DNS inverși: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home nu a putut determina rezolvatorii DNS privați adecvați pentru acest sistem.",
|
||||
"local_ptr_placeholder": "Introduceți o adresă de server per linie",
|
||||
"resolve_clients_title": "Permiteți rezolvarea inversa a adreselor IP ale clienților",
|
||||
"resolve_clients_desc": "Rezolvă invers adresele IP ale clienților în numele lor de gazde prin trimiterea interogărilor PTR la resolverele corespunzătoare (servere DNS private pentru clienți locali, servere în amonte pentru clienți cu adrese IP publice).",
|
||||
"use_private_ptr_resolvers_title": "Utilizați resolvere DNS inverse private",
|
||||
"resolve_clients_desc": "Rezolvă invers adresele IP ale clienților în numele lor de gazde prin trimiterea interogărilor PTR la rezolvatorii corespunzători (servere DNS private pentru clienți locali, servere în amonte pentru clienți cu adrese IP publice).",
|
||||
"use_private_ptr_resolvers_title": "Utilizați rezolvatori DNS inverși privați",
|
||||
"use_private_ptr_resolvers_desc": "Efectuează examinări DNS inverse pentru adresele deservite local folosind aceste servere în amonte. Dacă este dezactivată, AdGuard Home răspunde cu NXDOMAIN la toate aceste cereri PTR, cu excepția clienților cunoscuți din DHCP, /etc/hosts și așa mai departe.",
|
||||
"check_dhcp_servers": "Căutați servere DHCP",
|
||||
"save_config": "Salvare configurare",
|
||||
@@ -47,6 +47,7 @@
|
||||
"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",
|
||||
"form_error_gateway_ip": "Locația nu poate avea adresa IP a gateway-ului",
|
||||
"out_of_range_error": "Trebuie să fie în afara intervalului „{{start}}”-„{{end}}”",
|
||||
"lower_range_start_error": "Trebuie să fie mai mică decât începutul intervalului",
|
||||
"greater_range_start_error": "Trebuie să fie mai mare decât începutul intervalului",
|
||||
@@ -213,8 +214,8 @@
|
||||
"example_upstream_udp": "DNS obișnuit (over UDP, nume de gazdă);",
|
||||
"example_upstream_dot": "<0>DNS-over-TLS</0> criptat;",
|
||||
"example_upstream_doh": "<0>DNS-over-HTTPS</0> criptat;",
|
||||
"example_upstream_doq": "<0>DNS-over-QUIC</0> criptat (experimental);",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> pentru <1>DNSCrypt</1> sau rezolvere <2>DNS-over-HTTPS</2>;",
|
||||
"example_upstream_doq": "criptat <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> pentru <1>DNSCrypt</1> sau rezolvatori <2>DNS-over-HTTPS</2>;",
|
||||
"example_upstream_tcp": "DNS clasic (over TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS obișnuit (over TCP, nume de gazdă);",
|
||||
"all_lists_up_to_date_toast": "Toate listele sunt deja la zi",
|
||||
@@ -351,7 +352,7 @@
|
||||
"install_devices_android_list_5": "Schimbați valorile DNS 1 și DNS 2 la adresele serverului dvs. AdGuard Home.",
|
||||
"install_devices_ios_list_1": "Din ecranul de start, tapați Setări.",
|
||||
"install_devices_ios_list_2": "Alegeți Wi-Fi în meniul din stânga (este imposibil să configurați DNS pentru rețelele mobile).",
|
||||
"install_devices_ios_list_3": "Tapați numele rețelei active curente.",
|
||||
"install_devices_ios_list_3": "Apăsați pe numele rețelei active în prezent.",
|
||||
"install_devices_ios_list_4": "În câmpul DNS, introduceți adresele serverului dvs. AdGuard Home.",
|
||||
"get_started": "Să începem",
|
||||
"next": "Următor",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Dacă portul HTTPS este configurat, interfața administrator AdGuard Home va fi accesibilă prin HTTPS și va oferi de asemenea DNS-over-HTTPS în locația '/DNS-query'.",
|
||||
"encryption_dot": "Port DNS-over-TLS",
|
||||
"encryption_dot_desc": "Dacă acest port este configurat, AdGuard Home va rula un server DNS-over-TLS pe acest port.",
|
||||
"encryption_doq": "Port DNS-over-QUIC (experimental)",
|
||||
"encryption_doq_desc": "Dacă acest port este configurat, AdGuard Home va rula un server DNS-over-QUIC pe acest port. Este experimental și este posibil să nu fie fiabil. De asemenea, nu există prea mulți clienți care să-l susțină în acest moment.",
|
||||
"encryption_doq": "Portul DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Dacă este configurat acest port, AdGuard Home va rula un server DNS-over-QUIC pe acest port.",
|
||||
"encryption_certificates": "Certificate",
|
||||
"encryption_certificates_desc": "Pentru a utiliza criptarea, trebuie furnizate o serie de certificate SSL valabile pentru domeniul dvs.. Puteți obține un certificat gratuit pe <0>{{link}}</0> sau îl puteți cumpăra de la una din Autoritățile Certificate de încredere.",
|
||||
"encryption_certificates_input": "Copiați/lipiți certificatele dvs. PEM-codate aici.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Domenii blocate",
|
||||
"access_blocked_desc": "A nu se confunda cu filtrele. AdGuard Home respinge cererile DNS pentru aceste domenii, iar aceste cereri nici măcar nu apar în jurnalul de solicitări. Puteți specifica nume exacte de domenii, metacaractere sau reguli de filtrare URL, cum ar fi \"example.org\", \"*.exemple.org\" sau \"||example.org^\" în mod corespunzător.",
|
||||
"access_settings_saved": "Setările de acces au fost salvate cu succes",
|
||||
"updates_checked": "Actualizările au fost verificate cu succes",
|
||||
"updates_checked": "Este disponibilă o nouă versiune de AdGuard Home\n",
|
||||
"updates_version_equal": "AdGuard Home este la zi",
|
||||
"check_updates_now": "Verificați actualizările acum",
|
||||
"dns_privacy": "Confidențialitate DNS",
|
||||
@@ -585,7 +586,7 @@
|
||||
"list_updated": "{{count}} listă actualizată",
|
||||
"list_updated_plural": "{{count}} liste actualizate",
|
||||
"dnssec_enable": "Activați DNSSEC",
|
||||
"dnssec_enable_desc": "Activați semnalul DNSSEC în interogările DNS de ieșire și verificați rezultatul (este necesar un resolver compatibil DNSSEC).",
|
||||
"dnssec_enable_desc": "Activați semnalul DNSSEC în interogările DNS de ieșire și verificați rezultatul (este necesar un rezolvator compatibil DNSSEC).",
|
||||
"validated_with_dnssec": "Validat cu DNSSEC",
|
||||
"all_queries": "Toate interogările",
|
||||
"show_blocked_responses": "Blocat",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Некорректное имя сервера",
|
||||
"form_error_subnet": "Подсеть «{{cidr}}» не содержит IP-адрес «{{ip}}»",
|
||||
"form_error_positive": "Должно быть больше 0",
|
||||
"form_error_gateway_ip": "Аренда не может иметь IP-адрес шлюза",
|
||||
"out_of_range_error": "Должно быть вне диапазона «{{start}}»-«{{end}}»",
|
||||
"lower_range_start_error": "Должно быть меньше начала диапазона",
|
||||
"greater_range_start_error": "Должно быть больше начала диапазона",
|
||||
@@ -66,7 +67,7 @@
|
||||
"ip": "IP-адрес",
|
||||
"dhcp_table_hostname": "Имя хоста",
|
||||
"dhcp_table_expires": "Истекает",
|
||||
"dhcp_warning": "Если вы все равно хотите включить DHCP-сервер, убедитесь, что в сети больше нет активных DHCP-серверов. Иначе это может сломать доступ в сеть для подключённых устройств!",
|
||||
"dhcp_warning": "Если вы всё равно хотите включить DHCP-сервер, убедитесь, что в сети больше нет активных DHCP-серверов. Иначе это может сломать доступ в сеть для подключённых устройств!",
|
||||
"dhcp_error": "AdGuard Home не смог определить присутствие других DHCP-серверов в сети",
|
||||
"dhcp_static_ip_error": "Чтобы использовать DHCP-сервер, должен быть установлен статический IP-адрес. AdGuard Home не смог определить, использует ли этот сетевой интерфейс статический IP-адрес. Пожалуйста, установите его вручную.",
|
||||
"dhcp_dynamic_ip_found": "Ваша система использует динамический IP-адрес для интерфейса <0>{{interfaceName}}</0>. Чтобы использовать DHCP-сервер, необходимо установить статический IP-адрес. Ваш текущий IP-адрес – <0>{{ipAddress}}</0>. Мы автоматически установим его как статический, если вы нажмёте кнопку «Включить DHCP-сервер».",
|
||||
@@ -163,8 +164,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": "Безопасный поиск выкл.",
|
||||
@@ -179,7 +180,7 @@
|
||||
"edit_table_action": "Редактировать",
|
||||
"delete_table_action": "Удалить",
|
||||
"elapsed": "Затрачено",
|
||||
"filters_and_hosts_hint": "AdGuard Home распознает базовые правила блокировки и синтаксис файлов hosts.",
|
||||
"filters_and_hosts_hint": "AdGuard Home распознаёт базовые правила блокировки и синтаксис файлов hosts.",
|
||||
"no_blocklist_added": "Чёрные списки не добавлены",
|
||||
"no_whitelist_added": "Белые списки не добавлены",
|
||||
"add_blocklist": "Добавить чёрный список",
|
||||
@@ -198,7 +199,7 @@
|
||||
"enter_valid_allowlist": "Добавьте действующий URL-адрес в белый список.",
|
||||
"form_error_url_format": "Неверный формат URL",
|
||||
"form_error_url_or_path_format": "Неверный URL или абсолютный путь к списку",
|
||||
"custom_filter_rules": "Пользовательское правило фильтрации",
|
||||
"custom_filter_rules": "Пользовательские правила фильтрации",
|
||||
"custom_filter_rules_hint": "Вводите по одному правилу на строчку. Вы можете использовать правила блокировки или синтаксис файлов hosts.",
|
||||
"system_host_files": "Системные hosts-файлы",
|
||||
"examples_title": "Примеры",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "обычный DNS (поверх UDP, с именем хоста);",
|
||||
"example_upstream_dot": "зашифрованный <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "зашифрованный <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "зашифрованный <0>DNS-over-QUIC</0> (эксперементальный);",
|
||||
"example_upstream_doq": "зашифрован <0>DNS-over-QUIC</0>",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> для <1>DNSCrypt</1> или <2>DNS-over-HTTPS</2> серверов;",
|
||||
"example_upstream_tcp": "обычный DNS (поверх TCP);",
|
||||
"example_upstream_tcp_hostname": "обычный DNS (поверх TCP, с именем хоста);",
|
||||
@@ -328,10 +329,10 @@
|
||||
"install_submit_title": "Поздравляем!",
|
||||
"install_submit_desc": "Настройка завершена, AdGuard Home готов к использованию.",
|
||||
"install_devices_router": "Роутер",
|
||||
"install_devices_router_desc": "Эта настройка покроет все устройства, подключенные к вашему домашнему роутеру, и вам не нужно будет настраивать каждое вручную.",
|
||||
"install_devices_router_desc": "Эта настройка покроет все устройства, подключённые к вашему домашнему роутеру, и вам не нужно будет настраивать каждое вручную.",
|
||||
"install_devices_address": "DNS-сервер AdGuard Home доступен по следующим адресам",
|
||||
"install_devices_router_list_1": "Откройте настройки вашего роутера. Обычно вы можете открыть их в вашем браузере, например, http://192.168.0.1/ или http://192.168.1.1/. Вас могут попросить ввести пароль. Если вы не помните его, пароль часто можно сбросить, нажав на кнопку на самом роутере, но помните, что эта процедура может привести к потере всей конфигурации роутера. Если вашему роутеру необходимо приложение для настройки, установите его на свой телефон или ПК и воспользуйтесь им для настройки роутера.",
|
||||
"install_devices_router_list_2": "Найдите настройки DHCP или DNS. Найдите буквы «DNS» рядом с текстовым полем, в которое можно ввести два или три ряда цифр, разделенных на 4 группы от одной до трёх цифр.",
|
||||
"install_devices_router_list_2": "Найдите настройки DHCP или DNS. Найдите буквы «DNS» рядом с текстовым полем, в которое можно ввести два или три ряда цифр, разделённых на 4 группы от одной до трёх цифр.",
|
||||
"install_devices_router_list_3": "Введите туда адрес вашего AdGuard Home.",
|
||||
"install_devices_router_list_4": "Вы не можете установить собственный DNS-сервер на некоторых типах маршрутизаторов. В этом случае может помочь настройка AdGuard Home в качестве <0>DHCP-сервера</0>. В противном случае вам следует обратиться к руководству по настройке DNS-серверов для вашей конкретной модели маршрутизатора.",
|
||||
"install_devices_windows_list_1": "Откройте Панель управления через меню «Пуск» или через поиск Windows.",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Если порт HTTPS настроен, веб-интерфейс администрирования AdGuard Home будет доступен через HTTPS, а также DNS-over-HTTPS сервер будет доступен по пути '/dns-query'.",
|
||||
"encryption_dot": "Порт DNS-over-TLS",
|
||||
"encryption_dot_desc": "Если этот порт настроен, AdGuard Home запустит DNS-over-TLS-сервер на этому порту.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC (экспериментальный)",
|
||||
"encryption_doq_desc": "Если этот порт настроен, AdGuard Home запустит сервер DNS-over-QUIC на этом порте. Это экспериментально и может быть ненадёжно. Кроме того, не так много клиентов поддерживает этот способ в настоящий момент.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Если этот порт настроен, AdGuard Home запустит сервер DNS-over-QUIC на этом порте.",
|
||||
"encryption_certificates": "Сертификаты",
|
||||
"encryption_certificates_desc": "Для использования шифрования вам необходимо предоставить корректную цепочку SSL-сертификатов для вашего домена. Вы можете получить бесплатный сертификат на <0>{{link}}</0> или вы можете купить его у одного из доверенных Центров Сертификации.",
|
||||
"encryption_certificates_input": "Скопируйте сюда сертификаты в PEM-кодировке.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Неразрешённые домены",
|
||||
"access_blocked_desc": "Не путать с фильтрами. AdGuard Home будет игнорировать DNS-запросы с этими доменами. Здесь вы можете уточнить точные имена доменов, шаблоны, правила URL-фильтрации, например, «example.org», «*.example.org» или «||example.org».",
|
||||
"access_settings_saved": "Настройки доступа успешно сохранены",
|
||||
"updates_checked": "Проверка обновлений прошла успешно",
|
||||
"updates_checked": "Доступна новая версия AdGuard Home",
|
||||
"updates_version_equal": "Версия AdGuard Home актуальна",
|
||||
"check_updates_now": "Проверить обновления",
|
||||
"dns_privacy": "Зашифрованный DNS",
|
||||
@@ -475,7 +476,7 @@
|
||||
"rewrite_applied": "Применено правило перезаписи",
|
||||
"rewrite_hosts_applied": "Переписано по правилу файла hosts",
|
||||
"dns_rewrites": "Перезапись DNS-запросов",
|
||||
"form_domain": "Введите домен",
|
||||
"form_domain": "Введите имя или маску домена",
|
||||
"form_answer": "Введите IP адрес или домен",
|
||||
"form_error_domain_format": "Некорректный домен",
|
||||
"form_error_answer_format": "Некорректный ответ",
|
||||
@@ -589,7 +590,7 @@
|
||||
"validated_with_dnssec": "Подтверждено с помощью DNSSEC",
|
||||
"all_queries": "Все запросы",
|
||||
"show_blocked_responses": "Заблокировано",
|
||||
"show_whitelisted_responses": "В белом списке",
|
||||
"show_whitelisted_responses": "Разрешённые",
|
||||
"show_processed_responses": "Обработан",
|
||||
"blocked_safebrowsing": "Заблокировано согласно базе данных Safe Browsing",
|
||||
"blocked_adult_websites": "Заблокировано Родительским контролем",
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
"encryption_dot": "TLS-හරහා-ව.නා.ප. තොට",
|
||||
"encryption_dot_desc": "මෙම තොට වින්යාසගත කර ඇත්නම්, ඇඩ්ගාර්ඩ් හෝම් විසින් මෙම කවුළුව හරහා TLS-හරහා-ව.නා.ප. සේවාදායකයක් ධාවනය කරනු ඇත.",
|
||||
"encryption_doq": "QUIC-හරහා-ව.නා.ප. තොට",
|
||||
"encryption_doq_desc": "මෙම තොට වින්යාසගත කර ඇත්නම්, ඇඩ්ගාර්ඩ් හෝම් විසින් මෙම තොට හරහා QUIC-හරහා-ව.නා.ප. සේවාදායකයක් ධාවනය කරනු ඇත. එය පරීක්ෂාත්මක වන අතර විශ්වාසදායක නොවිය හැකිය. එසේම, මේ වන විට එයට සහාය දක්වන බොහෝ අනුග්රාහක නැත.",
|
||||
"encryption_doq_desc": "මෙම තොට වින්යාසගත කර ඇත්නම්, ඇඩ්ගාර්ඩ් හෝම් විසින් මෙම තොට හරහා QUIC-හරහා-ව.නා.ප. සේවාදායකයක් ධාවනය කරනු ඇත.",
|
||||
"encryption_certificates": "සහතික",
|
||||
"encryption_certificates_input": "ඔබගේ PEM-කේතනය කළ සහතික පිටපත් කර මෙහි අලවන්න.",
|
||||
"encryption_status": "තත්වය",
|
||||
@@ -406,7 +406,7 @@
|
||||
"access_disallowed_desc": "CIDR හෝ අ.ජා. කෙ. ලිපින ලැයිස්තුවක් වින්යාසගත කර ඇත්නම්, ඇඩ්ගාර්ඩ් හෝම් විසින් එම අ.ජා. කෙ. ලිපින වලින් ඉල්ලීම් අත්හරිනු ඇත.",
|
||||
"access_blocked_title": "නොඉඩ ලත් වසම්",
|
||||
"access_settings_saved": "ප්රවේශ වීමේ සැකසුම් සාර්ථකව සුරකින ලදි",
|
||||
"updates_checked": "යාවත්කාල සාර්ථකව පරික්ෂා කෙරිණි",
|
||||
"updates_checked": "ඇඩ්ගාර්ඩ් හෝම් හි නව අනුවාදයක් තිබේ",
|
||||
"updates_version_equal": "ඇඩ්ගාර්ඩ් හෝම් යාවත්කාලීනයි",
|
||||
"check_updates_now": "දැන් යාවත්කාල පරීක්ෂා කරන්න",
|
||||
"dns_privacy": "ව.නා.ප. රහස්යතා",
|
||||
@@ -414,12 +414,12 @@
|
||||
"setup_dns_privacy_android_2": "<1>HTTPS-හරහා-ව.නා.ප.</1> සහ <1>TLS-හරහා-ව.නා.ප.</1> සඳහා <0>ඇන්ඩ්රොයිඩ් සඳහා ඇඩ්ගාර්ඩ්</0> සහාය දක්වයි.",
|
||||
"setup_dns_privacy_other_title": "වෙනත් ක්රියාවට නැංවූ දෑ",
|
||||
"setup_dns_privacy_other_2": "<0>ඩීඑන්එස්ප්රොක්සි</0> දන්නා සියලුම ආරක්ෂිත ව.නා.ප. කෙටුම්පත් සඳහා සහාය දක්වයි.",
|
||||
"setup_dns_privacy_other_3": "<1>DNS-over-HTTPS</1> සඳහා <0>dnscrypt-පෙරකලාසිය</0> සහාය දක්වයි.",
|
||||
"setup_dns_privacy_other_4": "<1>DNS-over-HTTPS</1> සඳහා <0>මොසිල්ලා ෆයර්ෆොක්ස්</0> සහාය දක්වයි.",
|
||||
"setup_dns_privacy_other_5": "<0>මෙහි</0> සහ <1>මෙහි</1> තවත් ක්රියාවට නැංවූ දෑ ඔබට හමුවනු ඇත.",
|
||||
"setup_dns_privacy_ioc_mac": "අයිඕඑස් සහ මැක්ඕඑස් වින්යාසය",
|
||||
"setup_dns_notice": "ඔබට <1>DNS-over-HTTPS</1> හෝ <1>DNS-over-TLS</1> භාවිතයට ඇඩ්ගාර්ඩ් හෝම් සැකසුම් තුළ <0>සංකේතනය වින්යාසගත</0> කිරීමට ඇවැසිය.",
|
||||
"rewrite_added": "\"{{key}}\" සඳහා ව.නා.ප. නැවත ලිවීම සාර්ථකව එකතු කෙරිණි",
|
||||
"rewrite_deleted": "\"{{key}}\" සඳහා ව. නා. ප. නැවත ලිවීම සාර්ථකව ඉවත් කෙරිණි",
|
||||
"rewrite_add": "ව.නා.ප. නැවත ලිවීමක් එකතු කරන්න",
|
||||
"rewrite_not_found": "ව.නා.ප. නැවත ලිවීම් හමු නොවිණි",
|
||||
"rewrite_confirm_delete": "\"{{key}}\" සඳහා ව.නා.ප. නැවත ලිවීම ඉවත් කිරීමට අවශ්ය බව ඔබට විශ්වාසද?",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Neplatné meno servera",
|
||||
"form_error_subnet": "Podsieť \"{{cidr}}\" neobsahuje IP adresu \"{{ip}}\"",
|
||||
"form_error_positive": "Musí byť väčšie ako 0",
|
||||
"form_error_gateway_ip": "Prenájom nemôže mať IP adresu brány",
|
||||
"out_of_range_error": "Musí byť mimo rozsahu \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Musí byť nižšie ako začiatok rozsahu",
|
||||
"greater_range_start_error": "Musí byť väčšie ako začiatok rozsahu",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "štandardné DNS (cez UDP, hostname);",
|
||||
"example_upstream_dot": "šifrované <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "šifrované <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "šifrované <0>DNS-over-QUIC</0> (experimentálne);",
|
||||
"example_upstream_doq": "šifrované <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS pečiatky</0> pre <1>DNSCrypt</1> alebo <2>DNS-over-HTTPS</2> rezolvery;",
|
||||
"example_upstream_tcp": "obyčajná DNS (cez TCP);",
|
||||
"example_upstream_tcp_hostname": "štandardné DNS (cez TCP, hostname);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Ak je nakonfigurovaný HTTPS port, AdGuard Home administrátorské rozhranie bude prístupné cez HTTPS a bude tiež poskytovať DNS-cez-HTTPS na '/dns-query'.",
|
||||
"encryption_dot": "Port DNS-cez-TLS",
|
||||
"encryption_dot_desc": "Ak je tento port nakonfigurovaný, AdGuard Home bude na tomto porte spúšťať DNS-cez-TLS server.",
|
||||
"encryption_doq": "DNS-over-QUIC (experimentálne)",
|
||||
"encryption_doq_desc": "Ak je tento port nakonfigurovaný, AdGuard Home na tomto porte spustí server DNS-over-QUIC. Je to experimentálne a nemusí to byť spoľahlivé. Momentálne tiež nie je príliš veľa klientov, ktorí by ju podporovali.",
|
||||
"encryption_doq": "Port DNS-cez-QUIC",
|
||||
"encryption_doq_desc": "Ak je tento port nakonfigurovaný, AdGuard Home na tomto porte spustí server DNS-over-QUIC. ",
|
||||
"encryption_certificates": "Certifikáty",
|
||||
"encryption_certificates_desc": "Ak chcete používať šifrovanie, musíte pre svoju doménu poskytnúť platný reťazec certifikátov SSL. Certifikát môžete získať bezplatne na adrese <0>{{link}}</0> alebo si ho môžete kúpiť od jedného z dôveryhodných certifikačných orgánov.",
|
||||
"encryption_certificates_input": "Skopírujte alebo prilepte sem certifikáty vo formáte PEM.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Nepovolené domény",
|
||||
"access_blocked_desc": "Nesmie byť zamieňaná s filtrami. AdGuard Home zruší DNS dopyty, ktoré sa zhodujú s týmito doménami, a tieto dopyty sa nezobrazia ani v denníku dopytov. Môžete určiť presné názvy domén, zástupné znaky alebo pravidlá filtrovania URL adries, napr. \"example.org\", \"*.example.org\" alebo ||example.org^\" zodpovedajúcim spôsobom.",
|
||||
"access_settings_saved": "Nastavenia prístupu úspešne uložené",
|
||||
"updates_checked": "Aktualizácie úspešne skontrolované",
|
||||
"updates_checked": "K dispozícii je nová verzia aplikácie AdGuard Home\n",
|
||||
"updates_version_equal": "AdGuard Home je aktuálny",
|
||||
"check_updates_now": "Skontrolovať aktualizácie teraz",
|
||||
"dns_privacy": "DNS súkromie",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "Zagonski DNS strežniki",
|
||||
"bootstrap_dns_desc": "Zagonski DNS strežniki se uporabljajo za razreševanje IP naslovov DoH/DoT reševalcev, ki jih določite kot navzgornje.",
|
||||
"local_ptr_title": "Zasebni povratni strežniki DNS",
|
||||
"local_ptr_desc": "Strežniki DNS, ki jih AdGuard Home uporablja za lokalne poizvedbe PTR. Ti strežniki se uporabljajo za razreševanje imen gostiteljev z zasebnimi naslovi IP, na primer \"192.168.12.34\" uporablja DNS. Če ni nastavljen, uporablja naslove privzetih razreševalnikov DNS vašega OS, razen naslovov samega AdGuard Home.",
|
||||
"local_ptr_desc": "Strežniki DNS, ki jih AdGuard Home uporablja za lokalne PTR poizvedbe. Ti strežniki se uporabljajo za reševanje zahtev PTR za naslove v zasebnih obsegih IP, na primer \"192.168.12.34\", z uporabo obratnega DNS. Če ni nastavljen, AdGuard Home uporablja naslove privzetih razreševalnikov DNS vašega OS, razen naslovov samega AdGuard Home.",
|
||||
"local_ptr_default_resolver": "AdGuard Home privzeto uporablja te povratne razreševalnike DNS: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home ni mogel določiti ustreznih zasebnih povratnih reševalcev DNS za ta sistem.",
|
||||
"local_ptr_placeholder": "V vrstico vnesite en naslov strežnika",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Neveljavno ime strežnika",
|
||||
"form_error_subnet": "Podomrežje \"{{cidr}}\" ne vsebuje naslova IP \"{{ip}}\"",
|
||||
"form_error_positive": "Mora biti večja od 0",
|
||||
"form_error_gateway_ip": "Najem ne more imeti naslova IP prehoda",
|
||||
"out_of_range_error": "Mora biti izven razpona \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Mora biti manjši od začetka razpona",
|
||||
"greater_range_start_error": "Mora biti večji od začetka razpona",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "redni DNS (nad UDP, ime gostitelja);",
|
||||
"example_upstream_dot": "šifriran <0>DNS-prek-TLS</0>;",
|
||||
"example_upstream_doh": "šifriran <0>DNS-prek-HTTPS</0>;",
|
||||
"example_upstream_doq": "šifriran <0>DNS-prek-QUIC</0> (eksperimentalno);",
|
||||
"example_upstream_doq": "šifriran <0>DNS-prek-QUIC</0>;",
|
||||
"example_upstream_sdns": "lahko uporabite <0>DNS Žige</0> za reševalce <1>DNSCrypt</1> ali <2>DNS-prek-HTTPS</2>;",
|
||||
"example_upstream_tcp": "redni DNS (nad TCP);",
|
||||
"example_upstream_tcp_hostname": "redni DNS (nad TCP, ime gostitelja);",
|
||||
@@ -351,7 +352,7 @@
|
||||
"install_devices_android_list_5": "Spremeni nastavitev vrednosti DNS 1 in DNS 2 na naslove strežnikov AdGuard Home.",
|
||||
"install_devices_ios_list_1": "Na začetnem zaslonu izberite Nastavitve.",
|
||||
"install_devices_ios_list_2": "V levem meniju izberite Wi-Fi (nemogoče je konfigurirati DNS za mobilna omrežja).",
|
||||
"install_devices_ios_list_3": "Dotaknite se imena trenutno aktivnega omrežja.",
|
||||
"install_devices_ios_list_3": "Tapnite na ime trenutno aktivnega omrežja.",
|
||||
"install_devices_ios_list_4": "V polje DNS vnesite vaše naslove AdGuard Home strežnika.",
|
||||
"get_started": "Začnimo",
|
||||
"next": "Naprej",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Če so vrata HTTPS konfigurirana, bo skrbniški vmesnik AdGuard Home dostopen prek protokola HTTPS, prav tako pa bo zagotovil DNS-prek-HTTPS na mestu '/dns-query'.",
|
||||
"encryption_dot": "Vrata DNS-prek-TLS",
|
||||
"encryption_dot_desc": "Če so ta vrata konfigurirana, bo AdGuard Home na teh vratih zagnal DNS-prek-TLS strežnika.",
|
||||
"encryption_doq": "DNS-prek-vrat QUIC (eksperimentalno)",
|
||||
"encryption_doq_desc": "Če so nastavljena ta vrata bo AdGuard Home na teh vratih zagnal strežnik DNS-prek-QUIC. To je eksperimentalno in morda ni zanesljivo. Prav tako trenutno ni preveč odjemalcev, ki to podpirajo.",
|
||||
"encryption_doq": "DNS-prek-vrat QUIC",
|
||||
"encryption_doq_desc": "Če so nastavljena ta vrata bo AdGuard Home na teh vratih zagnal strežnik DNS-prek-QUIC. ",
|
||||
"encryption_certificates": "Digitalna potrdila",
|
||||
"encryption_certificates_desc": "Za uporabo šifriranja morate za svojo domeno zagotoviti veljavno verigo potrdil SSL. Brezplačno digitalno potrdilo lahko dobite na <0>{{link}}</0> ali pa ga kupite pri enem od zaupanja vrednih overiteljev.\n\n",
|
||||
"encryption_certificates_input": "Tukaj kopirajte/prilepite PEM šifrirana digitalna potrdila.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Prepovedane domene",
|
||||
"access_blocked_desc": "Ne gre zamenjati s filtri. AdGuard Home spusti poizvedbe DNS, ki se ujemajo s temi domenami, in te poizvedbe se niti ne pojavijo v dnevniku poizvedb. Določite lahko natančna imena domen, nadomestne znake ali pravila filtriranja URL-jev, npr. ustrezno \"example.org\", \"*.example.org\" ali \"|| example.org ^\".",
|
||||
"access_settings_saved": "Nastavitve dostopa so uspešno shranjene",
|
||||
"updates_checked": "Posodobitve so uspešno preverjene",
|
||||
"updates_checked": "Na voljo je nova različica programa AdGuard Home\n",
|
||||
"updates_version_equal": "AdGuard Home je posodobljen",
|
||||
"check_updates_now": "Preveri obstoj posodobitev zdaj",
|
||||
"dns_privacy": "Zasebnost DNS",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Nevažeće ime servera",
|
||||
"form_error_subnet": "Subnet \"{{cidr}}\" ne sadrži IP adresu \"{{ip}}\"",
|
||||
"form_error_positive": "Mora biti veće od 0",
|
||||
"form_error_gateway_ip": "Zakup ne može imati IP adresu mrežnog prolaza",
|
||||
"out_of_range_error": "Mora biti izvan opsega \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Mora biti manje od početnog opsega",
|
||||
"greater_range_start_error": "Mora biti veće od početnog opsega",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "uobičajen DNS (preko UDP, imena domaćina);",
|
||||
"example_upstream_dot": "šifrovano <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "šifrovano <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "šifrovano <0>DNS-over-QUIC</0> (eksperimentalno);",
|
||||
"example_upstream_doq": "šifrovano <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS brojeve</0> za <1>DNSCrypt</1> ili <2>DNS-over-HTTPS</2> razrešivače;",
|
||||
"example_upstream_tcp": "uobičajeni DNS (preko TCP);",
|
||||
"example_upstream_tcp_hostname": "uobičajen DNS (preko TCP, imena domaćina);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "Ako je HTTPS port konfigurisan, AdGuard Home administratorskom okruženju će se moći pristupati preko HTTPS, a to će takođe omogućiti DNS-over-HTTPS na '/dns-query' lokaciji.",
|
||||
"encryption_dot": "DNS-over-TLS port",
|
||||
"encryption_dot_desc": "Ako je ovaj port konfigurisan, AdGuard Home će pokretati DNS-over-TLS server na ovom portu.",
|
||||
"encryption_doq": "DNS-over-QUIC port (eksperimentalno)",
|
||||
"encryption_doq_desc": "Ako je ovaj port konfigurisan, AdGuard Home će pokrenuti DNS-over-QUIC server na tom portu. To je eksperiment i možda neće biti stabilno. Takođe, u ovom trenutku ne postoji puno klijenata koji ovo podržavaju.",
|
||||
"encryption_doq": "DNS-over-QUIC port",
|
||||
"encryption_doq_desc": "Ako je ovaj port konfigurisan, AdGuard Home će pokrenuti DNS-over-QUIC server na tom portu.",
|
||||
"encryption_certificates": "Sertifikati",
|
||||
"encryption_certificates_desc": "Da biste koristili šifrovanje, morate obezbediti važeći lanac SSL sertifikata za vaš domen. Besplatan sertifikat možete nabaviti na <0>{{link}}</0> ili ga možete kupiti od nekog od pouzdanih izdavalaca sertifikata.",
|
||||
"encryption_certificates_input": "Kopirajte/nalepite vaše PEM-kodirane sertifikate ovde.",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Blokirani domeni",
|
||||
"access_blocked_desc": "Da ne bude zabune sa filterima. AdGuard Home odustaje od DNS upita koji se podudaraju sa ovim domenima, a ovi upiti se čak i ne pojavljuju u evidenciji upita. Možete da navedete tačna imena domena, džoker znakove ili pravila URL filtera, npr. \"example.org\", \"*.example.org\" ili \"|| example.org^\" dopisno.",
|
||||
"access_settings_saved": "Postavke pristupa su uspešno sačuvane",
|
||||
"updates_checked": "Ažuriranja su uspešno proverena",
|
||||
"updates_checked": "Dostupna je nova verzija AdGuard Home-a",
|
||||
"updates_version_equal": "AdGuard Home je ažuriran na najnoviju verziju",
|
||||
"check_updates_now": "Proveri da li postoje ispravke",
|
||||
"dns_privacy": "DNS privatnost",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"client_settings": "Klientinställningar",
|
||||
"example_upstream_reserved": "Du kan specificera DNS-uppström <0>för en specifik domän</0>",
|
||||
"example_upstream_comment": "Du kan ange en kommentar",
|
||||
"example_upstream_reserved": "uppström <0>för en specifik domän</0>;",
|
||||
"example_upstream_comment": "du kan ange en kommentar.",
|
||||
"upstream_parallel": "Använd parallella förfrågningar för att snabba upp dessa genom att fråga alla uppströmsservrar samtidigt.",
|
||||
"parallel_requests": "Parallella förfrågningar",
|
||||
"load_balancing": "Lastbalansering",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Ogiltigt servernamn",
|
||||
"form_error_subnet": "Subnätet \"{{cidr}}\" innehåller inte IP-adressen \"{{ip}}\"",
|
||||
"form_error_positive": "Måste vara större än noll",
|
||||
"form_error_gateway_ip": "Lease kan inte ha IP-adressen för gatewayen",
|
||||
"out_of_range_error": "Måste vara utanför intervallet \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "Måste vara lägre än starten på intervallet",
|
||||
"greater_range_start_error": "Måste vara högre än starten på intervallet",
|
||||
@@ -196,7 +197,7 @@
|
||||
"choose_allowlist": "Välj frilistor",
|
||||
"enter_valid_blocklist": "Ange en giltig URL till blockeringslistan.",
|
||||
"enter_valid_allowlist": "Ange en giltig URL till frilistan.",
|
||||
"form_error_url_format": "Ogiltigt URL format",
|
||||
"form_error_url_format": "Ogiltigt URL-format",
|
||||
"form_error_url_or_path_format": "Ogiltig URL eller absolut sökväg till listan",
|
||||
"custom_filter_rules": "Egna filterregler",
|
||||
"custom_filter_rules_hint": "Skriv en regel per rad. Du kan använda antingen annonsblockeringsregler eller värdfilssyntax.",
|
||||
@@ -210,11 +211,13 @@
|
||||
"example_comment_hash": "# Också en kommentar",
|
||||
"example_regex_meaning": "blockera åtkomst till domäner som matchar det angivna uttrycket",
|
||||
"example_upstream_regular": "vanlig DNS (över UDP)",
|
||||
"example_upstream_udp": "vanlig DNS (över UDP, värdnamn);",
|
||||
"example_upstream_dot": "krypterat <0>DNS-over-TLS</0>",
|
||||
"example_upstream_doh": "krypterat <0>DNS-over-HTTPS</0>",
|
||||
"example_upstream_doq": "krypterat <0>DNS-over-QUIC</0>",
|
||||
"example_upstream_doq": "krypterat <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "Du kan använda <0>DNS-stamps</0> för <1>DNSCrypt</1> eller <2>DNS-over-HTTPS</2>-resolvers",
|
||||
"example_upstream_tcp": "vanlig DNS (över UDP)",
|
||||
"example_upstream_tcp_hostname": "vanlig DNS (över TCP, värdnamn);",
|
||||
"all_lists_up_to_date_toast": "Alla listor är redan uppdaterade",
|
||||
"updated_upstream_dns_toast": "Sparade uppströms dns-servrar",
|
||||
"dns_test_ok_toast": "Angivna DNS servrar fungerar korrekt",
|
||||
@@ -367,8 +370,8 @@
|
||||
"encryption_https_desc": "Om en HTTPS-port är inställd kommer gränssnittet till AdGuard Home administrering att kunna nås via HTTPS och kommer också att erbjuda DNS-over-HTTPS på '/dns-query' plats.",
|
||||
"encryption_dot": "DNS-över-TLS port",
|
||||
"encryption_dot_desc": "Om den här porten ställs in kommer AdGuard Home att använda DNS-over-TLS-server på porten.",
|
||||
"encryption_doq": "DNS-over-QUIC port (experimentell)",
|
||||
"encryption_doq_desc": "Om denna port är konfigurerad kommer AdGuard Home att köra en DNS-over-QUIC-server på denna port. Det är experimentellt och kanske inte är tillförlitligt. Dessutom finns det inte så många klienter som stödjer det för tillfället.",
|
||||
"encryption_doq": "DNS-over-QUIC port",
|
||||
"encryption_doq_desc": "Om denna port är konfigurerad kommer AdGuard Home att köra en DNS-over-QUIC-server på denna port. ",
|
||||
"encryption_certificates": "Certifikat",
|
||||
"encryption_certificates_desc": "För att använda kryptering måste du ange ett giltigt SSL-certifikat för din domän. Du kan skaffa ett certifikat gratis på <0>{{link}}</0> eller köpa ett från någon av de godkända certifikatutfärdare.",
|
||||
"encryption_certificates_input": "Kopiera/klistra in dina PEM-kodade certifikat här.",
|
||||
@@ -443,7 +446,7 @@
|
||||
"access_blocked_title": "Blockerade domäner",
|
||||
"access_blocked_desc": "Ej att förväxla med filter. AdGuard Home kastar DNS-frågor som matchar dessa domäner, och dessa frågor visas inte ens i frågeloggen. Du kan ange exakta domännamn, jokertecken eller URL-filterregler, t.ex. \"example.org\", \"*.example.org\" eller \"||example.org^\" på motsvarande sätt.",
|
||||
"access_settings_saved": "Åtkomstinställningar sparade",
|
||||
"updates_checked": "Sökning efter uppdateringar genomförd",
|
||||
"updates_checked": "En ny version av AdGuard Home är tillgänglig\n",
|
||||
"updates_version_equal": "AdGuard Home är uppdaterat",
|
||||
"check_updates_now": "Sök efter uppdateringar nu",
|
||||
"dns_privacy": "DNS-Integritet",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "DNS Önyükleme sunucuları",
|
||||
"bootstrap_dns_desc": "DNS Önyükleme sunucuları, belirttiğiniz üst sunucuların DoH/DoT çözümleyicilerine ait IP adreslerinin çözümlemek için kullanılır.",
|
||||
"local_ptr_title": "Özel ters DNS sunucuları",
|
||||
"local_ptr_desc": "AdGuard Home'un yerel PTR sorguları için kullandığı DNS sunucuları. Bu sunucular, rDNS kullanarak \"192.168.12.34\" gibi özel IP adreslerine sahip istemcilerin ana makine adlarını çözmek için kullanılır. Ayarlanmadığı durumda AdGuard Home, işletim sisteminizin varsayılan DNS çözümleme adreslerini kullanır.",
|
||||
"local_ptr_desc": "AdGuard Home'un yerel PTR sorguları için kullandığı DNS sunucuları. Bu sunucular, rDNS kullanarak, örneğin \"192.168.12.34\" gibi özel IP aralıklarındaki adresler için PTR isteklerini çözmek için kullanılır. Ayarlanmadığı durumda AdGuard Home, işletim sisteminizin varsayılan DNS çözümleme adreslerini kullanır.",
|
||||
"local_ptr_default_resolver": "AdGuard Home, varsayılan olarak aşağıdaki ters DNS çözümleyicilerini kullanır: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home, bu sistem için uygun olan özel ters DNS çözümleyicilerini belirleyemedi.",
|
||||
"local_ptr_placeholder": "Her satıra bir sunucu adresi girin",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Geçersiz sunucu adı",
|
||||
"form_error_subnet": "\"{{cidr}}\" alt ağı, \"{{ip}}\" IP adresini içermiyor",
|
||||
"form_error_positive": "0'dan büyük olmalıdır",
|
||||
"form_error_gateway_ip": "Kiralama, ağ geçidinin IP adresine sahip olamaz",
|
||||
"out_of_range_error": "\"{{start}}\"-\"{{end}}\" aralığının dışında olmalıdır",
|
||||
"lower_range_start_error": "Başlangıç aralığından daha düşük olmalıdır",
|
||||
"greater_range_start_error": "Başlangıç aralığından daha büyük olmalıdır",
|
||||
@@ -108,14 +109,14 @@
|
||||
"privacy_policy": "Gizlilik Politikası",
|
||||
"enable_protection": "Korumayı etkinleştir",
|
||||
"enabled_protection": "Koruma etkileştirildi",
|
||||
"disable_protection": "Korumayı durdur",
|
||||
"disable_protection": "Korumayı devre dışı bırak",
|
||||
"disabled_protection": "Koruma durduruldu",
|
||||
"refresh_statics": "İstatistikleri yenile",
|
||||
"dns_query": "DNS Sorguları",
|
||||
"blocked_by": "<0>Filtreler tarafından engellenen</0>",
|
||||
"stats_malware_phishing": "Engellenen kötü amaçlı yazılım ve kimlik avı",
|
||||
"stats_adult": "Engellenen yetişkin içerikli siteler",
|
||||
"stats_query_domain": "En fazla sorgulanan alan adları",
|
||||
"stats_query_domain": "Başlıca sorgulanan alan adları",
|
||||
"for_last_24_hours": "son 24 saat içindekiler",
|
||||
"for_last_days": "son {{count}} gün boyunca",
|
||||
"for_last_days_plural": "son {{count}} gün boyunca",
|
||||
@@ -123,8 +124,8 @@
|
||||
"stats_disabled_short": "İstatistikler devre dışı bırakıldı",
|
||||
"no_domains_found": "Alan adı bulunamadı",
|
||||
"requests_count": "İstek sayısı",
|
||||
"top_blocked_domains": "En fazla engellenen alan adları",
|
||||
"top_clients": "En aktif istemciler",
|
||||
"top_blocked_domains": "Başlıca engellenen alan adları",
|
||||
"top_clients": "Başlıca istemciler",
|
||||
"no_clients_found": "İstemci bulunamadı",
|
||||
"general_statistics": "Genel istatistikler",
|
||||
"number_of_dns_query_days": "Son {{count}} gün boyunca işlenen DNS sorgularının sayısı",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "normal DNS (UDP üzerinden, ana makine adı);",
|
||||
"example_upstream_dot": "şifrelenmiş <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "şifrelenmiş <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "şifrelenmiş <0>DNS-over-QUIC</0> (deneysel);",
|
||||
"example_upstream_doq": "şifrelenmiş <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<1>DNSCrypt</1> veya <2>DNS-over-HTTPS</2> çözümleyicileri için <0>DNS Damgaları</0>;",
|
||||
"example_upstream_tcp": "normal DNS (TCP üzerinden);",
|
||||
"example_upstream_tcp_hostname": "normal DNS (TCP üzerinden, ana makine adı);",
|
||||
@@ -238,7 +239,7 @@
|
||||
"empty_response_status": "Boş",
|
||||
"show_all_filter_type": "Tümünü göster",
|
||||
"show_filtered_type": "Filtrelenenleri göster",
|
||||
"no_logs_found": "Günlük kaydı bulunamadı",
|
||||
"no_logs_found": "Günlük bulunamadı",
|
||||
"refresh_btn": "Yenile",
|
||||
"previous_btn": "Önceki",
|
||||
"next_btn": "Sonraki",
|
||||
@@ -336,22 +337,22 @@
|
||||
"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ı açın.",
|
||||
"install_devices_windows_list_2": "Ağ ve İnternet kategorisine girin ve ardından Ağ ve Paylaşım Merkezi'ne girin.",
|
||||
"install_devices_windows_list_3": "Sol panelde \"Bağdaştırıcı ayarlarını değiştirin'e\" tıklayın.",
|
||||
"install_devices_windows_list_3": "Sol panelde \"Bağdaştırıcı ayarlarını değiştirin\" öğesine tıklayın.",
|
||||
"install_devices_windows_list_4": "Kullandığınız aktif bağlantının üzerine sağ tıklayın ve Özellikler öğesine tıklayın.",
|
||||
"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_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 öğesine 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 simgesine tıklayın ve Sistem Tercihleri'ne gidin.",
|
||||
"install_devices_macos_list_2": "Ağ'a tıklayın.",
|
||||
"install_devices_macos_list_1": "Apple simgesine tıklayın ve Sistem Tercihleri öğesine gidin.",
|
||||
"install_devices_macos_list_2": "Ağ öğesine 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_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_2": "Menüde bulunan Wi-Fi öğesine 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_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_3": "O anda aktif olan ağın adına dokunun.",
|
||||
"install_devices_ios_list_4": "DNS alanına AdGuard Home sunucunuzun adreslerini girin.",
|
||||
"get_started": "Başlayın",
|
||||
"next": "Sonraki",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "HTTPS bağlantı noktası yapılandırılırsa, AdGuard Home yönetici arayüzüne HTTPS aracılığıyla erişilebilir olacak ve ayrıca '/dns-query' üzerinden DNS-over-HTTPS bağlantısı sağlayacaktır.",
|
||||
"encryption_dot": "DNS-over-TLS bağlantı noktası",
|
||||
"encryption_dot_desc": "Bu bağlantı noktası yapılandırılırsa, AdGuard Home, DNS-over-TLS sunucusunu bu bağlantı noktası üzerinden çalıştıracaktır.",
|
||||
"encryption_doq": "DNS-over-QUIC bağlantı noktası (deneysel)",
|
||||
"encryption_doq_desc": "Bu bağlantı noktası yapılandırılırsa, AdGuard Home, DNS-over-QUIC sunucusunu bu bağlantı noktası üzerinden çalıştıracaktır. Bu özellik deneme aşamasındadır ve güvenilir olmayabilir. Ayrıca, şu anda bu özelliği destekleyen çok fazla istemci yok.",
|
||||
"encryption_doq": "DNS-over-QUIC bağlantı noktası",
|
||||
"encryption_doq_desc": "Bu bağlantı noktası yapılandırılırsa, AdGuard Home, bu bağlantı noktasında bir DNS-over-QUIC sunucusu çalıştıracaktır.",
|
||||
"encryption_certificates": "Sertifikalar",
|
||||
"encryption_certificates_desc": "Şifrelemeyi kullanmak için alan adınıza geçerli bir SSL sertifika zinciri sağlamanız gerekir. <0>{{link}}</0> adresinden ücretsiz bir sertifika alabilir veya güvenilir Sertifika Yetkililerinden satın alabilirsiniz.",
|
||||
"encryption_certificates_input": "PEM biçimindeki sertifikalarınızı kopyalayıp buraya yapıştırın.",
|
||||
@@ -388,7 +389,7 @@
|
||||
"encryption_issuer": "Sağlayan",
|
||||
"encryption_hostnames": "Ana makine 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_expiring_certificate": "SSL sertifikanızın süresi sona üzere. <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.",
|
||||
"form_error_port_range": "80-65535 aralığında geçerli bir bağlantı noktası değeri girin",
|
||||
"form_error_port_unsafe": "Güvenli olmayan bağlantı noktası",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "İzin verilmeyen 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ı",
|
||||
"updates_checked": "AdGuard Home'un yeni bir sürümü mevcut",
|
||||
"updates_version_equal": "AdGuard Home yazılımı güncel durumda",
|
||||
"check_updates_now": "Güncellemeleri şimdi denetle",
|
||||
"dns_privacy": "DNS Gizliliği",
|
||||
@@ -453,7 +454,7 @@
|
||||
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> <1>{{address}}</1> dizesini kullan.",
|
||||
"setup_dns_privacy_3": "<0>İşte, kullanabileceğiniz yazılımların bir listesi.</0>",
|
||||
"setup_dns_privacy_4": "Bir iOS 14 veya macOS Big Sur cihazında, DNS ayarlarına <highlight>DNS-over-HTTPS</highlight> veya <highlight>DNS-over-TLS</highlight> sunucuları ekleyen özel '.mobileconfig' dosyasını indirebilirsiniz.",
|
||||
"setup_dns_privacy_android_1": "Android 9, yerel olarak DNS-over-TLS protokolünü destekler. Yapılandırmak için Ayarlar → Ağ ve İnternet → Gelişmiş → Özel DNS seçeneğine gidin ve alan adınızı girin.",
|
||||
"setup_dns_privacy_android_1": "Android 9, yerel olarak DNS-over-TLS protokolünü destekler. Yapılandırmak için Ayarlar → Ağ ve İnternet → Gelişmiş → Özel DNS öğesine gidin ve alan adınızı girin.",
|
||||
"setup_dns_privacy_android_2": "<0>Android için AdGuard</0>, <1>DNS-over-HTTPS</1> ve <1>DNS-over-TLS</1> protokolünü destekler.",
|
||||
"setup_dns_privacy_android_3": "<0>Intra</0> Android'e <1>DNS-over-HTTPS</1> protokol desteğini ekler.",
|
||||
"setup_dns_privacy_ios_1": "<0>DNSCloak</0>, <1>DNS-over-HTTPS</1> protokolünü destekler, ancak kendi sunucunuzu kullanacak şekilde yapılandırmak için bir <2>DNS Damgası</2> oluşturmanız gerekir.",
|
||||
@@ -489,9 +490,9 @@
|
||||
"blocked_service": "Engellenen hizmet",
|
||||
"block_all": "Tümünü engelle",
|
||||
"unblock_all": "Tüm engellemeyi kaldır",
|
||||
"encryption_certificate_path": "Sertifika yolu",
|
||||
"encryption_certificate_path": "Sertifika dosya yolu",
|
||||
"encryption_private_key_path": "Özel anahtar yolu",
|
||||
"encryption_certificates_source_path": "Sertifika dosyalarının yolunu belirleyin",
|
||||
"encryption_certificates_source_path": "Bir sertifika dosyası yolu ayarlayın",
|
||||
"encryption_certificates_source_content": "Sertifika içeriğini yapıştır",
|
||||
"encryption_key_source_path": "Özel bir anahtar dosyası belirleyin",
|
||||
"encryption_key_source_content": "Özel anahtar içeriğini yapıştır",
|
||||
@@ -602,14 +603,14 @@
|
||||
"milliseconds_abbreviation": "ms",
|
||||
"cache_size": "Önbellek boyutu",
|
||||
"cache_size_desc": "DNS önbellek boyutu (bayt cinsinden).",
|
||||
"cache_ttl_min_override": "Minimum TTL'i değiştir",
|
||||
"cache_ttl_max_override": "Maksimum TTL'i değiştir",
|
||||
"cache_ttl_min_override": "Minimum kullanım süresini geçersiz kıl",
|
||||
"cache_ttl_max_override": "Maksimum kullanım süresini geçersiz kıl",
|
||||
"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 kullanım süresi girin (saniye olarak)",
|
||||
"enter_cache_ttl_max_override": "Maksimum kullanım süresi girin (saniye olarak)",
|
||||
"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 geçersiz kılma, maksimuma eşit veya bundan küçük olmalıdır",
|
||||
"ttl_cache_validation": "Minimum önbellek kullanım süresi geçersiz kılma, maksimum değerden küçük veya ona eşit olmalıdır",
|
||||
"cache_optimistic": "İyimser önbelleğe alma",
|
||||
"cache_optimistic_desc": "Girişlerin süresi dolduğunda bile AdGuard Home'un önbellekten yanıt vermesini sağlayın ve bunları yenilemeye çalışın.",
|
||||
"filter_category_general": "Genel",
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
"load_balancing": "Балансування навантаження",
|
||||
"load_balancing_desc": "Запитувати один сервер за раз. AdGuard Home використовуватиме зважений випадковий алгоритм для вибору сервера, щоб найшвидший сервер використовувався частіше.",
|
||||
"bootstrap_dns": "Bootstrap DNS-сервери",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS-сервери використовуються для пошуку IP-адреси DoH/DoT серверів, які ви встановили.",
|
||||
"bootstrap_dns_desc": "Bootstrap DNS-сервери використовуються для вирішення IP-адрес встановлених серверів DoH/DoT.",
|
||||
"local_ptr_title": "Приватні сервери для зворотного DNS",
|
||||
"local_ptr_desc": "DNS-сервери, які AdGuard Home використовує для локальних PTR-запитів. Ці сервери, використовуючи rDNS, використовуються для отримання доменних імен клієнтів у приватних мережах, наприклад, «192.168.12.34». Якщо список порожній, буде використовуватись системний DNS-сервер.",
|
||||
"local_ptr_default_resolver": "AdGuard Home усталено використовує такі зворотні DNS-резолвери: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home не зміг визначити приватні реверсивні DNS-резолвери, що були б придатними для цієї системи.",
|
||||
"local_ptr_desc": "DNS-сервери, які AdGuard Home використовує для локальних PTR-запитів. Ці сервери використовуються для вирішення PTR-запитів для адрес у приватних мережах, наприклад, «192.168.12.34». Якщо список порожній, AdGuard Home буде усталено використовувати системний DNS-сервер.",
|
||||
"local_ptr_default_resolver": "Стандартно AdGuard Home користується такими зворотними DNS-вирішувачами: {{ip}}.",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home не зміг визначити приватні зворотні DNS-вирішувачі, які підійшли б для цієї системи.",
|
||||
"local_ptr_placeholder": "Вводьте одну адресу на рядок",
|
||||
"resolve_clients_title": "Увімкнути запитування доменних імен для IP-адрес клієнтів",
|
||||
"resolve_clients_title": "Увімкнути зворотне вирішення IP-адрес клієнтів",
|
||||
"resolve_clients_desc": "Визначати доменні імена клієнтів за допомогою PTR-запитів до відповідних серверів — приватних DNS-серверів для локальних клієнтів та upstream-серверів для клієнтів з публічними IP-адресами.",
|
||||
"use_private_ptr_resolvers_title": "Використовувати приватні зворотні DNS-резолвери",
|
||||
"use_private_ptr_resolvers_desc": "Надсилати зворотні DNS-запити до вказаних серверів для клієнтів, що обслуговуються локально. Якщо вимкнено, AdGuard Home буде відповідати NXDOMAIN на всі такі PTR-запити, окрім запитів про клієнтів, що уже відомі по DHCP, /etc/hosts тощо.",
|
||||
"use_private_ptr_resolvers_desc": "Надсилати зворотні DNS-запити до вказаних серверів для клієнтів, що обслуговуються локально. Якщо вимкнено, AdGuard Home буде відповідати NXDOMAIN на всі такі PTR-запити, окрім запитів про клієнтів, що уже відомі завдяки DHCP, /etc/hosts тощо.",
|
||||
"check_dhcp_servers": "Перевірити DHCP-сервери",
|
||||
"save_config": "Зберегти конфігурацію",
|
||||
"enabled_dhcp": "DHCP-сервер увімкнено",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "Неправильна назва сервера",
|
||||
"form_error_subnet": "Підмережа «{{cidr}}» не містить IP-адресу «{{ip}}»",
|
||||
"form_error_positive": "Повинно бути більше за 0",
|
||||
"form_error_gateway_ip": "Оренда не може мати IP-адресу шлюзу",
|
||||
"out_of_range_error": "Не повинна бути в діапазоні «{{start}}»−«{{end}}»",
|
||||
"lower_range_start_error": "Має бути меншим за початкову адресу",
|
||||
"greater_range_start_error": "Має бути більшим за початкову адресу",
|
||||
@@ -60,12 +61,12 @@
|
||||
"dhcp_form_range_end": "Кінець діапазону",
|
||||
"dhcp_form_lease_title": "Час оренди DHCP (в секундах)",
|
||||
"dhcp_form_lease_input": "Тривалість оренди",
|
||||
"dhcp_interface_select": "Оберіть інтерфейс DHCP",
|
||||
"dhcp_interface_select": "Вибрати DHCP-інтерфейс",
|
||||
"dhcp_hardware_address": "Апаратна адреса",
|
||||
"dhcp_ip_addresses": "IP-адреси",
|
||||
"ip": "IP",
|
||||
"dhcp_table_hostname": "Назва вузла",
|
||||
"dhcp_table_expires": "Термін дії",
|
||||
"dhcp_table_expires": "Закінчується",
|
||||
"dhcp_warning": "Якщо ви однаково хочете увімкнути DHCP-сервер, переконайтеся, що у вашій мережі немає інших активних DHCP-серверів. Інакше, це може порушити роботу інтернету на під'єднаних пристроях!",
|
||||
"dhcp_error": "AdGuard Home не зміг визначити, чи є в мережі інший DHCP-сервер",
|
||||
"dhcp_static_ip_error": "Для використання DHCP-сервера необхідно встановити статичну IP-адресу. Нам не вдалося визначити, чи цей мережевий інтерфейс налаштовано для використання статичної IP-адреси. Встановіть статичну IP-адресу вручну.",
|
||||
@@ -77,7 +78,7 @@
|
||||
"dhcp_add_static_lease": "Додати статичну оренду",
|
||||
"dhcp_reset_leases": "Скинути всі аренди",
|
||||
"dhcp_reset_leases_confirm": "Ви дійсно хочете скинути усі аренди?",
|
||||
"dhcp_reset_leases_success": "Аренди DHCP успішно скинуто",
|
||||
"dhcp_reset_leases_success": "Оренду DHCP успішно скинуто",
|
||||
"dhcp_reset": "Ви дійсно хочете скинути DHCP-конфігурацію?",
|
||||
"country": "Країна",
|
||||
"city": "Місто",
|
||||
@@ -105,7 +106,7 @@
|
||||
"copyright": "Авторське право",
|
||||
"homepage": "Домашня сторінка",
|
||||
"report_an_issue": "Повідомити про проблему",
|
||||
"privacy_policy": "Політика приватності",
|
||||
"privacy_policy": "Політика конфіденційності",
|
||||
"enable_protection": "Увімкнути захист",
|
||||
"enabled_protection": "Захист увімкнено",
|
||||
"disable_protection": "Вимкнути захист",
|
||||
@@ -117,11 +118,11 @@
|
||||
"stats_adult": "Заблоковано вебсайтів для дорослих",
|
||||
"stats_query_domain": "Найчастіші запити доменів",
|
||||
"for_last_24_hours": "за останні 24 години",
|
||||
"for_last_days": "за останній день",
|
||||
"for_last_days": "за останній {{count}} день",
|
||||
"for_last_days_plural": "за останні {{count}} днів",
|
||||
"stats_disabled": "Статистику вимкнено. Ви можете увімкнути її на <0>сторінці налаштувань</0>.",
|
||||
"stats_disabled_short": "Статистику вимкнено",
|
||||
"no_domains_found": "Доменів не знайдено",
|
||||
"no_domains_found": "Не знайдено жодного домену",
|
||||
"requests_count": "Кількість запитів",
|
||||
"top_blocked_domains": "Найчастіше блоковані домени",
|
||||
"top_clients": "Найактивніші клієнти",
|
||||
@@ -131,21 +132,21 @@
|
||||
"number_of_dns_query_days_plural": "Кількість DNS-запитів, оброблених за останні {{count}} днів",
|
||||
"number_of_dns_query_24_hours": "Кількість DNS-запитів, оброблених за останні 24 години",
|
||||
"number_of_dns_query_blocked_24_hours": "Кількість DNS-запитів, заблокованих фільтрами і списками блокування hosts",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "Кількість DNS-запитів, заблокованих модулем безпеки перегляду AdGuard",
|
||||
"number_of_dns_query_blocked_24_hours_by_sec": "Кількість DNS-запитів, заблокованих модулем «Безпека перегляду» AdGuard",
|
||||
"number_of_dns_query_blocked_24_hours_adult": "Кількість заблокованих вебсайтів для дорослих",
|
||||
"enforced_save_search": "Примусовий безпечний пошук",
|
||||
"number_of_dns_query_to_safe_search": "Кількість DNS-запитів до пошукових систем, для яких примусово застосований безпечний пошук",
|
||||
"average_processing_time": "Середній час обробки",
|
||||
"average_processing_time_hint": "Середній час обробки DNS запиту в мілісекундах",
|
||||
"block_domain_use_filters_and_hosts": "Блокувати домени з використанням фільтрів та hosts-файлів",
|
||||
"block_domain_use_filters_and_hosts": "Блокування доменів за допомогою фільтрів та hosts-файлів",
|
||||
"filters_block_toggle_hint": "Ви можете налаштувати правила блокування в розділі <a>Фільтри</a>.",
|
||||
"use_adguard_browsing_sec": "Використовувати веб-службу безпечного перегляду AdGuard",
|
||||
"use_adguard_browsing_sec_hint": "AdGuard Home перевірятиме, чи додано домен до списку веб-служби безпечного перегляду браузера. Він використовуватиме API для перевірки — на сервер надсилається лише короткий префікс хешу SHA256 доменного імені.",
|
||||
"use_adguard_parental": "Використовувати вебсервіс Батьківського контролю AdGuard",
|
||||
"use_adguard_parental_hint": "AdGuard Home перевірятиме, чи домен містить матеріали для дорослих. Він використовує той самий орієнтований на приватність API, що й веб-служба безпечного перегляду.",
|
||||
"enforce_safe_search": "Використовувати безпечний пошук",
|
||||
"use_adguard_browsing_sec": "Використовувати вебслужбу «Безпека перегляду» AdGuard",
|
||||
"use_adguard_browsing_sec_hint": "AdGuard Home перевірятиме, чи підлягає домен блокуванню завдяки вебслужбі «Безпека перегляду». Для перевірки буде використано безпечний API — на сервер надсилається лише короткий префікс хешу SHA256 доменного імені.",
|
||||
"use_adguard_parental": "Використовувати вебслужбу «Батьківський контроль» AdGuard",
|
||||
"use_adguard_parental_hint": "AdGuard Home перевірить, чи містить домен матеріали для дорослих. Буде використано той же безпечний API, що й для «Безпеки перегляду» AdGuard.",
|
||||
"enforce_safe_search": "Використовувати Безпечний пошук",
|
||||
"enforce_save_search_hint": "AdGuard Home може примусово застосовувати безпечний пошук в таких пошукових системах: Google, YouTube, Bing, DuckDuckGo, Yandex, Pixabay.",
|
||||
"no_servers_specified": "Не вказано сервери",
|
||||
"no_servers_specified": "Сервери не вказано",
|
||||
"general_settings": "Загальні налаштування",
|
||||
"dns_settings": "Налаштування DNS",
|
||||
"dns_blocklists": "Список блокування DNS",
|
||||
@@ -158,15 +159,15 @@
|
||||
"upstream_dns": "Upstream DNS-сервери",
|
||||
"upstream_dns_help": "Введіть адреси серверів по одній на рядок. <a>Докладніше</a> про налаштування DNS-серверів.",
|
||||
"upstream_dns_configured_in_file": "Налаштовано в {{path}}",
|
||||
"test_upstream_btn": "Тест upstream серверів",
|
||||
"test_upstream_btn": "Перевірити сервери",
|
||||
"upstreams": "Upstreams",
|
||||
"apply_btn": "Застосувати",
|
||||
"disabled_filtering_toast": "Фільтрування вимкнено",
|
||||
"enabled_filtering_toast": "Фільтрування увімкнено",
|
||||
"disabled_safe_browsing_toast": "Безпечний перегляд вимкнено",
|
||||
"enabled_safe_browsing_toast": "Безпечний перегляд увімкнено",
|
||||
"disabled_parental_toast": "Батьківський контроль вимкнено",
|
||||
"enabled_parental_toast": "Батьківський контроль увімкнено",
|
||||
"disabled_parental_toast": "«Батьківський контроль» вимкнено",
|
||||
"enabled_parental_toast": "«Батьківський контроль» увімкнено",
|
||||
"disabled_safe_search_toast": "Безпечний пошук вимкнено",
|
||||
"enabled_save_search_toast": "Безпечний пошук увімкнено",
|
||||
"enabled_table_header": "Увімкнено",
|
||||
@@ -193,7 +194,7 @@
|
||||
"edit_blocklist": "Змінити список блокування",
|
||||
"edit_allowlist": "Змінити список дозволів",
|
||||
"choose_blocklist": "Виберіть списки блокування",
|
||||
"choose_allowlist": "Обрати списки дозволених сайтів",
|
||||
"choose_allowlist": "Виберіть списки дозволів",
|
||||
"enter_valid_blocklist": "Введіть дійсну URL-адресу в список блокування.",
|
||||
"enter_valid_allowlist": "Введіть дійсну URL-адресу в список дозволів.",
|
||||
"form_error_url_format": "Неправильний формат URL",
|
||||
@@ -213,12 +214,12 @@
|
||||
"example_upstream_udp": "звичайний DNS (поверх UDP, з назвою вузла);",
|
||||
"example_upstream_dot": "зашифрований <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "зашифрований <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "зашифрований <0>DNS-over-QUIC</0> (експериментальний);",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> для <1>DNSCrypt</1> або <2>DNS-over-HTTPS</2> серверів;",
|
||||
"example_upstream_doq": "зашифрований <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "<0>DNS Stamps</0> для <1>DNSCrypt-</1> або <2>DNS-over-HTTPS-</2>вирішувачів;",
|
||||
"example_upstream_tcp": "звичайний DNS (через TCP);",
|
||||
"example_upstream_tcp_hostname": "звичайний DNS (поверх TCP, з назвою вузла);",
|
||||
"all_lists_up_to_date_toast": "Всі списки вже оновлені",
|
||||
"updated_upstream_dns_toast": "DNS-сервери оновлено",
|
||||
"updated_upstream_dns_toast": "DNS-сервери успішно збережено",
|
||||
"dns_test_ok_toast": "Вказані DNS сервери працюють правильно",
|
||||
"dns_test_not_ok_toast": "Сервер «{{key}}»: неможливо використати. Перевірте правильність введення",
|
||||
"unblock": "Дозволити",
|
||||
@@ -245,7 +246,7 @@
|
||||
"loading_table_status": "Завантаження...",
|
||||
"page_table_footer_text": "Сторінка",
|
||||
"rows_table_footer_text": "рядків",
|
||||
"updated_custom_filtering_toast": "Власні правила фільтрування збережено",
|
||||
"updated_custom_filtering_toast": "Власні правила фільтрування успішно збережено",
|
||||
"rule_removed_from_custom_filtering_toast": "Правило вилучено з власних правил фільтрування: {{rule}}",
|
||||
"rule_added_to_custom_filtering_toast": "Правило додано до власних правил фільтрування: {{rule}}",
|
||||
"query_log_response_status": "Стан: {{value}}",
|
||||
@@ -266,7 +267,7 @@
|
||||
"dns_cache_config": "Конфігурація кешу DNS",
|
||||
"dns_cache_config_desc": "Тут ви можете налаштувати DNS-кеш",
|
||||
"blocking_mode": "Режим блокування",
|
||||
"default": "Типовий",
|
||||
"default": "Усталено",
|
||||
"nxdomain": "NXDOMAIN",
|
||||
"refused": "REFUSED",
|
||||
"null_ip": "Нульовий IP",
|
||||
@@ -316,7 +317,7 @@
|
||||
"install_settings_dns_desc": "Вам потрібно буде налаштувати свої пристрої або маршрутизатор для використання DNS-сервера за такими адресами:",
|
||||
"install_settings_all_interfaces": "Усі інтерфейси",
|
||||
"install_auth_title": "Авторизація",
|
||||
"install_auth_desc": "Необходно налаштувати автентифікацію паролем для вебінтерфейсу AdGuard Home. Навіть якщо він доступний лише у вашій локальній мережі, важливо захистити його від необмеженого доступу.\n\nДолжна быть настроена аутентификация паролем для веб-интерфейса AdGuard Home. Даже если он доступен только в вашей локальной сети, важно защитить его от неограниченного доступа.",
|
||||
"install_auth_desc": "Необхідно налаштувати автентифікацію паролем для вебінтерфейсу AdGuard Home. Навіть якщо він доступний лише у вашій локальній мережі, важливо захистити його від необмеженого доступу.",
|
||||
"install_auth_username": "Ім'я користувача",
|
||||
"install_auth_password": "Пароль",
|
||||
"install_auth_confirm": "Підтвердьте пароль",
|
||||
@@ -336,7 +337,7 @@
|
||||
"install_devices_router_list_4": "Ви не можете встановити власний DNS-сервер на деяких типах маршрутизаторів. У цьому разі вам може допомогти налаштування AdGuard Home в якості <0>DHCP-сервера</0>. В іншому разі вам потрібно знайти інструкцію щодо налаштування DNS-сервера для вашої конкретної моделі маршрутизатора.",
|
||||
"install_devices_windows_list_1": "Відкрийте Панель керування через меню «Пуск» або пошук Windows.",
|
||||
"install_devices_windows_list_2": "Перейдіть до категорії Мережа й Інтернет, а потім до Центру мереж і спільного доступу.",
|
||||
"install_devices_windows_list_3": "Зліва на екрані натисніть на «Змінити настройки адаптера».",
|
||||
"install_devices_windows_list_3": "Зліва на екрані натисніть на «Змінити налаштування адаптера».",
|
||||
"install_devices_windows_list_4": "Клацніть на активному з'єднанні правою кнопкою миші та виберіть «Властивості».",
|
||||
"install_devices_windows_list_5": "Знайдіть у списку пункт «Internet Protocol Version 4 (TCP/IPv4)» або «Internet Protocol Version 6 (TCP/IPv6)», виберіть його та натисніть кнопку Властивості ще раз.",
|
||||
"install_devices_windows_list_6": "Виберіть «Використовувати наступні адреси DNS-серверів» та введіть адреси вашого сервера AdGuard Home.",
|
||||
@@ -351,7 +352,7 @@
|
||||
"install_devices_android_list_5": "Змініть встановлені значення DNS 1 і DNS 2 на адреси вашого домашнього сервера AdGuard.",
|
||||
"install_devices_ios_list_1": "На головному екрані торкніться Налаштування.",
|
||||
"install_devices_ios_list_2": "Виберіть Wi-Fi у меню ліворуч (неможливо налаштувати DNS для мобільних мереж).",
|
||||
"install_devices_ios_list_3": "Натисніть на назву поточно активної мережі.",
|
||||
"install_devices_ios_list_3": "Натисніть на назву поточної активної мережі.",
|
||||
"install_devices_ios_list_4": "У полі DNS введіть адреси вашого сервера AdGuard Home.",
|
||||
"get_started": "Розпочати",
|
||||
"next": "Наступні",
|
||||
@@ -369,13 +370,13 @@
|
||||
"encryption_https_desc": "Якщо HTTPS-порт налаштовано, інтерфейс адміністратора AdGuard Home буде доступний через HTTPS, а також DNS-over-HTTPS-сервер буде доступний за адресою /dns-query.",
|
||||
"encryption_dot": "Порт DNS-over-TLS",
|
||||
"encryption_dot_desc": "Якщо цей порт налаштовано, AdGuard Home запустить на цьому порту сервер DNS-over-TLS.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC (експериментальний)",
|
||||
"encryption_doq_desc": "Якщо цей порт налаштовано, AdGuard Home запустить на цьому порту сервер DNS-over-QUIC. Це експериментально і може бути ненадійним. Крім того, зараз не так багато клієнтів, які це підтримують.",
|
||||
"encryption_doq": "Порт DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Якщо цей порт налаштовано, AdGuard Home запустить на ньому сервер DNS-over-QUIC.",
|
||||
"encryption_certificates": "Сертифікати",
|
||||
"encryption_certificates_desc": "Для використання шифрування потрібно надати дійсний ланцюжок сертифікатів SSL для вашого домену. Ви можете отримати безкоштовний сертифікат на <0>{{link}}</0> або придбати його в одному з надійних Центрів Сертифікації.",
|
||||
"encryption_certificates_desc": "Для використання шифрування потрібно надати дійсний ланцюжок сертифікатів SSL для вашого домену. Ви можете отримати безплатний сертифікат на <0>{{link}}</0> або придбати його в одному з надійних Центрів Сертифікації.",
|
||||
"encryption_certificates_input": "Скопіюйте/вставте сюди свої кодовані PEM сертифікати.",
|
||||
"encryption_status": "Статус",
|
||||
"encryption_expire": "Закічнується",
|
||||
"encryption_expire": "Закінчується",
|
||||
"encryption_key": "Приватний ключ",
|
||||
"encryption_key_input": "Скопіюйте/вставте сюди свій приватний ключ кодований PEM для вашого сертифіката.",
|
||||
"encryption_enable": "Увімкнути шифрування (HTTPS, DNS-over-HTTPS і DNS-over-TLS)",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "Заборонені домени",
|
||||
"access_blocked_desc": "Не плутайте з фільтрами. AdGuard Home буде ігнорувати DNS-запити з цими доменами, такі запити навіть не будуть записані до журналу. Ви можете вказати точні доменні імена, замінні знаки та правила фільтрування URL-адрес, наприклад, 'example.org', '*.example.org' або '||example.org^' відповідно.",
|
||||
"access_settings_saved": "Налаштування доступу успішно збережено",
|
||||
"updates_checked": "Оновлення успішно перевірені",
|
||||
"updates_checked": "Доступна нова версія AdGuard Home",
|
||||
"updates_version_equal": "AdGuard Home останньої версії",
|
||||
"check_updates_now": "Перевірити наявність оновлень",
|
||||
"dns_privacy": "Конфіденційність DNS",
|
||||
@@ -514,7 +515,7 @@
|
||||
"statistics_clear": "Очистити статистику",
|
||||
"statistics_clear_confirm": "Ви впевнені, що хочете очистити статистику?",
|
||||
"statistics_retention_confirm": "Ви впевнені, що хочете змінити тривалість статистики? Якщо зменшити значення інтервалу, деякі дані будуть втрачені",
|
||||
"statistics_cleared": "Статистика успішно очищена",
|
||||
"statistics_cleared": "Статистику успішно очищено",
|
||||
"statistics_enable": "Увімкнути статистику",
|
||||
"interval_hours": "{{count}} година",
|
||||
"interval_hours_plural": "{{count}} годин(и)",
|
||||
@@ -552,16 +553,16 @@
|
||||
"fastest_addr": "Найшвидша IP-адреса",
|
||||
"fastest_addr_desc": "Опитати всі DNS-сервери й повернути найшвидшу IP-адресу серед усіх наданих. Це сповільнить швидкість DNS-запитів, оскільки AdGuard Home повинен буде чекати відповіді усіх DNS-серверів, але водночас може покращити якість з'єднання.",
|
||||
"autofix_warning_text": "Якщо ви натиснете «Виправити», AdGuard Home налаштує вашу систему на використання DNS-сервера AdGuard Home.",
|
||||
"autofix_warning_list": "Це виконає наступні завдання: <0>Деактивує систему DNSStubListener</0> <0>Змінить адресу DNS сервера на 127.0.0.1</0> <0>Замінить символічне посилання /etc/resolv.conf на /run/systemd/resolve/resolv.conf</0> <0>Зупинить DNSStubListener (перезапустить сервіс systemd-resolved)</0>",
|
||||
"autofix_warning_list": "Будуть виконані такі дії: <0>Деактивація системи DNSStubListener</0> <0>Зміна адреси DNS-сервера на «127.0.0.1»</0> <0>Заміна символічного посилання «/etc/resolv.conf» на «/run/systemd/resolve/resolv.conf»</0> <0>Зупинка DNSStubListener (перезапуск системної служби systemd-resolved)</0>",
|
||||
"autofix_warning_result": "В результаті буде усталено, що усі DNS-запити вашої системи будуть опрацьовані AdGuard Home.",
|
||||
"tags_title": "Теги",
|
||||
"tags_desc": "Ви можете вибрати теги, які відповідають клієнту. Теги можна використати в правилах фільтрування, щоб точніше застосовувати їх. <0>Докладніше</0>.",
|
||||
"form_select_tags": "Виберіть теги клієнта",
|
||||
"check_title": "Перевірте фільтрування",
|
||||
"check_title": "Перевірити фільтрування",
|
||||
"check_desc": "Перевірити чи фільтрується назва вузла.",
|
||||
"check": "Перевірити",
|
||||
"form_enter_host": "Введіть назву вузла",
|
||||
"filtered_custom_rules": "Відфільтровано за власними правилами фільтрування",
|
||||
"filtered_custom_rules": "Відфільтровано завдяки власним правилам фільтрування",
|
||||
"choose_from_list": "Виберіть зі списку",
|
||||
"add_custom_list": "Додати власний список",
|
||||
"host_whitelisted": "Вузол додано до списку дозволів",
|
||||
@@ -585,14 +586,14 @@
|
||||
"list_updated": "{{count}} список оновлено",
|
||||
"list_updated_plural": "{{count}} списки оновлено",
|
||||
"dnssec_enable": "Увімкнути DNSSEC",
|
||||
"dnssec_enable_desc": "Встановити прапорець DNSSEC для вихідних DNS запитів та перевірити результат (потрібен розпізнавач з підтримкою DNSSEC).",
|
||||
"dnssec_enable_desc": "Увімкнути DNSSEC для вихідних DNS-запитів та перевірити результат (потрібен вирішувач з підтримкою DNSSEC).",
|
||||
"validated_with_dnssec": "Засвідчено DNSSEC",
|
||||
"all_queries": "Усі запити",
|
||||
"show_blocked_responses": "Заблоковані",
|
||||
"show_whitelisted_responses": "Дозволені",
|
||||
"show_processed_responses": "Оброблені",
|
||||
"blocked_safebrowsing": "Заблоковано Безпечним переглядом",
|
||||
"blocked_adult_websites": "Заблоковано Батьківським контролем",
|
||||
"blocked_safebrowsing": "Заблоковано модулем «Безпека перегляду»",
|
||||
"blocked_adult_websites": "Заблоковано «Батьківським контролем»",
|
||||
"blocked_threats": "Заблоковано загроз",
|
||||
"allowed": "Дозволено",
|
||||
"filtered": "Відфільтровано",
|
||||
|
||||
@@ -213,14 +213,14 @@
|
||||
"example_upstream_udp": "DNS thông thường (qua UDP, tên máy chủ);",
|
||||
"example_upstream_dot": "được mã hoá <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "được mã hoá <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "được mã hoá <0>DNS-over-QUIC</0> (thử nghiệm);",
|
||||
"example_upstream_doq": "được mã hoá <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "bạn có thể sử dụng <0>DNS Stamps</0> for <1>DNSCrypt</1> hoặc <2>DNS-over-HTTPS</2> ",
|
||||
"example_upstream_tcp": "DNS thông thường(dùng TCP);",
|
||||
"example_upstream_tcp_hostname": "DNS thông thường (qua TCP, tên máy chủ);",
|
||||
"all_lists_up_to_date_toast": "Tất cả danh sách đã ở phiên bản mới nhất",
|
||||
"updated_upstream_dns_toast": "Các máy chủ thượng nguồn đã được lưu thành công",
|
||||
"dns_test_ok_toast": "Máy chủ DNS có thể sử dụng",
|
||||
"dns_test_not_ok_toast": "Máy chủ \"\"': không thể sử dụng, vui lòng kiểm tra lại",
|
||||
"dns_test_not_ok_toast": "Máy chủ \"{{key}}\"': không thể sử dụng, vui lòng kiểm tra lại",
|
||||
"unblock": "Bỏ chặn",
|
||||
"block": "Chặn",
|
||||
"disallow_this_client": "Không cho phép client này",
|
||||
@@ -369,8 +369,8 @@
|
||||
"encryption_https_desc": "Nếu cổng HTTPS được định cấu hình, giao diện quản trị viên AdGuard Home sẽ có thể truy cập thông qua HTTPS và nó cũng sẽ cung cấp DNS-over-HTTPS trên vị trí '/dns-query'.",
|
||||
"encryption_dot": "Cổng DNS-over-TLS",
|
||||
"encryption_dot_desc": "Nếu cổng này được định cấu hình, AdGuard Home sẽ chạy máy chủ DNS-over-TLS trên cổng này.",
|
||||
"encryption_doq": "Cổng DNS-over-QUIC (thử nghiệm)",
|
||||
"encryption_doq_desc": "Nếu cổng này được định cấu hình, AdGuard Home sẽ chạy máy chủ DNS qua QUIC trên cổng này. Đó là thử nghiệm và có thể không đáng tin cậy. Ngoài ra, không có quá nhiều khách hàng hỗ trợ nó vào lúc này.",
|
||||
"encryption_doq": "Cổng DNS-over-QUIC",
|
||||
"encryption_doq_desc": "Nếu cổng này được định cấu hình, AdGuard Home sẽ chạy máy chủ DNS qua QUIC trên cổng này. ",
|
||||
"encryption_certificates": "Chứng chỉ",
|
||||
"encryption_certificates_desc": "Để sử dụng mã hóa, bạn cần cung cấp chuỗi chứng chỉ SSL hợp lệ cho miền của mình. Bạn có thể nhận chứng chỉ miễn phí trên <0>{{link}}</0> hoặc bạn có thể mua chứng chỉ từ một trong các Cơ Quan Chứng Nhận tin cậy.",
|
||||
"encryption_certificates_input": "Sao chép/dán chứng chỉ được mã hóa PEM của bạn tại đây.",
|
||||
@@ -445,7 +445,7 @@
|
||||
"access_blocked_title": "Tên miền bị chặn",
|
||||
"access_blocked_desc": "Đừng nhầm lẫn điều này với các bộ lọc. AdGuard Home sẽ bỏ các truy vấn DNS với các tên miền này trong câu hỏi của truy vấn.",
|
||||
"access_settings_saved": "Cài đặt truy cập đã lưu thành công",
|
||||
"updates_checked": "Đã kiểm tra thành công cập nhật",
|
||||
"updates_checked": "Phiên bản mới của AdGuard Home có sẵn",
|
||||
"updates_version_equal": "AdGuard Home đã được cập nhật",
|
||||
"check_updates_now": "Kiểm tra cập nhật ngay bây giờ",
|
||||
"dns_privacy": "DNS Riêng Tư",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "无效的服务器名",
|
||||
"form_error_subnet": "子网 \"{{cidr}}\" 不包含 IP 地址 \"{{ip}}\"",
|
||||
"form_error_positive": "必须大于 0",
|
||||
"form_error_gateway_ip": "租约期限不能有网关的 IP 地址",
|
||||
"out_of_range_error": "必定超出了范围 \"{{start}}\"-\"{{end}}\"",
|
||||
"lower_range_start_error": "必须小于范围起始值",
|
||||
"greater_range_start_error": "必须大于范围起始值",
|
||||
@@ -148,8 +149,8 @@
|
||||
"no_servers_specified": "未找到指定的服务器",
|
||||
"general_settings": "常规设置",
|
||||
"dns_settings": "DNS 设置",
|
||||
"dns_blocklists": "DNS封锁清单",
|
||||
"dns_allowlists": "DNS允许清单",
|
||||
"dns_blocklists": "DNS 拦截列表",
|
||||
"dns_allowlists": "DNS 允许列表",
|
||||
"dns_blocklists_desc": "AdGuard Home将阻止匹配DNS拦截清单的域名",
|
||||
"dns_allowlists_desc": "来自DNS允许列表的域将被允许,即使它们位于任意阻止列表中也是如此",
|
||||
"custom_filtering_rules": "自定义过滤规则",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "常规 DNS(通过 UDP、主机名);",
|
||||
"example_upstream_dot": "加密 <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "加密 <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "加密 <0>DNS-over-QUIC</0>(实验性的);",
|
||||
"example_upstream_doq": "加密 <0>DNS-over-QUIC</0>",
|
||||
"example_upstream_sdns": "<1>DNSCrypt</1> 的 <0>DNS Stamps</0> 或者 <2>DNS-over-HTTPS</2> 解析器;",
|
||||
"example_upstream_tcp": "常规 DNS(基于 TCP );",
|
||||
"example_upstream_tcp_hostname": "常规 DNS(通过 TCP、主机名);",
|
||||
@@ -335,22 +336,22 @@
|
||||
"install_devices_router_list_3": "请在此处输入您的 AdGuard Home 服务器地址。",
|
||||
"install_devices_router_list_4": "在某些类型的路由器上无法设置自定义 DNS 服务器。在此情况下将 AdGuard Home 设置为 <0>DHCP 服务器</0>,可能会有所帮助。否则您应该查找如何根据特定路由器型号设置 DNS 服务器的使用手册。",
|
||||
"install_devices_windows_list_1": "通过开始菜单或 Windows 搜索功能打开控制面板。",
|
||||
"install_devices_windows_list_2": "点击进入 ”网络和 Internet“ 后,再次点击进入 “网络和共享中心”",
|
||||
"install_devices_windows_list_2": "点击进入「网络和 Internet」后,再次点击进入「网络和共享中心」",
|
||||
"install_devices_windows_list_3": "在窗口的左侧点击「更改适配器设置」。",
|
||||
"install_devices_windows_list_4": "选择您正在连接的网络设备,右击它并选择「属性”」。",
|
||||
"install_devices_windows_list_5": "在列表中找到 ”Internet 协议版本 4 (TCP/IPv4)“ ,选择并再次点击 ”属性“ 。",
|
||||
"install_devices_windows_list_5": "在列表中找到「Internet 协议版本 4 (TCP/IPv4)」,选择并再次点击「属性」。",
|
||||
"install_devices_windows_list_6": "选择“使用下面的 DNS 服务器地址”,并输入您的 AdGuard Home 服务器地址。",
|
||||
"install_devices_macos_list_1": "点击苹果图标,进入「系统首选项」。",
|
||||
"install_devices_macos_list_2": "点击「网络」。",
|
||||
"install_devices_macos_list_3": "选择在列表中的第一个连接,并点击 ”高级“ 。",
|
||||
"install_devices_macos_list_4": "选择 ”DNS“ 选项卡,并输入您的 AdGuard Home 服务器地址。",
|
||||
"install_devices_macos_list_3": "选择在列表中的第一个连接,并点击「高级」。",
|
||||
"install_devices_macos_list_4": "选择「DNS」选项卡,并输入您的 AdGuard Home 服务器地址。",
|
||||
"install_devices_android_list_1": "在安卓主屏幕菜单中点击设置。",
|
||||
"install_devices_android_list_2": "点击菜单上的 ”无线局域网“ 选项。在屏幕上将列出所有可用的网络(蜂窝移动网络不支持修改 DNS )。",
|
||||
"install_devices_android_list_3": "长按当前已连接的网络,然后点击 ”修改网络设置“ 。",
|
||||
"install_devices_android_list_4": "在某些设备上,您可能需要选中 ”高级“ 复选框以查看进一步的设置。您可能需要调整您安卓设备的 DNS 设置,或是需要将 IP 设置从 DHCP 切换到静态。",
|
||||
"install_devices_android_list_2": "点击菜单上的「无线局域网」选项。在屏幕上将列出所有可用的网络(蜂窝移动网络不支持修改 DNS )。",
|
||||
"install_devices_android_list_3": "长按当前已连接的网络,然后点击「修改网络设置」。",
|
||||
"install_devices_android_list_4": "在某些设备上,您可能需要选中「高级」复选框以查看进一步的设置。您可能需要调整您安卓设备的 DNS 设置,或是需要将 IP 设置从 DHCP 切换到静态。",
|
||||
"install_devices_android_list_5": "将 DNS 1 和 DNS 2 的值改为您的 AdGuard Home 服务器地址。",
|
||||
"install_devices_ios_list_1": "从主屏幕中点击 ”设置“ 。",
|
||||
"install_devices_ios_list_2": "从左侧目录中选择 ”无线局域网“(移动数据网络环境下不支持修改 DNS )。",
|
||||
"install_devices_ios_list_1": "从主屏幕中点击「设置」。",
|
||||
"install_devices_ios_list_2": "从左侧目录中选择「无线局域网」(移动数据网络环境下不支持修改 DNS )。",
|
||||
"install_devices_ios_list_3": "点击当前已连接网络的名称。",
|
||||
"install_devices_ios_list_4": "在 DNS 字段中输入您的 AdGuard Home 服务器地址。",
|
||||
"get_started": "开始配置",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "如果配置了 HTTPS 端口,AdGuard Home 管理界面将可以通过 HTTPS 访问,它还将在在 '/dns-query' 位置提供 DNS-over-HTTPS 。",
|
||||
"encryption_dot": "DNS-over-TLS 端口",
|
||||
"encryption_dot_desc": "如果配置了此端口,AdGuard Home 将在此端口上运行一个 DNS-over-TLS 服务器。",
|
||||
"encryption_doq": "DNS-over-QUIC 端口(实验性的)",
|
||||
"encryption_doq_desc": "如果配置了此端口,AdGuard Home将在此端口上运行一个DNS-over-QUIC服务器。这是实验性的,可能不可靠。而且,支持此特性的客户端并不多。",
|
||||
"encryption_doq": "DNS-over-QUIC 端口",
|
||||
"encryption_doq_desc": "如果配置了此端口,AdGuard Home 将在此端口上运行一个 DNS-over-QUIC 服务器。",
|
||||
"encryption_certificates": "证书",
|
||||
"encryption_certificates_desc": "为了使用加密,您需要为域提供有效的 SSL 证书链。您可以在 <0>{{link}}</0> 上获得免费证书,也可以从受信任的证书颁发机构购买证书。",
|
||||
"encryption_certificates_input": "将您以 PEM 格式编码的证书复制粘贴到此处。",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "不允许的域名",
|
||||
"access_blocked_desc": "不要将此功能与过滤器混淆。AdGuard Home 将排除匹配这些网域的 DNS 查询,并且这些查询将不会在查询日志中显示。在此可以明确指定域名、通配符(wildcard)和网址过滤的规则,例如 \"example.org\"、\"*.example.org\" 或 \"||example.org^\"。",
|
||||
"access_settings_saved": "访问设置保存成功",
|
||||
"updates_checked": "检查更新成功",
|
||||
"updates_checked": "AdGuard Home 的新版本现在可用",
|
||||
"updates_version_equal": "AdGuard Home已经是最新版本",
|
||||
"check_updates_now": "立即检查更新",
|
||||
"dns_privacy": "DNS 隐私",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"bootstrap_dns": "自我啟動(Bootstrap)DNS 伺服器",
|
||||
"bootstrap_dns_desc": "自我啟動(Bootstrap)DNS 伺服器被用於解析您明確指定作為上游的 DoH/DoT 解析器之 IP 位址。",
|
||||
"local_ptr_title": "私人反向的 DNS 伺服器",
|
||||
"local_ptr_desc": "AdGuard Home 用於區域指標(PTR)查詢之 DNS 伺服器。這些伺服器被用於解析含私人 IP 位址的用戶端之主機名稱,例如,\"192.168.12.34\",使用反向的 DNS。如果未被設定,除 AdGuard Home 它本身的位址之外,AdGuard Home 使用您的作業系統之預設 DNS 解析器的位址。",
|
||||
"local_ptr_desc": "AdGuard Home 用於區域指標(PTR)查詢之 DNS 伺服器。這些伺服器被用於解析有關在私人 IP 範圍的位址之區域指標查詢,例如,\"192.168.12.34\",使用反向的 DNS。如果未被設定,AdGuard Home 使用您的作業系統之預設 DNS 解析器的位址。",
|
||||
"local_ptr_default_resolver": "預設下,AdGuard Home 使用以下反向的 DNS 解析器:{{ip}}。",
|
||||
"local_ptr_no_default_resolver": "AdGuard Home 無法為此系統決定合適的私人反向的 DNS 解析器。",
|
||||
"local_ptr_placeholder": "每行輸入一個伺服器位址",
|
||||
@@ -47,6 +47,7 @@
|
||||
"form_error_server_name": "無效的伺服器名稱",
|
||||
"form_error_subnet": "子網路 \"{{cidr}}\" 不包含該 IP 位址 \"{{ip}}\"",
|
||||
"form_error_positive": "必須大於 0",
|
||||
"form_error_gateway_ip": "租約不能有閘道的 IP 位址",
|
||||
"out_of_range_error": "必須在\"{{start}}\"-\"{{end}}\"範圍之外",
|
||||
"lower_range_start_error": "必須低於起始範圍",
|
||||
"greater_range_start_error": "必須大於起始範圍",
|
||||
@@ -213,7 +214,7 @@
|
||||
"example_upstream_udp": "常規 DNS(透過 UDP,主機名稱);",
|
||||
"example_upstream_dot": "加密的 <0>DNS-over-TLS</0>;",
|
||||
"example_upstream_doh": "加密的 <0>DNS-over-HTTPS</0>;",
|
||||
"example_upstream_doq": "加密的 <0>DNS-over-QUIC</0>(實驗性的);",
|
||||
"example_upstream_doq": "加密的 <0>DNS-over-QUIC</0>;",
|
||||
"example_upstream_sdns": "關於 <1>DNSCrypt</1> 或 <2>DNS-over-HTTPS</2> 解析器之 <0>DNS 戳記</0>;",
|
||||
"example_upstream_tcp": "常規 DNS(透過 TCP);",
|
||||
"example_upstream_tcp_hostname": "常規 DNS(透過 TCP,主機名稱);",
|
||||
@@ -369,8 +370,8 @@
|
||||
"encryption_https_desc": "如果 HTTPS 連接埠被配置,AdGuard Home 管理員介面透過 HTTPS 將為可存取的,且它也將於 '/dns-query' 位置上提供 DNS-over-HTTPS。",
|
||||
"encryption_dot": "DNS-over-TLS 連接埠",
|
||||
"encryption_dot_desc": "如果該連接埠被配置,AdGuard Home 將於此連接埠上運行 DNS-over-TLS 伺服器。",
|
||||
"encryption_doq": "DNS-over-QUIC 連接埠(實驗性的)",
|
||||
"encryption_doq_desc": "如果此連接埠被配置,AdGuard Home 將於此連接埠上運行 DNS-over-QUIC 伺服器。它是實驗性的並可能為不可靠的。再者,此刻沒有太多支援它的用戶端。",
|
||||
"encryption_doq": "DNS-over-QUIC 連接埠",
|
||||
"encryption_doq_desc": "如果此連接埠被配置,AdGuard Home 將於此連接埠上運行 DNS-over-QUIC 伺服器。",
|
||||
"encryption_certificates": "憑證",
|
||||
"encryption_certificates_desc": "為了使用加密,您需要提供有效的安全通訊端層(SSL)憑證鏈結供您的網域。於 <0>{{link}}</0> 上您可取得免費的憑證或您可從受信任的憑證授權單位之一購買它。",
|
||||
"encryption_certificates_input": "於此複製/貼上您的隱私增強郵件編碼之(PEM-encoded)憑證。",
|
||||
@@ -445,7 +446,7 @@
|
||||
"access_blocked_title": "未被允許的網域",
|
||||
"access_blocked_desc": "不要把這個和過濾器混淆。AdGuard Home 排除與這些網域相符的 DNS 查詢,且這些查詢甚至不會出現在查詢記錄中。您可相應地明確指定確切的域名、萬用字元(wildcard)或網址過濾器的規則,例如,\"example.org\"、\"*.example.org\" 或 \"||example.org^\"。",
|
||||
"access_settings_saved": "存取設定被成功地儲存",
|
||||
"updates_checked": "更新被成功地檢查",
|
||||
"updates_checked": "AdGuard Home 的新版本為可用的",
|
||||
"updates_version_equal": "AdGuard Home 為最新的",
|
||||
"check_updates_now": "立即檢查更新",
|
||||
"dns_privacy": "DNS 隱私",
|
||||
@@ -625,11 +626,11 @@
|
||||
"click_to_view_queries": "點擊以檢視查詢",
|
||||
"port_53_faq_link": "連接埠 53 常被 \"DNSStubListener\" 或 \"systemd-resolved\" 服務佔用。請閱讀有關如何解決這個的<0>用法說明</0>。",
|
||||
"adg_will_drop_dns_queries": "AdGuard Home 將持續排除來自此用戶端之所有的 DNS 查詢。",
|
||||
"filter_allowlist": "警告:此操作將把 \"{{disallowed_rule}}\" 規則排除在已允許用戶端的清單之外。",
|
||||
"last_rule_in_allowlist": "無法禁止此用戶端,因為排除 “{{disallowed_rule}}” 規則將禁用“已允許用戶端”的清單。",
|
||||
"filter_allowlist": "警告:此動作也將把 \"{{disallowed_rule}}\" 規則排除在已允許的用戶端的清單之外。",
|
||||
"last_rule_in_allowlist": "因為排除 \"{{disallowed_rule}}\" 規則將禁用\"已允許的用戶端\"清單,無法不允許此用戶端。",
|
||||
"use_saved_key": "使用該先前已儲存的金鑰",
|
||||
"parental_control": "家長控制",
|
||||
"safe_browsing": "安全瀏覽",
|
||||
"served_from_cache": "{{value}} <i>(由快取提供)</i>",
|
||||
"served_from_cache": "{{value}} <i>(由快取提供)</i>",
|
||||
"form_error_password_length": "密碼必須為至少長 {{value}} 個字元"
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ export const getTlsStatus = () => async (dispatch) => {
|
||||
export const setTlsConfigRequest = createAction('SET_TLS_CONFIG_REQUEST');
|
||||
export const setTlsConfigFailure = createAction('SET_TLS_CONFIG_FAILURE');
|
||||
export const setTlsConfigSuccess = createAction('SET_TLS_CONFIG_SUCCESS');
|
||||
export const dnsStatusSuccess = createAction('DNS_STATUS_SUCCESS');
|
||||
|
||||
export const setTlsConfig = (config) => async (dispatch, getState) => {
|
||||
dispatch(setTlsConfigRequest());
|
||||
@@ -39,6 +40,12 @@ export const setTlsConfig = (config) => async (dispatch, getState) => {
|
||||
const response = await apiClient.setTlsConfig(values);
|
||||
response.certificate_chain = atob(response.certificate_chain);
|
||||
response.private_key = atob(response.private_key);
|
||||
|
||||
const dnsStatus = await apiClient.getGlobalStatus();
|
||||
if (dnsStatus) {
|
||||
dispatch(dnsStatusSuccess(dnsStatus));
|
||||
}
|
||||
|
||||
dispatch(setTlsConfigSuccess(response));
|
||||
dispatch(addSuccessToast('encryption_config_saved'));
|
||||
redirectToCurrentProtocol(response, httpPort);
|
||||
|
||||
@@ -29,6 +29,8 @@ class Table extends Component {
|
||||
Header: this.props.t('actions_table_header'),
|
||||
accessor: 'actions',
|
||||
maxWidth: 100,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
Cell: (value) => (
|
||||
<div className="logs__row logs__row--center">
|
||||
<button
|
||||
|
||||
@@ -36,6 +36,7 @@ class Table extends Component {
|
||||
Cell: this.renderCheckbox,
|
||||
width: 90,
|
||||
className: 'text-center',
|
||||
resizable: false,
|
||||
},
|
||||
{
|
||||
Header: <Trans>name_table_header</Trans>,
|
||||
@@ -77,12 +78,14 @@ class Table extends Component {
|
||||
},
|
||||
{
|
||||
Header: <Trans>actions_table_header</Trans>,
|
||||
accessor: 'url',
|
||||
accessor: 'actions',
|
||||
className: 'text-center',
|
||||
width: 100,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
Cell: (row) => {
|
||||
const { value } = row;
|
||||
const { original } = row;
|
||||
const { url } = original;
|
||||
const { t, toggleFilteringModal, handleDelete } = this.props;
|
||||
|
||||
return (
|
||||
@@ -93,7 +96,7 @@ class Table extends Component {
|
||||
title={t('edit_table_action')}
|
||||
onClick={() => toggleFilteringModal({
|
||||
type: MODAL_TYPE.EDIT_FILTERS,
|
||||
url: value,
|
||||
url,
|
||||
})
|
||||
}
|
||||
>
|
||||
@@ -104,7 +107,7 @@ class Table extends Component {
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-icon btn-outline-secondary btn-sm"
|
||||
onClick={() => handleDelete(value)}
|
||||
onClick={() => handleDelete(url)}
|
||||
title={t('delete_table_action')}
|
||||
>
|
||||
<svg className="icons">
|
||||
|
||||
@@ -43,7 +43,7 @@ const InfiniteTable = ({
|
||||
|
||||
useEffect(() => {
|
||||
listener();
|
||||
}, [items.length < QUERY_LOGS_PAGE_LIMIT]);
|
||||
}, [items.length < QUERY_LOGS_PAGE_LIMIT, isEntireLog]);
|
||||
|
||||
useEffect(() => {
|
||||
const THROTTLE_TIME = 100;
|
||||
@@ -66,15 +66,24 @@ const InfiniteTable = ({
|
||||
|
||||
const isNothingFound = items.length === 0 && !processingGetLogs;
|
||||
|
||||
return <div className='logs__table' role='grid'>
|
||||
{loading && <Loading />}
|
||||
<Header />
|
||||
{isNothingFound
|
||||
? <label className="logs__no-data">{t('nothing_found')}</label>
|
||||
: <>{items.map(renderRow)}
|
||||
{!isEntireLog && <div ref={loader} className="logs__loading text-center">{t('loading_table_status')}</div>}
|
||||
</>}
|
||||
</div>;
|
||||
return (
|
||||
<div className="logs__table" role="grid">
|
||||
{loading && <Loading />}
|
||||
<Header />
|
||||
{isNothingFound ? (
|
||||
<label className="logs__no-data">{t('nothing_found')}</label>
|
||||
) : (
|
||||
<>
|
||||
{items.map(renderRow)}
|
||||
{!isEntireLog && (
|
||||
<div ref={loader} className="logs__loading text-center">
|
||||
{t('loading_table_status')}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
InfiniteTable.propTypes = {
|
||||
|
||||
@@ -338,10 +338,19 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.logs__row--icons {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.logs__table .logs__row {
|
||||
border-bottom: 2px solid var(--gray-216);
|
||||
}
|
||||
|
||||
.logs__tag {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* QUERY_STATUS_COLORS */
|
||||
.logs__row--blue {
|
||||
background-color: var(--blue);
|
||||
|
||||
@@ -152,6 +152,16 @@ const Logs = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!history.location.search) {
|
||||
(async () => {
|
||||
setIsLoading(true);
|
||||
await dispatch(setFilteredLogs());
|
||||
setIsLoading(false);
|
||||
})();
|
||||
}
|
||||
}, [history.location.search]);
|
||||
|
||||
const renderPage = () => <>
|
||||
<Filters
|
||||
filter={{
|
||||
|
||||
@@ -193,7 +193,7 @@ class ClientsTable extends Component {
|
||||
<div className="logs__row o-hidden">
|
||||
<span className="logs__text">
|
||||
{value.map((tag) => (
|
||||
<div key={tag} title={tag} className="small">
|
||||
<div key={tag} title={tag} className="logs__tag small">
|
||||
{tag}
|
||||
</div>
|
||||
))}
|
||||
@@ -225,6 +225,8 @@ class ClientsTable extends Component {
|
||||
Header: this.props.t('actions_table_header'),
|
||||
accessor: 'actions',
|
||||
maxWidth: 100,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
Cell: (row) => {
|
||||
const clientName = row.original.name;
|
||||
const {
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
validateMac,
|
||||
validateRequiredValue,
|
||||
validateIpv4InCidr,
|
||||
validateIpGateway,
|
||||
} from '../../../../helpers/validators';
|
||||
import { FORM_NAME } from '../../../../helpers/constants';
|
||||
import { toggleLeaseModal } from '../../../../actions';
|
||||
@@ -57,6 +58,7 @@ const Form = ({
|
||||
validateRequiredValue,
|
||||
validateIpv4,
|
||||
validateIpv4InCidr,
|
||||
validateIpGateway,
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -101,6 +103,7 @@ Form.propTypes = {
|
||||
ip: PropTypes.string.isRequired,
|
||||
hostname: PropTypes.string.isRequired,
|
||||
cidr: PropTypes.string.isRequired,
|
||||
gatewayIp: PropTypes.string,
|
||||
}),
|
||||
pristine: PropTypes.bool.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
|
||||
@@ -13,6 +13,7 @@ const Modal = ({
|
||||
cidr,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
gatewayIp,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
@@ -42,6 +43,7 @@ const Modal = ({
|
||||
cidr,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
gatewayIp,
|
||||
}}
|
||||
onSubmit={handleSubmit}
|
||||
processingAdding={processingAdding}
|
||||
@@ -61,6 +63,7 @@ Modal.propTypes = {
|
||||
cidr: PropTypes.string.isRequired,
|
||||
rangeStart: PropTypes.string,
|
||||
rangeEnd: PropTypes.string,
|
||||
gatewayIp: PropTypes.string,
|
||||
};
|
||||
|
||||
export default withTranslation()(Modal);
|
||||
|
||||
@@ -24,6 +24,7 @@ const StaticLeases = ({
|
||||
cidr,
|
||||
rangeStart,
|
||||
rangeEnd,
|
||||
gatewayIp,
|
||||
}) => {
|
||||
const [t] = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
@@ -70,6 +71,8 @@ const StaticLeases = ({
|
||||
Header: <Trans>actions_table_header</Trans>,
|
||||
accessor: 'actions',
|
||||
maxWidth: 150,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
// eslint-disable-next-line react/display-name
|
||||
Cell: (row) => {
|
||||
const { ip, mac, hostname } = row.original;
|
||||
@@ -104,6 +107,7 @@ const StaticLeases = ({
|
||||
cidr={cidr}
|
||||
rangeStart={rangeStart}
|
||||
rangeEnd={rangeEnd}
|
||||
gatewayIp={gatewayIp}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -117,6 +121,7 @@ StaticLeases.propTypes = {
|
||||
cidr: PropTypes.string.isRequired,
|
||||
rangeStart: PropTypes.string,
|
||||
rangeEnd: PropTypes.string,
|
||||
gatewayIp: PropTypes.string,
|
||||
};
|
||||
|
||||
cellWrap.propTypes = {
|
||||
|
||||
@@ -278,6 +278,7 @@ const Dhcp = () => {
|
||||
cidr={cidr}
|
||||
rangeStart={dhcp?.values?.v4?.range_start}
|
||||
rangeEnd={dhcp?.values?.v4?.range_end}
|
||||
gatewayIp={dhcp?.values?.v4?.gateway_ip}
|
||||
/>
|
||||
<div className="btn-list mt-2">
|
||||
<button
|
||||
|
||||
@@ -25,7 +25,9 @@ class Encryption extends Component {
|
||||
|
||||
handleFormChange = debounce((values) => {
|
||||
const submitValues = this.getSubmitValues(values);
|
||||
this.props.validateTlsConfig(submitValues);
|
||||
if (submitValues.enabled) {
|
||||
this.props.validateTlsConfig(submitValues);
|
||||
}
|
||||
}, DEBOUNCE_TIMEOUT);
|
||||
|
||||
getInitialValues = (data) => {
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: transparent;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-icon--green {
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
"urlhaus-filter-online": {
|
||||
"name": "Online Malicious URL Blocklist",
|
||||
"categoryId": "security",
|
||||
"homepage": "https://gitlab.com/curben/urlhaus-filter",
|
||||
"source": "https://curben.gitlab.io/malware-filter/urlhaus-filter-agh-online.txt"
|
||||
"homepage": "https://gitlab.com/malware-filter/urlhaus-filter",
|
||||
"source": "https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-agh-online.txt"
|
||||
},
|
||||
"dandelion-sprouts-anti-malware-list": {
|
||||
"name": "Dandelion Sprout's Anti-Malware List",
|
||||
|
||||
@@ -693,8 +693,8 @@ export const replaceZeroWithEmptyString = (value) => (parseInt(value, 10) === 0
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getLogsUrlParams = (search, response_status) => `?${queryString.stringify({
|
||||
search,
|
||||
response_status,
|
||||
search: search || undefined,
|
||||
response_status: response_status || undefined,
|
||||
})}`;
|
||||
|
||||
export const processContent = (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import whotracksmeDb from './whotracksme.json';
|
||||
import whotracksmeWebsites from './whotracksme_web.json';
|
||||
import adguardDb from './adguard.json';
|
||||
import { REPOSITORY } from '../constants';
|
||||
|
||||
@@ -20,6 +21,22 @@ export const sources = {
|
||||
ADGUARD: 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets link to tracker page on whotracks.me.
|
||||
*
|
||||
* @param trackerId
|
||||
* @return {string}
|
||||
*/
|
||||
const getWhotracksmeUrl = (trackerId) => {
|
||||
const websiteId = whotracksmeWebsites.websites[trackerId];
|
||||
if (websiteId) {
|
||||
// Overrides links to websites.
|
||||
return `https://whotracks.me/websites/${websiteId}.html`;
|
||||
}
|
||||
|
||||
return `https://whotracks.me/trackers/${trackerId}.html`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the source metadata for the specified tracker
|
||||
* @param {TrackerData} trackerData tracker data
|
||||
@@ -33,7 +50,7 @@ export const getSourceData = (trackerData) => {
|
||||
if (trackerData.source === sources.WHOTRACKSME) {
|
||||
return {
|
||||
name: 'Whotracks.me',
|
||||
url: `https://whotracks.me/trackers/${trackerData.id}.html`,
|
||||
url: getWhotracksmeUrl(trackerData.id),
|
||||
};
|
||||
}
|
||||
if (trackerData.source === sources.ADGUARD) {
|
||||
|
||||
6
client/src/helpers/trackers/whotracksme_web.json
Normal file
6
client/src/helpers/trackers/whotracksme_web.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"timeUpdated": "2021-12-19T13:50:00.512Z",
|
||||
"websites": {
|
||||
"netflix": "netflix.com"
|
||||
}
|
||||
}
|
||||
@@ -339,3 +339,14 @@ export const validatePasswordLength = (value) => {
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param value {string}
|
||||
* @returns {Function}
|
||||
*/
|
||||
export const validateIpGateway = (value, allValues) => {
|
||||
if (value === allValues.gatewayIp) {
|
||||
return i18next.t('form_error_gateway_ip');
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm, formValueSelector } from 'redux-form';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
import i18n from 'i18next';
|
||||
|
||||
import Controls from './Controls';
|
||||
import AddressList from './AddressList';
|
||||
@@ -31,10 +32,10 @@ const renderInterfaces = (interfaces) => Object.values(interfaces)
|
||||
|
||||
if (option && ip_addresses?.length > 0) {
|
||||
const ip = getInterfaceIp(option);
|
||||
const isDown = flags?.includes('down');
|
||||
const isUp = flags?.includes('up');
|
||||
|
||||
return <option value={ip} key={name} disabled={isDown}>
|
||||
{name} - {ip} {isDown && `(${<Trans>down</Trans>})`}
|
||||
return <option value={ip} key={name} disabled={!isUp}>
|
||||
{name} - {ip} {!isUp && `(${i18n.t('down')})`}
|
||||
</option>;
|
||||
}
|
||||
|
||||
|
||||
55
go.mod
55
go.mod
@@ -3,64 +3,65 @@ module github.com/AdguardTeam/AdGuardHome
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/AdguardTeam/dnsproxy v0.41.4
|
||||
github.com/AdguardTeam/dnsproxy v0.43.1
|
||||
github.com/AdguardTeam/golibs v0.10.8
|
||||
github.com/AdguardTeam/urlfilter v0.15.2
|
||||
github.com/AdguardTeam/urlfilter v0.16.0
|
||||
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/dimfeld/httptreemux/v5 v5.4.0
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/google/go-cmp v0.5.7
|
||||
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/kardianos/service v1.2.0
|
||||
github.com/lucas-clemente/quic-go v0.25.0
|
||||
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
|
||||
github.com/mdlayher/netlink v1.5.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/insomniacslk/dhcp v0.0.0-20220405050111-12fbdcb11b41
|
||||
github.com/kardianos/service v1.2.1
|
||||
github.com/lucas-clemente/quic-go v0.27.1
|
||||
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118
|
||||
github.com/mdlayher/netlink v1.6.0
|
||||
// TODO(a.garipov): This package is deprecated; find a new one or use
|
||||
// our own code for that.
|
||||
github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b
|
||||
github.com/miekg/dns v1.1.45
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/miekg/dns v1.1.49
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ti-mo/netfilter v0.4.0
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
howett.net/plist v1.0.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.4.1 // indirect
|
||||
github.com/BurntSushi/toml v1.1.0 // 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/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // 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/marten-seemann/qtls-go1-18 v0.1.0-beta.1 // indirect
|
||||
github.com/mdlayher/socket v0.1.1 // indirect
|
||||
github.com/josharian/native v1.0.0 // indirect
|
||||
github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect
|
||||
github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect
|
||||
github.com/mdlayher/socket v0.2.3 // 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
|
||||
github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // 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
|
||||
golang.org/x/tools v0.1.11-0.20220426200323-dcaea06afc12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // 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
|
||||
)
|
||||
|
||||
161
go.sum
161
go.sum
@@ -7,20 +7,19 @@ 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.41.4 h1:zA8BJmWBkSL5kp4b8CblQRgIrLGzJ4IUGQ7tA1255Cw=
|
||||
github.com/AdguardTeam/dnsproxy v0.41.4/go.mod h1:GCdEbTw683vBqksJIccPSYzBg2yIFbRiDnXltyIinug=
|
||||
github.com/AdguardTeam/dnsproxy v0.43.1 h1:E777KfQAi+VurOoWEdGQ5iqjSOOAzzbTfLOEzj8heCs=
|
||||
github.com/AdguardTeam/dnsproxy v0.43.1/go.mod h1:JUGTm5dmlll47JltztsT0N//pVJjdg6zu0SNeUeaA7g=
|
||||
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.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
|
||||
github.com/AdguardTeam/golibs v0.10.6/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
|
||||
github.com/AdguardTeam/golibs v0.10.8 h1:diU9gP9qG1qeLbAkzIwfUerpHSqzR6zaBgzvRMR/m6Q=
|
||||
github.com/AdguardTeam/golibs v0.10.8/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.16.0 h1:IO29m+ZyQuuOnPLTzHuXj35V1DZOp1Dcryl576P2syg=
|
||||
github.com/AdguardTeam/urlfilter v0.16.0/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
|
||||
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/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/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=
|
||||
@@ -35,15 +34,14 @@ github.com/ameshkov/dnsstamps v1.0.1/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaE
|
||||
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
|
||||
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/beefsack/go-rate v0.0.0-20200827232406-6cde80facd47 h1:M57m0xQqZIhx7CEJgeLSvRFKEK1RjzRuIXiA3HfYU7g=
|
||||
github.com/beefsack/go-rate v0.0.0-20200827232406-6cde80facd47/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
|
||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 h1:0b2vaepXIfMsG++IsjHiI2p4bxALD1Y2nQKGMR5zDQM=
|
||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
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=
|
||||
@@ -52,15 +50,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/digineo/go-ipset/v2 v2.2.1 h1:k6skY+0fMqeUjjeWO/m5OuWPSZUAn7AucHMnQ1MX77g=
|
||||
github.com/digineo/go-ipset/v2 v2.2.1/go.mod h1:wBsNzJlZlABHUITkesrggFnZQtgW5wkqw1uo8Qxe0VU=
|
||||
github.com/dimfeld/httptreemux/v5 v5.4.0 h1:IiHYEjh+A7pYbhWyjmGnj5HZK6gpOOvyBXCJ+BE8/Gs=
|
||||
github.com/dimfeld/httptreemux/v5 v5.4.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
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=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
@@ -95,10 +95,10 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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/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-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
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=
|
||||
@@ -118,87 +118,67 @@ 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-20220405050111-12fbdcb11b41 h1:Yg3n3AI7GoHnWt7dyjsLPU+TEuZfPAg0OdiA3MJUV6I=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20220405050111-12fbdcb11b41/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
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=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
|
||||
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/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=
|
||||
github.com/kardianos/service v1.2.0 h1:bGuZ/epo3vrt8IPC7mnKQolqFeYJb7Cs8Rk4PSOBB/g=
|
||||
github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||
github.com/kardianos/service v1.2.1 h1:AYndMsehS+ywIS6RB9KOlcXzteWUzxgMgBymJD7+BYk=
|
||||
github.com/kardianos/service v1.2.1/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=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0=
|
||||
github.com/lucas-clemente/quic-go v0.25.0 h1:K+X9Gvd7JXsOHtU0N2icZ2Nw3rx82uBej3mP4CLgibc=
|
||||
github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg=
|
||||
github.com/lucas-clemente/quic-go v0.27.1 h1:sOw+4kFSVrdWOYmUjufQ9GBVPqZ+tu+jMtXxXNmRJyk=
|
||||
github.com/lucas-clemente/quic-go v0.27.1/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
|
||||
github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
|
||||
github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco=
|
||||
github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
||||
github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk=
|
||||
github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 h1:EnzzN9fPUkUck/1CuY1FlzBaIYMoiBsdwTNmNGkwUUM=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI=
|
||||
github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ=
|
||||
github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
|
||||
github.com/marten-seemann/qtls-go1-17 v0.1.1 h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc=
|
||||
github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.1 h1:qp7p7XXUFL7fpBvSS1sWD+uSqPvzNQK43DH+/qEkj0Y=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
||||
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/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/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
|
||||
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og=
|
||||
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.1.2-0.20201013204415-ded538f7f4be/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8=
|
||||
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/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/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=
|
||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
||||
github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU=
|
||||
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/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
||||
github.com/mdlayher/socket v0.2.3 h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM=
|
||||
github.com/mdlayher/socket v0.2.3/go.mod h1:bz12/FozYNH/VbvC3q7TRIK/Y6dH1kCKsXaUeXi/FmY=
|
||||
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=
|
||||
github.com/miekg/dns v1.1.44/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
|
||||
github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=
|
||||
github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
@@ -232,8 +212,6 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA=
|
||||
github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ=
|
||||
@@ -281,13 +259,12 @@ github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ
|
||||
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/uio v0.0.0-20220204230159-dac05f7d2cb4 h1:hl6sK6aFgTLISijk6xIzeqnPzQcsLqqvL6vEfTPinME=
|
||||
github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
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=
|
||||
@@ -301,8 +278,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -311,8 +290,9 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
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=
|
||||
@@ -324,6 +304,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -337,24 +318,19 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
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=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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-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/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -397,17 +373,9 @@ 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-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=
|
||||
@@ -416,17 +384,19 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
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/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
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=
|
||||
@@ -447,17 +417,17 @@ 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/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.11-0.20220426200323-dcaea06afc12 h1:pODAJF0uBqx6zFa1MYaiTobVo5FzCbnTVUXeO8o71fE=
|
||||
golang.org/x/tools v0.1.11-0.20220426200323-dcaea06afc12/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
@@ -508,9 +478,6 @@ 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=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
|
||||
67
internal/aghalg/nullbool.go
Normal file
67
internal/aghalg/nullbool.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package aghalg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// NullBool is a nullable boolean. Use these in JSON requests and responses
|
||||
// instead of pointers to bool.
|
||||
type NullBool uint8
|
||||
|
||||
// NullBool values
|
||||
const (
|
||||
NBNull NullBool = iota
|
||||
NBTrue
|
||||
NBFalse
|
||||
)
|
||||
|
||||
// String implements the fmt.Stringer interface for NullBool.
|
||||
func (nb NullBool) String() (s string) {
|
||||
switch nb {
|
||||
case NBNull:
|
||||
return "null"
|
||||
case NBTrue:
|
||||
return "true"
|
||||
case NBFalse:
|
||||
return "false"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("!invalid NullBool %d", uint8(nb))
|
||||
}
|
||||
|
||||
// BoolToNullBool converts a bool into a NullBool.
|
||||
func BoolToNullBool(cond bool) (nb NullBool) {
|
||||
if cond {
|
||||
return NBTrue
|
||||
}
|
||||
|
||||
return NBFalse
|
||||
}
|
||||
|
||||
// type check
|
||||
var _ json.Marshaler = NBNull
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface for NullBool.
|
||||
func (nb NullBool) MarshalJSON() (b []byte, err error) {
|
||||
return []byte(nb.String()), nil
|
||||
}
|
||||
|
||||
// type check
|
||||
var _ json.Unmarshaler = (*NullBool)(nil)
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for *NullBool.
|
||||
func (nb *NullBool) UnmarshalJSON(b []byte) (err error) {
|
||||
if len(b) == 0 || bytes.Equal(b, []byte("null")) {
|
||||
*nb = NBNull
|
||||
} else if bytes.Equal(b, []byte("true")) {
|
||||
*nb = NBTrue
|
||||
} else if bytes.Equal(b, []byte("false")) {
|
||||
*nb = NBFalse
|
||||
} else {
|
||||
return fmt.Errorf("unmarshalling json data into aghalg.NullBool: bad value %q", b)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
113
internal/aghalg/nullbool_test.go
Normal file
113
internal/aghalg/nullbool_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package aghalg_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNullBool_MarshalJSON(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
wantErrMsg string
|
||||
want []byte
|
||||
in aghalg.NullBool
|
||||
}{{
|
||||
name: "null",
|
||||
wantErrMsg: "",
|
||||
want: []byte("null"),
|
||||
in: aghalg.NBNull,
|
||||
}, {
|
||||
name: "true",
|
||||
wantErrMsg: "",
|
||||
want: []byte("true"),
|
||||
in: aghalg.NBTrue,
|
||||
}, {
|
||||
name: "false",
|
||||
wantErrMsg: "",
|
||||
want: []byte("false"),
|
||||
in: aghalg.NBFalse,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, err := tc.in.MarshalJSON()
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("json", func(t *testing.T) {
|
||||
in := &struct {
|
||||
A aghalg.NullBool
|
||||
}{
|
||||
A: aghalg.NBTrue,
|
||||
}
|
||||
|
||||
got, err := json.Marshal(in)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, []byte(`{"A":true}`), got)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNullBool_UnmarshalJSON(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
wantErrMsg string
|
||||
data []byte
|
||||
want aghalg.NullBool
|
||||
}{{
|
||||
name: "empty",
|
||||
wantErrMsg: "",
|
||||
data: []byte{},
|
||||
want: aghalg.NBNull,
|
||||
}, {
|
||||
name: "null",
|
||||
wantErrMsg: "",
|
||||
data: []byte("null"),
|
||||
want: aghalg.NBNull,
|
||||
}, {
|
||||
name: "true",
|
||||
wantErrMsg: "",
|
||||
data: []byte("true"),
|
||||
want: aghalg.NBTrue,
|
||||
}, {
|
||||
name: "false",
|
||||
wantErrMsg: "",
|
||||
data: []byte("false"),
|
||||
want: aghalg.NBFalse,
|
||||
}, {
|
||||
name: "invalid",
|
||||
wantErrMsg: `unmarshalling json data into aghalg.NullBool: bad value "invalid"`,
|
||||
data: []byte("invalid"),
|
||||
want: aghalg.NBNull,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var got aghalg.NullBool
|
||||
err := got.UnmarshalJSON(tc.data)
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
assert.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("json", func(t *testing.T) {
|
||||
want := aghalg.NBTrue
|
||||
var got struct {
|
||||
A aghalg.NullBool
|
||||
}
|
||||
|
||||
err := json.Unmarshal([]byte(`{"A":true}`), &got)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, want, got.A)
|
||||
})
|
||||
}
|
||||
@@ -2,13 +2,11 @@ package aghnet
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
)
|
||||
@@ -27,15 +25,8 @@ type ARPDB interface {
|
||||
}
|
||||
|
||||
// NewARPDB returns the ARPDB properly initialized for the OS.
|
||||
func NewARPDB() (arp ARPDB, err error) {
|
||||
arp = newARPDB()
|
||||
|
||||
err = arp.Refresh()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("arpdb initial refresh: %w", err)
|
||||
}
|
||||
|
||||
return arp, nil
|
||||
func NewARPDB() (arp ARPDB) {
|
||||
return newARPDB()
|
||||
}
|
||||
|
||||
// Empty ARPDB implementation
|
||||
@@ -123,50 +114,33 @@ func (ns *neighs) reset(with []Neighbor) {
|
||||
// of Neighbors.
|
||||
type parseNeighsFunc func(sc *bufio.Scanner, lenHint int) (ns []Neighbor)
|
||||
|
||||
// runCmdFunc is the function that runs some command and returns its output
|
||||
// wrapped to be a io.Reader.
|
||||
type runCmdFunc func() (r io.Reader, err error)
|
||||
|
||||
// cmdARPDB is the implementation of the ARPDB that uses command line to
|
||||
// retrieve data.
|
||||
type cmdARPDB struct {
|
||||
parse parseNeighsFunc
|
||||
runcmd runCmdFunc
|
||||
ns *neighs
|
||||
parse parseNeighsFunc
|
||||
ns *neighs
|
||||
cmd string
|
||||
args []string
|
||||
}
|
||||
|
||||
// type check
|
||||
var _ ARPDB = (*cmdARPDB)(nil)
|
||||
|
||||
// runCmd runs the cmd with it's args and returns the result wrapped to be an
|
||||
// io.Reader. The error is returned either if the exit code retured by command
|
||||
// not equals 0 or the execution itself failed.
|
||||
func runCmd(cmd string, args ...string) (r io.Reader, err error) {
|
||||
var code int
|
||||
var out string
|
||||
code, out, err = aghos.RunCommand(cmd, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if code != 0 {
|
||||
return nil, fmt.Errorf("unexpected exit code %d", code)
|
||||
}
|
||||
|
||||
return strings.NewReader(out), nil
|
||||
}
|
||||
|
||||
// Refresh implements the ARPDB interface for *cmdARPDB.
|
||||
func (arp *cmdARPDB) Refresh() (err error) {
|
||||
defer func() { err = errors.Annotate(err, "cmd arpdb: %w") }()
|
||||
|
||||
var r io.Reader
|
||||
r, err = arp.runcmd()
|
||||
code, out, err := aghosRunCommand(arp.cmd, arp.args...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("running command: %w", err)
|
||||
} else if code != 0 {
|
||||
return fmt.Errorf("running command: unexpected exit code %d", code)
|
||||
}
|
||||
|
||||
sc := bufio.NewScanner(r)
|
||||
sc := bufio.NewScanner(bytes.NewReader(out))
|
||||
ns := arp.parse(sc, arp.ns.len())
|
||||
if err = sc.Err(); err != nil {
|
||||
// TODO(e.burkov): This error seems unreachable. Investigate.
|
||||
return fmt.Errorf("scanning the output: %w", err)
|
||||
}
|
||||
|
||||
@@ -187,8 +161,7 @@ func (arp *cmdARPDB) Neighbors() (ns []Neighbor) {
|
||||
type arpdbs struct {
|
||||
// arps is the set of ARPDB implementations to range through.
|
||||
arps []ARPDB
|
||||
// last is the last succeeded ARPDB index.
|
||||
last int
|
||||
neighs
|
||||
}
|
||||
|
||||
// newARPDBs returns a properly initialized *arpdbs. It begins refreshing from
|
||||
@@ -196,7 +169,10 @@ type arpdbs struct {
|
||||
func newARPDBs(arps ...ARPDB) (arp *arpdbs) {
|
||||
return &arpdbs{
|
||||
arps: arps,
|
||||
last: 0,
|
||||
neighs: neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,20 +182,18 @@ var _ ARPDB = (*arpdbs)(nil)
|
||||
// Refresh implements the ARPDB interface for *arpdbs.
|
||||
func (arp *arpdbs) Refresh() (err error) {
|
||||
var errs []error
|
||||
l := len(arp.arps)
|
||||
// Start from the last succeeded implementation.
|
||||
for i := 0; i < l; i++ {
|
||||
cur := (arp.last + i) % l
|
||||
err = arp.arps[cur].Refresh()
|
||||
if err == nil {
|
||||
// The succeeded implementation found so update the last succeeded
|
||||
// index.
|
||||
arp.last = cur
|
||||
|
||||
return nil
|
||||
for _, a := range arp.arps {
|
||||
err = a.Refresh()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
errs = append(errs, err)
|
||||
arp.reset(a.Neighbors())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
@@ -230,10 +204,8 @@ func (arp *arpdbs) Refresh() (err error) {
|
||||
}
|
||||
|
||||
// Neighbors implements the ARPDB interface for *arpdbs.
|
||||
//
|
||||
// TODO(e.burkov): Think of a way to avoid cloning the slice twice.
|
||||
func (arp *arpdbs) Neighbors() (ns []Neighbor) {
|
||||
if l := len(arp.arps); l > 0 && arp.last < l {
|
||||
return arp.arps[arp.last].Neighbors()
|
||||
}
|
||||
|
||||
return nil
|
||||
return arp.clone()
|
||||
}
|
||||
|
||||
@@ -13,18 +13,24 @@ import (
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
)
|
||||
|
||||
func newARPDB() *cmdARPDB {
|
||||
func newARPDB() (arp *cmdARPDB) {
|
||||
return &cmdARPDB{
|
||||
parse: parseArpA,
|
||||
runcmd: rcArpA,
|
||||
parse: parseArpA,
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
cmd: "arp",
|
||||
// Use -n flag to avoid resolving the hostnames of the neighbors. By
|
||||
// default ARP attempts to resolve the hostnames via DNS. See man 8
|
||||
// arp.
|
||||
//
|
||||
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
|
||||
args: []string{"-a", "-n"},
|
||||
}
|
||||
}
|
||||
|
||||
// parseArpA parses the output of the "arp -a" command on macOS and FreeBSD.
|
||||
// parseArpA parses the output of the "arp -a -n" command on macOS and FreeBSD.
|
||||
// The expected input format:
|
||||
//
|
||||
// host.name (192.168.0.1) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet]
|
||||
|
||||
@@ -8,8 +8,12 @@ import (
|
||||
)
|
||||
|
||||
const arpAOutput = `
|
||||
invalid.mac (1.2.3.4) at 12:34:56:78:910 on el0 ifscope [ethernet]
|
||||
invalid.ip (1.2.3.4.5) at ab:cd:ef:ab:cd:12 on ek0 ifscope [ethernet]
|
||||
invalid.fmt 1 at 12:cd:ef:ab:cd:ef on er0 ifscope [ethernet]
|
||||
hostname.one (192.168.1.2) at ab:cd:ef:ab:cd:ef on en0 ifscope [ethernet]
|
||||
hostname.two (::ffff:ffff) at ef:cd:ab:ef:cd:ab on em0 expires in 1198 seconds [ethernet]
|
||||
? (::1234) at aa:bb:cc:dd:ee:ff on ej0 expires in 1918 seconds [ethernet]
|
||||
`
|
||||
|
||||
var wantNeighs = []Neighbor{{
|
||||
@@ -20,4 +24,8 @@ var wantNeighs = []Neighbor{{
|
||||
Name: "hostname.two",
|
||||
IP: net.ParseIP("::ffff:ffff"),
|
||||
MAC: net.HardwareAddr{0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB},
|
||||
}, {
|
||||
Name: "",
|
||||
IP: net.ParseIP("::1234"),
|
||||
MAC: net.HardwareAddr{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,6 @@ package aghnet
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -34,11 +33,30 @@ func newARPDB() (arp *arpdbs) {
|
||||
|
||||
return newARPDBs(
|
||||
// Try /proc/net/arp first.
|
||||
&fsysARPDB{ns: ns, fsys: aghos.RootDirFS(), filename: "proc/net/arp"},
|
||||
// Try "arp -a" then.
|
||||
&cmdARPDB{parse: parseF, runcmd: rcArpA, ns: ns},
|
||||
// Try "ip neigh" finally.
|
||||
&cmdARPDB{parse: parseIPNeigh, runcmd: rcIPNeigh, ns: ns},
|
||||
&fsysARPDB{
|
||||
ns: ns,
|
||||
fsys: rootDirFS,
|
||||
filename: "proc/net/arp",
|
||||
},
|
||||
// Then, try "arp -a -n".
|
||||
&cmdARPDB{
|
||||
parse: parseF,
|
||||
ns: ns,
|
||||
cmd: "arp",
|
||||
// Use -n flag to avoid resolving the hostnames of the neighbors.
|
||||
// By default ARP attempts to resolve the hostnames via DNS. See
|
||||
// man 8 arp.
|
||||
//
|
||||
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
|
||||
args: []string{"-a", "-n"},
|
||||
},
|
||||
// Finally, try "ip neigh".
|
||||
&cmdARPDB{
|
||||
parse: parseIPNeigh,
|
||||
ns: ns,
|
||||
cmd: "ip",
|
||||
args: []string{"neigh"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -96,11 +114,11 @@ func (arp *fsysARPDB) Neighbors() (ns []Neighbor) {
|
||||
return arp.ns.clone()
|
||||
}
|
||||
|
||||
// parseArpAWrt parses the output of the "arp -a" command on OpenWrt. The
|
||||
// parseArpAWrt parses the output of the "arp -a -n" command on OpenWrt. The
|
||||
// expected input format:
|
||||
//
|
||||
// IP address HW type Flags HW address Mask Device
|
||||
// 192.168.11.98 0x1 0x2 5a:92:df:a9:7e:28 * wan
|
||||
// IP address HW type Flags HW address Mask Device
|
||||
// 192.168.11.98 0x1 0x2 5a:92:df:a9:7e:28 * wan
|
||||
//
|
||||
func parseArpAWrt(sc *bufio.Scanner, lenHint int) (ns []Neighbor) {
|
||||
if !sc.Scan() {
|
||||
@@ -140,8 +158,8 @@ func parseArpAWrt(sc *bufio.Scanner, lenHint int) (ns []Neighbor) {
|
||||
return ns
|
||||
}
|
||||
|
||||
// parseArpA parses the output of the "arp -a" command on Linux. The expected
|
||||
// input format:
|
||||
// parseArpA parses the output of the "arp -a -n" command on Linux. The
|
||||
// expected input format:
|
||||
//
|
||||
// hostname (192.168.1.1) at ab:cd:ef:ab:cd:ef [ether] on enp0s3
|
||||
//
|
||||
@@ -187,11 +205,6 @@ func parseArpA(sc *bufio.Scanner, lenHint int) (ns []Neighbor) {
|
||||
return ns
|
||||
}
|
||||
|
||||
// rcIPNeigh runs "ip neigh".
|
||||
func rcIPNeigh() (r io.Reader, err error) {
|
||||
return runCmd("ip", "neigh")
|
||||
}
|
||||
|
||||
// parseIPNeigh parses the output of the "ip neigh" command on Linux. The
|
||||
// expected input format:
|
||||
//
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -16,14 +15,21 @@ import (
|
||||
|
||||
const arpAOutputWrt = `
|
||||
IP address HW type Flags HW address Mask Device
|
||||
1.2.3.4.5 0x1 0x2 aa:bb:cc:dd:ee:ff * wan
|
||||
1.2.3.4 0x1 0x2 12:34:56:78:910 * wan
|
||||
192.168.1.2 0x1 0x2 ab:cd:ef:ab:cd:ef * wan
|
||||
::ffff:ffff 0x1 0x2 ef:cd:ab:ef:cd:ab * wan`
|
||||
|
||||
const arpAOutput = `
|
||||
invalid.mac (1.2.3.4) at 12:34:56:78:910 on el0 ifscope [ethernet]
|
||||
invalid.ip (1.2.3.4.5) at ab:cd:ef:ab:cd:12 on ek0 ifscope [ethernet]
|
||||
invalid.fmt 1 at 12:cd:ef:ab:cd:ef on er0 ifscope [ethernet]
|
||||
? (192.168.1.2) at ab:cd:ef:ab:cd:ef on en0 ifscope [ethernet]
|
||||
? (::ffff:ffff) at ef:cd:ab:ef:cd:ab on em0 expires in 100 seconds [ethernet]`
|
||||
|
||||
const ipNeighOutput = `
|
||||
1.2.3.4.5 dev enp0s3 lladdr aa:bb:cc:dd:ee:ff DELAY
|
||||
1.2.3.4 dev enp0s3 lladdr 12:34:56:78:910 DELAY
|
||||
192.168.1.2 dev enp0s3 lladdr ab:cd:ef:ab:cd:ef DELAY
|
||||
::ffff:ffff dev enp0s3 lladdr ef:cd:ab:ef:cd:ab router STALE`
|
||||
|
||||
@@ -36,6 +42,8 @@ var wantNeighs = []Neighbor{{
|
||||
}}
|
||||
|
||||
func TestFSysARPDB(t *testing.T) {
|
||||
require.NoError(t, fstest.TestFS(testdata, "proc_net_arp"))
|
||||
|
||||
a := &fsysARPDB{
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
@@ -52,33 +60,43 @@ func TestFSysARPDB(t *testing.T) {
|
||||
assert.Equal(t, wantNeighs, ns)
|
||||
}
|
||||
|
||||
func TestCmdARPDB_arpawrt(t *testing.T) {
|
||||
a := &cmdARPDB{
|
||||
parse: parseArpAWrt,
|
||||
runcmd: func() (r io.Reader, err error) { return strings.NewReader(arpAOutputWrt), nil },
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
func TestCmdARPDB_linux(t *testing.T) {
|
||||
sh := mapShell{
|
||||
"arp -a": {err: nil, out: arpAOutputWrt, code: 0},
|
||||
"ip neigh": {err: nil, out: ipNeighOutput, code: 0},
|
||||
}
|
||||
substShell(t, sh.RunCmd)
|
||||
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
t.Run("wrt", func(t *testing.T) {
|
||||
a := &cmdARPDB{
|
||||
parse: parseArpAWrt,
|
||||
cmd: "arp",
|
||||
args: []string{"-a"},
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
}
|
||||
|
||||
assert.Equal(t, wantNeighs, a.Neighbors())
|
||||
}
|
||||
|
||||
func TestCmdARPDB_ipneigh(t *testing.T) {
|
||||
a := &cmdARPDB{
|
||||
parse: parseIPNeigh,
|
||||
runcmd: func() (r io.Reader, err error) { return strings.NewReader(ipNeighOutput), nil },
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
}
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, wantNeighs, a.Neighbors())
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, wantNeighs, a.Neighbors())
|
||||
})
|
||||
|
||||
t.Run("ip_neigh", func(t *testing.T) {
|
||||
a := &cmdARPDB{
|
||||
parse: parseIPNeigh,
|
||||
cmd: "ip",
|
||||
args: []string{"neigh"},
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
}
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, wantNeighs, a.Neighbors())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,19 +12,25 @@ import (
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
func newARPDB() *cmdARPDB {
|
||||
func newARPDB() (arp *cmdARPDB) {
|
||||
return &cmdARPDB{
|
||||
runcmd: rcArpA,
|
||||
parse: parseArpA,
|
||||
parse: parseArpA,
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
cmd: "arp",
|
||||
// Use -n flag to avoid resolving the hostnames of the neighbors. By
|
||||
// default ARP attempts to resolve the hostnames via DNS. See man 8
|
||||
// arp.
|
||||
//
|
||||
// See also https://github.com/AdguardTeam/AdGuardHome/issues/3157.
|
||||
args: []string{"-a", "-n"},
|
||||
}
|
||||
}
|
||||
|
||||
// parseArpA parses the output of the "arp -a" command on OpenBSD. The expected
|
||||
// input format:
|
||||
// parseArpA parses the output of the "arp -a -n" command on OpenBSD. The
|
||||
// expected input format:
|
||||
//
|
||||
// Host Ethernet Address Netif Expire Flags
|
||||
// 192.168.1.1 ab:cd:ef:ab:cd:ef em0 19m59s
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
|
||||
const arpAOutput = `
|
||||
Host Ethernet Address Netif Expire Flags
|
||||
1.2.3.4.5 aa:bb:cc:dd:ee:ff em0 permanent
|
||||
1.2.3.4 12:34:56:78:910 em0 permanent
|
||||
192.168.1.2 ab:cd:ef:ab:cd:ef em0 19m56s
|
||||
::ffff:ffff ef:cd:ab:ef:cd:ab em0 permanent l
|
||||
`
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
@@ -13,6 +11,13 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewARPDB(t *testing.T) {
|
||||
var a ARPDB
|
||||
require.NotPanics(t, func() { a = NewARPDB() })
|
||||
|
||||
assert.NotNil(t, a)
|
||||
}
|
||||
|
||||
// TestARPDB is the mock implementation of ARPDB to use in tests.
|
||||
type TestARPDB struct {
|
||||
OnRefresh func() (err error)
|
||||
@@ -125,11 +130,11 @@ func TestARPDBS(t *testing.T) {
|
||||
assert.Equal(t, 1, succRefrCount)
|
||||
assert.NotEmpty(t, a.Neighbors())
|
||||
|
||||
// Only the last succeeded ARPDB should be used.
|
||||
// Unstable ARPDB should refresh successfully again.
|
||||
err = a.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 2, succRefrCount)
|
||||
assert.Equal(t, 1, succRefrCount)
|
||||
assert.NotEmpty(t, a.Neighbors())
|
||||
})
|
||||
|
||||
@@ -143,6 +148,7 @@ func TestARPDBS(t *testing.T) {
|
||||
|
||||
func TestCmdARPDB_arpa(t *testing.T) {
|
||||
a := &cmdARPDB{
|
||||
cmd: "cmd",
|
||||
parse: parseArpA,
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
@@ -151,7 +157,8 @@ func TestCmdARPDB_arpa(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("arp_a", func(t *testing.T) {
|
||||
a.runcmd = func() (r io.Reader, err error) { return strings.NewReader(arpAOutput), nil }
|
||||
sh := theOnlyCmd("cmd", 0, arpAOutput, nil)
|
||||
substShell(t, sh.RunCmd)
|
||||
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
@@ -160,9 +167,50 @@ func TestCmdARPDB_arpa(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("runcmd_error", func(t *testing.T) {
|
||||
a.runcmd = func() (r io.Reader, err error) { return nil, errors.Error("can't run") }
|
||||
sh := theOnlyCmd("cmd", 0, "", errors.Error("can't run"))
|
||||
substShell(t, sh.RunCmd)
|
||||
|
||||
err := a.Refresh()
|
||||
testutil.AssertErrorMsg(t, "cmd arpdb: running command: can't run", err)
|
||||
})
|
||||
|
||||
t.Run("bad_code", func(t *testing.T) {
|
||||
sh := theOnlyCmd("cmd", 1, "", nil)
|
||||
substShell(t, sh.RunCmd)
|
||||
|
||||
err := a.Refresh()
|
||||
testutil.AssertErrorMsg(t, "cmd arpdb: running command: unexpected exit code 1", err)
|
||||
})
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
sh := theOnlyCmd("cmd", 0, "", nil)
|
||||
substShell(t, sh.RunCmd)
|
||||
|
||||
err := a.Refresh()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Empty(t, a.Neighbors())
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmptyARPDB(t *testing.T) {
|
||||
a := EmptyARPDB{}
|
||||
|
||||
t.Run("refresh", func(t *testing.T) {
|
||||
var err error
|
||||
require.NotPanics(t, func() {
|
||||
err = a.Refresh()
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("neighbors", func(t *testing.T) {
|
||||
var ns []Neighbor
|
||||
require.NotPanics(t, func() {
|
||||
ns = a.Neighbors()
|
||||
})
|
||||
|
||||
assert.Empty(t, ns)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// rcArpA runs "arp -a".
|
||||
func rcArpA() (r io.Reader, err error) {
|
||||
return runCmd("arp", "-a")
|
||||
}
|
||||
@@ -5,28 +5,23 @@ package aghnet
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func newARPDB() *cmdARPDB {
|
||||
func newARPDB() (arp *cmdARPDB) {
|
||||
return &cmdARPDB{
|
||||
runcmd: rcArpA,
|
||||
parse: parseArpA,
|
||||
ns: &neighs{
|
||||
mu: &sync.RWMutex{},
|
||||
ns: make([]Neighbor, 0),
|
||||
},
|
||||
parse: parseArpA,
|
||||
cmd: "arp",
|
||||
args: []string{"/a"},
|
||||
}
|
||||
}
|
||||
|
||||
// rcArpA runs "arp /a".
|
||||
func rcArpA() (r io.Reader, err error) {
|
||||
return runCmd("arp", "/a")
|
||||
}
|
||||
|
||||
// parseArpA parses the output of the "arp /a" command on Windows. The expected
|
||||
// input format (the first line is empty):
|
||||
//
|
||||
|
||||
@@ -156,7 +156,7 @@ func tryConn4(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, n
|
||||
b := make([]byte, 1500)
|
||||
n, _, err := c.ReadFrom(b)
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
if errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
log.Debug("dhcpv4: didn't receive dhcp response")
|
||||
|
||||
return false, false, nil
|
||||
@@ -176,20 +176,21 @@ func tryConn4(req *dhcpv4.DHCPv4, c net.PacketConn, iface *net.Interface) (ok, n
|
||||
|
||||
log.Debug("dhcpv4: received message from server: %s", response.Summary())
|
||||
|
||||
if !(response.OpCode == dhcpv4.OpcodeBootReply &&
|
||||
response.HWType == iana.HWTypeEthernet &&
|
||||
bytes.Equal(response.ClientHWAddr, iface.HardwareAddr) &&
|
||||
bytes.Equal(response.TransactionID[:], req.TransactionID[:]) &&
|
||||
response.Options.Has(dhcpv4.OptionDHCPMessageType)) {
|
||||
|
||||
log.Debug("dhcpv4: received message from server doesn't match our request")
|
||||
switch {
|
||||
case
|
||||
response.OpCode != dhcpv4.OpcodeBootReply,
|
||||
response.HWType != iana.HWTypeEthernet,
|
||||
!bytes.Equal(response.ClientHWAddr, iface.HardwareAddr),
|
||||
response.TransactionID != req.TransactionID,
|
||||
!response.Options.Has(dhcpv4.OptionDHCPMessageType):
|
||||
log.Debug("dhcpv4: received response doesn't match the request")
|
||||
|
||||
return false, true, nil
|
||||
default:
|
||||
log.Tracef("dhcpv4: the packet is from an active dhcp server")
|
||||
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
log.Tracef("dhcpv4: the packet is from an active dhcp server")
|
||||
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
// checkOtherDHCPv6 sends a DHCP request to the specified network interface, and
|
||||
@@ -275,7 +276,7 @@ func tryConn6(req *dhcpv6.Message, c net.PacketConn) (ok, next bool, err error)
|
||||
|
||||
n, _, err := c.ReadFrom(b)
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
if errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
log.Debug("dhcpv6: didn't receive dhcp response")
|
||||
|
||||
return false, false, nil
|
||||
@@ -318,15 +319,3 @@ func tryConn6(req *dhcpv6.Message, c net.PacketConn) (ok, next bool, err error)
|
||||
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
// isTimeout returns true if err is an operation timeout error from net package.
|
||||
//
|
||||
// TODO(e.burkov): Consider moving into netutil.
|
||||
func isTimeout(err error) (ok bool) {
|
||||
var operr *net.OpError
|
||||
if errors.As(err, &operr) {
|
||||
return operr.Timeout()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const (
|
||||
ipv6HostnameMaxLen = len("ff80-f076-0000-0000-0000-0000-0000-0010")
|
||||
)
|
||||
|
||||
// generateIPv4Hostname generates the hostname for specific IP version.
|
||||
// generateIPv4Hostname generates the hostname by IP address version 4.
|
||||
func generateIPv4Hostname(ipv4 net.IP) (hostname string) {
|
||||
hnData := make([]byte, 0, ipv4HostnameMaxLen)
|
||||
for i, part := range ipv4 {
|
||||
@@ -24,7 +24,7 @@ func generateIPv4Hostname(ipv4 net.IP) (hostname string) {
|
||||
return string(hnData)
|
||||
}
|
||||
|
||||
// generateIPv6Hostname generates the hostname for specific IP version.
|
||||
// generateIPv6Hostname generates the hostname by IP address version 6.
|
||||
func generateIPv6Hostname(ipv6 net.IP) (hostname string) {
|
||||
hnData := make([]byte, 0, ipv6HostnameMaxLen)
|
||||
for i, partsNum := 0, net.IPv6len/2; i < partsNum; i++ {
|
||||
@@ -51,12 +51,11 @@ func generateIPv6Hostname(ipv6 net.IP) (hostname string) {
|
||||
//
|
||||
// ff80-f076-0000-0000-0000-0000-0000-0010
|
||||
//
|
||||
// ip must be either an IPv4 or an IPv6.
|
||||
func GenerateHostname(ip net.IP) (hostname string) {
|
||||
if ipv4 := ip.To4(); ipv4 != nil {
|
||||
return generateIPv4Hostname(ipv4)
|
||||
} else if ipv6 := ip.To16(); ipv6 != nil {
|
||||
return generateIPv6Hostname(ipv6)
|
||||
}
|
||||
|
||||
return ""
|
||||
return generateIPv6Hostname(ip)
|
||||
}
|
||||
|
||||
@@ -8,41 +8,57 @@ import (
|
||||
)
|
||||
|
||||
func TestGenerateHostName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
want string
|
||||
ip net.IP
|
||||
}{{
|
||||
name: "good_ipv4",
|
||||
want: "127-0-0-1",
|
||||
ip: net.IP{127, 0, 0, 1},
|
||||
}, {
|
||||
name: "bad_ipv4",
|
||||
want: "",
|
||||
ip: net.IP{127, 0, 0, 1, 0},
|
||||
}, {
|
||||
name: "good_ipv6",
|
||||
want: "fe00-0000-0000-0000-0000-0000-0000-0001",
|
||||
ip: net.ParseIP("fe00::1"),
|
||||
}, {
|
||||
name: "bad_ipv6",
|
||||
want: "",
|
||||
ip: net.IP{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff,
|
||||
},
|
||||
}, {
|
||||
name: "nil",
|
||||
want: "",
|
||||
ip: nil,
|
||||
}}
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
want string
|
||||
ip net.IP
|
||||
}{{
|
||||
name: "good_ipv4",
|
||||
want: "127-0-0-1",
|
||||
ip: net.IP{127, 0, 0, 1},
|
||||
}, {
|
||||
name: "good_ipv6",
|
||||
want: "fe00-0000-0000-0000-0000-0000-0000-0001",
|
||||
ip: net.ParseIP("fe00::1"),
|
||||
}, {
|
||||
name: "4to6",
|
||||
want: "1-2-3-4",
|
||||
ip: net.ParseIP("::ffff:1.2.3.4"),
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
hostname := GenerateHostname(tc.ip)
|
||||
assert.Equal(t, tc.want, hostname)
|
||||
})
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
hostname := GenerateHostname(tc.ip)
|
||||
assert.Equal(t, tc.want, hostname)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ip net.IP
|
||||
}{{
|
||||
name: "bad_ipv4",
|
||||
ip: net.IP{127, 0, 0, 1, 0},
|
||||
}, {
|
||||
name: "bad_ipv6",
|
||||
ip: net.IP{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff,
|
||||
},
|
||||
}, {
|
||||
name: "nil",
|
||||
ip: nil,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Panics(t, func() { GenerateHostname(tc.ip) })
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ type requestMatcher struct {
|
||||
//
|
||||
// It's safe for concurrent use.
|
||||
func (rm *requestMatcher) MatchRequest(
|
||||
req urlfilter.DNSRequest,
|
||||
req *urlfilter.DNSRequest,
|
||||
) (res *urlfilter.DNSResult, ok bool) {
|
||||
switch req.DNSType {
|
||||
case dns.TypeA, dns.TypeAAAA, dns.TypePTR:
|
||||
@@ -198,7 +198,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 *stringutil.Set.
|
||||
// map's values are guaranteed to be of type of *HostsRecord.
|
||||
func (hc *HostsContainer) Upd() (updates <-chan *netutil.IPMap) {
|
||||
return hc.updates
|
||||
}
|
||||
@@ -290,7 +290,7 @@ func (hp *hostsParser) parseFile(r io.Reader) (patterns []string, cont bool, err
|
||||
continue
|
||||
}
|
||||
|
||||
hp.addPairs(ip, hosts)
|
||||
hp.addRecord(ip, hosts)
|
||||
}
|
||||
|
||||
return nil, true, s.Err()
|
||||
@@ -335,41 +335,68 @@ func (hp *hostsParser) parseLine(line string) (ip net.IP, hosts []string) {
|
||||
return ip, hosts
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// HostsRecord represents a single hosts file record.
|
||||
type HostsRecord struct {
|
||||
Aliases *stringutil.Set
|
||||
Canonical string
|
||||
}
|
||||
|
||||
// Equal returns true if all fields of rec are equal to field in other or they
|
||||
// both are nil.
|
||||
func (rec *HostsRecord) Equal(other *HostsRecord) (ok bool) {
|
||||
if rec == nil {
|
||||
return other == nil
|
||||
}
|
||||
|
||||
return rec.Canonical == other.Canonical && rec.Aliases.Equal(other.Aliases)
|
||||
}
|
||||
|
||||
// addRecord puts the record for the IP address to the rules builder if needed.
|
||||
// The first host is considered to be the canonical name for the IP address.
|
||||
// hosts must have at least one name.
|
||||
func (hp *hostsParser) addRecord(ip net.IP, hosts []string) {
|
||||
line := strings.Join(append([]string{ip.String()}, hosts...), " ")
|
||||
|
||||
var rec *HostsRecord
|
||||
v, ok := hp.table.Get(ip)
|
||||
if !ok {
|
||||
// This ip is added at the first time.
|
||||
v = stringutil.NewSet()
|
||||
hp.table.Set(ip, v)
|
||||
rec = &HostsRecord{
|
||||
Aliases: stringutil.NewSet(),
|
||||
}
|
||||
|
||||
rec.Canonical, hosts = hosts[0], hosts[1:]
|
||||
hp.addRules(ip, rec.Canonical, line)
|
||||
hp.table.Set(ip, rec)
|
||||
} else {
|
||||
rec, ok = v.(*HostsRecord)
|
||||
if !ok {
|
||||
log.Error("%s: adding pairs: unexpected type %T", hostsContainerPref, v)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var set *stringutil.Set
|
||||
set, ok = v.(*stringutil.Set)
|
||||
if !ok {
|
||||
log.Debug("%s: adding pairs: unexpected value type %T", hostsContainerPref, v)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
processed := strings.Join(append([]string{ip.String()}, hosts...), " ")
|
||||
for _, h := range hosts {
|
||||
if set.Has(h) {
|
||||
for _, host := range hosts {
|
||||
if rec.Canonical == host || rec.Aliases.Has(host) {
|
||||
continue
|
||||
}
|
||||
|
||||
set.Add(h)
|
||||
rec.Aliases.Add(host)
|
||||
|
||||
rule, rulePtr := hp.writeRules(h, ip)
|
||||
hp.translations[rule], hp.translations[rulePtr] = processed, processed
|
||||
|
||||
log.Debug("%s: added ip-host pair %q-%q", hostsContainerPref, ip, h)
|
||||
hp.addRules(ip, host, line)
|
||||
}
|
||||
}
|
||||
|
||||
// writeRules writes the actual rule for the qtype and the PTR for the
|
||||
// host-ip pair into internal builders.
|
||||
// addRules adds rules and rule translations for the line.
|
||||
func (hp *hostsParser) addRules(ip net.IP, host, line string) {
|
||||
rule, rulePtr := hp.writeRules(host, ip)
|
||||
hp.translations[rule], hp.translations[rulePtr] = line, line
|
||||
|
||||
log.Debug("%s: added ip-host pair %q-%q", hostsContainerPref, ip, host)
|
||||
}
|
||||
|
||||
// writeRules writes the actual rule for the qtype and the PTR for the host-ip
|
||||
// pair into internal builders.
|
||||
func (hp *hostsParser) writeRules(host string, ip net.IP) (rule, rulePtr string) {
|
||||
arpa, err := netutil.IPToReversedAddr(ip)
|
||||
if err != nil {
|
||||
@@ -417,6 +444,7 @@ func (hp *hostsParser) writeRules(host string, ip net.IP) (rule, rulePtr string)
|
||||
}
|
||||
|
||||
// equalSet returns true if the internal hosts table just parsed equals target.
|
||||
// target's values must be of type *HostsRecord.
|
||||
func (hp *hostsParser) equalSet(target *netutil.IPMap) (ok bool) {
|
||||
if target == nil {
|
||||
// hp.table shouldn't appear nil since it's initialized on each refresh.
|
||||
@@ -427,22 +455,35 @@ func (hp *hostsParser) equalSet(target *netutil.IPMap) (ok bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
hp.table.Range(func(ip net.IP, b interface{}) (cont bool) {
|
||||
// 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.
|
||||
if a, hasIP := target.Get(ip); !hasIP {
|
||||
ok = true
|
||||
} else if hosts, aok := a.(*stringutil.Set); aok {
|
||||
ok = !hosts.Equal(b.(*stringutil.Set))
|
||||
hp.table.Range(func(ip net.IP, recVal interface{}) (cont bool) {
|
||||
var targetVal interface{}
|
||||
targetVal, ok = target.Get(ip)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Continue only if maps has no discrepancies.
|
||||
return !ok
|
||||
var rec *HostsRecord
|
||||
rec, ok = recVal.(*HostsRecord)
|
||||
if !ok {
|
||||
log.Error("%s: comparing: unexpected type %T", hostsContainerPref, recVal)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var targetRec *HostsRecord
|
||||
targetRec, ok = targetVal.(*HostsRecord)
|
||||
if !ok {
|
||||
log.Error("%s: comparing: target: unexpected type %T", hostsContainerPref, targetVal)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
ok = rec.Equal(targetRec)
|
||||
|
||||
return ok
|
||||
})
|
||||
|
||||
// Return true if every value from the IP map has no discrepancies with the
|
||||
// appropriate one from the target.
|
||||
return !ok
|
||||
return ok
|
||||
}
|
||||
|
||||
// sendUpd tries to send the parsed data to the ch.
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
"github.com/AdguardTeam/golibs/stringutil"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/AdguardTeam/urlfilter"
|
||||
@@ -159,31 +160,47 @@ func TestHostsContainer_refresh(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
testutil.CleanupAndRequireSuccess(t, hc.Close)
|
||||
|
||||
checkRefresh := func(t *testing.T, wantHosts *stringutil.Set) {
|
||||
upd, ok := <-hc.Upd()
|
||||
require.True(t, ok)
|
||||
require.NotNil(t, upd)
|
||||
checkRefresh := func(t *testing.T, want *HostsRecord) {
|
||||
t.Helper()
|
||||
|
||||
var ok bool
|
||||
var upd *netutil.IPMap
|
||||
select {
|
||||
case upd, ok = <-hc.Upd():
|
||||
require.True(t, ok)
|
||||
require.NotNil(t, upd)
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("did not receive after 1s")
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, upd.Len())
|
||||
|
||||
v, ok := upd.Get(ip)
|
||||
require.True(t, ok)
|
||||
|
||||
var set *stringutil.Set
|
||||
set, ok = v.(*stringutil.Set)
|
||||
require.True(t, ok)
|
||||
require.IsType(t, (*HostsRecord)(nil), v)
|
||||
|
||||
assert.True(t, set.Equal(wantHosts))
|
||||
rec, _ := v.(*HostsRecord)
|
||||
require.NotNil(t, rec)
|
||||
|
||||
assert.Truef(t, rec.Equal(want), "%+v != %+v", rec, want)
|
||||
}
|
||||
|
||||
t.Run("initial_refresh", func(t *testing.T) {
|
||||
checkRefresh(t, stringutil.NewSet("hostname"))
|
||||
checkRefresh(t, &HostsRecord{
|
||||
Aliases: stringutil.NewSet(),
|
||||
Canonical: "hostname",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("second_refresh", func(t *testing.T) {
|
||||
testFS["dir/file2"] = &fstest.MapFile{Data: []byte(ipStr + ` alias` + nl)}
|
||||
eventsCh <- event{}
|
||||
checkRefresh(t, stringutil.NewSet("hostname", "alias"))
|
||||
|
||||
checkRefresh(t, &HostsRecord{
|
||||
Aliases: stringutil.NewSet("alias"),
|
||||
Canonical: "hostname",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("double_refresh", func(t *testing.T) {
|
||||
@@ -193,7 +210,7 @@ func TestHostsContainer_refresh(t *testing.T) {
|
||||
|
||||
// Require the changes are written.
|
||||
require.Eventually(t, func() bool {
|
||||
res, ok := hc.MatchRequest(urlfilter.DNSRequest{
|
||||
res, ok := hc.MatchRequest(&urlfilter.DNSRequest{
|
||||
Hostname: "hostname",
|
||||
DNSType: dns.TypeA,
|
||||
})
|
||||
@@ -207,7 +224,7 @@ func TestHostsContainer_refresh(t *testing.T) {
|
||||
|
||||
// Require the changes are written.
|
||||
require.Eventually(t, func() bool {
|
||||
res, ok := hc.MatchRequest(urlfilter.DNSRequest{
|
||||
res, ok := hc.MatchRequest(&urlfilter.DNSRequest{
|
||||
Hostname: "hostname",
|
||||
DNSType: dns.TypeA,
|
||||
})
|
||||
@@ -286,6 +303,8 @@ func TestHostsContainer_Translate(t *testing.T) {
|
||||
OnClose: func() (err error) { panic("not implemented") },
|
||||
}
|
||||
|
||||
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
|
||||
|
||||
hc, err := NewHostsContainer(0, testdata, &stubWatcher, "etc_hosts")
|
||||
require.NoError(t, err)
|
||||
testutil.CleanupAndRequireSuccess(t, hc.Close)
|
||||
@@ -358,11 +377,18 @@ func TestHostsContainer_Translate(t *testing.T) {
|
||||
func TestHostsContainer(t *testing.T) {
|
||||
const listID = 1234
|
||||
|
||||
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
|
||||
|
||||
testCases := []struct {
|
||||
want []*rules.DNSRewrite
|
||||
req *urlfilter.DNSRequest
|
||||
name string
|
||||
req urlfilter.DNSRequest
|
||||
want []*rules.DNSRewrite
|
||||
}{{
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "simplehost",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "simple",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.IPv4(1, 0, 0, 1),
|
||||
@@ -372,27 +398,12 @@ func TestHostsContainer(t *testing.T) {
|
||||
Value: net.ParseIP("::1"),
|
||||
RRType: dns.TypeAAAA,
|
||||
}},
|
||||
name: "simple",
|
||||
req: urlfilter.DNSRequest{
|
||||
Hostname: "simplehost",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.IPv4(1, 0, 0, 0),
|
||||
RRType: dns.TypeA,
|
||||
}, {
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.ParseIP("::"),
|
||||
RRType: dns.TypeAAAA,
|
||||
}},
|
||||
name: "hello_alias",
|
||||
req: urlfilter.DNSRequest{
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "hello.world",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
name: "hello_alias",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.IPv4(1, 0, 0, 0),
|
||||
@@ -402,26 +413,41 @@ func TestHostsContainer(t *testing.T) {
|
||||
Value: net.ParseIP("::"),
|
||||
RRType: dns.TypeAAAA,
|
||||
}},
|
||||
name: "other_line_alias",
|
||||
req: urlfilter.DNSRequest{
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "hello.world.again",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "other_line_alias",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.IPv4(1, 0, 0, 0),
|
||||
RRType: dns.TypeA,
|
||||
}, {
|
||||
RCode: dns.RcodeSuccess,
|
||||
Value: net.ParseIP("::"),
|
||||
RRType: dns.TypeAAAA,
|
||||
}},
|
||||
}, {
|
||||
want: []*rules.DNSRewrite{},
|
||||
name: "hello_subdomain",
|
||||
req: urlfilter.DNSRequest{
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "say.hello",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
name: "hello_subdomain",
|
||||
want: []*rules.DNSRewrite{},
|
||||
name: "hello_alias_subdomain",
|
||||
req: urlfilter.DNSRequest{
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "say.hello.world",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "hello_alias_subdomain",
|
||||
want: []*rules.DNSRewrite{},
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "for.testing",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "lots_of_aliases",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
RRType: dns.TypeA,
|
||||
@@ -431,37 +457,37 @@ func TestHostsContainer(t *testing.T) {
|
||||
RRType: dns.TypeAAAA,
|
||||
Value: net.ParseIP("::2"),
|
||||
}},
|
||||
name: "lots_of_aliases",
|
||||
req: urlfilter.DNSRequest{
|
||||
Hostname: "for.testing",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "1.0.0.1.in-addr.arpa",
|
||||
DNSType: dns.TypePTR,
|
||||
},
|
||||
name: "reverse",
|
||||
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,
|
||||
},
|
||||
}, {
|
||||
want: []*rules.DNSRewrite{},
|
||||
name: "non-existing",
|
||||
req: urlfilter.DNSRequest{
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "nonexisting",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "non-existing",
|
||||
want: []*rules.DNSRewrite{},
|
||||
}, {
|
||||
want: nil,
|
||||
name: "bad_type",
|
||||
req: urlfilter.DNSRequest{
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "1.0.0.1.in-addr.arpa",
|
||||
DNSType: dns.TypeSRV,
|
||||
},
|
||||
name: "bad_type",
|
||||
want: nil,
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "domain",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
name: "issue_4216_4_6",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
RRType: dns.TypeA,
|
||||
@@ -471,12 +497,12 @@ func TestHostsContainer(t *testing.T) {
|
||||
RRType: dns.TypeAAAA,
|
||||
Value: net.ParseIP("::42"),
|
||||
}},
|
||||
name: "issue_4216_4_6",
|
||||
req: urlfilter.DNSRequest{
|
||||
Hostname: "domain",
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "domain4",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
name: "issue_4216_4",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
RRType: dns.TypeA,
|
||||
@@ -486,12 +512,12 @@ func TestHostsContainer(t *testing.T) {
|
||||
RRType: dns.TypeA,
|
||||
Value: net.IPv4(1, 3, 5, 7),
|
||||
}},
|
||||
name: "issue_4216_4",
|
||||
req: urlfilter.DNSRequest{
|
||||
Hostname: "domain4",
|
||||
DNSType: dns.TypeA,
|
||||
},
|
||||
}, {
|
||||
req: &urlfilter.DNSRequest{
|
||||
Hostname: "domain6",
|
||||
DNSType: dns.TypeAAAA,
|
||||
},
|
||||
name: "issue_4216_6",
|
||||
want: []*rules.DNSRewrite{{
|
||||
RCode: dns.RcodeSuccess,
|
||||
RRType: dns.TypeAAAA,
|
||||
@@ -501,11 +527,6 @@ func TestHostsContainer(t *testing.T) {
|
||||
RRType: dns.TypeAAAA,
|
||||
Value: net.ParseIP("::31"),
|
||||
}},
|
||||
name: "issue_4216_6",
|
||||
req: urlfilter.DNSRequest{
|
||||
Hostname: "domain6",
|
||||
DNSType: dns.TypeAAAA,
|
||||
},
|
||||
}}
|
||||
|
||||
stubWatcher := aghtest.FSWatcher{
|
||||
|
||||
@@ -2,19 +2,31 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
)
|
||||
|
||||
// Variables and functions to substitute in tests.
|
||||
var (
|
||||
// aghosRunCommand is the function to run shell commands.
|
||||
aghosRunCommand = aghos.RunCommand
|
||||
|
||||
// netInterfaces is the function to get the available network interfaces.
|
||||
netInterfaceAddrs = net.InterfaceAddrs
|
||||
|
||||
// rootDirFS is the filesystem pointing to the root directory.
|
||||
rootDirFS = aghos.RootDirFS()
|
||||
)
|
||||
|
||||
// ErrNoStaticIPInfo is returned by IfaceHasStaticIP when no information about
|
||||
// the IP being static is available.
|
||||
const ErrNoStaticIPInfo errors.Error = "no information about static ip"
|
||||
@@ -32,39 +44,29 @@ func IfaceSetStaticIP(ifaceName string) (err error) {
|
||||
}
|
||||
|
||||
// GatewayIP returns IP address of interface's gateway.
|
||||
func GatewayIP(ifaceName string) net.IP {
|
||||
cmd := exec.Command("ip", "route", "show", "dev", ifaceName)
|
||||
log.Tracef("executing %s %v", cmd.Path, cmd.Args)
|
||||
d, err := cmd.Output()
|
||||
if err != nil || cmd.ProcessState.ExitCode() != 0 {
|
||||
//
|
||||
// TODO(e.burkov): Investigate if the gateway address may be fetched in another
|
||||
// way since not every machine has the software installed.
|
||||
func GatewayIP(ifaceName string) (ip net.IP) {
|
||||
code, out, err := aghosRunCommand("ip", "route", "show", "dev", ifaceName)
|
||||
if err != nil {
|
||||
log.Debug("%s", err)
|
||||
|
||||
return nil
|
||||
} else if code != 0 {
|
||||
log.Debug("fetching gateway ip: unexpected exit code: %d", code)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
fields := strings.Fields(string(d))
|
||||
fields := bytes.Fields(out)
|
||||
// The meaningful "ip route" command output should contain the word
|
||||
// "default" at first field and default gateway IP address at third field.
|
||||
if len(fields) < 3 || fields[0] != "default" {
|
||||
if len(fields) < 3 || string(fields[0]) != "default" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return net.ParseIP(fields[2])
|
||||
}
|
||||
|
||||
// CanBindPort checks if we can bind to the given port.
|
||||
func CanBindPort(port int) (can bool, err error) {
|
||||
var addr *net.TCPAddr
|
||||
addr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var listener *net.TCPListener
|
||||
listener, err = net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
_ = listener.Close()
|
||||
return true, nil
|
||||
return net.ParseIP(string(fields[2]))
|
||||
}
|
||||
|
||||
// CanBindPrivilegedPorts checks if current process can bind to privileged
|
||||
@@ -99,19 +101,19 @@ func (iface NetInterface) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetValidNetInterfacesForWeb returns interfaces that are eligible for DNS and WEB only
|
||||
// we do not return link-local addresses here
|
||||
func GetValidNetInterfacesForWeb() ([]*NetInterface, error) {
|
||||
// GetValidNetInterfacesForWeb returns interfaces that are eligible for DNS and
|
||||
// WEB only we do not return link-local addresses here.
|
||||
//
|
||||
// TODO(e.burkov): Can't properly test the function since it's nontrivial to
|
||||
// substitute net.Interface.Addrs and the net.InterfaceAddrs can't be used.
|
||||
func GetValidNetInterfacesForWeb() (netIfaces []*NetInterface, err error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't get interfaces: %w", err)
|
||||
}
|
||||
if len(ifaces) == 0 {
|
||||
} else if len(ifaces) == 0 {
|
||||
return nil, errors.Error("couldn't find any legible interface")
|
||||
}
|
||||
|
||||
var netInterfaces []*NetInterface
|
||||
|
||||
for _, iface := range ifaces {
|
||||
var addrs []net.Addr
|
||||
addrs, err = iface.Addrs()
|
||||
@@ -131,26 +133,30 @@ func GetValidNetInterfacesForWeb() ([]*NetInterface, error) {
|
||||
ipNet, ok := addr.(*net.IPNet)
|
||||
if !ok {
|
||||
// Should be net.IPNet, this is weird.
|
||||
return nil, fmt.Errorf("got iface.Addrs() element %s that is not net.IPNet, it is %T", addr, addr)
|
||||
return nil, fmt.Errorf("got %s that is not net.IPNet, it is %T", addr, addr)
|
||||
}
|
||||
|
||||
// Ignore link-local.
|
||||
if ipNet.IP.IsLinkLocalUnicast() {
|
||||
continue
|
||||
}
|
||||
|
||||
netIface.Addresses = append(netIface.Addresses, ipNet.IP)
|
||||
netIface.Subnets = append(netIface.Subnets, ipNet)
|
||||
}
|
||||
|
||||
// Discard interfaces with no addresses.
|
||||
if len(netIface.Addresses) != 0 {
|
||||
netInterfaces = append(netInterfaces, netIface)
|
||||
netIfaces = append(netIfaces, netIface)
|
||||
}
|
||||
}
|
||||
|
||||
return netInterfaces, nil
|
||||
return netIfaces, nil
|
||||
}
|
||||
|
||||
// GetInterfaceByIP returns the name of interface containing provided ip.
|
||||
//
|
||||
// TODO(e.burkov): See TODO on GetValidInterfacesForWeb.
|
||||
func GetInterfaceByIP(ip net.IP) string {
|
||||
ifaces, err := GetValidNetInterfacesForWeb()
|
||||
if err != nil {
|
||||
@@ -170,6 +176,8 @@ func GetInterfaceByIP(ip net.IP) string {
|
||||
|
||||
// GetSubnet returns pointer to net.IPNet for the specified interface or nil if
|
||||
// the search fails.
|
||||
//
|
||||
// TODO(e.burkov): See TODO on GetValidInterfacesForWeb.
|
||||
func GetSubnet(ifaceName string) *net.IPNet {
|
||||
netIfaces, err := GetValidNetInterfacesForWeb()
|
||||
if err != nil {
|
||||
@@ -220,29 +228,21 @@ func IsAddrInUse(err error) (ok bool) {
|
||||
// CollectAllIfacesAddrs returns the slice of all network interfaces IP
|
||||
// addresses without port number.
|
||||
func CollectAllIfacesAddrs() (addrs []string, err error) {
|
||||
var ifaces []net.Interface
|
||||
ifaces, err = net.Interfaces()
|
||||
var ifaceAddrs []net.Addr
|
||||
ifaceAddrs, err = netInterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting network interfaces: %w", err)
|
||||
return nil, fmt.Errorf("getting interfaces addresses: %w", err)
|
||||
}
|
||||
|
||||
for _, iface := range ifaces {
|
||||
var ifaceAddrs []net.Addr
|
||||
ifaceAddrs, err = iface.Addrs()
|
||||
for _, addr := range ifaceAddrs {
|
||||
cidr := addr.String()
|
||||
var ip net.IP
|
||||
ip, _, err = net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting addresses for %q: %w", iface.Name, err)
|
||||
return nil, fmt.Errorf("parsing cidr: %w", err)
|
||||
}
|
||||
|
||||
for _, addr := range ifaceAddrs {
|
||||
cidr := addr.String()
|
||||
var ip net.IP
|
||||
ip, _, err = net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing cidr: %w", err)
|
||||
}
|
||||
|
||||
addrs = append(addrs, ip.String())
|
||||
}
|
||||
addrs = append(addrs, ip.String())
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
|
||||
10
internal/aghnet/net_bsd.go
Normal file
10
internal/aghnet/net_bsd.go
Normal file
@@ -0,0 +1,10 @@
|
||||
//go:build darwin || freebsd || openbsd
|
||||
// +build darwin freebsd openbsd
|
||||
|
||||
package aghnet
|
||||
|
||||
import "github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
return aghos.HaveAdminRights()
|
||||
}
|
||||
@@ -4,10 +4,11 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
@@ -23,11 +24,7 @@ type hardwarePortInfo struct {
|
||||
static bool
|
||||
}
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
return aghos.HaveAdminRights()
|
||||
}
|
||||
|
||||
func ifaceHasStaticIP(ifaceName string) (bool, error) {
|
||||
func ifaceHasStaticIP(ifaceName string) (ok bool, err error) {
|
||||
portInfo, err := getCurrentHardwarePortInfo(ifaceName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -36,9 +33,10 @@ func ifaceHasStaticIP(ifaceName string) (bool, error) {
|
||||
return portInfo.static, nil
|
||||
}
|
||||
|
||||
// getCurrentHardwarePortInfo gets information for the specified network interface.
|
||||
// getCurrentHardwarePortInfo gets information for the specified network
|
||||
// interface.
|
||||
func getCurrentHardwarePortInfo(ifaceName string) (hardwarePortInfo, error) {
|
||||
// First of all we should find hardware port name
|
||||
// First of all we should find hardware port name.
|
||||
m := getNetworkSetupHardwareReports()
|
||||
hardwarePort, ok := m[ifaceName]
|
||||
if !ok {
|
||||
@@ -48,6 +46,10 @@ func getCurrentHardwarePortInfo(ifaceName string) (hardwarePortInfo, error) {
|
||||
return getHardwarePortInfo(hardwarePort)
|
||||
}
|
||||
|
||||
// hardwareReportsReg is the regular expression matching the lines of
|
||||
// networksetup command output lines containing the interface information.
|
||||
var hardwareReportsReg = regexp.MustCompile("Hardware Port: (.*?)\nDevice: (.*?)\n")
|
||||
|
||||
// getNetworkSetupHardwareReports parses the output of the `networksetup
|
||||
// -listallhardwareports` command it returns a map where the key is the
|
||||
// interface name, and the value is the "hardware port" returns nil if it fails
|
||||
@@ -56,54 +58,44 @@ func getCurrentHardwarePortInfo(ifaceName string) (hardwarePortInfo, error) {
|
||||
// TODO(e.burkov): There should be more proper approach than parsing the
|
||||
// command output. For example, see
|
||||
// https://developer.apple.com/documentation/systemconfiguration.
|
||||
func getNetworkSetupHardwareReports() map[string]string {
|
||||
_, out, err := aghos.RunCommand("networksetup", "-listallhardwareports")
|
||||
func getNetworkSetupHardwareReports() (reports map[string]string) {
|
||||
_, out, err := aghosRunCommand("networksetup", "-listallhardwareports")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
re, err := regexp.Compile("Hardware Port: (.*?)\nDevice: (.*?)\n")
|
||||
if err != nil {
|
||||
return nil
|
||||
reports = make(map[string]string)
|
||||
|
||||
matches := hardwareReportsReg.FindAllSubmatch(out, -1)
|
||||
for _, m := range matches {
|
||||
reports[string(m[2])] = string(m[1])
|
||||
}
|
||||
|
||||
m := make(map[string]string)
|
||||
|
||||
matches := re.FindAllStringSubmatch(out, -1)
|
||||
for i := range matches {
|
||||
port := matches[i][1]
|
||||
device := matches[i][2]
|
||||
m[device] = port
|
||||
}
|
||||
|
||||
return m
|
||||
return reports
|
||||
}
|
||||
|
||||
func getHardwarePortInfo(hardwarePort string) (hardwarePortInfo, error) {
|
||||
h := hardwarePortInfo{}
|
||||
// hardwarePortReg is the regular expression matching the lines of networksetup
|
||||
// command output lines containing the port information.
|
||||
var hardwarePortReg = regexp.MustCompile("IP address: (.*?)\nSubnet mask: (.*?)\nRouter: (.*?)\n")
|
||||
|
||||
_, out, err := aghos.RunCommand("networksetup", "-getinfo", hardwarePort)
|
||||
func getHardwarePortInfo(hardwarePort string) (h hardwarePortInfo, err error) {
|
||||
_, out, err := aghosRunCommand("networksetup", "-getinfo", hardwarePort)
|
||||
if err != nil {
|
||||
return h, err
|
||||
}
|
||||
|
||||
re := regexp.MustCompile("IP address: (.*?)\nSubnet mask: (.*?)\nRouter: (.*?)\n")
|
||||
|
||||
match := re.FindStringSubmatch(out)
|
||||
if len(match) == 0 {
|
||||
match := hardwarePortReg.FindSubmatch(out)
|
||||
if len(match) != 4 {
|
||||
return h, errors.Error("could not find hardware port info")
|
||||
}
|
||||
|
||||
h.name = hardwarePort
|
||||
h.ip = match[1]
|
||||
h.subnet = match[2]
|
||||
h.gatewayIP = match[3]
|
||||
|
||||
if strings.Index(out, "Manual Configuration") == 0 {
|
||||
h.static = true
|
||||
}
|
||||
|
||||
return h, nil
|
||||
return hardwarePortInfo{
|
||||
name: hardwarePort,
|
||||
ip: string(match[1]),
|
||||
subnet: string(match[2]),
|
||||
gatewayIP: string(match[3]),
|
||||
static: bytes.Index(out, []byte("Manual Configuration")) == 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ifaceSetStaticIP(ifaceName string) (err error) {
|
||||
@@ -113,7 +105,7 @@ func ifaceSetStaticIP(ifaceName string) (err error) {
|
||||
}
|
||||
|
||||
if portInfo.static {
|
||||
return errors.Error("IP address is already static")
|
||||
return errors.Error("ip address is already static")
|
||||
}
|
||||
|
||||
dnsAddrs, err := getEtcResolvConfServers()
|
||||
@@ -121,50 +113,62 @@ func ifaceSetStaticIP(ifaceName string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
args := make([]string, 0)
|
||||
args = append(args, "-setdnsservers", portInfo.name)
|
||||
args = append(args, dnsAddrs...)
|
||||
args := append([]string{"-setdnsservers", portInfo.name}, dnsAddrs...)
|
||||
|
||||
// Setting DNS servers is necessary when configuring a static IP
|
||||
code, _, err := aghos.RunCommand("networksetup", args...)
|
||||
code, _, err := aghosRunCommand("networksetup", args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if code != 0 {
|
||||
} else if code != 0 {
|
||||
return fmt.Errorf("failed to set DNS servers, code=%d", code)
|
||||
}
|
||||
|
||||
// Actually configures hardware port to have static IP
|
||||
code, _, err = aghos.RunCommand("networksetup", "-setmanual",
|
||||
portInfo.name, portInfo.ip, portInfo.subnet, portInfo.gatewayIP)
|
||||
code, _, err = aghosRunCommand(
|
||||
"networksetup",
|
||||
"-setmanual",
|
||||
portInfo.name,
|
||||
portInfo.ip,
|
||||
portInfo.subnet,
|
||||
portInfo.gatewayIP,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if code != 0 {
|
||||
} else if code != 0 {
|
||||
return fmt.Errorf("failed to set DNS servers, code=%d", code)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// etcResolvConfReg is the regular expression matching the lines of resolv.conf
|
||||
// file containing a name server information.
|
||||
var etcResolvConfReg = regexp.MustCompile("nameserver ([a-zA-Z0-9.:]+)")
|
||||
|
||||
// getEtcResolvConfServers returns a list of nameservers configured in
|
||||
// /etc/resolv.conf.
|
||||
func getEtcResolvConfServers() ([]string, error) {
|
||||
body, err := os.ReadFile("/etc/resolv.conf")
|
||||
func getEtcResolvConfServers() (addrs []string, err error) {
|
||||
const filename = "etc/resolv.conf"
|
||||
|
||||
_, err = aghos.FileWalker(func(r io.Reader) (_ []string, _ bool, err error) {
|
||||
sc := bufio.NewScanner(r)
|
||||
for sc.Scan() {
|
||||
matches := etcResolvConfReg.FindAllStringSubmatch(sc.Text(), -1)
|
||||
if len(matches) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, m := range matches {
|
||||
addrs = append(addrs, m[1])
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false, sc.Err()
|
||||
}).Walk(rootDirFS, filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
re := regexp.MustCompile("nameserver ([a-zA-Z0-9.:]+)")
|
||||
|
||||
matches := re.FindAllStringSubmatch(string(body), -1)
|
||||
if len(matches) == 0 {
|
||||
return nil, errors.Error("found no DNS servers in /etc/resolv.conf")
|
||||
}
|
||||
|
||||
addrs := make([]string, 0)
|
||||
for i := range matches {
|
||||
addrs = append(addrs, matches[i][1])
|
||||
return nil, fmt.Errorf("parsing etc/resolv.conf file: %w", err)
|
||||
} else if len(addrs) == 0 {
|
||||
return nil, fmt.Errorf("found no dns servers in %s", filename)
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
|
||||
261
internal/aghnet/net_darwin_test.go
Normal file
261
internal/aghnet/net_darwin_test.go
Normal file
@@ -0,0 +1,261 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIfaceHasStaticIP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
shell mapShell
|
||||
ifaceName string
|
||||
wantHas assert.BoolAssertionFunc
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "success",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "IP address: 1.2.3.4\nSubnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
ifaceName: "en0",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
name: "success_static",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "Manual Configuration\nIP address: 1.2.3.4\n" +
|
||||
"Subnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
ifaceName: "en0",
|
||||
wantHas: assert.True,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
name: "reports_error",
|
||||
shell: theOnlyCmd(
|
||||
"networksetup -listallhardwareports",
|
||||
0,
|
||||
"",
|
||||
errors.Error("can't list"),
|
||||
),
|
||||
ifaceName: "en0",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: `could not find hardware port for en0`,
|
||||
}, {
|
||||
name: "port_error",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: errors.Error("can't get"),
|
||||
out: ``,
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
ifaceName: "en0",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: `can't get`,
|
||||
}, {
|
||||
name: "port_bad_output",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "nothing meaningful",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
ifaceName: "en0",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: `could not find hardware port info`,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
substShell(t, tc.shell.RunCmd)
|
||||
|
||||
has, err := IfaceHasStaticIP(tc.ifaceName)
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
tc.wantHas(t, has)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIfaceSetStaticIP(t *testing.T) {
|
||||
succFsys := fstest.MapFS{
|
||||
"etc/resolv.conf": &fstest.MapFile{
|
||||
Data: []byte(`nameserver 1.1.1.1`),
|
||||
},
|
||||
}
|
||||
panicFsys := &aghtest.FS{
|
||||
OnOpen: func(name string) (fs.File, error) { panic("not implemented") },
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
shell mapShell
|
||||
fsys fs.FS
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "success",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "IP address: 1.2.3.4\nSubnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -setdnsservers hwport 1.1.1.1": {
|
||||
err: nil,
|
||||
out: "",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -setmanual hwport 1.2.3.4 255.255.255.0 1.2.3.1": {
|
||||
err: nil,
|
||||
out: "",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
fsys: succFsys,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
name: "static_already",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "Manual Configuration\nIP address: 1.2.3.4\n" +
|
||||
"Subnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
fsys: panicFsys,
|
||||
wantErrMsg: `ip address is already static`,
|
||||
}, {
|
||||
name: "reports_error",
|
||||
shell: theOnlyCmd(
|
||||
"networksetup -listallhardwareports",
|
||||
0,
|
||||
"",
|
||||
errors.Error("can't list"),
|
||||
),
|
||||
fsys: panicFsys,
|
||||
wantErrMsg: `could not find hardware port for en0`,
|
||||
}, {
|
||||
name: "resolv_conf_error",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "IP address: 1.2.3.4\nSubnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
fsys: fstest.MapFS{
|
||||
"etc/resolv.conf": &fstest.MapFile{
|
||||
Data: []byte("this resolv.conf is invalid"),
|
||||
},
|
||||
},
|
||||
wantErrMsg: `found no dns servers in etc/resolv.conf`,
|
||||
}, {
|
||||
name: "set_dns_error",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "IP address: 1.2.3.4\nSubnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -setdnsservers hwport 1.1.1.1": {
|
||||
err: errors.Error("can't set"),
|
||||
out: "",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
fsys: succFsys,
|
||||
wantErrMsg: `can't set`,
|
||||
}, {
|
||||
name: "set_manual_error",
|
||||
shell: mapShell{
|
||||
"networksetup -listallhardwareports": {
|
||||
err: nil,
|
||||
out: "Hardware Port: hwport\nDevice: en0\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -getinfo hwport": {
|
||||
err: nil,
|
||||
out: "IP address: 1.2.3.4\nSubnet mask: 255.255.255.0\nRouter: 1.2.3.1\n",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -setdnsservers hwport 1.1.1.1": {
|
||||
err: nil,
|
||||
out: "",
|
||||
code: 0,
|
||||
},
|
||||
"networksetup -setmanual hwport 1.2.3.4 255.255.255.0 1.2.3.1": {
|
||||
err: errors.Error("can't set"),
|
||||
out: "",
|
||||
code: 0,
|
||||
},
|
||||
},
|
||||
fsys: succFsys,
|
||||
wantErrMsg: `can't set`,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
substShell(t, tc.shell.RunCmd)
|
||||
substRootDirFS(t, tc.fsys)
|
||||
|
||||
err := IfaceSetStaticIP("en0")
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -13,16 +13,12 @@ import (
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
)
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
return aghos.HaveAdminRights()
|
||||
}
|
||||
|
||||
func ifaceHasStaticIP(ifaceName string) (ok bool, err error) {
|
||||
const rcConfFilename = "etc/rc.conf"
|
||||
|
||||
walker := aghos.FileWalker(interfaceName(ifaceName).rcConfStaticConfig)
|
||||
|
||||
return walker.Walk(aghos.RootDirFS(), rcConfFilename)
|
||||
return walker.Walk(rootDirFS, rcConfFilename)
|
||||
}
|
||||
|
||||
// rcConfStaticConfig checks if the interface is configured by /etc/rc.conf to
|
||||
|
||||
@@ -4,56 +4,74 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"io/fs"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRcConfStaticConfig(t *testing.T) {
|
||||
const iface interfaceName = `em0`
|
||||
const nl = "\n"
|
||||
func TestIfaceHasStaticIP(t *testing.T) {
|
||||
const (
|
||||
ifaceName = `em0`
|
||||
rcConf = "etc/rc.conf"
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
rcconfData string
|
||||
wantCont bool
|
||||
name string
|
||||
rootFsys fs.FS
|
||||
wantHas assert.BoolAssertionFunc
|
||||
}{{
|
||||
name: "simple",
|
||||
rcconfData: `ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
|
||||
wantCont: false,
|
||||
name: "simple",
|
||||
rootFsys: fstest.MapFS{rcConf: &fstest.MapFile{
|
||||
Data: []byte(`ifconfig_` + ifaceName + `="inet 127.0.0.253 netmask 0xffffffff"` + nl),
|
||||
}},
|
||||
wantHas: assert.True,
|
||||
}, {
|
||||
name: "case_insensitiveness",
|
||||
rcconfData: `ifconfig_em0="InEt 127.0.0.253 NeTmAsK 0xffffffff"` + nl,
|
||||
wantCont: false,
|
||||
name: "case_insensitiveness",
|
||||
rootFsys: fstest.MapFS{rcConf: &fstest.MapFile{
|
||||
Data: []byte(`ifconfig_` + ifaceName + `="InEt 127.0.0.253 NeTmAsK 0xffffffff"` + nl),
|
||||
}},
|
||||
wantHas: assert.True,
|
||||
}, {
|
||||
name: "comments_and_trash",
|
||||
rcconfData: `# comment 1` + nl +
|
||||
`` + nl +
|
||||
`# comment 2` + nl +
|
||||
`ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
|
||||
wantCont: false,
|
||||
rootFsys: fstest.MapFS{rcConf: &fstest.MapFile{
|
||||
Data: []byte(`# comment 1` + nl +
|
||||
`` + nl +
|
||||
`# comment 2` + nl +
|
||||
`ifconfig_` + ifaceName + `="inet 127.0.0.253 netmask 0xffffffff"` + nl,
|
||||
),
|
||||
}},
|
||||
wantHas: assert.True,
|
||||
}, {
|
||||
name: "aliases",
|
||||
rcconfData: `ifconfig_em0_alias="inet 127.0.0.1/24"` + nl +
|
||||
`ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
|
||||
wantCont: false,
|
||||
rootFsys: fstest.MapFS{rcConf: &fstest.MapFile{
|
||||
Data: []byte(`ifconfig_` + ifaceName + `_alias="inet 127.0.0.1/24"` + nl +
|
||||
`ifconfig_` + ifaceName + `="inet 127.0.0.253 netmask 0xffffffff"` + nl,
|
||||
),
|
||||
}},
|
||||
wantHas: assert.True,
|
||||
}, {
|
||||
name: "incorrect_config",
|
||||
rcconfData: `ifconfig_em0="inet6 127.0.0.253 netmask 0xffffffff"` + nl +
|
||||
`ifconfig_em0="inet 256.256.256.256 netmask 0xffffffff"` + nl +
|
||||
`ifconfig_em0=""` + nl,
|
||||
wantCont: true,
|
||||
rootFsys: fstest.MapFS{rcConf: &fstest.MapFile{
|
||||
Data: []byte(
|
||||
`ifconfig_` + ifaceName + `="inet6 127.0.0.253 netmask 0xffffffff"` + nl +
|
||||
`ifconfig_` + ifaceName + `="inet 256.256.256.256 netmask 0xffffffff"` + nl +
|
||||
`ifconfig_` + ifaceName + `=""` + nl,
|
||||
),
|
||||
}},
|
||||
wantHas: assert.False,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
r := strings.NewReader(tc.rcconfData)
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, cont, err := iface.rcConfStaticConfig(r)
|
||||
substRootDirFS(t, tc.rootFsys)
|
||||
|
||||
has, err := IfaceHasStaticIP(ifaceName)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.wantCont, cont)
|
||||
tc.wantHas(t, has)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,16 +13,33 @@ import (
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/stringutil"
|
||||
"github.com/google/renameio/maybe"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// dhcpсdConf is the name of /etc/dhcpcd.conf file in the root filesystem.
|
||||
const dhcpcdConf = "etc/dhcpcd.conf"
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
cnbs, err := unix.PrctlRetInt(
|
||||
unix.PR_CAP_AMBIENT,
|
||||
unix.PR_CAP_AMBIENT_IS_SET,
|
||||
unix.CAP_NET_BIND_SERVICE,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
// Don't check the error because it's always nil on Linux.
|
||||
adm, _ := aghos.HaveAdminRights()
|
||||
|
||||
return cnbs == 1 || adm, err
|
||||
}
|
||||
|
||||
// dhcpcdStaticConfig checks if interface is configured by /etc/dhcpcd.conf to
|
||||
// have a static IP.
|
||||
func (n interfaceName) dhcpcdStaticConfig(r io.Reader) (subsources []string, cont bool, err error) {
|
||||
s := bufio.NewScanner(r)
|
||||
ifaceFound := findIfaceLine(s, string(n))
|
||||
if !ifaceFound {
|
||||
if !findIfaceLine(s, string(n)) {
|
||||
return nil, true, s.Err()
|
||||
}
|
||||
|
||||
@@ -61,9 +78,9 @@ func (n interfaceName) ifacesStaticConfig(r io.Reader) (sub []string, cont bool,
|
||||
fields := strings.Fields(line)
|
||||
fieldsNum := len(fields)
|
||||
|
||||
// Man page interfaces(5) declares that interface definition
|
||||
// should consist of the key word "iface" followed by interface
|
||||
// name, and method at fourth field.
|
||||
// Man page interfaces(5) declares that interface definition should
|
||||
// consist of the key word "iface" followed by interface name, and
|
||||
// method at fourth field.
|
||||
if fieldsNum >= 4 &&
|
||||
fields[0] == "iface" && fields[1] == string(n) && fields[3] == "static" {
|
||||
return nil, false, nil
|
||||
@@ -78,10 +95,10 @@ func (n interfaceName) ifacesStaticConfig(r io.Reader) (sub []string, cont bool,
|
||||
}
|
||||
|
||||
func ifaceHasStaticIP(ifaceName string) (has bool, err error) {
|
||||
// TODO(a.garipov): Currently, this function returns the first
|
||||
// definitive result. So if /etc/dhcpcd.conf has a static IP while
|
||||
// /etc/network/interfaces doesn't, it will return true. Perhaps this
|
||||
// is not the most desirable behavior.
|
||||
// TODO(a.garipov): Currently, this function returns the first definitive
|
||||
// result. So if /etc/dhcpcd.conf has and /etc/network/interfaces has no
|
||||
// static IP configuration, it will return true. Perhaps this is not the
|
||||
// most desirable behavior.
|
||||
|
||||
iface := interfaceName(ifaceName)
|
||||
|
||||
@@ -90,17 +107,15 @@ func ifaceHasStaticIP(ifaceName string) (has bool, err error) {
|
||||
filename string
|
||||
}{{
|
||||
FileWalker: iface.dhcpcdStaticConfig,
|
||||
filename: "etc/dhcpcd.conf",
|
||||
filename: dhcpcdConf,
|
||||
}, {
|
||||
FileWalker: iface.ifacesStaticConfig,
|
||||
filename: "etc/network/interfaces",
|
||||
}} {
|
||||
has, err = pair.Walk(aghos.RootDirFS(), pair.filename)
|
||||
has, err = pair.Walk(rootDirFS, pair.filename)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if has {
|
||||
} else if has {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
@@ -108,14 +123,6 @@ func ifaceHasStaticIP(ifaceName string) (has bool, err error) {
|
||||
return false, ErrNoStaticIPInfo
|
||||
}
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
cnbs, err := unix.PrctlRetInt(unix.PR_CAP_AMBIENT, unix.PR_CAP_AMBIENT_IS_SET, unix.CAP_NET_BIND_SERVICE, 0, 0)
|
||||
// Don't check the error because it's always nil on Linux.
|
||||
adm, _ := aghos.HaveAdminRights()
|
||||
|
||||
return cnbs == 1 || adm, err
|
||||
}
|
||||
|
||||
// findIfaceLine scans s until it finds the line that declares an interface with
|
||||
// the given name. If findIfaceLine can't find the line, it returns false.
|
||||
func findIfaceLine(s *bufio.Scanner, name string) (ok bool) {
|
||||
@@ -131,23 +138,23 @@ func findIfaceLine(s *bufio.Scanner, name string) (ok bool) {
|
||||
}
|
||||
|
||||
// ifaceSetStaticIP configures the system to retain its current IP on the
|
||||
// interface through dhcpdc.conf.
|
||||
// interface through dhcpcd.conf.
|
||||
func ifaceSetStaticIP(ifaceName string) (err error) {
|
||||
ipNet := GetSubnet(ifaceName)
|
||||
if ipNet.IP == nil {
|
||||
return errors.Error("can't get IP address")
|
||||
}
|
||||
|
||||
gatewayIP := GatewayIP(ifaceName)
|
||||
add := dhcpcdConfIface(ifaceName, ipNet, gatewayIP, ipNet.IP)
|
||||
|
||||
body, err := os.ReadFile("/etc/dhcpcd.conf")
|
||||
body, err := os.ReadFile(dhcpcdConf)
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
|
||||
gatewayIP := GatewayIP(ifaceName)
|
||||
add := dhcpcdConfIface(ifaceName, ipNet, gatewayIP)
|
||||
|
||||
body = append(body, []byte(add)...)
|
||||
err = maybe.WriteFile("/etc/dhcpcd.conf", body, 0o644)
|
||||
err = maybe.WriteFile(dhcpcdConf, body, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing conf: %w", err)
|
||||
}
|
||||
@@ -157,22 +164,24 @@ func ifaceSetStaticIP(ifaceName string) (err error) {
|
||||
|
||||
// dhcpcdConfIface returns configuration lines for the dhcpdc.conf files that
|
||||
// configure the interface to have a static IP.
|
||||
func dhcpcdConfIface(ifaceName string, ipNet *net.IPNet, gatewayIP, dnsIP net.IP) (conf string) {
|
||||
var body []byte
|
||||
|
||||
add := fmt.Sprintf(
|
||||
"\n# %[1]s added by AdGuard Home.\ninterface %[1]s\nstatic ip_address=%s\n",
|
||||
func dhcpcdConfIface(ifaceName string, ipNet *net.IPNet, gwIP net.IP) (conf string) {
|
||||
b := &strings.Builder{}
|
||||
stringutil.WriteToBuilder(
|
||||
b,
|
||||
"\n# ",
|
||||
ifaceName,
|
||||
ipNet)
|
||||
body = append(body, []byte(add)...)
|
||||
" added by AdGuard Home.\ninterface ",
|
||||
ifaceName,
|
||||
"\nstatic ip_address=",
|
||||
ipNet.String(),
|
||||
"\n",
|
||||
)
|
||||
|
||||
if gatewayIP != nil {
|
||||
add = fmt.Sprintf("static routers=%s\n", gatewayIP)
|
||||
body = append(body, []byte(add)...)
|
||||
if gwIP != nil {
|
||||
stringutil.WriteToBuilder(b, "static routers=", gwIP.String(), "\n")
|
||||
}
|
||||
|
||||
add = fmt.Sprintf("static domain_name_servers=%s\n\n", dnsIP)
|
||||
body = append(body, []byte(add)...)
|
||||
stringutil.WriteToBuilder(b, "static domain_name_servers=", ipNet.IP.String(), "\n\n")
|
||||
|
||||
return string(body)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
@@ -4,152 +4,124 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"io/fs"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDHCPCDStaticConfig(t *testing.T) {
|
||||
const iface interfaceName = `wlan0`
|
||||
func TestHasStaticIP(t *testing.T) {
|
||||
const ifaceName = "wlan0"
|
||||
|
||||
const (
|
||||
dhcpcd = "etc/dhcpcd.conf"
|
||||
netifaces = "etc/network/interfaces"
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
wantCont bool
|
||||
}{{
|
||||
name: "has_not",
|
||||
data: []byte(`#comment` + nl +
|
||||
`# comment` + nl +
|
||||
`interface eth0` + nl +
|
||||
`static ip_address=192.168.0.1/24` + nl +
|
||||
`# interface ` + iface + nl +
|
||||
`static ip_address=192.168.1.1/24` + nl +
|
||||
`# comment` + nl,
|
||||
),
|
||||
wantCont: true,
|
||||
}, {
|
||||
name: "has",
|
||||
data: []byte(`#comment` + nl +
|
||||
`# comment` + nl +
|
||||
`interface eth0` + nl +
|
||||
`static ip_address=192.168.0.1/24` + nl +
|
||||
`# interface ` + iface + nl +
|
||||
`static ip_address=192.168.1.1/24` + nl +
|
||||
`# comment` + nl +
|
||||
`interface ` + iface + nl +
|
||||
`# comment` + nl +
|
||||
`static ip_address=192.168.2.1/24` + nl,
|
||||
),
|
||||
wantCont: false,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
r := bytes.NewReader(tc.data)
|
||||
_, cont, err := iface.dhcpcdStaticConfig(r)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.wantCont, cont)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIfacesStaticConfig(t *testing.T) {
|
||||
const iface interfaceName = `enp0s3`
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
wantCont bool
|
||||
wantPatterns []string
|
||||
}{{
|
||||
name: "has_not",
|
||||
data: []byte(`allow-hotplug ` + iface + nl +
|
||||
`#iface enp0s3 inet static` + nl +
|
||||
`# address 192.168.0.200` + nl +
|
||||
`# netmask 255.255.255.0` + nl +
|
||||
`# gateway 192.168.0.1` + nl +
|
||||
`iface ` + iface + ` inet dhcp` + nl,
|
||||
),
|
||||
wantCont: true,
|
||||
wantPatterns: []string{},
|
||||
}, {
|
||||
name: "has",
|
||||
data: []byte(`allow-hotplug ` + iface + nl +
|
||||
`iface ` + iface + ` inet static` + nl +
|
||||
` address 192.168.0.200` + nl +
|
||||
` netmask 255.255.255.0` + nl +
|
||||
` gateway 192.168.0.1` + nl +
|
||||
`#iface ` + iface + ` inet dhcp` + nl,
|
||||
),
|
||||
wantCont: false,
|
||||
wantPatterns: []string{},
|
||||
}, {
|
||||
name: "return_patterns",
|
||||
data: []byte(`source hello` + nl +
|
||||
`source world` + nl +
|
||||
`#iface ` + iface + ` inet static` + nl,
|
||||
),
|
||||
wantCont: true,
|
||||
wantPatterns: []string{"hello", "world"},
|
||||
}, {
|
||||
// This one tests if the first found valid interface prevents
|
||||
// checking files under the `source` directive.
|
||||
name: "ignore_patterns",
|
||||
data: []byte(`source hello` + nl +
|
||||
`source world` + nl +
|
||||
`iface ` + iface + ` inet static` + nl,
|
||||
),
|
||||
wantCont: false,
|
||||
wantPatterns: []string{},
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
r := bytes.NewReader(tc.data)
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
patterns, has, err := iface.ifacesStaticConfig(r)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.wantCont, has)
|
||||
assert.ElementsMatch(t, tc.wantPatterns, patterns)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetStaticIPdhcpcdConf(t *testing.T) {
|
||||
testCases := []struct {
|
||||
rootFsys fs.FS
|
||||
name string
|
||||
dhcpcdConf string
|
||||
routers net.IP
|
||||
wantHas assert.BoolAssertionFunc
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "with_gateway",
|
||||
dhcpcdConf: nl + `# wlan0 added by AdGuard Home.` + nl +
|
||||
`interface wlan0` + nl +
|
||||
`static ip_address=192.168.0.2/24` + nl +
|
||||
`static routers=192.168.0.1` + nl +
|
||||
`static domain_name_servers=192.168.0.2` + nl + nl,
|
||||
routers: net.IP{192, 168, 0, 1},
|
||||
rootFsys: fstest.MapFS{
|
||||
dhcpcd: &fstest.MapFile{
|
||||
Data: []byte(`#comment` + nl +
|
||||
`# comment` + nl +
|
||||
`interface eth0` + nl +
|
||||
`static ip_address=192.168.0.1/24` + nl +
|
||||
`# interface ` + ifaceName + nl +
|
||||
`static ip_address=192.168.1.1/24` + nl +
|
||||
`# comment` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
name: "dhcpcd_has_not",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: `no information about static ip`,
|
||||
}, {
|
||||
name: "without_gateway",
|
||||
dhcpcdConf: nl + `# wlan0 added by AdGuard Home.` + nl +
|
||||
`interface wlan0` + nl +
|
||||
`static ip_address=192.168.0.2/24` + nl +
|
||||
`static domain_name_servers=192.168.0.2` + nl + nl,
|
||||
routers: nil,
|
||||
rootFsys: fstest.MapFS{
|
||||
dhcpcd: &fstest.MapFile{
|
||||
Data: []byte(`#comment` + nl +
|
||||
`# comment` + nl +
|
||||
`interface ` + ifaceName + nl +
|
||||
`static ip_address=192.168.0.1/24` + nl +
|
||||
`# interface ` + ifaceName + nl +
|
||||
`static ip_address=192.168.1.1/24` + nl +
|
||||
`# comment` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
name: "dhcpcd_has",
|
||||
wantHas: assert.True,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
rootFsys: fstest.MapFS{
|
||||
netifaces: &fstest.MapFile{
|
||||
Data: []byte(`allow-hotplug ` + ifaceName + nl +
|
||||
`#iface enp0s3 inet static` + nl +
|
||||
`# address 192.168.0.200` + nl +
|
||||
`# netmask 255.255.255.0` + nl +
|
||||
`# gateway 192.168.0.1` + nl +
|
||||
`iface ` + ifaceName + ` inet dhcp` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
name: "netifaces_has_not",
|
||||
wantHas: assert.False,
|
||||
wantErrMsg: `no information about static ip`,
|
||||
}, {
|
||||
rootFsys: fstest.MapFS{
|
||||
netifaces: &fstest.MapFile{
|
||||
Data: []byte(`allow-hotplug ` + ifaceName + nl +
|
||||
`iface ` + ifaceName + ` inet static` + nl +
|
||||
` address 192.168.0.200` + nl +
|
||||
` netmask 255.255.255.0` + nl +
|
||||
` gateway 192.168.0.1` + nl +
|
||||
`#iface ` + ifaceName + ` inet dhcp` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
name: "netifaces_has",
|
||||
wantHas: assert.True,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
rootFsys: fstest.MapFS{
|
||||
netifaces: &fstest.MapFile{
|
||||
Data: []byte(`source hello` + nl +
|
||||
`#iface ` + ifaceName + ` inet static` + nl,
|
||||
),
|
||||
},
|
||||
"hello": &fstest.MapFile{
|
||||
Data: []byte(`iface ` + ifaceName + ` inet static` + nl),
|
||||
},
|
||||
},
|
||||
name: "netifaces_another_file",
|
||||
wantHas: assert.True,
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
rootFsys: fstest.MapFS{
|
||||
netifaces: &fstest.MapFile{
|
||||
Data: []byte(`source hello` + nl +
|
||||
`iface ` + ifaceName + ` inet static` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
name: "netifaces_ignore_another",
|
||||
wantHas: assert.True,
|
||||
wantErrMsg: ``,
|
||||
}}
|
||||
|
||||
ipNet := &net.IPNet{
|
||||
IP: net.IP{192, 168, 0, 2},
|
||||
Mask: net.IPMask{255, 255, 255, 0},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
s := dhcpcdConfIface("wlan0", ipNet, tc.routers, net.IP{192, 168, 0, 2})
|
||||
assert.Equal(t, tc.dhcpcdConf, s)
|
||||
substRootDirFS(t, tc.rootFsys)
|
||||
|
||||
has, err := IfaceHasStaticIP(ifaceName)
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
tc.wantHas(t, has)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,10 @@ import (
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
)
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
return aghos.HaveAdminRights()
|
||||
}
|
||||
|
||||
func ifaceHasStaticIP(ifaceName string) (ok bool, err error) {
|
||||
filename := fmt.Sprintf("etc/hostname.%s", ifaceName)
|
||||
|
||||
return aghos.FileWalker(hostnameIfStaticConfig).Walk(aghos.RootDirFS(), filename)
|
||||
return aghos.FileWalker(hostnameIfStaticConfig).Walk(rootDirFS, filename)
|
||||
}
|
||||
|
||||
// hostnameIfStaticConfig checks if the interface is configured by
|
||||
|
||||
@@ -4,49 +4,69 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHostnameIfStaticConfig(t *testing.T) {
|
||||
const nl = "\n"
|
||||
func TestIfaceHasStaticIP(t *testing.T) {
|
||||
const ifaceName = "em0"
|
||||
|
||||
confFile := fmt.Sprintf("etc/hostname.%s", ifaceName)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
rcconfData string
|
||||
wantHas bool
|
||||
name string
|
||||
rootFsys fs.FS
|
||||
wantHas assert.BoolAssertionFunc
|
||||
}{{
|
||||
name: "simple",
|
||||
rcconfData: `inet 127.0.0.253` + nl,
|
||||
wantHas: true,
|
||||
name: "simple",
|
||||
rootFsys: fstest.MapFS{
|
||||
confFile: &fstest.MapFile{
|
||||
Data: []byte(`inet 127.0.0.253` + nl),
|
||||
},
|
||||
},
|
||||
wantHas: assert.True,
|
||||
}, {
|
||||
name: "case_sensitiveness",
|
||||
rcconfData: `InEt 127.0.0.253` + nl,
|
||||
wantHas: false,
|
||||
name: "case_sensitiveness",
|
||||
rootFsys: fstest.MapFS{
|
||||
confFile: &fstest.MapFile{
|
||||
Data: []byte(`InEt 127.0.0.253` + nl),
|
||||
},
|
||||
},
|
||||
wantHas: assert.False,
|
||||
}, {
|
||||
name: "comments_and_trash",
|
||||
rcconfData: `# comment 1` + nl +
|
||||
`` + nl +
|
||||
`# inet 127.0.0.253` + nl +
|
||||
`inet` + nl,
|
||||
wantHas: false,
|
||||
rootFsys: fstest.MapFS{
|
||||
confFile: &fstest.MapFile{
|
||||
Data: []byte(`# comment 1` + nl + nl +
|
||||
`# inet 127.0.0.253` + nl +
|
||||
`inet` + nl,
|
||||
),
|
||||
},
|
||||
},
|
||||
wantHas: assert.False,
|
||||
}, {
|
||||
name: "incorrect_config",
|
||||
rcconfData: `inet6 127.0.0.253` + nl +
|
||||
`inet 256.256.256.256` + nl,
|
||||
wantHas: false,
|
||||
rootFsys: fstest.MapFS{
|
||||
confFile: &fstest.MapFile{
|
||||
Data: []byte(`inet6 127.0.0.253` + nl + `inet 256.256.256.256` + nl),
|
||||
},
|
||||
},
|
||||
wantHas: assert.False,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
r := strings.NewReader(tc.rcconfData)
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, has, err := hostnameIfStaticConfig(r)
|
||||
substRootDirFS(t, tc.rootFsys)
|
||||
|
||||
has, err := IfaceHasStaticIP(ifaceName)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.wantHas, has)
|
||||
tc.wantHas(t, has)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,135 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
aghtest.DiscardLogOutput(m)
|
||||
}
|
||||
|
||||
// testdata is the filesystem containing data for testing the package.
|
||||
var testdata fs.FS = os.DirFS("./testdata")
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
aghtest.DiscardLogOutput(m)
|
||||
// substRootDirFS replaces the aghos.RootDirFS function used throughout the
|
||||
// package with fsys for tests ran under t.
|
||||
func substRootDirFS(t testing.TB, fsys fs.FS) {
|
||||
t.Helper()
|
||||
|
||||
prev := rootDirFS
|
||||
t.Cleanup(func() { rootDirFS = prev })
|
||||
rootDirFS = fsys
|
||||
}
|
||||
|
||||
// RunCmdFunc is the signature of aghos.RunCommand function.
|
||||
type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err error)
|
||||
|
||||
// substShell replaces the the aghos.RunCommand function used throughout the
|
||||
// package with rc for tests ran under t.
|
||||
func substShell(t testing.TB, rc RunCmdFunc) {
|
||||
t.Helper()
|
||||
|
||||
prev := aghosRunCommand
|
||||
t.Cleanup(func() { aghosRunCommand = prev })
|
||||
aghosRunCommand = rc
|
||||
}
|
||||
|
||||
// mapShell is a substitution of aghos.RunCommand that maps the command to it's
|
||||
// execution result. It's only needed to simplify testing.
|
||||
//
|
||||
// TODO(e.burkov): Perhaps put all the shell interactions behind an interface.
|
||||
type mapShell map[string]struct {
|
||||
err error
|
||||
out string
|
||||
code int
|
||||
}
|
||||
|
||||
// theOnlyCmd returns mapShell that only handles a single command and arguments
|
||||
// combination from cmd.
|
||||
func theOnlyCmd(cmd string, code int, out string, err error) (s mapShell) {
|
||||
return mapShell{cmd: {code: code, out: out, err: err}}
|
||||
}
|
||||
|
||||
// RunCmd is a RunCmdFunc handled by s.
|
||||
func (s mapShell) RunCmd(cmd string, args ...string) (code int, out []byte, err error) {
|
||||
key := strings.Join(append([]string{cmd}, args...), " ")
|
||||
ret, ok := s[key]
|
||||
if !ok {
|
||||
return 0, nil, fmt.Errorf("unexpected shell command %q", key)
|
||||
}
|
||||
|
||||
return ret.code, []byte(ret.out), ret.err
|
||||
}
|
||||
|
||||
// ifaceAddrsFunc is the signature of net.InterfaceAddrs function.
|
||||
type ifaceAddrsFunc func() (ifaces []net.Addr, err error)
|
||||
|
||||
// substNetInterfaceAddrs replaces the the net.InterfaceAddrs function used
|
||||
// throughout the package with f for tests ran under t.
|
||||
func substNetInterfaceAddrs(t *testing.T, f ifaceAddrsFunc) {
|
||||
t.Helper()
|
||||
|
||||
prev := netInterfaceAddrs
|
||||
t.Cleanup(func() { netInterfaceAddrs = prev })
|
||||
netInterfaceAddrs = f
|
||||
}
|
||||
|
||||
func TestGatewayIP(t *testing.T) {
|
||||
const ifaceName = "ifaceName"
|
||||
const cmd = "ip route show dev " + ifaceName
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
shell mapShell
|
||||
want net.IP
|
||||
}{{
|
||||
name: "success_v4",
|
||||
shell: theOnlyCmd(cmd, 0, `default via 1.2.3.4 onlink`, nil),
|
||||
want: net.IP{1, 2, 3, 4}.To16(),
|
||||
}, {
|
||||
name: "success_v6",
|
||||
shell: theOnlyCmd(cmd, 0, `default via ::ffff onlink`, nil),
|
||||
want: net.IP{
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0xFF, 0xFF,
|
||||
},
|
||||
}, {
|
||||
name: "bad_output",
|
||||
shell: theOnlyCmd(cmd, 0, `non-default via 1.2.3.4 onlink`, nil),
|
||||
want: nil,
|
||||
}, {
|
||||
name: "err_runcmd",
|
||||
shell: theOnlyCmd(cmd, 0, "", errors.Error("can't run command")),
|
||||
want: nil,
|
||||
}, {
|
||||
name: "bad_code",
|
||||
shell: theOnlyCmd(cmd, 1, "", nil),
|
||||
want: nil,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
substShell(t, tc.shell.RunCmd)
|
||||
|
||||
assert.Equal(t, tc.want, GatewayIP(ifaceName))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInterfaceByIP(t *testing.T) {
|
||||
@@ -130,3 +242,107 @@ func TestCheckPort(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCollectAllIfacesAddrs(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
wantErrMsg string
|
||||
addrs []net.Addr
|
||||
wantAddrs []string
|
||||
}{{
|
||||
name: "success",
|
||||
wantErrMsg: ``,
|
||||
addrs: []net.Addr{&net.IPNet{
|
||||
IP: net.IP{1, 2, 3, 4},
|
||||
Mask: net.CIDRMask(24, netutil.IPv4BitLen),
|
||||
}, &net.IPNet{
|
||||
IP: net.IP{4, 3, 2, 1},
|
||||
Mask: net.CIDRMask(16, netutil.IPv4BitLen),
|
||||
}},
|
||||
wantAddrs: []string{"1.2.3.4", "4.3.2.1"},
|
||||
}, {
|
||||
name: "not_cidr",
|
||||
wantErrMsg: `parsing cidr: invalid CIDR address: 1.2.3.4`,
|
||||
addrs: []net.Addr{&net.IPAddr{
|
||||
IP: net.IP{1, 2, 3, 4},
|
||||
}},
|
||||
wantAddrs: nil,
|
||||
}, {
|
||||
name: "empty",
|
||||
wantErrMsg: ``,
|
||||
addrs: []net.Addr{},
|
||||
wantAddrs: nil,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return tc.addrs, nil })
|
||||
|
||||
addrs, err := CollectAllIfacesAddrs()
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
|
||||
assert.Equal(t, tc.wantAddrs, addrs)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("internal_error", func(t *testing.T) {
|
||||
const errAddrs errors.Error = "can't get addresses"
|
||||
const wantErrMsg string = `getting interfaces addresses: ` + string(errAddrs)
|
||||
|
||||
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return nil, errAddrs })
|
||||
|
||||
_, err := CollectAllIfacesAddrs()
|
||||
testutil.AssertErrorMsg(t, wantErrMsg, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsAddrInUse(t *testing.T) {
|
||||
t.Run("addr_in_use", func(t *testing.T) {
|
||||
l, err := net.Listen("tcp", "0.0.0.0:0")
|
||||
require.NoError(t, err)
|
||||
testutil.CleanupAndRequireSuccess(t, l.Close)
|
||||
|
||||
_, err = net.Listen(l.Addr().Network(), l.Addr().String())
|
||||
assert.True(t, IsAddrInUse(err))
|
||||
})
|
||||
|
||||
t.Run("another", func(t *testing.T) {
|
||||
const anotherErr errors.Error = "not addr in use"
|
||||
|
||||
assert.False(t, IsAddrInUse(anotherErr))
|
||||
})
|
||||
}
|
||||
|
||||
func TestNetInterface_MarshalJSON(t *testing.T) {
|
||||
const want = `{` +
|
||||
`"hardware_address":"aa:bb:cc:dd:ee:ff",` +
|
||||
`"flags":"up|multicast",` +
|
||||
`"ip_addresses":["1.2.3.4","aaaa::1"],` +
|
||||
`"name":"iface0",` +
|
||||
`"mtu":1500` +
|
||||
`}` + "\n"
|
||||
|
||||
ip4, ip6 := net.IP{1, 2, 3, 4}, net.IP{0xAA, 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||
mask4, mask6 := net.CIDRMask(24, netutil.IPv4BitLen), net.CIDRMask(8, netutil.IPv6BitLen)
|
||||
|
||||
iface := &NetInterface{
|
||||
Addresses: []net.IP{ip4, ip6},
|
||||
Subnets: []*net.IPNet{{
|
||||
IP: ip4.Mask(mask4),
|
||||
Mask: mask4,
|
||||
}, {
|
||||
IP: ip6.Mask(mask6),
|
||||
Mask: mask6,
|
||||
}},
|
||||
Name: "iface0",
|
||||
HardwareAddr: net.HardwareAddr{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
|
||||
Flags: net.FlagUp | net.FlagMulticast,
|
||||
MTU: 1500,
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
err := json.NewEncoder(b).Encode(iface)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, want, b.String())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build !(linux || darwin || freebsd || openbsd)
|
||||
// +build !linux,!darwin,!freebsd,!openbsd
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package aghnet
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func canBindPrivilegedPorts() (can bool, err error) {
|
||||
return aghos.HaveAdminRights()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func ifaceHasStaticIP(string) (ok bool, err error) {
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
// DefaultRefreshIvl is the default period of time between refreshing cached
|
||||
// addresses.
|
||||
// const DefaultRefreshIvl = 5 * time.Minute
|
||||
@@ -16,39 +10,21 @@ type HostGenFunc func() (host string)
|
||||
|
||||
// SystemResolvers helps to work with local resolvers' addresses provided by OS.
|
||||
type SystemResolvers interface {
|
||||
// Get returns the slice of local resolvers' addresses. It should be
|
||||
// safe for concurrent use.
|
||||
// Get returns the slice of local resolvers' addresses. It must be safe for
|
||||
// concurrent use.
|
||||
Get() (rs []string)
|
||||
// refresh refreshes the local resolvers' addresses cache. It should be
|
||||
// safe for concurrent use.
|
||||
// refresh refreshes the local resolvers' addresses cache. It must be safe
|
||||
// for concurrent use.
|
||||
refresh() (err error)
|
||||
}
|
||||
|
||||
// refreshWithTicker refreshes the cache of sr after each tick form tickCh.
|
||||
func refreshWithTicker(sr SystemResolvers, tickCh <-chan time.Time) {
|
||||
defer log.OnPanic("systemResolvers")
|
||||
|
||||
// TODO(e.burkov): Implement a functionality to stop ticker.
|
||||
for range tickCh {
|
||||
err := sr.refresh()
|
||||
if err != nil {
|
||||
log.Error("systemResolvers: error in refreshing goroutine: %s", err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("systemResolvers: local addresses cache is refreshed")
|
||||
}
|
||||
}
|
||||
|
||||
// NewSystemResolvers returns a SystemResolvers with the cache refresh rate
|
||||
// defined by refreshIvl. It disables auto-resfreshing if refreshIvl is 0. If
|
||||
// defined by refreshIvl. It disables auto-refreshing if refreshIvl is 0. If
|
||||
// nil is passed for hostGenFunc, the default generator will be used.
|
||||
func NewSystemResolvers(
|
||||
refreshIvl time.Duration,
|
||||
hostGenFunc HostGenFunc,
|
||||
) (sr SystemResolvers, err error) {
|
||||
sr = newSystemResolvers(refreshIvl, hostGenFunc)
|
||||
sr = newSystemResolvers(hostGenFunc)
|
||||
|
||||
// Fill cache.
|
||||
err = sr.refresh()
|
||||
@@ -56,11 +32,5 @@ func NewSystemResolvers(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if refreshIvl > 0 {
|
||||
ticker := time.NewTicker(refreshIvl)
|
||||
|
||||
go refreshWithTicker(sr, ticker.C)
|
||||
}
|
||||
|
||||
return sr, nil
|
||||
}
|
||||
|
||||
@@ -24,12 +24,15 @@ func defaultHostGen() (host string) {
|
||||
|
||||
// systemResolvers is a default implementation of SystemResolvers interface.
|
||||
type systemResolvers struct {
|
||||
resolver *net.Resolver
|
||||
hostGenFunc HostGenFunc
|
||||
|
||||
// addrs is the set that contains cached local resolvers' addresses.
|
||||
addrs *stringutil.Set
|
||||
// addrsLock protects addrs.
|
||||
addrsLock sync.RWMutex
|
||||
// addrs is the set that contains cached local resolvers' addresses.
|
||||
addrs *stringutil.Set
|
||||
|
||||
// resolver is used to fetch the resolvers' addresses.
|
||||
resolver *net.Resolver
|
||||
// hostGenFunc generates hosts to resolve.
|
||||
hostGenFunc HostGenFunc
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -44,6 +47,7 @@ const (
|
||||
errUnexpectedHostFormat errors.Error = "unexpected host format"
|
||||
)
|
||||
|
||||
// refresh implements the SystemResolvers interface for *systemResolvers.
|
||||
func (sr *systemResolvers) refresh() (err error) {
|
||||
defer func() { err = errors.Annotate(err, "systemResolvers: %w") }()
|
||||
|
||||
@@ -56,7 +60,7 @@ func (sr *systemResolvers) refresh() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr SystemResolvers) {
|
||||
func newSystemResolvers(hostGenFunc HostGenFunc) (sr SystemResolvers) {
|
||||
if hostGenFunc == nil {
|
||||
hostGenFunc = defaultHostGen
|
||||
}
|
||||
@@ -76,19 +80,18 @@ func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr S
|
||||
func validateDialedHost(host string) (err error) {
|
||||
defer func() { err = errors.Annotate(err, "parsing %q: %w", host) }()
|
||||
|
||||
var ipStr string
|
||||
parts := strings.Split(host, "%")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
ipStr = host
|
||||
// host
|
||||
case 2:
|
||||
// Remove the zone and check the IP address part.
|
||||
ipStr = parts[0]
|
||||
host = parts[0]
|
||||
default:
|
||||
return errUnexpectedHostFormat
|
||||
}
|
||||
|
||||
if net.ParseIP(ipStr) == nil {
|
||||
if _, err = netutil.ParseIP(host); err != nil {
|
||||
return errBadAddrPassed
|
||||
}
|
||||
|
||||
|
||||
@@ -6,37 +6,32 @@ package aghnet
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func createTestSystemResolversImp(
|
||||
func createTestSystemResolversImpl(
|
||||
t *testing.T,
|
||||
refreshDur time.Duration,
|
||||
hostGenFunc HostGenFunc,
|
||||
) (imp *systemResolvers) {
|
||||
t.Helper()
|
||||
|
||||
sr := createTestSystemResolvers(t, refreshDur, hostGenFunc)
|
||||
sr := createTestSystemResolvers(t, hostGenFunc)
|
||||
require.IsType(t, (*systemResolvers)(nil), sr)
|
||||
|
||||
var ok bool
|
||||
imp, ok = sr.(*systemResolvers)
|
||||
require.True(t, ok)
|
||||
|
||||
return imp
|
||||
return sr.(*systemResolvers)
|
||||
}
|
||||
|
||||
func TestSystemResolvers_Refresh(t *testing.T) {
|
||||
t.Run("expected_error", func(t *testing.T) {
|
||||
sr := createTestSystemResolvers(t, 0, nil)
|
||||
sr := createTestSystemResolvers(t, nil)
|
||||
|
||||
assert.NoError(t, sr.refresh())
|
||||
})
|
||||
|
||||
t.Run("unexpected_error", func(t *testing.T) {
|
||||
_, err := NewSystemResolvers(0, func() string {
|
||||
_, err := NewSystemResolvers(func() string {
|
||||
return "127.0.0.1::123"
|
||||
})
|
||||
assert.Error(t, err)
|
||||
@@ -44,7 +39,7 @@ func TestSystemResolvers_Refresh(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSystemResolvers_DialFunc(t *testing.T) {
|
||||
imp := createTestSystemResolversImp(t, 0, nil)
|
||||
imp := createTestSystemResolversImpl(t, nil)
|
||||
|
||||
testCases := []struct {
|
||||
want error
|
||||
@@ -52,7 +47,7 @@ func TestSystemResolvers_DialFunc(t *testing.T) {
|
||||
address string
|
||||
}{{
|
||||
want: errFakeDial,
|
||||
name: "valid",
|
||||
name: "valid_ipv4",
|
||||
address: "127.0.0.1",
|
||||
}, {
|
||||
want: errFakeDial,
|
||||
|
||||
@@ -2,7 +2,6 @@ package aghnet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -10,13 +9,12 @@ import (
|
||||
|
||||
func createTestSystemResolvers(
|
||||
t *testing.T,
|
||||
refreshDur time.Duration,
|
||||
hostGenFunc HostGenFunc,
|
||||
) (sr SystemResolvers) {
|
||||
t.Helper()
|
||||
|
||||
var err error
|
||||
sr, err = NewSystemResolvers(refreshDur, hostGenFunc)
|
||||
sr, err = NewSystemResolvers(hostGenFunc)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, sr)
|
||||
|
||||
@@ -24,8 +22,14 @@ func createTestSystemResolvers(
|
||||
}
|
||||
|
||||
func TestSystemResolvers_Get(t *testing.T) {
|
||||
sr := createTestSystemResolvers(t, 0, nil)
|
||||
assert.NotEmpty(t, sr.Get())
|
||||
sr := createTestSystemResolvers(t, nil)
|
||||
|
||||
var rs []string
|
||||
require.NotPanics(t, func() {
|
||||
rs = sr.Get()
|
||||
})
|
||||
|
||||
assert.NotEmpty(t, rs)
|
||||
}
|
||||
|
||||
// TODO(e.burkov): Write tests for refreshWithTicker.
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
@@ -27,7 +26,7 @@ type systemResolvers struct {
|
||||
addrsLock sync.RWMutex
|
||||
}
|
||||
|
||||
func newSystemResolvers(refreshIvl time.Duration, _ HostGenFunc) (sr SystemResolvers) {
|
||||
func newSystemResolvers(_ HostGenFunc) (sr SystemResolvers) {
|
||||
return &systemResolvers{}
|
||||
}
|
||||
|
||||
|
||||
4
internal/aghnet/testdata/proc_net_arp
vendored
4
internal/aghnet/testdata/proc_net_arp
vendored
@@ -1,4 +1,6 @@
|
||||
IP address HW type Flags HW address Mask Device
|
||||
192.168.1.2 0x1 0x2 ab:cd:ef:ab:cd:ef * wan
|
||||
::ffff:ffff 0x1 0x0 ef:cd:ab:ef:cd:ab * br-lan
|
||||
0.0.0.0 0x0 0x0 00:00:00:00:00:00 * unspec
|
||||
0.0.0.0 0x0 0x0 00:00:00:00:00:00 * unspec
|
||||
1.2.3.4.5 0x1 0x2 aa:bb:cc:dd:ee:ff * wan
|
||||
1.2.3.4 0x1 0x2 12:34:56:78:910 * wan
|
||||
@@ -57,20 +57,22 @@ func HaveAdminRights() (bool, error) {
|
||||
const MaxCmdOutputSize = 64 * 1024
|
||||
|
||||
// RunCommand runs shell command.
|
||||
func RunCommand(command string, arguments ...string) (code int, output string, err error) {
|
||||
func RunCommand(command string, arguments ...string) (code int, output []byte, err error) {
|
||||
cmd := exec.Command(command, arguments...)
|
||||
out, err := cmd.Output()
|
||||
if len(out) > MaxCmdOutputSize {
|
||||
out = out[:MaxCmdOutputSize]
|
||||
}
|
||||
|
||||
if errors.As(err, new(*exec.ExitError)) {
|
||||
return cmd.ProcessState.ExitCode(), string(out), nil
|
||||
} else if err != nil {
|
||||
return 1, "", fmt.Errorf("command %q failed: %w: %s", command, err, out)
|
||||
if err != nil {
|
||||
if eerr := new(exec.ExitError); errors.As(err, &eerr) {
|
||||
return eerr.ExitCode(), eerr.Stderr, nil
|
||||
}
|
||||
|
||||
return 1, nil, fmt.Errorf("command %q failed: %w: %s", command, err, out)
|
||||
}
|
||||
|
||||
return cmd.ProcessState.ExitCode(), string(out), nil
|
||||
return cmd.ProcessState.ExitCode(), out, nil
|
||||
}
|
||||
|
||||
// PIDByCommand searches for process named command and returns its PID ignoring
|
||||
@@ -173,3 +175,13 @@ func RootDirFS() (fsys fs.FS) {
|
||||
// behavior is undocumented but it currently works.
|
||||
return os.DirFS("")
|
||||
}
|
||||
|
||||
// NotifyShutdownSignal notifies c on receiving shutdown signals.
|
||||
func NotifyShutdownSignal(c chan<- os.Signal) {
|
||||
notifyShutdownSignal(c)
|
||||
}
|
||||
|
||||
// IsShutdownSignal returns true if sig is a shutdown signal.
|
||||
func IsShutdownSignal(sig os.Signal) (ok bool) {
|
||||
return isShutdownSignal(sig)
|
||||
}
|
||||
|
||||
27
internal/aghos/os_unix.go
Normal file
27
internal/aghos/os_unix.go
Normal file
@@ -0,0 +1,27 @@
|
||||
//go:build darwin || freebsd || linux || openbsd
|
||||
// +build darwin freebsd linux openbsd
|
||||
|
||||
package aghos
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func notifyShutdownSignal(c chan<- os.Signal) {
|
||||
signal.Notify(c, unix.SIGINT, unix.SIGQUIT, unix.SIGTERM)
|
||||
}
|
||||
|
||||
func isShutdownSignal(sig os.Signal) (ok bool) {
|
||||
switch sig {
|
||||
case
|
||||
unix.SIGINT,
|
||||
unix.SIGQUIT,
|
||||
unix.SIGTERM:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,10 @@
|
||||
package aghos
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
@@ -35,3 +39,20 @@ func haveAdminRights() (bool, error) {
|
||||
func isOpenWrt() (ok bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
func notifyShutdownSignal(c chan<- os.Signal) {
|
||||
// syscall.SIGTERM is processed automatically. See go doc os/signal,
|
||||
// section Windows.
|
||||
signal.Notify(c, os.Interrupt)
|
||||
}
|
||||
|
||||
func isShutdownSignal(sig os.Signal) (ok bool) {
|
||||
switch sig {
|
||||
case
|
||||
os.Interrupt,
|
||||
syscall.SIGTERM:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// Package aghtls contains utilities for work with TLS.
|
||||
package aghtls
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// SaferCipherSuites returns a set of default cipher suites with vulnerable and
|
||||
// weak cipher suites removed.
|
||||
func SaferCipherSuites() (safe []uint16) {
|
||||
for _, s := range tls.CipherSuites() {
|
||||
switch s.ID {
|
||||
case
|
||||
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
|
||||
// Less safe 3DES and CBC suites, go on.
|
||||
default:
|
||||
safe = append(safe, s.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return safe
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
@@ -145,7 +146,7 @@ type dhcpServerConfigJSON struct {
|
||||
V4 *v4ServerConfJSON `json:"v4"`
|
||||
V6 *v6ServerConfJSON `json:"v6"`
|
||||
InterfaceName string `json:"interface_name"`
|
||||
Enabled nullBool `json:"enabled"`
|
||||
Enabled aghalg.NullBool `json:"enabled"`
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPSetConfigV4(
|
||||
@@ -156,7 +157,7 @@ func (s *Server) handleDHCPSetConfigV4(
|
||||
}
|
||||
|
||||
v4Conf := v4JSONToServerConf(conf.V4)
|
||||
v4Conf.Enabled = conf.Enabled == nbTrue
|
||||
v4Conf.Enabled = conf.Enabled == aghalg.NBTrue
|
||||
if len(v4Conf.RangeStart) == 0 {
|
||||
v4Conf.Enabled = false
|
||||
}
|
||||
@@ -183,7 +184,7 @@ func (s *Server) handleDHCPSetConfigV6(
|
||||
}
|
||||
|
||||
v6Conf := v6JSONToServerConf(conf.V6)
|
||||
v6Conf.Enabled = conf.Enabled == nbTrue
|
||||
v6Conf.Enabled = conf.Enabled == aghalg.NBTrue
|
||||
if len(v6Conf.RangeStart) == 0 {
|
||||
v6Conf.Enabled = false
|
||||
}
|
||||
@@ -206,7 +207,7 @@ func (s *Server) handleDHCPSetConfigV6(
|
||||
|
||||
func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
conf := &dhcpServerConfigJSON{}
|
||||
conf.Enabled = boolToNullBool(s.conf.Enabled)
|
||||
conf.Enabled = aghalg.BoolToNullBool(s.conf.Enabled)
|
||||
conf.InterfaceName = s.conf.InterfaceName
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(conf)
|
||||
@@ -230,7 +231,7 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if conf.Enabled == nbTrue && !v4Enabled && !v6Enabled {
|
||||
if conf.Enabled == aghalg.NBTrue && !v4Enabled && !v6Enabled {
|
||||
aghhttp.Error(r, w, http.StatusBadRequest, "dhcpv4 or dhcpv6 configuration must be complete")
|
||||
|
||||
return
|
||||
@@ -243,8 +244,8 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if conf.Enabled != nbNull {
|
||||
s.conf.Enabled = conf.Enabled == nbTrue
|
||||
if conf.Enabled != aghalg.NBNull {
|
||||
s.conf.Enabled = conf.Enabled == aghalg.NBTrue
|
||||
}
|
||||
|
||||
if conf.InterfaceName != "" {
|
||||
@@ -279,11 +280,11 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
type netInterfaceJSON struct {
|
||||
Name string `json:"name"`
|
||||
GatewayIP net.IP `json:"gateway_ip"`
|
||||
HardwareAddr string `json:"hardware_address"`
|
||||
Flags string `json:"flags"`
|
||||
GatewayIP net.IP `json:"gateway_ip"`
|
||||
Addrs4 []net.IP `json:"ipv4_addresses"`
|
||||
Addrs6 []net.IP `json:"ipv6_addresses"`
|
||||
Flags string `json:"flags"`
|
||||
}
|
||||
|
||||
func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -497,7 +498,6 @@ func (s *Server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
ip4 := l.IP.To4()
|
||||
|
||||
if ip4 == nil {
|
||||
l.IP = l.IP.To16()
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package dhcpd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// nullBool is a nullable boolean. Use these in JSON requests and responses
|
||||
// instead of pointers to bool.
|
||||
//
|
||||
// TODO(a.garipov): Inspect uses of *bool, move this type into some new package
|
||||
// if we need it somewhere else.
|
||||
type nullBool uint8
|
||||
|
||||
// nullBool values
|
||||
const (
|
||||
nbNull nullBool = iota
|
||||
nbTrue
|
||||
nbFalse
|
||||
)
|
||||
|
||||
// String implements the fmt.Stringer interface for nullBool.
|
||||
func (nb nullBool) String() (s string) {
|
||||
switch nb {
|
||||
case nbNull:
|
||||
return "null"
|
||||
case nbTrue:
|
||||
return "true"
|
||||
case nbFalse:
|
||||
return "false"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("!invalid nullBool %d", uint8(nb))
|
||||
}
|
||||
|
||||
// boolToNullBool converts a bool into a nullBool.
|
||||
func boolToNullBool(cond bool) (nb nullBool) {
|
||||
if cond {
|
||||
return nbTrue
|
||||
}
|
||||
|
||||
return nbFalse
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for *nullBool.
|
||||
func (nb *nullBool) UnmarshalJSON(b []byte) (err error) {
|
||||
if len(b) == 0 || bytes.Equal(b, []byte("null")) {
|
||||
*nb = nbNull
|
||||
} else if bytes.Equal(b, []byte("true")) {
|
||||
*nb = nbTrue
|
||||
} else if bytes.Equal(b, []byte("false")) {
|
||||
*nb = nbFalse
|
||||
} else {
|
||||
return fmt.Errorf("invalid nullBool value %q", b)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user