Compare commits

...

27 Commits

Author SHA1 Message Date
Ainar Garipov
c14bde280e Pull request: client: upd i18n
Merge in DNS/adguard-home from 2643-upd-i18n to master

Squashed commit of the following:

commit 12f4de7608c7a2335a137859301ff3a51e239596
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 3 13:32:37 2021 +0300

    client: fix punct in fr

commit 01369e0985ffd0f8780e514f9af614909d3ecdb4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 3 13:27:02 2021 +0300

    client: fix punct in de, fr

commit d06ea8fe2d2ca4f50e8721d9edb0a895062ac0a0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 3 13:07:57 2021 +0300

    client: upd i18n
2021-08-03 13:40:21 +03:00
Ainar Garipov
fb6bc322c1 Pull request: all: do not refuse reqs from untrusted proxies
Updates #2799.

Squashed commit of the following:

commit bc768fdd48b563017520f962480be4b2be90666a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Aug 2 15:00:10 2021 +0300

    all: do not refuse reqs from untrusted proxies
2021-08-02 15:11:00 +03:00
Ainar Garipov
12db98230c Pull request: client: imp setup guide i18n
Merge in DNS/adguard-home from imp-i18n to master

Squashed commit of the following:

commit a109d8fd8a32ab20106d1df61ab945bb139c12e4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 30 16:01:09 2021 +0300

    client: imp setup guide i18n
2021-07-30 16:09:12 +03:00
Eugene Burkov
6fa1167251 Pull request: 3289 freebsd dhcp
Merge in DNS/adguard-home from 3289-freebsd-dhcp to master

Updates #3289.

Squashed commit of the following:

commit 1365d8f17293da611b860525d519a7bbd7851902
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Jul 30 15:01:13 2021 +0300

    dhcpd: fix doc

commit 26724df27e92d457c39c8bf0fb78179a874e3fb2
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Jul 30 14:52:58 2021 +0300

    all: imp code & docs

commit 9a9574a885d3d2129ef54fefb9a56857ce060cff
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 29 15:51:07 2021 +0300

    all: fix broadcasting, sup freebsd dhcp, fix http response
2021-07-30 15:27:24 +03:00
Ainar Garipov
63ee95dfbe Pull request: all: replace aghstrings with stringutil
Merge in DNS/adguard-home from add-stringutil to master

Squashed commit of the following:

commit 4ca9b29356de7d0a162b1e5a6496c691e9751f15
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 29 17:29:25 2021 +0300

    all: replace aghstrings with stringutil
2021-07-29 17:40:31 +03:00
Ainar Garipov
0030e31e33 Pull request: all: add links to new guidelines
Merge in DNS/adguard-home from mv-hacking to master

Squashed commit of the following:

commit b4782bc2482c33dbf749f2249295fb0cb05f82e6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 28 13:40:27 2021 +0300

    all: add links to new guidelines
2021-07-28 14:17:11 +03:00
Eugene Burkov
fc063f580f Pull request: 3372 dnscrypt querylog
Merge in DNS/adguard-home from 3372-dnscrypt-logs to master

Updates #3372.

Squashed commit of the following:

commit 603383227540e1e62911c66d3c0440187d6a313c
Merge: c0379e2b f2046a5f
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jul 27 19:05:18 2021 +0300

    Merge branch 'master' into 3372-dnscrypt-logs

commit c0379e2bb53376efaf0a222e5be9a232821059c6
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jul 27 18:58:07 2021 +0300

    all: fix log of changes

commit 7ba9dba530684f00f17e8cafbd6a7f5ccde8579c
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jul 27 18:54:05 2021 +0300

    all: log changes

commit dbf107642bb39df63b45bd2844e10e3d682e3455
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jul 27 18:09:51 2021 +0300

    all: upd dnscrypt
2021-07-27 19:22:25 +03:00
Ainar Garipov
f2046a5f06 Pull request: scripts: imp docs and ports
Merge in DNS/adguard-home from dockerfile-ports to master

Squashed commit of the following:

commit ece0295105ee4429be68a72724da457dd1e87f7f
Merge: 3c5ae853 2f661df8
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 27 12:31:04 2021 +0300

    Merge branch 'master' into dockerfile-ports

commit 3c5ae8538b1463c21e91289adc27ceac9012e04e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 26 20:56:45 2021 +0300

    scripts: imp docs and ports
2021-07-27 13:12:26 +03:00
Eugene Burkov
2f661df88c Pull request: 2799 trusted proxy
Merge in DNS/adguard-home from 2799-trusted-proxy to master

Updates #2799.

Squashed commit of the following:

commit 708a06b30116126a575767ea70865a6de90de774
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Fri Jul 23 18:56:16 2021 +0300

    all: add trusted proxy mechanism
2021-07-26 19:30:35 +03:00
Ainar Garipov
8e8f14aefb Pull request: dnsforward: reply with appropriate block resp
Merge in DNS/adguard-home from access-proto-resp to master

Squashed commit of the following:

commit 9e78c002b31990d695c8dbd4561a3304a1827e3d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 20 13:16:44 2021 +0300

    dnsforward: reply with appropriate block resp
2021-07-20 14:45:08 +03:00
Ainar Garipov
0217c6ad11 Pull request: client: upd i18n
Merge in DNS/adguard-home from 2643-upd-i18n to master

Squashed commit of the following:

commit 328847d67d1be5632777dd146b4110d5ab1d57d4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 20 13:18:58 2021 +0300

    client: upd i18n more

commit b9856dbd013056aa690f7a5ca116a194d218554d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 20 12:52:33 2021 +0300

    client: upd i18n
2021-07-20 13:22:48 +03:00
Ainar Garipov
5e2a59dbb8 Pull request: scripts: do not use ls -q
Updates #3361.

Squashed commit of the following:

commit 97c13c506c4215ef55550527c8db425db85a9977
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 20 12:31:29 2021 +0300

    scripts: do not use ls -q
2021-07-20 12:41:33 +03:00
Ainar Garipov
5292c7c387 Pull request: openapi: upd version
Closes #3364.

Squashed commit of the following:

commit 840c20c87ccd64a83010718c68d65adcb390134d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 20 12:24:06 2021 +0300

    openapi: upd version
2021-07-20 12:31:52 +03:00
Ainar Garipov
b9e85695db Pull request: 2145 optimistic cache
Updates #2145.

Squashed commit of the following:

commit 0c15347f4573252849817f27f290c0d45381454c
Merge: 98bd3b89 ebade2b6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 14 20:44:58 2021 +0300

    Merge branch 'master' into 2145-optimistic-cache

commit 98bd3b895e0d881d5234f674b54f9fa7847dc8f0
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jul 14 13:12:56 2021 +0300

    client: handle optimistic cache

commit 0b469b72ffd43d736dbf139e7d47b23b9fa877c5
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 19:01:01 2021 +0300

    openapi: fix log of changes

commit f1594e7f7567e0278b08025a8e4da901ef330602
Merge: a034eb98 e113b276
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 18:53:01 2021 +0300

    Merge branch 'master' into 2145-optimistic-cache

commit a034eb98bafdca90befad7dfb6a9b0e4c939c879
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 18:45:28 2021 +0300

    dnsforward: fix tests

commit c72227f83c849714721c3512beeb9d1b800a7225
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 18:33:12 2021 +0300

    openapi: imp docs

commit 35fe0d2a8c98d007b8ac48653c18d10d52e72dce
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Mon Jun 28 14:19:46 2021 +0300

    dnsforward: add optimistic cache
2021-07-14 21:03:56 +03:00
Ildar Kamalov
ebade2b6ce Pull request: 3313 statistics settings UI
Closes #3313

Squashed commit of the following:

commit 6f2ff98a8282789e2dbb16694ca87a1f4cc8c076
Merge: 1221f02f f4dde3f2
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 14 15:53:18 2021 +0300

    Merge branch 'master' into 3313-statistics

commit 1221f02f40628964febd22967d85d5185f87b08d
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jul 14 15:23:09 2021 +0300

    client: make client names clickable

commit 99770ec065e14ce2522a59820f9851d79001923c
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jul 14 15:06:30 2021 +0300

    client: decreasing interval confirm, disabled stats message
2021-07-14 16:01:12 +03:00
Ildar Kamalov
f4dde3f2c1 3312 update search input on client select
Closes #3312

Squashed commit of the following:

commit 00919b2375ba2ad2662758e37e87a9d4db5ec613
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jul 14 14:16:09 2021 +0300

    client: update search input on client select
2021-07-14 14:39:11 +03:00
Ainar Garipov
4684c8e4ed Pull request: bamboo-specs: upd go
Merge in DNS/adguard-home from upd-go to master

Squashed commit of the following:

commit b7f0f61d9c8b0eef753ee24c18a477299a455e94
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 14 12:04:59 2021 +0300

    bamboo-specs: upd go
2021-07-14 12:43:11 +03:00
Ainar Garipov
167447547a Pull request: filtering: fix legacy rewrite domain case
Updates #3351.

Squashed commit of the following:

commit cc1c72cc13026ed703bb140e55dc3eb886846e48
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 13 17:23:33 2021 +0300

    filtering: fix legacy rewrite domain case
2021-07-13 19:45:25 +03:00
Ainar Garipov
ff4905b2a2 Pull request: aghnet: fix impap iteration
Updates #3346.

Squashed commit of the following:

commit d244cd1cc43a8c8e25b51d1117fa6fca1f4dcb18
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 12 21:52:39 2021 +0300

    aghnet: fix impap iteration
2021-07-13 14:07:45 +03:00
Ainar Garipov
194ea6ef95 Pull request: filtering: fix legacy rewrite wildcards
Updates #3343.

Squashed commit of the following:

commit ab3c3e002a6d2a11bc3207fdaaeb292aaa194907
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 12 20:58:57 2021 +0300

    filtering: fix legacy rewrite wildcards
2021-07-12 21:10:39 +03:00
Ainar Garipov
f419896ec6 Pull request: filtering: fix letter case in cname matching
Updates #3335.

Squashed commit of the following:

commit ff55c112417199e4b04098a32c5f4805b59356f9
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 12 12:38:46 2021 +0300

    filtering: fix letter case in cname matching
2021-07-12 13:10:47 +03:00
Ainar Garipov
1a693f790b Pull request: client: upd i18n
Merge in DNS/adguard-home from 2643-upd-i18n to master

Squashed commit of the following:

commit e965f59e87ca4ac3da69bac6a1d0526d091ea02a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 7 13:30:43 2021 +0300

    client: upd i18n
2021-07-07 13:44:53 +03:00
Ainar Garipov
1571609e59 Pull request #1238: dnsforward: fix panic
Updates #3318.

Squashed commit of the following:

commit eebaa3ac3a6bfcb29e280006ead8ea9554b8a3bf
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 6 14:59:00 2021 +0300

    dnsforward: imp code

commit 7591a3b183ab95f27f908267321518740cb7d4bb
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 6 14:55:33 2021 +0300

    dnsforward: fix panic
2021-07-06 15:08:55 +03:00
Ainar Garipov
4b5a66ee61 Pull request #1237: all: upd dnsproxy
Updates #3315.

Squashed commit of the following:

commit f91b979b4b9eb8141e7320a54992786a699aa437
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 6 13:48:29 2021 +0300

    all: upd dnsproxy
2021-07-06 14:12:57 +03:00
Eugene Burkov
e113b276e7 Pull request: 2504 querylog interval
Merge in DNS/adguard-home from 2504-querylog-ivl to master

Updates #2504.

Squashed commit of the following:

commit 5d15a6f735cd195fc81c8af909b56fbc7db1fe21
Merge: 8cd5c30d 97073d0d
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 18:45:10 2021 +0300

    Merge branch 'master' into 2504-querylog-ivl

commit 8cd5c30de6f72d4b12162dbc9e3d90132795fe94
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 18:35:50 2021 +0300

    client: fix fmt

commit e95d462c31d886bacec0735acc567fec7c962149
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 17:58:06 2021 +0300

    home: imp code

commit 48737b249c52a997a4f34dac45fbaf699477b007
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 17:23:18 2021 +0300

    home: imp duration

commit 44f5dc3d3ada5120d74caa24cace9a253b8f15d3
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 16:55:31 2021 +0300

    home: imp code, docs

commit bb2826521b7e5d248ce2ab686528219c312b8ba2
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 16:11:40 2021 +0300

    all: imp code, docs

commit d688aed1f340807a8bac8807c263956b0fc16f5b
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Thu Jul 1 13:49:42 2021 +0300

    all: change querylog interval setting format
2021-07-01 18:50:28 +03:00
Ainar Garipov
97073d0d9e Pull request: all: fix typos in chlog
Merge in DNS/adguard-home from imp-changelog to master

Squashed commit of the following:

commit 4a1ed06b77d4aa39c59e1b83fb019709a4362088
Merge: e1352bea 116bedd7
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 30 14:04:50 2021 +0300

    Merge branch 'master' into imp-changelog

commit e1352bea546211a5dd84890c51f32bdf69174850
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 30 13:59:46 2021 +0300

    all: fix typos in chlog
2021-06-30 14:10:06 +03:00
Eugene Burkov
116bedd727 Pull request: 3012 idna search
Merge in DNS/adguard-home from 3012-idna-search to master

Closes #3012.

Squashed commit of the following:

commit 6a9fbfe16860df5db5982a70cfbf040967b6e6ae
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 21:28:10 2021 +0300

    querylog: add todo

commit 31292ba1aeb9e91ff4f6abae7ffdf806a87cae66
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 21:21:46 2021 +0300

    querylog: imp docs, code

commit 35757f76837cb8034f6079a351d01aa4706bfea7
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 21:01:08 2021 +0300

    queerylog: fix idn case match

commit eecfc98b6449c5c7c5a23602e80e47002034bc25
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 20:32:00 2021 +0300

    querylog: imp code, docs

commit 8aa6242fe92a9c2daa674b976595b13be96b0cf7
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Tue Jun 29 20:00:54 2021 +0300

    querylog: sup idn search
2021-06-30 11:04:48 +03:00
96 changed files with 1704 additions and 1551 deletions

View File

@@ -10,11 +10,14 @@ and this project adheres to
## [Unreleased]
<!--
## [v0.107.0] - 2021-06-28 (APPROX.)
## [v0.107.0] - 2021-08-03 (APPROX.)
-->
### Added
- Static IP address detection on FreeBSD ([#3289]).
- Optimistic cache ([#2145]).
- New possible value of `6h` for `querylog_interval` setting ([#2504]).
- Blocking access using client IDs ([#2624], [#3162]).
- `source` directives support in `/etc/network/interfaces` on Linux ([#3257]).
- RFC 9000 support in DNS-over-QUIC.
@@ -35,13 +38,20 @@ and this project adheres to
([#3185]).
- The ability to completely disable reverse DNS resolving of IPs from
locally-served networks ([#3184]).
- New flag `--local-frontend` to serve dinamically changeable frontend files
- New flag `--local-frontend` to serve dynamically changeable frontend files
from disk as opposed to the ones that were compiled into the binary.
### Changed
- DNS-over-HTTPS queries that come from HTTP proxies in the `trusted_proxies`
list now use the real IP address of the client instead of the address of the
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.
- 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]).
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
@@ -50,15 +60,16 @@ and this project adheres to
### Deprecated
<!--
TODO(a.garipov): Remove the Go 1.16 deprecation message if Go 1.17 is not
released by then.
-->
- Go 1.16 support. v0.108.0 will require at least Go 1.17 to build.
### Fixed
- Incomplete HTTP response for static IP address.
- DNSCrypt queries weren't appearing in query log ([#3372]).
- Wrong IP address for proxied DNS-over-HTTPS queries ([#2799]).
- Domain name letter case mismatches in DNS rewrites ([#3351]).
- Conflicts between IPv4 and IPv6 DNS rewrites ([#3343]).
- 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
@@ -77,12 +88,16 @@ released by then.
[#1381]: https://github.com/AdguardTeam/AdGuardHome/issues/1381
[#1691]: https://github.com/AdguardTeam/AdGuardHome/issues/1691
[#2141]: https://github.com/AdguardTeam/AdGuardHome/issues/2141
[#2145]: https://github.com/AdguardTeam/AdGuardHome/issues/2145
[#2280]: https://github.com/AdguardTeam/AdGuardHome/issues/2280
[#2439]: https://github.com/AdguardTeam/AdGuardHome/issues/2439
[#2441]: https://github.com/AdguardTeam/AdGuardHome/issues/2441
[#2443]: https://github.com/AdguardTeam/AdGuardHome/issues/2443
[#2504]: https://github.com/AdguardTeam/AdGuardHome/issues/2504
[#2624]: https://github.com/AdguardTeam/AdGuardHome/issues/2624
[#2763]: https://github.com/AdguardTeam/AdGuardHome/issues/2763
[#2799]: https://github.com/AdguardTeam/AdGuardHome/issues/2799
[#3012]: https://github.com/AdguardTeam/AdGuardHome/issues/3012
[#3013]: https://github.com/AdguardTeam/AdGuardHome/issues/3013
[#3136]: https://github.com/AdguardTeam/AdGuardHome/issues/3136
[#3162]: https://github.com/AdguardTeam/AdGuardHome/issues/3162
@@ -96,6 +111,11 @@ released by then.
[#3217]: https://github.com/AdguardTeam/AdGuardHome/issues/3217
[#3256]: https://github.com/AdguardTeam/AdGuardHome/issues/3256
[#3257]: https://github.com/AdguardTeam/AdGuardHome/issues/3257
[#3289]: https://github.com/AdguardTeam/AdGuardHome/issues/3289
[#3335]: https://github.com/AdguardTeam/AdGuardHome/issues/3335
[#3343]: https://github.com/AdguardTeam/AdGuardHome/issues/3343
[#3351]: https://github.com/AdguardTeam/AdGuardHome/issues/3351
[#3372]: https://github.com/AdguardTeam/AdGuardHome/issues/3372
@@ -147,7 +167,7 @@ released by then.
### Fixed
- Local domain name handling when the DHCP server is disabled ([#3028]).
- Normalization of perviously-saved invalid static DHCP leases ([#3027]).
- Normalization of previously-saved invalid static DHCP leases ([#3027]).
- Validation of IPv6 addresses with zones in system resolvers ([#3022]).
[#3022]: https://github.com/AdguardTeam/AdGuardHome/issues/3022

View File

@@ -1,520 +1,79 @@
# AdGuard Home Developer Guidelines
Following this document is obligatory for all new code. Some of the rules
aren't enforced as thoroughly or remain broken in old code, but this is still
the place to find out about what we **want** our code to look like and how to
improve it.
The rules are mostly sorted in the alphabetical order.
## Contents
* [Git](#git)
* [Go](#go)
* [Code](#code)
* [Commenting](#commenting)
* [Formatting](#formatting)
* [Naming](#naming)
* [Testing](#testing)
* [Recommended Reading](#recommended-reading)
* [Markdown](#markdown)
* [Shell Scripting](#shell-scripting)
* [Shell Conditionals](#shell-conditionals)
* [Text, Including Comments](#text-including-comments)
* [YAML](#yaml)
<!-- NOTE: Use the IDs that GitHub would generate in order for this to work both
on GitHub and most other Markdown renderers. Use both "id" and "name"
attributes to make it work in Markdown renderers that strip "id". -->
This document was moved to the [AdGuard Code Guidelines repository][repo]. All
sections with IDs now only have links to the corresponding files and sections in
that repository.
## <a href="#git" id="git" name="git">Git</a>
* Call your branches either `NNNN-fix-foo` (where `NNNN` is the ID of the
GitHub issue you worked on in this branch) or just `fix-foo` if there was no
GitHub issue.
* Follow the commit message header format:
```none
pkg: fix the network error logging issue
```
Where `pkg` is the directory or Go package (without the `internal/` part)
where most changes took place. If there are several such packages, or the
change is top-level only, write `all`.
* Keep your commit messages, including headers, to eighty (**80**) columns.
* Only use lowercase letters in your commit message headers. The rest of the
message should follow the plain text conventions below.
The only exceptions are direct mentions of identifiers from the source code
and filenames like `HACKING.md`.
This section was moved to [its own document][git].
## <a href="#go" id="go" name="go">Go</a>
> Not Golang, not GO, not GOLANG, not GoLang. It is Go in natural language,
> golang for others.
This section was moved to [its own document][go].
— [@rakyll](https://twitter.com/rakyll/status/1229850223184269312)
### <a href="#code" id="code" name="code">Code</a>
### <a href="#code" id="code" name="code">Code</a>
This subsection was moved to the [corresponding section][code] of the Go
guidelines document.
* Always `recover` from panics in new goroutines. Preferably in the very
first statement. If all you want there is a log message, use `log.OnPanic`.
### <a href="#commenting" id="commenting" name="commenting">Commenting</a>
* Avoid `fallthrough`. It makes it harder to rearrange `case`s, to reason
about the code, and also to switch the code to a handler approach, if that
becomes necessary later.
This subsection was moved to the [corresponding section][cmnt] of the Go
guidelines document.
* Avoid `goto`.
### <a href="#formatting" id="formatting" name="formatting">Formatting</a>
* Avoid `init` and use explicit initialization functions instead.
This subsection was moved to the [corresponding section][fmt] of the Go
guidelines document.
* Avoid `new`, especially with structs, unless a temporary value is needed,
for example when checking the type of an error using `errors.As`.
### <a href="#naming" id="naming" name="naming">Naming</a>
* Check against empty strings like this:
This subsection was moved to the [corresponding section][name] of the Go
guidelines document.
```go
if s == "" {
// …
}
```
### <a href="#testing" id="testing" name="testing">Testing</a>
Except when the check is done to then use the first character:
```go
if len(s) > 0 {
c := s[0]
}
```
* Constructors should validate their arguments and return meaningful errors.
As a corollary, avoid lazy initialization.
* Prefer to define methods on pointer receievers, unless the type is small or
a non-pointer receiever is required, for example `MarshalFoo` methods (see
[staticcheck-911]).
* Don't mix horizontal and vertical placement of arguments in function and
method calls. That is, either this:
```go
err := f(a, b, c)
```
Or, when the arguments are too long, this:
```go
err := functionWithALongName(
firstArgumentWithALongName,
secondArgumentWithALongName,
thirdArgumentWithALongName,
)
```
Or, with a struct literal:
```go
err := functionWithALongName(arg, structType{
field1: val1,
field2: val2,
})
```
But **never** this:
```go
err := functionWithALongName(firstArgumentWithALongName,
secondArgumentWithALongName,
thirdArgumentWithALongName,
)
```
* Don't rely only on file names for build tags to work. Always add build tags
as well.
* Don't use `fmt.Sprintf` where a more structured approach to string
conversion could be used. For example, `aghnet.JoinHostPort`,
`net.JoinHostPort` or `url.(*URL).String`.
* Don't use naked `return`s.
* Don't write non-test code with more than four (**4**) levels of indentation.
Just like [Linus said], plus an additional level for an occasional error
check or struct initialization.
The exception proving the rule is the table-driven test code, where an
additional level of indentation is allowed.
* Eschew external dependencies, including transitive, unless absolutely
necessary.
* Minimize scope of variables as much as possible.
* No name shadowing, including of predeclared identifiers, since it can often
lead to subtle bugs, especially with errors. This rule does not apply to
struct fields, since they are always used together with the name of the
struct value, so there isn't any confusion.
* Prefer constants to variables where possible. Avoid global variables. Use
[constant errors] instead of `errors.New`.
* Prefer defining `Foo.String` and `ParseFoo` in terms of `Foo.MarshalText`
and `Foo.UnmarshalText` correspondingly and not the other way around.
* Prefer to use named functions for goroutines.
* Program code lines should not be longer than one hundred (**100**) columns.
For comments, see the text section below.
* Use linters. `make go-lint`.
* Write logs and error messages in lowercase only to make it easier to `grep`
logs and error messages without using the `-i` flag.
### <a href="#commenting" id="commenting" name="commenting">Commenting</a>
* See also the “[Text, Including Comments]” section below.
* Document everything, including unexported top-level identifiers, to build
a habit of writing documentation.
* Don't put identifiers into any kind of quotes.
* Put comments above the documented entity, **not** to the side, to improve
readability.
* When a method implements an interface, start the doc comment with the
standard template:
```go
// Foo implements the Fooer interface for *foo.
func (f *foo) Foo() {
// …
}
```
When the implemented interface is unexported:
```go
// Unwrap implements the hidden wrapper interface for *fooError.
func (err *fooError) Unwrap() (unwrapped error) {
// …
}
```
### <a href="#formatting" id="formatting" name="formatting">Formatting</a>
* Decorate `break`, `continue`, `return`, and other terminating statements
with empty lines unless it's the only statement in that block.
* Don't group type declarations together. Unlike with blocks of `const`s,
where a `iota` may be used or where all constants belong to a certain type,
there is no reason to group `type`s.
* Group `require.*` blocks together with the presceding related statements,
but separate from the following `assert.*` and unrelated requirements.
```go
val, ok := valMap[key]
require.True(t, ok)
require.NotNil(t, val)
assert.Equal(t, expected, val)
```
* Use `gofumpt --extra -s`.
* Write slices of struct like this:
```go
ts := []T{{
Field: Value0,
// …
}, {
Field: Value1,
// …
}, {
Field: Value2,
// …
}}
```
### <a href="#naming" id="naming" name="naming">Naming</a>
* Don't use underscores in file and package names, unless they're build tags
or for tests. This is to prevent accidental build errors with weird tags.
* Name benchmarks and tests using the same convention as examples. For
example:
```go
func TestFunction(t *testing.T) { /* … */ }
func TestFunction_suffix(t *testing.T) { /* … */ }
func TestType_Method(t *testing.T) { /* … */ }
func TestType_Method_suffix(t *testing.T) { /* … */ }
```
* Name parameters in interface definitions:
```go
type Frobulator interface {
Frobulate(f Foo, b Bar) (r Result, err error)
}
```
* Name the deferred errors (e.g. when closing something) `derr`.
* Unused arguments in anonymous functions must be called `_`:
```go
v.onSuccess = func(_ int, msg string) {
// …
}
```
* Use named returns to improve readability of function signatures.
* When naming a file which defines an entity, use singular nouns, unless the
entity is some form of a container for other entities:
```go
// File: client.go
package foo
type Client struct {
// …
}
```
```go
// File: clients.go
package foo
type Clients []*Client
// …
type ClientsWithCache struct {
// …
}
```
### <a href="#testing" id="testing" name="testing">Testing</a>
* Use `assert.NoError` and `require.NoError` instead of `assert.Nil` and
`require.Nil` on errors.
* Use formatted helpers, like `assert.Nilf` or `require.Nilf`, instead of
simple helpers when a formatted message is required.
* Use functions like `require.Foo` instead of `assert.Foo` when the test
cannot continue if the condition is false.
### <a href="#recommended-reading" id="recommended-reading" name="recommended-reading">Recommended Reading</a>
* <https://github.com/golang/go/wiki/CodeReviewComments>.
* <https://github.com/golang/go/wiki/TestComments>.
* <https://go-proverbs.github.io/>
[Linus said]: https://www.kernel.org/doc/html/v4.17/process/coding-style.html#indentation
[Text, Including Comments]: #text-including-comments
[constant errors]: https://dave.cheney.net/2016/04/07/constant-errors
[staticcheck-911]: https://github.com/dominikh/go-tools/issues/911
This subsection was moved to the [corresponding section][test] of the Go
guidelines document.
### <a href="#recommended-reading" id="recommended-reading" name="recommended-reading">Recommended Reading</a>
This subsection was moved to the [corresponding section][read] of the Go
guidelines document.
## <a href="#markdown" id="markdown" name="markdown">Markdown</a>
* **TODO(a.garipov):** Define more Markdown conventions.
* Prefer triple-backtick preformatted code blocks to indented code blocks.
* Use asterisks and not underscores for bold and italic.
* Use either link references or link destinations only. Put all link
reference definitions at the end of the second-level block.
This section was moved to [its own document][md].
## <a href="#shell-scripting" id="shell-scripting" name="shell-scripting">Shell Scripting</a>
* Avoid bashisms and GNUisms, prefer POSIX features only.
* Avoid spaces between patterns of the same `case` condition.
* `export` and `readonly` should be used separately from variable assignment,
because otherwise failures in command substitutions won't stop the script.
That is, do this:
```sh
X="$( echo 42 )"
export X
```
And **not** this:
```sh
# Bad!
export X="$( echo 42 )"
```
* If a binary value is needed, use `0` for `false`, and `1` for `true`.
* Mark every variable that shouldn't change later as `readonly`.
* Prefer `'raw strings'` to `"double quoted strings"` whenever possible.
* Put spaces within `$( cmd )`, `$(( expr ))`, and `{ cmd; }`.
* Put utility flags in the ASCII order and **don't** group them together. For
example, `ls -1 -A -q`.
* Script code lines should not be longer than one hundred (**100**) columns.
For comments, see the text section below.
* `snake_case`, not `camelCase` for variables. `kebab-case` for filenames.
* Start scripts with the following sections in the following order:
1. Shebang.
1. Some initial documentation (optional).
1. Verbosity level parsing (optional).
1. `set` options.
* UPPERCASE names for external exported variables, lowercase for local,
unexported ones.
* Use `set -e -f -u` and also `set -x` in verbose mode.
* Use the `"$var"` form instead of the `$var` form, unless word splitting is
required.
* When concatenating, always use the form with curly braces to prevent
accidental bad variable names. That is, `"${var}_tmp.txt"` and **not**
`"$var_tmp.txt"`. The latter will try to lookup variable `var_tmp`.
* When concatenating, surround the whole string with quotes. That is, use
this:
```sh
dir="${TOP_DIR}/sub"
```
And **not** this:
```sh
# Bad!
dir="${TOP_DIR}"/sub
```
### <a href="#shell-conditionals" id="shell-conditionals" name="shell-conditionals">Shell Conditionals</a>
Guidelines and agreements for using command `test`, also known as `[`:
* For conditionals that check for equality against multiple values, prefer
`case` instead of `test`.
* Prefer the `!= ''` form instead of using `-n` to check if string is empty.
* Spell compound conditions with `&&`, `||`, and `!` **outside** of `test`
instead of `-a`, `-o`, and `!` **inside** of `test` correspondingly. The
latter ones are pretty much deprecated in POSIX.
See also: “[Problems With the `test` Builtin: What Does `-a` Mean?][test]”.
* Use `=` for strings and `-eq` for numbers to catch typing errors.
[test]: https://www.oilshell.org/blog/2017/08/31.html
This section was moved to [its own document][sh].
### <a href="#shell-conditionals" id="shell-conditionals" name="shell-conditionals">Shell Conditionals</a>
This subsection was moved to the [corresponding section][cond] of the Shell
guidelines document.
## <a href="#text-including-comments" id="text-including-comments" name="text-including-comments">Text, Including Comments</a>
* End sentences with appropriate punctuation.
* Headers should be written with all initial letters capitalized, except for
references to variable names that start with a lowercase letter.
* Mark temporary todos—that is, todos that must be resolved or removed before
publishing a change—with two exclamation signs:
```go
// TODO(usr1): !! Remove this debug before pushing!
```
This makes it easier to find them both during development and during code
review.
* Start sentences with a capital letter, unless the first word is a reference
to a variable name that starts with a lowercase letter.
* Text should wrap at eighty (**80**) columns to be more readable, to use
a common standard, and to allow editing or diffing side-by-side without
wrapping.
The only exception are long hyperlinks.
* Use U.S. English, as it is the most widely used variety of English in the
code right now as well as generally.
* Use double spacing between sentences to make sentence borders more clear.
* Use the serial comma (a.k.a. Oxford comma) to improve comprehension,
decrease ambiguity, and use a common standard.
* Write todos like this:
```go
// TODO(usr1): Fix the frobulation issue.
```
Or, if several people need to look at the code:
```go
// TODO(usr1, usr2): Fix the frobulation issue.
```
This section was moved to [its own document][txt].
## <a href="#yaml" id="yaml" name="yaml">YAML</a>
* **TODO(a.garipov):** Define naming conventions for schema names in our
OpenAPI YAML file. And just generally OpenAPI conventions.
This section was moved to [its own document][yaml].
* **TODO(a.garipov):** Find a YAML formatter or write our own.
* All strings, including keys, must be quoted. Reason: the “[NO-rway Law]”.
* Indent with two (**2**) spaces. YAML documents can get pretty
deeply-nested.
* No extra indentation in multiline arrays:
```yaml
'values':
- 'value-1'
- 'value-2'
- 'value-3'
```
* Prefer single quotes for strings to prevent accidental escaping, unless
escaping is required or there are single quotes inside the string (e.g. for
GitHub Actions).
* Use `>` for multiline strings, unless you need to keep the line breaks. Use
`|` for multiline strings when you do.
[NO-rway Law]: https://news.ycombinator.com/item?id=17359376
[cmnt]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#commenting
[code]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#code
[cond]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Shell.md#shell-conditionals
[fmt]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#formatting
[git]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Git.md
[go]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md
[md]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Markdown.md
[name]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#naming
[read]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#recommended-reading
[repo]: https://github.com/AdguardTeam/CodeGuidelines
[sh]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Shell.md
[test]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md#testing
[txt]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Text.md
[yaml]: https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/YAML.md

View File

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

View File

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

View File

@@ -68,6 +68,9 @@
"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": "Горад",
@@ -481,10 +484,12 @@
"encryption_key_source_content": "Уставіць змесціва зачыненага ключа",
"stats_params": "Канфігурацыя статыстыкі",
"config_successfully_saved": "Канфігурацыя паспяхова захавана",
"interval_6_hour": "6 гадзін",
"interval_24_hour": "24 гадзіны",
"interval_days": "{{count}} дзень",
"interval_days_plural": "{{count}} дзён",
"domain": "Дамен",
"punycode": "Punycode",
"answer": "Адказ",
"filter_added_successfully": "Спіс паспяхова дададзены",
"filter_removed_successfully": "Спіс паспяхова выдалены",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "za posledních 24 hodin",
"for_last_days": "za posledních {{count}} dní",
"for_last_days_plural": "za posledních {{count}} dní",
"stats_disabled": "Statistiky byly vypnuty. Můžete je zapnout ze <0>stránky nastavení</0>.",
"stats_disabled_short": "Statistiky byly vypnuty",
"no_domains_found": "Nenalezeny žádné domény",
"requests_count": "Počet požadavků",
"top_blocked_domains": "Nejčastěji blokované domény",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Na některých typech routerů nemůžete nastavit vlastní DNS server. V tomto případě může AdGuard Home pomoci, pokud jej nastavíte jako <0>DHCP server</0>. V ostatních případech byste si v manuálu k Vašemu routeru měli zjistit, jak přizpůsobit vlastní DNS servery.",
"install_devices_windows_list_1": "Otevřete ovládací panel prostřednictvím nabídky Start nebo vyhledání v systému Windows.",
"install_devices_windows_list_2": "Přejděte na kategorii Síť a Internet a poté na Centrum sítí a sdílení.",
"install_devices_windows_list_3": "Na levé straně obrazovky najděte možnost Změnit nastavení adaptéru a klepněte na něj.",
"install_devices_windows_list_3": "Na levé straně obrazovky najděte možnost \"Změnit nastavení adaptéru\" a klepněte na něj.",
"install_devices_windows_list_4": "Vyberte své aktivní spojení, klikněte na něj pravým tlačítkem myši a zvolte Vlastnosti.",
"install_devices_windows_list_5": "V seznamu najděte Internet Protocol Version 4 (TCP/IP), vyberte jej a znovu klikněte na Vlastnosti.",
"install_devices_windows_list_6": "Zvolte Použít následující adresy serveru DNS a zadejte adresy AdGuard Home..",
"install_devices_windows_list_5": "V seznamu najděte \"Internet Protocol Version 4 (TCP/IP)\", (nebo IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\"), vyberte jej a znovu klikněte na Vlastnosti.",
"install_devices_windows_list_6": "Zvolte \"Použít následující adresy serveru DNS\" a zadejte adresy serveru AdGuard Home.",
"install_devices_macos_list_1": "Klikněte na ikonu Apple a přejděte na položku Systémové předvolby.",
"install_devices_macos_list_2": "Klikněte na Síť.",
"install_devices_macos_list_3": "Vyberte první připojení v seznamu a klepněte na tlačítko Pokročilé.",
@@ -426,9 +428,9 @@
"access_title": "Nastavení přístupu",
"access_desc": "Zde můžete konfigurovat pravidla přístupu pro server DNS AdGuard Home.",
"access_allowed_title": "Povolení klienti",
"access_allowed_desc": "Seznam adres CIDR nebo IP. Pokud je nakonfigurován, AdGuard Home bude přijímat požadavky pouze z těchto IP adres.",
"access_allowed_desc": "Seznam CIDR, IP adres nebo ID klientů. Pokud je nakonfigurován, AdGuard Home bude přijímat požadavky pouze od těchto klientů.",
"access_disallowed_title": "Blokovaní klienti",
"access_disallowed_desc": "Seznam adres CIDR nebo IP. Pokud je nakonfigurován, AdGuard Home bude odmítat požadavky pouze z těchto IP adres.",
"access_disallowed_desc": "Seznam CIDR, IP adres nebo ID klientů. Pokud je nakonfigurován, AdGuard Home bude odmítat požadavky od těchto klientů. Pokud jsou povolení klienti nakonfigurováni, je toto pole ignorováno.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Vložte obsahy soukromého klíče",
"stats_params": "Konfigurace statistik",
"config_successfully_saved": "Konfigurace byla úspěšně uložena",
"interval_6_hour": "6 hodin",
"interval_24_hour": "24 hodin",
"interval_days": "Dny: {{count}}",
"interval_days_plural": "Dny: {{count}}",
"domain": "Doména",
"punycode": "Punycode",
"answer": "Odpověď",
"filter_added_successfully": "Seznam byl úspěšně přidán",
"filter_removed_successfully": "Seznam byl úspěšně odstraněn",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Prodlužte nejkratší hodnotu TTL (v sekundách) obdrženou z odchozího serveru při ukládání DNS odpovědí do mezipaměti",
"cache_ttl_max_override_desc": "Nastavte maximální hodnotu TTL (v sekundách) pro položky v mezipaměti DNS",
"ttl_cache_validation": "Minimální hodnota TTL mezipaměti musí být menší nebo rovna maximální hodnotě",
"cache_optimistic": "Optimistický režim",
"cache_optimistic_desc": "Nechte AdGuard Home odpovědět z mezipaměti, i když už platnost položek skončila. Také se je pokuste obnovit.",
"filter_category_general": "Obecné",
"filter_category_security": "Bezpečnost",
"filter_category_regional": "Regionální",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "de seneste 24 timer",
"for_last_days": "den seneste {{count}} dag",
"for_last_days_plural": "de seneste {{count}} dage",
"stats_disabled": "Statistikker er deaktiveret. De kan aktiveres via <0>indstillingssiden</0>.",
"stats_disabled_short": "Statistikker er deaktiveret",
"no_domains_found": "Ingen domæner fundet",
"requests_count": "Antal forespørgsler",
"top_blocked_domains": "Hyppigst blokerede domæner",
@@ -426,9 +428,9 @@
"access_title": "Adgangsindstillinger",
"access_desc": "Her kan du opsætte adgangsregler for AdGuard Home DNS-serveren.",
"access_allowed_title": "Tilladte klienter",
"access_allowed_desc": "En liste over CIDR- eller IP-adresser. Hvis opsat, accepterer AdGuard Home kun forespørgsler fra disse IP-adresser.",
"access_allowed_desc": "En liste over CIDR-, IP-adresser eller klient-ID'er. Hvis opsat, accepterer AdGuard Home kun forespørgsler fra disse klienter.",
"access_disallowed_title": "Ikke tilladte klienter",
"access_disallowed_desc": "En liste over CIDR- eller IP-adresser. Hvis opsat, dropper AdGuard Home forespørgsler fra disse IP-adresser.",
"access_disallowed_desc": "En liste over CIDR-, IP-adresser eller klient-ID'er. Hvis opsat, dropper AdGuard Home forespørgsler fra disse klienter. Opsættes tilladte klienter, ignoreres dette felt.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Indsæt indholdet af den private nøgle",
"stats_params": "Statistikopsætning",
"config_successfully_saved": "Opsætning er gemt",
"interval_6_hour": "6 timer",
"interval_24_hour": "24 timer",
"interval_days": "{{count}} dag",
"interval_days_plural": "{{count}} dage",
"domain": "Domæne",
"punycode": "Punycode",
"answer": "Svar",
"filter_added_successfully": "Listen er tilføjet",
"filter_removed_successfully": "Listen er blevet fjernet",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Forlæng korte time-to-live værdier (sekunder) modtaget fra upstream-serveren, når DNS-svar cachelagres",
"cache_ttl_max_override_desc": "Indstil en maksimal time-to-live (sekunder) for registreringer i DNS-cachen",
"ttl_cache_validation": "Minimum cache TTL-værdi skal være mindre end eller lig med den maksimale værdi",
"cache_optimistic": "Optimistisk",
"cache_optimistic_desc": "Får AdGuard Home til at svare fra cachen, selv når posterne er udløbet, og prøver også at opdatere dem.",
"filter_category_general": "Generelt",
"filter_category_security": "Sikkerhed",
"filter_category_regional": "Regional",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "für die letzten 24 Stunden",
"for_last_days": "am letzten {{count}} Tag",
"for_last_days_plural": "in den letzten {{count}} Tage",
"stats_disabled": "Die Statistik wurde deaktiviert. Sie können diese in den <0>Einstellungen</0> erneut aktivieren.",
"stats_disabled_short": "Die Statistik wurde deaktiviert",
"no_domains_found": "Keine Domains gefunden",
"requests_count": "Anzahl der Anfragen",
"top_blocked_domains": "Am häufigsten gesperrte Domains",
@@ -326,7 +328,7 @@
"install_devices_windows_list_2": "Öffnen Sie die Kategorie „Netzwerk und Internet” und dann „Netzwerk- und Freigabecenter”.",
"install_devices_windows_list_3": "Suchen Sie auf der linken Seite des Bildschirms nach „Adaptereinstellungen ändern” und klicken Sie darauf.",
"install_devices_windows_list_4": "Wählen Sie Ihre aktive Verbindung aus, klicken Sie mit der rechten Maustaste darauf und wählen Sie „Eigenschaften”.",
"install_devices_windows_list_5": "Suchen Sie in der Liste nach „Internet Protokoll Version 4 (TCP/IP)”, markieren Sie diese und klicken Sie dann erneut auf „Eigenschaften”.",
"install_devices_windows_list_5": "Suchen Sie in der Liste nach „Internet Protokoll Version 4 (TCP/IP)” (oder, für IPv6, „Internet Protocol Version 6 (TCP/IPv6)“), markieren Sie diese und klicken Sie dann erneut auf „Eigenschaften”.",
"install_devices_windows_list_6": "Wählen Sie „Folgende DNS-Serveradressen verwenden” und geben Sie Ihre AdGuard Home-Serveradressen ein.",
"install_devices_macos_list_1": "Klicken Sie auf das Apple-Symbol (oben links in der Menüzeile) und wählen den Eintrag „Systemeinstellungen”.",
"install_devices_macos_list_2": "Klicken Sie dort auf „Netzwerk”",
@@ -426,9 +428,9 @@
"access_title": "Zugriffsrechte",
"access_desc": "Hier können Sie die Zugriffsregeln für den AdGuard Home DNS-Server konfigurieren.",
"access_allowed_title": "Zugelassene Clients",
"access_allowed_desc": "Eine Liste von CIDR- oder IP-Adressen. Wenn konfiguriert, akzeptiert AdGuard Home nur Anfragen von diesen IP-Adressen.",
"access_allowed_desc": "Eine Liste von CIDRs, IP-Adressen oder Client-IDs. Wenn konfiguriert, akzeptiert AdGuard Home Anfragen von diesen Clients.",
"access_disallowed_title": "Nicht zugelassene Clients",
"access_disallowed_desc": "Eine Liste von CIDR- oder IP-Adressen. Wenn konfiguriert, löscht AdGuard Home Anfragen von diesen IP-Adressen.",
"access_disallowed_desc": "Eine Liste von CIDRs, IP-Adressen oder Client-IDs. Wenn konfiguriert, löscht AdGuard Home Anfragen von diesen Clients. Wenn erlaubte Clients konfiguriert sind, wird dieses Feld ignoriert.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Inhalt des privaten Schlüssels einfügen",
"stats_params": "Statistikkonfiguration",
"config_successfully_saved": "Konfiguration erfolgreich gespeichert",
"interval_6_hour": "6 Stunden",
"interval_24_hour": "24 Stunden",
"interval_days": "{{count}} Tag",
"interval_days_plural": "{{count}} Tage",
"domain": "Domain",
"punycode": "Punycode",
"answer": "Antwort",
"filter_added_successfully": "Der Filter wurde erfolgreich hinzugefügt",
"filter_removed_successfully": "Der Filter wurde erfolgreich entfernt",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Überschreibt den TTL-Minimalwert, der vom vorgeschalteten Server empfangen wurde. Dieser Wert darf nicht mehr als 3600 (Sek.) (≙ 1 Stunde) betragen.",
"cache_ttl_max_override_desc": "Überschreibt den TLL-Maximalwert, der vom vorgeschalteten Server empfangen wurde.",
"ttl_cache_validation": "Der minimale Cache des TTL-Wertes muss kleiner oder gleich dem maximalen Wert sein",
"cache_optimistic": "Optimistisch",
"cache_optimistic_desc": "Sorgt dafür, dass AdGuard Home auch dann aus dem Zwischenspeicher antwortet, wenn die Einträge abgelaufen sind, und versucht zudem, diese zu aktualisieren.",
"filter_category_general": "Allgemein",
"filter_category_security": "Sicherheit",
"filter_category_regional": "Regional",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "for the last 24 hours",
"for_last_days": "for the last {{count}} day",
"for_last_days_plural": "for the last {{count}} days",
"stats_disabled": "The statistics have been disabled. You can turn it on from the <0>settings page</0>.",
"stats_disabled_short": "The statistics have been disabled",
"no_domains_found": "No domains found",
"requests_count": "Requests count",
"top_blocked_domains": "Top blocked domains",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "On some router types, a custom DNS server cannot be set up. In that case, setting up AdGuard Home as a <0>DHCP server</0> may help. Otherwise, you should check the router manual on how to customize DNS servers on your specific router model.",
"install_devices_windows_list_1": "Open Control Panel through Start menu or Windows search.",
"install_devices_windows_list_2": "Go to Network and Internet category and then to Network and Sharing Center.",
"install_devices_windows_list_3": "On the left side of the screen find Change adapter settings and click on it.",
"install_devices_windows_list_3": "On the left side of the screen find \"Change adapter settings\" and click on it.",
"install_devices_windows_list_4": "Select your active connection, right-click on it and choose Properties.",
"install_devices_windows_list_5": "Find Internet Protocol Version 4 (TCP/IP) in the list, select it and then click on Properties again.",
"install_devices_windows_list_6": "Choose Use the following DNS server addresses and enter your AdGuard Home server addresses.",
"install_devices_windows_list_5": "Find \"Internet Protocol Version 4 (TCP/IPv4)\" (or, for IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\") in the list, select it and then click on Properties again.",
"install_devices_windows_list_6": "Choose \"Use the following DNS server addresses\" and enter your AdGuard Home server addresses.",
"install_devices_macos_list_1": "Click on Apple icon and go to System Preferences.",
"install_devices_macos_list_2": "Click on Network.",
"install_devices_macos_list_3": "Select the first connection in your list and click Advanced.",
@@ -484,6 +486,7 @@
"encryption_key_source_content": "Paste the private key contents",
"stats_params": "Statistics configuration",
"config_successfully_saved": "Configuration successfully saved",
"interval_6_hour": "6 hours",
"interval_24_hour": "24 hours",
"interval_days": "{{count}} day",
"interval_days_plural": "{{count}} days",
@@ -594,6 +597,8 @@
"cache_ttl_min_override_desc": "Extend short time-to-live values (seconds) received from the upstream server when caching DNS responses",
"cache_ttl_max_override_desc": "Set a maximum time-to-live value (seconds) for entries in the DNS cache",
"ttl_cache_validation": "Minimum cache TTL value must be less than or equal to the maximum value",
"cache_optimistic": "Optimistic",
"cache_optimistic_desc": "Make AdGuard Home respond from the cache even when the entries are expired and also try to refresh them.",
"filter_category_general": "General",
"filter_category_security": "Security",
"filter_category_regional": "Regional",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "en las últimas 24 horas",
"for_last_days": "durante los últimos {{count}} días",
"for_last_days_plural": "durante los últimos {{count}} días",
"stats_disabled": "Las estadísticas se han deshabilitado. Puedes habilitarlas desde la <0>página de configuración</0>.",
"stats_disabled_short": "Las estadísticas se han deshabilitado",
"no_domains_found": "No se han encontrado dominios",
"requests_count": "Número de peticiones",
"top_blocked_domains": "Dominios más bloqueados",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "En algunos tipos de router, no se puede configurar un servidor DNS personalizado. En ese caso, configurar AdGuard Home como <0>servidor DHCP</0> puede ayudar. De lo contrario, debes consultar el manual del router para saber cómo personalizar los servidores DNS en tu modelo de router específico.",
"install_devices_windows_list_1": "Abre el Panel de control a través del menú Inicio o en el buscador de Windows.",
"install_devices_windows_list_2": "Ve a la categoría Redes e Internet, luego a Centro de redes y recursos compartidos.",
"install_devices_windows_list_3": "En el lado izquierdo de la pantalla, busca Cambiar configuración del adaptador y luego haz clic en él.",
"install_devices_windows_list_3": "En el lado izquierdo de la pantalla, busca \"Cambiar configuración del adaptador\" y luego haz clic en él.",
"install_devices_windows_list_4": "Selecciona tu conexión activa, haz clic derecho sobre ella y elige Propiedades.",
"install_devices_windows_list_5": "Busca en la lista el Protocolo de Internet versión 4 (TCP/IP), selecciónalo y vuelve a hacer clic en Propiedades.",
"install_devices_windows_list_6": "Elige Usar las siguientes direcciones de servidor DNS e ingresa las direcciones de tu servidor AdGuard Home.",
"install_devices_windows_list_5": "Busca en la lista el \"Protocolo de Internet versión 4 (TCP/IPv4)\" (o \"Protocolo de Internet versión 6 (TCP/IPv6)\"), selecciónalo y vuelve a hacer clic en Propiedades.",
"install_devices_windows_list_6": "Elige \"Usar las siguientes direcciones de servidor DNS\" e ingresa las direcciones de tu servidor AdGuard Home.",
"install_devices_macos_list_1": "Haz clic en el icono de Apple y ve a Preferencias del sistema.",
"install_devices_macos_list_2": "Haz clic en Red.",
"install_devices_macos_list_3": "Selecciona la primera conexión de la lista y haz clic en Avanzado.",
@@ -426,9 +428,9 @@
"access_title": "Configuración de acceso",
"access_desc": "Aquí puedes configurar las reglas de acceso para el servidor DNS de AdGuard Home.",
"access_allowed_title": "Clientes permitidos",
"access_allowed_desc": "Lista de CIDR o direcciones IP. Si está configurado, AdGuard Home solo aceptará peticiones de estas direcciones IP.",
"access_allowed_desc": "Lista de CIDR, direcciones IP o ID de clientes. Si está configurado, AdGuard Home aceptará peticiones solo de estos clientes.",
"access_disallowed_title": "Clientes no permitidos",
"access_disallowed_desc": "Lista de CIDR o direcciones IP. Si está configurado, AdGuard Home descartará las peticiones de estas direcciones IP.",
"access_disallowed_desc": "Lista de CIDR, direcciones IP o ID de clientes. Si está configurado, AdGuard Home descartará las peticiones de estos clientes. Si se configuran clientes permitidos, este campo será ignorado.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Pegar el contenido de la clave privada",
"stats_params": "Configuración de estadísticas",
"config_successfully_saved": "Configuración guardada correctamente",
"interval_6_hour": "6 horas",
"interval_24_hour": "24 horas",
"interval_days": "{{count}} día",
"interval_days_plural": "{{count}} días",
"domain": "Dominio",
"punycode": "Punycode",
"answer": "Respuesta",
"filter_added_successfully": "La lista ha sido añadida correctamente",
"filter_removed_successfully": "La lista ha sido eliminada correctamente",
@@ -547,7 +551,7 @@
"filtered_custom_rules": "Filtrado por reglas de filtrado personalizado",
"choose_from_list": "Elegir de la lista",
"add_custom_list": "Añadir lista personalizada",
"host_whitelisted": "El host está en la lista blanca",
"host_whitelisted": "El host está permitido",
"check_ip": "Direcciones IP: {{ip}}",
"check_cname": "CNAME: {{cname}}",
"check_reason": "Razón: {{reason}}",
@@ -572,7 +576,7 @@
"validated_with_dnssec": "Validado con DNSSEC",
"all_queries": "Todas las consultas",
"show_blocked_responses": "Bloqueado",
"show_whitelisted_responses": "En lista blanca",
"show_whitelisted_responses": "Permitido",
"show_processed_responses": "Procesado",
"blocked_safebrowsing": "Bloqueado por navegación segura",
"blocked_adult_websites": "Sitios web para adultos bloqueado",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Amplia el corto tiempo de vida de los valores recibidos del servidor DNS de subida al almacenar en caché las respuestas DNS",
"cache_ttl_max_override_desc": "Establece un valor de tiempo de vida máximo para las entradas en la caché DNS",
"ttl_cache_validation": "El valor TTL mínimo de la caché debe ser menor o igual al valor máximo",
"cache_optimistic": "Optimista",
"cache_optimistic_desc": "Haz que AdGuard Home responda desde la caché incluso cuando las entradas estén expiradas y también intente actualizarlas.",
"filter_category_general": "General",
"filter_category_security": "Seguridad",
"filter_category_regional": "Regional",

View File

@@ -9,7 +9,7 @@
"bootstrap_dns": "Serveurs DNS d'amorçage",
"bootstrap_dns_desc": "Les serveurs DNS d'amorçage sont utilisés pour résoudre les adresses IP des résolveurs DoH/DoT que vous spécifiez comme upstream.",
"local_ptr_title": "Serveurs DNS privés inverses",
"local_ptr_desc": "Les serveurs DNS que AdGuard Home utilise pour les requêtes PTR locales. Ces serveurs sont utilisés pour résoudre les noms d'hôte des clients avec des adresses IP privées, par exemple \"192.168.12.34\", en utilisant le DNS inversé. Si ce paramètre n'est pas défini, AdGuard Home utilise les adresses des résolveurs DNS par défaut de votre système d'exploitation, à l'exception des adresses d'AdGuard Home lui-même.",
"local_ptr_desc": "Les serveurs DNS que AdGuard Home utilise pour les requêtes PTR locales. Ces serveurs sont utilisés pour résoudre les noms d'hôte des clients avec des adresses IP privées, par exemple « 192.168.12.34 », en utilisant le DNS inversé. Si ce paramètre n'est pas défini, AdGuard Home utilise les adresses des résolveurs DNS par défaut de votre système d'exploitation, à l'exception des adresses d'AdGuard Home lui-même.",
"local_ptr_default_resolver": "Par défaut, AdGuard Home utilise les résolveurs DNS inversés suivants : {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home n'a pas pu déterminer de résolveurs DNS inversés privés appropriés pour ce système.",
"local_ptr_placeholder": "Saisissez une adresse de serveur par ligne",
@@ -68,6 +68,9 @@
"dhcp_new_static_lease": "Nouveau bail statique",
"dhcp_static_leases_not_found": "Aucun bail statique DHCP trouvé",
"dhcp_add_static_lease": "Ajoutez un bail statique",
"dhcp_reset_leases": "Réinitialiser tous les baux",
"dhcp_reset_leases_confirm": "Voulez-vous vraiment réinitialiser tous les baux DHCP?",
"dhcp_reset_leases_success": "Les baux DHCP ont été réinitialisés avec succès",
"dhcp_reset": "Voulez-vous vraiment réinitialiser votre configuration DHCP ?",
"country": "Pays",
"city": "Ville",
@@ -109,6 +112,8 @@
"for_last_24_hours": "pendant les dernières 24 heures",
"for_last_days": "pour les {{count}} derniers jours",
"for_last_days_plural": "pour les {{count}} derniers jours",
"stats_disabled": "Les statistiques ont été désactivées. Vous pouvez l'activer à partir de la <0>page des paramètres</0>.",
"stats_disabled_short": "Les statistiques ont été désactivées",
"no_domains_found": "Pas de domaines trouvés",
"requests_count": "Nombre de requêtes",
"top_blocked_domains": "Les domaines les plus fréquemment bloqués",
@@ -321,10 +326,10 @@
"install_devices_router_list_4": "Vous ne pouvez pas définir un serveur DNS personnalisé sur certains types de routeurs. Dans ce cas, la configuration de AdGuard Home en tant que <0>serveur DHCP</0> peut aider. Sinon, vous devez rechercher le manuel sur la façon de personnaliser les serveurs DNS pour votre modèle de routeur particulier.",
"install_devices_windows_list_1": "Ouvrez votre Panneau de configuration depuis le menu Démarrer ou la recherche Windows.",
"install_devices_windows_list_2": "Allez dans la catégorie Réseau et Internet et ensuite dans le Centre Réseau et Partage.",
"install_devices_windows_list_3": "Sur la partie gauche de l'écran, recherchez Modifier les paramètres de la carte et cliquez dessus.",
"install_devices_windows_list_3": "Sur la partie gauche de l'écran, recherchez « Modifier les paramètres de l'adaptateur » et cliquez dessus.",
"install_devices_windows_list_4": "Sélectionnez votre connexion active, clic droit dessus et sélectionnez Propriétés.",
"install_devices_windows_list_5": "Recherchez la version du protocole Internet 4 (TCP/IP) dans la liste, sélectionnez-la puis cliquez à nouveau sur Propriétés.",
"install_devices_windows_list_6": "Sélectionnez Utiliser ladresse de serveur DNS suivante et saisissez votre adresse de seveur AdGuard Home.",
"install_devices_windows_list_5": "Recherchez « Protocole Internet Version 4 (TCP/IPv4) » (soit, pour IPv6, « Protocole Internet Version 6 (TCP/IPv6) ») dans la liste, sélectionnez-la puis cliquez à nouveau sur Propriétés.",
"install_devices_windows_list_6": "Sélectionnez « Utiliser ladresse de serveur DNS suivante » et saisissez votre adresse de serveur AdGuard Home.",
"install_devices_macos_list_1": "Cliquez sur l'icône Apple et allez dans les Préférences Système.",
"install_devices_macos_list_2": "Cliquez sur Réseau.",
"install_devices_macos_list_3": "Sélectionnez la première connexion dans votre liste et cliquez sur Avancés.",
@@ -423,11 +428,11 @@
"access_title": "Paramètres d'accès",
"access_desc": "Ici vous pouvez configurer les règles d'accès au serveur DNS AdGuard Home.",
"access_allowed_title": "Clients autorisés",
"access_allowed_desc": "Une liste d'adresses IP ou CIDR. Si configuré, AdGuard Home acceptera uniquement les requêtes provenant de ces adresses IP.",
"access_allowed_desc": "Une liste de CIDR, d'adresses IP ou d'ID client. S'il est configuré, AdGuard Home acceptera uniquement les demandes de ces clients.",
"access_disallowed_title": "Clients non autorisés",
"access_disallowed_desc": "Une liste d'adresses IP ou CIDR. Si configuré, AdGuard Home bloquera les requêtes provenant de ces adresses IP.",
"access_disallowed_desc": "Une liste d'adresses IP ou CIDR. Si configuré, AdGuard Home bloquera les requêtes provenant de ces adresses IP. Si des clients sont configurés, ce champ sera ignoré.",
"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_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_version_equal": "AdGuard Home est à jour",
@@ -481,10 +486,12 @@
"encryption_key_source_content": "Coller les contenus de la clef privée",
"stats_params": "Configuration des statistiques",
"config_successfully_saved": "Configuration sauvegardée",
"interval_6_hour": "6 heures",
"interval_24_hour": "24 heures",
"interval_days": "{{count}} jour",
"interval_days_plural": "{{count}} jours",
"domain": "Domaine",
"punycode": "Punycode",
"answer": "Réponse",
"filter_added_successfully": "Le filtre a été ajouté avec succès",
"filter_removed_successfully": "La liste a été supprimée avec succès",
@@ -590,6 +597,8 @@
"cache_ttl_min_override_desc": "Prolonger les valeurs courtes de durée de vie (en secondes) reçues du serveur en amont lors de la mise en cache des réponses DNS",
"cache_ttl_max_override_desc": "Établir la valeur de durée de vie TTL maximale (en secondes) pour les saisies dans le cache du DNS",
"ttl_cache_validation": "La valeur TTL minimale du cache doit être inférieure ou égale à la valeur maximale",
"cache_optimistic": "Optimiste",
"cache_optimistic_desc": "Faites en sorte qu'AdGuard Home réponde à partir du cache même lorsque les entrées ont expiré et essayez également de les actualiser.",
"filter_category_general": "Général",
"filter_category_security": "Sécurité",
"filter_category_regional": "Régional",

View File

@@ -5,9 +5,18 @@
"upstream_parallel": "Koristi paralelne upite kako bi ubrzali rješavanje istovremenim ispitavanjem svih upstream poslužitelja.",
"parallel_requests": "Paralelni zahtjevi",
"load_balancing": "Load-balancing",
"load_balancing_desc": "Šaljite upite po jednom poslužitelju u isto vrijeme. AdGuard Home će koristiti ponderirani slučajni algoritam za odabir poslužitelja, tako da će se najbrži poslužitelj češće koristiti.",
"load_balancing_desc": "Pitajte jedan po jedan uzvodni poslužitelj. AdGuard Home koristi svoj ponderirani slučajni algoritam za odabir poslužitelja tako da se najbrži poslužitelj koristi češće.",
"bootstrap_dns": "Bootstrap DNS poslužitelji",
"bootstrap_dns_desc": "Bootstrap DNS poslužitelji koriste se za rezolvanje IP adresa DoH/DoT rezolvera koje navedete kao upstreams.",
"local_ptr_title": "Privatni obrnuti DNS poslužitelji",
"local_ptr_desc": "DNS poslužitelji koje AdGuard Home koristi za lokalne PTR upite. Ti se poslužitelji koriste za razrješavanje naziva glavnog računala klijenata s privatnim IP adresama, na primjer \"192.168.12.34\", koristeći obrnuti DNS. Ako nije postavljeno, AdGuard Home koristi adrese zadanih DNS razrješivača vašeg OS-a, osim za adrese samog AdGuard Homea.",
"local_ptr_default_resolver": "Prema zadanim postavkama AdGuard Home koristi sljedeće obrnute DNS razrješivače: {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home nije mogao odrediti prikladne privatne obrnute DNS razrješivače za ovaj sustav.",
"local_ptr_placeholder": "Unesite jednu adresu poslužitelja po retku",
"resolve_clients_title": "Omogući obrnuto rješavanje IP adresa klijenata",
"resolve_clients_desc": "Obrnuto razriješite IP adrese klijenata u nazive glavnih računala slanjem PTR upita odgovarajućim razrješivačima (privatni DNS poslužitelji za lokalne klijente, uzvodni poslužitelji za klijente s javnim IP adresama).",
"use_private_ptr_resolvers_title": "Koristi privatne reverzne DNS razrješivače",
"use_private_ptr_resolvers_desc": "Izvršite obrnuta DNS traženja za lokalno poslužene adrese pomoću ovih uzlaznih poslužitelja. Ako je onemogućen, AdGuard Home odgovara S NXDOMAIN-om na sve takve PTR zahtjeve osim za klijente poznate iz DHCP-a, /etc/hosts i tako dalje.",
"check_dhcp_servers": "Provjera DHCP poslužitelja",
"save_config": "Spremi konfiguraciju",
"enabled_dhcp": "DHCP poslužitelj je omogućen",
@@ -33,6 +42,7 @@
"form_error_mac_format": "Nevažeći MAC format",
"form_error_client_id_format": "Nevažeći format ID-a klijenta",
"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_negative": "Mora biti jednako ili veće od 0",
"range_end_error": "Mora biti veće od početne vrijednosti raspona",
@@ -58,6 +68,9 @@
"dhcp_new_static_lease": "Novi static lease",
"dhcp_static_leases_not_found": "Nisu pronađeni statični DHCP leases",
"dhcp_add_static_lease": "Dodaj static lease",
"dhcp_reset_leases": "Ponovno postavljanje svih najmova",
"dhcp_reset_leases_confirm": "Jeste li sigurni da želite resetirati sve najmove?",
"dhcp_reset_leases_success": "DHCP najmovi uspješno se resetiraju",
"dhcp_reset": "Jeste li sigurni da želite poništiti DHCP postavke?",
"country": "Država",
"city": "Grad",
@@ -99,6 +112,8 @@
"for_last_24_hours": "u zadnja 24 sata",
"for_last_days": "zadnjih {{count}} dana",
"for_last_days_plural": "zadnjih {{count}} dana",
"stats_disabled": "Statistika je onemogućena. Možete ga uključiti sa <0>stranice s postavkama</0>.",
"stats_disabled_short": "Statistika je onemogućena",
"no_domains_found": "Nije pronađena domena",
"requests_count": "Broj zahtjeva",
"top_blocked_domains": "Top blokirane domene",
@@ -118,11 +133,11 @@
"block_domain_use_filters_and_hosts": "Blokiraj domene koristeći filtre ili hosts datoteke",
"filters_block_toggle_hint": "Pravila blokiranja možete postaviti u postavkama <a>filtara</a>.",
"use_adguard_browsing_sec": "Koristi AdGuard uslugu zaštite pregledavanja",
"use_adguard_browsing_sec_hint": "AdGuard Home će provjeriti nalazi li se domena na popisu nedopuštenih domena od usluge zaštite pregledavanja. Za provjeru će se koristiti API za provjeru koji poštuje vašu privatnost. Samo mali dio SHA256 hash-a od naziva domene se šalje poslužitelju.",
"use_adguard_browsing_sec_hint": "AdGuard Home provjerit će je li domena blokirana sigurnosnim web servisom za pregledavanje. Za izvođenje provjere koristit će API za pretraživanje prilagođen privatnosti: poslužitelju se šalje samo kratki prefiks naziva domene SHA256 hash.",
"use_adguard_parental": "Koristi web uslugu AdGuard roditeljske zaštite",
"use_adguard_parental_hint": "AdGuard Home provjeriti će sadrži li domena sadržaj za odrasle. Koristi isti API za zaštitu privatnosti kao i naša usluga zaštite pregledavanja.",
"enforce_safe_search": "Omogući sigurno pretraživanje",
"enforce_save_search_hint": "AdGuard Home može nametnuti sigurno pretraživanje na sljedećim tražilicama: Google, Youtube, Bing, DuckDuckGo, Yandex i Pixabay.",
"enforce_safe_search": "Koristi sigurno pretraživanje",
"enforce_save_search_hint": "AdGuard Home provodit će sigurno pretraživanje u sljedećim tražilicama: Google, YouTube, Bing, DuckDuckGo, Yandex, Pixabay.",
"no_servers_specified": "Nije odabran nijedan poslužitelj",
"general_settings": "Opće postavke",
"dns_settings": "DNS postavke",
@@ -261,8 +276,8 @@
"plain_dns": "Obični DNS",
"form_enter_rate_limit": "Unesite ograničenje",
"rate_limit": "Ograničenje",
"edns_enable": "Omogući EDNS Client Subnet",
"edns_cs_desc": "Ako je omogućeno, AdGuard Home će slati podmreže klijenata na DNS poslužitelje.",
"edns_enable": "Omogući podmrežu klijenta EDNS-a",
"edns_cs_desc": "Pošaljite podmreže klijenata DNS poslužiteljima.",
"rate_limit_desc": "Broj zahtjeva u sekundi koji su dopušteni po jednom klijentu. Postavljanje na 0 znači neograničeno.",
"blocking_ipv4_desc": "Povratna IP adresa za blokirane A zahtjeve",
"blocking_ipv6_desc": "Povratna IP adresa za blokirane AAAA zahtjeve",
@@ -301,9 +316,9 @@
"install_devices_title": "Postavite vaše uređaje",
"install_devices_desc": "Da biste započeli koristiti AdGuard Home, morate postaviti uređaje da ga koriste.",
"install_submit_title": "Čestitamo!",
"install_submit_desc": "Postavljanje je dovršeno i spremni ste koristiti AdGuard Home.",
"install_submit_desc": "Postupak postavljanja je dovršen i sada ste spremni početi koristiti AdGuard Home.",
"install_devices_router": "Usmjerivač (Router)",
"install_devices_router_desc": "Ovo postavljanje će automatski pokriti sve uređaje povezane na vaš kućni router i nećete trebati ručno postavljati svaki od njih.",
"install_devices_router_desc": "Ova postavka automatski pokriva sve uređaje povezane s kućnim usmjerivačem, nema potrebe za ručnom konfiguracijom svakog od njih.",
"install_devices_address": "AdGuard Home DNS poslužitelj osluškuje sljedeće adrese",
"install_devices_router_list_1": "Otvorite postavke za router. Obično mu možete pristupiti iz preglednika putem URL-a, kao što je http://192.168.0.1/ ili http://192.168.1.1/. Od vas će se možda tražiti da unesete lozinku. Ako je se ne sjećate, lozinku možete često poništiti pritiskom na dumge na samom routeru. Neki routeri trebaju određenu aplikaciju, koja bi u tom slučaju trebala biti već instalirana na vašem računalu/telefonu.",
"install_devices_router_list_2": "Pronađite DHCP/DNS postavke. Potražite DNS slova pored polja koje dopušta dva ili tri skupa brojeva, svaki razdvojen u četiri skupine od jedne do tri znamenke.",
@@ -311,10 +326,10 @@
"install_devices_router_list_4": "Na nekim se vrstama usmjerivača ne može postaviti prilagođeni DNS poslužitelj. U ovom slučaju, može vam pomoći ako postavite AdGuard Home kao <0>DHCP poslužitelj</0>. U suprotnom, trebali biste potražiti priručnik o tome kako prilagoditi DNS poslužitelje za vaš određeni model routera.",
"install_devices_windows_list_1": "Otvorite Upravljačku ploču putem Start izbornika ili Windows pretrage.",
"install_devices_windows_list_2": "Idite na kategoriju Mreža i Internet i odaberite Centar za mreže i zajedničko korištenje.",
"install_devices_windows_list_3": "Na lijevoj strani zaslona pronađite Promjeni postavke adaptera i pritisnite na to.",
"install_devices_windows_list_3": "Na lijevoj strani zaslona pronađite \"Promjena postavki prilagodnika\" i kliknite na nju.",
"install_devices_windows_list_4": "Odaberite aktivnu vezu, pritisnite desni klik na nju i odaberite Svojstva.",
"install_devices_windows_list_5": "Pronađite Internet Protocol Version 4 (TCP/IP) na listi, odaberite ga i zatim pritisnite opet Postavke.",
"install_devices_windows_list_6": "Odaberite Koristi sljedeće DNS adrese poslužitelja i unesite vaše adrese od AdGuard Home poslužitelja.",
"install_devices_windows_list_5": "Na popisu pronađite \"Internet Protocol Version 4 (TCP/IPv4)\" (ili, za IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\"), odaberite ga i zatim ponovno kliknite svojstva.",
"install_devices_windows_list_6": "Odaberite \"Koristi sljedeće adrese DNS poslužitelja\" i unesite adrese AdGuard Home poslužitelja.",
"install_devices_macos_list_1": "Pritisnite na Apple ikonu i idite u Postavke sustava.",
"install_devices_macos_list_2": "Pritisnite na Mreža.",
"install_devices_macos_list_3": "Odaberite prvu vezu s vašeg popisa i pritisnite Napredno.",
@@ -323,7 +338,7 @@
"install_devices_android_list_2": "Pritisnite Wi-Fi u izborniku. Prikazat će se zaslon s popisom svih dostupnih mreža (nemoguće je postaviti prilagođeni DNS za mobilnu vezu).",
"install_devices_android_list_3": "Dugo pritisnite na mrežu na koju ste povezani i odaberite Uredi mrežu.",
"install_devices_android_list_4": "Na nekim će uređajima možda trebati označiti Napredno za prikaz dodatnih postavki. Da biste prilagodili postavke Android DNS-a, morati će te prebaciti IP postavke s DHCP-a na Statičke.",
"install_devices_android_list_5": "Promijenite DNS 1 i DNS 2 vrijednosti u one adrese AdGuard Home poslužitelja.",
"install_devices_android_list_5": "Promijenite vrijednosti DNS-a 1 i DNS-a 2 u adrese AdGuard Home poslužitelja.",
"install_devices_ios_list_1": "Na početnom zaslonu odaberite Postavke.",
"install_devices_ios_list_2": "Odaberite Wi-Fi u lijevom izborniku (ne moguće je postaviti DNS za mobilne mreže).",
"install_devices_ios_list_3": "Pritisnite na naziv vaše trenutne mreže.",
@@ -393,8 +408,9 @@
"client_edit": "Uredi klijenta",
"client_identifier": "Identifikator",
"ip_address": "IP adresa",
"client_identifier_desc": "Klijenti se mogu identificirati prema IP adresi, CIDR-u, MAC adresi ili posebnom ID-u klijenta (može se koristiti za DoT/DoH/DoQ). <0>Ovdje</0> možete saznati više o tome kako prepoznati klijente.",
"client_identifier_desc": "Klijenti se mogu identificirati putem IP adrese, CIDR-a, MAC adrese ili posebnog ID-a klijenta (može se koristiti za DoT/DoH/DoQ). <0>Ovdje</0> možete saznati više o tome kako prepoznati klijente.",
"form_enter_ip": "Unesite IP adresu",
"form_enter_subnet_ip": "Unesite IP adresu u podmrežu \"{{cidr}}\"",
"form_enter_mac": "Unesite MAC adresu",
"form_enter_id": "Unesi identifikator",
"form_add_id": "Dodaj identifikator",
@@ -412,11 +428,11 @@
"access_title": "Postavke pristupa",
"access_desc": "Postavite pravila pristupa za AdGuard Home DNS poslužitelj.",
"access_allowed_title": "Dopušteni klijenti",
"access_allowed_desc": "Popis CIDR-a ili IP adresa. Ukoliko je postavljeno, AdGuard Home će prihvatiti samo zahtjeve s ovih IP adresa.",
"access_allowed_desc": "Popis CIDR-ova, IP adresa ili ID-ova klijenata. Ako je konfiguriran, AdGuard Home prihvatit će zahtjeve samo tih klijenata.",
"access_disallowed_title": "Nedopušteni klijenti",
"access_disallowed_desc": "Popis CIDR-a ili IP adresa. Ukoliko je postavljeno, AdGuard Home će zaustaviti zahtjeve s ovih IP adresa.",
"access_disallowed_desc": "Popis CIDR-ova, IP adresa ili ID-ova klijenata. Ako je konfiguriran, AdGuard Home će odbaciti zahtjeve tih klijenata. Ako su konfigurirani dopušteni klijenti, ovo se polje zanemaruje.",
"access_blocked_title": "Nedopuštene domene",
"access_blocked_desc": "Ne miješajte ovo s filtrima. AdGuard Home će zaustaviti DNS upite s tim ovim domenama u podnesenim upitima. Ovdje možete definirati točne nazive domena, zamjenske znakove ili pravila URL filtriranja, npr. 'example.org', '*.example.org' or '||example.org^'.",
"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_version_equal": "AdGuard Home je ažuriran",
@@ -470,6 +486,7 @@
"encryption_key_source_content": "Zalijepi sadržaj privatnog ključa",
"stats_params": "Postavke statistike",
"config_successfully_saved": "Postavke su uspješno spremljene",
"interval_6_hour": "6 sati",
"interval_24_hour": "24 sata",
"interval_days": "{{count}} dan",
"interval_days_plural": "{{count}} dana",
@@ -516,8 +533,8 @@
"rewrite_domain_name": "Naziv domene: Dodajte CNAME zapis",
"rewrite_A": "<0>A</0>: posebna vrijednost, ukloni <0>A</0> zapis od upstreama",
"rewrite_AAAA": "<0>AAAA</0>: posebna vrijednost, ukloni <0>AAAA</0> zapis od upstreama",
"disable_ipv6": "Onemogući IPv6",
"disable_ipv6_desc": "Ukoliko je ova značajka omogućena, svi DNS upiti za IPv6 adrese (AAAA tip) će biti odbačeni.",
"disable_ipv6": "Onemogući razrješavanje IPv6 adresa",
"disable_ipv6_desc": "Ispustite sve DNS upite za IPv6 adrese (upišite AAAA).",
"fastest_addr": "Najbrža IP adresa",
"fastest_addr_desc": "Ispitajte sve DNS poslužitelje i vratite najbržu IP adresu među svim odgovorima. To usporava DNS upite jer AdGuard Home mora čekati odgovore svih DNS poslužitelja, ali poboljšava ukupnu povezanost.",
"autofix_warning_text": "Ako pritisnete \"Popravi\", AdGuard Home će postaviti vaš sustav da koristi AdGuardHome DNS poslužitelj.",
@@ -554,7 +571,7 @@
"list_updated": "{{count}} popis ažuriran",
"list_updated_plural": "{{count}} popisa ažurirana",
"dnssec_enable": "Omogući DNSSEC",
"dnssec_enable_desc": "Omogućite DNSSEC u izlaznim DNS upitima i provjerite rezultat (potreban je resolver s omogućenim DNSSEC-om)",
"dnssec_enable_desc": "Postavite ZASTAVICU DNSSEC-a u ulaznim DNS upitima i provjerite rezultat (potreban je DNSSEC-omogućen razrješivač).",
"validated_with_dnssec": "Potvrđeno s DNSSEC-om",
"all_queries": "Svi upiti",
"show_blocked_responses": "Blokirano",
@@ -579,12 +596,14 @@
"cache_ttl_min_override_desc": "Povećajte kratke vrijednosti TTL-a (u sekundama) primljene od upstream poslužitelja prilikom predmemoriranja DNS odgovora",
"cache_ttl_max_override_desc": "Postavite maksimalnu vrijednost TTL-a (u sekundama) za zapise u DNS predmemoriju",
"ttl_cache_validation": "Minimalna vrijednost TTL predmemorije mora biti manja ili jednaka maksimalnoj vrijednosti",
"cache_optimistic": "optimistički",
"cache_optimistic_desc": "Učinite da AdGuard Home reagira iz predmemorije čak i kada su unosi istekli i pokušajte ih osvježiti.",
"filter_category_general": "Općenito",
"filter_category_security": "Sigurnost",
"filter_category_regional": "Regionalno",
"filter_category_other": "Ostalo",
"filter_category_general_desc": "Popisi koji blokiraju pratitelje i oglase na većini uređaja",
"filter_category_security_desc": "Popisi koju su specijalizirani za blokiranje zlonamjernih programa, krađe identiteta ili domena za obmanu",
"filter_category_security_desc": "Popisi posebno dizajnirani za blokiranje zlonamjernih domena, domena za krađu identiteta i prijevare",
"filter_category_regional_desc": "Popisi koji se fokusiraju na regionalne oglase i poslužitelje za praćenje",
"filter_category_other_desc": "Ostali popisi nedopuštenih",
"setup_config_to_enable_dhcp_server": "Postavite konfiguraciju za omogućavanje DHCP poslužitelja",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "nelle ultime 24 ore",
"for_last_days": "per gli ultimi {{count}} giorni",
"for_last_days_plural": "per gli ultimi {{count}} giorni",
"stats_disabled": "Le statistiche sono state disattivate. Puoi attivarle dalla <0>pagina delle impostazioni</0>.",
"stats_disabled_short": "Le statistiche sono state disattivate",
"no_domains_found": "Nessun dominio trovato",
"requests_count": "Numero richieste",
"top_blocked_domains": "Domini maggiormente bloccati",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Su alcuni tipi di router, non è possibile configurare un server DNS personalizzato. In tal caso, configurare AdGuard Home come un <0>server DHCP</0> potrebbe aiutare. In alternativa, dovresti leggere il manuale di istruzioni per capire come personalizzare i server DNS sul tuo specifico modello di router.",
"install_devices_windows_list_1": "Apri il Pannello di controllo tramite il menu Start o la ricerca di Windows.",
"install_devices_windows_list_2": "Vai a Rete e categoria Internet e poi a Centro connessioni di rete e condivisione.",
"install_devices_windows_list_3": "Sul lato sinistro dello schermo, trova le impostazioni della scheda Cambia e fai clic su di esso.",
"install_devices_windows_list_3": "Sul lato sinistro dello schermo, trova \"Cambia impostazioni adattatore\" e clicca su di esso.",
"install_devices_windows_list_4": "Seleziona la tua connessione attiva, fai clic destro su di essa e scegli Proprietà.",
"install_devices_windows_list_5": "Trova Protocollo Internet versione 4 (TCP / IP) nell'elenco, selezionalo e quindi fai nuovamente clic su Proprietà.",
"install_devices_windows_list_6": "Scegli \"Utilizza i seguenti indirizzi del server DNS\" ed inserisci gli indirizzi del tuo server AdGuard Home.",
"install_devices_windows_list_5": "Trova \"Protocollo Internet versione 4 (TCP/IPv4)\" (o, per IPv6, \"Protocollo Internet versione 6 (TCP/IPv6)\" nella lista, selezionalo e quindi clicca nuovamente su Proprietà.",
"install_devices_windows_list_6": "Scegli \"Utilizza i seguenti indirizzi server DNS\" ed inserisci i tuoi indirizzi server AdGuard Home.",
"install_devices_macos_list_1": "Fai clic sull'icona Apple e vai su Preferenze di Sistema.",
"install_devices_macos_list_2": "Clicca sulla rete.",
"install_devices_macos_list_3": "Seleziona la prima connessione nel tuo elenco e fai clic su Avanzate.",
@@ -426,9 +428,9 @@
"access_title": "Impostazioni di accesso",
"access_desc": "Qui puoi configurare le regole d'accesso per il server DNS di AdGuard Home.",
"access_allowed_title": "Client permessi",
"access_allowed_desc": "Una lista in CIDR o indirizzi IP. Se configurata AdGuard Home accetterà richieste solo da questi indirizzi ip.",
"access_allowed_desc": "Una lista di CIDR, indirizzi IP o ID client. Se configurata AdGuard Home accetterà richieste solo da questi client.",
"access_disallowed_title": "Client non permessi",
"access_disallowed_desc": "Una lista in CIDR o indirizzi IP. Se configurata AdGuard Home non accetterà richieste da questi indirizzi ip.",
"access_disallowed_desc": "Una lista di CIDR, indirizzi IP o ID client. Se configurata, AdGuard Home rifiuterà richieste da questi client. Se i client consentiti risulteranno configurati, questo campo verrà ignorato.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Incolla i contenuti della chiave privata",
"stats_params": "Configurazione delle statistiche",
"config_successfully_saved": "Configurazione salvata correttamente",
"interval_6_hour": "6 ore",
"interval_24_hour": "24 ore",
"interval_days": "{{count}} giorni",
"interval_days_plural": "{{count}} giorni",
"domain": "Dominio",
"punycode": "Punycode",
"answer": "Risposta",
"filter_added_successfully": "Il filtro è stato aggiunto correttamente",
"filter_removed_successfully": "La lista è stata correttamente rimossa",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Estende i valori brevi (in secondi) ricevuti dal server upstream durante la memorizzazione nella cache delle risposte DNS",
"cache_ttl_max_override_desc": "Imposta un periodo massimo di attivazione (in secondi) per le voci nella cache DNS",
"ttl_cache_validation": "Il valore minimo della cache TTL deve essere inferiore o uguale al valore massimo",
"cache_optimistic": "Ottimistico",
"cache_optimistic_desc": "Fai in modo che AdGuard Home risponda dalla cache anche quando le voci risultano scadute e prova anche ad aggiornarle.",
"filter_category_general": "Generali",
"filter_category_security": "Sicurezza",
"filter_category_regional": "Regionale",

View File

@@ -68,6 +68,9 @@
"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": "街",
@@ -109,6 +112,8 @@
"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": "最もブロックされたドメイン",
@@ -321,10 +326,10 @@
"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": "一覧から「インターネット プロトコル バージョン4TCP/IPv4」を見つけ、それを選択してから、もう一度プロパティをクリックします。",
"install_devices_windows_list_6": "「次のDNSサーバアドレスを使う」を選択して、AdGuard Homeサーバアドレスを入力します。",
"install_devices_windows_list_5": "一覧から「インターネット プロトコル バージョン4TCP/IPv4もしくはIPv6の場合「インターネット プロトコル バージョン6TCP/IPv6を見つけ、それを選択してから、もう一度プロパティをクリックします。",
"install_devices_windows_list_6": "「次のDNSサーバアドレスを使う」を選択して、お使いのAdGuard Homeサーバアドレスを入力します。",
"install_devices_macos_list_1": "Apple アイコンをクリックして「システム環境設定」へ行きます。",
"install_devices_macos_list_2": "「ネットワーク」をクリックします。",
"install_devices_macos_list_3": "一覧の最初の接続を選択して「詳細...」をクリックします。",
@@ -423,9 +428,9 @@
"access_title": "アクセス設定",
"access_desc": "ここで、AdGuard Home DNSサーバのアクセスルールを設定できます。",
"access_allowed_title": "許可されたクライアント",
"access_allowed_desc": "CIDRまたはIPアドレスのリスト。設定されると、AdGuard HomeはこれらのIPアドレスからのリクエストのみを許可します。",
"access_allowed_desc": "CIDRIPアドレス、またはクライアントIDのリスト。設定されている場合、AdGuard HomeはこれらのIPアドレスからのリクエストのみを受け入れます。",
"access_disallowed_title": "拒否するクライアント",
"access_disallowed_desc": "CIDRまたはIPアドレスのリスト。設定されると、AdGuard HomeはこれらのIPアドレスからのリクエストを破棄します。",
"access_disallowed_desc": "CIDRIPアドレス、またはクライアントIDのリスト。設定されている場合、AdGuard HomeはこれらのIPアドレスからのリクエストを破棄します。「許可されたクライアント」欄が設定されている場合、この欄は無視されます。",
"access_blocked_title": "拒否するドメイン",
"access_blocked_desc": "こちらをフィルタと混同しないでください。AdGuard Homeは、ここで入力されたドメインに一致するDNSクエリをドロップし、そういったクエリはクエリログにも表示されません。ここでは、「example.org」、「*.example.org」、「 ||example.org^ 」など、特定のドメイン名、ワイルドカード、URLフィルタルールを入力できます。",
"access_settings_saved": "アクセス設定の保存に成功しました",
@@ -481,10 +486,12 @@
"encryption_key_source_content": "秘密鍵の内容をペーストする",
"stats_params": "統計設定",
"config_successfully_saved": "設定の保存に成功しました",
"interval_6_hour": "6時間",
"interval_24_hour": "24時間",
"interval_days": "{{count}}日",
"interval_days_plural": "{{count}}日",
"domain": "ドメイン",
"punycode": "Punycode",
"answer": "応答",
"filter_added_successfully": "フィルタの追加に成功しました",
"filter_removed_successfully": "リストの削除に成功しました。",
@@ -590,6 +597,8 @@
"cache_ttl_min_override_desc": "DNS応答をキャッシュするとき、上流サーバから受信した短いTTL秒単位を延長します",
"cache_ttl_max_override_desc": "DNSキャッシュ内のエントリの最大TTL秒単位を設定します",
"ttl_cache_validation": "最小キャッシュTTL値は最大値以下にする必要があります",
"cache_optimistic": "Optimistic (オプティミスティック)",
"cache_optimistic_desc": "エントリの有効期限が切れた場合でも、AdGuard Homeがキャッシュから応答するようにし、エントリの更新も試みます。",
"filter_category_general": "一般",
"filter_category_security": "セキュリティ",
"filter_category_regional": "地域別",

View File

@@ -68,6 +68,9 @@
"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": "도시",
@@ -109,6 +112,8 @@
"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": "차단된 도메인",
@@ -319,12 +324,12 @@
"install_devices_router_list_2": "각각 1~3자리 숫자의 네 그룹으로 분할된 두 세트의 숫자를 허용하는 필드 옆에 있는 DNS 문자를 찾으세요.",
"install_devices_router_list_3": "AdGuard Home 서버 주소를 입력하세요",
"install_devices_router_list_4": "일부 라우터 유형에서는 사용자 정의 DNS 서버를 설정할 수 없습니다. 이 경우에는 AdGuard Home을 <0>DHCP 서버</0>로 설정할 수 있습니다. 그렇지 않으면 특정 라우터 모델에 맞게 DNS 서버를 설정하는 방법을 찾아야 합니다.",
"install_devices_windows_list_1": "시작 메뉴 또는 윈도우 검색을 통해 제어판을 여세요",
"install_devices_windows_list_2": "네트워크 및 인터넷 카테고리로 이동한 다음 네트워크 및 공유 센터로 이동하세요.",
"install_devices_windows_list_3": "화면 왼쪽에서 어댑터 설정 변경을 찾아 클릭하세요.",
"install_devices_windows_list_4": "활성 연결을 선택한 후 우클릭으로 속성을 선택하세요.",
"install_devices_windows_list_5": "목록에서 인터넷 프로토콜 버전 4 (TCP/IP) 를 찾아 선택하고 속성을 다시 클릭하세요.",
"install_devices_windows_list_6": "다음 DNS 서버 주소 사용을 선택하고 AdGuard Home 서버 주소 입력하세요.",
"install_devices_windows_list_1": "시작 메뉴 또는 윈도우 검색을 통해 제어판을 엽니다.",
"install_devices_windows_list_2": "네트워크 및 인터넷 카테고리로 이동한 다음 네트워크 및 공유 센터로 이동합니다.",
"install_devices_windows_list_3": "화면 왼쪽에서 '어댑터 설정 변경'을 찾아 클릭합니다.",
"install_devices_windows_list_4": "활성 연결을 선택한 후 우클릭으로 속성을 선택합니다.",
"install_devices_windows_list_5": "목록에서 '인터넷 프로토콜 버전 4(TCP/IP)' (또는 IPv6의 경우 '인터넷 프로토콜 버전 6(TCP/IPv6)')를 찾아 선택하고 속성을 클릭합니다.",
"install_devices_windows_list_6": "'DNS 서버 주소 사용'을 선택하고 AdGuard Home 서버 주소 입력합니다.",
"install_devices_macos_list_1": "Apple 아이콘을 클릭하고 시스템 기본 설정으로 이동하세요.",
"install_devices_macos_list_2": "네트워크를 클릭하세요.",
"install_devices_macos_list_3": "목록에서 첫 번째 연결을 선택하고 고급을 클릭해주세요.",
@@ -423,9 +428,9 @@
"access_title": "접근 설정",
"access_desc": "여기에서 AdGuard Home DNS 서버에 대한 액세스 규칙을 구성할 수 있습니다.",
"access_allowed_title": "허용된 클라이언트",
"access_allowed_desc": "CIDR 또는 IP 주소 목록입니다. 구성된 경우 AdGuard Home은 이러한 IP 주소의 요청만 수락할 수 있습니다.",
"access_allowed_desc": "CIDR, IP 주소 또는 클라이언트 ID 목록입니다. 허용된 클라이언트가 구성된 경우, AdGuard Home은 이 클라이언트의 요청만 수락니다.",
"access_disallowed_title": "차단된 클라이언트",
"access_disallowed_desc": "CIDR 또는 IP 주소 목록입니다. 구성된 경우 AdGuard Home은 이러한 IP 주소의 요청을 삭제합니다.",
"access_disallowed_desc": "CIDR, IP 주소 또는 클라이언트 ID 목록입니다. 차단된 클라이언트가 구성된 경우, AdGuard Home은 이 클라이언트의 요청을 무시합니다. 허용된 클라이언트가 구성된 경우, 이 필드는 무시됩니다.",
"access_blocked_title": "차단된 도메인",
"access_blocked_desc": "이 기능을 필터와 혼동하지 마세요. AdGuard Home은 이 도메인에 대한 DNS 요청을 무시합니다. 여기에서는 'example.org' '*. example.org', '|| example.org ^'와 같은 특정 도메인 이름, 와일드 카드, URL 필터 규칙을 지정할 수 있습니다.",
"access_settings_saved": "액세스 설정이 성공적으로 저장되었습니다.",
@@ -481,10 +486,12 @@
"encryption_key_source_content": "비밀키 내용 붙여넣기",
"stats_params": "통계 구성",
"config_successfully_saved": "설정이 성공적으로 저장되었습니다.",
"interval_6_hour": "6시간",
"interval_24_hour": "24시간",
"interval_days": "{{count}} 일",
"interval_days_plural": "{{count}} 일",
"domain": "도메인",
"punycode": "Punycode",
"answer": "응답",
"filter_added_successfully": "목록이 성공적으로 추가됨",
"filter_removed_successfully": "목록이 성공적으로 제거되었습니다",
@@ -590,6 +597,8 @@
"cache_ttl_min_override_desc": "업스트림 서버에서 수신한 TTL 값(최소)을 무시합니다",
"cache_ttl_max_override_desc": "업스트림 서버에서 수신한 TTL 값(최대)을 무시합니다",
"ttl_cache_validation": "최소 캐시 TTL 값은 최대 값보다 이하여야 합니다",
"cache_optimistic": "캐시 유지",
"cache_optimistic_desc": "세션이 만료되었거나 새로고침을 시도하는 경우에도 AdGuard Home이 캐시를 기반으로 응답하도록 합니다.",
"filter_category_general": "일반 목록",
"filter_category_security": "보안 목록",
"filter_category_regional": "지역 목록",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "van de laatste 24-uur",
"for_last_days": "sinds de laatste {{count}} dagen",
"for_last_days_plural": "sinds de laatste {{count}} dagen",
"stats_disabled": "Statistieken zijn uitgeschakeld. Je kunt ze inschakelen op de <0>instellingen pagina</0>.",
"stats_disabled_short": "Statistieken zijn uitgeschakeld",
"no_domains_found": "Geen domeinen gevonden",
"requests_count": "Verzoek teller",
"top_blocked_domains": "Top geblokkeerde domeinen",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Je kan een DNS-server niet instellen op sommige routers. In dat geval kan het een oplossing zijn om AdGuard Home te definiëren als een <0>DHCP-server</0>. Je kan ook in de handleiding van je router kijken hoe je een DNS-server aanpast.",
"install_devices_windows_list_1": "Open het Configuratiescherm via het menu Start of Windows zoeken.",
"install_devices_windows_list_2": "Ga naar de categorie Netwerk en Internet en vervolgens naar Netwerkcentrum.",
"install_devices_windows_list_3": "Zoek aan de linkerkant van het scherm Adapter-instellingen wijzigen en klik erop.",
"install_devices_windows_list_3": "Zoek aan de linkerkant van het scherm \"Adapter-instellingen wijzigen\" en klik erop.",
"install_devices_windows_list_4": "Selecteer jouw actieve verbinding, klik er met de rechtermuisknop op en kies Eigenschappen.",
"install_devices_windows_list_5": "Zoek Internet Protocol versie 4 (TCP / IP) in de lijst, selecteer het en klik vervolgens opnieuw op Eigenschappen.",
"install_devices_windows_list_6": "Kies Gebruik de volgende DNS-server adressen en voer jouw AdGuard Home server adressen in.",
"install_devices_windows_list_5": "Zoek \"Internet Protocol versie 4 (TCP/IPv4)\" (of, voor IPv6, \"Internet Protocol versie 6 (TCP/IPv6)\") in de lijst, selecteer het en klik vervolgens opnieuw op Eigenschappen.",
"install_devices_windows_list_6": "Kies \"Gebruik de volgende DNS-serveradressen\" en voer jouw AdGuard Home serveradressen in.",
"install_devices_macos_list_1": "Klik op het Apple-pictogram en ga naar Systeemvoorkeuren.",
"install_devices_macos_list_2": "Klik op Netwerk.",
"install_devices_macos_list_3": "Selecteer de eerste verbinding in jouw lijst en klik op Geavanceerd.",
@@ -426,9 +428,9 @@
"access_title": "Toegangs instellingen",
"access_desc": "Hier kan je toegangsregels voor de AdGuard Home DNS-server instellen.",
"access_allowed_title": "Toegestane gebruikers",
"access_allowed_desc": "Een lijst van CIDR of IP adressen. Indien ingesteld, zal AdGuard Home alleen van deze IP adressen aanvragen accepteren.",
"access_allowed_desc": "Een lijst met CIDR's, IP-adressen of client-ID's. Indien geconfigureerd, accepteert AdGuard Home alleen verzoeken van deze cliënts.",
"access_disallowed_title": "Verworpen gebruikers",
"access_disallowed_desc": "Een lijst van CIDR of IP adressen. Indien ingesteld, zal AdGuard Home aanvragen van deze IP adressen verwerpen.",
"access_disallowed_desc": "Een lijst met CIDR's, IP-adressen of client-ID's. Indien geconfigureerd, zal AdGuard Home verzoeken van deze klanten verwerpen. Als toegestane cliënts zijn geconfigureerd, wordt dit veld genegeerd.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Inhoud privé sleutel plakken",
"stats_params": "Statistieken configuratie",
"config_successfully_saved": "Configuratie succesvol opgeslagen",
"interval_6_hour": "6 uren",
"interval_24_hour": "24 uur",
"interval_days": "{{count}} dagen",
"interval_days_plural": "{{count}} dagen",
"domain": "Domein",
"punycode": "Punycode",
"answer": "Antwoord",
"filter_added_successfully": "De lijst is succesvol toegevoegd",
"filter_removed_successfully": "De lijst is succesvol verwijderd",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Uitbreiden van korte Time-To-Live waardes (seconden) ontvangen van de upstream server bij het cachen van DNS antwoorden",
"cache_ttl_max_override_desc": "Instellen van maximum time-to-live waarde (seconden) voor opslag in de DNS cache",
"ttl_cache_validation": "Minimale waarde TTL-cache moet kleiner dan of gelijk zijn aan de maximale waarde",
"cache_optimistic": "Optimistisch",
"cache_optimistic_desc": "Laat AdGuard Home reageren vanuit de cache, zelfs als de vermeldingen zijn verlopen en probeer deze ook te vernieuwen.",
"filter_category_general": "Algemeen",
"filter_category_security": "Beveiliging",
"filter_category_regional": "Regionaal",

View File

@@ -233,6 +233,7 @@
"dns_over_tls": "DNS-over-TLS",
"dns_over_quic": "DNS-over-QUIC",
"client_id": "Klient-ID",
"client_id_placeholder": "Skriv inn klient-ID",
"download_mobileconfig_doh": "Last ned .mobileconfig for DNS-over-HTTPS",
"download_mobileconfig_dot": "Last ned .mobileconfig for DNS-over-TLS",
"plain_dns": "Ordinær DNS",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "przez ostatnie 24 godziny",
"for_last_days": "z ostatniego dnia",
"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",
"no_domains_found": "Nie znaleziono domen",
"requests_count": "Licznik żądań",
"top_blocked_domains": "Najpopularniejsze zablokowane domeny",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Na niektórych typach routerów nie można skonfigurować własnego serwera DNS. W takim przypadku pomocne może być skonfigurowanie AdGuard Home jako <0>serwera DHCP</0>. W przeciwnym razie należy sprawdzić w instrukcji obsługi routera, jak dostosować serwery DNS do konkretnego modelu routera.",
"install_devices_windows_list_1": "Otwórz panel Ustawienia w menu Start lub w Windows.",
"install_devices_windows_list_2": "Przejdź do kategorii Sieć i Internet, a następnie do Centrum sieci i udostępniania.",
"install_devices_windows_list_3": "Po lewej stronie ekranu znajdź Zmień ustawienia adaptera i kliknij na niego.",
"install_devices_windows_list_3": "Po lewej stronie ekranu znajdź \"Zmień ustawienia adaptera\" i kliknij na niego.",
"install_devices_windows_list_4": "Wybierz aktywne połączenie, kliknij je prawym przyciskiem myszy i wybierz Właściwości.",
"install_devices_windows_list_5": "Znajdź na liście protokół internetowy w wersji 4 (TCP/IP), zaznacz go, a następnie ponownie kliknij Właściwości.",
"install_devices_windows_list_6": "Wybierz Użyj następujących adresów serwerów DNS i wpisz adresy serwerów AdGuard Home.",
"install_devices_windows_list_5": "Znajdź na liście \"Protokół internetowy w wersji 4 (TCP/IPv4)\" (lub w przypadku IPv6 \"Protokół internetowy w wersji 6 (TCP/IPv6)\"), zaznacz go i ponownie kliknij na Właściwości.",
"install_devices_windows_list_6": "Wybierz opcję \"Użyj następujących adresów serwerów DNS\" i wprowadź adresy serwerów AdGuard Home.",
"install_devices_macos_list_1": "Kliknij ikonę Apple i przejdź do Preferencje systemowe.",
"install_devices_macos_list_2": "Kliknij Sieć.",
"install_devices_macos_list_3": "Wybierz pierwsze połączenie z listy i kliknij Zaawansowane.",
@@ -426,9 +428,9 @@
"access_title": "Ustawienia dostępu",
"access_desc": "Tutaj możesz skonfigurować reguły dostępu dla serwera DNS AdGuard Home.",
"access_allowed_title": "Dozwoleni klienci",
"access_allowed_desc": "Lista adresów CIDR lub IP. Jeśli jest skonfigurowany, AdGuard Home akceptuje tylko żądania z tych adresów IP.",
"access_allowed_desc": "Lista CIDR-ów, adresów IP lub identyfikatorów klientów. Jeśli zostanie skonfigurowana, AdGuard Home będzie przyjmował żądania tylko od tych klientów.",
"access_disallowed_title": "Niedozwoleni klienci",
"access_disallowed_desc": "Lista adresów CIDR lub IP. Po skonfigurowaniu AdGuard Home usunie żądania z tych adresów IP.",
"access_disallowed_desc": "Lista CIDR-ów, adresów IP lub identyfikatorów klientów. Jeśli jest skonfigurowana, AdGuard Home będzie odrzucał żądania od tych klientów. Jeśli skonfigurowano dozwolonych klientów, pole to jest ignorowane.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Wklej zawartość klucza prywatnego",
"stats_params": "Konfiguracja statystyk",
"config_successfully_saved": "Konfiguracja została pomyślnie zapisana",
"interval_6_hour": "6 godzin",
"interval_24_hour": "24 godziny",
"interval_days": "{{count}} dni",
"interval_days_plural": "{{count}} dni",
"domain": "Domena",
"punycode": "Punycode",
"answer": "Odpowiedź",
"filter_added_successfully": "Lista została pomyślnie dodana",
"filter_removed_successfully": "Lista została usunięta",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Zastąp wartość TTL (w sekundach) otrzymaną z serwera nadrzędnego podczas buforowania odpowiedzi DNS",
"cache_ttl_max_override_desc": "Ustaw maksymalną wartość TTL (w sekundach) dla wpisów w pamięci podręcznej DNS",
"ttl_cache_validation": "Minimalna pamięć podręczna wartości TTL musi być mniejsza lub równa maksymalnej wartości",
"cache_optimistic": "Optymistyczny",
"cache_optimistic_desc": "Spraw, aby AdGuard Home odpowiadał z pamięci podręcznej, nawet gdy wpisy wygasły, a także spróbuj je odświeżyć.",
"filter_category_general": "Ogólne",
"filter_category_security": "Bezpieczeństwo",
"filter_category_regional": "Regionalne",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "nas últimas 24 horas",
"for_last_days": "nos últimos {{count}} dias",
"for_last_days_plural": "nos últimos {{count}} dias",
"stats_disabled": "As estatísticas foram desativadas. Você pode ligá-las através da <0>página de configurações</0>.",
"stats_disabled_short": "As estatísticas foram desativadas",
"no_domains_found": "Nenhum domínio encontrado",
"requests_count": "Contagem de solicitações",
"top_blocked_domains": "Principais domínios bloqueados",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Em alguns tipos de roteador, um servidor DNS personalizado não pode ser configurado. Nesse caso, configurar o AdGuard Home como um <0>Servidor DHCP</0> pode ajudar. Caso contrário, você deve verificar o manual do roteador sobre como personalizar os servidores DNS em seu modelo de roteador específico.",
"install_devices_windows_list_1": "Abra o Painel de Controle pelo Menu Iniciar ou pela Pesquisa do Windows.",
"install_devices_windows_list_2": "Entre na categoria Rede e Internet e depois clique em Central de Rede e Compartilhamento.",
"install_devices_windows_list_3": "No lado esquerdo da janela clique em Alterar as configurações do adaptador.",
"install_devices_windows_list_3": "No lado esquerdo da janela clique em \"Alterar as configurações do adaptador\".",
"install_devices_windows_list_4": "Selecione sua atual conexão, clique nela com o botão direito do mouse e depois clique em Propriedades.",
"install_devices_windows_list_5": "Procure na lista por Internet Protocol Version 4 (TCP/IP), selecione e clique em Propriedades novamente.",
"install_devices_windows_list_6": "Marque usar os seguintes endereços de servidor DNS e digite os endereços do servidores do AdGuard Home.",
"install_devices_windows_list_5": "Procure na lista por \"Internet Protocol Version 4 (TCP/IP)\" (ou por IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\"), selecione e clique em Propriedades novamente.",
"install_devices_windows_list_6": "Marque \"usar os seguintes endereços de servidor DNS\" e digite os endereços do servidores do AdGuard Home.",
"install_devices_macos_list_1": "Clique na ícone da Apple e depois em Preferências do Sistema.",
"install_devices_macos_list_2": "Clique em Rede.",
"install_devices_macos_list_3": "Selecione a primeira conexão da lista e clique em Avançado.",
@@ -426,9 +428,9 @@
"access_title": "Configurações de acessos",
"access_desc": "Aqui você pode configurar as regras de acesso para o servidores de DNS do AdGuard Home.",
"access_allowed_title": "Clientes permitidos",
"access_allowed_desc": "Uma lista de endereços IP ou CIDR. Ao configurar, o AdGuard Home irá permitir solicitações apenas desses endereços de IP.",
"access_allowed_desc": "Uma lista de CIDRs, endereços IP ou IDs de cliente. Se configurado, o AdGuard Home do aceitará solicitações apenas desses clientes.",
"access_disallowed_title": "Clientes não permitidos",
"access_disallowed_desc": "Uma lista de endereços IP ou CIDR. Ao configurar, o AdGuard Home irá descartar as solicitações desses endereços de IP.",
"access_disallowed_desc": "Uma lista de CIDRs, endereços IP ou IDs de cliente. Se configurado, o AdGuard Home descartará as solicitações desses clientes. Se clientes permitidos estiverem configurados, este campo será ignorado.",
"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",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Colar o conteúdo da chave privada",
"stats_params": "Configuração de estatísticas",
"config_successfully_saved": "Configuração salva com sucesso",
"interval_6_hour": "6 horas",
"interval_24_hour": "24 horas",
"interval_days": "{{count}} dias",
"interval_days_plural": "{{count}} dias",
"domain": "Domínio",
"punycode": "Punycode",
"answer": "Resposta",
"filter_added_successfully": "O filtro foi adicionado com sucesso",
"filter_removed_successfully": "A lista foi removida com sucesso",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Prolongue os valores de curta duração (segundos) recebidos do servidor primário ao armazenar em cache as respostas DNS",
"cache_ttl_max_override_desc": "Defina um valor máximo de tempo de vida (segundos) para entradas no cache DNS",
"ttl_cache_validation": "O valor TTL mínimo do cache deve ser menor ou igual ao valor máximo",
"cache_optimistic": "Otimista",
"cache_optimistic_desc": "Faz o AdGuard Home responder a partir do cache mesmo quando as entradas expirarem e também tenta atualizá-las.",
"filter_category_general": "Geral",
"filter_category_security": "Segurança",
"filter_category_regional": "Regional",

View File

@@ -107,11 +107,13 @@
"dns_query": "Consultas de DNS",
"blocked_by": "<0>Bloqueado por filtros</0>",
"stats_malware_phishing": "Malware/phishing bloqueados",
"stats_adult": "Sites adultos bloqueados",
"stats_adult": "Sítios adultos bloqueados",
"stats_query_domain": "Principais domínios consultados",
"for_last_24_hours": "nas últimas 24 horas",
"for_last_days": "nos últimos {{count}} dias",
"for_last_days_plural": "nos últimos {{count}} dias",
"stats_disabled": "As estatísticas foram desativadas. Você pode ligá-las através da <0>página de definições</0>.",
"stats_disabled_short": "As estatísticas foram desativadas",
"no_domains_found": "Não foram encontrados domínios",
"requests_count": "Contagem de solicitações",
"top_blocked_domains": "Principais domínios bloqueados",
@@ -324,10 +326,10 @@
"install_devices_router_list_4": "Em alguns tipos de roteador, um servidor DNS personalizado não pode ser configurado. Nesse caso, configurar o AdGuard Home como um <0>Servidor DHCP</0> pode ajudar. Caso contrário, tu deve verificar o manual do router sobre como personalizar os servidores DNS em seu modelo de router específico.",
"install_devices_windows_list_1": "Abra o Painel de Controlo através do Menu Iniciar ou pela Pesquisa do Windows.",
"install_devices_windows_list_2": "Entre na categoria Rede e Internet e depois clique em Central de Rede e Partilha.",
"install_devices_windows_list_3": "No lado esquerdo da janela clique em Alterar as definições do adaptador.",
"install_devices_windows_list_3": "No lado esquerdo da janela clique em \"Alterar as definições do adaptador\".",
"install_devices_windows_list_4": "Selecione sua atual ligação, clique nela com o botão direito do rato e depois clique em Propriedades.",
"install_devices_windows_list_5": "Procure na lista por Internet Protocol Version 4 (TCP/IP), selecione e clique novamente em Propriedades.",
"install_devices_windows_list_6": "Marque Usar os seguintes endereços de servidor DNS e insira os endereços do servidores do AdGuard Home.",
"install_devices_windows_list_5": "Procure na lista por \"Internet Protocol Version 4 (TCP/IP)\" (ou por IPv6, \"Internet Protocol Version 6 (TCP/IPv6)\"), selecione e clique em Propriedades novamente.",
"install_devices_windows_list_6": "Marque \"Usar os seguintes endereços de servidor DNS\" e insira os endereços do servidores do AdGuard Home.",
"install_devices_macos_list_1": "Clique na ícone da Apple e depois em Preferências do Sistema.",
"install_devices_macos_list_2": "Clique em Rede.",
"install_devices_macos_list_3": "Selecione a primeira ligação da lista e clique em Avançado.",
@@ -426,9 +428,9 @@
"access_title": "Definições de acesso",
"access_desc": "Aqui pode configurar as regras de acesso para o servidores de DNS do AdGuard Home.",
"access_allowed_title": "Clientes permitidos",
"access_allowed_desc": "Uma lista de endereços IP ou CIDR. Ao configurar, o AdGuard Home irá permitir solicitações apenas desses endereços de IP.",
"access_allowed_desc": "Uma lista de CIDRs, endereços IP ou IDs de cliente. Se configurado, o AdGuard Home do aceitará solicitações apenas desses clientes.",
"access_disallowed_title": "Clientes não permitidos",
"access_disallowed_desc": "Uma lista de endereços IP ou CIDR. Ao configurar, o AdGuard Home irá descartar as solicitações desses endereços de IP.",
"access_disallowed_desc": "Uma lista de CIDRs, endereços IP ou IDs de cliente. Se configurado, o AdGuard Home descartará as solicitações desses clientes. Se clientes permitidos estiverem configurados, este campo será ignorado.",
"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",
@@ -470,7 +472,7 @@
"main_settings": "Definições principais",
"block_services": "Bloquear serviços específicos",
"blocked_services": "Serviços bloqueados",
"blocked_services_desc": "Permite o bloqueio rápido de sites e serviços populares.",
"blocked_services_desc": "Permite o bloqueio rápido de sítios e serviços populares.",
"blocked_services_saved": "Serviços bloqueados guardados com sucesso",
"blocked_services_global": "Usar serviços bloqueados globais",
"blocked_service": "Serviço bloqueado",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Colar o conteúdo da chave privada",
"stats_params": "Definição de estatísticas",
"config_successfully_saved": "Definição guardada com sucesso",
"interval_6_hour": "6 horas",
"interval_24_hour": "24 horas",
"interval_days": "{{count}} dias",
"interval_days_plural": "{{count}} dias",
"domain": "Domínio",
"punycode": "Punycode",
"answer": "Resposta",
"filter_added_successfully": "O filtro foi adicionado com sucesso",
"filter_removed_successfully": "A lista foi removida com sucesso",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Prolongue os valores de curta duração (segundos) recebidos do servidor primário ao armazenar em cache as respostas DNS",
"cache_ttl_max_override_desc": "Defina um valor máximo de tempo de vida (segundos) para entradas no cache DNS",
"ttl_cache_validation": "O valor TTL mínimo do cache deve ser menor ou igual ao valor máximo",
"cache_optimistic": "Otimista",
"cache_optimistic_desc": "Faz o AdGuard Home responder a partir do cache mesmo quando as entradas expirarem e também tenta atualizá-las.",
"filter_category_general": "Geral",
"filter_category_security": "Segurança",
"filter_category_regional": "Regional",

View File

@@ -1,10 +1,24 @@
{
"client_settings": "Setări client",
"example_upstream_reserved": "Puteți specifica un DNS în amonte <0>pentru domeniul (domeniile) specific(e)</0>",
"example_upstream_comment": "Puteți specifica un comentariu",
"upstream_parallel": "Folosiți interogări paralele pentru a accelera rezolvarea, interogând simultan toate serverele în amonte.",
"parallel_requests": "Solicitări paralele",
"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.",
"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_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",
"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",
"enabled_dhcp": "Server DHCP activat",
"disabled_dhcp": "Server DHCP dezactivat",
"unavailable_dhcp": "DHCP este indisponibil",
@@ -13,10 +27,12 @@
"dhcp_description": "Dacă routerul dvs. nu furnizează setări DHCP, puteți utiliza serverul DHCP încorporat AdGuard.",
"dhcp_enable": "Activați serverul DHCP",
"dhcp_disable": "Dezactivați serverul DHCP",
"dhcp_not_found": "Este sigur să activați serverul DHCP încorporat deoarece AdGuard Home nu a găsit niciun server DHCP activ în rețea. Cu toate acestea, ar trebui să verificați din nou manual, deoarece sondarea automată nu oferă în prezent o garanție de 100%.",
"dhcp_found": "În rețea se găsește un server DHCP activ. Nu este sigur să activați serverul DHCP încorporat.",
"dhcp_leases": "DHCP închiriate",
"dhcp_static_leases": "DHCP statice închiriate",
"dhcp_leases_not_found": "Nu s-au găsit DHCP închiriate",
"dhcp_config_saved": "Configurare DHCP salvată cu succes",
"dhcp_ipv4_settings": "Setări DHCP IPv4",
"dhcp_ipv6_settings": "Setări DHCP IPv6",
"form_error_required": "Câmp necesar",
@@ -26,6 +42,7 @@
"form_error_mac_format": "Format MAC invalid",
"form_error_client_id_format": "Format ID de client invalid",
"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_negative": "Trebuie să fie egală cu 0 sau mai mare",
"range_end_error": "Trebuie să fie mai mare decât începutul intervalului",
@@ -42,11 +59,19 @@
"ip": "IP",
"dhcp_table_hostname": "Hostname",
"dhcp_table_expires": "Expiră",
"dhcp_warning": "Dacă doriți să activați serverul DHCP oricum, asigurați-vă că nu există nici un alt server DHCP activ în rețeaua dvs., deoarece acest lucru poate rupe conectivitatea la Internet a dispozitivelor din rețea!",
"dhcp_error": "AdGuard Home nu a putut determina dacă există un alt server DHCP activ în rețea.",
"dhcp_static_ip_error": "Pentru a utiliza serverul DHCP, trebuie setată o adresă IP statică. AdGuard Home nu a reușit să determine dacă această interfață de rețea este configurată utilizând o adresă IP statică. Setați manual o adresă IP statică.",
"dhcp_dynamic_ip_found": "Sistemul dvs. folosește configurația dinamică a adreselor IP pentru interfața <0>{{interfaceName}}</0>. Pentru a utiliza serverul DHCP, trebuie setată o adresă IP statică. Adresa IP curentă este <0>{{ipAddress}}</0>. AdGuard Home o va configura automat ca adresă IP statică, dacă apăsați butonul \"Activați serverul DHCP\".",
"dhcp_lease_added": "\"{{key}}\" statică închiriată adăugată cu succes",
"dhcp_lease_deleted": "\"{{key}}\" statică închiriată eliminată cu succes",
"dhcp_new_static_lease": "Închiriere statică nouă",
"dhcp_static_leases_not_found": "Nu s-au găsit închirieri statice DHCP",
"dhcp_add_static_lease": "Adăugați închiriere statică",
"dhcp_reset_leases": "Resetați toate închirierile",
"dhcp_reset_leases_confirm": "Sigur doriți să resetați toate închirierile?",
"dhcp_reset_leases_success": "Închirierile DHCP au fost resetate cu succes",
"dhcp_reset": "Sigur doriți să resetați configurația DHCP?",
"country": "Țara",
"city": "Oraș",
"delete_confirm": "Sunteți sigur că doriți să ștergeți \"{{key}}\"?",
@@ -93,17 +118,24 @@
"top_clients": "Clienți de top",
"no_clients_found": "Nu au fost găsiți clienți",
"general_statistics": "Statistici generale",
"number_of_dns_query_days": "Numărul de interogări DNS procesate în ultima {{count}} zi",
"number_of_dns_query_days_plural": "Numărul de interogări DNS procesate în ultimele {{count}} zile",
"number_of_dns_query_24_hours": "Numărul de interogări DNS procesate în ultimele 24 de ore",
"number_of_dns_query_blocked_24_hours": "Numărul de interogări DNS blocate de filtrele adblock și lista de blocări din hosts",
"number_of_dns_query_blocked_24_hours_by_sec": "Numărul de interogări DNS blocate de modulul de securitate de navigare AdGuard",
"number_of_dns_query_blocked_24_hours_adult": "Numărul de site-uri pentru adulți blocate",
"enforced_save_search": "Căutare protejată întărită",
"number_of_dns_query_to_safe_search": "Numărul de interogări DNS pe motoarele de căutare pentru care a fost impusă Căutarea Sigură",
"average_processing_time": "Timpul mediu de procesare",
"average_processing_time_hint": "Timp mediu în milisecunde la procesarea unei cereri DNS",
"block_domain_use_filters_and_hosts": "Blocați domenii folosind filtre și fișiere hosts",
"filters_block_toggle_hint": "Puteți configura regulile de blocare în setările <a>Filtre</a>.",
"use_adguard_browsing_sec": "Utilizați serviciul Navigarea în Securitate AdGuard",
"use_adguard_browsing_sec_hint": "AdGuard Home va verifica dacă domeniul este în lista de blocări a serviciul web de securitate de navigare. Pentru acesta va utiliza un lookup API discret: un prefix scurt al numelui de domeniu SHA256 hash este trimis serverului.",
"use_adguard_browsing_sec_hint": "AdGuard Home va verifica dacă domeniul este blocat de serviciul web de securitate de navigare. Pentru acesta, va utiliza un API de căutare discret: numai un prefix scurt al hash-ului SHA256 al numelui de domeniu este trimis la server.",
"use_adguard_parental": "Utilizați Controlul Parental AdGuard",
"use_adguard_parental_hint": "AdGuard Home va verifica pentru conținut adult pe domeniu. Utilizează același API discret ca cel utilizat de serviciul de securitate de navigare.",
"enforce_safe_search": "Căutare protejată întărită",
"enforce_save_search_hint": "AdGuard Home poate impune căutarea protejată în următoarele motoare de căutare: Google, YouTube, Bing, DuckDuckGo, Yandex, Pixabay.",
"enforce_safe_search": "Folosiți Căutarea Sigură",
"enforce_save_search_hint": "AdGuard Home va impune Căutarea Sigură în următoarele motoare de căutare: Google, YouTube, Bing, DuckDuckGo, Yandex, Pixabay.",
"no_servers_specified": "Nu sunt specificate servere",
"general_settings": "Setări Generale",
"dns_settings": "Setări DNS",
@@ -115,6 +147,7 @@
"encryption_settings": "Setări de criptare",
"dhcp_settings": "Setări DHCP",
"upstream_dns": "Servere DNS în amonte",
"upstream_dns_help": "Introduceți o adresă de server pe linie. <a>Aflați mai multe</a> despre configurarea serverelor DNS în amonte.",
"upstream_dns_configured_in_file": "Configurat în {{path}}",
"test_upstream_btn": "Testați upstreams",
"upstreams": "Upstreams",
@@ -241,8 +274,9 @@
"plain_dns": "DNS simplu",
"form_enter_rate_limit": "Introduceți limita ratei",
"rate_limit": "Limita ratei",
"edns_enable": "Activați clientul subnet EDNS",
"edns_cs_desc": "Dacă este activat, AdGuard Home va trimite subnet-ul clienților către serverele DNS.",
"edns_enable": "Activați subrețeaua de clienți EDNS",
"edns_cs_desc": "Trimite subrețelele clienților la serverele DNS.",
"rate_limit_desc": "Numărul de interogări pe secundă permise pe client. Setarea la 0 înseamnă că nu există limită.",
"blocking_ipv4_desc": "Adresa IP de returnat pentru o cerere A de blocare",
"blocking_ipv6_desc": "Adresa IP de returnat pentru o cerere AAAA de blocare",
"blocking_mode_default": "Implicit: Răspunde cu adresa IP (0.0.0.0 for A; :: pentru AAAA) când sunt blocate de regulă tip Adblock; răspunde cu adresa IP specificată în regulă când sunt blocate de regula tip /etc/hosts",
@@ -265,6 +299,7 @@
"install_settings_listen": "Interfață de ascultare",
"install_settings_port": "Port",
"install_settings_interface_link": "Interfața dvs. de administrare AdGuard Home va fi disponibilă pe următoarele adrese:",
"form_error_port": "Introduceți un număr de port valid",
"install_settings_dns": "Server DNS",
"install_settings_dns_desc": "Va trebui să configurați aparatele sau routerul pentru a utiliza serverul DNS pe următoarele adrese:",
"install_settings_all_interfaces": "Toate interfețele",
@@ -279,12 +314,14 @@
"install_devices_title": "Configurați aparatele dvs",
"install_devices_desc": "Pentru a începe să utilizați AdGuard Home, trebuie să configurați aparatele.",
"install_submit_title": "Felicitări!",
"install_submit_desc": "Etapa de instalare este terminată și sunteți gata să începeți utilizarea AdGuard Home.",
"install_submit_desc": "Procedura de configurare este finalizată și acum sunteți gata să începeți utilizați AdGuard Home.",
"install_devices_router": "Router",
"install_devices_router_desc": "Această configurație va acoperi automat toate aparatele conectate la routerul de acasă și nu va trebui să le configurați manual pe fiecare.",
"install_devices_router_desc": "Această configurare acoperă automat toate dispozitivele conectate la routerul de acasă, nu este nevoie să le configurați manual.",
"install_devices_address": "Serverul DNS AdGuard Home ascultă pe următoarele adrese",
"install_devices_router_list_1": "Deschideți preferințele routerului dvs. De obicei, îl puteți accesa din browser printr-o adresă URL cum ar fi http://192.168.0.1/ sau http://192.168.1.1/. Vi se poate cere să introduceți o parolă. Dacă nu v-o amintiți, adesea puteți reseta parola apăsând un buton de pe routerul propriu-zis, dar fiți conștienți, că prin acest procedeu puteți pierde întreaga configurație a routerului. \nDacă routerul dvs. necesită o aplicație pentru configurare, instalați aplicația pe telefon sau pe PC și utilizați-o pentru a accesa setările routerului.",
"install_devices_router_list_2": "Găsiți setările DHCP/DNS. Căutați literele DNS lângă un câmp care să permită două sau trei seturi de numere, fiecare împărțit în patru grupuri de una până la trei cifre.",
"install_devices_router_list_3": "Introduceți adresele serverului dvs. AdGuard Home aici.",
"install_devices_router_list_4": "Unele tipuri de routere, nu permit configurarea unui server DNS personalizat. În acest caz, configurarea AdGuard Home ca un <0>server DHCP</0>vă poate ajuta. Dacă nu, ar trebui verificat manualul routerului dvs. specific, ca să aflați cum se pot personaliza serverele DNS.",
"install_devices_windows_list_1": "Deschideți panoul de control prin meniul Start sau căutare Windows.",
"install_devices_windows_list_2": "Accesați categoria \"Rețea și Internet\", apoi la \"Centrul de Rețea și Partajare\".",
"install_devices_windows_list_3": "În partea stângă a ecranului găsiți \"Schimbare setări adaptor\" și clicați pe el.",
@@ -299,7 +336,7 @@
"install_devices_android_list_2": "Tapați Wi-Fi din meniu. Ecranul cu toate rețelele disponibile va fi afișat (este imposibil să setați DNS personalizat pentru conexiunea mobilă).",
"install_devices_android_list_3": "Apăsați lung pe rețeaua la care sunteți conectat și tapați Modificare Rețea.",
"install_devices_android_list_4": "Pe unele aparate, poate fi necesar să bifați caseta Advanced pentru a vedea setările adiționale. Pentru a ajusta setările DNS Android, va trebui să comutați setările IP de la DHCP la Static.",
"install_devices_android_list_5": "Schimbați valorile DNS 1 și DNS 2 la cele ale serverului dvs. AdGuard Home.",
"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.",
@@ -310,6 +347,7 @@
"install_saved": "Salvat cu succes",
"encryption_title": "Criptare",
"encryption_desc": "Suport de Criptare (HTTPS/TLS) pentru DNS și interfața web administrator",
"encryption_config_saved": "Configurația de criptare salvată",
"encryption_server": "Nume de server",
"encryption_server_enter": "Introduceți numele domeniului",
"encryption_server_desc": "Pentru a utiliza HTTPS, trebuie să introduceți numele serverului care se potrivește cu certificatul SSL sau certificatul wildcard al dvs. În cazul în care câmpul nu este setat, va accepta conexiuni TLS pentru orice domeniu.",
@@ -340,10 +378,13 @@
"encryption_reset": "Sunteți sigur că doriți să resetați setările de criptare?",
"topline_expiring_certificate": "Certificatul dvs. SSL este pe cale să expire. Actualizați <0>Setările de criptare</0>.",
"topline_expired_certificate": "Certificatul dvs. SSL a expirat. Actualizați <0>Setările de criptare</0>.",
"form_error_port_range": "Introduceți valoarea portului între 80-65535",
"form_error_port_unsafe": "Acesta este un port nesigur",
"form_error_equal": "Nu trebuie să fie egale",
"form_error_password": "Parolele nu corespund",
"reset_settings": "Resetare setări",
"update_announcement": "AdGuard Home {{version}} este disponibil! <0>Clicați aici</0> pentru mai multe informații.",
"setup_guide": "Ghid de instalare",
"dns_addresses": "Adrese DNS",
"dns_start": "Serverul DNS demarează",
"dns_status_error": "Eroare la verificare statut server DNS",
@@ -365,8 +406,9 @@
"client_edit": "Editare client",
"client_identifier": "Identificator",
"ip_address": "Adresa IP",
"client_identifier_desc": "Clienții pot fi identificați prin adresa IP, CIDR, adresa MAC sau un ID special al clientului (poate fi folosit pentru DoT/DoH/DoQ). <0>Aici</0> puteți afla mai multe despre cum să identificați clienții.",
"client_identifier_desc": "Clienții pot fi identificați prin adresa IP, CIDR, adresa MAC sau un ID client special (poate fi folosit pentru DoT/DoH/DoQ). <0>Aici</0> puteți afla mai multe despre cum să identificați clienții.",
"form_enter_ip": "Introduceți IP",
"form_enter_subnet_ip": "Introduceți o adresă IP în subrețeaua „{{cidr}}”",
"form_enter_mac": "Introduceți MAC",
"form_enter_id": "Introduceți identificator",
"form_add_id": "Adăugați identificator",
@@ -384,10 +426,11 @@
"access_title": "Setări de acces",
"access_desc": "Aici puteți configura regulile de acces pentru serverul DNS AdGuard Home.",
"access_allowed_title": "Clienți autorizați",
"access_allowed_desc": "O listă de adrese CIDR sau IP. Dacă este configurat, AdGuard Home va accepta doar cereri de la aceste adrese IP.",
"access_allowed_desc": "O listă de adrese CIDR sau IP client. Dacă este configurat, AdGuard Home va accepta cereri numai de la acești clienți.",
"access_disallowed_title": "Clienți neautorizați",
"access_disallowed_desc": "O listă de adrese CIDR sau IP. Dacă este configurat, AdGuard Home va elimina cererile de la aceste adrese IP.",
"access_disallowed_desc": "O listă de adrese CIDR sau IP. Dacă este configurat, AdGuard Home va elimina cereri de la acești clienți. Dacă sunt configurați clienți permiși, acest câmp este ignorat.",
"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_version_equal": "AdGuard Home este la zi",
@@ -441,10 +484,12 @@
"encryption_key_source_content": "Lipiți conținutul cheii private",
"stats_params": "Configurația statisticilor",
"config_successfully_saved": "Configurarea a fost salvată cu succes",
"interval_6_hour": "6 ore",
"interval_24_hour": "24 ore",
"interval_days": "{{count}} zi",
"interval_days_plural": "{{count}} zile",
"domain": "Domeniu",
"punycode": "Punycode",
"answer": "Răspuns",
"filter_added_successfully": "Filtrul a fost adăugat cu succes",
"filter_removed_successfully": "Lista a fost eliminată cu succes",
@@ -487,9 +532,10 @@
"rewrite_domain_name": "Nume de domeniu: adăugați o înregistrare CNAME",
"rewrite_A": "<0>A</0>: valoare specială, păstrați <0>A</0> înregistrări din amonte",
"rewrite_AAAA": "<0>AAAA</0>: valoare specială, păstrați <0>AAAA</0> înregistrări din amonte",
"disable_ipv6": "Dezactivați IPv6",
"disable_ipv6_desc": "Dacă această opțiune este activată, toate interogările DNS pentru adrese IPv6 (tip AAAA) vor fi anulate.",
"disable_ipv6": "Dezactivați rezolvarea adreselor IPv6",
"disable_ipv6_desc": "Anulați toate interogările DNS pentru adresele IPv6 (tip AAAA).",
"fastest_addr": "Cea mai rapidă adresă IP",
"fastest_addr_desc": "Interoghează toate serverele DNS și întoarce adresa IP cea mai rapidă din răspunsuri. Acest lucru încetinește interogările DNS, deoarece AdGuard Home trebuie să aștepte răspunsuri de la toate serverele DNS, dar îmbunătățește conectivitatea generală.",
"autofix_warning_text": "Dacă clicați pe \"Fix\", AdGuardHome va configura sistemul dvs. pentru a utiliza serverul DNS AdGuardHome.",
"autofix_warning_list": "Va efectua aceste sarcini: <0>Dezactivare sistem DNSStubListener</0> <0>Setare adresă server DNS la 127.0.0.1</0> <0>Înlocuire link simbolic țintă /etc/resolv.conf cu /run/systemd/resolve/resolv.conf</0> <0>Oprire DNSStubListener (reîncărcare servici rezolvat prin sistem)</0>",
"autofix_warning_result": "Ca urmare, toate cererile DNS ale sistemul dvs. vor fi procesate în mod implicit de AdGuardHome.",
@@ -519,11 +565,12 @@
"set_static_ip": "Setați o adresă IP statică",
"install_static_ok": "Vești bune! Adresa IP statică este deja configurată",
"install_static_error": "AdGuard Home nu o poate configura automat pentru această interfață de rețea. Vă rugăm să căutați instrucțiuni despre cum să faceți acest lucru manual.",
"install_static_configure": "AdGuard Home a detectat că se folosește adresa IP dinamică <0>{{ip}}</0>. Doriți ca aceasta să fie setată ca adresă statică?",
"confirm_static_ip": "AdGuard Home va configura {{ip}} ca adresa dvs. IP statică. Doriți să continuați?",
"list_updated": "{{count}} listă actualizată",
"list_updated_plural": "{{count}} liste actualizate",
"dnssec_enable": "Activați DNSSEC",
"dnssec_enable_desc": "Setați steagul DNSSEC pe interogările DNS de ieșire și verificați rezultatul (este necesar un resolver DNSSEC activat)",
"dnssec_enable_desc": "Activați semnalul DNSSEC în interogările DNS de ieșire și verificați rezultatul (este necesar un resolver compatibil DNSSEC).",
"validated_with_dnssec": "Validat cu DNSSEC",
"all_queries": "Toate interogările",
"show_blocked_responses": "Blocat",
@@ -553,9 +600,10 @@
"filter_category_regional": "Regional",
"filter_category_other": "Altele",
"filter_category_general_desc": "Liste care blochează urmărirea și publicitatea pe majoritatea aparatelor",
"filter_category_security_desc": "Liste specializate în blocarea domeniilor malware, phishing sau înșelătorie",
"filter_category_security_desc": "Listele concepute special pentru a bloca domenii rău intenționate, phishing și înșelătorie",
"filter_category_regional_desc": "Liste focalizate pe reclame regionale și servere de urmărire",
"filter_category_other_desc": "Alte liste de blocări",
"setup_config_to_enable_dhcp_server": "Setați configurația pentru a activa serverul DHCP",
"original_response": "Răspuns original",
"click_to_view_queries": "Clicați pentru a vizualiza interogări",
"port_53_faq_link": "Portul 53 este adesea ocupat de serviciile \"DNSStubListener\" sau \"systemd-resolved\". Vă rugăm să citiți <0>această instrucțiune</0> despre cum să rezolvați aceasta.",

View File

@@ -5,7 +5,7 @@
"upstream_parallel": "Использовать параллельные запросы ко всем серверам одновременно для ускорения обработки запроса.",
"parallel_requests": "Параллельные запросы",
"load_balancing": "Распределение нагрузки\n",
"load_balancing_desc": "Запрашивайте по одному серверу за раз. AdGuard Home использует взвешенный случайный алгоритм для выбора сервера, так что самый быстрый сервер используется чаще.",
"load_balancing_desc": "Запрашивать по одному серверу за раз. AdGuard Home использует алгоритм взвешенного случайного выбора сервера, так что самый быстрый сервер используется чаще.",
"bootstrap_dns": "Bootstrap DNS-серверы",
"bootstrap_dns_desc": "Bootstrap DNS-серверы используются для поиска IP-адресов DoH/DoT серверов, которые вы указали.",
"local_ptr_title": "Приватные серверы для обратного DNS",
@@ -112,6 +112,8 @@
"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": "Часто блокируемые домены",
@@ -251,8 +253,8 @@
"anonymize_client_ip": "Анонимизировать IP-адрес клиента",
"anonymize_client_ip_desc": "Не сохранять полный IP-адрес клиента в журналах и статистике",
"dns_config": "Настройки DNS-сервера",
"dns_cache_config": "Настройка кэша DNS",
"dns_cache_config_desc": "Здесь можно настроить кэш DNS",
"dns_cache_config": "Настройка кеша DNS",
"dns_cache_config_desc": "Здесь можно настроить кеш DNS",
"blocking_mode": "Режим блокировки",
"default": "Стандартный",
"nxdomain": "NXDOMAIN",
@@ -326,8 +328,8 @@
"install_devices_windows_list_2": "Перейдите в «Сеть и интернет», а затем в «Центр управления сетями и общим доступом»",
"install_devices_windows_list_3": "В левой стороне экрана найдите «Изменение параметров адаптера» и кликните по нему.",
"install_devices_windows_list_4": "Выделите ваше активное подключение, затем кликните по нему правой клавишей мыши и выберите «Свойства».",
"install_devices_windows_list_5": "Найдите в списке пункт «IP версии 4 (TCP/IP)», выделите его и затем снова нажмите «Свойства».",
"install_devices_windows_list_6": "Выберите «Использовать следующие адреса DNS-серверов» и введите адрес AdGuard Home.",
"install_devices_windows_list_5": "Найдите в списке пункт «IP версии 4 (TCP/IPv4)» (или «IP версии 6 (TCP/IPv6)» для IPv6), выделите его и затем снова нажмите «Свойства».",
"install_devices_windows_list_6": "Выберите «Использовать следующие адреса DNS-серверов» и введите адреса серверов AdGuard Home.",
"install_devices_macos_list_1": "Кликните по иконке Apple и перейдите в «Системные настройки».",
"install_devices_macos_list_2": "Кликните по иконке «Сеть».",
"install_devices_macos_list_3": "Выберите первое подключение в списке и нажмите кнопку «Дополнительно».",
@@ -484,6 +486,7 @@
"encryption_key_source_content": "Вставить содержимое закрытого ключа",
"stats_params": "Конфигурация статистики",
"config_successfully_saved": "Конфигурация успешно сохранена",
"interval_6_hour": "6 часов",
"interval_24_hour": "24 часа",
"interval_days": "{{count}} день",
"interval_days_plural": "{{count}} дней",
@@ -593,7 +596,9 @@
"enter_cache_ttl_max_override": "Введите максимальный TTL (в секундах)",
"cache_ttl_min_override_desc": "Расширить короткие TTL-значения (в секундах), полученные с upstream-сервера при кешировании DNS-ответов",
"cache_ttl_max_override_desc": "Установить максимальное TTL-значение (в секундах) для записей в DNS-кэше",
"ttl_cache_validation": "Минимальное значение TTL кеша должно быть меньше или равно максимальному значению",
"ttl_cache_validation": "Минимальное значение TTL-кеша должно быть меньше или равно максимальному значению",
"cache_optimistic": "Оптимистичный",
"cache_optimistic_desc": "AdGuard Home будет отвечать из кеша, даже если ответы в нём неактуальны, и попытается обновить их.",
"filter_category_general": "Общие",
"filter_category_security": "Безопасность",
"filter_category_regional": "Региональные",

View File

@@ -3,7 +3,7 @@
"example_upstream_comment": "ඔබට අදහසක් සඳහන් කළ හැකිය",
"parallel_requests": "සමාන්තර ඉල්ලීම්",
"load_balancing": "ධාරිතාව තුලනය",
"local_ptr_title": "පෞද්ගලික ව.නා.ප. සේවාදායකයන්",
"local_ptr_title": "පෞද්ගලික ප්‍රතිවර්ත ව.නා.ප. සේවාදායකයන්",
"local_ptr_placeholder": "පේළියකට එක් සේවාදායක ලිපිනය බැගින් යොදන්න",
"resolve_clients_title": "අනුග්‍රාහකවල අ.ජා. කෙ. ලිපින ප්‍රතිවර්ත විසඳීම සබල කරන්න",
"check_dhcp_servers": "ග.ධා.වි.කෙ. සේවාදායකයන් සඳහා පරීක්ෂා කරන්න",
@@ -102,8 +102,8 @@
"use_adguard_browsing_sec": "ඇඩ්ගාර්ඩ් පිරික්සුම් ආරක්ෂණ වියමන සේවාව භාවිතා කරන්න",
"use_adguard_parental": "ඇඩ්ගාර්ඩ් දෙමාපිය පාලන වියමන සේවාව භාවිතා කරන්න",
"use_adguard_parental_hint": "වසමේ වැඩිහිටියන්ට අදාල කරුණු අඩංගු දැයි ඇඩ්ගාර්ඩ් හෝම් විසින් පරීක්ෂා කරනු ඇත. එය පිරික්සුම් ආරක්ෂණ වියමන සේවාව මෙන් රහස්‍යතා හිතකාමී යෙ.ක්‍ර. අ.මු. (API) භාවිතා කරයි.",
"enforce_safe_search": "ආරක්ෂිත සෙවීම බලාත්මක කරන්න",
"enforce_save_search_hint": "ඇඩ්ගාර්ඩ් හෝම් හට පහත සෙවුම් යන්ත්‍ර තුළ ආරක්ෂිත සෙවීම බලාත්මක කළ හැකිය: ගූගල්, යූටියුබ්, බින්ග්, ඩක්ඩක්ගෝ, යාන්ඩෙක්ස් සහ පික්සාබේ.",
"enforce_safe_search": "ආරක්ෂිත සෙවීම භාවිතා කරන්න",
"enforce_save_search_hint": "ඇඩ්ගාර්ඩ් හෝම් පහත සෙවුම් යන්ත්‍ර තුළ ආරක්ෂිත සෙවීම බලාත්මක කරනු ඇත: ගූගල්, යූටියුබ්, බින්ග්, ඩක්ඩක්ගෝ, යාන්ඩෙක්ස් සහ පික්සාබේ.",
"no_servers_specified": "සේවාදායක කිසිවක් නිශ්චිතව දක්වා නැත",
"general_settings": "පොදු සැකසුම්",
"dns_settings": "ව.නා.ප. සැකසුම්",
@@ -267,9 +267,9 @@
"install_devices_title": "ඔබගේ උපාංග වින්‍යාසගත කරන්න",
"install_devices_desc": "ඇඩ්ගාර්ඩ් හෝම් භාවිතා කිරීම ආරම්භයට, ඔබගේ උපාංග එය පරිශ්‍රීලනයට වින්‍යාසගත කිරීම අවශ්‍ය වේ.",
"install_submit_title": "සුභ පැතුම්!",
"install_submit_desc": "පිහිටුවීමේ ක්‍රියා පටිපාටිය අවසන් වී ඇති අතර ඔබ ඇඩ්ගාර්ඩ් හෝම් භාවිතය ආරම්භ කිරීමට සූදානම්ය.",
"install_submit_desc": "පිහිටුවීමේ ක්‍රියා පටිපාටිය අවසන් වී ඇති අතර ඔබ දැන් ඇඩ්ගාර්ඩ් හෝම් භාවිතය ආරම්භ කිරීමට සූදානම්ය.",
"install_devices_router": "මාර්ගකාරකය",
"install_devices_router_desc": "මෙම පිහිටුම ඔබගේ නිවසේ මාර්ගකාරකයට සම්බන්ධ සියලුම උපාංග ස්වයංක්‍රීයව ආවරණය කරන අතර ඔබට ඒවා අතින් වින්‍යාසගත කිරීමට අවශ්‍ය නොවනු ඇත.",
"install_devices_router_desc": "මෙම පිහිටුම ඔබගේ නිවසේ මාර්ගකාරකයට සම්බන්ධ සියලුම උපාංග ස්වයංක්‍රීයව ආවරණය කරන අතර ඔබට ඒ සෑම එකක්ම අතින් වින්‍යාසගත කිරීමට අවශ්‍ය නොව.",
"install_devices_address": "ඇඩ්ගාර්ඩ් හෝම් ව.නා.ප. සේවාදායකය පහත ලිපිනයන්ට සවන් දෙමින් පවතී",
"install_devices_router_list_2": "ග.ධා.වි.කෙ. (DHCP)/ ව.නා.ප. (DNS) සැකසුම් සොයා ගන්න. ඉලක්කම් කට්ටල දෙකකට හෝ තුනකට ඉඩ දෙන ක්ෂේත්‍රයක් අසල ඇති ව.නා.ප. අක්ෂර සොයන්න, සෑම එකක්ම ඉලක්කම් එකේ සිට තුන දක්වා කාණ්ඩ හතරකට බෙදා ඇත.",
"install_devices_router_list_3": "ඔබගේ ඇඩ්ගාර්ඩ් හෝම් සේවාදායක ලිපින එහි ඇතුළත් කරන්න.",
@@ -420,6 +420,7 @@
"encryption_key_source_content": "පුද්ගලික යතු‌රෙහි අන්තර්ගත අලවන්න",
"stats_params": "සංඛ්‍යාලේඛන වින්‍යාසය",
"config_successfully_saved": "වින්‍යාසය සාර්ථකව සුරකින ලදි",
"interval_6_hour": "පැය 6",
"interval_24_hour": "පැය 24",
"interval_days": "{{count}} දිනය",
"interval_days_plural": "දින {{count}}",

View File

@@ -112,6 +112,8 @@
"for_last_24_hours": "za posledných 24 hodín",
"for_last_days": "za posledný {{count}} deň",
"for_last_days_plural": "za posledných {{count}} dní",
"stats_disabled": "Štatistiky boli vypnuté. Môžete ich zapnúť na <0>stránke nastavení</0>.",
"stats_disabled_short": "Štatistiky boli vypnuté",
"no_domains_found": "Žiadna doména nebola nájdená",
"requests_count": "Počet dopytov",
"top_blocked_domains": "Najčastejšie zablokované domény",
@@ -426,9 +428,9 @@
"access_title": "Nastavenia prístupu",
"access_desc": "Tu môžete konfigurovať pravidlá prístupu pre server DNS AdGuard Home.",
"access_allowed_title": "Povolení klienti",
"access_allowed_desc": "Zoznam CIDR alebo IP adries. Ak je nakonfigurovaný, AdGuard Home akceptuje len dopyty z týchto IP adries",
"access_allowed_desc": "Zoznam CIDR, IP adries alebo ID klientov. Ak je nakonfigurovaný, AdGuard Home akceptuje len dopyty od týchto klientov.",
"access_disallowed_title": "Nepovolení klienti",
"access_disallowed_desc": "Zoznam CIDR alebo IP adries. Ak je nakonfigurovaný, AdGuard Home bude ignorovať dopyty z týchto IP adries",
"access_disallowed_desc": "Zoznam CIDR, IP adries alebo ID klientov. Ak je nakonfigurovaný, AdGuard Home bude ignorovať dopyty od týchto klientov.",
"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é",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "Vložte obsah privátneho kľúča",
"stats_params": "Konfigurácia štatistiky",
"config_successfully_saved": "Konfigurácia bola úspešne uložená",
"interval_6_hour": "6 hodín",
"interval_24_hour": "24 hodín",
"interval_days": "{{count}} deň",
"interval_days_plural": "{{count}} dní",
"domain": "Doména",
"punycode": "Punycode",
"answer": "Odpoveď",
"filter_added_successfully": "Filter bol úspešne pridaný",
"filter_removed_successfully": "Zoznam bol úspešne odstránený",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "Predĺži krátke hodnoty TTL (v sekundách) prijaté od servera typu upstream pri ukladaní odpovedí DNS do cache pamäte",
"cache_ttl_max_override_desc": "Nastaví maximálnu hodnotu TTL (v sekundách) pre záznamy v DNS cache pamäti",
"ttl_cache_validation": "Minimálna hodnota TTL cache musí byť menšia alebo rovná maximálnej hodnote",
"cache_optimistic": "Optimistické nastavenie",
"cache_optimistic_desc": "Nechajte AdGuard Home odpovedať z vyrovnávacej pamäte, aj keď už platnosť položiek skončila, a tiež sa pokúste ich obnoviť.",
"filter_category_general": "Všeobecné",
"filter_category_security": "Bezpečnosť",
"filter_category_regional": "Regionálne",

View File

@@ -68,6 +68,9 @@
"dhcp_new_static_lease": "Nov statični najem",
"dhcp_static_leases_not_found": "Ni najdenih statičnih najemov DHCP",
"dhcp_add_static_lease": "Dodaj statičen najem",
"dhcp_reset_leases": "Ponastavi vse najeme",
"dhcp_reset_leases_confirm": "Ali ste prepričani, da želite ponastaviti vse najeme?",
"dhcp_reset_leases_success": "Najemi DHCP so bili uspešno ponastavljeni",
"dhcp_reset": "Ali ste prepričani, da želite ponastaviti nastavitve DHCP?",
"country": "Dežela",
"city": "Mesto",
@@ -109,6 +112,8 @@
"for_last_24_hours": "v zadnjih 24 urah",
"for_last_days": "zadnjega {{count}} dne",
"for_last_days_plural": "zadnjih {{count}} dni",
"stats_disabled": "Statistika je onemogočena. Vklopite ga lahko na <0>strani z nastavitvami</0>.",
"stats_disabled_short": "Statistika je bila onemogočena",
"no_domains_found": "Ni najdenih domen",
"requests_count": "Štavilo zahtev",
"top_blocked_domains": "Najbolj zavirane domene",
@@ -323,7 +328,7 @@
"install_devices_windows_list_2": "Pojdite v 'Omrežje' in 'Kategorija interneta' in nato v 'Omrežje' in 'Središče za skupno rabo'.",
"install_devices_windows_list_3": "Na levi strani zaslona poiščite 'Spremeni nastavitve kartice' in kliknite nanjo.",
"install_devices_windows_list_4": "Izberite aktivno povezavo, kliknite na njo z desno miškino tipko in izberite 'Lastnosti'.",
"install_devices_windows_list_5": "Na seznamu poiščite različico 4 (TCP/IP) internetnega protokola, jo izberite in znova kliknite na 'Lastnosti'.",
"install_devices_windows_list_5": "Na seznamu poiščite 'Internet protokol različica 4 (TCP/IPv4)' (ali, za IPv6, 'Internet protokol različica 6 (TCP/IPv6)'), jo izberite in nato še enkrat kliknite 'Lastnosti'.",
"install_devices_windows_list_6": "Izberite 'Uporabi naslednje naslove DNS strežnikov' in vnesite vaše naslove strežnika AdGuard Home.",
"install_devices_macos_list_1": "Kliknite ikono Apple in pojdite na 'Nastavitve sistema'.",
"install_devices_macos_list_2": "Kliknite na 'Omrežje'",
@@ -423,9 +428,9 @@
"access_title": "Nastavitve dostopa",
"access_desc": "Tukaj lahko nastavite pravila dostopa strežnika DNS AdGuard Home.",
"access_allowed_title": "Dovoljeni odjemalci",
"access_allowed_desc": "Seznam naslovov CIDR ali IP. Če je konfiguriran, bo AdGuard Home sprejel zahteve samo od teh teh IP naslovov.",
"access_allowed_desc": "Seznam naslovov CIDR ali IP. Če je nastavljen, bo AdGuard Home sprejel zahteve samo od teh teh naslovov IP.",
"access_disallowed_title": "Zavrnjeni odjemalci",
"access_disallowed_desc": "Seznam naslovov CIDR ali IP. Če je konfiguriran, bo AdGuard Home spustil zahteve iz teh IP naslovov.",
"access_disallowed_desc": "Seznam naslovov CIDR ali IP. Če je nastavljen, bo AdGuard Home spustil zahteve iz teh naslovov IP.",
"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",
@@ -481,10 +486,12 @@
"encryption_key_source_content": "Prilepi vsebino zasebnega ključa",
"stats_params": "Nastavitve statistike",
"config_successfully_saved": "Nastavitve so uspešno shranjene",
"interval_6_hour": "6 ur",
"interval_24_hour": "24 ur",
"interval_days": "{{count}} dan",
"interval_days_plural": "{{count}} dni",
"domain": "Domena",
"punycode": "Slaba koda",
"answer": "Odgovor",
"filter_added_successfully": "Seznam je bil uspešno dodan",
"filter_removed_successfully": "Seznam je bil uspešno odstranjen",
@@ -590,6 +597,8 @@
"cache_ttl_min_override_desc": "Razširite kratke vrednosti časa v živo (v sekundah), ki jih prejme strežnik za predpomnjenje, ko predpomni odzive DNS",
"cache_ttl_max_override_desc": "Nastavi največjo vrednost časa v živo (v sekundah) za vnose v predpomnilnik DNS",
"ttl_cache_validation": "Najmanjša vrednost predpomnilnika TTL mora biti manjša ali enaka največji vrednosti",
"cache_optimistic": "Optimistično",
"cache_optimistic_desc": "Poskrbi, da se AdGuard Home odzove iz predpomnilnika, tudi ko vnosi potečejo, in jih tudi poskusi osvežiti.",
"filter_category_general": "Splošno",
"filter_category_security": "Varnost",
"filter_category_regional": "Področno",

View File

@@ -5,18 +5,18 @@
"upstream_parallel": "Tüm üst sunucuları eş zamanlı sorgulayarak çözümlemeyi hızlandırmak için paralel sorgular kullanın.",
"parallel_requests": "Paralel istekler",
"load_balancing": "Yük dengeleme",
"load_balancing_desc": "Bir seferde bir üst sunucusunu sorgulayın. AdGuard Home, sunucuyu seçmek için ağırlıklı rastgele algoritmasını kullanır, böylece en hızlı sunucu daha sık kullanılır.",
"load_balancing_desc": "Her seferde bir üst sunucuyu sorgulayın. AdGuard Home, sunucuyu seçmek için ağırlıklı rastgele algoritmasını kullanır, böylece en hızlı sunucu daha sık kullanılır.",
"bootstrap_dns": "DNS Önyükleme sunucuları",
"bootstrap_dns_desc": "DNS Önyükleme sunucuları, seçtiğiniz üst sunucuların DoH/DoT çözücülerine ait ip adreslerinin çözülmesi için kullanılır.",
"bootstrap_dns_desc": "DNS Önyükleme sunucuları, belirttiğiniz üst sunucuların DoH/DoT çözücülerine ait IP adreslerinin çözülmesi 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 bilgisayar adlarını çözmek için kullanılır. Ayarlanmazsa, AdGuard Home işletim sisteminizin varsayılan DNS çözümlerini kullanır.",
"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 bilgisayar 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_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 özel ters DNS çözümleyicilerini belirleyemedi.",
"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",
"resolve_clients_title": "İstemcilerin IP adreslerinin ters çözümlenmesini etkinleştir",
"resolve_clients_desc": "Karşılık gelen çözümleyicilere (yerel istemciler için özel DNS sunucuları, genel IP adresleri olan istemciler için üst sunucuları) PTR sorguları göndererek istemcilerin IP adreslerini ana bilgisayar adlarına tersine çözün.",
"use_private_ptr_resolvers_title": "Özel DNS çözümleyicileri kullan",
"use_private_ptr_resolvers_desc": "Bu üst kaynak sunucularını kullanarak yerel olarak sunulan adresler için ters DNS aramaları gerçekleştirin. Devre dışı bırakılırsa, AdGuard Home, DHCP, /etc/hosts, vb. tarafından bilinen istemciler dışında bu tür tüm PTR isteklerine NXDOMAIN ile yanıt verir.",
"resolve_clients_desc": "Karşılık gelen çözümleyicilere (yerel istemciler için özel DNS sunucuları, genel IP adresleri olan istemciler için üst sunucuları) PTR sorguları göndererek istemcilerin IP adreslerini ana bilgisayar adlarının tersine çözün.",
"use_private_ptr_resolvers_title": "Özel ters DNS çözümleyicileri kullan",
"use_private_ptr_resolvers_desc": "Bu üst kaynak sunucularını kullanarak yerel olarak sunulan adresler için ters DNS aramaları yapın. Devre dışı bırakılırsa, AdGuard Home, DHCP, /etc/hosts, vb. tarafından bilinen istemciler dışında bu tür tüm PTR isteklerine NXDOMAIN ile yanıt verir.",
"check_dhcp_servers": "DHCP sunucularını denetle",
"save_config": "Yapılandırmayı kaydet",
"enabled_dhcp": "DHCP sunucusu etkinleştirildi",
@@ -24,11 +24,11 @@
"unavailable_dhcp": "DHCP kullanılamıyor",
"unavailable_dhcp_desc": "AdGuard Home, işletim sisteminizde DHCP sunucusu çalıştıramıyor",
"dhcp_title": "DHCP sunucusu (deneysel!)",
"dhcp_description": "Yönlendiriciniz DHCP ayarlarını sağlamıyorsa, AdGuard'ın kendi yerleşik DHCP sunucusunu kullanabilirsiniz.",
"dhcp_description": "Yönlendiriciniz DHCP ayarlarını sağlamıyorsa, AdGuard'ın yerleşik DHCP sunucusunu kullanabilirsiniz.",
"dhcp_enable": "DHCP sunucusunu etkinleştir",
"dhcp_disable": "DHCP sunucusunu devre dışı bırak",
"dhcp_not_found": "Yerleşik DHCP sunucusunu etkinleştirmek güvenlidir, çünkü AdGuard Home ağ üzerinde herhangi bir etkin DHCP sunucusu bulmamıştır. Ancak, otomatik deneme şu anda %100 garanti sağlamadığından, bunu elle yeniden kontrol etmelisiniz.",
"dhcp_found": "Ağ üzerinde bazı aktif DHCP sunucuları bulundu. Yerleşik DHCP sunucusunu aktif etmek sağlıklı olmayacaktır.",
"dhcp_not_found": "AdGuard Home,da herhangi bir aktif DHCP sunucusu bulamadığı için yerleşik DHCP sunucusunu etkinleştirmek güvenlidir. Ancak, otomatik ayarlama şu anda %100 garanti sağlamadığından bunu elle yeniden kontrol etmelisiniz.",
"dhcp_found": "Ağ üzerinde aktif bir DHCP sunucusu bulundu. Yerleşik DHCP sunucusunu etkinleştirmek güvenli olmayacaktır.",
"dhcp_leases": "DHCP kiralamaları",
"dhcp_static_leases": "Sabit DHCP kiralamaları",
"dhcp_leases_not_found": "DHCP kiralaması bulunamadı",
@@ -43,12 +43,12 @@
"form_error_client_id_format": "Geçersiz istemci kimliği biçimi",
"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ı",
"form_error_positive": "0'dan büyük olmalıdır",
"form_error_negative": "0 veya daha büyük olmalıdır",
"range_end_error": "Başlangıç aralığından daha büyük olmalı",
"dhcp_form_gateway_input": "Ağ Geçidi IP'si",
"dhcp_form_subnet_input": "Alt Ağ Maskesi",
"dhcp_form_range_title": "IP adres aralığı",
"dhcp_form_subnet_input": "Alt ağ maskesi",
"dhcp_form_range_title": "IP adresi aralığı",
"dhcp_form_range_start": "Aralık başlangıcı",
"dhcp_form_range_end": "Aralık sonu",
"dhcp_form_lease_title": "DHCP kira süresi (saniye olarak)",
@@ -57,12 +57,12 @@
"dhcp_hardware_address": "Donanım adresi",
"dhcp_ip_addresses": "IP adresleri",
"ip": "IP",
"dhcp_table_hostname": "Ana bilgisayar Adı",
"dhcp_table_hostname": "Bilgisayar Adı",
"dhcp_table_expires": "Geçerlilik Tarihi",
"dhcp_warning": "DHCP sunucusunu yine de etkinleştirmek istiyorsanız, ağınızda başka aktif DHCP sunucusu olmadığından emin olun çünkü bu, ağdaki cihazların İnternet bağlantısını kesebilir!",
"dhcp_warning": "DHCP sunucusunu yine de etkinleştirmek istiyorsanız, ağınızda başka aktif DHCP sunucusu olmadığından emin olun, aksi takdirde ağa bağlı cihazların İnternet bağlantısı kesilebilir!",
"dhcp_error": "AdGuard Home, ağda başka bir etkin DHCP sunucusu olup olmadığını belirleyemedi.",
"dhcp_static_ip_error": "DHCP sunucusunu kullanmak için statik bir IP adresi ayarlanmalıdır. AdGuard Home, bu ağ arayüzünün statik bir IP adresi kullanılarak yapılandırılıp yapılandırılmadığını belirleyemedi. Lütfen elle statik bir IP adresi ayarlayın.",
"dhcp_dynamic_ip_found": "Sisteminiz <0>{{interfaceName}}</0> arayüzü için dinamik IP adresi yapılandırması kullanıyor. DHCP sunucusunu kullanmak için statik bir IP adresi ayarlanmalı. Geçerli IP adresiniz <0>{{ipAddress}}</0>. \"DHCP sunucusunu etkinleştir\" düğmesine basarsanız, AdGuard Home bu IP adresini otomatikman statik olarak ayarlayacak.",
"dhcp_static_ip_error": "DHCP sunucusunu kullanmak için sabit bir IP adresi ayarlanmalıdır. AdGuard Home, bu ağ arayüzünün sabit bir IP adresi kullanılarak yapılandırılıp yapılandırılmadığını belirleyemedi. Lütfen sabit IP adresini elle ayarlayın.",
"dhcp_dynamic_ip_found": "Sisteminiz, <0>{{interfaceName}}</0> arayüzü için dinamik IP adresi yapılandırması kullanıyor. DHCP sunucusunu kullanmak için sabit bir IP adresi ayarlanmalıdır. Geçerli olan IP adresiniz <0>{{ipAddress}}</0>. \"DHCP sunucusunu etkinleştir\" düğmesine basarsanız, AdGuard Home bu IP adresini otomatik bir şekilde sabit olarak ayarlayacaktır.",
"dhcp_lease_added": "Sabit kiralama \"{{key}}\" başarıyla eklendi",
"dhcp_lease_deleted": "Sabit kiralama \"{{key}}\" başarıyla silindi",
"dhcp_new_static_lease": "Yeni sabit kiralama",
@@ -74,20 +74,20 @@
"dhcp_reset": "DHCP yapılandırmasını sıfırlamak istediğinizden emin misiniz?",
"country": "Ülke",
"city": "Şehir",
"delete_confirm": "\"{{key}}\" silmek istediğinizden emin misiniz?",
"delete_confirm": "\"{{key}}\" öğesini silmek istediğinizden emin misiniz?",
"form_enter_hostname": "Ana bilgisayar adı girin",
"error_details": "Hata detayları",
"error_details": "Hata ayrıntıları",
"response_details": "Yanıt ayrıntıları",
"request_details": "İstek ayrıntıları",
"client_details": "İstemci detayları",
"details": "Detaylar",
"client_details": "İstemci ayrıntıları",
"details": "Ayrıntılar",
"back": "Geri",
"dashboard": "Pano",
"dashboard": "Ana Sayfa",
"settings": "Ayarlar",
"filters": "Filtreler",
"filter": "Filtre",
"query_log": "Sorgu Günlüğü",
"compact": "Kompakt",
"compact": "Yoğun",
"nothing_found": "Hiçbir şey bulunamadı",
"faq": "SSS",
"version": "Sürüm",
@@ -98,20 +98,22 @@
"copyright": "Telif hakkı",
"homepage": "Ana sayfa",
"report_an_issue": "Bir sorun bildir",
"privacy_policy": "Gizlilik politikası",
"privacy_policy": "Gizlilik ilkesi",
"enable_protection": "Korumayı etkinleştir",
"enabled_protection": "Koruma etkileştirildi",
"disable_protection": "Korumayı durdur",
"disabled_protection": "Koruma devre dışı",
"disabled_protection": "Koruma durduruldu",
"refresh_statics": "İstatistikleri yenile",
"dns_query": "DNS Sorguları",
"blocked_by": "<0>Filtreler tarafından engellendi</0>",
"stats_malware_phishing": "Kötü amaçlı yazılım/kimlik avı engellendi",
"stats_malware_phishing": "Kötü amaçlı yazılım ve kimlik avı engellendi",
"stats_adult": "Yetişkin içerikli site engellendi",
"stats_query_domain": "En fazla sorgulanan alan adları",
"for_last_24_hours": "son 24 saat içindekiler",
"for_last_days": "son {{count}} gün için",
"for_last_days": "son {{count}} gün boyunca",
"for_last_days_plural": "son {{count}} gün boyunca",
"stats_disabled": "İstatistikler devre dışı bırakıldı. Bunu, <0>ayarlar sayfasından</0> etkinleştirebilirsiniz.",
"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ı",
@@ -121,11 +123,11 @@
"number_of_dns_query_days": "Son {{count}} gün boyunca işlenen DNS sorgularının sayısı",
"number_of_dns_query_days_plural": "Son {{count}} gün boyunca işlenen DNS sorgularının sayısı",
"number_of_dns_query_24_hours": "Son 24 saat içinde işlenen DNS sorgularının sayısı",
"number_of_dns_query_blocked_24_hours": "Adblock filtreleri ve ana bilgisayar engelleme listeleri tarafından engellenen DNS isteklerinin sayısı",
"number_of_dns_query_blocked_24_hours_by_sec": "AdGuard gezinti koruması modülü tarafından engellenmiş DNS isteklerinin sayısı",
"number_of_dns_query_blocked_24_hours_adult": "Engellenen yetişkin sitelerinin sayısı",
"enforced_save_search": "Zorunlu kılınmış güvenli arama",
"number_of_dns_query_to_safe_search": "Güvenli Aramanın zorunlu kıldığı arama motorlarına gönderilen DNS isteklerinin sayısı",
"number_of_dns_query_blocked_24_hours": "Reklam engelleme filtreleri ve engelleme listeleri tarafından engellenen DNS isteklerinin sayısı",
"number_of_dns_query_blocked_24_hours_by_sec": "AdGuard gezinti koruması modülü tarafından engellenen DNS isteklerinin sayısı",
"number_of_dns_query_blocked_24_hours_adult": "Engellenen yetişkin içerikli sitelerin sayısı",
"enforced_save_search": "Uygulanan güvenli arama",
"number_of_dns_query_to_safe_search": "Güvenli Aramanın uygulandığı arama motorlarına gönderilen DNS isteklerinin sayısı",
"average_processing_time": "Ortalama işlem süresi",
"average_processing_time_hint": "Bir DNS isteğinin mili saniye cinsinden ortalama işlem süresi",
"block_domain_use_filters_and_hosts": "Filtre ve ana bilgisayar listelerini kullanarak alan adlarını engelle",
@@ -133,16 +135,16 @@
"use_adguard_browsing_sec": "AdGuard gezinti koruması web hizmetini kullan",
"use_adguard_browsing_sec_hint": "AdGuard Home, alan adının gezinti koruması web hizmeti tarafından engellenip engellenmediğini kontrol eder. Kontrolü gerçekleştirmek için gizlilik dostu arama API'sini kullanır: sunucuya yalnızca SHA256 karma alan adının kısa bir ön eki gönderilir.",
"use_adguard_parental": "AdGuard ebeveyn kontrolü web hizmetini kullan",
"use_adguard_parental_hint": "AdGuard Home, alan adının yetişkin içerik bulundurup bulundurmadığını kontrol edecek. Gezinti güvenliği web hizmeti ile kullandığımız aynı gizlilik dostu API'yi kullanıyoruz.",
"use_adguard_parental_hint": "AdGuard Home, alan adının yetişkin içerik bulundurup bulundurmadığını kontrol eder. Gezinti koruması web hizmeti ile kullandığımız aynı gizlilik dostu API'yi kullanır.",
"enforce_safe_search": "Güvenli aramayı kullan",
"enforce_save_search_hint": "AdGuard Home, şu arama motorlarında güvenli aramayı zorunlu kılar: Google, YouTube, Bing, DuckDuckGo, Yandex ve Pixabay.",
"no_servers_specified": "Sunucu adresi girilmedi",
"enforce_save_search_hint": "AdGuard Home, şu arama motorlarında güvenli aramayı uygular: Google, YouTube, Bing, DuckDuckGo, Yandex ve Pixabay.",
"no_servers_specified": "Sunucu belirtilmedi",
"general_settings": "Genel ayarlar",
"dns_settings": "DNS ayarları",
"dns_blocklists": "DNS engelleme listeleri",
"dns_allowlists": "DNS izin verilen listeleri",
"dns_blocklists_desc": "AdGuard Home, engelleme listeleriyle eşleşen alanları engeller.",
"dns_allowlists_desc": "DNS izin verilen listelerindeki alanlara, engelleme listelerinden birinde olsalar bile izin verilir.",
"dns_allowlists": "DNS izin listeleri",
"dns_blocklists_desc": "AdGuard Home, engelleme listeleriyle eşleşen alan adlarını engeller.",
"dns_allowlists_desc": "DNS izin listesindeki alan adlarına, engelleme listesinde olsa bile izin verilir.",
"custom_filtering_rules": "Özel filtreleme kuralları",
"encryption_settings": "Şifreleme ayarları",
"dhcp_settings": "DHCP ayarları",
@@ -153,13 +155,13 @@
"upstreams": "Üst kaynak",
"apply_btn": "Uygula",
"disabled_filtering_toast": "Filtreleme devre dışı",
"enabled_filtering_toast": "Filtreleme çalışıyor",
"enabled_filtering_toast": "Filtreleme etkin",
"disabled_safe_browsing_toast": "Güvenli gezinti devre dışı",
"enabled_safe_browsing_toast": "Güvenli gezinti çalışıyor",
"enabled_safe_browsing_toast": "Güvenli gezinti etkin",
"disabled_parental_toast": "Ebeveyn kontrolü devre dışı",
"enabled_parental_toast": "Ebeveyn kontrolü çalışıyor",
"enabled_parental_toast": "Ebeveyn kontrolü etkin",
"disabled_safe_search_toast": "Güvenli arama devre dışı",
"enabled_save_search_toast": "Güvenli arama çalışıyor",
"enabled_save_search_toast": "Güvenli arama etkin",
"enabled_table_header": "Etkin",
"name_table_header": "İsim",
"list_url_table_header": "Liste URL'si",
@@ -170,31 +172,31 @@
"edit_table_action": "Düzenle",
"delete_table_action": "Sil",
"elapsed": "Geçen zaman",
"filters_and_hosts_hint": "AdGuard Home temel reklam engelleme kuralları ve ana bilgisayar dosyalarının sözdizim kurallarını anlamaktadır.",
"filters_and_hosts_hint": "AdGuard Home, temel reklam engelleme kurallarını ve ana bilgisayar engelleme dosyalarının söz dizimini anlar.",
"no_blocklist_added": "Engelleme listesi eklenmedi",
"no_whitelist_added": "İzin verilen listesi eklenmedi",
"no_whitelist_added": "İzin listesi eklenmedi",
"add_blocklist": "Engelleme listesi ekle",
"add_allowlist": "İzin verilen listesine ekle",
"add_allowlist": "İzin listesi ekle",
"cancel_btn": "İptal",
"enter_name_hint": "İsim girin",
"enter_url_or_path_hint": "Bir URL ya da listenin tam yolunu girin",
"enter_url_or_path_hint": "Listenin URL adresini veya dosya konumunu girin",
"check_updates_btn": "Güncellemeleri denetle",
"new_blocklist": "Yeni engelleme listesi",
"new_allowlist": "Yeni izin verilen listesi",
"new_allowlist": "Yeni izin listesi",
"edit_blocklist": "Engelleme listesini düzenle",
"edit_allowlist": "İzin verilen listesini düzenle",
"edit_allowlist": "İzin listesini düzenle",
"choose_blocklist": "Engelleme listelerini seçin",
"choose_allowlist": "İzin verilen listelerini seç",
"choose_allowlist": "İzin listelerini seçin",
"enter_valid_blocklist": "Engelleme listesine geçerli bir URL girin.",
"enter_valid_allowlist": "İzin verilen listesine geçerli bir URL girin.",
"enter_valid_allowlist": "İzin listesine geçerli bir URL girin.",
"form_error_url_format": "Geçersiz URL biçimi",
"form_error_url_or_path_format": "Geçersiz URL ya da listenin tam yolu",
"form_error_url_or_path_format": "Listenin URL adresi veya dosya konumu geçersiz",
"custom_filter_rules": "Özel filtreleme kuralları",
"custom_filter_rules_hint": "Her satıra bir kural girin. Reklama engelleme kuralı veya ana bilgisayar dosyası sözdizimi kullanabilirsiniz.",
"custom_filter_rules_hint": "Her satıra bir kural girin. Reklam engelleme kuralı veya ana bilgisayar dosyası söz dizimi kullanabilirsiniz.",
"examples_title": "Örnekler",
"example_meaning_filter_block": "example.org alan adına ve tüm alt alan adlarına olan erişimi engeller",
"example_meaning_filter_whitelist": "example.org alan adına ve tüm alt alan adlarına olan erişim engelini kaldırır",
"example_meaning_host_block": "AdGuard Home bu example.org adresi için 127.0.0.1 adresine yönlendirme yapacaktır (alt alan adları için geçerli değildir)",
"example_meaning_host_block": "AdGuard Home, example.org adresi için 127.0.0.1 adresine yönlendirme yapacaktır (alt alan adları için geçerli değildir)",
"example_comment": "! Buraya bir yorum ekledim",
"example_comment_meaning": "sadece bir yorum",
"example_comment_hash": "# Bir yorum daha ekledim",
@@ -203,18 +205,18 @@
"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>",
"example_upstream_sdns": "<1>DNSCrypt</1> veya <2>DNS-over-HTTPS</2> çözüleri için <0>DNS Damgaları</0> kullanabilirsiniz.",
"example_upstream_sdns": "<1>DNSCrypt</1> veya <2>DNS-over-HTTPS</2> çözümleyicileri için <0>DNS Damgaları</0> kullanabilirsiniz",
"example_upstream_tcp": "normal DNS (TCP üzerinden)",
"all_lists_up_to_date_toast": "Tüm listeler zaten güncel",
"all_lists_up_to_date_toast": "Tüm listeler güncel durumda",
"updated_upstream_dns_toast": "Üst DNS sunucuları güncellendi",
"dns_test_ok_toast": "Belirtilmiş DNS sunucuları düzgün çalışıyor",
"dns_test_ok_toast": "Belirtilen DNS sunucuları düzgün çalışıyor",
"dns_test_not_ok_toast": "Sunucu \"{{key}}\": kullanılamıyor, lütfen doğru yazdığınızdan emin olun",
"unblock": "Engeli kaldır",
"block": "Engelle",
"disallow_this_client": "Bu istemciye izin verme",
"allow_this_client": "Bu istemciye izin ver",
"block_for_this_client_only": "Yalnızca bu istemci için engelle",
"unblock_for_this_client_only": "Yalnızca bu müşteri için engellemeyi kaldır",
"unblock_for_this_client_only": "Yalnızca bu istemci için engellemeyi kaldır",
"time_table_header": "Saat",
"date": "Tarih",
"domain_name_table_header": "Alan adı",
@@ -225,7 +227,7 @@
"client_table_header": "İstemci",
"empty_response_status": "Boş",
"show_all_filter_type": "Tümünü göster",
"show_filtered_type": "Filtrelenmişleri göster",
"show_filtered_type": "Filtrelenenleri göster",
"no_logs_found": "Günlük kaydı bulunamadı",
"refresh_btn": "Yenile",
"previous_btn": "Önceki",
@@ -234,24 +236,24 @@
"page_table_footer_text": "Sayfa",
"rows_table_footer_text": "satır",
"updated_custom_filtering_toast": "Özel filtreleme kuralları güncellendi",
"rule_removed_from_custom_filtering_toast": "Özel filtreleme kurallarından kural kaldırıldı: {{rule}}",
"rule_added_to_custom_filtering_toast": "Özel filtreleme kurallarına kural eklendi: {{rule}}",
"rule_removed_from_custom_filtering_toast": "Özel filtreleme kurallarından kaldırıldı: {{rule}}",
"rule_added_to_custom_filtering_toast": "Özel filtreleme kurallarına eklendi: {{rule}}",
"query_log_response_status": "Durum: {{value}}",
"query_log_filtered": "{{filter}} tarafından filtrelendi",
"query_log_confirm_clear": "Tüm sorgu günlüğünü temizlemek istediğinizden emin misiniz?",
"query_log_cleared": "Sorgu günlüğü başarıyla temizlendi",
"query_log_updated": "Sorgu günlüğü başarıyla güncellendi",
"query_log_clear": "Sorgu günlüklerini temizle",
"query_log_retention": "Sorgu günlüklerinin saklanması",
"query_log_retention": "Sorgu günlüklerini sakla",
"query_log_enable": "Günlüğü etkinleştir",
"query_log_configuration": "Günlük yapılandırması",
"query_log_disabled": "Sorgu günlüğü devre dışı bırakıldı ve <0>ayarlar</0>da yapılandırılabilir",
"query_log_strict_search": "Katı arama için çift tırnak işareti kullanın",
"query_log_disabled": "Sorgu günlüğü devre dışı bırakıldı, bunu <0>ayarlar</0> kısmından yapılandırılabilirsiniz",
"query_log_strict_search": "Tam arama için çift tırnak işareti kullanın",
"query_log_retention_confirm": "Sorgu günlüğü saklama süresini değiştirmek istediğinize emin misiniz? Aralık değerini azaltırsanız, bazı veriler kaybolacaktır",
"anonymize_client_ip": "İstemci IP'sini anonimize et",
"anonymize_client_ip_desc": "İstemcinin tam IP adresini günlüklere ve istatistiklere kaydetmeyin",
"dns_config": "DNS sunucusu yapılandırması",
"dns_cache_config": "DNS önbelleği yapılandırması",
"anonymize_client_ip": "İstemcinin IP adresini gizle",
"anonymize_client_ip_desc": "İstemcinin IP adresini günlüklere ve istatistiklere kaydetmeyin",
"dns_config": "DNS sunucu yapılandırması",
"dns_cache_config": "DNS önbellek yapılandırması",
"dns_cache_config_desc": "Burada DNS önbelleğini yapılandırabilirsiniz",
"blocking_mode": "Engelleme modu",
"default": "Varsayılan",
@@ -266,134 +268,134 @@
"dns_over_tls": "DNS-over-TLS",
"dns_over_quic": "DNS-over-QUIC",
"client_id": "İstemci Kimliği",
"client_id_placeholder": "İstemci Kimliği girin",
"client_id_desc": "Farklı istemciler, özel bir istemci kimliği ile tanımlanabilir. <a>Burada</a> istemcileri nasıl belirleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.",
"client_id_placeholder": "İstemci kimliği girin",
"client_id_desc": "Farklı istemciler, özel bir istemci kimliği ile tanımlanabilir. <a>Burada</a> istemcileri nasıl tanımlayacağınız hakkında daha fazla bilgi edinebilirsiniz.",
"download_mobileconfig_doh": "DNS-over-HTTPS için .mobileconfig dosyasını indir",
"download_mobileconfig_dot": "DNS-over-TLS için .mobileconfig dosyasını indir",
"download_mobileconfig": "Yapılandırma dosyasını indir",
"plain_dns": "Sade DNS",
"plain_dns": "Düz DNS",
"form_enter_rate_limit": "Sıklık limitini girin",
"rate_limit": "Sıklık limiti",
"edns_enable": "EDNS istemci alt ağını etkinleştir",
"edns_cs_desc": "İstemcilerin alt ağlarını DNS sunucularına gönderin.",
"rate_limit_desc": "Tek bir istemcinin yapmasına izin verilen saniye başına istek sayısı 0 olarak ayarlamak, sınır olmadığı anlamına gelir.",
"rate_limit_desc": "İstemci başına izin verilen saniyedeki istek sayısı. 0 olarak ayarlamak, sınır olmadığı anlamına gelir.",
"blocking_ipv4_desc": "Engellenen bir A isteği için geri döndürülecek IP adresi",
"blocking_ipv6_desc": "Engellenen bir AAAA isteği için geri döndürülecek IP adresi",
"blocking_mode_default": "Varsayılan: Reklam engelleme stili kuralı tarafından engellendiğinde sıfır IP adresiyle (A için 0.0.0.0; AAAA için) yanıt verin; /etc/hosts-style kuralı tarafından engellendiğinde, kuralda belirtilen IP adresiyle yanıt verin",
"blocking_mode_refused": "REFUSED: REFUSED kod ile yanıt verin",
"blocking_mode_nxdomain": "NXDOMAIN: NXDOMAIN koduyla yanıt",
"blocking_mode_default": "Varsayılan: Reklam engelleme tarzı kural tarafından engellendiğinde sıfır IP adresiyle (A için 0.0.0.0; :: AAAA için) yanıt verin; /etc/hosts-tarzı kural tarafından engellendiğinde, kuralda belirtilen IP adresiyle yanıt verin",
"blocking_mode_refused": "REFUSED: REFUSED koduyla yanıt verin",
"blocking_mode_nxdomain": "NXDOMAIN: NXDOMAIN koduyla yanıt verin",
"blocking_mode_null_ip": "Boş IP: Sıfır IP adresiyle yanıt verin (A için 0.0.0.0; :: AAAA için)",
"blocking_mode_custom_ip": "Özel IP: El ile ayarlanmış bir IP adresi ile yanıt verin",
"upstream_dns_client_desc": "Bu alanı boş tutarsanız, AdGuard Home, <0>DNS ayarlarında</0> yapılandırılmış sunucuları kullanır.",
"blocking_mode_custom_ip": "Özel IP: El ile ayarlanmış bir IP adresiyle yanıt verin",
"upstream_dns_client_desc": "Bu alanı boş bırakırsanız, AdGuard Home, <0>DNS ayarlarında</0> yapılandırılan sunucuları kullanır.",
"tracker_source": "İzleyici kaynağı",
"source_label": "Kaynak",
"found_in_known_domain_db": "Bilinen alan adları veri tabanı içinde bulundu.",
"found_in_known_domain_db": "Alan adlarının bilindiği veri tabanında bulundu.",
"category_label": "Kategori",
"rule_label": "Kural",
"list_label": "Liste",
"unknown_filter": "Bilinmeyen filtre {{filterId}}",
"known_tracker": "Bilinen izleyici",
"install_welcome_title": "AdGuard Home'a hoş geldiniz!",
"install_welcome_desc": "AdGuard Home, ağ genelinde reklam ve izleyicileri engelleyen bir DNS sunucusudur. Tüm ağınızı ve tüm cihazlarınızı kontrol etmenize yarayan bir araçtır, istemci tarafında bir program kullanmanıza gerek duymaz.",
"install_welcome_desc": "AdGuard Home, ağ genelinde reklamları ve izleyicileri engelleyen bir DNS sunucusudur. Tüm ağınızı ve tüm cihazlarınızı kontrol etmenizi sağlar, istemci tarafında herhangi bir program kullanmanıza gerek duymaz.",
"install_settings_title": "Yönetici Web Arayüzü",
"install_settings_listen": "Dinleme arayüzü",
"install_settings_port": "Bağlantı noktası",
"install_settings_interface_link": "AdGuard Home yönetici web arayüzü sayfanız şu adresten erişilebilir olacaktır:",
"form_error_port": "Geçerli bağlantı noktası numarası girin",
"form_error_port": "Geçerli bir bağlantı noktası değeri girin",
"install_settings_dns": "DNS sunucusu",
"install_settings_dns_desc": "Cihazlarınızı veya yönlendiricinizi şu adresteki DNS sunucusunu kullanması için ayarlamanız gerekecek:",
"install_settings_all_interfaces": "Tüm arayüzler",
"install_auth_title": "Kimlik Doğrulama",
"install_auth_desc": "AdAdGuard Home yönetici web arayüzüne erişim için kullanıcı adı ve şifresi oluşturmanız şiddetle tavsiye edilir. Sadece yerel ağınız erişilebilir olsa bile izinsiz giriş yapılmasını engellemek için şifrenizin olması önemlidir.",
"install_auth_desc": "AdGuard Home yönetici web arayüzüne erişim için kullanıcı adı ve şifre yapılandırmanız önemle tavsiye edilir. Yalnızca yerel ağınızdan erişilebilir olsa bile izinsiz erişimden korumak yine de önemlidir.",
"install_auth_username": "Kullanıcı adı",
"install_auth_password": "Parola",
"install_auth_confirm": "Parolayı onayla",
"install_auth_username_enter": "Kullanıcı adı girin",
"install_auth_password_enter": "Şifre girin",
"install_auth_password_enter": "Parola girin",
"install_step": "Adım",
"install_devices_title": "Cihazlarınızı ayarlayın",
"install_devices_desc": "AdGuard Home'un çalışması için cihazlarınızı onu kullanacak şekilde ayarlamalısınız.",
"install_devices_title": "Cihazlarınızı yapılandırın",
"install_devices_desc": "AdGuard Home'u kullanmaya başlamak için, cihazlarınızı onu kullanacak şekilde yapılandırmanız gerekir.",
"install_submit_title": "Tebrikler!",
"install_submit_desc": "Kurulum prosedürü tamamlandı ve artık AdGuard Home'u kullanmaya hazırsınız.",
"install_submit_desc": "Kurulum işlemi tamamlandı ve artık AdGuard Home'u kullanmaya hazırsınız.",
"install_devices_router": "Yönlendirici",
"install_devices_router_desc": "Bu kurulum, ev yönlendiricinize bağlı tüm cihazları otomatik olarak kapsar ve her birini elle yapılandırmanıza gerek yoktur.",
"install_devices_address": "AdGuard Home DNS sunucusu şu adresi dinleyecektir",
"install_devices_router_list_1": "Yönlendiricinizin ayarlarına girin. Genellikle tarayıcınızdan http://192.168.0.1/ veya http://192.168.1.1/ gibi bir URL aracılığıyla erişebilirsiniz. Bir parola girmeniz istenebilir. Hatırlamıyorsanız, genellikle yönlendiricinin üzerindeki bir düğmeye basarak parolayı sıfırlayabilirsiniz, ancak bu yöntemin seçilmesi durumunda muhtemelen tüm yönlendirici yapılandırmasını kaybedeceğinizi unutmayın. Yönlendiricinizin kurulması için bir uygulama gerekiyorsa, lütfen uygulamayı telefonunuza veya PC'nize yükleyin ve yönlendiricinin ayarlarına erişmek için kullanın.",
"install_devices_router_list_1": "Yönlendiricinizin ayarlarına gidin. Genellikle tarayıcınızdan http://192.168.0.1/ veya http://192.168.1.1/ gibi bir URL aracılığıyla erişebilirsiniz. Bir parola girmeniz istenebilir. Hatırlamıyorsanız, genellikle yönlendiricinin üzerindeki bir düğmeye basarak parolayı sıfırlayabilirsiniz, ancak bu işlemin seçilmesi durumunda yüksek ihtimalle tüm yönlendirici yapılandırmasını kaybedeceğinizi unutmayın. Yönlendiricinizin kurulumu için bir uygulama gerekiyorsa, lütfen uygulamayı telefonunuza veya PC'nize yükleyin ve yönlendiricinin ayarlarına erişmek için kullanın.",
"install_devices_router_list_2": "DHCP/DNS ayarlarını bulun. DNS satırlarını arayın, genelde iki veya üç tanedir, üç rakam girilebilen dört ayrı grup içeren satırdır.",
"install_devices_router_list_3": "AdGuard Home sunucusunun adresini o kısma yazın.",
"install_devices_router_list_4": "Bazı yönlendirici türlerinde özel bir DNS sunucusu kurulamaz. Bu durumda, AdGuard Home'u bir <0>DHCP sunucusu</0> olarak kurmak yardımcı olabilir. Aksi takdirde, belirli yönlendirici modelinizdeki DNS sunucularını nasıl özelleştireceğiniz konusunda yönlendirici kılavuzunu kontrol etmelisiniz.",
"install_devices_windows_list_1": "Başlat menüsünden veya Windows aramasıyla Denetim Masası'na girin.",
"install_devices_windows_list_2": "Ağ ve Internet kategorisine girin, sonra Ağ ve Paylaşım Merkezi'ne girin.",
"install_devices_windows_list_3": "Sol taraftaki Bağdaştırıcı ayarlarını değiştir ayarını bulun ve ona tıklayın.",
"install_devices_windows_list_4": "Aktif bağlantınızı seçin, sağ tıklayın ve Özellikler'e tıklayın.",
"install_devices_windows_list_5": "Listeden İnternet Protokolü Sürüm 4 (TCP/IP)'ye tıklayın ve Özellikler'e tıklayın.",
"install_devices_windows_list_6": "Aşağıdaki DNS sunucu adreslerini kullanın'ı seçin ve Tercih edilen DNS sunucusu alanına AdGuard Home sunucusunun adreslerini girin.",
"install_devices_macos_list_1": "Apple simgesine tıklayın ve Sistem Tercihleri'ne tıklayın.",
"install_devices_router_list_4": "Bazı yönlendirici türlerinde özel bir DNS sunucusu ayarlanamaz. Bu durumda, AdGuard Home'u <0>DHCP sunucusu</0> olarak ayarlamak yardımcı olabilir. Aksi takdirde, yönlendirici modeliniz için DNS sunucularını nasıl ayarlayacağınız konusunda yönlendirici kılavuzuna bakmalısınız.",
"install_devices_windows_list_1": "Başlat menüsünden veya Windows araması aracılığıyla Denetim Masası'nıın.",
"install_devices_windows_list_2": "Ağ ve İnternet kategorisine girin ve ardından Ağ ve Paylaşım Merkezi'ne girin.",
"install_devices_windows_list_3": "Ekranın sol tarafında bulunan \"Adaptör ayarlarını değiştir\" öğesini bulun ve 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_6": "\"Aşağıdaki DNS sunucu adreslerini kullan\"ı seçin ve AdGuard Home sunucu adreslerinizi girin.",
"install_devices_macos_list_1": "Apple simgesinde bulunan Sistem Tercihleri'ne tıklayın.",
"install_devices_macos_list_2": "Ağ seçeneğine tıklayın.",
"install_devices_macos_list_3": "Listenizdeki ilk bağlantıyı seçin ve Gelişmiş'e tıklayın.",
"install_devices_macos_list_4": "DNS sekmesine tıklayın ve AdGuard Home sunucunuzun adreslerini girin.",
"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 cihazınızda Ayarlar simgesine dokunun.",
"install_devices_android_list_2": "Wi-Fi menüsüne dokunun. Mevcut tüm ağlar listelenecektir (mobil bağlantı için isteğe bağlı DNS sunucusu ayarlanamaz).",
"install_devices_android_list_3": "Bağlı olduğunuz ağa uzun basın ve Ağı Değiştir'e dokunun.",
"install_devices_android_list_4": "Bazı cihazlarda, diğer ayarları görmek için Gelişmiş kutucuğu işaretlemeniz gerekebilir. Android DNS ayarlarınızı yapmak için IP ayarlarını DHCP'den Statik'e geçirmeniz gerekecektir.",
"install_devices_android_list_5": "DNS 1 ve DNS 2 değerlerini AdGuard Home sunucu adreslerinizle değiştirin.",
"install_devices_android_list_2": "Menüde bulunan Wi-Fi seçeneğine dokunun. Mevcut tüm ağlar listelenecektir (mobil ağlar için özel DNS sunucusu ayarlanamaz).",
"install_devices_android_list_3": "Bağlı olduğunuz ağın üzerine basılı tutun ve Ağı Değiştir'e dokunun.",
"install_devices_android_list_4": "Bazı cihazlarda, diğer ayarları görmek için \"Gelişmiş\" seçeneğini seçmeniz gerekebilir. Android DNS ayarlarınızı yapmak için IP ayarlarını DHCP modundan Statik moda almanız gerekecektir.",
"install_devices_android_list_5": "DNS 1 ve DNS 2 değerlerini AdGuard Home sunucunuzun adresleriyle değiştirin.",
"install_devices_ios_list_1": "Ana ekrandaki Ayarlar simgesine dokunun.",
"install_devices_ios_list_2": "Sol menüdeki Wi-Fi bölümüne girin (mobil bağlantı için isteğe bağlı DNS sunucusu ayarlanamaz).",
"install_devices_ios_list_2": "Sol menüde bulunan Wi-Fi bölümüne girin (mobil ağlar için özel DNS sunucusu ayarlanamaz).",
"install_devices_ios_list_3": "Bağlı olduğunuz ağın ismine dokunun.",
"install_devices_ios_list_4": "DNS alanına AdGuard Home sunucunuzun adreslerini girin.",
"get_started": "Başlarken",
"get_started": "Başlayın",
"next": "Sonraki",
"open_dashboard": "Panoyu Aç",
"open_dashboard": "Ana Sayfayı Aç",
"install_saved": "Başarıyla kaydedildi",
"encryption_title": "Şifreleme",
"encryption_desc": "Hem DNS ve hem de yönetici web arayüzü için şifreleme (HTTPS/TLS) desteği",
"encryption_desc": "DNS ve yönetici web arayüzü için şifreleme (HTTPS/TLS) desteği",
"encryption_config_saved": "Şifreleme yapılandırması kaydedildi",
"encryption_server": "Sunucu adı",
"encryption_server_enter": "Alan adınızı girin",
"encryption_server_desc": "HTTPS kullanmak için, SSL sertifikanız veya joker karakter sertifikanızla eşleşen sunucu adını girmeniz gerekir. Alan ayarlanmazsa, herhangi bir alan adı için TKG bağlantılarını kabul eder.",
"encryption_server_desc": "HTTPS kullanmak için SSL sertifikanızla veya Willcard sertifikanızla eşleşen sunucu adını girmeniz gerekir. Bu alan ayarlanmazsa, herhangi bir alan adının TLS bağlantılarını kabul eder.",
"encryption_redirect": "Otomatik olarak HTTPS'e yönlendir",
"encryption_redirect_desc": "Etkinleştirirseniz AdGuard Home sizi HTTP yerine HTTPS adreslerine yönlendirir.",
"encryption_redirect_desc": "Etkinleştirirseniz, AdGuard Home sizi HTTP adresi yerine HTTPS adresine yönlendirir.",
"encryption_https": "HTTPS bağlantı noktası",
"encryption_https_desc": "Eğer HTTPS portu yapılandırılmışsa, AdGuard Home yönetici arayüzü HTTPS ile ulaşılabilir olacak, ayrıca '/dns-query' üzerinden DNS-over-HTTPS hizmeti de çalışacak.",
"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ğlanır.",
"encryption_dot": "DNS-over-TLS bağlantı noktası",
"encryption_dot_desc": "Eğer bu portu yapılandırırsanız AdGuard Home bu port üzerinden DNS-over-TLS sunucusu çalıştıracak.",
"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ı",
"encryption_doq_desc": "Bu bağlantı noktası yapılandırılırsa, AdGuard Home bu bağlantı noktasında DNS-over-QUIC sunucusu çalıştıracaktır. Deneysel ve güvenilir olmayabilir. Ayrıca, şu anda bunu destekleyen çok fazla istemci yok.",
"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_certificates": "Sertifikalar",
"encryption_certificates_desc": "Şifrelemeyi kullanmak için alan adınız için geçerli bir SSL sertifika zinciri temin etmeniz gerekir. <0>{{link}}</0> adresinden ücretsiz temin edebilirsiniz veya güvenilir Sertifika Otoritelerinden satın alabilirsiniz.",
"encryption_certificates_input": "PEM biçimindeki sertifikalarınızı buraya yapıştırın.",
"encryption_certificates_desc": "Şifrelemeyi kullanmak için alan adınız için 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.",
"encryption_status": "Durum",
"encryption_expire": "Bitiş tarihi",
"encryption_key": "Özel anahtar",
"encryption_key_input": "Sertifikanızın PEM biçimi özel anahtarını buraya yapıştırın.",
"encryption_key_input": "Sertifikanızın PEM biçimli özel anahtarını kopyalayıp buraya yapıştırın.",
"encryption_enable": "Şifrelemeyi etkinleştir (HTTPS, DNS-over-HTTPS ve DNS-over-TLS)",
"encryption_enable_desc": "Şifrelemeyi etkinleştirirseniz, AdGuard Home yönetici arayüzü HTTPS üzerinden çalışır ve DNS sunucusu DNS-over-HTTPS ve DNS-over-TLS üzerinden gelen istekleri dinler.",
"encryption_enable_desc": "Şifrelemeyi etkinleştirirseniz, AdGuard Home yönetici arayüzü HTTPS üzerinden çalışır ve DNS sunucusu, DNS-over-HTTPS ve DNS-over-TLS üzerinden gelen istekleri dinler.",
"encryption_chain_valid": "Sertifika zinciri geçerli",
"encryption_chain_invalid": "Sertifika zinciri geçersiz",
"encryption_key_valid": "Bu geçerli bir {{type}} özel anahtar",
"encryption_key_invalid": "Bu geçersiz bir {{type}} özel anahtar",
"encryption_subject": "Konu",
"encryption_issuer": "Sertifikayı veren",
"encryption_issuer": "Sağlayan",
"encryption_hostnames": "Ana bilgisayar adları",
"encryption_reset": "Şifreleme ayarlarını sıfırlamak istediğinize emin misiniz?",
"encryption_reset": "Şifreleme ayarlarını sıfırlamak istediğinizden emin misiniz?",
"topline_expiring_certificate": "SSL sertifikanızın süresi dolmak üzere. <0>Şifreleme ayarlarını</0> güncelleyin.",
"topline_expired_certificate": "SSL sertifikanızın süresi dolmuş. <0>Şifreleme ayarlarını</0> güncelleyin.",
"topline_expired_certificate": "SSL sertifikanızın süresi doldu. <0>Şifreleme ayarlarını</0> güncelleyin.",
"form_error_port_range": "80-65535 aralığında geçerli bir bağlantı noktası değeri girin",
"form_error_port_unsafe": "Bu güvenli olmayan bir bağlantı noktası",
"form_error_equal": "Eşit olmamalı",
"form_error_port_unsafe": "Bu bağlantı noktası güvenli değil",
"form_error_equal": "Aynı olmamalı",
"form_error_password": "Şifreler uyuşmuyor",
"reset_settings": "Ayarları sıfırla",
"update_announcement": "AdGuard Home {{version}} şu an yüklenmeye hazır! Daha fazla bilgi için <0>buraya tıklayın.</0>",
"setup_guide": "Kurulum rehberi",
"update_announcement": "AdGuard Home {{version}} sürümü mevcut! Daha fazla bilgi için <0>buraya tıklayın.</0>",
"setup_guide": "Kurulum Rehberi",
"dns_addresses": "DNS adresleri",
"dns_start": "DNS sunucusu başlatılıyor",
"dns_status_error": "DNS sunucusu durumunu alma hatası",
"down": "kapalı",
"dns_status_error": "DNS sunucusunun durumu denetlenirken bir hata oluştu",
"down": "Kapalı",
"fix": "Düzelt",
"dns_providers": "Aralarından seçim yapabileceğiniz bilinen <0>DNS sağlayıcıların listesi</0>.",
"update_now": "Şimdi güncelleyin",
"update_failed": "Otomatik güncelleme başarısız oldu. Lütfen elle güncellemek için <a>talimatları uygulayın</a>.",
"processing_update": "Lütfen bekleyin. AdGuard Home güncelleniyor",
"dns_providers": "Aralarından seçim yapabileceğiniz, bilinen <0>DNS sağlayıcıların listesi</0>.",
"update_now": "Şimdi güncelle",
"update_failed": "Otomatik güncelleme başarısız oldu. Elle güncellemek için lütfen <a>bu adımları uygulayın</a>.",
"processing_update": "Lütfen bekleyin, AdGuard Home güncelleniyor",
"clients_title": "İstemciler",
"clients_desc": "AdGuard Home'a bağlı cihazları yapılandırın",
"settings_global": "Genel",
@@ -401,15 +403,15 @@
"table_client": "İstemci",
"table_name": "İsim",
"save_btn": "Kaydet",
"client_add": "İstemci ekle",
"client_add": "İstemci Ekle",
"client_new": "Yeni İstemci",
"client_edit": "İstemciyi düzenle",
"client_edit": "İstemciyi Düzenle",
"client_identifier": "Tanımlayıcı",
"ip_address": "IP adresi",
"client_identifier_desc": "İstemciler IP adresi, CIDR, MAC adresi veya özel bir istemci kimliği ile tanımlanabilir (DoT/DoH/DoQ için kullanılabilir). <0>Burada</0> istemcileri nasıl belirleyeceğiniz hakkında daha fazla bilgi edinebilirsiniz.",
"form_enter_ip": "IP Girin",
"client_identifier_desc": "İstemciler IP adresi, CIDR, MAC adresi veya özel bir istemci kimliği ile tanımlanabilir (DoT/DoH/DoQ için kullanılabilir). İstemcileri nasıl tanımlayacağınız hakkında daha fazla bilgiyi <0>burada</0> bulabilirsiniz.",
"form_enter_ip": "IP adresi girin",
"form_enter_subnet_ip": "\"{{cidr}}\" alt ağına bir IP adresi girin",
"form_enter_mac": "MAC Girin",
"form_enter_mac": "MAC adresi girin",
"form_enter_id": "Tanımlayıcı girin",
"form_add_id": "Tanımlayıcı ekle",
"form_client_name": "İstemci ismi girin",
@@ -422,82 +424,84 @@
"client_confirm_delete": "\"{{key}}\" istemcisini silmek istediğinizden emin misiniz?",
"list_confirm_delete": "Bu listeyi silmek istediğinizden emin misiniz?",
"auto_clients_title": "İstemciler (çalışma zamanı)",
"auto_clients_desc": "AdGuard Home'u kullanan, ancak yapılandırmada saklanmayan istemcilerdeki veriler",
"auto_clients_desc": "AdGuard Home'u kullanan ancak yapılandırmada depolanmayan istemcilerle ilgili veriler",
"access_title": "Erişim ayarları",
"access_desc": "Burada, AdGuard Home DNS sunucusu için erişim kurallarını yapılandırabilirsiniz.",
"access_desc": "AdGuard Home DNS sunucusu için erişim kurallarını buradan yapılandırabilirsiniz.",
"access_allowed_title": "İzin verilen istemciler",
"access_allowed_desc": "CIDR veya IP adreslerinin listesi. Yapılandırılırsa, AdGuard Home yalnızca bu IP adreslerinden gelen istekleri kabul edecektir.",
"access_allowed_desc": "CIDR'lerin, IP adreslerinin veya istemci kimliklerinin listesi. Yapılandırılırsa, AdGuard Home yalnızca bu istemcilerden gelen istekleri kabul eder.",
"access_disallowed_title": "İzin verilmeyen istemciler",
"access_disallowed_desc": "CIDR veya IP adreslerinin listesi. Yapılandırılırsa, AdGuard Home yalnızca bu IP adreslerinden gelen istekleri cevapsız bırakacaktır.",
"access_blocked_title": "Engellenmiş alan adları",
"access_blocked_desc": "Bunu filtrelerle karıştırmayın. AdGuard Home, sorguların sorularına bu alan adlarıyla DNS sorgularını bırakacaktır. Burada tam alan adlarını, joker karakterleri ve URL filtre kurallarını belirtebilirsiniz, örn. \"example.org\", \"*.example.org\" veya \"|| example.org^\".",
"access_disallowed_desc": "CIDR'lerin, IP adreslerinin veya istemci kimliklerinin listesi. Yapılandırılırsa, AdGuard Home bu istemcilerden gelen istekleri keser. İzin verilen istemciler yapılandırılırsa, bu alan yok sayılır.",
"access_blocked_title": "Engellenen alan adları",
"access_blocked_desc": "Bu işlem filtrelerle ilgili değildir. AdGuard Home, bu alan adlarından gelen DNS sorgularını yanıtsız bırakır ve bu sorgular sorgu günlüğünde görünmez. Tam alan adlarını, joker karakterleri veya URL filtre kurallarını belirtebilirsiniz, ör. \"example.org\", \"*.example.org\" veya \"||example.org^\".",
"access_settings_saved": "Erişim ayarları başarıyla kaydedildi!",
"updates_checked": "Güncelleme kontrolü başarılı",
"updates_version_equal": "AdGuard Home yazılımı günceldir",
"updates_version_equal": "AdGuard Home yazılımı güncel durumda",
"check_updates_now": "Güncellemeleri şimdi denetle",
"dns_privacy": "DNS Gizliliği",
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> <1>{{address}}</1> dizesini kullan.",
"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_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 aslen DNS-over-TLS desteklemektedir. Yapılandırmak için, Ayarlar → Ağ ve internet → Gelişmiş → Özel DNS seçeneğine gidin ve alan adınızı buraya girin.",
"setup_dns_privacy_android_2": "<0>AdGuard for Android</0>, <1>DNS-over-HTTPS</1> ve <1>DNS-over-TLS</1> desteklemektedir.",
"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_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> desteğini ekler.",
"setup_dns_privacy_ios_1": "<0>DNSCloak</0>, <1>DNS-over-HTTPS</1> destekler, ancak kendi sunucunuzu kullanacak şekilde yapılandırmak için bir <2>DNS Damgası</2> oluşturmanız gerekir.",
"setup_dns_privacy_ios_2": "<0>AdGuard for iOS</0>, <1>DNS-over-HTTPS</1> ve <1>DNS-over-TLS</1> destekler.",
"setup_dns_privacy_other_title": "Diğer uygulamalar",
"setup_dns_privacy_other_1": "AdGuard Home'un kendisi herhangi bir platformda güvenli bir DNS istemcisi olabilir.",
"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.",
"setup_dns_privacy_ios_2": "<0>iOS için AdGuard</0>, <1>DNS-over-HTTPS</1> ve <1>DNS-over-TLS</1> protokolünü destekler.",
"setup_dns_privacy_other_title": "Diğer kullanım alanları",
"setup_dns_privacy_other_1": "AdGuard Home, herhangi bir platformda güvenli bir DNS istemcisi olabilir.",
"setup_dns_privacy_other_2": "<0>dnsproxy</0>, bilinen tüm güvenli DNS protokollerini destekler.",
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0>, <1>DNS-over-HTTPS</1> destekler.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0>, <1>DNS-over-HTTPS</1> desteklemektedir.",
"setup_dns_privacy_other_5": "<0>Burada</0> ve <1>burada</1> daha fazla uygulama bulacaksınız.",
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0>, <1>DNS-over-HTTPS</1> protokolünü destekler.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0>, <1>DNS-over-HTTPS</1> protokolünü destekler.",
"setup_dns_privacy_other_5": "<0>Burada</0> ve <1>burada</1> daha fazla kullanım alanı bulacaksınız.",
"setup_dns_privacy_ioc_mac": "iOS ve macOS yapılandırması",
"setup_dns_notice": "<1>DNS-over-HTTPS</1> veya <1>DNS-over-TLS</1> kullanmak için, AdGuard Home ayarlarında <0>Şifreleme yapılandırmasını</0> yapmanız gerekir.",
"setup_dns_notice": "<1>DNS-over-HTTPS</1> veya <1>DNS-over-TLS</1> protokolünü kullanmak için AdGuard Home üzerinde <0>Şifreleme ayarları</0> bölümünden ayarları yapmanız gerekir.",
"rewrite_added": "\"{{key}}\" için DNS yeniden yazımı başarıyla eklendi",
"rewrite_deleted": "\"{{key}}\" için DNS yeniden yazımı başarıyla silindi",
"rewrite_add": "DNS yeniden yazımı ekle",
"rewrite_not_found": "DNS yeniden yazımı bulunamadı",
"rewrite_confirm_delete": "\"{{key}}\" için DNS yeniden yazımını silmek istediğinize emin misiniz?",
"rewrite_desc": "Belirli bir alan adı için kolayca özel DNS yanıtı yapılandırmanıza olanak tanır.",
"rewrite_applied": "Uygulanan Yeniden Yazım kuralı",
"rewrite_desc": "Belirli bir alan adı için özel DNS yanıtını kolayca yapılandırmanızı sağlar.",
"rewrite_applied": "Yeniden yazım kuralı uygulandı",
"rewrite_hosts_applied": "Ana bilgisayar dosyası kuralı tarafından yeniden yazıldı",
"dns_rewrites": "DNS yeniden yazımları",
"form_domain": "Alan adı girin",
"form_answer": "IP adresini veya alan adı girin",
"form_domain": "Alan adı veya joker karakter girin",
"form_answer": "IP adresi veya alan adı girin",
"form_error_domain_format": "Geçersiz alan adı biçimi",
"form_error_answer_format": "Geçersiz cevap biçimi",
"form_error_answer_format": "Geçersiz yanıt biçimi",
"configure": "Yapılandır",
"main_settings": "Ana ayarlar",
"block_services": "Belirli hizmetleri engelle",
"blocked_services": "Engellenen hizmetler",
"blocked_services_desc": "Popüler siteleri ve hizmetleri hızlı bir şekilde engellemenizi sağlar.",
"blocked_services_saved": "Engellenen servisler başarıyla kaydedildi",
"blocked_services_global": "Genel engellenen hizmetleri kullanın",
"blocked_services_saved": "Engellenen hizmetler başarıyla kaydedildi",
"blocked_services_global": "Genel olarak engellenen hizmetleri kullan",
"blocked_service": "Engellenen hizmet",
"block_all": "Hepsini engelle",
"unblock_all": "Tüm engellemeyi kaldır",
"encryption_certificate_path": "Sertifika yolu",
"encryption_private_key_path": "Özel anahtar yolu",
"encryption_certificates_source_path": "Sertifika dosyalarının yolunu belirleyin",
"encryption_certificates_source_content": "Sertifikaların içeriklerini yapıştırı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çeriklerini yapıştırın",
"encryption_key_source_content": "Özel anahtar içeriğini yapıştır",
"stats_params": "İstatistik yapılandırması",
"config_successfully_saved": "Yapılandırma başarıyla kaydedildi",
"interval_6_hour": "6 saat",
"interval_24_hour": "24 saat",
"interval_days": "{{count}} gün",
"interval_days_plural": "{{count}} gün",
"domain": "Alan adı",
"answer": "Cevap",
"filter_added_successfully": "Filtre başarıyla eklendi",
"filter_removed_successfully": "Filtre başarıyla kaldırıldı",
"filter_updated": "Filtre başarıyla güncellendi",
"punycode": "Punycode",
"answer": "Yanıt",
"filter_added_successfully": "Liste başarıyla eklendi",
"filter_removed_successfully": "Liste başarıyla kaldırıldı",
"filter_updated": "Liste başarıyla güncellendi",
"statistics_configuration": "İstatistik yapılandırması",
"statistics_retention": "İstatistikleri depolama",
"statistics_retention_desc": "Zaman değerini azaltırsanız bazı veriler kaybolacaktır",
"statistics_retention": "İstatistikleri sakla",
"statistics_retention_desc": "Zaman değerini azaltırsanız, bazı veriler kaybolacaktır",
"statistics_clear": " İstatistikleri temizle",
"statistics_clear_confirm": "İstatistikleri temizlemeyi istediğinizden emin misiniz?",
"statistics_retention_confirm": "İstatistik saklama süresini değiştirmek istediğinize emin misiniz? Aralık değerini azaltırsanız, bazı veriler kaybolacaktır",
"statistics_clear_confirm": "İstatistikleri temizlemek istediğinizden emin misiniz?",
"statistics_retention_confirm": "İstatistik saklama süresini değiştirmek istediğinizden emin misiniz? Zaman değerini azaltırsanız, bazı veriler kaybolacaktır",
"statistics_cleared": "İstatistikler başarıyla temizlendi",
"interval_hours": "{{count}} saat",
"interval_hours_plural": "{{count}} saat",
@@ -512,87 +516,89 @@
"sign_in": "Giriş yap",
"sign_out": "Oturumu kapat",
"forgot_password": "Parolanızı mı unuttunuz?",
"forgot_password_desc": "Kullanıcı hesabınız için yeni bir parola oluşturmak için lütfen <0>bu adımları</0> takip edin.",
"forgot_password_desc": "Kullanıcı hesabınız için yeni bir parola oluşturmak istiyorsanız lütfen <0>bu adımları</0> uygulayın.",
"location": "Konum",
"orgname": "Organizasyon adı",
"orgname": "Kuruluş adı",
"netname": "Ağ adı",
"network": "Ağ",
"descr": "Açıklama",
"whois": "Whois",
"filtering_rules_learn_more": "Kendi ana bilgisayar listelerinizi oluşturma hakkında <0>daha fazla bilgi edinin</0></0>.",
"blocked_by_response": "Cevap olarak CNAME veya IP tarafından engellendi",
"filtering_rules_learn_more": "Kendi ana bilgisayar listelerinizi oluşturma hakkında <0>daha fazla bilgi edinin</0>.",
"blocked_by_response": "Yanıt olarak CNAME veya IP tarafından engellendi",
"blocked_by_cname_or_ip": "CNAME veya IP tarafından engellendi",
"try_again": "Tekrar deneyin",
"try_again": "Tekrar dene",
"domain_desc": "Yeniden yazılmasını istediğiniz alan adını veya joker karakteri girin.",
"example_rewrite_domain": "cevapları yalnızca bu alan adı için yeniden yaz.",
"example_rewrite_wildcard": "tüm <0>example.org</0> alt alanları için cevapları yeniden yaz.",
"example_rewrite_domain": "yanıtları yalnızca bu alan adı için yeniden yaz.",
"example_rewrite_wildcard": "tüm <0>example.org</0> alt alanları için yanıtları yeniden yaz.",
"rewrite_ip_address": "IP adresi: bu IP'yi A veya AAAA yanıtında kullanın",
"rewrite_domain_name": "Alan adı: bir CNAME kaydı ekleyin",
"rewrite_A": "<0>A</0>: özel değer, üst sunucudan gelen <0>A</0> kayıtlarını tut",
"rewrite_AAAA": "<0>AAA</0>: özel değer, üst sunucudan gelen <0>AAA</0> kayıtlarını tut",
"rewrite_A": "<0>A</0>: özel değer, üst sunucudan gelen <0>A</0> kayıtlarını tutun",
"rewrite_AAAA": "<0>AAA</0>: özel değer, üst sunucudan gelen <0>AAA</0> kayıtlarını tutun",
"disable_ipv6": "IPv6 adreslerinin çözümlenmesini devre dışı bırak",
"disable_ipv6_desc": "IPv6 adresleri için tüm DNS sorgularını bırakın (AAAA yazın).",
"disable_ipv6_desc": "IPv6 adresleri için tüm DNS sorgularını yanıtsız bırakır (AAAA yazar).",
"fastest_addr": "En hızlı IP adresi",
"fastest_addr_desc": "Tüm DNS sunucularını sorgulayın ve tüm yanıtlar arasında en hızlı IP adresini döndürün. AdGuard Home'un tüm DNS sunucularından yanıt beklemesi gerektiğinden, bu DNS sorgularını yavaşlatır ancak genel bağlantıyı iyileştirir.",
"autofix_warning_text": "\"Düzelt\" i tıklatırsanız, AdGuardHome sisteminizi AdGuardHome DNS sunucusunu kullanacak şekilde yapılandırır.",
"fastest_addr_desc": "Tüm DNS sunucularını sorgulayın ve tüm yanıtlar arasından en hızlı olan IP adresini döndürün. AdGuard Home'un tüm DNS sunucularından yanıt beklemesi gerektiği için DNS sorgularını yavaşlatır, ancak genel bağlantıyı iyileştirir.",
"autofix_warning_text": "\"Düzelt\" seçeneğine tıklarsanız, AdGuard Home, sisteminizi AdGuard Home DNS sunucusunu kullanacak şekilde yapılandırır.",
"autofix_warning_list": "Bu görevleri gerçekleştirecek: <0>Sistem DNSStubListener'ı devre dışı bırakın</0> <0>DNS sunucusu adresini 127.0.0.1 olarak ayarlayın</0> <0>/etc/resolv.conf'un sembolik bağlantı hedefini /run/systemd/resolve/resolv.conf ile değiştirin<0> <0>DNSStubListener'ı durdurun (systemd çözümlenmiş hizmeti yeniden yükleyin)</0>",
"autofix_warning_result": "Sonuç olarak, sisteminizden gelen tüm DNS istekleri varsayılan olarak AdGuard Home tarafından işlenecektir.",
"tags_title": "Etiketler",
"tags_desc": "Müşteriye karşılık gelen etiketleri seçebilirsiniz. Etiketler filtreleme kurallarına dahil edilebilir ve bunları daha doğru uygulamanıza olanak tanır. <0>Daha fazla bilgi edinin</0>",
"tags_desc": "İstemciyi tanımlayan etiketleri seçebilirsiniz. Etiketler, filtreleme kurallarına dahil edilebilir ve bunları daha doğru bir şekilde uygulamanıza olanak tanır. <0>Daha fazla bilgi edinin</0>",
"form_select_tags": "İstemci etiketlerini seçin",
"check_title": "Filtrelemeyi denetleyin",
"check_desc": "Ana bilgisayar adının filtrelenip filtrelenmediğini kontrol edin",
"check_desc": "Ana bilgisayar adının filtreleme durumunu kontrol edin",
"check": "Denetle",
"form_enter_host": "Ana bilgisayar adı girin",
"filtered_custom_rules": "Özel filtreleme kurallarına göre filtrelendi",
"choose_from_list": "Listeden seç",
"add_custom_list": "Özel bir liste ekle",
"host_whitelisted": "Ana bilgisayar beyaz listeye eklendi",
"add_custom_list": "Özel liste ekle",
"host_whitelisted": "Ana bilgisayara izin verildi",
"check_ip": "IP adresleri: {{ip}}",
"check_cname": "CNAME: {{cname}}",
"check_reason": "Sebep: {{reason}}",
"check_service": "Hizmet adı: {{service}}",
"service_name": "Servis adı",
"service_name": "Hizmet adı",
"check_not_found": "Filtre listelerinizde bulunamadı",
"client_confirm_block": "\"{{ip}}\" istemcisini engellemek istediğinizden emin misiniz?",
"client_confirm_unblock": "\"{{ip}}\" istemcisinin engellemesini kaldırmak istediğinizden emin misiniz?",
"client_blocked": "\"{{ip}}\" istemcisi başarıyla engellendi",
"client_unblocked": "\"{{ip}}\" istemcinin engellemesi başarıyla kaldırıldı",
"static_ip": "Statik IP adres",
"static_ip_desc": "AdGuard Home bir sunucudur, bu nedenle düzgün çalışması için statik bir IP adresine ihtiyaç duyar. Aksi takdirde, bir noktada yönlendiriciniz bu cihaza farklı bir IP adresi atayabilir.",
"set_static_ip": "Statik IP adresi ayarlama",
"install_static_ok": "İyi haberler! Statik IP adresi zaten yapılandırılmış",
"install_static_error": "AdGuard Home, bu ağ arayüzü için otomatik olarak yapılandıramaz. Lütfen bunu manuel olarak nasıl yapacağınıza ilişkin bir talimat arayın.",
"install_static_configure": "AdGuard Home, <0>{{ip}}</0> dinamik IP adresinin kullanıldığını tespit etti. Statik adresiniz olarak ayarlanmasını ister misiniz?",
"confirm_static_ip": "AdGuard Home, {{ip}} adresini statik IP adresiniz olacak şekilde yapılandıracak. Devam etmek istiyor musunuz?",
"static_ip": "Sabit IP adresi",
"static_ip_desc": "AdGuard Home bir sunucudur, bu nedenle düzgün çalışması için sabit bir IP adresine ihtiyacı vardır. Aksi takdirde, yönlendiriciniz bir zaman sonra bu cihaza farklı bir IP adresi atayabilir.",
"set_static_ip": "Sabit IP adresi ayarla",
"install_static_ok": "Güzel haber! Sabit IP adresi zaten yapılandırılmış",
"install_static_error": "AdGuard Home, bu ağ arayüzü için otomatik olarak yapılandıramıyor. Lütfen bunu elle nasıl yapacağınızla ilgili talimatlara bakın.",
"install_static_configure": "AdGuard Home, <0>{{ip}}</0> dinamik IP adresinin kullanıldığını tespit etti. Sabit adresiniz olarak ayarlanmasını ister misiniz?",
"confirm_static_ip": "AdGuard Home, {{ip}} adresini sabit IP adresiniz olacak şekilde yapılandıracaktır. Devam etmek istiyor musunuz?",
"list_updated": "{{count}} liste güncellendi",
"list_updated_plural": "{{count}} liste güncellendi",
"dnssec_enable": "DNSSEC'i etkinleştir",
"dnssec_enable_desc": "DNSSEC'i giden DNS sorguları için etkinleştir ve sonucu kontrol et (DNSSEC-etkin sorgulama gerekli).",
"dnssec_enable_desc": "Giden DNS sorguları için DNSSEC özelliğini etkinleştir ve sonucu kontrol et (DNSSEC özellikli çözümleyici gerekli).",
"validated_with_dnssec": "DNSSEC ile doğrulandı",
"all_queries": "Tüm sorgular",
"show_blocked_responses": "Engellendi",
"show_whitelisted_responses": "Beyaz listeye eklendi",
"show_whitelisted_responses": "İzin verildi",
"show_processed_responses": "İşlendi",
"blocked_safebrowsing": "Güvenli gezinti tarafından engellendi",
"blocked_adult_websites": "Yetişkin içerikli site engellendi",
"blocked_threats": "Engellenen Tehditler",
"allowed": "İzin verildi",
"filtered": "Filtrelenmiş",
"allowed": "İzin verilen",
"filtered": "Filtrelenen",
"rewritten": "Yeniden yazılan",
"safe_search": "Güvenli arama",
"blocklist": "Engelleme listesi",
"milliseconds_abbreviation": "ms",
"cache_size": "Önbellek boyutu",
"cache_size_desc": "DNS önbelleği boyutu (byte cinsinden)",
"cache_size_desc": "DNS önbellek boyutu (bayt cinsinden)",
"cache_ttl_min_override": "Minimum TTL'yi değiştir",
"cache_ttl_max_override": "Maksimum TTL'yi değiştir",
"enter_cache_size": "Önbellek boyutunu girin (byte)",
"enter_cache_size": "Önbellek boyutunu girin (bayt)",
"enter_cache_ttl_min_override": "Minimum TTL değerini girin (saniye)",
"enter_cache_ttl_max_override": "Maksimum TTL değerini girin (saniye)",
"cache_ttl_min_override_desc": "DNS yanıtlarını önbelleğe alırken üst sunucusundan alınan kullanım süresi değerini (saniye) uzatın",
"cache_ttl_max_override_desc": "DNS önbelleğindeki girişler için maksimum kullanım süresi değerini (saniye) ayarlayın",
"cache_ttl_min_override_desc": "DNS yanıtlarını önbelleğe alırken üst sunucudan alınan kullanım süresi değerini uzatın (saniye olarak)",
"cache_ttl_max_override_desc": "DNS önbelleğindeki girişler için maksimum kullanım süresi değerini ayarlayın (saniye olarak)",
"ttl_cache_validation": "Minimum önbellek TTL değeri, maksimum değerden küçük veya bu değere eşit olmalıdır",
"cache_optimistic": "İyimser",
"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",
"filter_category_security": "Güvenlik",
"filter_category_regional": "Bölgesel",
@@ -602,10 +608,10 @@
"filter_category_regional_desc": "Bölgesel reklamlara ve izleme sunucularına odaklanan listeler",
"filter_category_other_desc": "Diğer engelleme listeleri",
"setup_config_to_enable_dhcp_server": "DHCP sunucusunu etkinleştirmek için kurulum yapılandırması",
"original_response": "Esas yanıt",
"original_response": "Gerçek yanıt",
"click_to_view_queries": "Sorguları görmek için tıklayın",
"port_53_faq_link": "Port 53 genellikle \"DNSStubListener\" veya \"sistemd-resolved\" hizmetler tarafından kullanılır. Lütfen problemin nasıl çözüleceğine ilişkin <0>bu talimatı</0> okuyun.",
"adg_will_drop_dns_queries": "AdGuard Home, bu istemciden gelen tüm DNS sorgularını iptal eder.",
"client_not_in_allowed_clients": "İstemciye \"İzin verilen istemciler\" listesinde olmadığı için izin verilmiyor.",
"port_53_faq_link": "53 numaralı bağlantı noktası genellikle \"DNSStubListener\" veya \"systemd-resolved\" hizmetleri tarafından kullanılır. Lütfen bu sorunun nasıl çözüleceğine ilişkin <0>bu talimatı</0> okuyun.",
"adg_will_drop_dns_queries": "AdGuard Home, bu istemciden gelen tüm DNS sorgularını yok sayar.",
"client_not_in_allowed_clients": "\"İzin verilen istemciler\" listesinde olmadığı için istemciye izin verilmiyor.",
"experimental": "Deneysel"
}

View File

@@ -68,6 +68,9 @@
"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": "城市",
@@ -109,6 +112,8 @@
"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": "被拦截域名排行",
@@ -324,7 +329,7 @@
"install_devices_windows_list_3": "在窗口的左侧找到 ”更改适配器设置“ 并点击进入。",
"install_devices_windows_list_4": "选择您正在连接的网络设备,右击它并选择 ”属性“ 。",
"install_devices_windows_list_5": "在列表中找到 ”Internet 协议版本 4 (TCP/IPv4)“ ,选择并再次点击 ”属性“ 。",
"install_devices_windows_list_6": "选择使用下面的 DNS 服务器地址,并输入您的 AdGuard Home 服务器地址。",
"install_devices_windows_list_6": "选择使用下面的 DNS 服务器地址,并输入您的 AdGuard Home 服务器地址。",
"install_devices_macos_list_1": "点击苹果图标,进入 ”系统首选项“。",
"install_devices_macos_list_2": "点击 ”网络“ 。",
"install_devices_macos_list_3": "选择在列表中的第一个连接,并点击 ”高级“ 。",
@@ -423,9 +428,9 @@
"access_title": "访问设置",
"access_desc": "您可在此处配置 AdGuard Home DNS 服务器的访问规则。",
"access_allowed_title": "允许的客户端",
"access_allowed_desc": "CIDRIP 地址列表。如配置,则 AdGuard Home 仅接受自这些 IP 地址的请求。",
"access_allowed_desc": "CIDRIP 地址或客户端 ID 的列表。如配置,则 AdGuard Home 仅接受自这些客户端的请求。",
"access_disallowed_title": "不允许的客户端",
"access_disallowed_desc": "CIDR 或 IP 地址列表。如配置,则 AdGuard Home 会放弃源自这些 IP 地址的请求。",
"access_disallowed_desc": "CIDR、IP 地址或客户端 ID 的列表。如果已配置,则 AdGuard Home 将丢弃来自这些 IP 地址的请求。如果允许的客户端已配置,此字段将会被忽略。",
"access_blocked_title": "不允许的域名",
"access_blocked_desc": "不要将此功能与过滤器混淆。AdGuard Home 将排除匹配这些网域的 DNS 查询并且这些查询将不会在查询日志中显示。在此可以明确指定域名、通配符wildcard和网址过滤的规则例如 \"example.org\"、\"*.example.org\" 或 \"||example.org^\"。",
"access_settings_saved": "访问设置保存成功",
@@ -481,10 +486,12 @@
"encryption_key_source_content": "粘贴私钥内容",
"stats_params": "统计配置",
"config_successfully_saved": "配置保存成功",
"interval_6_hour": "6 小时",
"interval_24_hour": "24 小时",
"interval_days": "{{count}} 天",
"interval_days_plural": "{{count}} 天",
"domain": "域名",
"punycode": "Punycode",
"answer": "应答",
"filter_added_successfully": "已成功添加过滤器",
"filter_removed_successfully": "已成功删除该列表",
@@ -590,6 +597,8 @@
"cache_ttl_min_override_desc": "缓存 DNS 响应时,延长从上游服务器接收到的 TTL 值 (秒)",
"cache_ttl_max_override_desc": "设定 DNS 缓存条目的最大 TTL 值(秒)",
"ttl_cache_validation": "最小缓存TTL值必须小于或等于最大值",
"cache_optimistic": "优化的",
"cache_optimistic_desc": "即使条目已过期,也让 AdGuard Home 从缓存中响应,并尝试刷新它们。",
"filter_category_general": "常规",
"filter_category_security": "安全",
"filter_category_regional": "区域",

View File

@@ -112,6 +112,8 @@
"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": "熱門封鎖網域排行",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "貼上私鑰內容",
"stats_params": "統計資料設定",
"config_successfully_saved": "已儲存設定",
"interval_6_hour": "6 小時",
"interval_24_hour": "24 小時",
"interval_days": "{{count}} 天",
"interval_days_plural": "{{count}} 天",
"domain": "網域",
"punycode": "Punycode",
"answer": "回應",
"filter_added_successfully": "已成功新增清單",
"filter_removed_successfully": "已成功移除清單",
@@ -593,6 +597,8 @@
"cache_ttl_min_override_desc": "快取 DNS 回應時,延長從上游伺服器收到的 TTL 值 (秒)",
"cache_ttl_max_override_desc": "設定 DNS 快取條目的最大 TTL 值(秒)",
"ttl_cache_validation": "最小快取 TTL 值必須小於或等於最大值",
"cache_optimistic": "優化的",
"cache_optimistic_desc": "即使條目已過期,也讓 AdGuard Home 從快取中回應,並嘗試刷新它們。",
"filter_category_general": "一般",
"filter_category_security": "安全性",
"filter_category_regional": "區域性",

View File

@@ -112,6 +112,8 @@
"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": "熱門已封鎖的網域",
@@ -324,10 +326,10 @@
"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": "在清單中找到網際網路通訊協定第 4 版TCP/IPv4選擇它然後再次向內容點擊。",
"install_devices_windows_list_6": "選擇使用下列的 DNS 伺服器位址,然後輸入您的 AdGuard Home 伺服器位址。",
"install_devices_windows_list_5": "在清單中找到\"網際網路通訊協定第 4 版TCP/IPv4\"[或用於 IPv6\"網際網路通訊協定第 6 版TCP/IPv6\"],選擇它,然後再次向內容點擊。",
"install_devices_windows_list_6": "選擇\"使用下列的 DNS 伺服器位址\",然後輸入您的 AdGuard Home 伺服器位址。",
"install_devices_macos_list_1": "向 Apple 圖像點擊,然後去系統偏好設定。",
"install_devices_macos_list_2": "向網路點擊。",
"install_devices_macos_list_3": "選擇在您的清單中之首要的連線,然後點擊進階的。",
@@ -426,9 +428,9 @@
"access_title": "存取設定",
"access_desc": "於此您可配置用於 AdGuard Home DNS 伺服器之存取規則。",
"access_allowed_title": "已允許的用戶端",
"access_allowed_desc": "無類別網域間路由CIDR)或 IP 位址之清單。如果被配置AdGuard Home 將接受僅來自這些 IP 位址的請求。",
"access_allowed_desc": "無類別網域間路由CIDRsIP 位址或用戶端 ID 之清單。如果被配置AdGuard Home 將接受僅來自這些用戶端的請求。",
"access_disallowed_title": "未被允許的用戶端",
"access_disallowed_desc": "無類別網域間路由CIDR)或 IP 位址之清單。如果被配置AdGuard Home 將排除來自這些 IP 位址的請求。",
"access_disallowed_desc": "無類別網域間路由CIDRsIP 位址或用戶端 IDs 之清單。如果被配置AdGuard Home 將排除來自這些用戶端的請求。如果已允許的用戶端被配置,此欄位被忽略。",
"access_blocked_title": "未被允許的網域",
"access_blocked_desc": "不要把這個和過濾器混淆。AdGuard Home 排除與這些網域相符的 DNS 查詢且這些查詢甚至不會出現在查詢記錄中。您可相應地明確指定確切的域名、萬用字元wildcard或網址過濾器的規則例如\"example.org\"、\"*.example.org\" 或 \"||example.org^\"。",
"access_settings_saved": "存取設定被成功地儲存",
@@ -484,10 +486,12 @@
"encryption_key_source_content": "貼上該私密金鑰內容",
"stats_params": "統計資料配置",
"config_successfully_saved": "配置被成功地儲存",
"interval_6_hour": "6 小時",
"interval_24_hour": "24 小時",
"interval_days": "{{count}} 日",
"interval_days_plural": "{{count}} 日",
"domain": "網域",
"punycode": "國際化域名代碼Punycode",
"answer": "回應",
"filter_added_successfully": "該清單已被成功地加入",
"filter_removed_successfully": "該清單已被成功地移除",
@@ -593,12 +597,14 @@
"cache_ttl_min_override_desc": "當快取 DNS 回應時,延長從上游的伺服器收到的短存活時間數值(秒)",
"cache_ttl_max_override_desc": "設定最大的存活時間數值(秒)供在 DNS 快取中的項目",
"ttl_cache_validation": "最小的快取存活時間TTL數值必須小於或等於最大的數值",
"cache_optimistic": "樂觀快取模式",
"cache_optimistic_desc": "即使當項目為已到期的,從快取使 AdGuard Home 回覆,並還嘗試重新整理它們。",
"filter_category_general": "一般的",
"filter_category_security": "安全性",
"filter_category_regional": "區域性的",
"filter_category_other": "其它的",
"filter_category_general_desc": "封鎖大多數朝向裝置的追蹤和廣告之清單",
"filter_category_security_desc": "特別地封鎖惡意、網路釣魚和詐騙的網域之清單",
"filter_category_security_desc": "專門地封鎖惡意、網路釣魚和詐騙的網域之清單",
"filter_category_regional_desc": "專注於區域性的廣告和追蹤伺服器之清單",
"filter_category_other_desc": "其它的封鎖清單",
"setup_config_to_enable_dhcp_server": "設置配置以啟用 DHCP 伺服器",

View File

@@ -1,12 +1,15 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { HashLink as Link } from 'react-router-hash-link';
import { Trans, useTranslation } from 'react-i18next';
import classNames from 'classnames';
import Statistics from './Statistics';
import Counters from './Counters';
import Clients from './Clients';
import QueriedDomains from './QueriedDomains';
import BlockedDomains from './BlockedDomains';
import { SETTINGS_URLS } from '../../helpers/constants';
import PageTitle from '../ui/PageTitle';
import Loading from '../ui/Loading';
@@ -34,6 +37,16 @@ const Dashboard = ({
getAllStats();
}, []);
const getSubtitle = () => {
if (stats.interval === 0) {
return t('stats_disabled_short');
}
return stats.interval === 1
? t('for_last_24_hours')
: t('for_last_days', { count: stats.interval });
};
const buttonText = protectionEnabled ? 'disable_protection' : 'enable_protection';
const buttonClass = classNames('btn btn-sm dashboard-title__button', {
@@ -52,14 +65,12 @@ const Dashboard = ({
</svg>
</button>;
const subtitle = stats.interval === 1
? t('for_last_24_hours')
: t('for_last_days', { count: stats.interval });
const statsProcessing = stats.processingStats
|| stats.processingGetConfig
|| access.processing;
const subtitle = getSubtitle();
return <>
<PageTitle title={t('dashboard')} containerClass="page-title--dashboard">
<button
@@ -81,6 +92,20 @@ const Dashboard = ({
{statsProcessing && <Loading />}
{!statsProcessing && <div className="row row-cards dashboard">
<div className="col-lg-12">
{stats.interval === 0 && (
<div className="alert alert-warning" role="alert">
<Trans components={[
<Link
to={`${SETTINGS_URLS.settings}#stats-config`}
key="0"
>
link
</Link>,
]}>
stats_disabled
</Trans>
</div>
)}
<Statistics
interval={stats.interval}
dnsQueries={stats.dnsQueries}

View File

@@ -3,7 +3,9 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { nanoid } from 'nanoid';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import propTypes from 'prop-types';
import { checkFiltered, getBlockingClientName } from '../../../helpers/helpers';
import { BLOCK_ACTIONS } from '../../../helpers/constants';
import { toggleBlocking, toggleBlockingForClient } from '../../../actions';
@@ -192,12 +194,13 @@ const ClientCell = ({
{renderFormattedClientCell(client, clientInfo, isDetailed, true)}
</div>
{isDetailed && clientName && !whoisAvailable && (
<div
className="detailed-info d-none d-sm-block logs__text"
<Link
className="detailed-info d-none d-sm-block logs__text logs__text--link"
to={`logs?search=${encodeURIComponent(clientName)}`}
title={clientName}
>
{clientName}
</div>
</Link>
)}
</div>
{renderBlockingButton(isFiltered, domain)}

View File

@@ -197,4 +197,5 @@ Form.propTypes = {
export default reduxForm({
form: FORM_NAME.LOGS_FILTER,
enableReinitialize: true,
})(Form);

View File

@@ -51,6 +51,15 @@
color: #888888;
}
.logs__text--link {
color: #467fcf;
}
.logs__text--link:hover,
.logs__text--link:focus {
color: #295a9f;
}
.icon--selected {
background-color: var(--gray-f3);
border: solid 1px var(--gray-d8);

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { Trans, useTranslation } from 'react-i18next';
import { shallowEqual, useSelector } from 'react-redux';
import { renderInputField, toNumber } from '../../../../helpers/form';
import { renderInputField, toNumber, CheckboxField } from '../../../../helpers/form';
import { CACHE_CONFIG_FIELDS, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants';
import { replaceZeroWithEmptyString } from '../../../../helpers/helpers';
@@ -47,27 +47,48 @@ const Form = ({
}) => <div className="col-12" key={name}>
<div className="col-12 col-md-7 p-0">
<div className="form__group form__group--settings">
<label htmlFor={name}
className="form__label form__label--with-desc">{t(title)}</label>
<label
htmlFor={name}
className="form__label form__label--with-desc"
>
{t(title)}
</label>
<div className="form__desc form__desc--top">{t(description)}</div>
<Field
name={name}
type="number"
component={renderInputField}
placeholder={t(placeholder)}
disabled={processingSetConfig}
className="form-control"
validate={validate}
normalizeOnBlur={replaceZeroWithEmptyString}
normalize={toNumber}
min={min}
max={max}
name={name}
type="number"
component={renderInputField}
placeholder={t(placeholder)}
disabled={processingSetConfig}
className="form-control"
validate={validate}
normalizeOnBlur={replaceZeroWithEmptyString}
normalize={toNumber}
min={min}
max={max}
/>
</div>
</div>
</div>)}
{minExceedsMax
&& <span className="text-danger pl-3 pb-3">{t('ttl_cache_validation')}</span>}
{minExceedsMax && (
<span className="text-danger pl-3 pb-3">
{t('ttl_cache_validation')}
</span>
)}
</div>
<div className="row">
<div className="col-12 col-md-7">
<div className="form__group form__group--settings">
<Field
name="cache_optimistic"
type="checkbox"
component={CheckboxField}
placeholder={t('cache_optimistic')}
disabled={processingSetConfig}
subtitle={t('cache_optimistic_desc')}
/>
</div>
</div>
</div>
<button
type="submit"

View File

@@ -10,7 +10,7 @@ const CacheConfig = () => {
const { t } = useTranslation();
const dispatch = useDispatch();
const {
cache_size, cache_ttl_max, cache_ttl_min,
cache_size, cache_ttl_max, cache_ttl_min, cache_optimistic,
} = useSelector((state) => state.dnsConfig, shallowEqual);
const handleFormSubmit = (values) => {
@@ -31,6 +31,7 @@ const CacheConfig = () => {
cache_size: replaceZeroWithEmptyString(cache_size),
cache_ttl_max: replaceZeroWithEmptyString(cache_ttl_max),
cache_ttl_min: replaceZeroWithEmptyString(cache_ttl_min),
cache_optimistic,
}}
onSubmit={handleFormSubmit}
/>

View File

@@ -4,26 +4,33 @@ import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { CheckboxField, renderRadioField, toNumber } from '../../../helpers/form';
import { CheckboxField, renderRadioField, toFloatNumber } from '../../../helpers/form';
import { FORM_NAME, QUERY_LOG_INTERVALS_DAYS } from '../../../helpers/constants';
import '../FormButton.css';
const getIntervalFields = (processing, t, toNumber) => QUERY_LOG_INTERVALS_DAYS.map((interval) => {
const title = interval === 1 ? t('interval_24_hour') : t('interval_days', { count: interval });
const getIntervalTitle = (interval, t) => {
switch (interval) {
case 0.25:
return t('interval_6_hour');
case 1:
return t('interval_24_hour');
default:
return t('interval_days', { count: interval });
}
};
return (
<Field
key={interval}
name="interval"
type="radio"
component={renderRadioField}
value={interval}
placeholder={title}
normalize={toNumber}
disabled={processing}
/>
);
});
const getIntervalFields = (processing, t, toNumber) => QUERY_LOG_INTERVALS_DAYS.map((interval) => (
<Field
key={interval}
name="interval"
type="radio"
component={renderRadioField}
value={interval}
placeholder={getIntervalTitle(interval, t)}
normalize={toNumber}
disabled={processing}
/>
));
const Form = (props) => {
const {
@@ -56,7 +63,7 @@ const Form = (props) => {
</label>
<div className="form__group form__group--settings">
<div className="custom-controls-stacked">
{getIntervalFields(processing, t, toNumber)}
{getIntervalFields(processing, t, toFloatNumber)}
</div>
</div>
<div className="mt-5">

View File

@@ -7,9 +7,13 @@ import Form from './Form';
class StatsConfig extends Component {
handleFormSubmit = (values) => {
const { t } = this.props;
// eslint-disable-next-line no-alert
if (window.confirm(t('statistics_retention_confirm'))) {
const { t, interval: prevInterval } = this.props;
if (values.interval < prevInterval) {
if (window.confirm(t('statistics_retention_confirm'))) {
this.props.setStatsConfig(values);
}
} else {
this.props.setStatsConfig(values);
}
};
@@ -28,7 +32,11 @@ class StatsConfig extends Component {
} = this.props;
return (
<Card title={t('statistics_configuration')} bodyType="card-body box-body--settings">
<Card
title={t('statistics_configuration')}
bodyType="card-body box-body--settings"
id="stats-config"
>
<div className="form">
<Form
initialValues={{ interval }}

View File

@@ -357,7 +357,7 @@ export const NOT_FILTERED = 'NotFiltered';
export const STATS_INTERVALS_DAYS = [0, 1, 7, 30, 90];
export const QUERY_LOG_INTERVALS_DAYS = [1, 7, 30, 90];
export const QUERY_LOG_INTERVALS_DAYS = [0.25, 1, 7, 30, 90];
export const FILTERS_INTERVALS_HOURS = [0, 1, 12, 24, 72, 168];

View File

@@ -276,6 +276,12 @@ export const ip4ToInt = (ip) => {
*/
export const toNumber = (value) => value && parseInt(value, 10);
/**
* @param value {string}
* @returns {*|number}
*/
export const toFloatNumber = (value) => value && parseFloat(value, 10);
/**
* @param value {string}
* @returns {boolean}

View File

@@ -43,7 +43,7 @@ export const renderFormattedClientCell = (value, info, isDetailed = false, isLog
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
if (name) {
const nameValue = <div className="logs__text logs__text--nowrap" title={`${name} (${value})`}>
const nameValue = <div className="logs__text logs__text--link logs__text--nowrap" title={`${name} (${value})`}>
{name}&nbsp;<small>{`(${value})`}</small>
</div>;

8
go.mod
View File

@@ -3,15 +3,15 @@ module github.com/AdguardTeam/AdGuardHome
go 1.16
require (
github.com/AdguardTeam/dnsproxy v0.38.0
github.com/AdguardTeam/golibs v0.8.0
github.com/AdguardTeam/dnsproxy v0.39.1
github.com/AdguardTeam/golibs v0.8.4
github.com/AdguardTeam/urlfilter v0.14.6
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.1.3
github.com/ameshkov/dnscrypt/v2 v2.2.1
github.com/digineo/go-ipset/v2 v2.2.1
github.com/fsnotify/fsnotify v1.4.9
github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020
github.com/google/go-cmp v0.5.5 // indirect
github.com/google/go-cmp v0.5.5
github.com/google/renameio v1.0.1
github.com/insomniacslk/dhcp v0.0.0-20210310193751-cfd4d47082c2
github.com/kardianos/service v1.2.0

11
go.sum
View File

@@ -9,13 +9,13 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AdguardTeam/dhcp v0.0.0-20210519141215-51808c73c0bf h1:gc042VRSIRSUzZ+Px6xQCRWNJZTaPkomisDfUZmoFNk=
github.com/AdguardTeam/dhcp v0.0.0-20210519141215-51808c73c0bf/go.mod h1:TKl4jN3Voofo4UJIicyNhWGp/nlQqQkFxmwIFTvBkKI=
github.com/AdguardTeam/dnsproxy v0.38.0 h1:7GyyNJOieIVOgdnhu47exqWjHPQro7wQhqzvQjaZt6M=
github.com/AdguardTeam/dnsproxy v0.38.0/go.mod h1:xMfevPAwpK1ULoLO0CARg/OiUsPH92kfyliXhPTc62M=
github.com/AdguardTeam/dnsproxy v0.39.1 h1:qU5LgMsw6Q4qwVuZ4cpWVQqD+7k1kK2Z2NoNar60yto=
github.com/AdguardTeam/dnsproxy v0.39.1/go.mod h1:aNXKNdTyKfgAG2OS712SYSaGIM9AasZsZxfiY4YiR/0=
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.4.4/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.8.0 h1:rHo+yIgT2fivFG0yW2Cwk/DPc2+t/Aw6QvzPpiIFre0=
github.com/AdguardTeam/golibs v0.8.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.8.4 h1:jd6GwvQQtfSLOKn30qisDVujvas3q7Agjm3BOEqRWpQ=
github.com/AdguardTeam/golibs v0.8.4/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.14.6 h1:emqoKZElooHACYehRBYENeKVN1a/rspxiqTIMYLuoIo=
github.com/AdguardTeam/urlfilter v0.14.6/go.mod h1:klx4JbOfc4EaNb5lWLqOwfg+pVcyRukmoJRvO55lL5U=
@@ -29,8 +29,9 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
github.com/ameshkov/dnscrypt/v2 v2.1.3 h1:DG4Uf7LSDg6XDj9sp3maxh3Ur26jeGQaP5MeYosn6v0=
github.com/ameshkov/dnscrypt/v2 v2.1.3/go.mod h1:+8SbPbVXpxxcUsgGi8eodkqWPo1MyNHxKYC8hDpqLSo=
github.com/ameshkov/dnscrypt/v2 v2.2.1 h1:+cApRxzeBZqjUNsN26TTz7r5A8U+buON3kJgIYE3QWQ=
github.com/ameshkov/dnscrypt/v2 v2.2.1/go.mod h1:+8SbPbVXpxxcUsgGi8eodkqWPo1MyNHxKYC8hDpqLSo=
github.com/ameshkov/dnsstamps v1.0.1/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=

View File

@@ -74,6 +74,11 @@ func (m *IPMap) Range(f func(ip net.IP, v interface{}) (cont bool)) {
}
for k, v := range m.m {
// Array slicing produces a pointer, so copy the array here.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/3346
// as well as https://github.com/kyoh86/looppointer/issues/9.
k := k
if !f(net.IP(k[:]), v) {
break
}

View File

@@ -13,9 +13,9 @@ import (
"syscall"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
)
// ErrNoStaticIPInfo is returned by IfaceHasStaticIP when no information about
@@ -371,14 +371,14 @@ func ReverseAddr(ip net.IP) (arpa string) {
strLen, suffix = arpaV4MaxLen, arpaV4Suffix[1:]
ip = ip4
writeByte = func(val byte) {
aghstrings.WriteToBuilder(b, strconv.Itoa(int(val)), dot)
stringutil.WriteToBuilder(b, strconv.Itoa(int(val)), dot)
}
} else if ip6 := ip.To16(); ip6 != nil {
strLen, suffix = arpaV6MaxLen, arpaV6Suffix[1:]
ip = ip6
writeByte = func(val byte) {
aghstrings.WriteToBuilder(
stringutil.WriteToBuilder(
b,
strconv.FormatUint(uint64(val&0xF), 16),
dot,
@@ -395,7 +395,7 @@ func ReverseAddr(ip net.IP) (arpa string) {
for i := len(ip) - 1; i >= 0; i-- {
writeByte(ip[i])
}
aghstrings.WriteToBuilder(b, suffix)
stringutil.WriteToBuilder(b, suffix)
return b.String()
}

View File

@@ -0,0 +1,78 @@
//go:build freebsd
// +build freebsd
package aghnet
import (
"bufio"
"fmt"
"io"
"net"
"os"
"strings"
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/golibs/errors"
)
func canBindPrivilegedPorts() (can bool, err error) {
return aghos.HaveAdminRights()
}
// maxCheckedFileSize is the maximum acceptable length of the /etc/rc.conf file.
const maxCheckedFileSize = 1024 * 1024
func ifaceHasStaticIP(ifaceName string) (ok bool, err error) {
const filename = "/etc/rc.conf"
var f *os.File
f, err = os.Open(filename)
if err != nil {
return false, err
}
defer func() { err = errors.WithDeferred(err, f.Close()) }()
var r io.Reader
r, err = aghio.LimitReader(f, maxCheckedFileSize)
if err != nil {
return false, err
}
return rcConfStaticConfig(r, ifaceName)
}
// rcConfStaticConfig checks if the interface is configured by /etc/rc.conf to
// have a static IP.
func rcConfStaticConfig(r io.Reader, ifaceName string) (has bool, err error) {
s := bufio.NewScanner(r)
for ifaceLinePref := fmt.Sprintf("ifconfig_%s", ifaceName); s.Scan(); {
line := strings.TrimSpace(s.Text())
if !strings.HasPrefix(line, ifaceLinePref) {
continue
}
eqIdx := len(ifaceLinePref)
if line[eqIdx] != '=' {
continue
}
fieldsStart, fieldsEnd := eqIdx+2, len(line)-1
if fieldsStart >= fieldsEnd {
continue
}
fields := strings.Fields(line[fieldsStart:fieldsEnd])
if len(fields) >= 2 &&
strings.ToLower(fields[0]) == "inet" &&
net.ParseIP(fields[1]) != nil {
return true, s.Err()
}
}
return false, s.Err()
}
func ifaceSetStaticIP(string) (err error) {
return aghos.Unsupported("setting static ip")
}

View File

@@ -0,0 +1,60 @@
//go:build freebsd
// +build freebsd
package aghnet
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRcConfStaticConfig(t *testing.T) {
const ifaceName = `em0`
const nl = "\n"
testCases := []struct {
name string
rcconfData string
wantHas bool
}{{
name: "simple",
rcconfData: `ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
wantHas: true,
}, {
name: "case_insensitiveness",
rcconfData: `ifconfig_em0="InEt 127.0.0.253 NeTmAsK 0xffffffff"` + nl,
wantHas: true,
}, {
name: "comments_and_trash",
rcconfData: `# comment 1` + nl +
`` + nl +
`# comment 2` + nl +
`ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
wantHas: true,
}, {
name: "aliases",
rcconfData: `ifconfig_em0_alias="inet 127.0.0.1/24"` + nl +
`ifconfig_em0="inet 127.0.0.253 netmask 0xffffffff"` + nl,
wantHas: true,
}, {
name: "incorrect_config",
rcconfData: `ifconfig_em0="inet6 127.0.0.253 netmask 0xffffffff"` + nl +
`ifconfig_em0="inet 127.0.0.253 net-mask 0xffffffff"` + nl +
`ifconfig_em0="inet 256.256.256.256 netmask 0xffffffff"` + nl +
`ifconfig_em0=""` + nl,
wantHas: false,
}}
for _, tc := range testCases {
r := strings.NewReader(tc.rcconfData)
t.Run(tc.name, func(t *testing.T) {
has, err := rcConfStaticConfig(r, ifaceName)
require.NoError(t, err)
assert.Equal(t, tc.wantHas, has)
})
}
}

View File

@@ -14,8 +14,8 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/google/renameio/maybe"
"golang.org/x/sys/unix"
)
@@ -70,7 +70,7 @@ func (rc *recurrentChecker) checkFile(sourcePath, desired string) (
}
// handlePatterns parses the patterns and takes care of duplicates.
func (rc *recurrentChecker) handlePatterns(sourcesSet *aghstrings.Set, patterns []string) (
func (rc *recurrentChecker) handlePatterns(sourcesSet *stringutil.Set, patterns []string) (
subsources []string,
err error,
) {
@@ -111,7 +111,7 @@ func (rc *recurrentChecker) check(desired string) (has bool, err error) {
var patterns, subsources []string
// The slice of sources is separate from the set of sources to keep the
// order in which the files are walked.
for sourcesSet := aghstrings.NewSet(rc.initPath); i < len(sources); i++ {
for sourcesSet := stringutil.NewSet(rc.initPath); i < len(sources); i++ {
patterns, has, err = rc.checkFile(sources[i], desired)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
@@ -217,7 +217,7 @@ func ifacesStaticConfig(r io.Reader, ifaceName string) (subsources []string, has
s := bufio.NewScanner(r)
for s.Scan() {
line := strings.TrimSpace(s.Text())
if aghstrings.IsCommentOrEmpty(line) {
if len(line) == 0 || line[0] == '#' {
continue
}

View File

@@ -1,12 +1,9 @@
//go:build !(linux || darwin)
// +build !linux,!darwin
//go:build !(linux || darwin || freebsd)
// +build !linux,!darwin,!freebsd
package aghnet
import (
"fmt"
"runtime"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
)
@@ -14,10 +11,10 @@ func canBindPrivilegedPorts() (can bool, err error) {
return aghos.HaveAdminRights()
}
func ifaceHasStaticIP(string) (bool, error) {
return false, fmt.Errorf("cannot check if IP is static: not supported on %s", runtime.GOOS)
func ifaceHasStaticIP(string) (ok bool, err error) {
return false, aghos.Unsupported("checking static ip")
}
func ifaceSetStaticIP(string) error {
return fmt.Errorf("cannot set static IP on %s", runtime.GOOS)
func ifaceSetStaticIP(string) (err error) {
return aghos.Unsupported("setting static ip")
}

View File

@@ -11,8 +11,8 @@ import (
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/stringutil"
)
// defaultHostGen is the default method of generating host for Refresh.
@@ -27,7 +27,7 @@ type systemResolvers struct {
hostGenFunc HostGenFunc
// addrs is the set that contains cached local resolvers' addresses.
addrs *aghstrings.Set
addrs *stringutil.Set
addrsLock sync.RWMutex
}
@@ -64,7 +64,7 @@ func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr S
PreferGo: true,
},
hostGenFunc: hostGenFunc,
addrs: aghstrings.NewSet(),
addrs: stringutil.NewSet(),
}
s.resolver.Dial = s.dialFunc

View File

@@ -1,71 +0,0 @@
package aghstrings
// unit is a convenient alias for struct{}
type unit = struct{}
// Set is a set of strings.
type Set struct {
m map[string]unit
}
// NewSet returns a new string set containing strs.
func NewSet(strs ...string) (set *Set) {
set = &Set{
m: make(map[string]unit, len(strs)),
}
for _, s := range strs {
set.Add(s)
}
return set
}
// Add adds s to the set. Add panics if the set is a nil set, just like a nil
// map does.
func (set *Set) Add(s string) {
set.m[s] = unit{}
}
// Del deletes s from the set. Calling Del on a nil set has no effect, just
// like delete on an empty map doesn't.
func (set *Set) Del(s string) {
if set != nil {
delete(set.m, s)
}
}
// Has returns true if s is in the set. Calling Has on a nil set returns false,
// just like indexing on an empty map does.
func (set *Set) Has(s string) (ok bool) {
if set != nil {
_, ok = set.m[s]
}
return ok
}
// Len returns the length of the set. A nil set has a length of zero, just like
// an empty map.
func (set *Set) Len() (n int) {
if set == nil {
return 0
}
return len(set.m)
}
// Values returns all values in the set. The order of the values is undefined.
// Values returns nil if the set is nil.
func (set *Set) Values() (strs []string) {
if set == nil {
return nil
}
strs = make([]string, 0, len(set.m))
for s := range set.m {
strs = append(strs, s)
}
return strs
}

View File

@@ -1,56 +0,0 @@
package aghstrings
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSet(t *testing.T) {
const s = "a"
t.Run("nil", func(t *testing.T) {
var set *Set
assert.NotPanics(t, func() {
set.Del(s)
})
assert.NotPanics(t, func() {
assert.False(t, set.Has(s))
})
assert.NotPanics(t, func() {
assert.Equal(t, 0, set.Len())
})
assert.NotPanics(t, func() {
assert.Nil(t, set.Values())
})
assert.Panics(t, func() {
set.Add(s)
})
})
t.Run("non_nil", func(t *testing.T) {
set := NewSet()
assert.Equal(t, 0, set.Len())
ok := set.Has(s)
assert.False(t, ok)
set.Add(s)
ok = set.Has(s)
assert.True(t, ok)
assert.Equal(t, []string{s}, set.Values())
set.Del(s)
ok = set.Has(s)
assert.False(t, ok)
set = NewSet(s)
assert.Equal(t, 1, set.Len())
})
}

View File

@@ -1,103 +0,0 @@
// Package aghstrings contains utilities dealing with strings.
package aghstrings
import (
"strings"
)
// CloneSliceOrEmpty returns the copy of a or empty strings slice if a is nil.
func CloneSliceOrEmpty(a []string) (b []string) {
return append([]string{}, a...)
}
// CloneSlice returns the exact copy of a.
func CloneSlice(a []string) (b []string) {
if a == nil {
return nil
}
return CloneSliceOrEmpty(a)
}
// Coalesce returns the first non-empty string. It is named after the function
// COALESCE in SQL except that since strings in Go are non-nullable, it uses an
// empty string as a NULL value. If strs or all it's elements are empty, it
// returns an empty string.
func Coalesce(strs ...string) (res string) {
for _, s := range strs {
if s != "" {
return s
}
}
return ""
}
// FilterOut returns a copy of strs with all strings for which f returned true
// removed.
func FilterOut(strs []string, f func(s string) (ok bool)) (filtered []string) {
for _, s := range strs {
if !f(s) {
filtered = append(filtered, s)
}
}
return filtered
}
// InSlice checks if string is in the slice of strings.
func InSlice(strs []string, str string) (ok bool) {
for _, s := range strs {
if s == str {
return true
}
}
return false
}
// IsCommentOrEmpty returns true of the string starts with a "#" character or is
// an empty string.
func IsCommentOrEmpty(s string) (ok bool) {
return len(s) == 0 || s[0] == '#'
}
// SplitNext splits string by a byte and returns the first chunk skipping empty
// ones. Whitespaces are trimmed.
func SplitNext(s *string, sep rune) (chunk string) {
if s == nil {
return chunk
}
i := strings.IndexByte(*s, byte(sep))
if i == -1 {
chunk = *s
*s = ""
return strings.TrimSpace(chunk)
}
chunk = (*s)[:i]
*s = (*s)[i+1:]
var j int
var r rune
for j, r = range *s {
if r != sep {
break
}
}
*s = (*s)[j:]
return strings.TrimSpace(chunk)
}
// WriteToBuilder is a convenient wrapper for strings.(*Builder).WriteString
// that deals with multiple strings and ignores errors that are guaranteed to be
// nil.
func WriteToBuilder(b *strings.Builder, strs ...string) {
// TODO(e.burkov): Recover from panic?
for _, s := range strs {
_, _ = b.WriteString(s)
}
}

View File

@@ -1,137 +0,0 @@
package aghstrings
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCloneSlice_family(t *testing.T) {
a := []string{"1", "2", "3"}
t.Run("cloneslice_simple", func(t *testing.T) {
assert.Equal(t, a, CloneSlice(a))
})
t.Run("cloneslice_nil", func(t *testing.T) {
assert.Nil(t, CloneSlice(nil))
})
t.Run("cloneslice_empty", func(t *testing.T) {
assert.Equal(t, []string{}, CloneSlice([]string{}))
})
t.Run("clonesliceorempty_nil", func(t *testing.T) {
assert.Equal(t, []string{}, CloneSliceOrEmpty(nil))
})
t.Run("clonesliceorempty_empty", func(t *testing.T) {
assert.Equal(t, []string{}, CloneSliceOrEmpty([]string{}))
})
t.Run("clonesliceorempty_sameness", func(t *testing.T) {
assert.Equal(t, CloneSlice(a), CloneSliceOrEmpty(a))
})
}
func TestCoalesce(t *testing.T) {
assert.Equal(t, "", Coalesce())
assert.Equal(t, "a", Coalesce("a"))
assert.Equal(t, "a", Coalesce("", "a"))
assert.Equal(t, "a", Coalesce("a", ""))
assert.Equal(t, "a", Coalesce("a", "b"))
}
func TestFilterOut(t *testing.T) {
strs := []string{
"1.2.3.4",
"",
"# 5.6.7.8",
}
want := []string{
"1.2.3.4",
}
got := FilterOut(strs, IsCommentOrEmpty)
assert.Equal(t, want, got)
}
func TestInSlice(t *testing.T) {
simpleStrs := []string{"1", "2", "3"}
testCases := []struct {
name string
str string
strs []string
want bool
}{{
name: "yes",
str: "2",
strs: simpleStrs,
want: true,
}, {
name: "no",
str: "4",
strs: simpleStrs,
want: false,
}, {
name: "nil",
str: "any",
strs: nil,
want: false,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.want, InSlice(tc.strs, tc.str))
})
}
}
func TestSplitNext(t *testing.T) {
t.Run("ordinary", func(t *testing.T) {
s := " a,b , c "
require.Equal(t, "a", SplitNext(&s, ','))
require.Equal(t, "b", SplitNext(&s, ','))
require.Equal(t, "c", SplitNext(&s, ','))
assert.Empty(t, s)
})
t.Run("nil_source", func(t *testing.T) {
assert.Equal(t, "", SplitNext(nil, 's'))
})
}
func TestWriteToBuilder(t *testing.T) {
b := &strings.Builder{}
t.Run("single", func(t *testing.T) {
assert.NotPanics(t, func() { WriteToBuilder(b, t.Name()) })
assert.Equal(t, t.Name(), b.String())
})
b.Reset()
t.Run("several", func(t *testing.T) {
const (
_1 = "one"
_2 = "two"
_123 = _1 + _2
)
assert.NotPanics(t, func() { WriteToBuilder(b, _1, _2) })
assert.Equal(t, _123, b.String())
})
b.Reset()
t.Run("nothing", func(t *testing.T) {
assert.NotPanics(t, func() { WriteToBuilder(b) })
assert.Equal(t, "", b.String())
})
t.Run("nil_builder", func(t *testing.T) {
assert.Panics(t, func() { WriteToBuilder(nil, "a") })
})
}

View File

@@ -412,7 +412,9 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
result := dhcpSearchResult{
V4: dhcpSearchV4Result{
OtherServer: dhcpSearchOtherResult{},
StaticIP: dhcpStaticIPStatus{},
StaticIP: dhcpStaticIPStatus{
Static: "yes",
},
},
V6: dhcpSearchV6Result{
OtherServer: dhcpSearchOtherResult{},

View File

@@ -38,6 +38,9 @@ type V4ServerConf struct {
GatewayIP net.IP `yaml:"gateway_ip" json:"gateway_ip"`
SubnetMask net.IP `yaml:"subnet_mask" json:"subnet_mask"`
// broadcastIP is the broadcasting address pre-calculated from the
// configured gateway IP and subnet mask.
broadcastIP net.IP
// The first & the last IP address for dynamic leases
// Bytes [0..2] of the last allowed IP address must match the first IP

View File

@@ -12,9 +12,9 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/go-ping/ping"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv4/server4"
@@ -32,7 +32,7 @@ type v4Server struct {
leasedOffsets *bitSet
// leaseHosts is the set of all hostnames of all known DHCP clients.
leaseHosts *aghstrings.Set
leaseHosts *stringutil.Set
// leases contains all dynamic and static leases.
leases []*Lease
@@ -105,7 +105,7 @@ func (s *v4Server) ResetLeases(leases []*Lease) (err error) {
}
s.leasedOffsets = newBitSet()
s.leaseHosts = aghstrings.NewSet()
s.leaseHosts = stringutil.NewSet()
s.leases = nil
for _, l := range leases {
@@ -927,12 +927,30 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4
resp.Options.Update(dhcpv4.OptMessageType(dhcpv4.MessageTypeNak))
}
// peer is expected to be of type *net.UDPConn as the server4.NewServer
// initializes it.
udpPeer, ok := peer.(*net.UDPAddr)
if !ok {
log.Error("dhcpv4: peer is of unexpected type %T", peer)
return
}
// Despite the fact that server4.NewIPv4UDPConn explicitly sets socket
// options to allow broadcasting, it also binds the connection to a
// specific interface. On FreeBSD conn.WriteTo causes errors while
// writing to the addresses that belong to another interface. So, use
// the broadcast address specific for the binded interface in case
// server4.Server.Serve sets it to net.IPv4Bcast.
if udpPeer.IP.Equal(net.IPv4bcast) {
udpPeer.IP = s.conf.broadcastIP
}
log.Debug("dhcpv4: sending: %s", resp.Summary())
_, err = conn.WriteTo(resp.ToBytes(), peer)
if err != nil {
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
return
}
}
@@ -1017,7 +1035,7 @@ func (s *v4Server) Stop() (err error) {
func v4Create(conf V4ServerConf) (srv DHCPServer, err error) {
s := &v4Server{}
s.conf = conf
s.leaseHosts = aghstrings.NewSet()
s.leaseHosts = stringutil.NewSet()
// TODO(a.garipov): Don't use a disabled server in other places or just
// use an interface.
@@ -1043,6 +1061,12 @@ func v4Create(conf V4ServerConf) (srv DHCPServer, err error) {
Mask: subnetMask,
}
bcastIP := aghnet.CloneIP(routerIP)
for i, b := range subnetMask {
bcastIP[i] |= ^b
}
s.conf.broadcastIP = bcastIP
s.conf.ipRange, err = newIPRange(conf.RangeStart, conf.RangeEnd)
if err != nil {
return s, fmt.Errorf("dhcpv4: %w", err)

View File

@@ -8,8 +8,8 @@ import (
"strings"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/AdguardTeam/urlfilter"
"github.com/AdguardTeam/urlfilter/filterlist"
)
@@ -20,8 +20,8 @@ type accessCtx struct {
allowedIPs *aghnet.IPMap
blockedIPs *aghnet.IPMap
allowedClientIDs *aghstrings.Set
blockedClientIDs *aghstrings.Set
allowedClientIDs *stringutil.Set
blockedClientIDs *stringutil.Set
blockedHostsEng *urlfilter.DNSEngine
@@ -40,7 +40,7 @@ func processAccessClients(
clientStrs []string,
ips *aghnet.IPMap,
nets *[]*net.IPNet,
clientIDs *aghstrings.Set,
clientIDs *stringutil.Set,
) (err error) {
for i, s := range clientStrs {
if ip := net.ParseIP(s); ip != nil {
@@ -71,8 +71,8 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessCtx, err er
allowedIPs: aghnet.NewIPMap(0),
blockedIPs: aghnet.NewIPMap(0),
allowedClientIDs: aghstrings.NewSet(),
blockedClientIDs: aghstrings.NewSet(),
allowedClientIDs: stringutil.NewSet(),
blockedClientIDs: stringutil.NewSet(),
}
err = processAccessClients(allowed, a.allowedIPs, &a.allowedNets, a.allowedClientIDs)
@@ -87,7 +87,7 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessCtx, err er
b := &strings.Builder{}
for _, h := range blockedHosts {
aghstrings.WriteToBuilder(b, strings.ToLower(h), "\n")
stringutil.WriteToBuilder(b, strings.ToLower(h), "\n")
}
lists := []filterlist.RuleList{
@@ -174,9 +174,9 @@ func (s *Server) accessListJSON() (j accessListJSON) {
defer s.serverLock.RUnlock()
return accessListJSON{
AllowedClients: aghstrings.CloneSlice(s.conf.AllowedClients),
DisallowedClients: aghstrings.CloneSlice(s.conf.DisallowedClients),
BlockedHosts: aghstrings.CloneSlice(s.conf.BlockedHosts),
AllowedClients: stringutil.CloneSlice(s.conf.AllowedClients),
DisallowedClients: stringutil.CloneSlice(s.conf.DisallowedClients),
BlockedHosts: stringutil.CloneSlice(s.conf.BlockedHosts),
}
}

View File

@@ -12,12 +12,12 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/ameshkov/dnscrypt/v2"
)
@@ -94,6 +94,11 @@ type FilteringConfig struct {
AllowedClients []string `yaml:"allowed_clients"` // IP addresses of whitelist clients
DisallowedClients []string `yaml:"disallowed_clients"` // IP addresses of clients that should be blocked
BlockedHosts []string `yaml:"blocked_hosts"` // hosts that should be blocked
// TrustedProxies is the list of IP addresses and CIDR networks to
// detect proxy servers addresses the DoH requests from which should be
// handled. The value of nil or an empty slice for this field makes
// Proxy not trust any address.
TrustedProxies []string `yaml:"trusted_proxies"`
// DNS cache settings
// --
@@ -101,6 +106,8 @@ type FilteringConfig struct {
CacheSize uint32 `yaml:"cache_size"` // DNS cache size (in bytes)
CacheMinTTL uint32 `yaml:"cache_ttl_min"` // override TTL value (minimum) received from upstream server
CacheMaxTTL uint32 `yaml:"cache_ttl_max"` // override TTL value (maximum) received from upstream server
// CacheOptimistic defines if optimistic cache mechanism should be used.
CacheOptimistic bool `yaml:"cache_optimistic"`
// Other settings
// --
@@ -208,8 +215,10 @@ func (s *Server) createProxyConfig() (proxy.Config, error) {
Ratelimit: int(s.conf.Ratelimit),
RatelimitWhitelist: s.conf.RatelimitWhitelist,
RefuseAny: s.conf.RefuseAny,
TrustedProxies: s.conf.TrustedProxies,
CacheMinTTL: s.conf.CacheMinTTL,
CacheMaxTTL: s.conf.CacheMaxTTL,
CacheOptimistic: s.conf.CacheOptimistic,
UpstreamConfig: s.conf.UpstreamConfig,
BeforeRequestHandler: s.beforeRequestHandler,
RequestHandler: s.handleDNSRequest,
@@ -318,17 +327,15 @@ func (s *Server) prepareUpstreamSettings() error {
if err != nil {
return err
}
d := string(data)
for len(d) != 0 {
s := aghstrings.SplitNext(&d, '\n')
upstreams = append(upstreams, s)
}
upstreams = stringutil.SplitTrimmed(string(data), "\n")
log.Debug("dns: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName)
} else {
upstreams = s.conf.UpstreamDNS
}
upstreams = aghstrings.FilterOut(upstreams, aghstrings.IsCommentOrEmpty)
upstreams = stringutil.FilterOut(upstreams, IsCommentOrEmpty)
upstreamConfig, err := proxy.ParseUpstreamsConfig(
upstreams,
&upstream.Options{

View File

@@ -6,11 +6,11 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/miekg/dns"
)
@@ -379,15 +379,17 @@ func (s *Server) ipToHost(ip net.IP) (host string, ok bool) {
var v interface{}
v, ok = s.tableIPToHost.Get(ip)
if !ok {
return "", false
}
var typOK bool
if host, typOK = v.(string); !typOK {
if host, ok = v.(string); !ok {
log.Error("dns: bad type %T in tableIPToHost for %s", v, ip)
return "", false
}
return host, ok
return host, true
}
// Respond to PTR requests if the target IP is leased by our DHCP server and the
@@ -516,7 +518,7 @@ func (s *Server) processUpstream(ctx *dnsContext) (rc resultCode) {
if d.Addr != nil && s.conf.GetCustomUpstreamByClient != nil {
// Use the clientID first, since it has a higher priority.
id := aghstrings.Coalesce(ctx.clientID, ipStringFromAddr(d.Addr))
id := stringutil.Coalesce(ctx.clientID, ipStringFromAddr(d.Addr))
upsConf, err := s.conf.GetCustomUpstreamByClient(id)
if err != nil {
log.Error("dns: getting custom upstreams for client %s: %s", id, err)

View File

@@ -11,7 +11,6 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
@@ -21,6 +20,7 @@ import (
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/miekg/dns"
)
@@ -222,12 +222,13 @@ func (s *Server) WriteDiskConfig(c *FilteringConfig) {
sc := s.conf.FilteringConfig
*c = sc
c.RatelimitWhitelist = aghstrings.CloneSlice(sc.RatelimitWhitelist)
c.BootstrapDNS = aghstrings.CloneSlice(sc.BootstrapDNS)
c.AllowedClients = aghstrings.CloneSlice(sc.AllowedClients)
c.DisallowedClients = aghstrings.CloneSlice(sc.DisallowedClients)
c.BlockedHosts = aghstrings.CloneSlice(sc.BlockedHosts)
c.UpstreamDNS = aghstrings.CloneSlice(sc.UpstreamDNS)
c.RatelimitWhitelist = stringutil.CloneSlice(sc.RatelimitWhitelist)
c.BootstrapDNS = stringutil.CloneSlice(sc.BootstrapDNS)
c.AllowedClients = stringutil.CloneSlice(sc.AllowedClients)
c.DisallowedClients = stringutil.CloneSlice(sc.DisallowedClients)
c.BlockedHosts = stringutil.CloneSlice(sc.BlockedHosts)
c.TrustedProxies = stringutil.CloneSlice(sc.TrustedProxies)
c.UpstreamDNS = stringutil.CloneSlice(sc.UpstreamDNS)
}
// RDNSSettings returns the copy of actual RDNS configuration.
@@ -235,7 +236,7 @@ func (s *Server) RDNSSettings() (localPTRResolvers []string, resolveClients, res
s.serverLock.RLock()
defer s.serverLock.RUnlock()
return aghstrings.CloneSlice(s.conf.LocalPTRResolvers),
return stringutil.CloneSlice(s.conf.LocalPTRResolvers),
s.conf.ResolveClients,
s.conf.UsePrivateRDNS
}
@@ -397,13 +398,13 @@ func (s *Server) filterOurDNSAddrs(addrs []string) (filtered []string, err error
return nil, err
}
ourAddrsSet := aghstrings.NewSet(ourAddrs...)
ourAddrsSet := stringutil.NewSet(ourAddrs...)
// TODO(e.burkov): The approach of subtracting sets of strings is not
// really applicable here since in case of listening on all network
// interfaces we should check the whole interface's network to cut off
// all the loopback addresses as well.
return aghstrings.FilterOut(addrs, ourAddrsSet.Has), nil
return stringutil.FilterOut(addrs, ourAddrsSet.Has), nil
}
// setupResolvers initializes the resolvers for local addresses. For internal

View File

@@ -58,7 +58,7 @@ func createTestServer(
t.Helper()
rules := `||nxdomain.example.org
||null.example.org^
||NULL.example.org^
127.0.0.1 host.example.org
@@||whitelist.example.org^
||127.0.0.255`
@@ -581,13 +581,13 @@ func TestServerCustomClientUpstream(t *testing.T) {
// testCNAMEs is a map of names and CNAMEs necessary for the TestUpstream work.
var testCNAMEs = map[string]string{
"badhost.": "null.example.org.",
"whitelist.example.org.": "null.example.org.",
"badhost.": "NULL.example.org.",
"whitelist.example.org.": "NULL.example.org.",
}
// testIPv4 is a map of names and IPv4s necessary for the TestUpstream work.
var testIPv4 = map[string][]net.IP{
"null.example.org.": {{1, 2, 3, 4}},
"NULL.example.org.": {{1, 2, 3, 4}},
"example.org.": {{127, 0, 0, 255}},
}
@@ -609,7 +609,7 @@ func TestBlockCNAMEProtectionEnabled(t *testing.T) {
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
// 'badhost' has a canonical name 'null.example.org' which should be
// 'badhost' has a canonical name 'NULL.example.org' which should be
// blocked by filters, but protection is disabled so it is not.
req := createTestMessage("badhost.")
@@ -644,13 +644,13 @@ func TestBlockCNAME(t *testing.T) {
want bool
}{{
host: "badhost.",
// 'badhost' has a canonical name 'null.example.org' which is
// 'badhost' has a canonical name 'NULL.example.org' which is
// blocked by filters: response is blocked.
want: true,
}, {
host: "whitelist.example.org.",
// 'whitelist.example.org' has a canonical name
// 'null.example.org' which is blocked by filters
// 'NULL.example.org' which is blocked by filters
// but 'whitelist.example.org' is in a whitelist:
// response isn't blocked.
want: false,
@@ -671,8 +671,11 @@ func TestBlockCNAME(t *testing.T) {
assert.Equal(t, dns.RcodeSuccess, reply.Rcode)
if tc.want {
require.Len(t, reply.Answer, 1)
a, ok := reply.Answer[0].(*dns.A)
require.True(t, ok)
ans := reply.Answer[0]
a, ok := ans.(*dns.A)
require.Truef(t, ok, "got %T", ans)
assert.True(t, a.A.IsUnspecified())
}
})
@@ -701,7 +704,7 @@ func TestClientRulesForCNAMEMatching(t *testing.T) {
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
// 'badhost' has a canonical name 'null.example.org' which is blocked by
// 'badhost' has a canonical name 'NULL.example.org' which is blocked by
// filters: response is blocked.
req := dns.Msg{
MsgHdr: dns.MsgHdr{
@@ -742,7 +745,7 @@ func TestNullBlockedRequest(t *testing.T) {
RecursionDesired: true,
},
Question: []dns.Question{{
Name: "null.example.org.",
Name: "NULL.example.org.",
Qtype: dns.TypeA,
Qclass: dns.ClassINET,
}},
@@ -757,7 +760,7 @@ func TestNullBlockedRequest(t *testing.T) {
}
func TestBlockedCustomIP(t *testing.T) {
rules := "||nxdomain.example.org^\n||null.example.org^\n127.0.0.1 host.example.org\n@@||whitelist.example.org^\n||127.0.0.255\n"
rules := "||nxdomain.example.org^\n||NULL.example.org^\n127.0.0.1 host.example.org\n@@||whitelist.example.org^\n||127.0.0.255\n"
filters := []filtering.Filter{{
ID: 0,
Data: []byte(rules),
@@ -802,7 +805,7 @@ func TestBlockedCustomIP(t *testing.T) {
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
req := createTestMessageWithType("null.example.org.", dns.TypeA)
req := createTestMessageWithType("NULL.example.org.", dns.TypeA)
reply, err := dns.Exchange(req, addr.String())
require.NoError(t, err)
@@ -813,7 +816,7 @@ func TestBlockedCustomIP(t *testing.T) {
assert.True(t, net.IP{0, 0, 0, 1}.Equal(a.A))
req = createTestMessageWithType("null.example.org.", dns.TypeAAAA)
req = createTestMessageWithType("NULL.example.org.", dns.TypeAAAA)
reply, err = dns.Exchange(req, addr.String())
require.NoError(t, err)

View File

@@ -27,7 +27,7 @@ func (s *Server) beforeRequestHandler(
blocked, _ := s.IsBlockedClient(ip, clientID)
if blocked {
return false, nil
return s.preBlockedResponse(pctx)
}
if len(pctx.Req.Question) == 1 {
@@ -35,7 +35,7 @@ func (s *Server) beforeRequestHandler(
if s.access.isBlockedHost(host) {
log.Debug("host %s is in access blocklist", host)
return false, nil
return s.preBlockedResponse(pctx)
}
}

View File

@@ -10,11 +10,11 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/miekg/dns"
)
@@ -41,6 +41,7 @@ type dnsConfig struct {
CacheSize *uint32 `json:"cache_size"`
CacheMinTTL *uint32 `json:"cache_ttl_min"`
CacheMaxTTL *uint32 `json:"cache_ttl_max"`
CacheOptimistic *bool `json:"cache_optimistic"`
ResolveClients *bool `json:"resolve_clients"`
UsePrivateRDNS *bool `json:"use_private_ptr_resolvers"`
LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"`
@@ -50,9 +51,9 @@ func (s *Server) getDNSConfig() dnsConfig {
s.serverLock.RLock()
defer s.serverLock.RUnlock()
upstreams := aghstrings.CloneSliceOrEmpty(s.conf.UpstreamDNS)
upstreams := stringutil.CloneSliceOrEmpty(s.conf.UpstreamDNS)
upstreamFile := s.conf.UpstreamDNSFileName
bootstraps := aghstrings.CloneSliceOrEmpty(s.conf.BootstrapDNS)
bootstraps := stringutil.CloneSliceOrEmpty(s.conf.BootstrapDNS)
protectionEnabled := s.conf.ProtectionEnabled
blockingMode := s.conf.BlockingMode
blockingIPv4 := s.conf.BlockingIPv4
@@ -64,9 +65,10 @@ func (s *Server) getDNSConfig() dnsConfig {
cacheSize := s.conf.CacheSize
cacheMinTTL := s.conf.CacheMinTTL
cacheMaxTTL := s.conf.CacheMaxTTL
cacheOptimistic := s.conf.CacheOptimistic
resolveClients := s.conf.ResolveClients
usePrivateRDNS := s.conf.UsePrivateRDNS
localPTRUpstreams := aghstrings.CloneSliceOrEmpty(s.conf.LocalPTRResolvers)
localPTRUpstreams := stringutil.CloneSliceOrEmpty(s.conf.LocalPTRResolvers)
var upstreamMode string
if s.conf.FastestAddr {
upstreamMode = "fastest_addr"
@@ -89,6 +91,7 @@ func (s *Server) getDNSConfig() dnsConfig {
CacheSize: &cacheSize,
CacheMinTTL: &cacheMinTTL,
CacheMaxTTL: &cacheMaxTTL,
CacheOptimistic: &cacheOptimistic,
UpstreamMode: &upstreamMode,
ResolveClients: &resolveClients,
UsePrivateRDNS: &usePrivateRDNS,
@@ -283,6 +286,11 @@ func (s *Server) setConfigRestartable(dc dnsConfig) (restart bool) {
restart = true
}
if dc.CacheOptimistic != nil {
s.conf.CacheOptimistic = *dc.CacheOptimistic
restart = true
}
return restart
}
@@ -333,13 +341,20 @@ type upstreamJSON struct {
PrivateUpstreams []string `json:"private_upstream"`
}
// IsCommentOrEmpty returns true of the string starts with a "#" character or is
// an empty string. This function is useful for filtering out non-upstream
// lines from upstream configs.
func IsCommentOrEmpty(s string) (ok bool) {
return len(s) == 0 || s[0] == '#'
}
// ValidateUpstreams validates each upstream and returns an error if any
// upstream is invalid or if there are no default upstreams specified.
//
// TODO(e.burkov): Move into aghnet or even into dnsproxy.
func ValidateUpstreams(upstreams []string) (err error) {
// No need to validate comments
upstreams = aghstrings.FilterOut(upstreams, aghstrings.IsCommentOrEmpty)
upstreams = stringutil.FilterOut(upstreams, IsCommentOrEmpty)
// Consider this case valid because defaultDNS will be used
if len(upstreams) == 0 {
@@ -521,7 +536,7 @@ func checkPrivateUpstreamExc(u upstream.Upstream) (err error) {
}
func checkDNS(input string, bootstrap []string, timeout time.Duration, ef excFunc) (err error) {
if aghstrings.IsCommentOrEmpty(input) {
if IsCommentOrEmpty(input) {
return nil
}

View File

@@ -48,7 +48,7 @@ func loadTestData(t *testing.T, casesFileName string, cases interface{}) {
const jsonExt = ".json"
func TestDNSForwardHTTTP_handleGetConfig(t *testing.T) {
func TestDNSForwardHTTP_handleGetConfig(t *testing.T) {
filterConf := &filtering.Config{
SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000,
@@ -123,7 +123,7 @@ func TestDNSForwardHTTTP_handleGetConfig(t *testing.T) {
}
}
func TestDNSForwardHTTTP_handleSetConfig(t *testing.T) {
func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
filterConf := &filtering.Config{
SafeBrowsingEnabled: true,
SafeBrowsingCacheSize: 1000,
@@ -241,6 +241,12 @@ func TestDNSForwardHTTTP_handleSetConfig(t *testing.T) {
}
}
func TestIsCommentOrEmpty(t *testing.T) {
assert.True(t, IsCommentOrEmpty(""))
assert.True(t, IsCommentOrEmpty("# comment"))
assert.False(t, IsCommentOrEmpty("1.2.3.4"))
}
// TODO(a.garipov): Rewrite to check the actual error messages.
func TestValidateUpstream(t *testing.T) {
testCases := []struct {

View File

@@ -266,6 +266,20 @@ func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSCo
return resp
}
// preBlockedResponse returns a protocol-appropriate response for a request that
// was blocked by access settings.
func (s *Server) preBlockedResponse(pctx *proxy.DNSContext) (reply bool, err error) {
if pctx.Proto == proxy.ProtoUDP || pctx.Proto == proxy.ProtoDNSCrypt {
// Return nil so that dnsproxy drops the connection and thus
// prevent DNS amplification attacks.
return false, nil
}
pctx.Res = s.makeResponseREFUSED(pctx.Req)
return true, nil
}
// Create REFUSED DNS response
func (s *Server) makeResponseREFUSED(request *dns.Msg) *dns.Msg {
resp := dns.Msg{}

View File

@@ -23,6 +23,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -51,6 +52,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -79,6 +81,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []

View File

@@ -30,6 +30,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -62,6 +63,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -95,6 +97,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -128,6 +131,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -161,6 +165,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -194,6 +199,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -227,6 +233,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -260,6 +267,7 @@
"cache_size": 1024,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -293,6 +301,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -326,6 +335,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -361,6 +371,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -396,6 +407,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -430,6 +442,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -463,6 +476,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []
@@ -498,6 +512,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": [
@@ -533,6 +548,7 @@
"cache_size": 0,
"cache_ttl_min": 0,
"cache_ttl_max": 0,
"cache_optimistic": false,
"resolve_clients": false,
"use_private_ptr_resolvers": false,
"local_ptr_upstreams": []

View File

@@ -14,10 +14,10 @@ import (
"sync/atomic"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/AdguardTeam/urlfilter"
"github.com/AdguardTeam/urlfilter/filterlist"
"github.com/AdguardTeam/urlfilter/rules"
@@ -403,6 +403,8 @@ func (d *DNSFilter) CheckHostRules(host string, qtype uint16, setts *Settings) (
return Result{}, nil
}
host = strings.ToLower(host)
return d.matchHost(host, qtype, setts)
}
@@ -490,12 +492,12 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) {
d.confLock.RLock()
defer d.confLock.RUnlock()
rr := findRewrites(d.Rewrites, host)
rr := findRewrites(d.Rewrites, host, qtype)
if len(rr) != 0 {
res.Reason = Rewritten
}
cnames := aghstrings.NewSet()
cnames := stringutil.NewSet()
origHost := host
for len(rr) != 0 && rr[0].Type == dns.TypeCNAME {
log.Debug("rewrite: CNAME for %s is %s", host, rr[0].Answer)
@@ -515,15 +517,14 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) {
cnames.Add(host)
res.CanonName = rr[0].Answer
rr = findRewrites(d.Rewrites, host)
rr = findRewrites(d.Rewrites, host, qtype)
}
for _, r := range rr {
if (r.Type == dns.TypeA && qtype == dns.TypeA) ||
(r.Type == dns.TypeAAAA && qtype == dns.TypeAAAA) {
if r.Type == qtype && (qtype == dns.TypeA || qtype == dns.TypeAAAA) {
if r.IP == nil { // IP exception
res.Reason = 0
res.Reason = NotFilteredNotFound
return res
}

View File

@@ -15,10 +15,16 @@ import (
// RewriteEntry is a rewrite array element
type RewriteEntry struct {
// Domain is the domain for which this rewrite should work.
Domain string `yaml:"domain"`
Answer string `yaml:"answer"` // IP address or canonical name
Type uint16 `yaml:"-"` // DNS record type: CNAME, A or AAAA
IP net.IP `yaml:"-"` // Parsed IP address (if Type is A or AAAA)
// Answer is the IP address, canonical name, or one of the special
// values: "A" or "AAAA".
Answer string `yaml:"answer"`
// IP is the IP address that should be used in the response if Type is
// A or AAAA.
IP net.IP `yaml:"-"`
// Type is the DNS record type: A, AAAA, or CNAME.
Type uint16 `yaml:"-"`
}
func (r *RewriteEntry) equals(b RewriteEntry) bool {
@@ -26,27 +32,32 @@ func (r *RewriteEntry) equals(b RewriteEntry) bool {
}
func isWildcard(host string) bool {
return len(host) >= 2 &&
host[0] == '*' && host[1] == '.'
return len(host) > 1 && host[0] == '*' && host[1] == '.'
}
// Return TRUE of host name matches a wildcard pattern
func matchDomainWildcard(host, wildcard string) bool {
return isWildcard(wildcard) &&
strings.HasSuffix(host, wildcard[1:])
// matchDomainWildcard returns true if host matches the wildcard pattern.
func matchDomainWildcard(host, wildcard string) (ok bool) {
return isWildcard(wildcard) && strings.HasSuffix(host, wildcard[1:])
}
type rewritesArray []RewriteEntry
// rewritesSorted is a slice of legacy rewrites for sorting.
//
// The sorting priority:
//
// A and AAAA > CNAME
// wildcard > exact
// lower level wildcard > higher level wildcard
//
type rewritesSorted []RewriteEntry
func (a rewritesArray) Len() int { return len(a) }
// Len implements the sort.Interface interface for legacyRewritesSorted.
func (a rewritesSorted) Len() int { return len(a) }
func (a rewritesArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Swap implements the sort.Interface interface for legacyRewritesSorted.
func (a rewritesSorted) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Priority:
// . CNAME < A/AAAA;
// . exact < wildcard;
// . higher level wildcard < lower level wildcard
func (a rewritesArray) Less(i, j int) bool {
// Less implements the sort.Interface interface for legacyRewritesSorted.
func (a rewritesSorted) Less(i, j int) bool {
if a[i].Type == dns.TypeCNAME && a[j].Type != dns.TypeCNAME {
return true
} else if a[i].Type != dns.TypeCNAME && a[j].Type == dns.TypeCNAME {
@@ -67,31 +78,42 @@ func (a rewritesArray) Less(i, j int) bool {
return len(a[i].Domain) > len(a[j].Domain)
}
// Prepare entry for use
// prepare prepares the a new or decoded entry.
func (r *RewriteEntry) prepare() {
if r.Answer == "AAAA" {
// TODO(a.garipov): Write a case-agnostic version of strings.HasSuffix
// and use it in matchDomainWildcard instead of using strings.ToLower
// everywhere.
r.Domain = strings.ToLower(r.Domain)
switch r.Answer {
case "AAAA":
r.IP = nil
r.Type = dns.TypeAAAA
return
} else if r.Answer == "A" {
case "A":
r.IP = nil
r.Type = dns.TypeA
return
default:
// Go on.
}
ip := net.ParseIP(r.Answer)
if ip == nil {
r.Type = dns.TypeCNAME
return
}
r.IP = ip
r.Type = dns.TypeAAAA
ip4 := ip.To4()
if ip4 != nil {
r.IP = ip4
r.Type = dns.TypeA
} else {
r.IP = ip
r.Type = dns.TypeAAAA
}
}
@@ -101,19 +123,23 @@ func (d *DNSFilter) prepareRewrites() {
}
}
// Get the list of matched rewrite entries.
// Priority: CNAME, A/AAAA; exact, wildcard.
// If matched exactly, don't return wildcard entries.
// If matched by several wildcards, select the more specific one
func findRewrites(a []RewriteEntry, host string) []RewriteEntry {
rr := rewritesArray{}
// findRewrites returns the list of matched rewrite entries. The priority is:
// CNAME, then A and AAAA; exact, then wildcard. If the host is matched
// exactly, wildcard entries aren't returned. If the host matched by wildcards,
// return the most specific for the question type.
func findRewrites(a []RewriteEntry, host string, qtype uint16) []RewriteEntry {
rr := rewritesSorted{}
for _, r := range a {
if r.Domain != host {
if !matchDomainWildcard(host, r.Domain) {
continue
}
if r.Domain != host && !matchDomainWildcard(host, r.Domain) {
continue
}
// Return CNAMEs for all types requests, but only the
// appropriate ones for A and AAAA.
if r.Type == dns.TypeCNAME ||
(r.Type == qtype && (qtype == dns.TypeA || qtype == dns.TypeAAAA)) {
rr = append(rr, r)
}
rr = append(rr, r)
}
if len(rr) == 0 {

View File

@@ -57,59 +57,84 @@ func TestRewrites(t *testing.T) {
}, {
Domain: "a.host3.com",
Answer: "x.host.com",
}, {
Domain: "*.hostboth.com",
Answer: "1.2.3.6",
}, {
Domain: "*.hostboth.com",
Answer: "1234::5678",
}, {
Domain: "BIGHOST.COM",
Answer: "1.2.3.7",
}}
d.prepareRewrites()
testCases := []struct {
name string
host string
dtyp uint16
wantCName string
wantVals []net.IP
dtyp uint16
}{{
name: "not_filtered_not_found",
host: "hoost.com",
dtyp: dns.TypeA,
name: "not_filtered_not_found",
host: "hoost.com",
wantCName: "",
wantVals: nil,
dtyp: dns.TypeA,
}, {
name: "rewritten_a",
host: "www.host.com",
dtyp: dns.TypeA,
wantCName: "host.com",
wantVals: []net.IP{{1, 2, 3, 4}, {1, 2, 3, 5}},
dtyp: dns.TypeA,
}, {
name: "rewritten_aaaa",
host: "www.host.com",
dtyp: dns.TypeAAAA,
wantCName: "host.com",
wantVals: []net.IP{net.ParseIP("1:2:3::4")},
dtyp: dns.TypeAAAA,
}, {
name: "wildcard_match",
host: "abc.host.com",
dtyp: dns.TypeA,
wantVals: []net.IP{{1, 2, 3, 5}},
name: "wildcard_match",
host: "abc.host.com",
wantCName: "",
wantVals: []net.IP{{1, 2, 3, 5}},
dtyp: dns.TypeA,
}, {
name: "wildcard_override",
host: "a.host.com",
dtyp: dns.TypeA,
wantVals: []net.IP{{1, 2, 3, 4}},
name: "wildcard_override",
host: "a.host.com",
wantCName: "",
wantVals: []net.IP{{1, 2, 3, 4}},
dtyp: dns.TypeA,
}, {
name: "wildcard_cname_interaction",
host: "www.host2.com",
dtyp: dns.TypeA,
wantCName: "host.com",
wantVals: []net.IP{{1, 2, 3, 4}, {1, 2, 3, 5}},
dtyp: dns.TypeA,
}, {
name: "two_cnames",
host: "b.host.com",
dtyp: dns.TypeA,
wantCName: "somehost.com",
wantVals: []net.IP{{0, 0, 0, 0}},
dtyp: dns.TypeA,
}, {
name: "two_cnames_and_wildcard",
host: "b.host3.com",
dtyp: dns.TypeA,
wantCName: "x.host.com",
wantVals: []net.IP{{1, 2, 3, 5}},
dtyp: dns.TypeA,
}, {
name: "issue3343",
host: "www.hostboth.com",
wantCName: "",
wantVals: []net.IP{net.ParseIP("1234::5678")},
dtyp: dns.TypeAAAA,
}, {
name: "issue3351",
host: "bighost.com",
wantCName: "",
wantVals: []net.IP{{1, 2, 3, 7}},
dtyp: dns.TypeA,
}}
for _, tc := range testCases {
@@ -123,7 +148,8 @@ func TestRewrites(t *testing.T) {
return
}
require.Equal(t, Rewritten, r.Reason)
require.Equalf(t, Rewritten, r.Reason, "got %s", r.Reason)
if tc.wantCName != "" {
assert.Equal(t, tc.wantCName, r.CanonName)
}
@@ -143,12 +169,15 @@ func TestRewritesLevels(t *testing.T) {
d.Rewrites = []RewriteEntry{{
Domain: "host.com",
Answer: "1.1.1.1",
Type: dns.TypeA,
}, {
Domain: "*.host.com",
Answer: "2.2.2.2",
Type: dns.TypeA,
}, {
Domain: "*.sub.host.com",
Answer: "3.3.3.3",
Type: dns.TypeA,
}}
d.prepareRewrites()
@@ -234,53 +263,61 @@ func TestRewritesExceptionIP(t *testing.T) {
d.Rewrites = []RewriteEntry{{
Domain: "host.com",
Answer: "1.2.3.4",
Type: dns.TypeA,
}, {
Domain: "host.com",
Answer: "AAAA",
Type: dns.TypeAAAA,
}, {
Domain: "host2.com",
Answer: "::1",
Type: dns.TypeAAAA,
}, {
Domain: "host2.com",
Answer: "A",
Type: dns.TypeA,
}, {
Domain: "host3.com",
Answer: "A",
Type: dns.TypeA,
}}
d.prepareRewrites()
testCases := []struct {
name string
host string
dtyp uint16
want []net.IP
dtyp uint16
}{{
name: "match_A",
host: "host.com",
dtyp: dns.TypeA,
want: []net.IP{{1, 2, 3, 4}},
dtyp: dns.TypeA,
}, {
name: "exception_AAAA_host.com",
host: "host.com",
want: nil,
dtyp: dns.TypeAAAA,
}, {
name: "exception_A_host2.com",
host: "host2.com",
want: nil,
dtyp: dns.TypeA,
}, {
name: "match_AAAA_host2.com",
host: "host2.com",
dtyp: dns.TypeAAAA,
want: []net.IP{net.ParseIP("::1")},
dtyp: dns.TypeAAAA,
}, {
name: "exception_A_host3.com",
host: "host3.com",
want: nil,
dtyp: dns.TypeA,
}, {
name: "match_AAAA_host3.com",
host: "host3.com",
want: nil,
dtyp: dns.TypeAAAA,
want: []net.IP{},
}}
for _, tc := range testCases {
@@ -292,8 +329,10 @@ func TestRewritesExceptionIP(t *testing.T) {
return
}
assert.Equal(t, Rewritten, r.Reason)
assert.Equalf(t, Rewritten, r.Reason, "got %s", r.Reason)
require.Len(t, r.IPList, len(tc.want))
for _, ip := range tc.want {
assert.True(t, ip.Equal(r.IPList[0]))
}

View File

@@ -13,10 +13,10 @@ import (
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/miekg/dns"
"golang.org/x/net/publicsuffix"
)
@@ -186,16 +186,16 @@ func (c *sbCtx) getQuestion() string {
for hash := range c.hashToHost {
// TODO(e.burkov, a.garipov): Find out and document why exactly
// this slice.
aghstrings.WriteToBuilder(b, hex.EncodeToString(hash[0:2]), ".")
stringutil.WriteToBuilder(b, hex.EncodeToString(hash[0:2]), ".")
}
if c.svc == "SafeBrowsing" {
aghstrings.WriteToBuilder(b, sbTXTSuffix)
stringutil.WriteToBuilder(b, sbTXTSuffix)
return b.String()
}
aghstrings.WriteToBuilder(b, pcTXTSuffix)
stringutil.WriteToBuilder(b, pcTXTSuffix)
return b.String()
}

View File

@@ -12,7 +12,6 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
@@ -21,6 +20,7 @@ import (
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
)
const clientsUpdatePeriod = 10 * time.Minute
@@ -86,7 +86,7 @@ type clientsContainer struct {
lock sync.Mutex
allTags *aghstrings.Set
allTags *stringutil.Set
// dhcpServer is used for looking up clients IP addresses by MAC addresses
dhcpServer *dhcpd.Server
@@ -114,7 +114,7 @@ func (clients *clientsContainer) Init(
clients.idIndex = make(map[string]*Client)
clients.ipToRC = aghnet.NewIPMap(0)
clients.allTags = aghstrings.NewSet(clientTags...)
clients.allTags = stringutil.NewSet(clientTags...)
clients.dhcpServer = dhcpServer
clients.etcHosts = etcHosts
@@ -221,10 +221,10 @@ func (clients *clientsContainer) WriteDiskConfig(objects *[]clientObject) {
UseGlobalBlockedServices: !cli.UseOwnBlockedServices,
}
cy.Tags = aghstrings.CloneSlice(cli.Tags)
cy.IDs = aghstrings.CloneSlice(cli.IDs)
cy.BlockedServices = aghstrings.CloneSlice(cli.BlockedServices)
cy.Upstreams = aghstrings.CloneSlice(cli.Upstreams)
cy.Tags = stringutil.CloneSlice(cli.Tags)
cy.IDs = stringutil.CloneSlice(cli.IDs)
cy.BlockedServices = stringutil.CloneSlice(cli.BlockedServices)
cy.Upstreams = stringutil.CloneSlice(cli.Upstreams)
*objects = append(*objects, cy)
}
@@ -328,10 +328,10 @@ func (clients *clientsContainer) Find(id string) (c *Client, ok bool) {
return nil, false
}
c.IDs = aghstrings.CloneSlice(c.IDs)
c.Tags = aghstrings.CloneSlice(c.Tags)
c.BlockedServices = aghstrings.CloneSlice(c.BlockedServices)
c.Upstreams = aghstrings.CloneSlice(c.Upstreams)
c.IDs = stringutil.CloneSlice(c.IDs)
c.Tags = stringutil.CloneSlice(c.Tags)
c.BlockedServices = stringutil.CloneSlice(c.BlockedServices)
c.Upstreams = stringutil.CloneSlice(c.Upstreams)
return c, true
}
@@ -349,7 +349,7 @@ func (clients *clientsContainer) findUpstreams(
return nil, nil
}
upstreams := aghstrings.FilterOut(c.Upstreams, aghstrings.IsCommentOrEmpty)
upstreams := stringutil.FilterOut(c.Upstreams, dnsforward.IsCommentOrEmpty)
if len(upstreams) == 0 {
return nil, nil
}

View File

@@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"sync"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
@@ -102,11 +103,12 @@ type dnsConfig struct {
// time interval for statistics (in days)
StatsInterval uint32 `yaml:"statistics_interval"`
QueryLogEnabled bool `yaml:"querylog_enabled"` // if true, query log is enabled
QueryLogFileEnabled bool `yaml:"querylog_file_enabled"` // if true, query log will be written to a file
QueryLogInterval uint32 `yaml:"querylog_interval"` // time interval for query log (in days)
QueryLogMemSize uint32 `yaml:"querylog_size_memory"` // number of entries kept in memory before they are flushed to disk
AnonymizeClientIP bool `yaml:"anonymize_client_ip"` // anonymize clients' IP addresses in logs and stats
QueryLogEnabled bool `yaml:"querylog_enabled"` // if true, query log is enabled
QueryLogFileEnabled bool `yaml:"querylog_file_enabled"` // if true, query log will be written to a file
// QueryLogInterval is the interval for query log's files rotation.
QueryLogInterval Duration `yaml:"querylog_interval"`
QueryLogMemSize uint32 `yaml:"querylog_size_memory"` // number of entries kept in memory before they are flushed to disk
AnonymizeClientIP bool `yaml:"anonymize_client_ip"` // anonymize clients' IP addresses in logs and stats
dnsforward.FilteringConfig `yaml:",inline"`
@@ -177,6 +179,8 @@ var config = configuration{
RefuseAny: true,
AllServers: false,
TrustedProxies: []string{"127.0.0.0/8", "::1/128"},
// set default maximum concurrent queries to 300
// we introduced a default limit due to this:
// https://github.com/AdguardTeam/AdGuardHome/issues/2015#issuecomment-674041912
@@ -185,7 +189,7 @@ var config = configuration{
},
FilteringEnabled: true, // whether or not use filter lists
FiltersUpdateIntervalHours: 24,
UpstreamTimeout: Duration{dnsforward.DefaultTimeout},
UpstreamTimeout: Duration{Duration: dnsforward.DefaultTimeout},
LocalDomainName: "lan",
ResolveClients: true,
UsePrivateRDNS: true,
@@ -212,7 +216,7 @@ func initConfig() {
config.DNS.QueryLogEnabled = true
config.DNS.QueryLogFileEnabled = true
config.DNS.QueryLogInterval = 90
config.DNS.QueryLogInterval = Duration{Duration: 90 * 24 * time.Hour}
config.DNS.QueryLogMemSize = 1000
config.DNS.CacheSize = 4 * 1024 * 1024
@@ -281,7 +285,7 @@ func parseConfig() error {
}
if config.DNS.UpstreamTimeout.Duration == 0 {
config.DNS.UpstreamTimeout = Duration{dnsforward.DefaultTimeout}
config.DNS.UpstreamTimeout = Duration{Duration: dnsforward.DefaultTimeout}
}
return nil
@@ -328,7 +332,7 @@ func (c *configuration) write() error {
Context.queryLog.WriteDiskConfig(&dc)
config.DNS.QueryLogEnabled = dc.Enabled
config.DNS.QueryLogFileEnabled = dc.FileEnabled
config.DNS.QueryLogInterval = dc.RotationIvl
config.DNS.QueryLogInterval = Duration{Duration: dc.RotationIvl}
config.DNS.QueryLogMemSize = dc.MemSize
config.DNS.AnonymizeClientIP = dc.AnonymizeClientIP
}

View File

@@ -48,7 +48,7 @@ func initDNSServer() error {
HTTPRegister: httpRegister,
FindClient: Context.clients.findMultiple,
BaseDir: baseDir,
RotationIvl: config.DNS.QueryLogInterval,
RotationIvl: config.DNS.QueryLogInterval.Duration,
MemSize: config.DNS.QueryLogMemSize,
Enabled: config.DNS.QueryLogEnabled,
FileEnabled: config.DNS.QueryLogFileEnabled,

View File

@@ -12,6 +12,35 @@ type Duration struct {
time.Duration
}
// String implements the fmt.Stringer interface for Duration. It wraps
// time.Duration.String method and additionally cuts off non-leading zero values
// of minutes and seconds. Some values which are differ between the
// implementations:
//
// Duration: "1m", time.Duration: "1m0s"
// Duration: "1h", time.Duration: "1h0m0s"
// Duration: "1h1m", time.Duration: "1h1m0s"
//
func (d Duration) String() (str string) {
str = d.Duration.String()
secs := d.Seconds()
var secsInt int
if secsInt = int(secs); float64(secsInt) != secs || secsInt%60 != 0 {
return str
}
const (
tailMin = len(`0s`)
tailMinSec = len(`0m0s`)
)
if (secsInt%3600)/60 != 0 {
return str[:len(str)-tailMin]
}
return str[:len(str)-tailMinSec]
}
// MarshalText implements the encoding.TextMarshaler interface for Duration.
func (d Duration) MarshalText() (text []byte, err error) {
return []byte(d.String()), nil
@@ -19,6 +48,8 @@ func (d Duration) MarshalText() (text []byte, err error) {
// UnmarshalText implements the encoding.TextUnmarshaler interface for
// *Duration.
//
// TODO(e.burkov): Make it able to parse larger units like days.
func (d *Duration) UnmarshalText(b []byte) (err error) {
defer func() { err = errors.Annotate(err, "unmarshalling duration: %w") }()

View File

@@ -12,6 +12,50 @@ import (
yaml "gopkg.in/yaml.v2"
)
func TestDuration_String(t *testing.T) {
testCases := []struct {
name string
val time.Duration
}{{
name: "1s",
val: time.Second,
}, {
name: "1m",
val: time.Minute,
}, {
name: "1h",
val: time.Hour,
}, {
name: "1m1s",
val: time.Minute + time.Second,
}, {
name: "1h1m",
val: time.Hour + time.Minute,
}, {
name: "1h0m1s",
val: time.Hour + time.Second,
}, {
name: "1ms",
val: time.Millisecond,
}, {
name: "1h0m0.001s",
val: time.Hour + time.Millisecond,
}, {
name: "1.001s",
val: time.Second + time.Millisecond,
}, {
name: "1m1.001s",
val: time.Minute + time.Second + time.Millisecond,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
d := Duration{Duration: tc.val}
assert.Equal(t, tc.name, d.String())
})
}
}
// durationEncodingTester is a helper struct to simplify testing different
// Duration marshalling and unmarshalling cases.
type durationEncodingTester struct {

View File

@@ -6,12 +6,12 @@ import (
"net/http"
"strings"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
)
// TODO(a.garipov): Get rid of a global variable?
var allowedLanguages = aghstrings.NewSet(
var allowedLanguages = stringutil.NewSet(
"be",
"bg",
"cs",

View File

@@ -9,12 +9,12 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/miekg/dns"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -86,7 +86,7 @@ func TestRDNS_Begin(t *testing.T) {
list: map[string]*Client{},
idIndex: tc.cliIDIndex,
ipToRC: aghnet.NewIPMap(0),
allTags: aghstrings.NewSet(),
allTags: stringutil.NewSet(),
},
}
ipCache.Clear()
@@ -206,7 +206,7 @@ func TestRDNS_WorkerLoop(t *testing.T) {
list: map[string]*Client{},
idIndex: map[string]*Client{},
ipToRC: aghnet.NewIPMap(0),
allTags: aghstrings.NewSet(),
allTags: stringutil.NewSet(),
}
ch := make(chan net.IP)
rdns := &RDNS{

View File

@@ -14,7 +14,6 @@ import (
"net/http"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"sync"
@@ -22,6 +21,7 @@ import (
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/google/go-cmp/cmp"
"golang.org/x/sys/cpu"
)
@@ -270,8 +270,9 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
}
status = validateCertificates(string(data.CertificateChainData), string(data.PrivateKeyData), data.ServerName)
restartHTTPS := false
t.confLock.Lock()
if !reflect.DeepEqual(t.conf, data) {
if !cmp.Equal(t.conf, data) {
log.Printf("tls config settings have changed, will restart HTTPS server")
restartHTTPS = true
}

View File

@@ -9,6 +9,7 @@ import (
"runtime"
"strconv"
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/golibs/errors"
@@ -19,7 +20,7 @@ import (
)
// currentSchemaVersion is the current schema version.
const currentSchemaVersion = 11
const currentSchemaVersion = 12
// These aliases are provided for convenience.
type (
@@ -82,6 +83,7 @@ func upgradeConfigSchema(oldVersion int, diskConf yobj) (err error) {
upgradeSchema8to9,
upgradeSchema9to10,
upgradeSchema10to11,
upgradeSchema11to12,
}
n := 0
@@ -647,6 +649,46 @@ func upgradeSchema10to11(diskConf yobj) (err error) {
return nil
}
// upgradeSchema11to12 performs the following changes:
//
// # BEFORE:
// 'querylog_interval': 90
//
// # AFTER:
// 'querylog_interval': '2160h'
//
func upgradeSchema11to12(diskConf yobj) (err error) {
log.Printf("Upgrade yaml: 11 to 12")
diskConf["schema_version"] = 12
dnsVal, ok := diskConf["dns"]
if !ok {
return nil
}
var dns yobj
dns, ok = dnsVal.(yobj)
if !ok {
return fmt.Errorf("unexpected type of dns: %T", dnsVal)
}
const field = "querylog_interval"
// Set the initial value from home.initConfig function.
qlogIvl := 90
qlogIvlVal, ok := dns[field]
if ok {
qlogIvl, ok = qlogIvlVal.(int)
if !ok {
return fmt.Errorf("unexpected type of %s: %T", field, qlogIvlVal)
}
}
dns[field] = Duration{Duration: time.Duration(qlogIvl) * 24 * time.Hour}
return nil
}
// TODO(a.garipov): Replace with log.Output when we port it to our logging
// package.
func funcName() string {

View File

@@ -2,6 +2,7 @@ package home
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -415,3 +416,98 @@ func TestUpgradeSchema10to11(t *testing.T) {
check(t, conf)
})
}
func TestUpgradeSchema11to12(t *testing.T) {
testCases := []struct {
ivl any
want any
wantErr string
name string
}{{
ivl: 1,
want: Duration{Duration: 24 * time.Hour},
wantErr: "",
name: "success",
}, {
ivl: 0.25,
want: 0,
wantErr: "unexpected type of querylog_interval: float64",
name: "fail",
}}
for _, tc := range testCases {
conf := yobj{
"dns": yobj{
"querylog_interval": tc.ivl,
},
"schema_version": 11,
}
t.Run(tc.name, func(t *testing.T) {
err := upgradeSchema11to12(conf)
if tc.wantErr != "" {
require.Error(t, err)
assert.Equal(t, tc.wantErr, err.Error())
return
}
require.NoError(t, err)
require.Equal(t, conf["schema_version"], 12)
dnsVal, ok := conf["dns"]
require.True(t, ok)
var newDNSConf yobj
newDNSConf, ok = dnsVal.(yobj)
require.True(t, ok)
var newIvl Duration
newIvl, ok = newDNSConf["querylog_interval"].(Duration)
require.True(t, ok)
assert.Equal(t, tc.want, newIvl)
})
}
t.Run("no_dns", func(t *testing.T) {
err := upgradeSchema11to12(yobj{})
assert.NoError(t, err)
})
t.Run("bad_dns", func(t *testing.T) {
err := upgradeSchema11to12(yobj{
"dns": 0,
})
require.Error(t, err)
assert.Equal(t, "unexpected type of dns: int", err.Error())
})
t.Run("no_field", func(t *testing.T) {
conf := yobj{
"dns": yobj{},
}
err := upgradeSchema11to12(conf)
require.NoError(t, err)
dns, ok := conf["dns"]
require.True(t, ok)
var dnsVal yobj
dnsVal, ok = dns.(yobj)
require.True(t, ok)
var ivl interface{}
ivl, ok = dnsVal["querylog_interval"]
require.True(t, ok)
var ivlVal Duration
ivlVal, ok = ivl.(Duration)
require.True(t, ok)
assert.Equal(t, 90*24*time.Hour, ivlVal.Duration)
})
}

View File

@@ -10,10 +10,10 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/cache"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
)
const (
@@ -107,7 +107,7 @@ func whoisParse(data string) (m strmap) {
v = trimValue(v)
case "descr", "netname":
k = "orgname"
v = aghstrings.Coalesce(orgname, v)
v = stringutil.Coalesce(orgname, v)
orgname = v
case "whois":
k = "whois"

View File

@@ -6,17 +6,21 @@ import (
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/jsonutil"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"golang.org/x/net/idna"
)
type qlogConfig struct {
Enabled bool `json:"enabled"`
Interval uint32 `json:"interval"`
AnonymizeClientIP bool `json:"anonymize_client_ip"`
Enabled bool `json:"enabled"`
// Use float64 here to support fractional numbers and not mess the API
// users by changing the units.
Interval float64 `json:"interval"`
AnonymizeClientIP bool `json:"anonymize_client_ip"`
}
// Register web handlers
@@ -69,7 +73,7 @@ func (l *queryLog) handleQueryLogClear(_ http.ResponseWriter, _ *http.Request) {
func (l *queryLog) handleQueryLogInfo(w http.ResponseWriter, r *http.Request) {
resp := qlogConfig{}
resp.Enabled = l.conf.Enabled
resp.Interval = l.conf.RotationIvl
resp.Interval = l.conf.RotationIvl.Hours() / 24
resp.AnonymizeClientIP = l.conf.AnonymizeClientIP
jsonVal, err := json.Marshal(resp)
@@ -93,7 +97,8 @@ func (l *queryLog) handleQueryLogConfig(w http.ResponseWriter, r *http.Request)
return
}
if req.Exists("interval") && !checkInterval(d.Interval) {
ivl := time.Duration(24*d.Interval) * time.Hour
if req.Exists("interval") && !checkInterval(ivl) {
httpError(r, w, http.StatusBadRequest, "Unsupported interval")
return
}
@@ -105,7 +110,7 @@ func (l *queryLog) handleQueryLogConfig(w http.ResponseWriter, r *http.Request)
conf.Enabled = d.Enabled
}
if req.Exists("interval") {
conf.RotationIvl = d.Interval
conf.RotationIvl = ivl
}
if req.Exists("anonymize_client_ip") {
conf.AnonymizeClientIP = d.AnonymizeClientIP
@@ -127,25 +132,53 @@ func getDoubleQuotesEnclosedValue(s *string) bool {
}
// parseSearchCriterion parses a search criterion from the query parameter.
func (l *queryLog) parseSearchCriterion(q url.Values, name string, ct criterionType) (ok bool, sc searchCriterion, err error) {
func (l *queryLog) parseSearchCriterion(q url.Values, name string, ct criterionType) (
ok bool,
sc searchCriterion,
err error,
) {
val := q.Get(name)
if len(val) == 0 {
return false, searchCriterion{}, nil
if val == "" {
return false, sc, nil
}
c := searchCriterion{
strict := getDoubleQuotesEnclosedValue(&val)
var asciiVal string
switch ct {
case ctTerm:
// Decode lowercased value from punycode to make EqualFold and
// friends work properly with IDNAs.
//
// TODO(e.burkov): Make it work with parts of IDNAs somehow.
loweredVal := strings.ToLower(val)
if asciiVal, err = idna.ToASCII(loweredVal); err != nil {
log.Debug("can't convert %q to ascii: %s", val, err)
} else if asciiVal == loweredVal {
// Purge asciiVal to prevent checking the same value
// twice.
asciiVal = ""
}
case ctFilteringStatus:
if !stringutil.InSlice(filteringStatusValues, val) {
return false, sc, fmt.Errorf("invalid value %s", val)
}
default:
return false, sc, fmt.Errorf(
"invalid criterion type %v: should be one of %v",
ct,
[]criterionType{ctTerm, ctFilteringStatus},
)
}
sc = searchCriterion{
criterionType: ct,
value: val,
}
if getDoubleQuotesEnclosedValue(&c.value) {
c.strict = true
asciiVal: asciiVal,
strict: strict,
}
if ct == ctFilteringStatus && !aghstrings.InSlice(filteringStatusValues, c.value) {
return false, c, fmt.Errorf("invalid value %s", c.value)
}
return true, c, nil
return true, sc, nil
}
// parseSearchParams - parses "searchParams" from the HTTP request's query string
@@ -175,15 +208,19 @@ func (l *queryLog) parseSearchParams(r *http.Request) (p *searchParams, err erro
p.maxFileScanEntries = 0
}
paramNames := map[string]criterionType{
"search": ctTerm,
"response_status": ctFilteringStatus,
}
for k, v := range paramNames {
for _, v := range []struct {
urlField string
ct criterionType
}{{
urlField: "search",
ct: ctTerm,
}, {
urlField: "response_status",
ct: ctFilteringStatus,
}} {
var ok bool
var c searchCriterion
ok, c, err = l.parseSearchCriterion(q, k, v)
ok, c, err = l.parseSearchCriterion(q, v.urlField, v.ct)
if err != nil {
return nil, err
}

View File

@@ -100,8 +100,17 @@ func (l *queryLog) Close() {
_ = l.flushLogBuffer(true)
}
func checkInterval(days uint32) bool {
return days == 1 || days == 7 || days == 30 || days == 90
func checkInterval(ivl time.Duration) (ok bool) {
// The constants for possible values of query log's rotation interval.
const (
quarterDay = 6 * time.Hour
day = 24 * time.Hour
week = day * 7
month = day * 30
threeMonths = day * 90
)
return ivl == quarterDay || ivl == day || ivl == week || ivl == month || ivl == threeMonths
}
func (l *queryLog) WriteDiskConfig(c *Config) {

View File

@@ -26,7 +26,7 @@ func TestQueryLog(t *testing.T) {
l := newQueryLog(Config{
Enabled: true,
FileEnabled: true,
RotationIvl: 1,
RotationIvl: 24 * time.Hour,
MemSize: 100,
BaseDir: t.TempDir(),
})
@@ -128,7 +128,7 @@ func TestQueryLog(t *testing.T) {
func TestQueryLogOffsetLimit(t *testing.T) {
l := newQueryLog(Config{
Enabled: true,
RotationIvl: 1,
RotationIvl: 24 * time.Hour,
MemSize: 100,
BaseDir: t.TempDir(),
})
@@ -153,33 +153,34 @@ func TestQueryLogOffsetLimit(t *testing.T) {
testCases := []struct {
name string
want string
wantLen int
offset int
limit int
wantLen int
want string
}{{
name: "page_1",
want: firstPageDomain,
wantLen: 10,
offset: 0,
limit: 10,
wantLen: 10,
want: firstPageDomain,
}, {
name: "page_2",
want: secondPageDomain,
wantLen: 10,
offset: 10,
limit: 10,
wantLen: 10,
want: secondPageDomain,
}, {
name: "page_2.5",
want: secondPageDomain,
wantLen: 5,
offset: 15,
limit: 10,
wantLen: 5,
want: secondPageDomain,
}, {
name: "page_3",
want: "",
wantLen: 0,
offset: 20,
limit: 10,
wantLen: 0,
}}
for _, tc := range testCases {
@@ -202,7 +203,7 @@ func TestQueryLogMaxFileScanEntries(t *testing.T) {
l := newQueryLog(Config{
Enabled: true,
FileEnabled: true,
RotationIvl: 1,
RotationIvl: 24 * time.Hour,
MemSize: 100,
BaseDir: t.TempDir(),
})
@@ -230,7 +231,7 @@ func TestQueryLogFileDisabled(t *testing.T) {
l := newQueryLog(Config{
Enabled: true,
FileEnabled: false,
RotationIvl: 1,
RotationIvl: 24 * time.Hour,
MemSize: 2,
BaseDir: t.TempDir(),
})

View File

@@ -41,10 +41,17 @@ type Config struct {
// BaseDir is the base directory for log files.
BaseDir string
// RotationIvl is the interval for log rotation, in days. After that
// period, the old log file will be renamed, NOT deleted, so the actual
// log retention time is twice the interval.
RotationIvl uint32
// RotationIvl is the interval for log rotation. After that period, the
// old log file will be renamed, NOT deleted, so the actual log
// retention time is twice the interval. The value must be one of:
//
// 6 * time.Hour
// 24 * time.Hour
// 7 * 24 * time.Hour
// 30 * 24 * time.Hour
// 90 * 24 * time.Hour
//
RotationIvl time.Duration
// MemSize is the number of entries kept in a memory buffer before they
// are flushed to disk.
@@ -118,7 +125,7 @@ func newQueryLog(conf Config) (l *queryLog) {
"querylog: warning: unsupported rotation interval %d, setting to 1 day",
conf.RotationIvl,
)
l.conf.RotationIvl = 1
l.conf.RotationIvl = 24 * time.Hour
}
return l

View File

@@ -104,43 +104,52 @@ func (l *queryLog) rotate() error {
return nil
}
func (l *queryLog) readFileFirstTimeValue() int64 {
f, err := os.Open(l.logFile)
func (l *queryLog) readFileFirstTimeValue() (first time.Time, err error) {
var f *os.File
f, err = os.Open(l.logFile)
if err != nil {
return -1
return time.Time{}, err
}
defer func() {
derr := f.Close()
if derr != nil {
log.Error("querylog: closing file: %s", derr)
}
}()
buf := make([]byte, 500)
r, err := f.Read(buf)
defer func() { err = errors.WithDeferred(err, f.Close()) }()
buf := make([]byte, 512)
var r int
r, err = f.Read(buf)
if err != nil {
return -1
return time.Time{}, err
}
buf = buf[:r]
val := readJSONValue(string(buf), `"T":"`)
val := readJSONValue(string(buf[:r]), `"T":"`)
t, err := time.Parse(time.RFC3339Nano, val)
if err != nil {
return -1
return time.Time{}, err
}
log.Debug("querylog: the oldest log entry: %s", val)
return t.Unix()
return t, nil
}
func (l *queryLog) periodicRotate() {
intervalSeconds := uint64(l.conf.RotationIvl) * 24 * 60 * 60
defer log.OnPanic("querylog: rotating")
var err error
for {
oldest := l.readFileFirstTimeValue()
if uint64(oldest)+intervalSeconds <= uint64(time.Now().Unix()) {
_ = l.rotate()
var oldest time.Time
oldest, err = l.readFileFirstTimeValue()
if err != nil {
log.Debug("%s", err)
}
if oldest.Add(l.conf.RotationIvl).After(time.Now()) {
err = l.rotate()
if err != nil {
log.Debug("%s", err)
}
}
// What?
time.Sleep(24 * time.Hour)
}
}

View File

@@ -37,7 +37,7 @@ func TestQueryLog_Search_findClient(t *testing.T) {
l := newQueryLog(Config{
FindClient: findClient,
BaseDir: t.TempDir(),
RotationIvl: 1,
RotationIvl: 24 * time.Hour,
MemSize: 100,
Enabled: true,
FileEnabled: true,

View File

@@ -11,10 +11,9 @@ import (
type criterionType int
const (
// ctTerm is for searching by the domain name, the client's IP
// address, the client's ID or the client's name.
//
// TODO(e.burkov): Make it support IDNA while #3012.
// ctTerm is for searching by the domain name, the client's IP address,
// the client's ID or the client's name. The domain name search
// supports IDNAs.
ctTerm criterionType = iota
// ctFilteringStatus is for searching by the filtering status.
//
@@ -47,6 +46,7 @@ var filteringStatusValues = []string{
// searchCriterion is a search criterion that is used to match a record.
type searchCriterion struct {
value string
asciiVal string
criterionType criterionType
// strict, if true, means that the criterion must be applied to the
// whole value rather than the part of it. That is, equality and not
@@ -54,14 +54,16 @@ type searchCriterion struct {
strict bool
}
func (c *searchCriterion) ctDomainOrClientCaseStrict(
func ctDomainOrClientCaseStrict(
term string,
asciiTerm string,
clientID string,
name string,
host string,
ip string,
) (ok bool) {
return strings.EqualFold(host, term) ||
(asciiTerm != "" && strings.EqualFold(host, asciiTerm)) ||
strings.EqualFold(clientID, term) ||
strings.EqualFold(ip, term) ||
strings.EqualFold(name, term)
@@ -98,8 +100,9 @@ func containsFold(s, substr string) (ok bool) {
return false
}
func (c *searchCriterion) ctDomainOrClientCaseNonStrict(
func ctDomainOrClientCaseNonStrict(
term string,
asciiTerm string,
clientID string,
name string,
host string,
@@ -107,6 +110,7 @@ func (c *searchCriterion) ctDomainOrClientCaseNonStrict(
) (ok bool) {
return containsFold(clientID, term) ||
containsFold(host, term) ||
(asciiTerm != "" && containsFold(host, asciiTerm)) ||
containsFold(ip, term) ||
containsFold(name, term)
}
@@ -127,10 +131,24 @@ func (c *searchCriterion) quickMatch(line string, findClient quickMatchClientFun
}
if c.strict {
return c.ctDomainOrClientCaseStrict(c.value, clientID, name, host, ip)
return ctDomainOrClientCaseStrict(
c.value,
c.asciiVal,
clientID,
name,
host,
ip,
)
}
return c.ctDomainOrClientCaseNonStrict(c.value, clientID, name, host, ip)
return ctDomainOrClientCaseNonStrict(
c.value,
c.asciiVal,
clientID,
name,
host,
ip,
)
case ctFilteringStatus:
// Go on, as we currently don't do quick matches against
// filtering statuses.
@@ -162,12 +180,11 @@ func (c *searchCriterion) ctDomainOrClientCase(e *logEntry) bool {
}
ip := e.IP.String()
term := strings.ToLower(c.value)
if c.strict {
return c.ctDomainOrClientCaseStrict(term, clientID, name, host, ip)
return ctDomainOrClientCaseStrict(c.value, c.asciiVal, clientID, name, host, ip)
}
return c.ctDomainOrClientCaseNonStrict(term, clientID, name, host, ip)
return ctDomainOrClientCaseNonStrict(c.value, c.asciiVal, clientID, name, host, ip)
}
func (c *searchCriterion) ctFilteringStatusCase(res filtering.Result) bool {

View File

@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
"github.com/AdguardTeam/golibs/stringutil"
)
// Channel constants.
@@ -93,16 +93,16 @@ func fmtModule(m *debug.Module) (formatted string) {
b := &strings.Builder{}
aghstrings.WriteToBuilder(b, m.Path)
stringutil.WriteToBuilder(b, m.Path)
if ver := m.Version; ver != "" {
sep := modInfoAtSep
if ver == "(devel)" {
sep = modInfoDevSep
}
aghstrings.WriteToBuilder(b, sep, ver)
stringutil.WriteToBuilder(b, sep, ver)
}
if sum := m.Sum; sum != "" {
aghstrings.WriteToBuilder(b, modInfoSumLeft, sum, modInfoSumRight)
stringutil.WriteToBuilder(b, modInfoSumLeft, sum, modInfoSumRight)
}
return b.String()
@@ -142,7 +142,7 @@ const (
func Verbose() (v string) {
b := &strings.Builder{}
aghstrings.WriteToBuilder(
stringutil.WriteToBuilder(
b,
vFmtAGHHdr,
nl,
@@ -156,15 +156,15 @@ func Verbose() (v string) {
runtime.Version(),
)
if buildtime != "" {
aghstrings.WriteToBuilder(b, nl, vFmtTimeHdr, buildtime)
stringutil.WriteToBuilder(b, nl, vFmtTimeHdr, buildtime)
}
aghstrings.WriteToBuilder(b, nl, vFmtGOOSHdr, nl, vFmtGOARCHHdr)
stringutil.WriteToBuilder(b, nl, vFmtGOOSHdr, nl, vFmtGOARCHHdr)
if goarm != "" {
aghstrings.WriteToBuilder(b, nl, vFmtGOARMHdr, "v", goarm)
stringutil.WriteToBuilder(b, nl, vFmtGOARMHdr, "v", goarm)
} else if gomips != "" {
aghstrings.WriteToBuilder(b, nl, vFmtGOMIPSHdr, gomips)
stringutil.WriteToBuilder(b, nl, vFmtGOMIPSHdr, gomips)
}
aghstrings.WriteToBuilder(b, nl, vFmtRaceHdr, strconv.FormatBool(isRace))
stringutil.WriteToBuilder(b, nl, vFmtRaceHdr, strconv.FormatBool(isRace))
info, ok := debug.ReadBuildInfo()
if !ok {
@@ -175,10 +175,10 @@ func Verbose() (v string) {
return b.String()
}
aghstrings.WriteToBuilder(b, nl, vFmtDepsHdr)
stringutil.WriteToBuilder(b, nl, vFmtDepsHdr)
for _, dep := range info.Deps {
if depStr := fmtModule(dep); depStr != "" {
aghstrings.WriteToBuilder(b, nltb, depStr)
stringutil.WriteToBuilder(b, nltb, depStr)
}
}

View File

@@ -4,7 +4,25 @@
## v0.107: API changes
### Client IDs in Access Settings
### The new field `"cache_optimistic"` in DNS configuration
* The new optional field `"cache_optimistic"` in `POST /control/dns_config`
method makes AdGuard Home use or not use the optimistic cache mechanism.
* The new field `"cache_optimistic"` in `GET /control/dns_info` method is true
if AdGuard Home uses the optimistic cache mechanism.
### New possible value of `"interval"` field in `QueryLogConfig`
* The value of `"interval"` field in `POST /control/querylog_config` and `GET
/control/querylog_info` methods could now take the value of `0.25`. It's
equal to 6 hours.
* All the possible values of `"interval"` field are enumerated.
* The type of `"interval"` field is now `number` instead of `integer`.
### Client IDs in Access Settings
* The `POST /control/access/set` HTTP API now accepts client IDs in
`"allowed_clients"` and `"disallowed_clients"` fields.

View File

@@ -4,7 +4,7 @@
'description': >
AdGuard Home REST-ish API. Our admin web interface is built on top of this
REST-ish API.
'version': '0.105'
'version': '0.107'
'contact':
'name': 'AdGuard Home'
'url': 'https://github.com/AdguardTeam/AdGuardHome'
@@ -1322,6 +1322,8 @@
'type': 'integer'
'cache_ttl_max':
'type': 'integer'
'cache_optimistic':
'type': 'boolean'
'upstream_mode':
'enum':
- ''
@@ -2008,8 +2010,15 @@
'type': 'boolean'
'description': 'Is query log enabled'
'interval':
'type': 'integer'
'description': 'Time period to keep data (1 | 7 | 30 | 90)'
'description': >
Time period for query log rotation.
'type': 'number'
'enum':
- 0.25
- 1
- 7
- 30
- 90
'anonymize_client_ip':
'type': 'boolean'
'description': "Anonymize clients' IP addresses"

View File

@@ -4,29 +4,32 @@ set -e -f -u
# Show all temporary todos to the programmer but don't fail the commit
# if there are any, because the commit could be in a temporary branch.
git grep -e 'TODO.*!!' -- ':!HACKING.md' ':!scripts/hooks/pre-commit' | cat || :
git grep -e 'TODO.*!!' -- ':!scripts/hooks/pre-commit' | cat || :
verbose="${VERBOSE:-0}"
readonly verbose
if [ "$( git diff --cached --name-only -- 'client/*.js' )" ]
then
make js-lint js-test
make VERBOSE="$verbose" js-lint js-test
fi
if [ "$( git diff --cached --name-only -- 'client2/*.js' 'client2/*.ts' 'client2/*.tsx' )" ]
then
make js-beta-lint js-beta-test
make VERBOSE="$verbose" js-beta-lint js-beta-test
fi
if [ "$( git diff --cached --name-only -- '*.go' '*.mod' '*.sh' 'Makefile' )" ]
then
make go-os-check go-lint go-test
make VERBOSE="$verbose" go-os-check go-lint go-test
fi
if [ "$( git diff --cached --name-only -- '*.md' '*.yaml' '*.yml' )" ]
then
make txt-lint
make VERBOSE="$verbose" txt-lint
fi
if [ "$( git diff --cached --name-only -- './openapi/openapi.yaml' )" ]
then
make openapi-lint
make VERBOSE="$verbose" openapi-lint
fi

View File

@@ -467,7 +467,7 @@ handle_existing() {
return 0
fi
if [ "$( ls -1 -A -q $agh_dir )" != '' ]
if [ "$( ls -1 -A $agh_dir )" != '' ]
then
log 'the existing AdGuard Home installation is detected'

View File

@@ -33,18 +33,21 @@ COPY --chown=nobody:nogroup\
RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome
# 53 : DNS
# 67, 68 : DHCP
# 80 : HTTP
# 443 : HTTPS, DNS-over-HTTPS, DNSCrypt
# 853 : DNS-over-TLS
# 3000 : HTTP alt
# 3001 : HTTP beta
# 5443 : DNSCrypt alt
# 6060 : HTTP pprof
# 8853 : DNS-over-QUIC
EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 443/udp 853/tcp\
3000/tcp 3001/tcp 5443/tcp 5443/udp 6060/tcp 8853/udp
# 53 : TCP, UDP : DNS
# 67 : UDP : DHCP (server)
# 68 : UDP : DHCP (client)
# 80 : TCP : HTTP (main)
# 443 : TCP, UDP : HTTPS, DNS-over-HTTPS (incl. HTTP/3), DNSCrypt (main)
# 784 : UDP : DNS-over-QUIC (experimental)
# 853 : TCP, UDP : DNS-over-TLS, DNS-over-QUIC
# 3000 : TCP, UDP : HTTP(S) (alt, incl. HTTP/3)
# 3001 : TCP, UDP : HTTP(S) (beta, incl. HTTP/3)
# 5443 : TCP, UDP : DNSCrypt (alt)
# 6060 : TCP : HTTP (pprof)
# 8853 : UDP : DNS-over-QUIC (experimental)
EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 443/udp 784/udp\
853/tcp 853/udp 3000/tcp 3000/udp 3001/tcp 3001/udp 5443/tcp\
5443/udp 6060/tcp 8853/udp
WORKDIR /opt/adguardhome/work

View File

@@ -73,11 +73,31 @@ esac
# Simple Analyzers
# blocklist_imports is a simple check against unwanted packages. Package
# io/ioutil is soft-deprecated. Packages errors and log are replaced by our own
# packages in the github.com/AdguardTeam/golibs module.
# blocklist_imports is a simple check against unwanted packages. The following
# packages are banned:
#
# * Package io/ioutil is soft-deprecated.
#
# * Packages errors and log are replaced by our own packages in the
# github.com/AdguardTeam/golibs module.
#
# * Package reflect is often an overkill, and for deep comparisons there are
# much better functions in module github.com/google/go-cmp. Which is
# already our indirect dependency and which may or may not enter the stdlib
# at some point.
#
# See https://github.com/golang/go/issues/45200.
#
# * Package unsafe is… unsafe.
#
blocklist_imports() {
git grep -F -e '"errors"' -e '"io/ioutil"' -e '"log"' -- '*.go' || exit 0;
git grep\
-e '[[:space:]]"errors"$'\
-e '[[:space:]]"io/ioutil"$'\
-e '[[:space:]]"log"$'\
-e '[[:space:]]"reflect"$'\
-e '[[:space:]]"unsafe"$'\
-- '*.go' || exit 0;
}
# method_const is a simple check against the usage of some raw strings and
@@ -181,8 +201,7 @@ gocyclo --over 17 ./internal/dhcpd/ ./internal/dnsforward/\
# Apply stricter standards to new or vetted code
gocyclo --over 10 ./internal/aghio/ ./internal/aghnet/ ./internal/aghos/\
./internal/aghstrings/ ./internal/aghtest/ ./internal/tools/\
./internal/version/ ./main.go
./internal/aghtest/ ./internal/tools/ ./internal/version/ ./main.go
gosec --quiet $go_files