Compare commits

..

91 Commits

Author SHA1 Message Date
Ainar Garipov
2c9dcc12ff Pull request 1976: upd-all
Squashed commit of the following:

commit 13300d57c5f01109fff7d61751dd369c05a45b8d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Aug 24 14:10:43 2023 +0300

    all: upd deps, filters, i18n, svcs, trackers
2023-08-24 14:30:19 +03:00
Stanislav Chzhen
6fea7099a2 Pull request 1967: AG-24794-imp-arpdb
Squashed commit of the following:

commit 6f6f6cc5d9b9ae04e369e0b789aaab74f234e6a0
Merge: 9aa3ac58c 8fb76701f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 24 13:29:47 2023 +0300

    Merge branch 'master' into AG-24794-imp-arpdb

commit 9aa3ac58c76fc4b2f950a988d63dfebd0652e507
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 16:14:02 2023 +0300

    scripts: gocognit: add arpdb

commit e99b0534be1891de1c13f4010beeedb4459ccd7c
Merge: 84893bc2d 3722c2846
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 16:08:25 2023 +0300

    Merge branch 'master' into AG-24794-imp-arpdb

commit 84893bc2d3018c9ee1e411578b33cdb6ba6d3d81
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 16:07:43 2023 +0300

    arpdb: add todo

commit ad4b3689b51324521bf47c478c61b6008332b4f5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 14:02:07 2023 +0300

    arpdb: imp code

commit 9cdd17dadbb91ccc3f8e79ba7a21bc365647e089
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Aug 18 19:05:10 2023 +0300

    all: imp arpdb
2023-08-24 13:42:17 +03:00
Ainar Garipov
8fb76701f4 Pull request 1974: 6133-upd-quic-go
Updates #6133.

Squashed commit of the following:

commit cb096e3cdef8e85fa3a27e3bb3065317aaa29048
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 23 19:41:04 2023 +0300

    openapi: imp chlog

commit 623594f95d4be3a03e451849f7b1b5181785aeeb
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 23 19:25:47 2023 +0300

    all: upd quic-go, txt-lint
2023-08-23 20:10:54 +03:00
Eugene Burkov
2b9019313b Pull request 1973: 6132 fix hosts stratup
Merge in DNS/adguard-home from 6132-fix-hosts-startup to master

Updates #6132.

Squashed commit of the following:

commit 7495e62531f7c0bd775969195da1cbd446f018f7
Merge: c5d99bcef 4b04c620f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 18:50:14 2023 +0300

    Merge branch 'master' into 6132-fix-hosts-startup

commit c5d99bcefa870ba0d2543158e97b3001f65be459
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 18:01:17 2023 +0300

    filtering: fix hosts results

commit b7acf266ad73520a0b795c495c8fc75c547ed993
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 17:34:43 2023 +0300

    all: revert changes of log of changes

commit 293240d5b1277cebd26732c535ad004af76df532
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 17:30:07 2023 +0300

    aghnet: imp logs

commit d1f7d73477a1a8fed5b1fb8b7f42d1c92acd919c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 17:19:54 2023 +0300

    aghnet: impl handle set

commit b643793c537fcdd4ba00bae4d7207cb4f1d60d80
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 17:00:05 2023 +0300

    aghnet: fix initial refresh
2023-08-23 18:57:24 +03:00
Stanislav Chzhen
4b04c620f2 Pull request 1963: AG-24051-stats-collector
Updates #6108.

Squashed commit of the following:

commit ca584c8dbbece70b90f6298a0a18a933a698fcf6
Merge: b6e136232 28cfde921
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 17:00:52 2023 +0300

    Merge branch 'master' into AG-24051-stats-collector

commit b6e136232dd619ce09150b608ae5017676031e25
Merge: bbd4780b0 3722c2846
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 23 16:25:45 2023 +0300

    Merge branch 'master' into AG-24051-stats-collector

commit bbd4780b03a1c954fe2b349d27f1ab3bf7739518
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 22 17:47:51 2023 +0300

    stats: imp test

commit cfe3b9bdf5fd75bff98f985884b3bff8a88ae8ee
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 22 16:57:31 2023 +0300

    stats: add test

commit cb579a157056f79c1c3d08479a718698a74e0bb9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Aug 21 15:24:40 2023 +0300

    stats: imp docs

commit 3c6ab3affb9ac402db7e3cc3d9696154770e1037
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 17 14:41:35 2023 +0300

    stats: imp code

commit 125a31b73bb31f7f4886daad9ce7e3bbc97b38c9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 16 12:29:10 2023 +0300

    stats: imp test

commit 1ba1eb3b7bd540621bf17ca50d4c2ba4bc55a9f8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 15 19:57:34 2023 +0300

    stats: add test

commit 46622f4fdf2775ddaba626b9786af183680e8889
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 15 15:47:06 2023 +0300

    stats: rm stats collector
2023-08-23 17:09:42 +03:00
Eugene Burkov
28cfde9212 Pull request 1966: 6050 upd urlfilter
Merge in DNS/adguard-home from upd-urlfilter to master

Updates #6050.

Squashed commit of the following:

commit 80337ab02d616e25fa455e46c9535c088b5c5ea5
Merge: fb2cfd1a5 31f7aaecc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 16:50:49 2023 +0300

    Merge branch 'master' into upd-urlfilter

commit fb2cfd1a5c94d92030fc8832615764f100d010e5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 23 16:22:43 2023 +0300

    dnsforward: imp code, docs

commit 2900333bb85d4e064db9de27bd5bfe7c3ef00747
Merge: 977ed35e4 2bfc9fcb1
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 18:06:05 2023 +0300

    Merge branch 'master' into upd-urlfilter

commit 977ed35e4ed377f1031721d58e0fcb58de1e74ac
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 17:06:30 2023 +0300

    all: log changes

commit 1228a0770485799bf50bbe68005dbb0ba9a96a9c
Merge: 78305eb2e 4b4036fa6
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 16:51:42 2023 +0300

    Merge branch 'master' into upd-urlfilter

commit 78305eb2ebc3854dd11ce35d6b4c7eecccd7cc78
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 15:55:05 2023 +0300

    all: upd urlfilter

commit 63a29e18d5034e5f9433121ff7e7c45aebfa1f0f
Merge: 748c53430 762e5be97
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 21 20:12:49 2023 +0300

    Merge branch 'master' into upd-urlfilter

commit 748c5343020b0c6d4d4f16eb3d30b875c0a94e0f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 21 20:07:44 2023 +0300

    all: imp code, docs

commit 91975140f3305a6793e07142f7c9a75120a4ce8c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 17 16:16:19 2023 +0300

    all: upd urlfilter
2023-08-23 16:58:24 +03:00
Dimitry Kolyshev
31f7aaecc3 Pull request : 6126-client: boostrap dns
Merge in DNS/adguard-home from 6126-bootstrap-dns to master

Squashed commit of the following:

commit 024e0280fb12f36e9d151132d1042c6c3c78615b
Merge: f2be5189d 3722c2846
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 23 16:09:48 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6126-bootstrap-dns

commit f2be5189da339830cbbef4dfc0399d23b4284320
Merge: 311429086 2bfc9fcb1
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 23 15:56:30 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6126-bootstrap-dns

commit 3114290863f8d50f144ca519f396a7509897ed4a
Merge: 332e28730 cb6d4620c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 17:33:20 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6126-bootstrap-dns

commit 332e2873056771d2ba30188891e2b03ee0cb6cd6
Author: Shared Content Manager account <translate@adguard.com>
Date:   Tue Aug 22 17:32:28 2023 +0300

    client: imd texts

commit 83162fc835580e08bced3c70ebdc37ef139d0f38
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 16:29:41 2023 +0300

    client: boostrap dns
2023-08-23 16:37:35 +03:00
Ainar Garipov
3722c28464 Pull request 1972: fix-snap-upload
Squashed commit of the following:

commit 6d028abb64ef08b3678e8dc55942433308f98819
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 23 14:57:26 2023 +0300

    scripts: fix snap upload
2023-08-23 16:08:00 +03:00
Eugene Burkov
2bfc9fcb12 Pull request 1971: fix hosts windows
Merge in DNS/adguard-home from fix-hosts-windows to master

Squashed commit of the following:

commit 8e080ade8980f73006eb33de930749b91d203915
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 17:49:23 2023 +0300

    aghnet: fix src path
2023-08-22 18:03:32 +03:00
Dimitry Kolyshev
cb6d4620c5 Pull request: 6122-dnsforward: ipv6 hints filtering
Merge in DNS/adguard-home from 6122-ipv6hints-filtering to master

Squashed commit of the following:

commit 4c0923de9110ebd5dac28dbfbffeb7f834d7c567
Merge: b1ba1a9a8 4b4036fa6
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 17:00:46 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6122-ipv6hints-filtering

commit b1ba1a9a8641ae846d0360bd50115153ff7c3b19
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 15:56:45 2023 +0300

    client: disable ipv6

commit 34f2a19aaec0928e83469945d807d9339715d671
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 15:16:27 2023 +0300

    client: disable ipv6

commit e0387597f81163c9e76bcf20307099c1ca72ca22
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 15:11:45 2023 +0300

    dnsforward: imp code

commit 22cdac4516759edbc6a81dd7636f0170fa669071
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 22 13:59:22 2023 +0300

    dnsforward: ipv6 hints filtering
2023-08-22 17:18:35 +03:00
Eugene Burkov
4b4036fa6a Pull request 1964: AG-23599 use hostsfile
Merge in DNS/adguard-home from AG-23599-use-hostsfile to master

Squashed commit of the following:

commit 4766e67a9d5faa4bc89a2a935d187ce4829f7214
Merge: 38369360b 762e5be97
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Aug 22 16:33:54 2023 +0300

    Merge branch 'master' into AG-23599-use-hostsfile

commit 38369360b7d0e5c9ec373c5a06bac8792ca9cd69
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 21 18:09:15 2023 +0300

    filtering: imp tests

commit 1c4d4a9f9639f048173e1c949f39f9ecb6ed0347
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 21 14:00:10 2023 +0300

    filtering: imp cognit, cyclo

commit c50c33d7240c2812a715759fabf140e02184b729
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 21 12:57:31 2023 +0300

    filtering: imp code

commit 92203b16719a717a2946c0401e166b1b38ddb7bc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Aug 18 17:39:11 2023 +0300

    all: imp code, docs

commit 523e8cd50f9136feede657385b7274fa6ba64131
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 17 15:14:02 2023 +0300

    all: fix ipv6

commit 6ce4537132615cbdc34a0b1f326fedd2b63c355d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 17 14:17:27 2023 +0300

    all: rm urlfilter from hosts

commit d6666e851680c7e586325ea5970e0356ab919074
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 16 15:09:52 2023 +0300

    WIP

commit 4a2732960558bef6636d3c428bad4c7c830016ca
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 16 14:47:13 2023 +0300

    all: use hostsfile
2023-08-22 16:45:11 +03:00
Ainar Garipov
762e5be97a Pull request 1968: fix-gocognit
Squashed commit of the following:

commit 72b089044e8584ad7d0ed88c5b7e0eb8a39ed9b6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Aug 21 19:48:07 2023 +0300

    all: fix gocognit; upd tools
2023-08-21 19:56:08 +03:00
Stanislav Chzhen
ff341bd7cf Pull request 1965: 3701-fallback-dns
Updates #3701.

Squashed commit of the following:

commit 5801acd3a919a55be6cb1de3b5c8afb61d5136d8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Aug 21 13:37:57 2023 +0300

    all: upd chlog

commit 5c40913f76131854d321950f80ae9d5b78e56d9d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 17 13:15:19 2023 +0300

    dnsforward: add fallback dns servers
2023-08-21 19:34:02 +03:00
Ainar Garipov
05262d7b6b Pull request 1962: upd-code-deps
Squashed commit of the following:

commit 7a24cf8f9c5515f642cbfc7e730b95005eeab11d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 15 14:54:16 2023 +0300

    all: upd code, deps, tools
2023-08-15 15:09:08 +03:00
Stanislav Chzhen
887c48cee8 Pull request 1961: 6106-fix-dns-filter
Updates #6106.

Squashed commit of the following:

commit e06ae2195c9231901dda76b7afc00f45021ee369
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 15 14:13:15 2023 +0300

    dnsforward: add docs

commit c9d77fa04b4d358593e492a9abdca94053ace631
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 15 14:02:32 2023 +0300

    dnsforward: fix dns filter
2023-08-15 14:29:08 +03:00
Dimitry Kolyshev
85e87b9c1d Pull request: 6093-log-conf
Updates #6093.

Squashed commit of the following:

commit f3478b9ad30a025b2a4044ab4ca54517568c833d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 15:27:51 2023 +0300

    home: imp code

commit 07b51d83eb1491f33ef959406495f3154aadd774
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 15:18:00 2023 +0300

    all: imp docs

commit 4892c8673af738d9f1b2abd5b1da854f60439bcf
Merge: 7cb376c95 c54635e8a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 13:57:02 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6093-log-conf

commit 7cb376c953222437aba67120ab14f74341260b20
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 12:48:26 2023 +0300

    all: docs

commit 89f0d46bd99cebde234e56db6867fdf371d8191b
Merge: 67c776763 94cf50a53
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 12:46:26 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6093-log-conf

commit 67c7767631da510bcb05856a6556fb6aff172fda
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 12:39:26 2023 +0300

    home: log conf
2023-08-14 18:53:05 +03:00
Dimitry Kolyshev
c54635e8a1 Pull request: 6020-rulelist-name
Updates #6020.

Squashed commit of the following:

commit fedb9415fb40d103261ca9b966c3d634692f899d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 12:45:06 2023 +0300

    filtering: imp tests

commit d85d193ca7808e9089fa8ac3b26652f9c88c44ad
Merge: f1c1eddc1 94cf50a53
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 11:07:39 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6020-rulelist-name

commit f1c1eddc113d2659adb666d7849ce0830eaf71f0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 10:59:07 2023 +0300

    filtering: imp tests

commit 39e9d546dc2438409607ffebe414e9d656275504
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 11 10:02:48 2023 +0300

    filtering: imp code

commit 230f15ddad95c670e93c58db6d9928c3d0e0b79b
Merge: 1940fb397 111005b8d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 15:03:08 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6020-rulelist-name

commit 1940fb3973344a7d1ab8acfdc9401ed41fe0e666
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 15:01:57 2023 +0300

    all: docs

commit 810f6d17968873ce489b2e24f496d31179675e37
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 15:00:59 2023 +0300

    filtering: imp code

commit f310dd2281dc81cd816701696cf1bb289b4fb708
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 12:19:55 2023 +0300

    client: flt name

commit 9494771c57c464dbe5117315efdb3104b977bac4
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 12:18:57 2023 +0300

    filtering: flt name
2023-08-11 13:55:49 +03:00
Eugene Burkov
94cf50a53d Pull request 1955: Upd libraries
Merge in DNS/adguard-home from upd-libs to master

Squashed commit of the following:

commit 72f4fb7d5ab8eaecb917a843dec56e3fa38b725c
Merge: 8defe106f 111005b8d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 10 19:50:33 2023 +0300

    Merge branch 'master' into upd-libs

commit 8defe106fc982ba916f42d5722f1cc0152042d04
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Aug 10 19:38:01 2023 +0300

    dnsforward: revert behavior

commit 8ccb2f675373772f8a6f829b80b317fda0c5f730
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 9 18:35:12 2023 +0300

    all: imp code

commit a3112d3438a466bae515e56a6ee97394066ba481
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 9 17:26:52 2023 +0300

    filtering: revert type

commit 56d2528fb4c8ee5504de0c6ec24050d63c8e6330
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 9 14:57:04 2023 +0300

    stats: fix sort

commit 0dbb446602b7536df508a8e53c4a532455c9d064
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 9 14:52:28 2023 +0300

    all: upd golibs & dnsproxy
2023-08-10 20:00:17 +03:00
Dimitry Kolyshev
111005b8d4 Pull request: AG-18118-bamboo-artifacts
Squashed commit of the following:

commit 217790cf2ab0adf3df9f24f1f40c2bc9a310b7ee
Merge: c5226c823 418c830e5
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 14:45:59 2023 +0300

    Merge remote-tracking branch 'origin/master' into AG-18118-bamboo-artifacts

commit c5226c823afba20abb9cc0db028ef232a40171a3
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 12:35:35 2023 +0300

    all: bamboo artifacts

commit c540cc3a92b8d1cfc48e0c36be0f0e4f1600d9bf
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 12:25:40 2023 +0300

    all: bamboo artifacts

commit b6aa24b00e2baff16a3aab45eca737391ef9cf90
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 11:07:02 2023 +0300

    all: revert bamboo expire conf

commit abf46235baf7d7de71cf89d2ae9e14290eaecc39
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 10:55:44 2023 +0300

    all: bamboo artifacts

commit 77bd6e0aa06cfa4e5364abca4a8e19d2308ee9f0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 09:49:57 2023 +0300

    all: bamboo artifacts

commit 37aea65e0c2a5a77a02dd927aa3c52937988a2f7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Aug 10 09:41:48 2023 +0300

    all: bamboo artifacts

commit d26c50960a12c3db62ff54d69d16cd6d3c0d2ee9
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 17:20:20 2023 +0300

    all: bamboo artifacts

commit 3afc5be520ac2c11196ac6a8b58e112ec140a760
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 17:09:04 2023 +0300

    all: bamboo artifacts

commit 2ecf440fbff7feb837a4cf650d105e83d2b5efed
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 17:00:22 2023 +0300

    all: bamboo artifacts

commit 2f1c4a1c712bd900d0b1c86db9c343ccd1b9dfaa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 16:26:23 2023 +0300

    all: bamboo artifacts
2023-08-10 15:02:55 +03:00
Ainar Garipov
418c830e53 Pull request 1957: 1453-fix-stats-table
Updates #1453.

Squashed commit of the following:

commit 81105a53a588e6c5d3e16e8ded955b6462a94b7c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 9 17:51:42 2023 +0300

    client: fix total for upstream table
2023-08-09 18:44:42 +03:00
Dimitry Kolyshev
1e939703e5 Pull request: 6053-https-filtering
Updates #6053.

Squashed commit of the following:

commit b71957f87eca93e9827d027c246d2ca9d7a7f45a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 16:12:10 2023 +0300

    all: docs

commit 3e394fb2d723c4e305ea91f10fffc866f0b9948a
Merge: f406a5ff4 c47509fab
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 15:15:37 2023 +0300

    all: imp code

commit f406a5ff4977acdcd19557969bd405747b84ebbc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 15:05:43 2023 +0300

    all: imp code

commit 0de1e0e8a9f0dfd3a0ff0c9e787d6e50cf2a1ee8
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 14:45:21 2023 +0300

    all: docs

commit d98cbafe62edd77afcf6c760e28cb5e7632a993e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 11:54:39 2023 +0300

    dnsforward: https blocked rcode

commit c13ffda6182920f97fe8293a9c0b518bbf77956e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 10:45:27 2023 +0300

    dnsforward: imp tests

commit 9c5bc29b33d53ba82ca11f508391e5b5d534a834
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 9 10:08:06 2023 +0300

    dnsforward: imp code

commit d6ff28b9c277c24b4f273cd4b292543ead13d859
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 8 16:00:15 2023 +0300

    all: imp code

commit 832b59965d1515badd0a0650f9753fc2985dff1c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 8 13:32:15 2023 +0300

    dnsforward: https filtering

commit 6a2bdd11331ffddb13bac4e05de85b6661360783
Merge: 257a1b6b8 54aee2272
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 8 11:44:12 2023 +0300

    Merge remote-tracking branch 'origin/master' into 6053-https-filtering

    # Conflicts:
    #	CHANGELOG.md

commit 257a1b6b868826cb4112c1c88b177290242d3fdd
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 8 11:26:13 2023 +0300

    dnsforward: imp tests

commit edba217a72101b8b5a79e7b82614b3ea0e4c1f09
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 4 15:03:02 2023 +0300

    dnsforward: https filtering

commit 4c93be3e0c7b98c1242b60ba5a3c45cea2775be4
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 4 14:36:33 2023 +0300

    docs: https filtering

commit 1d2d1aa3b4ce7a994395fade2f87b2d88d68ac63
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Aug 4 12:54:05 2023 +0300

    all: https filtering hints
2023-08-09 16:27:21 +03:00
Stanislav Chzhen
c47509fabc Pull request 1928: 1453-stats-tests
Updates #1453.

Squashed commit of the following:

commit f08f68ef5493dad03d3eb120d886f2df1af28be6
Merge: b70b088af 54aee2272
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 8 19:04:06 2023 +0300

    Merge branch 'master' into 1453-stats-tests

commit b70b088af0fdc7d6d048d688160048bad1fceb12
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 3 19:32:04 2023 +0300

    stats: imp code

commit c341012ba61894c255c1868624be1cac0d26a6fa
Merge: a2ac8c34e 5eb3cd0f9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 3 13:36:24 2023 +0300

    Merge branch 'master' into 1453-stats-tests

commit a2ac8c34ee32606ca5e259c3e2a47db0dd5858de
Author: Ildar Kamalov <ik@adguard.com>
Date:   Thu Aug 3 13:25:12 2023 +0300

    client: add top upstreams and average processing time tables

commit 11118947f9bf945be0b056f8475cf3b848c6e66e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Aug 1 17:24:57 2023 +0300

    stats: imp docs

commit 904cf81d02a1f327b9647fa7ad9e181cfabb68a4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 31 17:34:06 2023 +0300

    stats: imp code

commit 34f0c96dd5865d1470385322a88842dd0b3d996d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 31 15:43:46 2023 +0300

    all: imp docs

commit 2cb2d0d8bef3580f64bc25c414fe9b5ea6b9f997
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jul 28 17:24:31 2023 +0300

    all: imp code

commit 5251a899fecc21e50a0ba06042f96f5b404e196a
Merge: b6c2b12d4 300821a7f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 27 20:34:39 2023 +0300

    Merge branch 'master' into 1453-stats-tests

commit b6c2b12d4425012efd73549c3a426735f3a677cd
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 27 20:32:18 2023 +0300

    stats: imp code

commit 5546b82a78326f9cc6d8c87df5083f8fc66a0178
Merge: 8a3d6b1b4 5f8fa006c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 27 14:24:01 2023 +0300

    Merge branch 'master' into 1453-stats-tests

commit 8a3d6b1b49ce189f95adfa7406a34108e885e676
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 27 14:17:47 2023 +0300

    all: imp code

commit 2a48001e275e3cdcf70e13e1c9cebd4e502f3259
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 25 18:27:20 2023 +0300

    all: imp docs

commit 3dd21890175af32a3368378f7e013383f6d040ec
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 25 16:00:39 2023 +0300

    all: imp naming

commit 6124456fc3149b71f6bd58d35ecf24eb6cf40d5d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 20 16:15:56 2023 +0300

    all: add upstreams avg processing time

commit 187ad0c77a81c9fd95c24e23141355db2e83e50d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 18 16:42:19 2023 +0300

    all: add top upstreams
2023-08-09 14:33:52 +03:00
Eugene Burkov
54aee22720 Pull request 1954: upd urlfilter
Merge in DNS/adguard-home from upd-urlfilter to master

Squashed commit of the following:

commit e3f1e9c818e8627ee827e9d7383b4a7985ee24aa
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 7 17:05:19 2023 +0300

    all: log changes

commit 541faedad84f45da58303772675b0da32d170c39
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Aug 7 16:15:38 2023 +0300

    all: upd urlfilter
2023-08-07 17:14:20 +03:00
Stanislav Chzhen
93a0601f41 Pull request 1952: 5948-fix-dns-filter
Updates #5948.

Squashed commit of the following:

commit 9dbc197f004a19211e5fedeb9bdd7075e2915fce
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Aug 7 15:06:38 2023 +0300

    all: imp chlog

commit fbcccc2ff3663fc8ae0cd75ef6ac4cdcc0fa7d36
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 3 16:58:35 2023 +0300

    all: upd chlog

commit 4f9e8fcbfb4d43fd98a99529f20e9d40946ee5c1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Aug 2 19:24:42 2023 +0300

    dnsforward: fix dns filter
2023-08-07 16:07:21 +03:00
Dimitry Kolyshev
5eb3cd0f92 Pull request 1947: AG-24320 home: pprof conf
Squashed commit of the following:

commit bc0facffe41e140fab00edeeeca3b69306cf2ceb
Merge: 71e0806ba c0691cab6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 2 17:34:15 2023 +0300

    Merge branch 'master' into pprof-conf

commit 71e0806bac52412cae7cad2748216ece7fbed36f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Aug 2 08:37:51 2023 +0300

    all: docs

commit 6ebb6f9a5f4dbeb753dd470879f2e5ff556ee5f1
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 1 15:56:45 2023 +0300

    home: imp code

commit ca084011cddc20f5c0b770ee38f9ac55d62bff24
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 1 13:57:53 2023 +0300

    all: docs

commit 1b498a84d6cb8207d350fceb4db64d45dc2aa46d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 1 13:46:13 2023 +0300

    all: docs

commit 0cd76c057e0f3e9e62e5bf38f95080afa830f4ff
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Aug 1 13:00:43 2023 +0300

    home: pprof conf
2023-08-02 17:39:33 +03:00
Ainar Garipov
c0691cab6a Pull request 1951: upd-chlog
Squashed commit of the following:

commit 6b727dbc2b8f09765f63a983abf5b83c1340149c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 2 17:11:38 2023 +0300

    all: upd chlog
2023-08-02 17:17:25 +03:00
Ainar Garipov
c0c152885d Pull request 1950: upd-all
Squashed commit of the following:

commit 6e17dd9bf96fd684bd2ff28285ff9ef6534641e9
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 2 14:59:19 2023 +0300

    all: upd i18n, svcs, trackers
2023-08-02 15:58:05 +03:00
Ainar Garipov
a6c5cab218 Pull request 1949: upd-go
Squashed commit of the following:

commit d850dc74a5f36797bd2270c011fe0525adbf9d14
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Aug 2 13:15:01 2023 +0300

    all: upd go, tools
2023-08-02 13:25:04 +03:00
Ainar Garipov
fe0edc0065 Pull request 1948: imp-test
Squashed commit of the following:

commit d2e61b0a2406a503d9d7bcd12612ed7e04c1fac6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 1 18:02:29 2023 +0300

    client: imp addrproc test

commit f7cf0fb1549299b00fdbe400bb4a96c73530bfe0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Aug 1 17:23:12 2023 +0300

    dnsforward: rm mutex
2023-08-01 19:10:41 +03:00
Andrey Meshkov
2cbc5e5f9d Pull request 1946: Unix --> Linux/Unix/MacOS
Merge in DNS/adguard-home from fix-readme-unix to master

Squashed commit of the following:

commit c51fbed552876d3298480aad2f7382585c036091
Author: Andrey Meshkov <am@adguard.com>
Date:   Mon Jul 31 16:16:52 2023 +0300

    Added bsd

commit 30bee72bcf6f629b3f1871ddb6181fd2f4d1f7fa
Author: Andrey Meshkov <am@adguard.com>
Date:   Sun Jul 30 17:47:53 2023 +0300

    Unix --> Linux/Unix/MacOS
2023-07-31 16:31:03 +03:00
Stanislav Chzhen
5d900bdaa4 Pull request 1942: AG-24087-opts-root-cas
Squashed commit of the following:

commit 60db425504fce9743d46cfc0d155364fa5a1e77e
Merge: c589343e7 79306cb48
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jul 28 19:43:01 2023 +0300

    Merge branch 'master' into AG-24087-opts-root-cas

commit c589343e7b1db6f66c3890fd2caff755fcf92d08
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 27 14:59:23 2023 +0300

    all: upd dnsproxy
2023-07-28 19:50:53 +03:00
Ainar Garipov
79306cb48a Pull request 1944: 6049-block-ns-root
Updates #6049.

Squashed commit of the following:

commit 288a486b741b4dc57769bd5a0bdd67b4d75cc8c0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 27 20:59:14 2023 +0300

    dnsforward: fix blocking of ns root
2023-07-27 21:06:51 +03:00
Eugene Burkov
300821a7fb Pull request 1943: 6046 Local PTR
Merge in DNS/adguard-home from 6046-local-ptr to master

Updates #6046.

Squashed commit of the following:

commit 3e90815f29173d2f68970278bd7b1b29cc0a4465
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jul 27 18:17:41 2023 +0300

    all: log changes

commit 7639f6f785670c15911fb3ca20abeb4e2b8f8582
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jul 27 17:40:49 2023 +0300

    all: fix 0 ttl ptr
2023-07-27 18:23:23 +03:00
Ainar Garipov
5f8fa006cf Pull request 1941: upd-chlog-deps
Squashed commit of the following:

commit 1ede57bd8778a18a61823e046f78464fca2ecd3c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 26 16:06:13 2023 +0300

    all: upd chlog, deps
2023-07-26 16:24:46 +03:00
Ainar Garipov
9f3af37eb3 Pull request 1940: upd-all
Squashed commit of the following:

commit 1119a81fdbc0c2bad7845931e25109fa47a8b07b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 26 13:02:24 2023 +0300

    all: upd i18n, svcs, tools
2023-07-26 13:10:23 +03:00
Ainar Garipov
698b963e11 Pull request 1937: imp-filter-upd
Squashed commit of the following:

commit 6ce649c06398cf8a6f8e1a90f560fa8205f6500e
Merge: 1c6327e5d 996c6b3ee
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 25 17:42:01 2023 +0300

    Merge branch 'master' into imp-filter-upd

commit 1c6327e5d4c04393abc5d4d3e4b8568d4c6eca23
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 21 17:32:47 2023 +0300

    all: imp code; use renameio/v2 consistently

commit 1669288c9b662d1310f83a4e0d3f1f60731188cd
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 21 16:26:17 2023 +0300

    all: add renameioutil; imp flt upd
2023-07-25 17:47:24 +03:00
Stanislav Chzhen
996c6b3ee3 Pull request 1938: AG-24132-rdns-ttl
Squashed commit of the following:

commit ba1e7b12cf7c0dc3ffab508d59c149f6c0930548
Merge: 8a94433ec ed86af582
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 25 13:43:25 2023 +0300

    Merge branch 'master' into AG-24132-rdns-ttl

commit 8a94433ec119d2158c166dd0222f57917908f3ad
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 24 19:30:21 2023 +0300

    all: imp docs

commit 4c1a3676b7be7ac4295c4e28550ddb6eb79a35d4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 24 13:13:34 2023 +0300

    all: add rdns ttl
2023-07-25 14:16:26 +03:00
Ildar Kamalov
ed86af582a Pull request: fix invalid client tags after submit
Updates #6002

Squashed commit of the following:

commit 1129596eb460c0726f53c10ce1e4758833786984
Author: Ildar Kamalov <ik@adguard.com>
Date:   Mon Jul 24 16:09:52 2023 +0300

    client: fix invalid client tags after submit
2023-07-25 09:59:45 +03:00
Eugene Burkov
ac2ecaf4f5 Pull request 1936: fix-addr-proc
Merge in DNS/adguard-home from fix-addr-proc to master

Squashed commit of the following:

commit eb48be2aa4ceb27aa95c55034b35486d8f8d3c9e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jul 21 14:43:04 2023 +0300

    dnsforward: rm redundant precaution

commit c58f1464e2c72b79724217f6ec1445da4a4ee5f5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jul 21 14:40:09 2023 +0300

    all: revise the addr proc crutch

commit 8a01be9e1abe70268eff996460d2e56132462887
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jul 20 20:05:54 2023 +0300

    dnsforward: fix tests panic
2023-07-24 15:11:11 +03:00
Stanislav Chzhen
f9daf72c7e Pull request 1934: AG-24191-blocker-languages
Squashed commit of the following:

commit 00294be24c45724a9b2c7a14226dec9f0bf6d24e
Merge: ef96a6759 84a2991ac
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 20 19:45:31 2023 +0300

    Merge branch 'master' into AG-24191-blocker-languages

commit ef96a6759b29c8d30c58dfc787aff573b5c7d5e6
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 20 19:32:29 2023 +0300

    scripts: imp docs

commit d89b4a4e6a49e6fa3f010e7b8dfedf55cea149f0
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 20 19:05:38 2023 +0300

    scripts: imp code

commit bd4d3a68187099691d91c2736bf816333b843f00
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 20 17:54:39 2023 +0300

    scripts: add blocker languages
2023-07-20 19:52:14 +03:00
Ainar Garipov
84a2991ac2 Pull request 1935: upd-pprof
Squashed commit of the following:

commit 71d8936bddcf2d2b293015d3091df72aa1333270
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 20 18:48:08 2023 +0300

    next/websvc: fix pprof disabling

commit 30cc75d1eb89f7422555c18ad474324ab55eb13b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 20 18:30:29 2023 +0300

    all: upd golibs; add pprof to next
2023-07-20 18:57:06 +03:00
Ainar Garipov
5be0e84719 Pull request 1933: upd-golibs
Squashed commit of the following:

commit 081d10e6909def3a075707e75dbd0c5f63f91903
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 20 14:17:01 2023 +0300

    aghnet: fix docs

commit 7433b72c0653cb33fe5ff810ae8a1346a6994f95
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 20 14:03:16 2023 +0300

    all: imp tests; upd golibs
2023-07-20 14:26:35 +03:00
Ainar Garipov
4e8d3d7628 Pull request 1932: upd-all
Squashed commit of the following:

commit cac6e9a9bc9a3ed631a3e3d2d2f36174e6c0c415
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 19 16:56:35 2023 +0300

    all: upd flts, i18n, svcs, tools, trackers
2023-07-19 17:17:03 +03:00
Ainar Garipov
685d982924 Pull request 1930: fewer-globals
Squashed commit of the following:

commit ce882cfff4c1f7afdf0cba13b39e6ee568eb812f
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 19 15:56:52 2023 +0300

    all: imp code, lint

commit 96fc5c589e7474f4bba291b0a20a0834148bb9c1
Merge: 3e91eea6b b0185201c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 21:22:32 2023 +0300

    Merge branch 'master' into fewer-globals

commit 3e91eea6b68bac51251784e3069b1c9d241da439
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 19:01:45 2023 +0300

    home: rm globals
2023-07-19 16:57:57 +03:00
Ainar Garipov
b0185201c6 Pull request 1931: 6006-fix-cmdline-upd
Updates #6006.

Squashed commit of the following:

commit f974a08856b894fd586cfbba703d98dbcf8c6a97
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 20:51:58 2023 +0300

    home: fix cmdline update
2023-07-18 21:20:43 +03:00
Stanislav Chzhen
33ce24abe4 Pull request 1922: AG-23889-upd-dnsproxy
Merge in DNS/adguard-home from AG-23889-upd-dnsproxy to master

Squashed commit of the following:

commit ec61d4824946d28bf898d023d3321753273b7df3
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 19:09:32 2023 +0300

    all: imp code

commit 271f1ca0e6e583c829519cb0b5b24ab070e08933
Merge: 684c5aedc dee7c0681
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 17:54:52 2023 +0300

    Merge branch 'master' into AG-23889-upd-dnsproxy

commit 684c5aedc7206578f89b80932999e714506d5ce0
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jul 18 16:51:17 2023 +0300

    dnsforward: save prev proxy behavior

commit 9032c2179b941bec6d43b3e6bafdca5125a462b4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jul 17 17:45:10 2023 +0500

    dnsforward: use proxy ua

commit f658c031957fe45243e66a589ed32294e9aa4e27
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jul 17 17:37:03 2023 +0500

    dnsforward: fix private rdns ups conf for dns64

commit 70080e347dbc32cbdcb7d757514da13f865f8381
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 13 16:56:34 2023 +0300

    all: upd dnsproxy
2023-07-18 20:02:01 +03:00
Ainar Garipov
dee7c0681d Pull request 1929: fix-gh-tmpl
Squashed commit of the following:

commit 8ac1f14e422ad9a7cc0186e5ea18988613639240
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 17:04:36 2023 +0300

    .github: do not use md
2023-07-18 17:11:12 +03:00
Ainar Garipov
7bfad08dde Pull request 1927: 6006-use-address-processor
Updates #6006.

Squashed commit of the following:

commit ac27db95c12858b6ef182a0bd4acebab67a23993
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 15:47:17 2023 +0300

    all: imp code

commit 3936288512bfc2d44902ead6ab1bb5711f92b73c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 17 19:23:46 2023 +0300

    all: imp client resolving
2023-07-18 17:02:07 +03:00
Ainar Garipov
dead10e033 Pull request 1925: 6006-client-processor
Updates #6006.

Squashed commit of the following:

commit c72d6375e9c472c73b0bb9d025a8e197f404ba38
Merge: 02d64b10e 0cd441f04
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 18 13:56:26 2023 +0300

    Merge branch 'master' into 6006-client-processor

commit 02d64b10e19b2e937e45cab58d2310231a19bfbc
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 17 19:42:07 2023 +0300

    client: imp code, tests

commit b1613463089b4dde97484ff6a44b05888f0c2276
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 17 18:42:19 2023 +0300

    client: imp code, docs, tests

commit f71a17983b70d79839cf35dbe3279f0fdcac2ed7
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 14 21:53:47 2023 +0300

    all: add new client processor; imp code
2023-07-18 14:02:32 +03:00
Ainar Garipov
0cd441f04f Pull request 1926: imp-gh-tmpls
Squashed commit of the following:

commit 1a66a8af6aeb1b57507759b526d5adca2e8f7d1d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 17 17:09:45 2023 +0300

    .github: fix length

commit b9551cd5b09531cdb7887bd657a60459dd59259c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 17 16:58:48 2023 +0300

    all: imp gh tmpls, readme
2023-07-17 17:30:36 +03:00
Ainar Garipov
2adc8624c0 Pull request 1924: 6003-relax-rule-validation
Updates #6003.

Squashed commit of the following:

commit 1874860877662999d158631e3a25f8072c24f155
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 13 19:36:26 2023 +0300

    filtering/rulelist: imp test

commit 871a41af8039bf4d4fb139622d4296bcaff6729c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 13 19:10:35 2023 +0300

    filtering/rulelist: relax validation
2023-07-13 19:43:53 +03:00
Ainar Garipov
f22d893845 Pull request 1921: 6003-relax-scan-limit
Updates #6003.

Squashed commit of the following:

commit 1cc42303c29edc621802fc182ccb5701e412f099
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 13 13:47:41 2023 +0300

    all: fix chlog

commit e835084c7aac6384ea7b0886e6b3b1d614438baa
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 13 13:40:45 2023 +0300

    rulelist: imp longer line handling
2023-07-13 13:57:32 +03:00
Ainar Garipov
de63eeabfa Pull request 1920: 5985-client-text
Updates #5985.

Squashed commit of the following:

commit 925b55df066cb44eb37851491034f65727efcc79
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 20:39:04 2023 +0300

    client: imp text more

commit f4094eeeab01c168362366450169f7806faba198
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 20:24:33 2023 +0300

    client: fix text

commit 4e3a76da7c5f3d12716dbf5a9d5472e0c9b744c0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 20:22:31 2023 +0300

    client: imp runtime client text
2023-07-12 21:05:29 +03:00
Ainar Garipov
1aaffd1b72 Pull request 1919: rm-ports
Squashed commit of the following:

commit 892cb403112f8b816d99e645d7419bfd49ad3c33
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 17:30:28 2023 +0300

    docker: rm 784, 8853 ports
2023-07-12 17:52:29 +03:00
Ainar Garipov
eb97e7dc01 Pull request 1918: upd-chlog
Squashed commit of the following:

commit d5d21a8dd3ca892b8c9ba3d6c2154a99933d6dc3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 16:07:53 2023 +0300

    all: upd chlog
2023-07-12 16:14:23 +03:00
Stanislav Chzhen
55335c4061 Pull request 1908: AG-23497-scripts-download-languages
Squashed commit of the following:

commit 874e847fc9bbfaeb8af1c02eb0ba1dbb98bd008f
Merge: 4becdd809 a79deda66
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jul 12 16:01:45 2023 +0300

    Merge branch 'master' into AG-23497-scripts-download-languages

commit 4becdd8092558b15d783674f5b9d1e9c151e3a8c
Merge: 1e5385c33 40884624c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jul 12 13:34:34 2023 +0300

    Merge branch 'master' into AG-23497-scripts-download-languages

commit 1e5385c33a298b0b8563fee6704f6bb3ded12d60
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 11 19:56:29 2023 +0300

    all: upd golibs, imp code

commit 0498960b00be21b1294f8b71108b234554e5847f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jul 7 19:05:58 2023 +0300

    scripts: imp naming

commit 6e36ed83c6bec2fe6159442a9e6805c0720e27f5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 6 16:37:13 2023 +0300

    scripts: separate files

commit 55027cfa1c04b0a36e5267b024b53a45f26dd974
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jul 5 13:51:40 2023 +0300

    scripts: add download languages
2023-07-12 16:06:17 +03:00
Ainar Garipov
a79deda665 Pull request 1917: upd-go
Squashed commit of the following:

commit 72423458d6589027221d340a53af607622678b23
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 12 14:24:02 2023 +0300

    all: upd go
2023-07-12 14:37:05 +03:00
Ainar Garipov
40884624c2 Pull request 1916: 5990-root-ignore
Updates #5990.

Squashed commit of the following:

commit 1d5d3451c855681a631b85652417ee1bebadab01
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 11 20:11:45 2023 +0300

    all: allow ignoring root in querylog and stats
2023-07-11 20:42:40 +03:00
Ainar Garipov
0a1887a854 Pull request 1914: upd-flts
Squashed commit of the following:

commit a8932f56fad583ecfcb7efae36fc516454bc6610
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 11 16:20:55 2023 +0300

    filtering: fix docs; upd svcs
2023-07-11 16:27:20 +03:00
Dimitry Kolyshev
65b526b969 Pull request: 5972-ip-dupl-ans
Updates #5972.

Squashed commit of the following:

commit 0e089f9ff8fd7e6d7cb53aa7c3b92435d1d41a81
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 11 15:33:16 2023 +0300

    dnsforward: imp code

commit 39527c078fd9ad6ea4906659e185d54e74ef6465
Merge: 03641b0b5 61ed74374
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 11 11:29:19 2023 +0300

    Merge remote-tracking branch 'origin/master' into 5972-ip-dupl-ans

    # Conflicts:
    #	CHANGELOG.md

commit 03641b0b511f8e48d386be76d0a4776296cf047d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jul 10 14:03:28 2023 +0300

    all: dupl ips in answer
2023-07-11 15:46:01 +03:00
Ainar Garipov
61ed743748 Pull request 1913: parental-cache-size
Squashed commit of the following:

commit 6e7dcf0c59c478869e65cb6945d8d262b9eb1879
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 10 19:44:49 2023 +0300

    home: fix parental cache size
2023-07-10 20:00:29 +03:00
Ainar Garipov
c02a14117d Pull request 1912: 5896-safe-browsing-ptr
Updates #5896.

Squashed commit of the following:

commit 49340544a2a8762283397cdb54b91ed534591fa0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 10 17:59:45 2023 +0300

    hashprefix: fix loop pointer
2023-07-10 19:04:31 +03:00
Ainar Garipov
7b92d53b84 Pull request 1910: new-rulelist-parser
Squashed commit of the following:

commit bac0da6818388d67840b8fe9b633ce0804964ed9
Merge: cb6759b63 f7dd83251
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 7 18:22:40 2023 +0300

    Merge branch 'master' into new-rulelist-parser

commit cb6759b63546b35074ec0ae04769ddb5e83ebac1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 7 12:18:44 2023 +0300

    all: upd tools

commit d28bf4cb42057b84e0c1325389db121a91f7c989
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 6 19:35:48 2023 +0300

    all: upd chlog

commit 7df637b00331dff5810c3a76f4a7d2cee24148f1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 6 19:30:42 2023 +0300

    rulelist: fix tabs

commit 0598d0d43504b246570e9ee76d79dff0d86413c5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 6 19:06:18 2023 +0300

    all: add go-bench, go-fuzz; imp docs

commit a9ab7726048e216b13876a85991f3e3e8696a029
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jul 6 18:18:14 2023 +0300

    filtering: add new parser
2023-07-07 18:27:33 +03:00
Ainar Garipov
f7dd832517 Pull request 1909: 5939-rm-healthcheck
Updates #5939.

Squashed commit of the following:

commit 087309b4ef100e97339f49cf1c2e90ba2fa4293f
Merge: 360df813d c21f958ea
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jul 7 13:18:52 2023 +0300

    Merge branch 'master' into 5939-rm-healthcheck

commit 360df813d995f935c591aaea9c56fe4372ca2281
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jul 5 14:16:18 2023 +0300

    all: rm docker healthcheck
2023-07-07 13:58:15 +03:00
Stanislav Chzhen
c21f958eaf Pull request 1878: AG-22597-imp-rdns
Squashed commit of the following:

commit ccad155c34989943d88a0a260c50845d1f4ece6b
Merge: 0cd889f6a 5a195b441
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 6 17:00:58 2023 +0300

    Merge branch 'master' into AG-22597-imp-rdns

commit 0cd889f6a500f5616af0f8d8fdcde0403b87ad4f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jul 6 12:20:49 2023 +0300

    dnsforward: imp code

commit 1aaa1998b914b0d53142c21fa3bdcae502e4f3f6
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 4 20:11:55 2023 +0300

    home: add todo

commit aed232fcf70ef546f373d5235b73abcb4fbb4b6c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jul 4 13:25:28 2023 +0300

    all: imp code, tests

commit 5c028c2766ffb8ebdc358a245a249c6a55d9ad81
Merge: 83d6ae7f6 97af062f7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 3 18:54:42 2023 +0300

    Merge branch 'master' into AG-22597-imp-rdns

commit 83d6ae7f61a7b81a8d73cd6d747035278c64fb70
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jul 3 18:53:05 2023 +0300

    home: imp code

commit 8153988dece0406e51a90a43eaffae59dba30a36
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 30 18:06:09 2023 +0300

    all: imp code

commit 00d3cc11a9378318f176aae00ddf972f255d575c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 30 13:05:04 2023 +0300

    all: add tests

commit ffdc95f237bfdb780922b4390d82cdc0154b0621
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 15:20:00 2023 +0300

    all: imp code, docs

commit 0dc60e2b355750ca701558927d22fb9ad187ea7e
Merge: 69dd56bdb d4a4bda64
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 15:13:19 2023 +0300

    Merge branch 'master' into AG-22597-imp-rdns

commit 69dd56bdb75056b0fa6bcf6538af7fff93383323
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 23 14:36:29 2023 +0300

    rdns: add tests

commit 16909b51adbe3a3f230291834cc9486dd8a0e8f8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 19 16:28:26 2023 +0300

    rdns: extract rdns
2023-07-06 17:10:06 +03:00
Dimitry Kolyshev
5a195b441c Pull request: log-yaml-conf
Updates #4897.

Squashed commit of the following:

commit 8a961157c9930bf4859ce2209e5016ce94987e12
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jul 5 10:13:24 2023 +0400

    home: imp code

commit 509c07eed06311d773bc3e34b3ca28d9f14186fe
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 4 17:33:31 2023 +0400

    all: fix

commit f032e28f98552f238721491c998fca2d7d4b9802
Merge: ee0113435 c46516475
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 4 17:31:29 2023 +0400

    Merge remote-tracking branch 'origin/master' into log-yaml-conf

    # Conflicts:
    #	CHANGELOG.md

commit ee011343512e82d4e21cb402759d0284523ba02a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 4 12:31:42 2023 +0400

    all: changelog

commit 07f4c4a244b1b6200d3056cde5ebced6254084a7
Merge: 2042c0753 97af062f7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jul 4 12:25:21 2023 +0400

    Merge remote-tracking branch 'origin/master' into log-yaml-conf

commit 2042c0753ec29de6045c3f1de6d075cb93d6ec27
Merge: a1d3a5130 8004b135b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jul 3 16:25:26 2023 +0400

    Merge remote-tracking branch 'origin/master' into log-yaml-conf

commit a1d3a51307e80f9e509bd6f3bee1a7b17bf1ffe6
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Jun 30 11:11:32 2023 +0400

    home: imp code

commit 2392a3b02620b8c38e88afb4d75988be85fe1338
Merge: 4224fbed7 39f5c50ac
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 16:46:47 2023 +0400

    home: imp code

commit 4224fbed7113e94bee44d0ab0272e8302a8086f3
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 16:39:35 2023 +0400

    home: imp code

commit 5ce708cc50bed83e64f062e599fc8b6143d0d44d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 12:48:42 2023 +0400

    all: docs

commit 4b6d898a888818410f59b843c3ca1a685aafec82
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 12:20:54 2023 +0400

    home: imp code

commit 431b44eda71f488c747c3efa4da0a6c222b1cf06
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 12:03:17 2023 +0400

    home: imp tests

commit 53a5c31060018c37953beb27d80c46f92bbe14af
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 17:40:49 2023 +0400

    home: imp docs

commit bfa57d9f21e3326baafd3a52e91d54396d8e03fa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 15:49:40 2023 +0400

    home: log conf

commit 49e06dca9dc2ceb2647b7e36dac145ccf78a6c3f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 15:41:02 2023 +0400

    home: log conf

commit 9be432dea7cec8ae0c0d3ee1f73c58c76376d07e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 10:45:01 2023 +0400

    home: log conf
2023-07-06 10:09:04 +03:00
Ainar Garipov
c46516475d Pull request 1906: 5896-safe-browsing-cpu-ram
Updates #5896.

Squashed commit of the following:

commit 81ac59e2f95ef3ad6ac5c4668c07c35d69570454
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jul 4 16:07:33 2023 +0300

    hashprefix: fix cache coding
2023-07-04 16:17:18 +03:00
Ainar Garipov
97af062f7b Pull request 1905: upd-chlog
Squashed commit of the following:

commit 783d9c9265be564e91e62b24d0e0e3213f1f7d7d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 3 17:14:17 2023 +0300

    all: upd chlog
2023-07-03 17:17:29 +03:00
Ainar Garipov
8004b135b1 Pull request 1904: 5959-fix-error-days
Updates #5959.

* commit '4b9264531be50e81fe610050a12827b71bc3a9cd':
  clients: use constant a day in milliseconds
  clients: fix lint
  fix error days
2023-07-03 14:34:19 +03:00
Ildar Kamalov
4b9264531b clients: use constant a day in milliseconds 2023-07-03 14:29:33 +03:00
Ainar Garipov
9a506d3755 clients: fix lint 2023-07-03 14:23:18 +03:00
qingbo
e320eb29c2 fix error days 2023-07-03 18:48:14 +08:00
Ainar Garipov
282f11a7c2 Pull request 1903: upd-all
Squashed commit of the following:

commit 61838cb3e08dcfd16c9fa521a8243207ec2091aa
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jul 3 13:30:37 2023 +0300

    all: upd i18n, svcs, tools, trackers
2023-07-03 13:40:30 +03:00
Eugene Burkov
91f3e29c08 Pull request 1891: 5902-bootstrap-hosts
Merge in DNS/adguard-home from 5902-bootstrap-hosts to master

Updates #5902.

Squashed commit of the following:

commit fcc65d3a8d7566acc361f54b18d1af85045225e2
Merge: 0c336af07 1fd6cf1a2
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jun 30 12:29:06 2023 +0300

    Merge branch 'master' into 5902-bootstrap-hosts

commit 0c336af07d2864533e1f10029b4321d7cd210a47
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jun 29 15:40:28 2023 +0300

    all: imp & simplify

commit 45aae90035b98b30199cc7fc92991528f4e968c0
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 20:24:43 2023 +0300

    all: imp code, docs

commit e3dbb5bfe5dfbde7af00f39adcc15e9711e5feb0
Merge: a33a8e93c 2069eddf9
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 18:27:36 2023 +0300

    Merge branch 'master' into 5902-bootstrap-hosts

commit a33a8e93cb36f7d0c4472e524e44de6ff0ab6653
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 13:27:11 2023 +0300

    aghos: add type check

commit 781a3a248871df2ea37a936c8d6b0b11e2d2f3a4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 13:09:37 2023 +0300

    all: log changes

commit 4575368655356f84992fad2bfb78cbc1c88da25a
Merge: 636c440fc cf7c12c97
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 13:08:11 2023 +0300

    Merge branch 'master' into 5902-bootstrap-hosts

commit 636c440fca9cbdfd5c12b7f89432fb9323e01d86
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 28 13:06:32 2023 +0300

    all: imp tests

commit 0eff7a747e32216d78abf9db9460cb9d48f31f96
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jun 26 18:40:22 2023 +0300

    dnsforward: imp code

commit 7489a30971e3c76b8f62fd4ca11a977eeabe2cf5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jun 26 17:04:10 2023 +0300

    all: resolve upstreams with hosts
2023-06-30 12:41:10 +03:00
Stanislav Chzhen
1fd6cf1a2f Pull request 1901: 5946-fix-blocked-services-client-schedule
Updates #5946.

Squashed commit of the following:

commit cd6ba613fae56d05a2e51ae1a65e9fcf4a39899e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 30 11:27:52 2023 +0300

    home: fix blocked services client schedule
2023-06-30 11:56:03 +03:00
Ainar Garipov
efed23701a Pull request 1900: fix-docker-script
Closes #5947.

Squashed commit of the following:

commit 309fab7afd78585a561830379f06dd531e6f260e
Merge: 31a6a577d ad1bf5cf6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 30 10:43:36 2023 +0300

    Merge branch 'master' into fix-docker-script

commit 31a6a577ddd2ae8f6a27f852f655628333f8e3da
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 29 21:48:37 2023 +0300

    scripts: fix unbound variable

commit 59b2bb836a11b2f2719d5c5a9bf5d025736d4435
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 29 21:12:37 2023 +0300

    scripts: fix docker
2023-06-30 10:47:44 +03:00
Stanislav Chzhen
ad1bf5cf6e Pull request 1898: fix-whois-gocognit
Squashed commit of the following:

commit 69675b742a3b8a1d513f1b5f9c488577ced329b8
Merge: 0d069b769 ee8eb1d8a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 19:31:26 2023 +0300

    Merge branch 'master' into fix-whois-gocognit

commit 0d069b76938d9b3011b8d92865e7630027f1ebd1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 19:21:02 2023 +0300

    whois: imp code more

commit 6c4ab4a4e0451551bcec5472d997a88989f013e4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 18:08:50 2023 +0300

    whois: imp code

commit 0d04ddbd6f8bb3848673c3f86fc26dca2fd4d402
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 17:47:06 2023 +0300

    whois: imp docs

commit d7b75f7b42604374cb8cb0aaf141eb5c7fc985d3
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 29 16:54:49 2023 +0300

    all: imp code
2023-06-29 19:35:33 +03:00
Ainar Garipov
ee8eb1d8a6 Pull request 1899: nextapi-pidfile-webaddr
Squashed commit of the following:

commit 73b97b638016dd3992376c2cd7d11b2e85b2c3a4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 29 18:43:05 2023 +0300

    next: use maybe; sync conf

commit 99e18b8fbfad11343a1e66f746085d54be7aafea
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 29 18:13:13 2023 +0300

    next: add local frontend, pidfile, webaddr
2023-06-29 19:10:39 +03:00
Dimitry Kolyshev
39f5c50acd Pull request: home: http conf
Updates #2860.

Squashed commit of the following:

commit 0d55a99d5c0b9f1d8c9497775dd69929e5091eaa
Merge: 73a203ac8 d4a4bda64
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 16:25:36 2023 +0400

    Merge remote-tracking branch 'origin/master' into http-yaml-conf

commit 73a203ac8acf083fa289015e1f301d05bf320ea7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 16:21:48 2023 +0400

    home: imp docs

commit a4819ace94bfe4427f70f1b8341c9babc9234740
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 29 11:45:30 2023 +0400

    snap: imp script

commit b0913c7ac5c6c46d6a73790fd57d8c5f9d7ace75
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 17:34:03 2023 +0400

    all: docs

commit 14820d6d56f958081d9f236277fd34f356bdab33
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 13:21:43 2023 +0400

    home: imp tests

commit 9db800d3ce39c36da7959e37b4a46736f4217e5c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 13:17:34 2023 +0400

    all: docs

commit 9174a0ae710da51d85b4e1b1af79eda6a61dd3a2
Merge: ca8c4ae95 d88181343
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 10:19:01 2023 +0400

    Merge remote-tracking branch 'origin/master' into http-yaml-conf

    # Conflicts:
    #	CHANGELOG.md
    #	internal/home/upgrade.go
    #	internal/home/upgrade_test.go

commit ca8c4ae954ece25d78ef2f873bb3ba71fa4b8fa9
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 10:07:15 2023 +0400

    snap: imp script

commit d84473f8e07b2c6e65023613eb4032fd01951521
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 28 09:59:57 2023 +0400

    snap: imp script

commit 8a0808e42ddbff7d9d3345d758f91b14bb4453be
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 15:03:53 2023 +0400

    home: http conf

commit e8fbb89cc5748f9d8fa4be9e702756bd8b869de9
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 14:59:37 2023 +0400

    home: imp code

commit 46541aabc421118562d564675dfd7e594d2056aa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 12:36:14 2023 +0400

    snap: bind port

commit cecda5fcfd8c473db42f235b4f586b2193086997
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 12:12:39 2023 +0400

    docker: bind port

commit 8d8945b70366c6b018616a32421c77eb281a6ea1
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 11:06:32 2023 +0400

    home: imp code

commit ae5e8c1c4333d7b752c08605d80e41f55ee50e59
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 27 11:02:09 2023 +0400

    home: imp code

commit c9ee460f37e32941b84ea5fa94d21b186d6dd82b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 26 17:11:10 2023 +0400

    home: imp code

commit 44c72445112ef38d6ec9c25b197c119edd6c959f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 26 11:52:19 2023 +0400

    all: docs

commit e3bf5faeb748f347b1202a496788739ff9219ed0
Merge: 38cc0f639 e7e638443
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 26 11:39:12 2023 +0400

    Merge remote-tracking branch 'origin/master' into http-yaml-conf

commit 38cc0f6399040f1fa39d9da31ad6db65a6bdd4cc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 26 11:38:17 2023 +0400

    snap: bind port

commit 3b9cb9e8cc89a67e55cecc7a2040c150f8675b4c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 26 11:25:03 2023 +0400

    docker: bind port

... and 4 more commits
2023-06-29 15:29:52 +03:00
Ainar Garipov
d4a4bda645 Pull request 1897: nextapi-write-conf
Squashed commit of the following:

commit 72f25ffe73d6b8216b01e590fba66fb5f6944113
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 28 21:29:04 2023 +0300

    next: add conf writing, validation
2023-06-29 14:34:06 +03:00
Ainar Garipov
2069eddf98 Pull request 1896: fix-docker
Squashed commit of the following:

commit e64194bd053085b6bdcef6dcda40e7b52234a2ec
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 28 18:02:22 2023 +0300

    scripts: fix docker tags
2023-06-28 18:12:45 +03:00
Ainar Garipov
c652653ea4 Pull request 1894: upd-all
Squashed commit of the following:

commit 77daec27a1f5650a99b9e404f700a1e323741740
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 28 14:28:32 2023 +0300

    all: fix i18n script; upd deps, i18n, svcs
2023-06-28 15:29:38 +03:00
Ainar Garipov
6889837785 Pull request 1893: all: imp logs; upd dnsproxy
Updates #5285.

Squashed commit of the following:

commit 8e7d17505492b6983ba9e713455b98652938d73d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 28 13:33:14 2023 +0300

    all: imp logs; upd dnsproxy
2023-06-28 13:46:04 +03:00
Ainar Garipov
cf7c12c97b Pull request 1892: next-imp-dnssvc
Squashed commit of the following:

commit 770a3f338ecb270fcff7792a4ffe3cf95492d2ae
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 27 20:10:39 2023 +0300

    dnssvc: fix test for darwin

commit 6564abcc0904784ff3787e1a046d665519a108b3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 27 19:57:19 2023 +0300

    all: fix .gitignore, tests

commit 3ff1be0462b3adea81d98b1f65eeb685d2d72030
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 27 19:30:05 2023 +0300

    next: add conf example; imp dnssvc
2023-06-28 12:48:53 +03:00
Stanislav Chzhen
d88181343c Pull request 1883: 951-blocked-services-client-schedule
Updates #951.

Squashed commit of the following:

commit 94e4766932940a99c5265489bccb46d0ed6cec25
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 27 17:21:41 2023 +0300

    chlog: upd docs

commit b4022c33860c258bf29650413f0c972b849a1758
Merge: cfa24ff01 e7e638443
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 27 16:33:20 2023 +0300

    Merge branch 'master' into 951-blocked-services-client-schedule

commit cfa24ff0190b2bc12736700eeff815525fbaf5fe
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 27 15:04:10 2023 +0300

    chlog: imp docs

commit dad27590d5eefde82758d58fc06a20c139492db8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 26 17:38:08 2023 +0300

    home: imp err msg

commit 7d9ba98c4477000fc2e0f06c3462fe9cd0c65293
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 26 16:58:00 2023 +0300

    all: add tests

commit 8e952fc4e3b3d433b29efe47c88d6b7806e99ff8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 23 16:36:10 2023 +0300

    schedule: add todo

commit 723573a98d5b930334a5fa125eb12593f4a2430d
Merge: 2151ab2a6 e54fc9b1e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 23 11:40:03 2023 +0300

    Merge branch 'master' into 951-blocked-services-client-schedule

commit 2151ab2a627b9833ba6cce9621f72b29d326da75
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 23 11:37:49 2023 +0300

    all: add tests

commit 81ab341db3e4053f09b181d8111c0da197bdac05
Merge: aa7ae41a8 66345e855
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 22 17:59:01 2023 +0300

    Merge branch 'master' into 951-blocked-services-client-schedule

commit aa7ae41a868045fe24e390b25f15551fd8821529
Merge: 304389a48 06d465b0d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 21 17:10:11 2023 +0300

    Merge branch 'master' into 951-blocked-services-client-schedule

commit 304389a487f728e8ced293ea811a4e0026a37f0d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 21 17:05:31 2023 +0300

    home: imp err msg

commit 29cfc7ae2a0bbd5ec3205eae3f6f810519787f26
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 20:42:59 2023 +0300

    all: imp err handling

commit 8543868eef6442fd30131d9567b66222999101e9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 18:21:50 2023 +0300

    all: upd chlog

commit c5b614d45e5cf25c30c52343f48139fb34c77539
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 14:37:47 2023 +0300

    all: add blocked services schedule
2023-06-27 18:03:07 +03:00
Ildar Kamalov
e7e638443f Pull request 1889: AG-22207 handle rewrite update
Updates #1577

Squashed commit of the following:

commit a07ff51fb3f1eb58ab9a922d7bc11ed1d65ef3a7
Merge: 7db696814 2f515e8d8
Author: Ildar Kamalov <ik@adguard.com>
Date:   Fri Jun 23 16:50:09 2023 +0300

    Merge branch 'master' into AG-22207

commit 7db696814f2134fd3a3415cbcfa0ffdac1fabda3
Author: Ildar Kamalov <ik@adguard.com>
Date:   Fri Jun 23 14:57:09 2023 +0300

    fix changelog

commit bf9458b3f18697ca1fc504c51fa443934f76371f
Author: Ildar Kamalov <ik@adguard.com>
Date:   Fri Jun 23 14:48:20 2023 +0300

    changelog

commit bc2bf3f9507957afe63a654334b6e22858d1e41b
Author: Ildar Kamalov <ik@adguard.com>
Date:   Fri Jun 23 13:28:28 2023 +0300

    client: handle rewrite edit
2023-06-23 17:10:59 +03:00
Dimitry Kolyshev
2f515e8d8f Pull request: all: docs
Merge in DNS/adguard-home from cmdline-flag-docs to master

Updates #4235.

Squashed commit of the following:

commit 1d68255b3d3003207eed535f9491fedb1d839e8b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri Jun 23 16:04:15 2023 +0400

    all: docs
2023-06-23 15:09:00 +03:00
Dimitry Kolyshev
e54fc9b1e9 Pull request: web-addr-cmdline
Merge in DNS/adguard-home from web-addr-cmdline to master

Squashed commit of the following:

commit 27652dbfae227f9a9f4d921f14af1e5897d7830d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 17:51:43 2023 +0400

    home: web-addr opt

commit b234d108e70fed3ff11eeb4986946f8a50dda515
Merge: eef1b5cbb 66345e855
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 17:10:57 2023 +0400

    Merge remote-tracking branch 'origin/master' into web-addr-cmdline

    # Conflicts:
    #	CHANGELOG.md

commit eef1b5cbb9f7dd9819c8038800a4bbcf3ff575aa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 17:04:12 2023 +0400

    all: docs

    Updates #4231.

commit b4adb0bae82e44101f7b6685a29926c3d02e95af
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 16:58:12 2023 +0400

    all: docker

    Updates #4231.

commit a4012fddc50a3f5143136df8f3b865d7e1b9087c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 11:24:02 2023 +0400

    all: docker

commit bd5cc3308298b1022dea501c2fe79d96df24ce2a
Merge: 36841dd85 123ca8738
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 11:22:51 2023 +0400

    Merge remote-tracking branch 'origin/master' into web-addr-cmdline

commit 36841dd85fe1d006e6ec518329cb8ceea0915599
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 21 11:53:40 2023 +0400

    all: docker

commit 5c4756a56d251f1486b92f333f11485b5f4807f4
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 21 11:50:41 2023 +0400

    all: imp docs

commit 7b6fba81f2d5a354bdf259d812d04f3bd64de0c6
Merge: 54c119024 ca313521d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed Jun 21 11:47:36 2023 +0400

    Merge remote-tracking branch 'origin/master' into web-addr-cmdline

commit 54c119024f3999d5c4dec06b21e3bb78803bf388
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 15:57:54 2023 +0400

    home: imp code

commit c87e0a690376aa6a28a018c3cbbb5de0ad16333d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 15:56:45 2023 +0400

    all: imp docs

commit de240d00e334f7fd3dbf39ac08472183deeb32db
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 15:54:27 2023 +0400

    all: docker

commit 568d5371e73fb6c5ba19a036e7a5135764f6538b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 13:38:53 2023 +0400

    all: docs

commit 407e230c8e3bc293e8d533ca5db1f28fec4b3c54
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 13:24:23 2023 +0400

    home: deprecate opts

commit 6e628fad6f4ee9f23213eeb55bec500db4435175
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue Jun 20 13:18:10 2023 +0400

    home: web-addr opt
2023-06-23 10:03:01 +03:00
Dimitry Kolyshev
66345e855e Pull request: filtering: fix filter delete
Merge in DNS/adguard-home from 5700-fix-filter-delete to master

Squashed commit of the following:

commit 51e5c82bf6c12b48b1c07622639216ecba21e115
Merge: b4f8abdf2 37e046acc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 17:05:23 2023 +0400

    Merge remote-tracking branch 'origin/master' into 5700-fix-filter-delete

commit b4f8abdf2e9a8c94594cb0e3b00b37e0ed49578a
Merge: eac30a13f f40ef76c7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 16:55:58 2023 +0400

    Merge remote-tracking branch 'origin/master' into 5700-fix-filter-delete

commit eac30a13fb30404b2e058d1889be566d359d5000
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 14:03:07 2023 +0400

    filtering: imp code

commit 4e270789b83bdcff09d94ace46dd0b02d2c6893c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 14:02:04 2023 +0400

    all: docs

commit b818468ae29f647bcc0f4e408d10c8469829da95
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu Jun 22 13:18:12 2023 +0400

    filtering: fix filter delete
2023-06-22 16:09:55 +03:00
Stanislav Chzhen
37e046acc4 Pull request 1886: fix-blocked-services-client-schedule
Merge in DNS/adguard-home from fix-blocked-services-client-schedule to master

Updates #951.

Squashed commit of the following:

commit 1c890953ff4b7862db10f99f4851797050ad9d8e
Merge: ac0b722d1 f40ef76c7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 22 15:54:03 2023 +0300

    Merge branch 'master' into fix-blocked-services-client-schedule

commit ac0b722d1deef664ab464e0bff387542e027bd3f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 22 14:32:03 2023 +0300

    home: fix typo

commit 64eb519c4b77cff1071059f1f41acfd0e3ea9513
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 22 14:23:07 2023 +0300

    home: add test case

commit c7b60f3ea89e41f8b84bf6f2f5e075e9b3dd45ec
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 22 12:00:24 2023 +0300

    home: imp code

commit 7806c920bb0c4b4c44c3fed7e920f795904630b2
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 21 20:49:47 2023 +0300

    home: add tests

commit d37c9fde882965f005ddec86ad0502585d2eea95
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 21 18:49:43 2023 +0300

    home: fix client blocked services
2023-06-22 15:58:09 +03:00
Eugene Burkov
f40ef76c79 Pull request 1861: 4923-gopacket-dhcp vol.1
Merge in DNS/adguard-home from 4923-gopacket-dhcp to master

Updates #4923.

Squashed commit of the following:

commit edf36ce8b1873272c3daebe8cc8f8132793aac44
Merge: a17513d3e 123ca8738
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jun 22 14:14:39 2023 +0300

    Merge branch 'master' into 4923-gopacket-dhcp

commit a17513d3e0a9e596d56444dfa46478eee15631de
Merge: f04727c29 994906fbd
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 21 17:49:09 2023 +0300

    Merge branch 'master' into 4923-gopacket-dhcp

commit f04727c29eaf22f9eb53f3aa33d42d00e177b224
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jun 20 15:42:31 2023 +0300

    home: revert clients container

commit c58284ac6b5b2274da5eed2e853847d757709e5b
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jun 19 21:10:36 2023 +0300

    all: imp code, names, docs

commit 4c4613c939e1325d11655822d9dbc3f05a6d203c
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jun 13 18:51:12 2023 +0300

    all: imp code

commit 0b4a6e0dd561d9b7bb78dea21dcc947bcd0bd583
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Jun 7 18:40:15 2023 +0300

    all: imp api

commit 0425edea03d6ca0859657df683bef6ec45bfc399
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Mon Jun 5 15:57:23 2023 +0300

    dhcpsvc: introduce package

commit 5628ebe6cccf91e2c48778966730bcbbe9e1d9f2
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jun 1 17:49:12 2023 +0300

    WIP
2023-06-22 14:18:43 +03:00
256 changed files with 12703 additions and 6455 deletions

View File

@@ -32,31 +32,33 @@
- 'attributes':
'description': 'On which Platform does the issue occur?'
'label': 'Platform (OS and CPU architecture)'
# NOTE: Keep the 386 at the bottom for each OS, because a lot of people
# Seem to confuse them with AMD64, which is what they actually need.
'options':
- 'Darwin (aka macOS)/AMD64 (aka x86_64)'
- 'Darwin (aka macOS)/ARM64'
- 'FreeBSD/386'
- 'FreeBSD/AMD64 (aka x86_64)'
- 'FreeBSD/ARM64'
- 'FreeBSD/ARMv5'
- 'FreeBSD/ARMv6'
- 'FreeBSD/ARMv7'
- 'Linux/386'
- 'Linux/AMD64 (aka x86_64)'
- 'Linux/ARM64'
- 'Linux/ARMv5'
- 'Linux/ARMv6'
- 'Linux/ARMv7'
- 'Linux/MIPS LE'
- 'Linux/MIPS'
- 'Linux/MIPS64 LE'
- 'Linux/MIPS64'
- 'Linux/PPC64 LE'
- 'OpenBSD/AMD64 (aka x86_64)'
- 'OpenBSD/ARM64'
- 'Windows/386'
- 'Windows/AMD64 (aka x86_64)'
- 'Windows/ARM64'
- 'Darwin (aka macOS), AMD64 (aka x86_64)'
- 'Darwin (aka macOS), ARM64'
- 'FreeBSD, AMD64 (aka x86_64)'
- 'FreeBSD, ARM64'
- 'FreeBSD, ARMv5'
- 'FreeBSD, ARMv6'
- 'FreeBSD, ARMv7'
- 'FreeBSD, 32-bit Intel (aka 386)'
- 'Linux, AMD64 (aka x86_64)'
- 'Linux, ARM64'
- 'Linux, ARMv5'
- 'Linux, ARMv6'
- 'Linux, ARMv7'
- 'Linux, MIPS LE'
- 'Linux, MIPS'
- 'Linux, MIPS64 LE'
- 'Linux, MIPS64'
- 'Linux, PPC64 LE'
- 'Linux, 32-bit Intel (aka 386)'
- 'OpenBSD, AMD64 (aka x86_64)'
- 'OpenBSD, ARM64'
- 'Windows, AMD64 (aka x86_64)'
- 'Windows, ARM64'
- 'Windows, 32-bit Intel (aka 386)'
- 'Custom (please mention in the description)'
'id': 'os'
'type': 'dropdown'
@@ -142,8 +144,10 @@
'type': 'textarea'
'validations':
'required': false
'description': >
Open a bug report. Please do not open bug reports for questions or help
with configuring clients. If you want to ask for help, use the Discussions
section.
# NOTE: GitHub limits the description length to 200 characters. Also, Markdown
# doesn't work here.
'description': |
For help, use the Discussions section instead. Write the title in English
to make it easier for other people to search for duplicates. (Any language
is fine in the body.)
'name': 'Bug'

View File

@@ -48,7 +48,11 @@
'type': 'textarea'
'validations':
'required': false
'description': 'Suggest a feature or an enhancement for AdGuard Home'
# NOTE: GitHub limits the description length to 200 characters. Also, Markdown
# doesn't work here.
'description': |
Write the title in English to make it easier for other people to search for
duplicates. (Any language is fine in the body.)
'labels':
- 'feature request'
'name': 'Feature request or enhancement'

View File

@@ -1,7 +1,7 @@
'name': 'build'
'env':
'GO_VERSION': '1.19.10'
'GO_VERSION': '1.20.7'
'NODE_VERSION': '14'
'on':

View File

@@ -1,7 +1,7 @@
'name': 'lint'
'env':
'GO_VERSION': '1.19.10'
'GO_VERSION': '1.20.7'
'on':
'push':

6
.gitignore vendored
View File

@@ -9,6 +9,7 @@
*.db
*.log
*.snap
*.test
/agh-backup/
/bin/
/build/*
@@ -16,10 +17,13 @@
/dist/
/filtering/tests/filtering.TestLotsOfRules*.pprof
/filtering/tests/top-1m.csv
/internal/next/AdGuardHome.yaml
/launchpad_credentials
/querylog.json*
/snapcraft_login
AdGuardHome*
AdGuardHome
AdGuardHome.exe
AdGuardHome.yaml*
coverage.txt
node_modules/

View File

@@ -835,7 +835,7 @@ Request:
Response:
200 OK
### API: Validate TLS configuration
Request:
@@ -2008,7 +2008,7 @@ Request:
Response:
200 OK
DOH plist file
## API: Get DNS over TLS .mobileconfig

View File

@@ -14,32 +14,298 @@ and this project adheres to
<!--
## [v0.108.0] - TBA
## [v0.107.33] - 2023-06-28 (APPROX.)
## [v0.107.37] - 2023-08-16 (APPROX.)
See also the [v0.107.33 GitHub milestone][ms-v0.107.33].
See also the [v0.107.37 GitHub milestone][ms-v0.107.37].
[ms-v0.107.33]: https://github.com/AdguardTeam/AdGuardHome/milestone/68?closed=1
[ms-v0.107.37]: https://github.com/AdguardTeam/AdGuardHome/milestone/72?closed=1
NOTE: Add new changes BELOW THIS COMMENT.
-->
### Added
- The new HTTP API, `GET /control/querylog/export`, which can be used to
export query log items. See `openapi/openapi.yaml` for the full description
([#3389]).
- The ability to set inactivity periods for filtering blocked services in the
configuration file ([#951]). The UI changes are coming in the upcoming
releases.
- IPv6 hints are now filtered in case IPv6 addresses resolving is disabled
([#6122]).
- The ability to set fallback DNS servers in the configuration file ([#3701]).
- While adding or updating blocklists, the title can now be parsed from
`! Title:` definition of the blocklist's source ([#6020]).
- The ability to filter DNS HTTPS records including IPv4/v6 hints ([#6053]).
- Two new metrics showing total number of responses from each upstream DNS
server and their average processing time in the Web UI ([#1453]).
- The ability to set the port for the `pprof` debug API, see configuration
changes below.
### Changed
- `$dnsrewrite` rules containing IPv4-mapped IPv6 addresses are now working
consistently with legacy DNS rewrites and match the `AAAA` requests.
- For non-A and non-AAAA requests, which has been filtered, the NODATA response
is returned if the blocking mode isn't set to `Null IP`. In previous versions
it returned NXDOMAIN response in such cases.
#### Configuration Changes
In this release, the schema version has changed from 24 to 25.
- Property `debug_pprof` which used to setup profiling HTTP handler, is now
moved to the new `pprof` object under `http` section. The new object contains
properties `enabled` and `port`:
```yaml
# BEFORE:
'debug_pprof': true
# AFTER:
'http':
'pprof':
'enabled': true
'port': 6060
```
Note that the new default `6060` is used as default. To rollback this change,
remove the new object `pprof`, set back `debug_pprof`, and change the
`schema_version` back to `24`.
### Fixed
- Occasional DNS-over-QUIC and DNS-over-HTTP/3 errors ([#6133]).
- Legacy DNS rewrites containing IPv4-mapped IPv6 addresses are now matching the
`AAAA` requests, not `A` ([#6050]).
- File log configuration, such as `max_size`, being ignored ([#6093]).
- Panic on using a single-slash filtering rule.
- Panic on shutting down while DNS requests are in process of filtering
([#5948]).
[#1453]: https://github.com/AdguardTeam/AdGuardHome/issues/1453
[#3701]: https://github.com/AdguardTeam/AdGuardHome/issues/3701
[#5948]: https://github.com/AdguardTeam/AdGuardHome/issues/5948
[#6020]: https://github.com/AdguardTeam/AdGuardHome/issues/6020
[#6050]: https://github.com/AdguardTeam/AdGuardHome/issues/6050
[#6053]: https://github.com/AdguardTeam/AdGuardHome/issues/6053
[#6093]: https://github.com/AdguardTeam/AdGuardHome/issues/6093
[#6122]: https://github.com/AdguardTeam/AdGuardHome/issues/6122
[#6133]: https://github.com/AdguardTeam/AdGuardHome/issues/6133
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->
## [v0.107.36] - 2023-08-02
See also the [v0.107.36 GitHub milestone][ms-v0.107.36].
### Security
- Go version has been updated to prevent the possibility of exploiting the
CVE-2023-29409 Go vulnerability fixed in [Go 1.20.7][go-1.20.7].
### Deprecated
- Go 1.20 support. Future versions will require at least Go 1.21 to build.
### Fixed
- Inability to block queries for the root domain, such as `NS .` queries, using
the *Disallowed domains* feature on the *DNS settings* page ([#6049]). Users
who want to block `.` queries should use the `|.^` AdBlock rule or a similar
regular expression.
- Client hostnames not resolving when upstream server responds with zero-TTL
records ([#6046]).
[#6046]: https://github.com/AdguardTeam/AdGuardHome/issues/6046
[#6049]: https://github.com/AdguardTeam/AdGuardHome/issues/6049
[go-1.20.7]: https://groups.google.com/g/golang-announce/c/X0b6CsSAaYI/m/Efv5DbZ9AwAJ
[ms-v0.107.36]: https://github.com/AdguardTeam/AdGuardHome/milestone/71?closed=1
## [v0.107.35] - 2023-07-26
See also the [v0.107.35 GitHub milestone][ms-v0.107.35].
### Changed
- Improved reliability filtering-rule list updates on Unix systems.
### Fixed
- Occasional client information lookup failures that could lead to the DNS
server getting stuck ([#6006]).
- `bufio.Scanner: token too long` and other errors when trying to add
filtering-rule lists with lines over 1024 bytes long or containing cosmetic
rules ([#6003]).
### Removed
- Default exposure of the non-standard ports 784 and 8853 for DNS-over-QUIC in
the `Dockerfile`.
[#6003]: https://github.com/AdguardTeam/AdGuardHome/issues/6003
[#6006]: https://github.com/AdguardTeam/AdGuardHome/issues/6006
[ms-v0.107.35]: https://github.com/AdguardTeam/AdGuardHome/milestone/70?closed=1
## [v0.107.34] - 2023-07-12
See also the [v0.107.34 GitHub milestone][ms-v0.107.34].
### Security
- Go version has been updated to prevent the possibility of exploiting the
CVE-2023-29406 Go vulnerability fixed in [Go 1.19.11][go-1.19.11].
### Added
- Ability to ignore queries for the root domain, such as `NS .` queries
([#5990]).
### Changed
- Improved CPU and RAM consumption during updates of filtering-rule lists.
#### Configuration Changes
In this release, the schema version has changed from 23 to 24.
- Properties starting with `log_`, and `verbose` property, which used to set up
logging are now moved to the new object `log` containing new properties
`file`, `max_backups`, `max_size`, `max_age`, `compress`, `local_time`, and
`verbose`:
```yaml
# BEFORE:
'log_file': ""
'log_max_backups': 0
'log_max_size': 100
'log_max_age': 3
'log_compress': false
'log_localtime': false
'verbose': false
# AFTER:
'log':
'file': ""
'max_backups': 0
'max_size': 100
'max_age': 3
'compress': false
'local_time': false
'verbose': false
```
To rollback this change, remove the new object `log`, set back `log_` and
`verbose` properties and change the `schema_version` back to `23`.
### Deprecated
- Default exposure of the non-standard ports 784 and 8853 for DNS-over-QUIC in
the `Dockerfile`.
### Fixed
- Two unspecified IPs when a host is blocked in two filter lists ([#5972]).
- Incorrect setting of Parental Control cache size.
- Excessive RAM and CPU consumption by Safe Browsing and Parental Control
filters ([#5896]).
### Removed
- The `HEALTHCHECK` section and the use of `tini` in the `ENTRYPOINT` section in
`Dockerfile` ([#5939]). They caused a lot of issues, especially with tools
like `docker-compose` and `podman`.
**NOTE:** Some Docker tools may cache `ENTRYPOINT` sections, so some users may
be required to backup their configuration, stop the container, purge the old
image, and reload it from scratch.
[#5896]: https://github.com/AdguardTeam/AdGuardHome/issues/5896
[#5972]: https://github.com/AdguardTeam/AdGuardHome/issues/5972
[#5990]: https://github.com/AdguardTeam/AdGuardHome/issues/5990
[go-1.19.11]: https://groups.google.com/g/golang-announce/c/2q13H6LEEx0/m/sduSepLLBwAJ
[ms-v0.107.34]: https://github.com/AdguardTeam/AdGuardHome/milestone/69?closed=1
## [v0.107.33] - 2023-07-03
See also the [v0.107.33 GitHub milestone][ms-v0.107.33].
### Added
- The new command-line flag `--web-addr` is the address to serve the web UI on,
in the host:port format.
- The ability to set inactivity periods for filtering blocked services, both
globally and per client, in the configuration file ([#951]). The UI changes
are coming in the upcoming releases.
- The ability to edit rewrite rules via `PUT /control/rewrite/update` HTTP API
([#1577]).
and the Web UI ([#1577]).
### Changed
#### Configuration Changes
In this release, the schema version has changed from 20 to 21.
In this release, the schema version has changed from 20 to 23.
- Properties `bind_host`, `bind_port`, and `web_session_ttl` which used to setup
web UI binding configuration, are now moved to a new object `http` containing
new properties `address` and `session_ttl`:
```yaml
# BEFORE:
'bind_host': '1.2.3.4'
'bind_port': 8080
'web_session_ttl': 720
# AFTER:
'http':
'address': '1.2.3.4:8080'
'session_ttl': '720h'
```
Note that the new `http.session_ttl` property is now a duration string. To
rollback this change, remove the new object `http`, set back `bind_host`,
`bind_port`, `web_session_ttl`, and change the `schema_version` back to `22`.
- Property `clients.persistent.blocked_services`, which in schema versions 21
and earlier used to be a list containing ids of blocked services, is now an
object containing ids and schedule for blocked services:
```yaml
# BEFORE:
'clients':
'persistent':
- 'name': 'client-name'
'blocked_services':
- id_1
- id_2
# AFTER:
'clients':
'persistent':
- 'name': client-name
'blocked_services':
'ids':
- id_1
- id_2
'schedule':
'time_zone': 'Local'
'sun':
'start': '0s'
'end': '24h'
'mon':
'start': '1h'
'end': '23h'
```
To rollback this change, replace `clients.persistent.blocked_services` object
with the list of ids of blocked services and change the `schema_version` back
to `21`.
- Property `dns.blocked_services`, which in schema versions 20 and earlier used
to be a list containing ids of blocked services, is now an object containing
ids and schedule for blocked services:
@@ -83,8 +349,23 @@ In this release, the schema version has changed from 20 to 21.
To rollback this change, replace `dns.blocked_services` object with the list
of ids of blocked services and change the `schema_version` back to `20`.
### Deprecated
- The `HEALTHCHECK` section and the use of `tini` in the `ENTRYPOINT` section in
`Dockerfile` ([#5939]). They cause a lot of issues, especially with tools
like `docker-compose` and `podman`, and will be removed in a future release.
- Flags `-h`, `--host`, `-p`, `--port` have been deprecated. The `-h` flag
will work as an alias for `--help`, instead of the deprecated `--host` in the
future releases.
### Fixed
- Ignoring of `/etc/hosts` file when resolving the hostnames of upstream DNS
servers ([#5902]).
- Excessive error logging when using DNS-over-QUIC ([#5285]).
- Inability to set `bind_host` in `AdGuardHome.yaml` in Docker ([#4231],
[#4235]).
- The blocklists can now be deleted properly ([#5700]).
- Queries with the question-section target `.`, for example `NS .`, are now
counted in the statistics and correctly shown in the query log ([#5910]).
- Safe Search not working with `AAAA` queries for domains that don't have `AAAA`
@@ -92,13 +373,16 @@ In this release, the schema version has changed from 20 to 21.
[#951]: https://github.com/AdguardTeam/AdGuardHome/issues/951
[#1577]: https://github.com/AdguardTeam/AdGuardHome/issues/1577
[#3389]: https://github.com/AdguardTeam/AdGuardHome/issues/3389
[#4231]: https://github.com/AdguardTeam/AdGuardHome/issues/4231
[#4235]: https://github.com/AdguardTeam/AdGuardHome/pull/4235
[#5285]: https://github.com/AdguardTeam/AdGuardHome/issues/5285
[#5700]: https://github.com/AdguardTeam/AdGuardHome/issues/5700
[#5902]: https://github.com/AdguardTeam/AdGuardHome/issues/5902
[#5910]: https://github.com/AdguardTeam/AdGuardHome/issues/5910
[#5913]: https://github.com/AdguardTeam/AdGuardHome/issues/5913
[#5939]: https://github.com/AdguardTeam/AdGuardHome/discussions/5939
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->
[ms-v0.107.33]: https://github.com/AdguardTeam/AdGuardHome/milestone/68?closed=1
@@ -2080,11 +2364,15 @@ See also the [v0.104.2 GitHub milestone][ms-v0.104.2].
<!--
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.33...HEAD
[v0.107.33]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.32...v0.107.33
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.37...HEAD
[v0.107.37]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.36...v0.107.37
-->
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.32...HEAD
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.36...HEAD
[v0.107.36]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.35...v0.107.36
[v0.107.35]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.34...v0.107.35
[v0.107.34]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.33...v0.107.34
[v0.107.33]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.32...v0.107.33
[v0.107.32]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.31...v0.107.32
[v0.107.31]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.30...v0.107.31
[v0.107.30]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.29...v0.107.30

View File

@@ -78,7 +78,7 @@ build: deps quick-build
quick-build: js-build go-build
ci: deps test
ci: deps test go-bench go-fuzz
deps: js-deps go-deps
lint: js-lint go-lint
@@ -104,8 +104,10 @@ js-deps:
js-lint: ; $(NPM) $(NPM_FLAGS) run lint
js-test: ; $(NPM) $(NPM_FLAGS) run test
go-bench: ; $(ENV) "$(SHELL)" ./scripts/make/go-bench.sh
go-build: ; $(ENV) "$(SHELL)" ./scripts/make/go-build.sh
go-deps: ; $(ENV) "$(SHELL)" ./scripts/make/go-deps.sh
go-fuzz: ; $(ENV) "$(SHELL)" ./scripts/make/go-fuzz.sh
go-lint: ; $(ENV) "$(SHELL)" ./scripts/make/go-lint.sh
go-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-tools.sh
@@ -128,3 +130,10 @@ openapi-lint: ; cd ./openapi/ && $(YARN) test
openapi-show: ; cd ./openapi/ && $(YARN) start
txt-lint: ; $(ENV) "$(SHELL)" ./scripts/make/txt-lint.sh
# TODO(a.garipov): Consider adding to scripts/ and the common project
# structure.
go-upd-tools:
cd ./internal/tools/ &&\
"$(GO.MACRO)" get -u &&\
"$(GO.MACRO)" mod tidy

View File

@@ -54,7 +54,7 @@ code.
* [Getting Started](#getting-started)
* [Automated install (Unix)](#automated-install-linux-and-mac)
* [Automated install (Linux/Unix/MacOS/FreeBSD/OpenBSD)](#automated-install-linux-and-mac)
* [Alternative methods](#alternative-methods)
* [Guides](#guides)
* [API](#api)
@@ -79,7 +79,7 @@ code.
## <a href="#getting-started" id="getting-started" name="getting-started">Getting Started</a>
### <a href="#automated-install-linux-and-mac" id="automated-install-linux-and-mac" name="automated-install-linux-and-mac">Automated install (Unix)</a>
### <a href="#automated-install-linux-and-mac" id="automated-install-linux-and-mac" name="automated-install-linux-and-mac">Automated install (Linux/Unix/MacOS/FreeBSD/OpenBSD)</a>
To install with `curl` run the following command:
@@ -261,7 +261,7 @@ Run `make init` to prepare the development environment.
You will need this to build AdGuard Home:
* [Go](https://golang.org/dl/) v1.19 or later;
* [Go](https://golang.org/dl/) v1.20 or later;
* [Node.js](https://nodejs.org/en/download/) v10.16.2 or later;
* [npm](https://www.npmjs.com/) v6.14 or later;
* [yarn](https://yarnpkg.com/) v1.22.5 or later.
@@ -416,7 +416,8 @@ There are three options how you can install an unstable version:
### <a href="#reporting-issues" id="reporting-issues" name="reporting-issues">Report issues</a>
If you run into any problem or have a suggestion, head to [this page][iss] and
click on the “New issue” button.
click on the “New issue” button. Please follow the instructions in the issue
form carefully and don't forget to start by searching for duplicates.
[iss]: https://github.com/AdguardTeam/AdGuardHome/issues

View File

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

View File

@@ -10,7 +10,7 @@
# Make sure to sync any changes with the branch overrides below.
'variables':
'channel': 'edge'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'dockerGo': 'adguard/golang-ubuntu:7.0'
'snapcraftChannel': 'edge'
'stages':
@@ -191,7 +191,7 @@
# need to build a few of these.
'variables':
'channel': 'beta'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'dockerGo': 'adguard/golang-ubuntu:7.0'
'snapcraftChannel': 'beta'
# release-vX.Y.Z branches are the branches from which the actual final
# release is built.
@@ -207,5 +207,5 @@
# are the ones that actually get released.
'variables':
'channel': 'release'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'dockerGo': 'adguard/golang-ubuntu:7.0'
'snapcraftChannel': 'candidate'

View File

@@ -5,7 +5,7 @@
'key': 'AHBRTSPECS'
'name': 'AdGuard Home - Build and run tests'
'variables':
'dockerGo': 'adguard/golang-ubuntu:6.7'
'dockerGo': 'adguard/golang-ubuntu:7.0'
'stages':
- 'Tests':
@@ -14,6 +14,12 @@
'jobs':
- 'Test'
- 'Artifact':
manual: false
final: false
jobs:
- 'Artifact'
'Test':
'docker':
'image': '${bamboo.dockerGo}'
@@ -41,6 +47,53 @@
'requirements':
- 'adg-docker': 'true'
'Artifact':
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'key': 'ART'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |-
#!/bin/sh
set -e -f -u -x
# Explicitly checkout the revision that we need.
git checkout "${bamboo.repository.revision.number}"
make\
ARCH="amd64"\
OS="windows darwin linux"\
CHANNEL="development"\
SIGN=0\
PARALLELISM=1\
VERBOSE=2\
build-release
'artifacts':
- 'name': 'AdGuardHome_windows_amd64'
'pattern': 'dist/AdGuardHome_windows_amd64.zip'
'shared': true
'required': true
- 'name': 'AdGuardHome_darwin_amd64'
'pattern': 'dist/AdGuardHome_darwin_amd64.zip'
'shared': true
'required': true
- 'name': 'AdGuardHome_linux_amd64'
'pattern': 'dist/AdGuardHome_linux_amd64.tar.gz'
'shared': true
'required': true
'requirements':
- 'adg-docker': 'true'
'branches':
'create': 'for-pull-request'
'delete':

View File

@@ -125,6 +125,8 @@
"top_clients": "كبار العملاء",
"no_clients_found": "لم يتم العثور على عملاء",
"general_statistics": "الإحصاءات العامة",
"top_upstreams": "أعلى الخوادم upstream",
"no_upstreams_data_found": "لم يتم العثور على بيانات خوادم upstream",
"number_of_dns_query_days": "عدد استعلامات DNS التي تمت معالجتها لآخر {{count}} يوم",
"number_of_dns_query_days_plural": "عدد استعلامات DNS التي تمت معالجتها لآخر {{count}} أيام",
"number_of_dns_query_24_hours": "عدد استعلامات DNS التي تمت معالجتها لآخر 24 ساعة",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "تم اعداده في {{path}}",
"test_upstream_btn": "اختبار upstream",
"upstreams": "Upstreams",
"upstream": "Upstream",
"apply_btn": "تطبيق",
"disabled_filtering_toast": "تم تعطيل الفلترة",
"enabled_filtering_toast": "تم تمكين الفلترة",
@@ -212,6 +215,7 @@
"example_upstream_udp": "regular DNS (over UDP, hostname);",
"example_upstream_dot": "مشفر<0>DNS-over-TLS</0>;",
"example_upstream_doh": "مشفر <0>DNS-over-HTTPS</0>;",
"example_upstream_doh3": "DNS-over-HTTPS المشفر مع فرض <0> HTTP / 3</0> ولا يوجد رجوع إلى HTTP / 2 أو أقل ؛",
"example_upstream_doq": "encrypted <0>DNS-over-QUIC</0>;",
"example_upstream_sdns": "<0>DNS Stamps</0> for <1>DNSCrypt</1> or <2>DNS-over-HTTPS</2> resolvers;",
"example_upstream_tcp": "regular DNS (over TCP);",

View File

@@ -125,6 +125,8 @@
"top_clients": "Частыя кліенты",
"no_clients_found": "Кліентаў не знойдзена",
"general_statistics": "Агульная статыстыка",
"top_upstreams": "Часта запытаныя upstream серверы",
"no_upstreams_data_found": "Няма дадзеных аб upstream серверах",
"number_of_dns_query_days": "Колькасць DNS-запытаў за апошні {{count}} дзень",
"number_of_dns_query_days_plural": "Колькасць DNS запытаў, апрацаваных за апошнія {{count}} дзён",
"number_of_dns_query_24_hours": "Колькасць DNS-запытаў за 24 гадзіны",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Наладжаны ў {{path}}",
"test_upstream_btn": "Тэст upstream сервераў",
"upstreams": "Upstreams",
"upstream": "Upstream сервер",
"apply_btn": "Ужыць",
"disabled_filtering_toast": "Фільтрацыя выкл.",
"enabled_filtering_toast": "Фільтрацыя ўкл.",
@@ -475,7 +478,9 @@
"setup_dns_notice": "Каб выкарыстоўваць <1>DNS-over-HTTPS</1> ці <1>DNS-over-TLS</1>, вам патрэбна <0>наладзіць шыфраванне</0> у наладах AdGuard Home.",
"rewrite_added": "Правіла перанакіравання DNS для «{{key}}» паспяхова дададзена",
"rewrite_deleted": "Правіла перанакіравання DNS для «{{key}}» паспяхова выдалена",
"rewrite_updated": "Перазапіс DNS паспяхова абноўлены",
"rewrite_add": "Дадаць правіла перанакіравання DNS",
"rewrite_edit": "Рэдагаваць перазапіс DNS",
"rewrite_not_found": "Не знойдзена правілаў перанакіравання DNS",
"rewrite_confirm_delete": "Вы ўпэўнены, што хочаце выдаліць правіла перанакіравання DNS для «{{key}}»?",
"rewrite_desc": "Дазваляе лёгка наладзіць карыстацкі DNS-адказ для пэўнага дамена.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Nejčastější klienti",
"no_clients_found": "Nenalezeny žádní klienti",
"general_statistics": "Obecné statistiky",
"top_upstreams": "Top odchozí připojení",
"no_upstreams_data_found": "Nebyla nalezena žádná data odchozích připojení",
"number_of_dns_query_days": "Počet DNS dotazů zpracovaných za posledních {{count}} den",
"number_of_dns_query_days_plural": "Počet DNS dotazů zpracovaných za posledních {{count}} dní",
"number_of_dns_query_24_hours": "Počet DNS dotazů zpracovaných za posledních 24 hodin",
@@ -134,6 +136,7 @@
"enforced_save_search": "Vynucené bezpečné vyhledávání",
"number_of_dns_query_to_safe_search": "Počet požadavků DNS na vyhledávače, při kterých bylo vynucené bezpečné vyhledávání",
"average_processing_time": "Průměrný čas zpracování",
"processing_time": "Doba zpracování",
"average_processing_time_hint": "Průměrný čas zpracování požadavků DNS v milisekundách",
"block_domain_use_filters_and_hosts": "Blokovat domény pomocí filtrů a seznamů adres",
"filters_block_toggle_hint": "Pravidla blokování můžete nastavit v nastavení <a>Filtry</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Konfigurováno v {{path}}",
"test_upstream_btn": "Test upstreamů",
"upstreams": "Odesláno",
"upstream": "Odchozí připojení",
"apply_btn": "Použít",
"disabled_filtering_toast": "Vypnuté filtrování",
"enabled_filtering_toast": "Zapnuté filtrování",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Opravdu chcete odstranit klienta \"{{key}}\"?",
"list_confirm_delete": "Opravdu chcete smazat tento seznam?",
"auto_clients_title": "Spuštění klienti",
"auto_clients_desc": "Zařízení, která nejsou na seznamu stálých klientů, a mohou nadále používat AdGuard Home",
"auto_clients_desc": "Informace o IP adresách zařízení, která používají nebo mohou používat AdGuard Home. Tyto informace se získávají z několika zdrojů, včetně souborů hosts, reverzního DNS atd.",
"access_title": "Nastavení přístupu",
"access_desc": "Zde můžete konfigurovat pravidla přístupu pro server DNS AdGuard Home",
"access_allowed_title": "Povolení klienti",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Pro použití <1>DNS skrze HTTPS</1> nebo <1>DNS skrze TLS</1> potřebujete v nastaveních AdGuard Home <0>nakonfigurovat šifrování</0>.",
"rewrite_added": "Přesměrování DNS pro „{{key}}“ úspěšně přidáno",
"rewrite_deleted": "Přesměrování DNS pro „{{key}}“ úspěšně smazáno",
"rewrite_updated": "Přesměrování DNS bylo úspěšně aktualizováno",
"rewrite_add": "Přidat přesměrování DNS",
"rewrite_edit": "Upravit přesměrování DNS",
"rewrite_not_found": "Přesměrování DNS nenalezeny",
"rewrite_confirm_delete": "Jste si jisti, že chcete smazat přesměrování DNS pro „{{key}}“?",
"rewrite_desc": "Umožňuje snadno nakonfigurovat vlastní DNS odezvy pro konkrétní název domény.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Hyppigste klienter",
"no_clients_found": "Ingen klienter fundet",
"general_statistics": "Generelle statistikker",
"top_upstreams": "Top-upstreams",
"no_upstreams_data_found": "Ingen upstreams-data fundet",
"number_of_dns_query_days": "Antallet af DNS-forespørgsler behandlet den seneste {{count}} dag",
"number_of_dns_query_days_plural": "Antallet af DNS-forespørgsler behandlet de seneste {{count}} dage",
"number_of_dns_query_24_hours": "Antallet af DNS-forespørgsler behandlet de seneste 24 timer",
@@ -134,6 +136,7 @@
"enforced_save_search": "Håndhævet sikker søgning",
"number_of_dns_query_to_safe_search": "Antallet af DNS-forespørgsler til søgemaskiner, hvor Sikker Søgning blev håndhævet",
"average_processing_time": "Gennemsnitlig behandlingstid",
"processing_time": "Behandlingstid",
"average_processing_time_hint": "Gennemsnitlig behandlingstid i millisekunder af DNS-forespørgsel",
"block_domain_use_filters_and_hosts": "Blokér domæner vha. filtre og værtsfiler",
"filters_block_toggle_hint": "Du kan opsætte blokeringsregler i <a>Filterindstillingerne</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Opsat i {{path}}",
"test_upstream_btn": "Test upstreams",
"upstreams": "Upstreams",
"upstream": "Upstream",
"apply_btn": "Anvend",
"disabled_filtering_toast": "Filtrering deaktiveret",
"enabled_filtering_toast": "Filtrering aktiveret",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Sikker på, at du vil slette klient \"{{key}}\"?",
"list_confirm_delete": "Sikker på, at du vil slette denne liste?",
"auto_clients_title": "Klienter (runtime)",
"auto_clients_desc": "Enheder, som ikke er på listen over Permanente klienter, kan stadig bruge AdGuard Home",
"auto_clients_desc": "Oplysninger om IP-adresser på enheder, som (måske) bruger AdGuard Home. Disse oplysninger indsamles fra flere kilder, herunder hosts-filer, reverse DNS mv.",
"access_title": "Adgangsindstillinger",
"access_desc": "Her kan adgangsregler for AdGuard Home DNS-serveren opsættes",
"access_allowed_title": "Tilladte klienter",
@@ -478,7 +482,9 @@
"setup_dns_notice": "For at kunne bruge <1>DNS-over-HTTPS</1> eller <1>DNS-over-TLS</1>, skal du <0>opsætte Krypteringen</0> i AdGuard Homes indstillinger.",
"rewrite_added": "DNS-omskrivning for \"{{key}}\" blev tilføjet",
"rewrite_deleted": "DNS-omskrivning for \"{{key}}\" blev slettet",
"rewrite_updated": "DNS-omskrivning hermed opdateret",
"rewrite_add": "Tilføj DNS-omskrivning",
"rewrite_edit": "Redigér DNS-omskrivning",
"rewrite_not_found": "Ingen DNS-omskrivninger fundet",
"rewrite_confirm_delete": "Sikker på, at du vil slette DNS-omskrivning for \"{{key}}\"?",
"rewrite_desc": "Gør det nemt at opsætte det tilpassede DNS-svar for et specifikt domænenavn.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Top Clients",
"no_clients_found": "Keine Clients gefunden",
"general_statistics": "Allgemeine Statistiken",
"top_upstreams": "Top Upstreams",
"no_upstreams_data_found": "Keine Upstream-Daten gefunden",
"number_of_dns_query_days": "Anzahl der in den letzten {{count}} Tagen verarbeiteten DNS-Anfragen",
"number_of_dns_query_days_plural": "Anzahl der DNS-Abfragen, die in den letzten {{count}} Tagen verarbeitet wurden",
"number_of_dns_query_24_hours": "Anzahl der in den letzten 24 Stunden durchgeführten DNS-Anfragen",
@@ -134,6 +136,7 @@
"enforced_save_search": "Sichere Suche erzwungen",
"number_of_dns_query_to_safe_search": "Anzahl der DNS-Anfragen bei denen Sichere Suche für Suchanfragen erzwungen wurde",
"average_processing_time": "Durchschnittliche Bearbeitungsdauer",
"processing_time": "Verarbeitungszeit",
"average_processing_time_hint": "Durchschnittliche Zeit in Millisekunden zur Bearbeitung von DNS-Anfragen",
"block_domain_use_filters_and_hosts": "Domains durch Filter und Host-Dateien sperren",
"filters_block_toggle_hint": "Sie können Blockierregeln in den <a>Filter</a>einstellungen erstellen.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Konfiguriert in {{path}}",
"test_upstream_btn": "Upstreams testen",
"upstreams": "Upstreams",
"upstream": "Upstream",
"apply_btn": "Anwenden",
"disabled_filtering_toast": "Filtern deaktiviert",
"enabled_filtering_toast": "Filtern aktiviert",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Möchten Sie den Client „{{key}}“ wirklich löschen?",
"list_confirm_delete": "Möchten Sie diese Liste wirklich löschen?",
"auto_clients_title": "Laufzeit-Clients",
"auto_clients_desc": "Geräte, die nicht auf der Liste der persistenten Clients stehen und trotzdem AdGuard Home verwenden dürfen",
"auto_clients_desc": "Informationen über IP-Adressen der Geräten, die AdGuard Home nutzen oder nutzen könnten. Diese Informationen werden aus verschiedenen Quellen gesammelt, darunter Hosts-Dateien, Reverse-DNS usw.",
"access_title": "Zugriffsrechte",
"access_desc": "Hier können Sie die Zugriffsregeln für den DNS-Server von AdGuard Home konfigurieren",
"access_allowed_title": "Zugelassene Clients",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Um <1>DNS-over-HTTTPS</1> oder <1>DNS-over-TLS</1> verwenden zu können, müssen Sie in den AdGuard Home Einstellungen die <0>Verschlüsselung konfigurieren</0>.",
"rewrite_added": "DNS-Umschreibung für „{{key}}“ erfolgreich hinzugefügt",
"rewrite_deleted": "DNS-Umschreibung für „{{key}}“ erfolgreich entfernt",
"rewrite_updated": "DNS-Rewrite erfolgreich aktualisiert",
"rewrite_add": "DNS-Umschreibung hinzufügen",
"rewrite_edit": "DNS-Rewrite bearbeiten",
"rewrite_not_found": "Keine DNS-Umschreibungen gefunden",
"rewrite_confirm_delete": "Möchten Sie die DNS-Umschreibung für „{{key}}“ wirklich entfernen?",
"rewrite_desc": "Ermöglicht die einfache Konfiguration der benutzerdefinierten DNS-Antwort für einen bestimmten Domainnamen.",

View File

@@ -7,7 +7,7 @@
"load_balancing": "Load-balancing",
"load_balancing_desc": "Query one upstream server at a time. AdGuard Home uses its weighted random algorithm to pick the server so that the fastest server is used more often.",
"bootstrap_dns": "Bootstrap DNS servers",
"bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams.",
"bootstrap_dns_desc": "IP addresses of DNS servers used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams. Comments are not permitted.",
"local_ptr_title": "Private reverse DNS servers",
"local_ptr_desc": "The DNS servers that AdGuard Home uses for local PTR queries. These servers are used to resolve PTR requests for addresses in private IP ranges, for example \"192.168.12.34\", using reverse DNS. If not set, AdGuard Home uses the addresses of the default DNS resolvers of your OS except for the addresses of AdGuard Home itself.",
"local_ptr_default_resolver": "By default, AdGuard Home uses the following reverse DNS resolvers: {{ip}}.",
@@ -125,6 +125,8 @@
"top_clients": "Top clients",
"no_clients_found": "No clients found",
"general_statistics": "General statistics",
"top_upstreams": "Top upstreams",
"no_upstreams_data_found": "No upstreams data found",
"number_of_dns_query_days": "The number of DNS queries processed for the last {{count}} day",
"number_of_dns_query_days_plural": "The number of DNS queries processed for the last {{count}} days",
"number_of_dns_query_24_hours": "The number of DNS queries processed for the last 24 hours",
@@ -134,6 +136,7 @@
"enforced_save_search": "Enforced safe search",
"number_of_dns_query_to_safe_search": "The number of DNS requests to search engines for which Safe Search was enforced",
"average_processing_time": "Average processing time",
"processing_time": "Processing time",
"average_processing_time_hint": "Average time in milliseconds on processing a DNS request",
"block_domain_use_filters_and_hosts": "Block domains using filters and hosts files",
"filters_block_toggle_hint": "You can setup blocking rules in the <a>Filters</a> settings.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configured in {{path}}",
"test_upstream_btn": "Test upstreams",
"upstreams": "Upstreams",
"upstream": "Upstream",
"apply_btn": "Apply",
"disabled_filtering_toast": "Disabled filtering",
"enabled_filtering_toast": "Enabled filtering",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Are you sure you want to delete client \"{{key}}\"?",
"list_confirm_delete": "Are you sure you want to delete this list?",
"auto_clients_title": "Runtime clients",
"auto_clients_desc": "Devices not on the list of Persistent clients that may still use AdGuard Home",
"auto_clients_desc": "Information about IP addresses of devices that are using or may use AdGuard Home. This information is gathered from several sources, including hosts files, reverse DNS, etc.",
"access_title": "Access settings",
"access_desc": "Here you can configure access rules for the AdGuard Home DNS server",
"access_allowed_title": "Allowed clients",
@@ -478,7 +482,9 @@
"setup_dns_notice": "In order to use <1>DNS-over-HTTPS</1> or <1>DNS-over-TLS</1>, you need to <0>configure Encryption</0> in AdGuard Home settings.",
"rewrite_added": "DNS rewrite for \"{{key}}\" successfully added",
"rewrite_deleted": "DNS rewrite for \"{{key}}\" successfully deleted",
"rewrite_updated": "DNS rewrite successfully updated",
"rewrite_add": "Add DNS rewrite",
"rewrite_edit": "Edit DNS rewrite",
"rewrite_not_found": "No DNS rewrites found",
"rewrite_confirm_delete": "Are you sure you want to delete DNS rewrite for \"{{key}}\"?",
"rewrite_desc": "Allows to easily configure custom DNS response for a specific domain name.",
@@ -562,7 +568,7 @@
"rewrite_A": "<0>A</0>: special value, keep <0>A</0> records from the upstream",
"rewrite_AAAA": "<0>AAAA</0>: special value, keep <0>AAAA</0> records from the upstream",
"disable_ipv6": "Disable resolving of IPv6 addresses",
"disable_ipv6_desc": "Drop all DNS queries for IPv6 addresses (type AAAA).",
"disable_ipv6_desc": "Drop all DNS queries for IPv6 addresses (type AAAA) and remove IPv6 hints from HTTPS responses.",
"fastest_addr": "Fastest IP address",
"fastest_addr_desc": "Query all DNS servers and return the fastest IP address among all responses. This slows down DNS queries as AdGuard Home has to wait for responses from all DNS servers, but improves the overall connectivity.",
"autofix_warning_text": "If you click \"Fix\", AdGuard Home will configure your system to use AdGuard Home DNS server.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Clientes más frecuentes",
"no_clients_found": "No se han encontrado clientes",
"general_statistics": "Estadísticas generales",
"top_upstreams": "Mejores upstreams",
"no_upstreams_data_found": "No se han encontrado datos de upstreams",
"number_of_dns_query_days": "Número de consultas DNS procesadas durante el último {{count}} día",
"number_of_dns_query_days_plural": "Número de consultas DNS procesadas durante los últimos {{count}} días",
"number_of_dns_query_24_hours": "Número de consultas DNS procesadas durante las últimas 24 horas",
@@ -134,6 +136,7 @@
"enforced_save_search": "Búsquedas seguras forzadas",
"number_of_dns_query_to_safe_search": "Número de peticiones DNS a los motores de búsqueda para los que se aplicó la búsqueda segura forzada",
"average_processing_time": "Tiempo promedio de procesamiento",
"processing_time": "Tiempo de procesamiento",
"average_processing_time_hint": "Tiempo promedio en milisegundos al procesar una petición DNS",
"block_domain_use_filters_and_hosts": "Bloquear dominios usando filtros y archivos hosts",
"filters_block_toggle_hint": "Puedes configurar las reglas de bloqueo en la configuración de <a>filtros</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configurado en {{path}}",
"test_upstream_btn": "Probar DNS de subida",
"upstreams": "DNS de subida",
"upstream": "Upstream",
"apply_btn": "Aplicar",
"disabled_filtering_toast": "Filtrado deshabilitado",
"enabled_filtering_toast": "Filtrado habilitado",
@@ -444,7 +448,7 @@
"client_confirm_delete": "¿Estás seguro de que deseas eliminar el cliente \"{{key}}\"?",
"list_confirm_delete": "¿Estás seguro de que deseas eliminar esta lista?",
"auto_clients_title": "Clientes activos",
"auto_clients_desc": "Dispositivos que no están en la lista de clientes persistentes que aún pueden utilizar AdGuard Home",
"auto_clients_desc": "Información sobre las direcciones IP de los dispositivos que usan o pueden usar AdGuard Home. Esta información se recopila de varias fuentes, incluidos ficheros de host, DNS inverso, etc.",
"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",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Para utilizar <1>DNS mediante HTTPS</1> o <1>DNS mediante TLS</1>, debes <0>configurar el cifrado</0> en la configuración de AdGuard Home.",
"rewrite_added": "Reescritura DNS para \"{{key}}\" añadido correctamente",
"rewrite_deleted": "Reescritura DNS para \"{{key}}\" eliminado correctamente",
"rewrite_updated": "Reconfiguración de DNS actualizada correctamente",
"rewrite_add": "Añadir reescritura DNS",
"rewrite_edit": "Editar reconfiguración de DNS",
"rewrite_not_found": "No se han encontrado reescrituras DNS",
"rewrite_confirm_delete": "¿Estás seguro de que deseas eliminar la reescritura DNS para \"{{key}}\"?",
"rewrite_desc": "Permite configurar fácilmente la respuesta DNS personalizada para un nombre de dominio específico.",

View File

@@ -118,6 +118,8 @@
"top_clients": "بالاترین کلاینت ها",
"no_clients_found": "کلاینتی یافت نشد",
"general_statistics": "آمار عمومی",
"top_upstreams": "سرورهای بالادست بالا",
"no_upstreams_data_found": "هیچ اطلاعاتی در مورد سرورهای بالادست یافت نشد",
"number_of_dns_query_days": "تعداد جستار DNS پردازش شده در {{count}} روز آخر",
"number_of_dns_query_days_plural": "تعداد جستار DNS پردازش شده در {{count}} روز گذشته",
"number_of_dns_query_24_hours": "تعداد جستار DNS پردازش شده در 24 ساعت گذشته",
@@ -149,6 +151,7 @@
"upstream_dns": "سرورهای DNS جریان ارسالی",
"test_upstream_btn": "تست جریان ارسالی",
"upstreams": "جریان ارسالی",
"upstream": "سرور مادر",
"apply_btn": "اِعمال",
"disabled_filtering_toast": "فیلترینگ غیرفعال شده است",
"enabled_filtering_toast": "فیلترینگ فعال شده است",
@@ -440,7 +443,9 @@
"setup_dns_notice": "به منظور استفاده از <1>DNS-over-HTTPS</1> یا <1>DNS-over-TLS</1>، شما نیاز به <0>پیکربندی رمزگذاری</0> در تنظیمات AdGuard Home دارید.",
"rewrite_added": "بازنویسی DNS برای \"{{key}}\" با موفقیت اضافه شد",
"rewrite_deleted": "بازنویسی DNS برای \"{{key}}\" با موفقیت حذف شد",
"rewrite_updated": "بازنویسی DNS با موفقیت به روز شد",
"rewrite_add": "افزودن بازنویسی DNS",
"rewrite_edit": "بازنویسی DNS را ویرایش کنید",
"rewrite_not_found": "بازنویسی DNS یافت نشد",
"rewrite_confirm_delete": "آیا واقعا میخواهید بازنویسی DNS برای \"{{key}}\" را حذف کنید؟",
"rewrite_desc": "به آسانی اجازه پیکربندی پاسخ DNS دستی برای یک نام دامنه خاص را می دهد.",

View File

@@ -2,21 +2,21 @@
"client_settings": "Päätelaiteasetukset",
"example_upstream_reserved": "ylävirta <0>tietyille verkkotunnuksille</0>;",
"example_upstream_comment": "kommentti.",
"upstream_parallel": "Käytä rinnakkaisia pyyntöjä ja nopeuta selvitystä käyttämällä kaikkia ylävirran palvelimia samanaikaisesti.",
"upstream_parallel": "Käytä rinnakkaisia pyyntöjä ja nopeuta selvitystä käyttämällä kaikkia ylävirtapalvelimia samanaikaisesti.",
"parallel_requests": "Rinnakkaiset pyynnöt",
"load_balancing": "Kuormantasaus",
"load_balancing_desc": "Lähetä pyyntö yhdelle ylävirran palvelimelle kerrallaan. AdGuard Home pyrkii valitsemaan nopeimman palvelimen painotetun satunnaisalgoritminsa avulla.",
"load_balancing_desc": "Lähetä pyyntö yhdelle ylävirtapalvelimelle kerrallaan. AdGuard Home pyrkii valitsemaan nopeimman palvelimen painotetun satunnaisalgoritminsa avulla.",
"bootstrap_dns": "Bootstrap DNS-palvelimet",
"bootstrap_dns_desc": "Bootstrap DNS-palvelimia käytetään ylävirroiksi määritettyjen DoH/DoT-resolvereiden IP-osoitteiden selvitykseen.",
"local_ptr_title": "Yksityiset käänteiset DNS-palvelimet",
"local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-pyynnöille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien PTR-pyyntöjen osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteisen DNS:n avulla. Jos ei käytössä, AdGuard Home käyttää käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.",
"local_ptr_default_resolver": "Oletusarvoisesti AdGuard Home käyttää seuraavia käänteisDNS-resolvereita: {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home ei voinut määrittää tälle järjestelmälle sopivaa yksityistä käänteisDNS-resolveria.",
"local_ptr_title": "Yksityiset käänteis-DNS-palvelimet",
"local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-pyynnöille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien PTR-pyyntöjen osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteis-DNS:n avulla. Jos ei käytössä, AdGuard Home käyttää käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.",
"local_ptr_default_resolver": "Oletusarvoisesti AdGuard Home käyttää seuraavia käänteis-DNS-resolvereita: {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home ei voinut määrittää tälle järjestelmälle sopivaa yksityistä käänteis-DNS-resolveria.",
"local_ptr_placeholder": "Syötä yksi palvelimen osoite per rivi",
"resolve_clients_title": "Käytä päätelaitteiden IP-osoitteille käänteistä selvitystä",
"resolve_clients_desc": "Selvitä päätelaitteiden IP-osoitteiden isäntänimet käänteisesti lähettämällä PTR-pyynnöt sopiville resolvereille (yksityiset DNS-palvelimet paikallisille päätelaitteille, lähtevät palvelimet päätelaitteille, joilla on julkiset IP-osoitteet).",
"use_private_ptr_resolvers_title": "Käytä yksityisiä käänteisDNS-resolvereita",
"use_private_ptr_resolvers_desc": "Suorita käänteiset DNS-selvitykset paikallisesti tarjotuille osoitteille käyttäen näitä ylävirran palvelimia. Jos ei käytössä, vastaa AdGuard Home kaikkiin sen tyyppisiin PTR-pyyntöihin NXDOMAIN-arvolla, pois lukien DHCP, /etc/hosts, yms. -tiedoista tunnistettut päätelaitteet.",
"resolve_clients_desc": "Selvitä päätelaitteiden IP-osoitteiden isäntänimet käänteisesti lähettämällä PTR-pyynnöt sopiville resolvereille (yksityiset DNS-palvelimet paikallisille päätelaitteille, yvirtapalvelimet päätelaitteille, joilla on julkiset IP-osoitteet).",
"use_private_ptr_resolvers_title": "Käytä yksityisiä käänteis-DNS-resolvereita",
"use_private_ptr_resolvers_desc": "Suorita käänteis-DNS-selvitykset paikallisesti tarjotuille osoitteille käyttäen näitä ylävirtapalvelimia. Jos ei käytössä, vastaa AdGuard Home kaikkiin sen tyyppisiin PTR-pyyntöihin NXDOMAIN-arvolla, pois lukien DHCP, /etc/hosts, yms. -tiedoista tunnistettut päätelaitteet.",
"check_dhcp_servers": "Etsi DHCP-palvelimia",
"save_config": "Tallenna asetukset",
"enabled_dhcp": "DHCP-palvelin otettiin käyttöön",
@@ -125,6 +125,8 @@
"top_clients": "Käytetyimmät päätelaitteet",
"no_clients_found": "Päätelaitteita ei löytynyt",
"general_statistics": "Yleiset tilastot",
"top_upstreams": "Käytetyimmät ylävirrat",
"no_upstreams_data_found": "Ylävirtatietoja ei löytynyt",
"number_of_dns_query_days": "Käsiteltyjen DNS-pyyntöjen määrä viimeisten {{count}} päivän ajalta",
"number_of_dns_query_days_plural": "Käsiteltyjen DNS-pyyntöjen määrä viimeisten {{count}} päivän ajalta",
"number_of_dns_query_24_hours": "Käsiteltyjen DNS-pyyntöjen määrä viimeisten 24 tunnin ajalta",
@@ -134,6 +136,7 @@
"enforced_save_search": "Turvallinen haku pakotettiin",
"number_of_dns_query_to_safe_search": "DNS-pyyntöjen määrä, joille turvallinen haku pakotettiin käyttöön",
"average_processing_time": "Keskimääräinen käsittelyaika",
"processing_time": "Käsittelyaika",
"average_processing_time_hint": "Keskimääräinen DNS-pyynnön käsittelyyn kulutettu aika millisekunteina",
"block_domain_use_filters_and_hosts": "Estä verkkotunnuksia suodattimilla ja hosts-tiedostoilla",
"filters_block_toggle_hint": "Voit määrittää estosääntöjä <a>suodatinasetuksissa</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Määritetty tiedostossa {{path}}",
"test_upstream_btn": "Testaa ylävirtoja",
"upstreams": "Ylävirrat",
"upstream": "Ylävirta",
"apply_btn": "Käytä",
"disabled_filtering_toast": "Suodatus poistettiin käytöstä",
"enabled_filtering_toast": "Suodatus otettiin käyttöön",
@@ -220,9 +224,9 @@
"example_upstream_tcp_port": "tavallinen DNS (TCP, portti);",
"example_upstream_tcp_hostname": "tavallinen DNS (TCP, isäntänimi);",
"all_lists_up_to_date_toast": "Kaikki listat ovat ajan tasalla",
"updated_upstream_dns_toast": "Ylävirtojen palvelimet tallennettiin",
"updated_upstream_dns_toast": "Ylävirtapalvelimet tallennettiin",
"dns_test_ok_toast": "Määritetyt DNS-palvelimet toimivat oikein",
"dns_test_not_ok_toast": "Palvelin \"{{key}}\": ei voitu käyttää, tarkista sen oikeinkirjoitus",
"dns_test_not_ok_toast": "Palvelin \"{{key}}\": Ei voitu käyttää, tarkista oikeinkirjoitus",
"dns_test_warning_toast": "Datavuon \"{{key}}\" ei vastaa testipyyntöihin eikä välttämättä toimi kunnolla",
"unblock": "Salli",
"block": "Estä",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Haluatko varmasti poistaa päätelaitteen \"{{key}}\"?",
"list_confirm_delete": "Haluatko varmasti poistaa tämän listan?",
"auto_clients_title": "Määrittämättömät päätelaitteet",
"auto_clients_desc": "Päätelaitteet, joita ei ole määritetty pysyviksi ja jotka voivat silti käyttää AdGuard Homea.",
"auto_clients_desc": "Päätelaitteet, joita ei ole määritetty pysyviksi ja jotka voivat silti käyttää AdGuard Homea. Näitä tietoja kertään useista lähteistä, mm. hosts-tiedostoista ja kääteis-DNS:llä.",
"access_title": "Käytön asetukset",
"access_desc": "Tässä voidaan määrittää AdGuard Homen DNS-palvelimen käyttöoikeussääntöjä.",
"access_allowed_title": "Sallitut päätelaitteet",
@@ -478,7 +482,9 @@
"setup_dns_notice": "<1>DNS-over-HTTPS</1> tai <1>DNS-over-TLS</1> -toteutuksia varten, on AdGuard Homen <0>Salausasetukset</0> määritettävä.",
"rewrite_added": "Kohteen \"{{key}}\" DNS-uudelleenohjaus lisättiin",
"rewrite_deleted": "Kohteen \"{{key}}\" DNS-uudelleenohjaus poistettiin",
"rewrite_updated": "DNS-uudelleenohjaukset päivitettiin",
"rewrite_add": "Lisää DNS-uudelleenohjaus",
"rewrite_edit": "Muokkaa DNS-uudelleenohjausta",
"rewrite_not_found": "DNS-uudelleenohjauksia ei löytynyt",
"rewrite_confirm_delete": "Haluatko varmasti poistaa DNS-uudelleenohjauksen kohteelle \"{{key}}\"?",
"rewrite_desc": "Mahdollistaa oman DNS-vastauksen helpon määrityksen tietylle verkkotunnukselle.",
@@ -621,7 +627,7 @@
"enter_cache_size": "Syötä välimuistin koko (tavuina)",
"enter_cache_ttl_min_override": "Syötä vähimmäis-TTL (sekunteina)",
"enter_cache_ttl_max_override": "Syötä enimmäis-TTL (sekunteina)",
"cache_ttl_min_override_desc": "Pidennä ylävirran palvelimelta vastaanotettuja, lyhyitä elinaika-arvoja (sekunteina) tallennettaessa DNS-vastauksia välimuistiin.",
"cache_ttl_min_override_desc": "Pidennä ylävirtapalvelimelta vastaanotettuja, lyhyitä elinaika-arvoja (sekunteina) tallennettaessa DNS-vastauksia välimuistiin.",
"cache_ttl_max_override_desc": "Määritä DNS-välimuistin kohteiden enimmäiselinaika (sekunteina).",
"ttl_cache_validation": "Välimuistin vähimmäiselinajan on oltava pienempi tai sama kuin enimmäiselinajan",
"cache_optimistic": "Optimistinen välimuisti",

View File

@@ -125,6 +125,8 @@
"top_clients": "Meilleurs clients",
"no_clients_found": "Pas de clients trouvés",
"general_statistics": "Statistiques générales",
"top_upstreams": "Top amonts",
"no_upstreams_data_found": "Aucune donnée en amont trouvée",
"number_of_dns_query_days": "Le nombre de requêtes DNS traitées pour les {{count}} derniers jours",
"number_of_dns_query_days_plural": "Le nombre de requêtes DNS traitées ces {{count}} derniers jours",
"number_of_dns_query_24_hours": "Le nombre de requêtes DNS traitées au cours des 24 dernières heures",
@@ -134,6 +136,7 @@
"enforced_save_search": "Recherche sécurisée forcée",
"number_of_dns_query_to_safe_search": "Le nombre de requêtes DNS faites avec la Recherche securisée",
"average_processing_time": "Temps moyen de traitement",
"processing_time": "Délai de traitement",
"average_processing_time_hint": "Temps moyen (en millisecondes) de traitement d'une requête DNS",
"block_domain_use_filters_and_hosts": "Bloquez les domaines à l'aide des filtres et fichiers hosts",
"filters_block_toggle_hint": "Vous pouvez configurer les règles de filtrage dans les paramètres des <a>Filtres</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configuré dans {{path}}",
"test_upstream_btn": "Tester les upstreams",
"upstreams": "En amont",
"upstream": "Amont",
"apply_btn": "Appliquer",
"disabled_filtering_toast": "Filtrage désactivé",
"enabled_filtering_toast": "Filtrage activé",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Voulez-vous vraiment supprimer le client « {{key}} » ?",
"list_confirm_delete": "Voulez-vous vraiment supprimer cette liste ?",
"auto_clients_title": "Clients d'exécution",
"auto_clients_desc": "Appareils ne figurant pas sur la liste des clients persistants qui peuvent encore utiliser AdGuard Home.",
"auto_clients_desc": "Informations sur les adresses IP des appareils qui utilisent ou pourraient utiliser AdGuard Home. Ces informations sont recueillies à partir de plusieurs sources, notamment les fichiers hosts, le DNS inverse, etc.",
"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",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Pour utiliser le <1>DNS-over-HTTPS</1> ou le <1>DNS-over-TLS</1>, vous devez <0>configurer le Chiffrement</0> dans les paramètres de AdGuard Home.",
"rewrite_added": "Réécriture DNS pour « {{key}} » ajoutée",
"rewrite_deleted": "Réécriture DNS pour « {{key}} » supprimée",
"rewrite_updated": "Réécriture DNS mise à jour",
"rewrite_add": "Ajouter une réécriture DNS",
"rewrite_edit": "Modifier la réécriture DNS",
"rewrite_not_found": "Aucune réécriture DNS trouvée",
"rewrite_confirm_delete": "Voulez-vous vraiment supprimer la réécriture DNS pour « {{key}} » ?",
"rewrite_desc": "Permet de configurer facilement la réponse DNS personnalisée pour un nom de domaine spécifique.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Top klijenti",
"no_clients_found": "Nema pronađenih klijenata",
"general_statistics": "Opća statistika",
"top_upstreams": "Top upstream poslužitelji",
"no_upstreams_data_found": "Nema podataka o upstream poslužiteljima",
"number_of_dns_query_days": "Broj DNS upita obrađenih u posljednja {{count}} dan",
"number_of_dns_query_days_plural": "Broj DNS upita obrađenih u posljednja {{count}} dana",
"number_of_dns_query_24_hours": "Broj DNS upita obrađenih u posljednja 24 sata",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Postavljeno u {{path}}",
"test_upstream_btn": "Testiraj upstream-ove",
"upstreams": "Upstreams",
"upstream": "Upstream poslužitelj",
"apply_btn": "Primijeni",
"disabled_filtering_toast": "Onemogućeno filtriranje",
"enabled_filtering_toast": "Omogućeno filtriranje",
@@ -444,7 +447,7 @@
"client_confirm_delete": "Jeste li sigurni da želite ukloniti \"{{key}}\" klijenta?",
"list_confirm_delete": "Jeste li sigurni da želite ukloniti ovaj popis?",
"auto_clients_title": "Runtime klijenti",
"auto_clients_desc": "Podaci na klijentu koji koriste AdGuard Home, ali se ne mijenjaju u postavkama",
"auto_clients_desc": "Informacije o IP adresama uređaja koji koriste ili bi mogli koristiti AdGuard Home. Ove informacije prikupljaju se iz nekoliko izvora, uključujući datoteke hostova, obrnuti DNS itd.",
"access_title": "Postavke pristupa",
"access_desc": "Ovdje možete konfigurirati pravila pristupa za AdGuard Home DNS poslužitelj",
"access_allowed_title": "Dopušteni klijenti",
@@ -478,7 +481,9 @@
"setup_dns_notice": "Da biste koristili <1>DNS-over-HTTPS</1> ili <1>DNS-over-TLS</1>, morate <0>postaviti šifriranje</0> u AdGuard Home postavkama.",
"rewrite_added": "DNS prijepis za \"{{key}}\" je uspješno dodan",
"rewrite_deleted": "DNS prijepis za \"{{key}}\" je uspješno uklonjen",
"rewrite_updated": "Prepisivanje DNS-a uspješno ažurirano",
"rewrite_add": "Dodaj DNS prijepis",
"rewrite_edit": "Uredite prepisivanje DNS-a",
"rewrite_not_found": "Nema DNS prijepisa",
"rewrite_confirm_delete": "Jeste li sigurni da želite ukloniti DNS prijepis za \"{{key}}\" klijenta?",
"rewrite_desc": "Omogućuje jednostavno postavljanje prilagođenog DNS odgovora za određenu domenu.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Legaktívabb kliensek",
"no_clients_found": "Nem található kliens",
"general_statistics": "Általános statisztikák",
"top_upstreams": "Top upstream szerverek",
"no_upstreams_data_found": "Nem található upstream szerver adat",
"number_of_dns_query_days": "Lekérdezések száma az utolsó {{count}} napban",
"number_of_dns_query_days_plural": "Feldolgozott DNS lekérdezések száma az utolsó {{count}} napban",
"number_of_dns_query_24_hours": "Az elmúlt 24 órában feldolgozott DNS lekérdezések száma",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Beállítva itt: {{path}}",
"test_upstream_btn": "Upstreamek tesztelése",
"upstreams": "Upstream-ek",
"upstream": "Upstream szerver",
"apply_btn": "Alkalmaz",
"disabled_filtering_toast": "Szűrés letiltva",
"enabled_filtering_toast": "Szűrés engedélyezve",
@@ -167,6 +170,7 @@
"enabled_parental_toast": "Szülői felügyelet engedélyezve",
"disabled_safe_search_toast": "Biztonságos keresés letiltva",
"enabled_save_search_toast": "Biztonságos keresés engedélyezve",
"updated_save_search_toast": "A Biztonságos keresés beállításai frissítve",
"enabled_table_header": "Engedélyezve",
"name_table_header": "Név",
"list_url_table_header": "Lista URL-je",
@@ -290,6 +294,8 @@
"rate_limit": "Kérések korlátozása",
"edns_enable": "EDNS kliens alhálózat engedélyezése",
"edns_cs_desc": "Adja hozzá az EDNS Client Subnet beállítást (ECS) a felfelé irányuló kérésekhez, és naplózza a kliensek által küldött értékeket a lekérdezési naplóban.",
"edns_use_custom_ip": "Használjon egyéni IP-címet az EDNS-hez",
"edns_use_custom_ip_desc": "Engedélyezze az egyéni IP-cím használatát az EDNS-hez",
"rate_limit_desc": "Maximálisan hány kérést küldhet egy kliens másodpercenkén. Ha 0-ra állítja, akkor nincs korlátozás.",
"blocking_ipv4_desc": "A blokkolt A kéréshez visszaadandó IP-cím",
"blocking_ipv6_desc": "A blokkolt AAAA kéréshez visszaadandó IP-cím",
@@ -441,7 +447,7 @@
"client_confirm_delete": "Biztosan törölni szeretné a(z) \"{{key}}\" klienst?",
"list_confirm_delete": "Biztosan törölni kívánja ezt a listát?",
"auto_clients_title": "Futási idejű kliensek",
"auto_clients_desc": "Ezek az eszközök nem szerepelnek a fenntartott kliensek listáján, de használják az AdGuard Home-ot",
"auto_clients_desc": "Az AdGuard Home-ot használó vagy esetleg használó eszközök IP-címeire vonatkozó információk. Ezeket az információkat több forrásból gyűjtik, beleértve a hosts fájlokat, a fordított DNS-t stb.",
"access_title": "Hozzáférési beállítások",
"access_desc": "Itt konfigurálhatja az AdGuard Home DNS-kiszolgáló hozzáférési szabályait",
"access_allowed_title": "Engedélyezett kliensek",
@@ -475,7 +481,9 @@
"setup_dns_notice": "Ahhoz, hogy a <1>DNS-over-HTTPS</1> vagy a <1>DNS-over-TLS</1> valamelyikét használja, muszáj <0>beállítania a titkosítást</0> az AdGuard Home beállításaiban.",
"rewrite_added": "DNS átírás a(z) \"{{key}}\" kulcshoz sikeresen hozzáadva",
"rewrite_deleted": "DNS átírás a(z) \"{{key}}\" kulcshoz sikeresen törölve",
"rewrite_updated": "A DNS újraírása sikeresen frissítve",
"rewrite_add": "DNS átírás hozzáadása",
"rewrite_edit": "DNS újraírás szerkesztése",
"rewrite_not_found": "Nem találhatók DNS átírások",
"rewrite_confirm_delete": "Biztosan törölni szeretné a DNS átírást ehhez: \"{{key}}\"?",
"rewrite_desc": "Lehetővé teszi, hogy egyszerűen beállítson egyéni DNS választ egy adott domain névhez.",
@@ -523,6 +531,10 @@
"statistics_retention_confirm": "Biztos benne, hogy megváltoztatja a statisztika megőrzési idejét? Ha csökkentette az értéket, a megadottnál korábbi adatok elvesznek",
"statistics_cleared": "A statisztikák sikeresen vissza lettek állítva",
"statistics_enable": "Statisztikák engedélyezése",
"ignore_domains": "Figyelmen kívül hagyott domainek (újsorral elválasztva)",
"ignore_domains_title": "Figyelmen kívül hagyott domainek",
"ignore_domains_desc_stats": "Az ezekre a tartományokra vonatkozó lekérdezések nem kerülnek a statisztikákba",
"ignore_domains_desc_query": "Az ezekhez a tartományokhoz tartozó lekérdezések nem kerülnek a lekérdezési naplóba",
"interval_hours": "{{count}} óra",
"interval_hours_plural": "{{count}} óra",
"filters_configuration": "Szűrők beállításai",
@@ -643,5 +655,29 @@
"confirm_dns_cache_clear": "Biztos benne, hogy törölni szeretné a DNS-gyorsítótárat?",
"cache_cleared": "A DNS gyorsítótár sikeresen törlődött",
"clear_cache": "Gyorsítótár törlése",
"protection_section_label": "Védelem"
"make_static": "Statikussá tétel",
"theme_auto_desc": "Automatikus (az eszköz színsémájától függően)",
"theme_dark_desc": "Sötét téma",
"theme_light_desc": "Világos téma",
"disable_for_seconds": "{{count}} másodpercig",
"disable_for_seconds_plural": "{{count}} másodpercig",
"disable_for_minutes": "{{count}} percig",
"disable_for_minutes_plural": "{{count}} percig",
"disable_for_hours": "{{count}} óráig",
"disable_for_hours_plural": "{{count}} óráig",
"disable_until_tomorrow": "Holnapig",
"disable_notify_for_seconds": "Kapcsolja ki a védelmet {{count}} másodpercre",
"disable_notify_for_seconds_plural": "Kapcsolja ki a védelmet {{count}} másodpercre",
"disable_notify_for_minutes": "Kapcsolja ki a védelmet {{count}} percre",
"disable_notify_for_minutes_plural": "Kapcsolja ki a védelmet {{count}} percre",
"disable_notify_for_hours": "Kapcsolja ki a védelmet {{count}} órára",
"disable_notify_for_hours_plural": "Kapcsolja ki a védelmet {{count}} órára",
"disable_notify_until_tomorrow": "Holnapig kapcsolja ki a védelmet",
"enable_protection_timer": "A védelem {{time}}-kor aktiválódik",
"custom_retention_input": "Adja meg a megőrzést órákban",
"custom_rotation_input": "Írja be a forgatást órákban",
"protection_section_label": "Védelem",
"log_and_stats_section_label": "Lekérdezési napló és statisztikák",
"ignore_query_log": "Figyelmen kívül hagyja ezt az ügyfelet a lekérdezési naplóban",
"ignore_statistics": "Hagyja figyelmen kívül ezt az ügyfelet a statisztikákban"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "Klien teratas",
"no_clients_found": "Tidak ditemukan klien",
"general_statistics": "Statistik umum",
"top_upstreams": "Top servers upstream",
"no_upstreams_data_found": "Tidak ada data server upstream yang ditemukan",
"number_of_dns_query_days": "Jumlah kueri DNS diproses selama {{value}} hari terakhir",
"number_of_dns_query_days_plural": "Jumlah kueri DNS yang diproses selama {{count}} hari terakhir",
"number_of_dns_query_24_hours": "Jumlah kueri DNS diproses selama 24 jam terakhir",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Diatur dalam {{path}}",
"test_upstream_btn": "Uji hulu",
"upstreams": "Upstream",
"upstream": "Server upstream",
"apply_btn": "Terapkan",
"disabled_filtering_toast": "Penyaringan nonaktif",
"enabled_filtering_toast": "Penyaringan aktif",
@@ -474,7 +477,9 @@
"setup_dns_notice": "Jikalau ingin menggunakan <1>DNS-over-HTTPS</1> atau <1>DNS-over-TLS</1>, Anda perlu <0>mengatur Enkripsi</0> pada pengaturan AdGuard Home.",
"rewrite_added": "DNS rewrite untuk \"{{key}}\" berhasil ditambahkan",
"rewrite_deleted": "DNS rewrite untuk \"{{key}}\" berhasil dihapus",
"rewrite_updated": "Penulisan ulang DNS berhasil diperbarui",
"rewrite_add": "Tambah DNS rewrite",
"rewrite_edit": "Edit penulisan ulang DNS",
"rewrite_not_found": "Tidak ada DNS rewrite ditemukan",
"rewrite_confirm_delete": "Apakah anda yakin ingin menghapus DNS rewrite untuk \"{{key}}\"?",
"rewrite_desc": "Memungkinkan untuk dengan mudah mengkonfigurasi respons DNS kustom untuk nama domain tertentu.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Client più utilizzati",
"no_clients_found": "Nessun client trovato",
"general_statistics": "Statistiche generali",
"top_upstreams": "Top upstream",
"no_upstreams_data_found": "Nessun dato upstream trovato",
"number_of_dns_query_days": "Numero di richieste DNS elaborate negli ultimi {{count}} giorni",
"number_of_dns_query_days_plural": "Numero di richieste DNS elaborate negli ultimi {{count}} giorni",
"number_of_dns_query_24_hours": "Numero di richieste DNS elaborate nelle ultime 24 ore",
@@ -134,6 +136,7 @@
"enforced_save_search": "Ricerca sicura forzata",
"number_of_dns_query_to_safe_search": "Numero di richieste DNS dai motori di ricerca per i quali la Ricerca Sicura è stata forzata",
"average_processing_time": "Tempo di elaborazione medio",
"processing_time": "Tempo di elaborazione",
"average_processing_time_hint": "Tempo medio in millisecondi per elaborare una richiesta DNS",
"block_domain_use_filters_and_hosts": "Blocca domini utilizzando filtri e file hosts",
"filters_block_toggle_hint": "Puoi impostare le regole di blocco nelle impostazioni dei <a>Filtri</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configurato su {{path}}",
"test_upstream_btn": "Testa gli upstream",
"upstreams": "Upstream",
"upstream": "Upstream",
"apply_btn": "Applica",
"disabled_filtering_toast": "Disattiva filtri",
"enabled_filtering_toast": "Attiva filtri",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Sei sicuro di voler eliminare il client \"{{key}}\"?",
"list_confirm_delete": "Sei sicuro di voler eliminare questo elenco?",
"auto_clients_title": "Client in tempo reale",
"auto_clients_desc": "Dispositivi non presenti nell'elenco dei client Persistenti che possono ancora utilizzare AdGuard Home",
"auto_clients_desc": "Informazioni sugli indirizzi IP dei dispositivi che utilizzano o potrebbero utilizzare AdGuard Home. Queste informazioni vengono raccolte da diverse fonti, inclusi file host, DNS inverso, ecc.",
"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",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Per utilizzare <1>DNS su HTTPS</1> o <1>DNS su TLS</1>, è necessario <0>configurare la crittografia</0> nelle impostazioni di AdGuard Home.",
"rewrite_added": "Riscrittura DNS per \"{{key}}\" aggiunta correttamente",
"rewrite_deleted": "La riscrittura DNS per \"{{key}}\" è stata eliminata correttamente",
"rewrite_updated": "Riscrittura DNS aggiornata correttamente",
"rewrite_add": "Aggiungi la riscrittura DNS",
"rewrite_edit": "Modifica della riscrittura DNS",
"rewrite_not_found": "Nessuna riscrittura DNS trovata",
"rewrite_confirm_delete": "Sei sicuro di voler cancellare la riscrittura DNS per \"{{key}}\"?",
"rewrite_desc": "Consente di configurare facilmente la risposta DNS personalizzata per un nome di dominio specifico.",

View File

@@ -7,16 +7,16 @@
"load_balancing": "ロードバランシング",
"load_balancing_desc": "一度に1つのアップストリームサーバに処理要求します。 AdGuard Homeは、重み付きランダムアルゴリズムweighted random algorithmを使用してサーバを選択するため、最速のサーバがより頻繁に使用されます。",
"bootstrap_dns": "ブートストラップDNSサーバ",
"bootstrap_dns_desc": "ブートストラップDNSサーバは、上流として指定したDoHDoTリゾルバのIPアドレスを解決するために使用されます。",
"bootstrap_dns_desc": "ブートストラップDNSサーバは、アップストリームとして指定したDoHDoTリゾルバのIPアドレスを解決するために使用されます。",
"local_ptr_title": "プライベートリバースDNSサーバー",
"local_ptr_desc": "AdGuard HomeがローカルPTRクエリに使用するDNSサーバーです。これらのサーバーは、rDNSを使ってプライベートIPアドレス例えば\"192.168.12.34\"を持つクライアントのホスト名を解決するために使用されます。設定されていない場合、AdGuard HomeはOSのデフォルトDNSリゾルバーのアドレスAdGuard Home自体のアドレスを除くを自動的に使用します。",
"local_ptr_default_resolver": "デフォルトでは、AdGuard Homeは次のリバースDNSリゾルバを使用します: {{ip}}",
"local_ptr_no_default_resolver": "AdGuard Homeは、このシステムに適したプライベートリバースDNSリゾルバを特定できませんでした。",
"local_ptr_placeholder": "1行に1つのサーバを入力してください。",
"resolve_clients_title": "クライアントのIPアドレスの逆解決を有効にする",
"resolve_clients_desc": "対応するリゾルバーローカルクライアントの場合はプライベートDNSサーバ、パブリックIPを持つクライアントの場合は上流サーバにPTRクエリを送信することにより、クライアントのIPアドレスをホストネームに逆解決します。",
"resolve_clients_desc": "対応するリゾルバーローカルクライアントの場合はプライベートDNSサーバ、パブリックIPを持つクライアントの場合はアップストリームサーバにPTRクエリを送信することにより、クライアントのIPアドレスをホストネームに逆解決します。",
"use_private_ptr_resolvers_title": "プライベートリバースDNSリゾルバを使用",
"use_private_ptr_resolvers_desc": "これらの上流サーバを使用して、ローカルで提供されるアドレスのリバースDNSルックアップを実行します。無効にすると、AdGuard Homeは、DHCP, /etc/hosts などから認識されるクライアントを除き、すべてのこのようなPTR要求にNXDOMAINで応答します。",
"use_private_ptr_resolvers_desc": "これらのアップストリームサーバを使用して、ローカルで提供されるアドレスのリバースDNSルックアップを実行します。無効にすると、AdGuard Homeは、DHCP, /etc/hosts などから認識されるクライアントを除き、すべてのこのようなPTR要求にNXDOMAINで応答します。",
"check_dhcp_servers": "DHCPサーバをチェックする",
"save_config": "構成を保存する",
"enabled_dhcp": "DHCPサーバを有効にしました",
@@ -125,6 +125,8 @@
"top_clients": "トップクライアント",
"no_clients_found": "クライアント情報はありません",
"general_statistics": "全般的な統計",
"top_upstreams": "上位のアップストリーム",
"no_upstreams_data_found": "アップストリームのデータが見つかりません",
"number_of_dns_query_days": "過去{{count}}日間に処理されたDNSクエリの数",
"number_of_dns_query_days_plural": "過去{{count}}日間に処理されたDNSクエリの数",
"number_of_dns_query_24_hours": "過去24時間に処理されたDNSクエリの数",
@@ -134,6 +136,7 @@
"enforced_save_search": "強制されたセーフサーチ",
"number_of_dns_query_to_safe_search": "セーフサーチが強制適用された検索エンジンへのDNSリクエストの数",
"average_processing_time": "平均処理時間",
"processing_time": "処理時間",
"average_processing_time_hint": "DNSリクエストの処理にかかる平均時間ミリ秒単位",
"block_domain_use_filters_and_hosts": "フィルタとhostsファイルを使用してドメインをブロックする",
"filters_block_toggle_hint": "<a>フィルタ</a>の設定でブロックするルールを設定することができます。",
@@ -153,11 +156,12 @@
"custom_filtering_rules": "カスタム・フィルタリングルール",
"encryption_settings": "暗号化設定",
"dhcp_settings": "DHCP設定",
"upstream_dns": "上流DNSサーバ",
"upstream_dns_help": "サーバのアドレスは1行に1つずつ入力してください。上流DNSサーバの構成設定について詳しくは<a>こちら</a>でご確認いただけます。",
"upstream_dns": "アップストリームDNSサーバ",
"upstream_dns_help": "サーバのアドレスは1行に1つずつ入力してください。アップストリームDNSサーバの構成設定について詳しくは<a>こちら</a>でご確認いただけます。",
"upstream_dns_configured_in_file": "{{path}} にて設定されています",
"test_upstream_btn": "上流サーバをテストする",
"upstreams": "上流",
"test_upstream_btn": "アップストリームをテストする",
"upstreams": "アップストリーム",
"upstream": "アップストリーム",
"apply_btn": "適用する",
"disabled_filtering_toast": "フィルタリングを無効にしました",
"enabled_filtering_toast": "フィルタリングを有効にしました",
@@ -220,7 +224,7 @@
"example_upstream_tcp_port": "レギュラーDNSover TCP、ポート付き);",
"example_upstream_tcp_hostname": "通常のDNSover TCP, ホスト名)。",
"all_lists_up_to_date_toast": "すべてのリストは既に最新です",
"updated_upstream_dns_toast": "上流DNSサーバを保存しました。",
"updated_upstream_dns_toast": "アップストリームサーバを保存しました。",
"dns_test_ok_toast": "指定されたDNSサーバは正しく動作しています",
"dns_test_not_ok_toast": "サーバ \"{{key}}\": 使用できませんでした。正しく入力されているかどうかを確認してください",
"dns_test_warning_toast": "アップストリーム\"{{key}}\"はテストリクエストに応答せず、正しく動作しない可能性があります。",
@@ -444,7 +448,7 @@
"client_confirm_delete": "クライアント \"{{key}}\" を削除してもよろしいですか?",
"list_confirm_delete": "このリストを削除してもよろしいですか?",
"auto_clients_title": "ランタイムクライアント",
"auto_clients_desc": "永続的クライアントのリストに未登録で、AdGuard Homeを使用する場合があるデバイスのリスト。",
"auto_clients_desc": "AdGuard Home を使用している、または使用する可能性のあるデバイスの IP アドレスに関する情報です。この情報は、hosts ファイル、リバース DNS など、複数の情報源から収集されます。",
"access_title": "アクセス設定",
"access_desc": "こちらでは、AdGuard Home DNSサーバーのアクセスルールを設定できます。",
"access_allowed_title": "許可されたクライアント",
@@ -478,7 +482,9 @@
"setup_dns_notice": "<1>DNS-over-HTTPS</1>または<1>DNS-over-TLS</1>を使用するには、AdGuard Home 設定の<0>暗号化設定</0>が必要です。",
"rewrite_added": "\"{{key}}\" のDNS書き換え情報を追加完了しました",
"rewrite_deleted": "\"{{key}}\" のDNS書き換え情報を削除完了しました",
"rewrite_updated": "DNS rewrite を更新完了しました。",
"rewrite_add": "DNS書き換え情報を追加する",
"rewrite_edit": "DNS rewrite を編集する",
"rewrite_not_found": "DNS書き換え情報はありません",
"rewrite_confirm_delete": "\"{{key}}\" のDNS書き換え情報を削除してもよろしいですか",
"rewrite_desc": "特定のドメイン名に対するDNS応答を簡単にカスタマイズすることを可能にします。",
@@ -621,7 +627,7 @@
"enter_cache_size": "キャッシュサイズ(バイト単位)を入力してください",
"enter_cache_ttl_min_override": "最小TTL秒単位を入力してください",
"enter_cache_ttl_max_override": "最大TTL秒単位を入力してください",
"cache_ttl_min_override_desc": "DNS応答をキャッシュするとき、上流サーバから受信した短いTTL秒単位を延長します。",
"cache_ttl_min_override_desc": "DNS応答をキャッシュするとき、アップストリームサーバから受信した短いTTL秒単位を延長します。",
"cache_ttl_max_override_desc": "DNSキャッシュ内のエントリの最大TTL秒単位を設定します。",
"ttl_cache_validation": "最小キャッシュTTL上書き値は最大値以下にする必要があります",
"cache_optimistic": "Optimistic cashing (オプティミスティック・キャッシュ)",

View File

@@ -125,6 +125,8 @@
"top_clients": "클라이언트",
"no_clients_found": "클라이언트가 없습니다",
"general_statistics": "일반 통계",
"top_upstreams": "상위 업스트림",
"no_upstreams_data_found": "업스트림 데이터 없음",
"number_of_dns_query_days": "최근 {{count}}일 동안 처리된 DNS 쿼리의 수",
"number_of_dns_query_days_plural": "최근 {{count}}일 동안 처리된 DNS 쿼리의 수",
"number_of_dns_query_24_hours": "최근 24시간 동안 처리된 DNS 쿼리의 수",
@@ -134,6 +136,7 @@
"enforced_save_search": "세이프서치 강제",
"number_of_dns_query_to_safe_search": "세이프서치가 적용된 검색 엔진에 대해 DNS 요청 수",
"average_processing_time": "평균처리 시간",
"processing_time": "처리 시간",
"average_processing_time_hint": "DNS 요청 처리시 평균 시간(밀리초)",
"block_domain_use_filters_and_hosts": "필터 및 호스트 파일을 사용하여 도메인 차단",
"filters_block_toggle_hint": "차단규칙<a>필터</a>을 설정할 수 있습니다.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "{{path}}에서 구성됨",
"test_upstream_btn": "업스트림 테스트",
"upstreams": "업스트림",
"upstream": "업스트림",
"apply_btn": "적용",
"disabled_filtering_toast": "필터링 비활성화됨",
"enabled_filtering_toast": "필터링 활성화됨",
@@ -444,7 +448,7 @@
"client_confirm_delete": "정말 클라이언트 '{{key}}'을(를) 삭제하시겠습니까?",
"list_confirm_delete": "정말로 이 목록을 제거하시겠습니까?",
"auto_clients_title": "런타임 클라이언트",
"auto_clients_desc": "AdGuard Home을 계속 사용할 수 있는 영구 클라이언트 목록에 없는 디바이스입니다",
"auto_clients_desc": "AdGuard Home을 사용 중이거나 사용할 수 있는 기기의 IP 주소에 대한 정보가 표시됩니다. 이 정보는 호스트 파일, 역방향 DNS 등 여러 소스에서 수집됩니다.",
"access_title": "접근 설정",
"access_desc": "여기에서 AdGuard Home DNS 서버에 대한 액세스 규칙을 설정할 수 있습니다",
"access_allowed_title": "허용된 클라이언트",
@@ -478,7 +482,9 @@
"setup_dns_notice": "<1>DNS-over-HTTPS</1> 또는 <1>DNS-over-TLS를</1> 사용하려면 AdGuard Home 설정에서 <0>암호화를 구성해야 합니다.</0>",
"rewrite_added": "'{{key}}'에 대한 DNS 수정 정보를 성공적으로 추가 됩니다",
"rewrite_deleted": "'{{key}}'에 대한 DNS 수정 정보를 성공적으로 삭제 됩니다",
"rewrite_updated": "DNS 다시 쓰기 업데이트 완료",
"rewrite_add": "DNS 변환 정보를 추가합니다",
"rewrite_edit": "DNS 다시 쓰기 편집",
"rewrite_not_found": "DNS 변경 정보를 찾을 수 없습니다",
"rewrite_confirm_delete": "'{{key}}'에 대한 DNS 변경 정보를 삭제하시겠습니까?",
"rewrite_desc": "특정 도메인 이름에 대한 사용자 지정 DNS 응답을 쉽게 구성할 수 있습니다.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Top gebruikers",
"no_clients_found": "Geen gebruikers gevonden",
"general_statistics": "Algemene statistieken",
"top_upstreams": "Top upstreams",
"no_upstreams_data_found": "Geen upstreams-gegevens gevonden",
"number_of_dns_query_days": "Aantal verwerkte DNS aanvragen van de laatste {{count}} dag",
"number_of_dns_query_days_plural": "Aantal verwerkte DNS aanvragen van de laatste {{count}} dagen",
"number_of_dns_query_24_hours": "Aantal verwerkte DNS aanvragen van de laatste 24 uur",
@@ -134,6 +136,7 @@
"enforced_save_search": "Geforceerd veilig zoeken",
"number_of_dns_query_to_safe_search": "Aantal DNS aanvragen in zoekmachines dmv geforceerd veilig zoeken",
"average_processing_time": "Gemiddelde procestijd",
"processing_time": "Verwerkingstijd",
"average_processing_time_hint": "Gemiddelde verwerkingstijd in milliseconden van een DNS aanvraag",
"block_domain_use_filters_and_hosts": "Domeinen blokkeren d.m.v. filters en host-bestanden",
"filters_block_toggle_hint": "Je kan blokkeringsregels toevoegen in de <a>Filters</a> instellingen.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Geconfigureerd in {{path}}",
"test_upstream_btn": "Test upstream",
"upstreams": "Upstreams",
"upstream": "Upstream",
"apply_btn": "Toepassen",
"disabled_filtering_toast": "Filters uitgeschakeld",
"enabled_filtering_toast": "Filters ingeschakeld",
@@ -186,7 +190,7 @@
"cancel_btn": "Annuleren",
"enter_name_hint": "Voeg naam toe",
"enter_url_or_path_hint": "Voer een URL in of het pad van de lijst",
"check_updates_btn": "Controleer op updates",
"check_updates_btn": "Controleren op updates",
"new_blocklist": "Nieuwe blokkeerlijst",
"new_allowlist": "Nieuwe toelatingslijst",
"edit_blocklist": "Blokkeerlijst beheren",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Ben je zeker dat je deze gebruiker \"{{key}}\" wilt verwijderen?",
"list_confirm_delete": "Ben je zeker om deze lijst te verwijderen?",
"auto_clients_title": "Runtime-clients",
"auto_clients_desc": "Apparaten die niet op de lijst van permanente clients staan die mogelijk nog steeds AdGuard Home gebruiken",
"auto_clients_desc": "Informatie over IP-adressen van apparaten die AdGuard Home gebruiken of kunnen gebruiken. Deze informatie wordt verzameld uit verschillende bronnen, waaronder hosts-bestanden, reverse DNS, enz.",
"access_title": "Toegangs instellingen",
"access_desc": "Hier kan je toegangsregels voor de AdGuard Home DNS-server instellen",
"access_allowed_title": "Toegestane gebruikers",
@@ -456,7 +460,7 @@
"access_settings_saved": "Toegangsinstellingen succesvol opgeslagen",
"updates_checked": "Een nieuwe versie van AdGuard Home is beschikbaar\n",
"updates_version_equal": "AdGuard Home is actueel",
"check_updates_now": "Controleer op updates",
"check_updates_now": "Nu controleren op updates",
"version_request_error": "Updatecontrole mislukt. Controleer je internetverbinding.",
"dns_privacy": "DNS Privacy",
"setup_dns_privacy_1": "<0>DNS-via-TLS:</0> Gebruik <1>{{address}}</1> string.",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Om <1>DNS-via-HTTPS</1> of <1>DNS-via-TLS</1> te gebruiken, moet je <0>Versleuteling configureren</0> in de AdGuard Home instellingen.",
"rewrite_added": "DNS-herschrijving voor \"{{key}}\" met succes toegevoegd",
"rewrite_deleted": "DNS-herschrijving voor \"{{key}}\" met succes verwijderd",
"rewrite_updated": "DNS-herschrijven succesvol bijgewerkt",
"rewrite_add": "DNS-herschrijving toevoegen",
"rewrite_edit": "DNS-herschrijven bewerken",
"rewrite_not_found": "Geen DNS-herschrijving gevonden",
"rewrite_confirm_delete": "Bent u zeker dat u DNS-herschrijving \"{{key}}\" wilt verwijderen?",
"rewrite_desc": "Hiermee kunt u eenvoudig aangepaste DNS-antwoorden configureren voor een specifieke domeinnaam.",
@@ -571,7 +577,7 @@
"tags_title": "Labels",
"tags_desc": "Je kunt labels selecteren die overeenkomen met de client. Labels kunnen worden opgenomen in de filterregels om ze \n nauwkeuriger toe te passen. <0>Meer informatie</0>.",
"form_select_tags": "Client tags selecteren",
"check_title": "Controleer de filtering",
"check_title": "De filtering controleren",
"check_desc": "Controleren of een hostnaam wordt gefilterd.",
"check": "Controleren",
"form_enter_host": "Voer een hostnaam in",

View File

@@ -114,6 +114,8 @@
"top_clients": "Vanligste klienter",
"no_clients_found": "Ingen klienter ble funnet",
"general_statistics": "Generelle statistikker",
"top_upstreams": "Topp oppstrøms servere",
"no_upstreams_data_found": "Ingen oppstrøms servere data funnet",
"number_of_dns_query_days": "Antall DNS-spørringer behandlet for de siste {{count}} dagene",
"number_of_dns_query_days_plural": "Antall DNS-forespørsler som ble behandlet de siste {{count}} dagene",
"number_of_dns_query_24_hours": "Antall DNS-forespørsler som ble behandlet de siste 24 timene",
@@ -147,6 +149,7 @@
"upstream_dns_configured_in_file": "Satt opp i {{path}}",
"test_upstream_btn": "Test oppstrømstilkoblinger",
"upstreams": "Oppstrømstjenere",
"upstream": "Oppstrøms server",
"apply_btn": "Benytt",
"disabled_filtering_toast": "Skrudde av filtrering",
"enabled_filtering_toast": "Skrudde på filtrering",
@@ -457,7 +460,9 @@
"setup_dns_notice": "For å benytte <1>DNS-over-HTTPS</1> eller <1>DNS-over-TLS</1>, må du <0>sette opp Kryptering</0> i AdGuard Home-innstillingene.",
"rewrite_added": "DNS-omdirigeringen for «{{key}}» ble vellykket lagt til",
"rewrite_deleted": "DNS-omdirigeringen for «{{key}}» ble vellykket slettet",
"rewrite_updated": "DNS-omskriving ble oppdatert",
"rewrite_add": "Legg til DNS-omdirigering",
"rewrite_edit": "Rediger DNS-omskriving",
"rewrite_not_found": "Ingen DNS-omdirigeringer ble funnet",
"rewrite_confirm_delete": "Er du sikker på at du vil slette DNS-omdirigeringen for «{{key}}»?",
"rewrite_desc": "Lar deg enkelt konfigurere selvvalgte DNS-tilbakemeldinger for et spesifikt domenenavn.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Główni klienci",
"no_clients_found": "Nie znaleziono klienta",
"general_statistics": "Ogólne statystyki",
"top_upstreams": "Często żądane serwery nadrzędne",
"no_upstreams_data_found": "Brak danych dotyczących serwerów nadrzędnych",
"number_of_dns_query_days": "Liczba przetworzonych zapytań DNS w ciągu ostatnich {{count}} dni",
"number_of_dns_query_days_plural": "Liczba przetworzonych zapytań DNS w ciągu ostatnich {{count}} dni",
"number_of_dns_query_24_hours": "Liczba zapytań DNS przetworzonych w ciągu ostatnich 24 godzin",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Skonfigurowano w {{path}}",
"test_upstream_btn": "Test głównych serwerów DNS",
"upstreams": "Główne serwery DNS",
"upstream": "Serwer nadrzędny",
"apply_btn": "Zastosuj",
"disabled_filtering_toast": "Wyłączone filtrowanie",
"enabled_filtering_toast": "Włączone filtrowanie",
@@ -444,7 +447,7 @@
"client_confirm_delete": "Czy na pewno chcesz usunąć klienta \"{{key}}\"?",
"list_confirm_delete": "Czy na pewno chcesz usunąć tę listę?",
"auto_clients_title": "Uruchomieni klienci",
"auto_clients_desc": "Urządzenia, których nie ma na liście stałych klientów, które mogą nadal korzystać z AdGuard Home",
"auto_clients_desc": "Informacje o adresach IP urządzeń korzystających lub mogących korzystać z AdGuard Home. Te informacje są gromadzone z wielu źródeł takich jak pliki hosta, odwrotna translacja DNS, itp.",
"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",
@@ -470,7 +473,7 @@
"setup_dns_privacy_ios_2": "Aplikacja <0>AdGuard dla iOS</0> obsługuje <1>DNS-over-HTTPS</1> i <1>DNS-over-TLS</1>.",
"setup_dns_privacy_other_title": "Inne implementacje",
"setup_dns_privacy_other_1": "Sam AdGuard Home może być bezpiecznym klientem DNS na dowolnej platformie.",
"setup_dns_privacy_other_2": "<0>dnsproxy</0> obsługuje wszystkie znane bezpieczne protokoły DNS.\n\n",
"setup_dns_privacy_other_2": "<0>dnsproxy</0> obsługuje wszystkie znane bezpieczne protokoły DNS.",
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> obsługuje <1>DNS-over-HTTPS</1>.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> obsługuje <1>DNS-over-HTTPS</1>.",
"setup_dns_privacy_other_5": "Znajdziesz więcej implementacji <0>tutaj</0> i <1>tutaj</1>.",
@@ -478,7 +481,9 @@
"setup_dns_notice": "Aby skorzystać z <1>DNS-over-HTTPS</1> lub <1>DNS-over-TLS</1>, musisz w ustawieniach AdGuard Home <0>skonfigurować szyfrowanie</0>.",
"rewrite_added": "Pomyślnie dodano przepisanie DNS dla „{{key}}”",
"rewrite_deleted": "Przepisanie DNS dla „{{key}}” zostało pomyślnie usunięte",
"rewrite_updated": "Pomyślnie zaktualizowano przepisywanie DNS",
"rewrite_add": "Dodaj przepisywanie DNS",
"rewrite_edit": "Edytuj przepisywanie DNS",
"rewrite_not_found": "Nie znaleziono przepisywania DNS",
"rewrite_confirm_delete": "Czy na pewno chcesz usunąć przepisywanie DNS dla „{{key}}”?",
"rewrite_desc": "Pozwala łatwo skonfigurować niestandardową odpowiedź DNS dla określonej nazwy domeny.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Principais clientes",
"no_clients_found": "Nenhuma cliente encontrado",
"general_statistics": "Estatísticas gerais",
"top_upstreams": "Melhores servidores DNS primários",
"no_upstreams_data_found": "Nenhum dado de servidor DNS primário encontrado",
"number_of_dns_query_days": "O número de consultas DNS processadas nos últimos {{count}} dias",
"number_of_dns_query_days_plural": "Número de consultas DNS processadas nos últimos {{count}} dias",
"number_of_dns_query_24_hours": "O número de consultas DNS processadas nas últimas 24 horas",
@@ -134,6 +136,7 @@
"enforced_save_search": "Forçar pesquisa segura",
"number_of_dns_query_to_safe_search": "O número de solicitações de DNS para mecanismos de pesquisa para os quais a pesquisa segura foi aplicada",
"average_processing_time": "Tempo médio de processamento",
"processing_time": "Tempo de processamento",
"average_processing_time_hint": "Tempo médio em milissegundos no processamento de uma solicitação DNS",
"block_domain_use_filters_and_hosts": "Bloquear domínios usando arquivos de filtros e hosts",
"filters_block_toggle_hint": "Você pode configurar as regras de bloqueio nas configurações de <a>Filtros</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configurado em {{path}}",
"test_upstream_btn": "Testar DNS primário",
"upstreams": "DNS primário",
"upstream": "Servidor DNS primário",
"apply_btn": "Aplicar",
"disabled_filtering_toast": "Filtragem desativada",
"enabled_filtering_toast": "Filtragem ativada",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Você tem certeza de que deseja excluir o cliente \"{{key}}\"?",
"list_confirm_delete": "Você tem certeza de que deseja excluir essa lista?",
"auto_clients_title": "Clientes ativos",
"auto_clients_desc": "Dispositivo não está na lista de dispositivos persistentes que podem ser utilizados no AdGuard Home",
"auto_clients_desc": "Informações sobre endereços IP de dispositivos que usam ou podem usar o AdGuard Home. Essas informações são coletadas de várias fontes, incluindo arquivos de hosts, DNS reverso, etc.",
"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",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Para usar o <1>DNS-sobre-HTTPS</1> ou <1>DNS-sobre-TLS</1>, você precisa <0>configurar a criptografia</0> nas configurações do AdGuard Home.",
"rewrite_added": "Reescrita de DNS para \"{{key}}\" adicionada com sucesso",
"rewrite_deleted": "Reescrita de DNS para \"{{key}}\" excluída com sucesso",
"rewrite_updated": "Reconfiguração de DNS atualizada com êxito",
"rewrite_add": "Adicionar reescrita de DNS",
"rewrite_edit": "Editar reconfiguração de DNS",
"rewrite_not_found": "Nenhuma reescrita de DNS foi encontrada",
"rewrite_confirm_delete": "Você tem certeza de que deseja excluir a reescrita de DNS para \"{{key}}\"?",
"rewrite_desc": "Permite configurar uma resposta personalizada do DNS para um nome de domínio específico.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Principais clientes",
"no_clients_found": "Nenhum cliente foi encontrado",
"general_statistics": "Estatísticas gerais",
"top_upstreams": "Melhores servidores DNS primários",
"no_upstreams_data_found": "Nenhum dado de servidor DNS primário encontrado",
"number_of_dns_query_days": "Número de consultas DNS processadas durante los últimos {{count}} días",
"number_of_dns_query_days_plural": "Número de consultas DNS processadas durante os últimos {{count}} dias",
"number_of_dns_query_24_hours": "O número de consultas DNS processadas nas últimas 24 horas",
@@ -134,6 +136,7 @@
"enforced_save_search": "Forçar pesquisa segura",
"number_of_dns_query_to_safe_search": "O número de solicitações de DNS para motores de busca para os quais a pesquisa segura foi aplicada",
"average_processing_time": "Tempo médio de processamento",
"processing_time": "Tempo de processamento",
"average_processing_time_hint": "Tempo médio em milissegundos no processamento de uma solicitação DNS",
"block_domain_use_filters_and_hosts": "Bloquear domínios usando ficheiros de filtros e hosts",
"filters_block_toggle_hint": "Pode configurar as regras de bloqueio nas configurações de <a>Filtros</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Configurado em {{path}}",
"test_upstream_btn": "Testar DNS primário",
"upstreams": "DNS primário",
"upstream": "Servidor DNS primário",
"apply_btn": "Aplicar",
"disabled_filtering_toast": "Filtragem desativada",
"enabled_filtering_toast": "Filtragem ativada",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Tem a certeza de que deseja excluir o cliente \"{{key}}\"?",
"list_confirm_delete": "Você tem certeza de que deseja excluir essa lista?",
"auto_clients_title": "Clientes ativos",
"auto_clients_desc": "Dispositivo não está na lista de dispositivos persistentes que podem ser utilizados no AdGuard Home",
"auto_clients_desc": "Informações sobre endereços IP de dispositivos que estão a utilizar ou podem utilizar o AdGuard Home. Estas informações são recolhidas a partir de várias fontes, incluindo ficheiros hosts, DNS reverso etc.",
"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",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Para usar o <1>DNS-sobre-HTTPS</1> ou <1>DNS-sobre-TLS</1>, precisa de <0>configurar a criptografia</0> nas configurações do AdGuard Home.",
"rewrite_added": "Reescrita de DNS para \"{{key}}\" adicionada com sucesso",
"rewrite_deleted": "Reescrita de DNS para \"{{key}}\" excluída com sucesso",
"rewrite_updated": "Reedição de DNS atualizada com sucesso",
"rewrite_add": "Adicionar reescrita de DNS",
"rewrite_edit": "Editar reedição de DNS",
"rewrite_not_found": "Nenhuma reescrita de DNS foi encontrada",
"rewrite_confirm_delete": "Tem a certeza de que deseja excluir a reescrita de DNS para \"{{key}}\"?",
"rewrite_desc": "Permite configurar uma resposta personalizada do DNS para um nome de domínio específico.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Clienți de top",
"no_clients_found": "Nu au fost găsiți clienți",
"general_statistics": "Statistici generale",
"top_upstreams": "Top servere în amonte",
"no_upstreams_data_found": "Nu există date despre serverele din amonte",
"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",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Configurat în {{path}}",
"test_upstream_btn": "Testați upstreams",
"upstreams": "Upstreams",
"upstream": "Server în amonte",
"apply_btn": "Aplică",
"disabled_filtering_toast": "Filtrare dezactivată",
"enabled_filtering_toast": "Filtrare activată",
@@ -167,6 +170,7 @@
"enabled_parental_toast": "Control Parental activat",
"disabled_safe_search_toast": "Căutare protejată dezactivată",
"enabled_save_search_toast": "Căutare protejată activată",
"updated_save_search_toast": "Setări Căutare sigură actualizate",
"enabled_table_header": "Activat",
"name_table_header": "Nume",
"list_url_table_header": "Lista URL",
@@ -256,12 +260,12 @@
"query_log_cleared": "Jurnalul de interogare a fost șters cu succes",
"query_log_updated": "Jurnalul de solicitări a fost actualizat cu succes",
"query_log_clear": "Curăță jurnalele",
"query_log_retention": "Retenție jurnale interogare",
"query_log_retention": "Interogarea jurnalelor de rotație",
"query_log_enable": "Activați jurnal",
"query_log_configuration": "Configurația jurnalelor",
"query_log_disabled": "Jurnalul de interogare este dezactivat și poate fi configurat în <0>setări</0>",
"query_log_strict_search": "Utilizați ghilimele duble pentru căutare strictă",
"query_log_retention_confirm": "Sunteți sigur doriți să schimbați retenția jurnalului de interogare? Reducând valoarea intervalului, unele date vor fi pierdute",
"query_log_retention_confirm": "Sigur doriți să modificați rotația jurnalului de interogări? Dacă micșorați valoarea intervalului, unele date se vor pierde",
"anonymize_client_ip": "Anonimizare client IP",
"anonymize_client_ip_desc": "Nu salvați adresa IP completă a clientului în jurnale și statistici",
"dns_config": "Configurația serverului DNS",
@@ -290,6 +294,8 @@
"rate_limit": "Limita ratei",
"edns_enable": "Activați subrețeaua de clienți EDNS",
"edns_cs_desc": "Adaugă opțiunea EDNS Client Subnet (ECS) la solicitările în amonte și înregistrează valorile trimise de clienți în jurnalul de interogare.",
"edns_use_custom_ip": "Utilizați IP personalizat pentru EDNS",
"edns_use_custom_ip_desc": "Permiteți utilizarea IP-ului personalizat pentru EDNS",
"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",
@@ -441,7 +447,7 @@
"client_confirm_delete": "Sunteți sigur că doriți să ștergeți clientul \"{{key}}\"?",
"list_confirm_delete": "Sigur doriți să ștergeți această listă?",
"auto_clients_title": "Clienți runtime",
"auto_clients_desc": "Dispozitivele care nu se află pe lista de clienți Persistent care pot utiliza în continuare AdGuard Home",
"auto_clients_desc": "Informații despre adresele IP ale dispozitivelor care utilizează sau pot utiliza AdGuard Home. Aceste informații sunt colectate din mai multe surse, inclusiv din fișiere hosts, DNS inversat etc.",
"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",
@@ -475,7 +481,9 @@
"setup_dns_notice": "Pentru a utiliza <1>DNS-over-HTTPS</1> sau <1>DNS-over-TLS</1>, trebuie să <0>configurați Criptarea</0> în setările AdGuard Home.",
"rewrite_added": "Rescriere DNS pentru \"{{key}}\" adăugată cu succes",
"rewrite_deleted": "Rescriere DNS pentru \"{{key}}\" ștearsă cu succes",
"rewrite_updated": "DNS rescrie actualizat cu succes",
"rewrite_add": "Adăugați rescriere DNS",
"rewrite_edit": "Editați rescrierea DNS",
"rewrite_not_found": "Nu s-au găsit rescrieri DNS",
"rewrite_confirm_delete": "Sunteți sigur că doriți să ștergeți rescrierea DNS pentru \"{{key}}\"?",
"rewrite_desc": "Permite configurarea cu ușurință a răspunsului personalizat DNS pentru un nume de domeniu specific.",
@@ -523,6 +531,10 @@
"statistics_retention_confirm": "Sunteți sigur că doriți să schimbați păstrarea statisticilor? Dacă reduceți valoarea intervalului, unele date vor fi pierdute",
"statistics_cleared": "Statisticile au fost șterse cu succes",
"statistics_enable": "Activați statisticile",
"ignore_domains": "Domenii ignorate (separate prin linie nouă)",
"ignore_domains_title": "Domenii ignorate",
"ignore_domains_desc_stats": "Interogările pentru aceste domenii nu sunt scrise în statistici",
"ignore_domains_desc_query": "Interogările pentru aceste domenii nu sunt scrise în jurnalul de interogări",
"interval_hours": "{{count}} oră",
"interval_hours_plural": "{{count}} ore",
"filters_configuration": "Configurația filtrelor",
@@ -643,5 +655,29 @@
"confirm_dns_cache_clear": "Sunteți sigur că doriți să ștergeți memoria cache DNS?",
"cache_cleared": "Cache-ul DNS a fost golit cu succes",
"clear_cache": "Goliți memoria cache",
"protection_section_label": "Protecție"
"make_static": "Faceți static",
"theme_auto_desc": "Auto (pe baza schemei de culori a dispozitivului dvs.)",
"theme_dark_desc": "Temă întunecată",
"theme_light_desc": "Temă luminoasă",
"disable_for_seconds": "Timp de {{count}} secundă",
"disable_for_seconds_plural": "Timp de {{count}} secunde",
"disable_for_minutes": "Timp de {{count}} minut",
"disable_for_minutes_plural": "Timp de {{count}} minute",
"disable_for_hours": "Timp de {{count}} oră",
"disable_for_hours_plural": "Timp de {{count}} ore",
"disable_until_tomorrow": "Până mâine",
"disable_notify_for_seconds": "Dezactivați protecția timp de {{count}} secundă",
"disable_notify_for_seconds_plural": "Dezactivați protecția timp de {{count}} secunde",
"disable_notify_for_minutes": "Dezactivați protecția timp de {{count}} minut",
"disable_notify_for_minutes_plural": "Dezactivați protecția timp de {{count}} minute",
"disable_notify_for_hours": "Dezactivează protecția timp de {{count}} oră",
"disable_notify_for_hours_plural": "Dezactivați protecția timp de {{count}} ore",
"disable_notify_until_tomorrow": "Dezactivează protecția până mâine",
"enable_protection_timer": "Protecția va fi activată în {{time}}",
"custom_retention_input": "Introduceți reținerea în ore",
"custom_rotation_input": "Introduceți rotația în ore",
"protection_section_label": "Protecție",
"log_and_stats_section_label": "Jurnal de interogări și statistici",
"ignore_query_log": "Ignorați acest client în jurnalul de interogări",
"ignore_statistics": "Ignorați acest client în statistici"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "Частые клиенты",
"no_clients_found": "Клиентов не найдено",
"general_statistics": "Общая статистика",
"top_upstreams": "Часто запрашиваемые upstream-серверы",
"no_upstreams_data_found": "Нет данных об upstream-серверах",
"number_of_dns_query_days": "Количество DNS-запросов за последний {{count}} день",
"number_of_dns_query_days_plural": "Количество DNS запросов, обработанных за последние {{count}} дней",
"number_of_dns_query_24_hours": "Количество DNS-запросов за последние 24 часа",
@@ -134,8 +136,9 @@
"enforced_save_search": "Применён безопасный поиск",
"number_of_dns_query_to_safe_search": "Количество запросов DNS для поисковых систем, для которых был применён Безопасный поиск",
"average_processing_time": "Среднее время обработки запроса",
"processing_time": "Время обработки",
"average_processing_time_hint": "Среднее время для обработки запроса DNS в миллисекундах",
"block_domain_use_filters_and_hosts": "Блокировать домены с использованием фильтров и файлов хостов",
"block_domain_use_filters_and_hosts": "Блокировать домены с использованием фильтров и файлов hosts",
"filters_block_toggle_hint": "Вы можете настроить правила блокировки в <a>«Фильтрах»</a>.",
"use_adguard_browsing_sec": "Включить Безопасную навигацию AdGuard",
"use_adguard_browsing_sec_hint": "AdGuard Home проверит, включён ли домен в веб-службу безопасности браузера. Он будет использовать API, чтобы выполнить проверку: на сервер отправляется только короткий префикс имени домена SHA256.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Настроен в {{path}}",
"test_upstream_btn": "Тест upstream серверов",
"upstreams": "Upstreams",
"upstream": "Upstream-сервер",
"apply_btn": "Применить",
"disabled_filtering_toast": "Фильтрация выкл.",
"enabled_filtering_toast": "Фильтрация вкл.",
@@ -296,7 +300,7 @@
"rate_limit_desc": "Ограничение на количество запросов в секунду для каждого клиента (0 — неограниченно).",
"blocking_ipv4_desc": "IP-адрес, возвращаемый при блокировке A-запроса",
"blocking_ipv6_desc": "IP-адрес, возвращаемый при блокировке AAAA-запроса",
"blocking_mode_default": "Стандартный: Отвечает с нулевым IP-адресом, (0.0.0.0 для A; :: для AAAA) когда заблокировано правилом в стиле Adblock; отвечает с IP-адресом, указанным в правиле, когда заблокировано правилом в стиле /etc/hosts-style",
"blocking_mode_default": "Стандартный: Отвечает с нулевым IP-адресом, (0.0.0.0 для A; :: для AAAA) когда заблокировано правилом в стиле Adblock; отвечает с IP-адресом, указанным в правиле, когда заблокировано правилом в стиле файлов hosts",
"blocking_mode_refused": "REFUSED: Отвечает с кодом REFUSED",
"blocking_mode_nxdomain": "NXDOMAIN: Отвечает с кодом NXDOMAIN\n",
"blocking_mode_null_ip": "Нулевой IP: Отвечает с нулевым IP-адресом (0.0.0.0 для A; :: для AAAA)",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Вы уверены, что хотите удалить клиента «{{key}}»?",
"list_confirm_delete": "Вы уверены, что хотите удалить этот список?",
"auto_clients_title": "Клиенты (runtime)",
"auto_clients_desc": "Несохранённые клиенты, которые могут пользоваться AdGuard Home",
"auto_clients_desc": "Информация об IP-адресах устройств, которые используют или могут использовать AdGuard Home. Эта информация собирается из нескольких источников, включая файлы hosts, обратный DNS и так далее.",
"access_title": "Настройки доступа",
"access_desc": "Здесь вы можете настроить правила доступа к DNS-серверу AdGuard Home",
"access_allowed_title": "Разрешённые клиенты",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Чтобы использовать <1>DNS-over-HTTPS</1> или <1>DNS-over-TLS</1>, вам нужно <0>настроить шифрование</0> в настройках AdGuard Home.",
"rewrite_added": "Правило перезаписи DNS-запросов для «{{key}}» успешно добавлено",
"rewrite_deleted": "Правило перезаписи DNS-запросов для «{{key}}» успешно удалено",
"rewrite_updated": "Правило перезаписи DNS-запросов успешно обновлено",
"rewrite_add": "Добавить правило перезаписи DNS-запросов",
"rewrite_edit": "Редактировать правило перезаписи DNS-запросов",
"rewrite_not_found": "Не найдено правил перезаписи DNS-запросов",
"rewrite_confirm_delete": "Вы уверены, что хотите удалить правило перезаписи DNS-запросов для «{{key}}»?",
"rewrite_desc": "Позволяет легко настроить пользовательский DNS-ответ для определеннного домена.",

View File

@@ -153,6 +153,7 @@
"enabled_parental_toast": "දෙමාපිය පාලනය සබල කෙරිණි",
"disabled_safe_search_toast": "ආරක්‍ෂිත සෙවුම අබල කෙරිණි",
"enabled_save_search_toast": "ආරක්‍ෂිත සෙවුම සබල කෙරිණි",
"updated_save_search_toast": "ආරක්‍ෂිත සෙවුමේ සැකසුම් යාවත්කාල විය",
"enabled_table_header": "සබලයි",
"name_table_header": "නම",
"list_url_table_header": "ඒ.ස.නි.(URL) ලැයිස්තුව",
@@ -237,12 +238,12 @@
"query_log_cleared": "විමසුම් සටහන සාර්ථකව හිස් කර ඇත",
"query_log_updated": "විමසුම් සටහන සාර්ථකව යාවත්කාල කෙරිණි",
"query_log_clear": "විමසුම් සටහන් හිස් කරන්න",
"query_log_retention": "විමසුම් සටහන් රඳවා තබා ගැනීම",
"query_log_retention": "විමසුම් සටහන් රඳවීම",
"query_log_enable": "සටහන සබල කරන්න",
"query_log_configuration": "සටහන් වින්‍යාසය",
"query_log_disabled": "විමසුම් සටහන අබල කර ඇති අතර එය <0>සැකසුම්</0> තුළ වින්‍යාසගත කළ හැකිය",
"query_log_strict_search": "ඉතා නිවැරදිව සෙවීමට ද්විත්ව උද්ධෘතය භාවිතා කරන්න",
"query_log_retention_confirm": "විමසුම් සටහන රඳවා තබා ගැනීම වෙනස් කිරීමට ඇවැසි බව ඔබට විශ්වාසද? ඔබ කාල පරතරයෙහි අගය අඩු කළහොත් සමහර දත්ත නැති වී යනු ඇත",
"query_log_retention_confirm": "විමසුම් සටහන රඳවා තබා ගැනීම වෙනස් කිරීමට වුවමනා ද? ඔබ කාල පරතරයෙහි අගය අඩු කළහොත් සමහර දත්ත නැති වී යනු ඇත",
"anonymize_client_ip": "අනුග්‍රාහකයෙහි අ.ජා.කෙ. (IP) නිර්නාමික කරන්න",
"anonymize_client_ip_desc": "සටහන් සහ සංඛ්‍යාලේඛන තුළ අනුග්‍රාහකයේ පූර්ණ අ.ජා.කෙ. ලිපිනය සුරකින්න එපා",
"dns_config": "ව.නා.ප. සේවාදායක වින්‍යාසය",
@@ -270,6 +271,8 @@
"form_enter_rate_limit": "අනුපාත සීමාව ඇතුල් කරන්න",
"rate_limit": "අනුපාත සීමාව",
"edns_enable": "EDNS අනුග්‍රාහක අනුජාලය සබල කරන්න",
"edns_use_custom_ip": "EDNS සඳහා අභිරුචි අ.ජා.කෙ. යොදාගන්න",
"edns_use_custom_ip_desc": "EDNS සඳහා අභිරුචි අ.ජා.කෙ. භාවිතයට ඉඩදෙන්න",
"rate_limit_desc": "එක් අනුග්‍රාහකයකට ඉඩ දී ඇති තත්පරයට ඉල්ලීම් ගණන. එය 0 ලෙස සැකසීම යනුවෙන් අදහස් කරන්නේ සීමාවක් නැති බවයි.",
"blocking_ipv4_desc": "අවහිර කළ A ඉල්ලීමක් සඳහා ආපසු එවිය යුතු අ.ජා.කෙ. (IP) ලිපිනය",
"blocking_ipv6_desc": "අවහිර කළ AAAA ඉල්ලීමක් සඳහා ආපසු එවිය යුතු අ.ජා.කෙ. (IP) ලිපිනය",
@@ -278,6 +281,9 @@
"blocking_mode_nxdomain": "නොපවතින වසම: NXDOMAIN කේතය සමඟ ප්‍රතිචාර දක්වයි",
"blocking_mode_null_ip": "අභිශූන්‍යය අ.ජා.කෙ.: ශුන්‍ය අ.ජා.කෙ. ලිපිනය සමඟ ප්‍රතිචාර දක්වයි (A සඳහා 0.0.0.0; AAAA සඳහා ::)",
"blocking_mode_custom_ip": "අභිරුචි අන්තර්ජාල කෙටුම්පත: අතින් සැකසූ අ.ජා. කෙ. ලිපිනයක් සමඟ ප්‍රතිචාර දක්වයි",
"theme_auto": "ස්වයං",
"theme_light": "දීප්ත",
"theme_dark": "අඳුරු",
"upstream_dns_client_desc": "ඔබ මෙම ක්ෂේත්‍රය හිස්ව තබා ගන්නේ නම්, ඇඩ්ගාර්ඩ් හෝම් විසින් <0>ව.නා.ප. සැකසුම්</0> හි වින්‍යාසගත කර ඇති සේවාදායක භාවිතා කරනු ඇත.",
"tracker_source": "ලුහුබැඳීම් මූලාශ්‍රය",
"source_label": "මූලාශ්‍රය",
@@ -370,6 +376,7 @@
"encryption_issuer": "නිකුත් කරන්නා",
"encryption_hostnames": "ධාරක නාම",
"encryption_reset": "සංකේතාංකන සැකසුම් යළි පිහිටුවීමට අවශ්‍ය බව ඔබට විශ්වාස ද?",
"encryption_warning": "අවවාදයයි",
"topline_expiring_certificate": "ඔබගේ SSL සහතිකය කල් ඉකුත්වීමට ආසන්න වී ඇත. <0>සංකේතන සැකසුම්</0> යාවත්කාල කරන්න.",
"topline_expired_certificate": "ඔබගේ SSL සහතිකය කල් ඉකුත් වී ඇත. <0>සංකේතන සැකසුම්</0> යාවත්කාල කරන්න.",
"form_error_port_range": "80-65535 පරාසය හි තොටක අගයක් ඇතුල් කරන්න",
@@ -428,6 +435,7 @@
"updates_checked": "ඇඩ්ගාර්ඩ් හෝම් හි නව අනුවාදයක් තිබේ",
"updates_version_equal": "ඇඩ්ගාර්ඩ් හෝම් යාවත්කාලීනයි",
"check_updates_now": "දැන් යාවත්කාල පරීක්‍ෂා කරන්න",
"version_request_error": "යාවත්කාලීන පරීක්‍ෂාවට අසමත් විය. ඔබගේ අන්තර්ජාල සම්බන්ධතාවය පරීක්‍ෂා කරන්න.",
"dns_privacy": "ව.නා.ප. රහස්‍යතා",
"setup_dns_privacy_1": "<0>TLS-මගින්-ව.නා.ප.</0> සඳහා <1>{{address}}</1>.",
"setup_dns_privacy_2": "<0>HTTPS-මගින්-ව.නා.ප.</0> සඳහා <1>{{address}}</1>.",
@@ -446,7 +454,9 @@
"setup_dns_notice": "ඔබට <1>HTTPS-මගින්-ව.නා.ප.</1> හෝ <1>DNS-මගින්-ව.නා.ප.</1> භාවිතයට ඇඩ්ගාර්ඩ් හෝම් සැකසුම් තුළ <0>සංකේතනය වින්‍යාසගත</0> කළ යුතුය.",
"rewrite_added": "\"{{key}}\" සඳහා ව.නා.ප. නැවත ලිවීම සාර්ථකව එකතු කෙරිණි",
"rewrite_deleted": "\"{{key}}\" සඳහා ව.නා.ප. නැවත ලිවීම ඉවත් කෙරිණි",
"rewrite_add": "ව.නා.ප. නැවත ලිවීමක් එකතු කරන්න",
"rewrite_updated": "ව.නා.ප. නැවත ලිවීම සාර්ථකව යාවත්කාලීන කෙරිණි",
"rewrite_add": "ව.නා.ප. නැවත ලිවීමක් යොදන්න",
"rewrite_edit": "ව.නා.ප. නැවත ලිවීම සංස්කරණය",
"rewrite_not_found": "ව.නා.ප. නැවත ලිවීම් හමු නොවිණි",
"rewrite_confirm_delete": "\"{{key}}\" සඳහා ව.නා.ප. නැවත ලිවීම ඉවත් කිරීමට අවශ්‍ය බව ඔබට විශ්වාසද?",
"rewrite_desc": "නිශ්චිත වසම් නාමයක් සඳහා අභිරුචි ව.නා.ප. ප්‍රතිචාර පහසුවෙන් වින්‍යාසගත කිරීමට ඉඩ දෙයි.",
@@ -490,8 +500,10 @@
"statistics_clear": "සංඛ්‍යාලේඛන හිස් කරන්න",
"statistics_clear_confirm": "සංඛ්‍යාලේඛන ඉවත් කිරීමට වුවමනා ද?",
"statistics_retention_confirm": "සංඛ්‍යාලේඛන රඳවා තබා ගැනීම වෙනස් කිරීමට අවශ්‍ය බව ඔබට විශ්වාසද? ඔබ කාල පරතරයෙහි අගය අඩු කළහොත් සමහර දත්ත නැති වී යනු ඇත",
"statistics_cleared": "සංඛ්‍යාලේඛන සාර්ථකව ඉවත් කෙරිණි",
"statistics_cleared": "සංඛ්‍යාලේඛන සාර්ථකව හිස් කෙරිණි",
"statistics_enable": "සංඛ්‍යාලේඛන සබල කරන්න",
"ignore_domains": "නොසලකන වසම් (පේළියකට එක බැගින්)",
"ignore_domains_title": "නොසලකන වසම්",
"interval_hours": "පැය {{count}}",
"interval_hours_plural": "පැය {{count}}",
"filters_configuration": "පෙරහන් වින්‍යාසය",
@@ -601,5 +613,34 @@
"parental_control": "දෙමාපිය පාලනය",
"safe_browsing": "ආරක්‍ෂිත පිරික්සුම",
"served_from_cache": "{{value}} <i>(නිහිතයෙන් ගැනිණි)</i>",
"form_error_password_length": "මුරපදය අවම වශයෙන් අකුරු {{value}} ක් දිගු විය යුතුමයි"
"form_error_password_length": "මුරපදය අවම වශයෙන් අකුරු {{value}} ක් දිගු විය යුතුමයි",
"anonymizer_notification": "<0>සටහන:</0> අ.ජා.කෙ. නිර්නාමිකකරණය සබලයි. ඔබට එය <1>පොදු සැකසුම්</1> හරහා අබල කිරීමට හැකිය .",
"confirm_dns_cache_clear": "ඔබට ව.නා.ප. නිහිතය හිස් කිරීමට වුවමනාද?",
"cache_cleared": "ව.නා.ප. නිහිතය හිස් කෙරිණි",
"clear_cache": "නිහිතය මකන්න",
"make_static": "ස්ථිතික කරන්න",
"theme_auto_desc": "ස්වයං (උපාංගයේ වර්ණ පරිපාටිය මත පදනම්ව)",
"theme_dark_desc": "අඳුරු තේමාව",
"theme_light_desc": "දීප්ත තේමාව",
"disable_for_seconds": "තත්පර {{count}} ක්",
"disable_for_seconds_plural": "තත්පර {{count}} ක්",
"disable_for_minutes": "විනාඩි {{count}} ක්",
"disable_for_minutes_plural": "විනාඩි {{count}} ක්",
"disable_for_hours": "පැය {{count}} ක්",
"disable_for_hours_plural": "පැය {{count}} ක්",
"disable_until_tomorrow": "හෙට වනතුරු",
"disable_notify_for_seconds": "තත්. {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_for_seconds_plural": "තත්. {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_for_minutes": "විනාඩි {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_for_minutes_plural": "විනාඩි {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_for_hours": "පැය {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_for_hours_plural": "පැය {{count}} කට රැකවරණය අබල කරන්න",
"disable_notify_until_tomorrow": "හෙට වනතුරු රැකවරණය අබල කරන්න",
"enable_protection_timer": "{{time}} න් රැකවරණය සබල කෙරේ",
"custom_retention_input": "රඳවා ගැනීම පැය වලින්",
"custom_rotation_input": "රඳවා ගැනීම පැය වලින්",
"protection_section_label": "රැකවරණය",
"log_and_stats_section_label": "විමසුම් සටහන හා සංඛ්‍යාලේඛන",
"ignore_query_log": "සටහනෙහි අනුග්‍රාහකය නොසලකන්න",
"ignore_statistics": "සංඛ්‍යාලේඛනයට අනුග්‍රාහකය නොසලකන්න"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "Najčastejší klienti",
"no_clients_found": "Neboli nájdení žiadni klienti",
"general_statistics": "Všeobecná štatistika",
"top_upstreams": "Často požadované upstream servery",
"no_upstreams_data_found": "Nenašli sa žiadne údaje o upstream serveroch",
"number_of_dns_query_days": "Počet DNS dopytov spracovaných za posledný {{count}} deň",
"number_of_dns_query_days_plural": "Počet DNS dopytov spracovaných za posledných {{count}} dní",
"number_of_dns_query_24_hours": "Počet DNS dopytov spracovaných za posledných 24 hodín",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Konfigurované v {{path}}",
"test_upstream_btn": "Test upstreamov",
"upstreams": "Upstreams",
"upstream": "Upstream server",
"apply_btn": "Použiť",
"disabled_filtering_toast": "Vypnutá filtrácia",
"enabled_filtering_toast": "Zapnutá filtrácia",
@@ -387,7 +390,7 @@
"encryption_key": "Súkromný kľúč",
"encryption_key_input": "Skopírujte a prilepte sem svoj súkromný kľúč vo formáte PEM pre Váš certifikát.",
"encryption_enable": "Zapnite šifrovanie (HTTPS, DNS-cez-HTTPS a DNS-cez-TLS)",
"encryption_enable_desc": "Ak je šifrovanie zapnuté, AdGuard Home administrátorské rozhranie bude pracovať cez HTTPS a DNS server bude počúvať požiadavky cez DNS-cez-HTTPS a DNS-cez-TLS.",
"encryption_enable_desc": "Ak je šifrovanie zapnuté, AdGuard Home administrátorské rozhranie bude pracovať cez HTTPS a DNS server bude počúvať dopyty cez DNS-cez-HTTPS a DNS-cez-TLS.",
"encryption_chain_valid": "Certifikačný reťazec je platný",
"encryption_chain_invalid": "Certifikačný reťazec je neplatný",
"encryption_key_valid": "Toto je platný {{type}} súkromný kľúč",
@@ -444,7 +447,7 @@
"client_confirm_delete": "Naozaj chcete vymazať \"{{key}}\" klienta?",
"list_confirm_delete": "Naozaj chcete vymazať tento zoznam?",
"auto_clients_title": "Runtime klienti",
"auto_clients_desc": "Zariadenia, ktoré nie sú na zozname trvalých klientov, ktorí môžu stále používať AdGuard Home",
"auto_clients_desc": "Informácie o IP adresách zariadení, ktoré používajú alebo môžu používať AdGuard Home. Tieto informácie sa získavajú z viacerých zdrojov vrátane súborov hosts, reverzného DNS atď.",
"access_title": "Nastavenia prístupu",
"access_desc": "Tu môžete konfigurovať pravidlá prístupu pre server DNS AdGuard Home.",
"access_allowed_title": "Povolení klienti",
@@ -478,7 +481,9 @@
"setup_dns_notice": "Pre použitie <1>DNS-over-HTTPS</1> alebo <1>DNS-over-TLS</1>, potrebujete v nastaveniach AdGuard Home <0>nakonfigurovať šifrovanie</0>.",
"rewrite_added": "DNS prepísanie pre \"{{key}}\" bolo úspešne pridané",
"rewrite_deleted": "DNS prepísanie pre \"{{key}}\" bolo úspešne vymazané",
"rewrite_updated": "Prepísanie DNS bolo úspešne aktualizované",
"rewrite_add": "Pridať DNS prepísanie",
"rewrite_edit": "Upraviť prepísanie DNS",
"rewrite_not_found": "Neboli nájdené žiadne DNS prepísania",
"rewrite_confirm_delete": "Naozaj chcete odstrániť prepísanie DNS pre \"{{key}}\"?",
"rewrite_desc": "Umožňuje ľahko nakonfigurovať vlastnú odpoveď DNS pre konkrétne meno domény.",
@@ -495,7 +500,7 @@
"blocked_services": "Blokované služby",
"blocked_services_desc": "Umožňuje rýchlo blokovať populárne stránky a služby.",
"blocked_services_saved": "Blokované služby boli úspešne uložené",
"blocked_services_global": "Použite globálne blokované služby",
"blocked_services_global": "Použiť globálne blokované služby",
"blocked_service": "Blokované služby",
"block_all": "Blokovať všetko",
"unblock_all": "Odblokovať všetko",
@@ -552,7 +557,7 @@
"whois": "WHOIS",
"filtering_rules_learn_more": "<0>Dozvedieť sa viac</0> o tvorbe vlastných zoznamov hostiteľov.",
"blocked_by_response": "Blokované pomocou CNAME alebo IP v odpovedi",
"blocked_by_cname_or_ip": "Zablokované na základe CNAME alebo IP",
"blocked_by_cname_or_ip": "Blokované pomocou CNAME alebo IP",
"try_again": "Skúste znova",
"domain_desc": "Zadajte meno domény alebo zástupný znak, ktorý chcete prepísať.",
"example_rewrite_domain": "prepísať odpovede iba pre toto meno domény.",
@@ -569,7 +574,7 @@
"autofix_warning_list": "Bude vykonávať tieto úlohy: <0>Deaktivovať systém DNSStubListener</0> <0>Nastaviť adresu servera DNS na 127.0.0.1</0> <0>Nahradiť cieľový symbolický odkaz /etc/resolv.conf na /run/systemd/resolve/resolv.conf</0> <0>Zastaviť službu DNSStubListener (znova načítať službu systemd-resolved)</0>",
"autofix_warning_result": "Výsledkom bude, že všetky DNS dopyty z Vášho systému budú štandardne spracované službou AdGuard Home.",
"tags_title": "Tagy",
"tags_desc": "Môžete vybrať značky, ktoré zodpovedajú klientovi. Zahrňte značky do pravidiel filtrovania, aby ste ich použili presnejšie. <0>Viac informácií</0>.",
"tags_desc": "Môžete vybrať značky, ktoré zodpovedajú klientovi. Zahrňte značky do pravidiel filtrácie, aby ste ich použili presnejšie. <0>Viac informácií</0>.",
"form_select_tags": "Zvoľte tagy klienta",
"check_title": "Skontrolujte filtráciu",
"check_desc": "Skontrolujte, či je názov hostiteľa filtrovaný.",
@@ -606,7 +611,7 @@
"show_whitelisted_responses": "Obsiahnuté v bielej listine",
"show_processed_responses": "Spracované",
"blocked_safebrowsing": "Zablokované modulom Bezpečné prehliadanie",
"blocked_adult_websites": "Zablokovaná stránka pre dospelých",
"blocked_adult_websites": "Zablokované Rodičovskou kontrolou",
"blocked_threats": "Zablokované hrozby",
"allowed": "Povolené",
"filtered": "Filtrované",

View File

@@ -125,6 +125,8 @@
"top_clients": "Najpogostejši odjemalci",
"no_clients_found": "Ni najdenih odjemalcev",
"general_statistics": "Splošna statistika",
"top_upstreams": "Pogosto zahtevani gorvodni strežniki",
"no_upstreams_data_found": "Ni podatkov o gorvodnih strežnikih",
"number_of_dns_query_days": "Število obdelanih poizvedb DNS v zadnjem {{count}} dnevu",
"number_of_dns_query_days_plural": "Število obdelanih poizvedb DNS v zadnjih {{count}} dneh",
"number_of_dns_query_24_hours": "Število obdelanih poizvedb DNS v zadnjih 24 urah",
@@ -134,6 +136,7 @@
"enforced_save_search": "Prisilno varno iskanje",
"number_of_dns_query_to_safe_search": "Število zahtev DNS za iskalnike, za katere je bilo uveljavljeno varno iskanje",
"average_processing_time": "Povprečni čas obdelave",
"processing_time": "Čas obdelave",
"average_processing_time_hint": "Povprečni čas v milisekundah pri obdelavi zahteve DNS",
"block_domain_use_filters_and_hosts": "Onemogoči domene s filtri in gostiteljskimi datotekami",
"filters_block_toggle_hint": "Pravila zaviranja lahko nastavite v nastavitvah <a>Filtri</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Nastavljen v {{path}}",
"test_upstream_btn": "Preizkusi upstreame",
"upstreams": "Tokovi navzgor",
"upstream": "Gorvodni strežnik",
"apply_btn": "Uporabi",
"disabled_filtering_toast": "Onemogočeno filtriranje",
"enabled_filtering_toast": "Omogočeno filtriranje",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Ali ste prepričani, da želite izbrisati odjemalca \"{{key}}\"?",
"list_confirm_delete": "Ali ste prepričani, da želite izbrisati ta seznam?",
"auto_clients_title": "Odjemalci izvajanja",
"auto_clients_desc": "Naprave, ki niso na seznamu trajnih odjemalcev, ki morda še vedno uporabljajo AdGuard Home",
"auto_clients_desc": "Informacije o naslovih IP naprav, ki uporabljajo ali bi lahko uporabljale AdGuard Home. Te informacije so zbrane iz več virov, vključno z datotekami gostiteljev, povratnim DNS-jem itd.",
"access_title": "Nastavitve dostopa",
"access_desc": "Tukaj lahko nastavite pravila dostopa strežnika DNS AdGuard Home",
"access_allowed_title": "Dovoljeni odjemalci",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Za uporabo <1>DNS-prek-HTTPS</1> ali <1>DNS-prek-TLS</1>, morate <0>konfigurirati šifriranje</0> v nastavitvah AdGuard Home.",
"rewrite_added": "Uspešno je dodano DNS prepisovanje za \"{{key}}\"",
"rewrite_deleted": "Uspešno je izbrisano DNS prepisovanje za \"{{key}}\"",
"rewrite_updated": "DNS prepisovanje uspešno posodobljen",
"rewrite_add": "Dodaj prepisovanje DNS",
"rewrite_edit": "Urejanje prepisa DNS",
"rewrite_not_found": "Ni bilo najdenih prepisovanj DNS",
"rewrite_confirm_delete": "Ali ste prepričani, da želite izbrisati prepisovanje DNS za \"{{key}}\"?",
"rewrite_desc": "Omogoča enostavno konfiguriranje odgovora DNS po meri za določeno ime domene.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Najčešći klijenti",
"no_clients_found": "Nema pronađenih klijenata",
"general_statistics": "Opšte statistike",
"top_upstreams": "Često traženi upstream serveri",
"no_upstreams_data_found": "Nema podataka o upstream serverima",
"number_of_dns_query_days": "Broj obrađenih DNS unosa u poslednjih {{count}} dan",
"number_of_dns_query_days_plural": "Broj obrađenih DNS unosa u poslednjih {{count}} dana",
"number_of_dns_query_24_hours": "Broj obrađenih DNS unosa u poslednja 24 časa",
@@ -158,6 +160,7 @@
"upstream_dns_configured_in_file": "Konfiguriši u {{path}}",
"test_upstream_btn": "Testiraj upstreams",
"upstreams": "Upstreams",
"upstream": "Upstream-server",
"apply_btn": "Primeni",
"disabled_filtering_toast": "Isključeno filtriranje",
"enabled_filtering_toast": "Uključeno filtriranje",
@@ -167,6 +170,7 @@
"enabled_parental_toast": "Uključena roditeljska kontrola",
"disabled_safe_search_toast": "Isključena sigurna pretraga",
"enabled_save_search_toast": "Uključeno sigurno pretraživanje",
"updated_save_search_toast": "Ažurirane postavke bezbedne pretrage",
"enabled_table_header": "Uključeno",
"name_table_header": "Ime",
"list_url_table_header": "URL do liste",
@@ -256,12 +260,12 @@
"query_log_cleared": "Dnevnik unosa je uspešno očišćen",
"query_log_updated": "Dnevnik zapisa je uspešno ažuriran",
"query_log_clear": "Očisti dnevnike unosa",
"query_log_retention": "Zadržavanje dnevnika unosa",
"query_log_retention": "Rotacija evidencija upita",
"query_log_enable": "Uključi dnevnik",
"query_log_configuration": "Konfiguracija dnevnika",
"query_log_disabled": "Dnevnik unosa je isključen ali se može konfigurisati u <0>postavkama</0>",
"query_log_strict_search": "Koristi duple navodnike za striktnu pretragu",
"query_log_retention_confirm": "Jeste li sigurni da želite da promenite zadržavanje dnevnika unosa? Ako smanjite vrednost intervala, neki podaci će biti izgubljeni",
"query_log_retention_confirm": "Želite li zaista da promenite rotaciju evidencije upita? Ako smanjite vrednost intervala, neki podaci će biti izgubljeni",
"anonymize_client_ip": "Anonimizuj IP klijenta",
"anonymize_client_ip_desc": "Ne čuvaj punu IP adresu klijenta u dnevnicima i statistikama",
"dns_config": "Konfiguracija DNS servera",
@@ -290,6 +294,8 @@
"rate_limit": "Ograničenje brzine",
"edns_enable": "Uključi EDNS Client Subnet",
"edns_cs_desc": "Dodajte opciju podmreži EDNS klijenta (ECS) uzvodnim zahtevima i evidentirajte vrednosti koje klijenti šalju u evidenciji upita.",
"edns_use_custom_ip": "Koristi prilagođeni IP za EDNS",
"edns_use_custom_ip_desc": "Dozvoli korišćenje prilagođenog IP-a za EDNS",
"rate_limit_desc": "Broj zahteva u sekundi dozvoljen po klijentu. Postavljanje na 0 znači da nema ograničenja.",
"blocking_ipv4_desc": "IP adresa koja će biti vraćena za blokirane zahteve",
"blocking_ipv6_desc": "IP adresa koja će biti vraćena za blokirane AAAA zahteve",
@@ -441,7 +447,7 @@
"client_confirm_delete": "Jeste li sigurni da želite da izbrišete klijenta \"{{key}}\"?",
"list_confirm_delete": "Jeste li sigurni da želite da izbrišete ovu listu?",
"auto_clients_title": "Klijenti (runtime)",
"auto_clients_desc": "Uređaji koji nisu na listi upornih klijenata koji i dalje mogu da koriste AdGuard Home",
"auto_clients_desc": "Podaci o klijentima koji koriste AdGuard Home, ali nisu sačuvani u konfiguraciji",
"access_title": "Postavke pristupa",
"access_desc": "Ovde možete konfigurisati pravila pristupa za AdGuard Home DNS server",
"access_allowed_title": "Dozvoljeni klijenti",
@@ -475,7 +481,9 @@
"setup_dns_notice": "Kako biste koristili <1>DNS-over-HTTPS</1> ili <1>DNS-over-TLS</1>, potrebno je da <0>konfigurišete šifrovanje</0> u AdGuard Home postavkama.",
"rewrite_added": "DNS prepisivanje za \"{{key}}\" je uspešno dodato",
"rewrite_deleted": "DNS prepisivanje za \"{{key}}\" uspešno izbrisano",
"rewrite_updated": "DNS ponovo napisao uspešno ažuriran",
"rewrite_add": "Dodaj DNS prepisivanje",
"rewrite_edit": "Uređivanje DNS prepravke",
"rewrite_not_found": "DNS prepisivanja nisu pronađena",
"rewrite_confirm_delete": "Jeste li sigurni da želite da izbrišete DNS prepisivanje za \"{{key}}\"?",
"rewrite_desc": "Dozvoljava da jednostavno konfigurišete prilagođeni DNS odgovor za određeni domen.",
@@ -523,6 +531,10 @@
"statistics_retention_confirm": "Jeste li sigurni da želite da promenite zadržavanje statistike? Ako smanjite vrednost intervala, neki podaci će biti izgubljeni",
"statistics_cleared": "Statistika je uspešno očišćena",
"statistics_enable": "Uključi statistiku",
"ignore_domains": "Zanemari domene (razdvojene novom linijom)",
"ignore_domains_title": "Zanemareni domeni",
"ignore_domains_desc_stats": "Upiti za ove domene nisu upisani u statistiku",
"ignore_domains_desc_query": "Upiti za ove domene nisu upisani u evidenciju upita",
"interval_hours": "{{count}} čas",
"interval_hours_plural": "{{count}} časova",
"filters_configuration": "Konfiguracija filtera",
@@ -643,5 +655,29 @@
"confirm_dns_cache_clear": "Želite li zaista da obrišite DNS keš?",
"cache_cleared": "DNS keš je uspešno očišćen",
"clear_cache": "Obriši keš memoriju",
"protection_section_label": "Zaštita"
"make_static": "Učini statičnim",
"theme_auto_desc": "Automatski (na osnovu šeme boja uređaja)",
"theme_dark_desc": "Tamna tema",
"theme_light_desc": "Svetla tema",
"disable_for_seconds": "Za {{count}} sekund",
"disable_for_seconds_plural": "Za {{count}} sekundi",
"disable_for_minutes": "Za {{count}} minut",
"disable_for_minutes_plural": "Za {{count}} minuta",
"disable_for_hours": "Za {{count}} sat",
"disable_for_hours_plural": "Za {{count}} sati",
"disable_until_tomorrow": "Do sutra",
"disable_notify_for_seconds": "Isključi zaštitu na {{count}} sekund",
"disable_notify_for_seconds_plural": "Isključi zaštitu na {{count}} sekundi",
"disable_notify_for_minutes": "Isključi zaštitu na {{count}} minut",
"disable_notify_for_minutes_plural": "Isključi zaštitu na {{count}} minuta",
"disable_notify_for_hours": "Isključi zaštitu na {{count}} sat",
"disable_notify_for_hours_plural": "Isključi zaštitu na {{count}} sati",
"disable_notify_until_tomorrow": "Isključi zaštitu do sutra",
"enable_protection_timer": "Zaštita će biti uključena u {{time}}",
"custom_retention_input": "Unesite zadržavanje u časovima",
"custom_rotation_input": "Unesite rotaciju u časovima",
"protection_section_label": "Zaštita",
"log_and_stats_section_label": "Evidencija upita i statistika",
"ignore_query_log": "Zanemari ovog klijenta u evidenciji upita",
"ignore_statistics": "Zanemari ovog klijenta u statističkim podacima"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "Toppklienter",
"no_clients_found": "Inga klienter hittade",
"general_statistics": "Allmän statistik",
"top_upstreams": "Topp uppströmsservrar",
"no_upstreams_data_found": "Inga uppströmsdata hittades",
"number_of_dns_query_days": "Antalet DNS-förfrågningar som utfördes under senaste {{count}} dagen",
"number_of_dns_query_days_plural": "Ett antal DNS förfrågningar utfördes under de senaste {{count}} dagarna",
"number_of_dns_query_24_hours": "Antalet DNS-förfrågningar som utfördes under de senaste 24 timmarna",
@@ -134,6 +136,7 @@
"enforced_save_search": "Aktivering av Säker surf",
"number_of_dns_query_to_safe_search": "Antalet DNS-förfrågningar mot sökmotorer där Säker surf tvingats",
"average_processing_time": "Genomsnittlig processtid",
"processing_time": "Bearbetningstid",
"average_processing_time_hint": "Genomsnittlig processtid i millisekunder för DNS-förfrågning",
"block_domain_use_filters_and_hosts": "Blockera domäner med filter- och värdfiler",
"filters_block_toggle_hint": "Du kan ställa in egna blockerings regler i <a>Filterinställningar</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Konfigurerad i {{path}}",
"test_upstream_btn": "Testa uppströmmar",
"upstreams": "Uppströms",
"upstream": "Uppströms server",
"apply_btn": "Tillämpa",
"disabled_filtering_toast": "Filtrering bortkopplad",
"enabled_filtering_toast": "Filtrering inkopplad",
@@ -475,7 +479,9 @@
"setup_dns_notice": "För att kunna använda <1>DNS-över-HTTPS</1> eller <1>DNS-över-TLS</1>, behöver du <0>konfigurera Kryptering</0> i AdGuard Home-inställningar.",
"rewrite_added": "DNS-omskrivning för \"{{key}}\" lyckad",
"rewrite_deleted": "DNS-omskrivning för \"{{key}}\" har tagits bort",
"rewrite_updated": "DNS-omskrivning har uppdaterats",
"rewrite_add": "Lägg till DNS omskrivning",
"rewrite_edit": "Redigera DNS-omskrivning",
"rewrite_not_found": "Inga DNS omskrivningar hittades",
"rewrite_confirm_delete": "Är du säker på att du vill ta bort DNS-omskrivningen för \"{{key}}\"?",
"rewrite_desc": "Gör det enkelt att konfigurera anpassat DNS svar för ett specifikt domännamn.",

View File

@@ -172,6 +172,7 @@
"dnscrypt": "DNSCrypt",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"dns_over_quic": "DNS-over-QUIC",
"form_enter_rate_limit": "ป้อนขีดจำกัดอัตรา",
"rate_limit": "จำกัดอัตรา",
"edns_enable": "เปิดใช้งานซับเน็ตไคลเอ็นต์ EDNS",
@@ -392,6 +393,7 @@
"show_processed_responses": "การประมวลผล",
"blocked_adult_websites": "ถูกปิดกั้นโดยการควบคุมของผู้ปกครอง",
"safe_search": "ค้นหาอย่างปลอดภัย",
"blocklist": "บัญชีดำ",
"filter_category_other": "อื่น ๆ",
"parental_control": "ควบคุมโดยผู้ปกครอง"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "Başlıca istemciler",
"no_clients_found": "İstemci bulunamadı",
"general_statistics": "Genel istatistikler",
"top_upstreams": "Başlıca üst kaynaklar",
"no_upstreams_data_found": "Üst kaynak verisi bulunamadı",
"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ı",
@@ -134,6 +136,7 @@
"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",
"processing_time": "İşlem süresi",
"average_processing_time_hint": "Bir DNS isteğinin milisaniye cinsinden ortalama işlem süresi",
"block_domain_use_filters_and_hosts": "Filtre ve hosts dosyalarını kullanarak alan adlarını engelle",
"filters_block_toggle_hint": "<a>Filtreler</a> ayarlarında engelleme kuralları oluşturabilirsiniz.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "{{path}} dosyasında yapılandırıldı",
"test_upstream_btn": "Üst sunucuyu test et",
"upstreams": "Üst kaynak",
"upstream": "Üst kaynak",
"apply_btn": "Uygula",
"disabled_filtering_toast": "Filtreleme devre dışı",
"enabled_filtering_toast": "Filtreleme etkin",
@@ -444,7 +448,7 @@
"client_confirm_delete": "\"{{key}}\" istemcisini silmek istediğinizden emin misiniz?",
"list_confirm_delete": "Bu listeyi silmek istediğinizden emin misiniz?",
"auto_clients_title": "Çalışma zamanı istemcileri",
"auto_clients_desc": "Henüz AdGuard Home'u kullanabilecek Kalıcı istemciler listesinde olmayan cihazlar",
"auto_clients_desc": "AdGuard Home'u kullanan veya kullanabilecek cihazların IP adresleri hakkında bilgiler. Bu bilgiler, hosts dosyaları, ters DNS, vb. dahil olmak üzere çeşitli kaynaklardan toplanır.",
"access_title": "Erişim ayarları",
"access_desc": "AdGuard Home DNS sunucusu için erişim kurallarını buradan yapılandırabilirsiniz",
"access_allowed_title": "İzin verilen istemciler",
@@ -478,7 +482,9 @@
"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_updated": "DNS yeniden yazma başarıyla güncellendi",
"rewrite_add": "DNS yeniden yazımı ekle",
"rewrite_edit": "DNS yeniden yazmayı düzenle",
"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 özel DNS yanıtını kolayca yapılandırmanızı sağlar.",

View File

@@ -125,6 +125,8 @@
"top_clients": "Найактивніші клієнти",
"no_clients_found": "Клієнтів не знайдено",
"general_statistics": "Загальна статистика",
"top_upstreams": "Часто запитувані upstream-сервери",
"no_upstreams_data_found": "Немає даних про upstream-сервери",
"number_of_dns_query_days": "Кількість DNS-запитів, оброблених за останні {{count}} дні",
"number_of_dns_query_days_plural": "Кількість DNS-запитів, оброблених за останні {{count}} днів",
"number_of_dns_query_24_hours": "Кількість DNS-запитів, оброблених за останні 24 години",
@@ -134,6 +136,7 @@
"enforced_save_search": "Примусовий безпечний пошук",
"number_of_dns_query_to_safe_search": "Кількість DNS-запитів до пошукових систем, для яких примусово застосований безпечний пошук",
"average_processing_time": "Середній час обробки",
"processing_time": "Час обробки",
"average_processing_time_hint": "Середній час обробки DNS запиту в мілісекундах",
"block_domain_use_filters_and_hosts": "Блокування доменів за допомогою фільтрів та hosts-файлів",
"filters_block_toggle_hint": "Ви можете налаштувати правила блокування в розділі <a>Фільтри</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Налаштовано в {{path}}",
"test_upstream_btn": "Перевірити сервери",
"upstreams": "Upstreams",
"upstream": "Upstream-сервер",
"apply_btn": "Застосувати",
"disabled_filtering_toast": "Фільтрування вимкнено",
"enabled_filtering_toast": "Фільтрування увімкнено",
@@ -444,7 +448,7 @@
"client_confirm_delete": "Ви впевнені, що хочете видалити клієнта «{{key}}»?",
"list_confirm_delete": "Ви впевнені, що хочете видалити цей список?",
"auto_clients_title": "Runtime-клієнти",
"auto_clients_desc": "Клієнти, які використовують AdGuard Home, незалежно від того, чи збережені вони в списку постійних",
"auto_clients_desc": "Інформація про IP-адреси пристроїв, які використовують або можуть використовувати AdGuard Home. Ця інформація збирається з кількох джерел, зокрема з файлів hosts, зворотного DNS тощо.",
"access_title": "Налаштування доступу",
"access_desc": "Тут ви можете налаштувати правила доступу для DNS-сервера AdGuard Home",
"access_allowed_title": "Дозволені клієнти",
@@ -478,7 +482,9 @@
"setup_dns_notice": "Для використання <1>DNS-over-HTTPS</1> або <1>DNS-over-TLS</1>, вам потрібно <0>налаштувати Шифрування</0> в налаштуваннях AdGuard Home.",
"rewrite_added": "Перезапис DNS для «{{key}}» успішно додано",
"rewrite_deleted": "Перезапис DNS для «{{key}}» успішно видалено",
"rewrite_updated": "Перезапис DNS успішно оновлено",
"rewrite_add": "Додати перезапис DNS",
"rewrite_edit": "Редагувати перезапис DNS",
"rewrite_not_found": "Перезаписів DNS не знайдено",
"rewrite_confirm_delete": "Ви впевнені, що хочете видалити перезапис DNS для «{{key}}»?",
"rewrite_desc": "Дозволяє легко налаштувати власну відповідь DNS для певного доменного імені.",

View File

@@ -1,5 +1,5 @@
{
"client_settings": "Cài đặt máy khách",
"client_settings": "Cài đặt thiết bị",
"example_upstream_reserved": "ngược dòng <0>cho các miền cụ thể</0>;",
"example_upstream_comment": "một lời bình luận.",
"upstream_parallel": "Sử dụng truy vấn song song để tăng tốc độ giải quyết bằng cách truy vấn đồng thời tất cả các máy chủ ngược tuyến",
@@ -125,6 +125,8 @@
"top_clients": "Người dùng hàng đầu",
"no_clients_found": "Không có người dùng",
"general_statistics": "Thống kê chung",
"top_upstreams": "Máy chủ thượng nguồn hàng đầu",
"no_upstreams_data_found": "Không tìm thấy dữ liệu máy chủ ngược dòng",
"number_of_dns_query_days": "Một số truy vấn DNS được xử lý trong {{count}} ngày qua",
"number_of_dns_query_days_plural": "Một số truy vấn DNS được xử lý trong {{count}} ngày qua",
"number_of_dns_query_24_hours": "Số yêu cầu DNS đã xử lý trong 24 giờ qua",
@@ -134,6 +136,7 @@
"enforced_save_search": "Bắt buộc tìm kiếm an toàn",
"number_of_dns_query_to_safe_search": "Số yêu cầu DNS tới công cụ tìm kiếm đã chuyển thành tìm kiếm an toàn",
"average_processing_time": "Thời gian xử lý trung bình",
"processing_time": "Thời gian xử lý",
"average_processing_time_hint": "Thời gian trung bình cho một yêu cầu DNS tính bằng mili giây",
"block_domain_use_filters_and_hosts": "Chặn tên miền sử dụng các bộ lọc và file hosts",
"filters_block_toggle_hint": "Bạn có thể thiết lập quy tắc chặn tại cài đặt <a>Bộ lọc</a>.",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "Cấu hình tại {{path}}",
"test_upstream_btn": "Kiểm tra",
"upstreams": "Nguồn",
"upstream": "Máy chủ thượng nguồn",
"apply_btn": "Áp dụng",
"disabled_filtering_toast": "Đã tắt chặn quảng cáo",
"enabled_filtering_toast": "Đã bật chặn quảng cáo",
@@ -167,6 +171,7 @@
"enabled_parental_toast": "Đã bật quản lý của phụ huynh",
"disabled_safe_search_toast": "Đã tắt tìm kiếm an toàn",
"enabled_save_search_toast": "Đã bật tìm kiếm an toàn",
"updated_save_search_toast": "Cài đặt Tìm kiếm an toàn đã được cập nhật",
"enabled_table_header": "Kích hoạt",
"name_table_header": "Tên",
"list_url_table_header": "URL bộ lọc",
@@ -256,12 +261,12 @@
"query_log_cleared": "Nhật ký truy vấn đã được xóa thành công",
"query_log_updated": "Cập nhật thành công nhật kí truy xuất",
"query_log_clear": "Xóa nhật ký truy vấn",
"query_log_retention": "Lưu giữ nhật ký truy vấn",
"query_log_retention": "Xoay vòng nhật ký truy vấn",
"query_log_enable": "Bật nhật ký",
"query_log_configuration": "Cấu hình nhật ký",
"query_log_disabled": "Nhật ký truy vấn bị vô hiệu hóa và có thể được định cấu hình trong <0>cài đặt</ 0>",
"query_log_strict_search": "Sử dụng dấu ngoặc kép để tìm kiếm nghiêm ngặt",
"query_log_retention_confirm": "Bạn có chắc chắn muốn thay đổi lưu giữ nhật ký truy vấn? Nếu bạn giảm giá trị khoảng, một số dữ liệu sẽ bị mất",
"query_log_retention_confirm": "Bạn có chắc chắn muốn thay đổi xoay vòng nhật ký truy vấn không? Nếu bạn giảm giá trị khoảng thời gian, một số dữ liệu sẽ bị mất",
"anonymize_client_ip": "Ẩn danh IP khách",
"anonymize_client_ip_desc": "Không lưu địa chỉ IP đầy đủ của khách hàng trong nhật ký và thống kê",
"dns_config": "Thiết lập máy chủ DNS",
@@ -290,6 +295,8 @@
"rate_limit": "Giới hạn yêu cầu",
"edns_enable": "Bật mạng con EDNS Client",
"edns_cs_desc": "Thêm tùy chọn EDNS Client Subnet (ECS) vào các yêu cầu ngược dòng và ghi lại các giá trị được gửi bởi các máy khách trong nhật ký truy vấn.",
"edns_use_custom_ip": "Sử dụng địa chỉ IP tùy chỉnh cho EDNS",
"edns_use_custom_ip_desc": "Cho phép sử dụng địa chỉ IP tùy chỉnh cho EDNS",
"rate_limit_desc": "Số lượng yêu cầu mỗi giây mà một khách hàng được phép thực hiện (0: không giới hạn)",
"blocking_ipv4_desc": "Địa chỉ IP được trả lại cho một yêu cầu A bị chặn",
"blocking_ipv6_desc": "Địa chỉ IP được trả lại cho một yêu cầu AAA bị chặn",
@@ -441,7 +448,7 @@
"client_confirm_delete": "Bạn có chắc chắn muốn xóa máy khách \"{{key}}\" không?",
"list_confirm_delete": "Bạn có muốn xóa bộ lọc này?",
"auto_clients_title": "Máy khách (thời gian chạy)",
"auto_clients_desc": "Các thiết bị không có trong danh sách khách hàng ổn định vẫn có thể sử dụng AdGuard Home",
"auto_clients_desc": "Thông tin về địa chỉ IP của thiết bị đang sử dụng hoặc có thể sử dụng AdGuard Home. Thông tin này được thu thập từ nhiều nguồn, bao gồm tệp máy chủ, DNS ngược, v.v.",
"access_title": "Cài đặt truy cập",
"access_desc": "Tại đây bạn có thể định cấu hình quy tắc truy cập cho máy chủ AdGuard Home DNS",
"access_allowed_title": "Máy chủ được phép",
@@ -475,7 +482,9 @@
"setup_dns_notice": "Để sử dụng <1>DNS-over-HTTPS</1> hoặc <1>DNS-over-TLS</1>, bạn cần <0>định cấu hình Mã hóa</0> trong cài đặt AdGuard Home.",
"rewrite_added": "DNS viết lại cho \"{{key}}\" đã thêm thành công",
"rewrite_deleted": "DNS viết lại cho \"{{key}}\" đã xóa thành công",
"rewrite_updated": "Viết lại DNS được cập nhật thành công",
"rewrite_add": "Thêm DNS viết lại",
"rewrite_edit": "Chỉnh sửa viết lại DNS",
"rewrite_not_found": "Không tìm thấy DNS viết lại",
"rewrite_confirm_delete": "Bạn có chắc chắn muốn xóa DNS viết lại cho \"{{key}}\" không?",
"rewrite_desc": "Cho phép dễ dàng định cấu hình tùy chỉnh DNS phản hồi cho một tên miền cụ thể.",
@@ -523,6 +532,10 @@
"statistics_retention_confirm": "Bạn có chắc chắn muốn thay đổi lưu giữ số liệu thống kê? Nếu bạn giảm giá trị khoảng, một số dữ liệu sẽ bị mất",
"statistics_cleared": "Xoá thống kê thành công",
"statistics_enable": "Bật thống kê",
"ignore_domains": "Các miền bị bỏ qua (cách nhau bởi dòng mới)",
"ignore_domains_title": "Các miền bị bỏ qua",
"ignore_domains_desc_stats": "Các truy vấn cho các miền này sẽ không được ghi vào thống kê",
"ignore_domains_desc_query": "Các truy vấn cho các miền này sẽ không được ghi vào nhật ký truy vấn",
"interval_hours": "{{count}} giờ",
"interval_hours_plural": "{{count}} giờ",
"filters_configuration": "Cấu hình bộ lọc",
@@ -643,5 +656,29 @@
"confirm_dns_cache_clear": "Bạn có chắc chắn muốn xóa bộ đệm ẩn DNS không?",
"cache_cleared": "Đã xóa thành công bộ đệm DNS",
"clear_cache": "Xóa bộ nhớ cache",
"protection_section_label": "Sự bảo vệ"
"make_static": "Chuyển sang tĩnh",
"theme_auto_desc": "Tự động (dựa trên chủ đề màu của thiết bị của bạn)",
"theme_dark_desc": "Chủ đề tối",
"theme_light_desc": "Chủ đề sáng",
"disable_for_seconds": "Trong {{count}} giây",
"disable_for_seconds_plural": "Trong {{count}} giây",
"disable_for_minutes": "Trong {{count}} phút",
"disable_for_minutes_plural": "Trong {{count}} phút",
"disable_for_hours": "Trong {{count}} giờ",
"disable_for_hours_plural": "Trong {{count}} giờ",
"disable_until_tomorrow": "Cho đến ngày mai",
"disable_notify_for_seconds": "Tắt bảo vệ trong {{count}} giây",
"disable_notify_for_seconds_plural": "Tắt bảo vệ trong {{count}} giây",
"disable_notify_for_minutes": "Tắt bảo vệ trong {{count}} phút",
"disable_notify_for_minutes_plural": "Tắt bảo vệ trong {{count}} phút",
"disable_notify_for_hours": "Tắt bảo vệ trong {{count}} giờ",
"disable_notify_for_hours_plural": "Tắt bảo vệ trong {{count}} giờ",
"disable_notify_until_tomorrow": "Vô hiệu hóa bảo vệ cho đến ngày mai",
"enable_protection_timer": "Bảo vệ sẽ được bật trong {{time}}",
"custom_retention_input": "Nhập thời gian giữ lại theo giờ",
"custom_rotation_input": "Nhập chu kỳ theo giờ",
"protection_section_label": "Sự bảo vệ",
"log_and_stats_section_label": "Nhật ký truy vấn và thống kê",
"ignore_query_log": "Bỏ qua máy khách này trong nhật ký truy vấn",
"ignore_statistics": "Bỏ qua máy khách này trong thống kê"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "客户端排行",
"no_clients_found": "未找到客户端",
"general_statistics": "概况统计",
"top_upstreams": "经常请求的上游服务器",
"no_upstreams_data_found": "未找到上游服务器数据",
"number_of_dns_query_days": "过去 {{count}} 天内处理的 DNS 查询总数",
"number_of_dns_query_days_plural": "在过去的 {{count}} 天内处理了多少个 DNS 查询",
"number_of_dns_query_24_hours": "过去 24 小时内处理的 DNS 请求总数",
@@ -134,6 +136,7 @@
"enforced_save_search": "强制安全搜索",
"number_of_dns_query_to_safe_search": "启用强制安全搜索后对搜索引擎的 DNS 请求总数",
"average_processing_time": "平均处理时间",
"processing_time": "处理时间",
"average_processing_time_hint": "处理 DNS 请求的平均时间(毫秒)",
"block_domain_use_filters_and_hosts": "使用过滤器和 Hosts 文件以拦截指定域名",
"filters_block_toggle_hint": "你可以在 <a>过滤器</a> 设置中添加过滤规则。",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "配置路径{{path}}",
"test_upstream_btn": "测试上游 DNS",
"upstreams": "上游服务器",
"upstream": "上游服务器",
"apply_btn": "应用",
"disabled_filtering_toast": "过滤器已禁用",
"enabled_filtering_toast": "过滤器已启用",
@@ -444,7 +448,7 @@
"client_confirm_delete": "您确定要删除客户端 \"{{key}}\"",
"list_confirm_delete": "您确定要删除此列表吗?",
"auto_clients_title": "客户端(运行时间)",
"auto_clients_desc": "不在可继续使用 AdGuard Home 的持久客户端列表中的设备。",
"auto_clients_desc": "有关正在使用或可能使用 AdGuard Home 的设备的 IP 地址的信息。此信息是从多个来源收集的,包括 hosts 文件、反向 DNS 等。",
"access_title": "访问设置",
"access_desc": "您可以在此处配置 AdGuard Home 的 DNS 服务器的访问规则",
"access_allowed_title": "允许的客户端",
@@ -478,7 +482,9 @@
"setup_dns_notice": "为了使用 <1>DNS-over-HTTPS</1> 或者 <1>DNS-over-TLS</1> ,您需要在 AdGuard Home 设置中 <0>配置加密</0> 。",
"rewrite_added": "已成功添加 \"{{key}}\" 的 DNS 重写",
"rewrite_deleted": "已成功删除 \"{{key}}\" 的 DNS 重写",
"rewrite_updated": "DNS 重写已成功更新",
"rewrite_add": "添加 DNS 重写",
"rewrite_edit": "编辑 DNS 重写",
"rewrite_not_found": "未找到 DNS 重写",
"rewrite_confirm_delete": "您确定要删除 \"{{key}}\" 的 DNS 重写?",
"rewrite_desc": "可以轻松地为特定域名配置自定义 DNS 响应。",

View File

@@ -48,6 +48,7 @@
"out_of_range_error": "必須介於 \"{{start}}\" - \"{{end}}\" 範圍之外",
"lower_range_start_error": "必須小於起始值",
"greater_range_start_error": "必須大於起始值",
"gateway_or_subnet_invalid": "無效子網路",
"dhcp_form_gateway_input": "閘道 IP 位址",
"dhcp_form_subnet_input": "子網路遮罩",
"dhcp_form_range_title": "IP 位址範圍",
@@ -163,7 +164,7 @@
"disabled_parental_toast": "已停用家長監護",
"enabled_parental_toast": "已啟用家長監護",
"disabled_safe_search_toast": "已停用安全搜尋",
"enabled_save_search_toast": "已啟用安全搜尋",
"updated_save_search_toast": "已更新安全搜尋設定",
"enabled_table_header": "啟用",
"name_table_header": "名稱",
"list_url_table_header": "清單 URL 網址",
@@ -195,6 +196,7 @@
"form_error_url_or_path_format": "列表中含有的 URL 網址或絕對路徑",
"custom_filter_rules": "自訂過濾規則",
"custom_filter_rules_hint": "一行一條規則。您可以使用「adblock」語法或「hosts檔案」的語法。",
"system_host_files": "系統 hosts 檔案",
"examples_title": "範例",
"example_meaning_filter_block": "封鎖對 example.org 網域及其所有子網域的存取",
"example_meaning_filter_whitelist": "解除對 example.org 網域及其所有子網域存取封鎖",
@@ -209,6 +211,10 @@
"example_upstream_doq": "加密 <0>DNS-over-QUIC</0>",
"example_upstream_sdns": "您可以使透過 <0>DNS Stamps</0> 來解析 <1>DNSCrypt</1> 或 <2>DNS-over-HTTPS</2>",
"example_upstream_tcp": "一般 DNS透過 TCP",
"example_upstream_regular_port": "一般 DNS透過 UDP連接埠",
"example_upstream_udp": "一般 DNS透過 UDP主機名稱",
"example_upstream_tcp_port": "一般 DNS透過 TCP連接埠",
"example_upstream_tcp_hostname": "一般 DNS透過 TCP主機名稱",
"all_lists_up_to_date_toast": "所有清單已更新至最新",
"dns_test_ok_toast": "設定中的 DNS 上游運作正常",
"dns_test_not_ok_toast": "DNS 設定中的 \"{{key}}\" 出現錯誤,請確認是否正確輸入",
@@ -279,6 +285,8 @@
"rate_limit": "速率限制",
"edns_enable": "啟用 EDNS Client Subnet",
"edns_cs_desc": "傳送用戶端的子網路給 DNS 伺服器。",
"edns_use_custom_ip": "使用自訂 EDNS IP",
"edns_use_custom_ip_desc": "允許使用自訂 EDNS IP",
"rate_limit_desc": "限制單一裝置每秒發出的查詢次數(設定為 0 即表示無限制)",
"blocking_ipv4_desc": "回覆指定 IPv4 位址給被封鎖的網域的 A 紀錄查詢",
"blocking_ipv6_desc": "回覆指定 IPv6 位址給被封鎖的網域的 AAAA 紀錄查詢",
@@ -287,6 +295,9 @@
"blocking_mode_nxdomain": "NXDOMAIN回應 NXDOMAIN 狀態碼",
"blocking_mode_null_ip": "Null IP回應零值的 IP 位址A 紀錄回應 0.0.0.0 AAAA 紀錄回應 ::",
"blocking_mode_custom_ip": "自訂 IP 位址:回應一個自訂的 IP 位址",
"theme_auto": "自動",
"theme_light": "明亮",
"theme_dark": "深色",
"upstream_dns_client_desc": "如果您將此欄位留白AdGuard Home 將使用 <0>DNS 設定</0> 內的設定的 DNS 伺服器。",
"tracker_source": "追蹤器來源",
"source_label": "來源",
@@ -397,6 +408,7 @@
"dns_providers": "下列為常見的<0> DNS 伺服器</0>。",
"update_now": "立即更新",
"update_failed": "自動更新發生錯誤。請嘗試依照<a>以下步驟</a> 來手動更新。",
"manual_update": "請嘗試依照<a>下列步驟</a>來手動更新。",
"processing_update": "請稍候AdGuard Home 正在更新",
"clients_title": "用戶端",
"clients_desc": "對已連接到 AdGuard Home 的裝置進行設定",
@@ -460,6 +472,7 @@
"rewrite_added": "「{{key}}」的 DNS 覆寫新增成功",
"rewrite_deleted": "「{{key}}」的 DNS 覆寫刪除成功",
"rewrite_add": "新增 DNS 覆寫",
"rewrite_edit": "編輯 DNS 覆寫",
"rewrite_not_found": "找不到 DNS 覆寫",
"rewrite_confirm_delete": "您確定要刪除 \"{{key}}\" 的 DNS 覆寫?",
"rewrite_desc": "提供簡單的方式對特定網域自訂 DNS 回應。",
@@ -493,6 +506,7 @@
"interval_days": "{{count}} 天",
"interval_days_plural": "{{count}} 天",
"domain": "網域",
"ecs": "EDNS 子網",
"punycode": "Punycode",
"answer": "回應",
"filter_added_successfully": "已成功新增清單",
@@ -505,6 +519,9 @@
"statistics_clear_confirm": "您確定要清除統計資料嗎?",
"statistics_retention_confirm": "您確定要更改統計資料保存時間嗎?如果您縮短期限部分資料可能將會遺失",
"statistics_cleared": "已清除統計資料",
"statistics_enable": "啟用統計數據",
"ignore_domains": "已忽略網域(每行一個)",
"ignore_domains_title": "已忽略網域",
"interval_hours": "{{count}} 小時",
"interval_hours_plural": "{{count}} 小時",
"filters_configuration": "過濾器設定",
@@ -613,5 +630,23 @@
"original_response": "原始回應",
"click_to_view_queries": "按一下以檢視查詢結果",
"port_53_faq_link": "連接埠 53 經常被「DNSStubListener」或「systemd-resolved」服務佔用。請閱讀下列有關解決<0>這個問題</0>的說明",
"adg_will_drop_dns_queries": "AdGuard Home 將停止回應此用戶端的所有 DNS 查詢。"
"adg_will_drop_dns_queries": "AdGuard Home 將停止回應此用戶端的所有 DNS 查詢。",
"safe_browsing": "安全瀏覽",
"served_from_cache": "{{value}} <i>(由快取回應)</i>",
"form_error_password_length": "密碼必須至少 {{value}} 個字元長度",
"make_static": "新增為靜態",
"theme_dark_desc": "深色主題",
"theme_light_desc": "淺色主題",
"disable_for_seconds": "{{count}} 秒",
"disable_for_seconds_plural": "{{count}} 秒",
"disable_for_minutes": "{{count}} 分鐘",
"disable_for_minutes_plural": "{{count}} 分鐘",
"disable_for_hours": "{{count}} 小時",
"disable_for_hours_plural": "{{count}} 小時",
"disable_until_tomorrow": "直到明天",
"disable_notify_for_seconds": "暫停防護 {{count}} 秒",
"disable_notify_for_seconds_plural": "暫停防護 {{count}} 秒",
"disable_notify_for_minutes": "暫停防護 {{count}} 分鐘",
"disable_notify_for_minutes_plural": "暫停防護 {{count}} 分鐘",
"disable_notify_for_hours": "暫停防護 {{count}} 小時"
}

View File

@@ -125,6 +125,8 @@
"top_clients": "熱門用戶端",
"no_clients_found": "無已發現之用戶端",
"general_statistics": "一般的統計資料",
"top_upstreams": "經常請求的上游伺服器",
"no_upstreams_data_found": "找不到上游伺服器資料",
"number_of_dns_query_days": "在最近的 {{count}} 日內已處理的 DNS 查詢之數量",
"number_of_dns_query_days_plural": "在最近的 {{count}} 日內已處理的 DNS 查詢之數量",
"number_of_dns_query_24_hours": "在最近的 24 小時內已處理的 DNS 查詢之數量",
@@ -134,13 +136,14 @@
"enforced_save_search": "已強制執行的安全搜尋",
"number_of_dns_query_to_safe_search": "安全搜尋已被強制執行之屬於搜尋引擎的 DNS 請求之數量",
"average_processing_time": "平均的處理時間",
"processing_time": "處理時間",
"average_processing_time_hint": "在處理一項 DNS 請求時以毫秒ms計的平均時間",
"block_domain_use_filters_and_hosts": "透過過濾器和主機檔案封鎖網域",
"filters_block_toggle_hint": "您可在<a>過濾器</a>設定中設置封鎖規則。",
"use_adguard_browsing_sec": "使用 AdGuard 瀏覽安全網路服務",
"use_adguard_browsing_sec_hint": "AdGuard Home 將檢查該網域是否被瀏覽安全網路服務封鎖。它將使用友好的隱私查找應用程式介面API以執行檢查僅域名 SHA256 雜湊的短前綴被傳送到該伺服器。",
"use_adguard_browsing_sec_hint": "AdGuard Home 將檢查該網域是否被瀏覽安全網路服務封鎖。它將使用對隱私友好的查找應用程式介面API以執行檢查僅域名 SHA256 雜湊的短前綴被傳送到該伺服器。",
"use_adguard_parental": "使用 AdGuard 家長控制之網路服務",
"use_adguard_parental_hint": "AdGuard Home 將檢查網域是否包含成人資料。它使用如同瀏覽安全網路服務一樣之友好的隱私應用程式介面API。",
"use_adguard_parental_hint": "AdGuard Home 將檢查網域是否包含成人資料。它使用如同瀏覽安全網路服務一樣之對隱私友好的應用程式介面API。",
"enforce_safe_search": "使用安全搜尋",
"enforce_save_search_hint": "AdGuard Home 將在下列的搜尋引擎Google、YouTube、Bing、DuckDuckGo、Yandex 和 Pixabay 中強制執行安全搜尋。",
"no_servers_specified": "無已明確指定的伺服器",
@@ -158,6 +161,7 @@
"upstream_dns_configured_in_file": "被配置在 {{path}}",
"test_upstream_btn": "測試上行資料流",
"upstreams": "上游",
"upstream": "上游伺服器",
"apply_btn": "套用",
"disabled_filtering_toast": "已禁用過濾",
"enabled_filtering_toast": "已啟用過濾",
@@ -444,7 +448,7 @@
"client_confirm_delete": "您確定您想要刪除用戶端 \"{{key}}\" 嗎?",
"list_confirm_delete": "您確定您想要刪除該清單嗎?",
"auto_clients_title": "執行時期用戶端",
"auto_clients_desc": "未於可能仍然使用 AdGuard Home 的持續性用戶端之清單上的裝置",
"auto_clients_desc": "AdGuard Home 使用或可能使用的裝置的 IP 地址資訊。這些資訊來自多個來源,包括主機檔案、反向 DNS 等。",
"access_title": "存取設定",
"access_desc": "於此您可配置用於 AdGuard Home DNS 伺服器之存取規則",
"access_allowed_title": "已允許的用戶端",
@@ -478,7 +482,9 @@
"setup_dns_notice": "為了使用 <1>DNS-over-HTTPS</1> 或 <1>DNS-over-TLS</1>,您需要在 AdGuard Home 設定裡<0>配置加密</0>。",
"rewrite_added": "對於 \"{{key}}\" 之 DNS 改寫被成功地加入",
"rewrite_deleted": "對於 \"{{key}}\" 之 DNS 改寫被成功地刪除",
"rewrite_updated": "DNS 重寫已成功更新",
"rewrite_add": "新增 DNS 改寫",
"rewrite_edit": "編輯 DNS 重寫",
"rewrite_not_found": "無已發現之 DNS 改寫",
"rewrite_confirm_delete": "您確定您想要刪除對於 \"{{key}}\" 之 DNS 改寫嗎?",
"rewrite_desc": "允許輕易地配置自訂的 DNS 回應供特定的域名。",

View File

@@ -38,6 +38,29 @@ export const addRewrite = (config) => async (dispatch) => {
}
};
export const updateRewriteRequest = createAction('UPDATE_REWRITE_REQUEST');
export const updateRewriteFailure = createAction('UPDATE_REWRITE_FAILURE');
export const updateRewriteSuccess = createAction('UPDATE_REWRITE_SUCCESS');
/**
* @param {Object} config
* @param {string} config.target - current DNS rewrite value
* @param {string} config.update - updated DNS rewrite value
*/
export const updateRewrite = (config) => async (dispatch) => {
dispatch(updateRewriteRequest());
try {
await apiClient.updateRewrite(config);
dispatch(updateRewriteSuccess());
dispatch(toggleRewritesModal());
dispatch(getRewritesList());
dispatch(addSuccessToast(i18next.t('rewrite_updated', { key: config.domain })));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(updateRewriteFailure());
}
};
export const deleteRewriteRequest = createAction('DELETE_REWRITE_REQUEST');
export const deleteRewriteFailure = createAction('DELETE_REWRITE_FAILURE');
export const deleteRewriteSuccess = createAction('DELETE_REWRITE_SUCCESS');

View File

@@ -56,6 +56,8 @@ export const getStats = () => async (dispatch) => {
top_clients: topClientsWithInfo,
top_queried_domains: normalizeTopStats(stats.top_queried_domains),
avg_processing_time: secondsToMilliseconds(stats.avg_processing_time),
top_upstreams_responses: normalizeTopStats(stats.top_upstreams_responses),
top_upstrems_avg_time: normalizeTopStats(stats.top_upstreams_avg_time),
};
dispatch(getStatsSuccess(normalizedStats));

View File

@@ -455,6 +455,8 @@ class Api {
REWRITE_ADD = { path: 'rewrite/add', method: 'POST' };
REWRITE_UPDATE = { path: 'rewrite/update', method: 'PUT' };
REWRITE_DELETE = { path: 'rewrite/delete', method: 'POST' };
getRewritesList() {
@@ -470,6 +472,14 @@ class Api {
return this.makeRequest(path, method, parameters);
}
updateRewrite(config) {
const { path, method } = this.REWRITE_UPDATE;
const parameters = {
data: config,
};
return this.makeRequest(path, method, parameters);
}
deleteRewrite(config) {
const { path, method } = this.REWRITE_DELETE;
const parameters = {

View File

@@ -6,7 +6,7 @@ import { shallowEqual, useSelector } from 'react-redux';
import Card from '../ui/Card';
import { formatNumber } from '../../helpers/helpers';
import LogsSearchLink from '../ui/LogsSearchLink';
import { RESPONSE_FILTER } from '../../helpers/constants';
import { RESPONSE_FILTER, DAY } from '../../helpers/constants';
import Tooltip from '../ui/Tooltip';
const Row = ({
@@ -54,12 +54,12 @@ const Counters = ({ refreshButton, subtitle }) => {
avgProcessingTime,
} = useSelector((state) => state.stats, shallowEqual);
const { t } = useTranslation();
const days = interval / DAY;
const rows = [
{
label: 'dns_query',
count: numDnsQueries,
tooltipTitle: interval === 1 ? 'number_of_dns_query_24_hours' : t('number_of_dns_query_days', { count: interval }),
tooltipTitle: days === 1 ? 'number_of_dns_query_24_hours' : t('number_of_dns_query_days', { count: days }),
response_status: RESPONSE_FILTER.ALL.QUERY,
},
{

View File

@@ -0,0 +1,79 @@
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import round from 'lodash/round';
import { withTranslation, Trans } from 'react-i18next';
import Card from '../ui/Card';
import DomainCell from './DomainCell';
const TimeCell = ({ value }) => {
if (!value) {
return '';
}
const valueInMilliseconds = round(value * 1000);
return (
<div className="logs__row o-hidden">
<span className="logs__text logs__text--full" title={valueInMilliseconds}>
{valueInMilliseconds}&nbsp;ms
</span>
</div>
);
};
TimeCell.propTypes = {
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
};
const UpstreamAvgTime = ({
t,
refreshButton,
topUpstreamsAvgTime,
subtitle,
}) => (
<Card
title={t('average_processing_time')}
subtitle={subtitle}
bodyType="card-table"
refresh={refreshButton}
>
<ReactTable
data={topUpstreamsAvgTime.map(({ name: domain, count }) => ({
domain,
count,
}))}
columns={[
{
Header: <Trans>upstream</Trans>,
accessor: 'domain',
Cell: DomainCell,
},
{
Header: <Trans>processing_time</Trans>,
accessor: 'count',
maxWidth: 190,
Cell: TimeCell,
},
]}
showPagination={false}
noDataText={t('no_upstreams_data_found')}
minRows={6}
defaultPageSize={100}
className="-highlight card-table-overflow--limited stats__table"
/>
</Card>
);
UpstreamAvgTime.propTypes = {
topUpstreamsAvgTime: PropTypes.array.isRequired,
refreshButton: PropTypes.node.isRequired,
subtitle: PropTypes.string.isRequired,
t: PropTypes.func.isRequired,
};
export default withTranslation()(UpstreamAvgTime);

View File

@@ -0,0 +1,81 @@
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import { withTranslation, Trans } from 'react-i18next';
import Card from '../ui/Card';
import Cell from '../ui/Cell';
import DomainCell from './DomainCell';
import { getPercent } from '../../helpers/helpers';
import { STATUS_COLORS } from '../../helpers/constants';
const CountCell = (totalBlocked) => (
function cell(row) {
const { value } = row;
const percent = getPercent(totalBlocked, value);
return (
<Cell
value={value}
percent={percent}
color={STATUS_COLORS.green}
/>
);
}
);
const getTotalUpstreamRequests = (stats) => {
let total = 0;
stats.forEach(({ count }) => { total += count; });
return total;
};
const UpstreamResponses = ({
t,
refreshButton,
topUpstreamsResponses,
subtitle,
}) => (
<Card
title={t('top_upstreams')}
subtitle={subtitle}
bodyType="card-table"
refresh={refreshButton}
>
<ReactTable
data={topUpstreamsResponses.map(({ name: domain, count }) => ({
domain,
count,
}))}
columns={[
{
Header: <Trans>upstream</Trans>,
accessor: 'domain',
Cell: DomainCell,
},
{
Header: <Trans>requests_count</Trans>,
accessor: 'count',
maxWidth: 190,
Cell: CountCell(getTotalUpstreamRequests(topUpstreamsResponses)),
},
]}
showPagination={false}
noDataText={t('no_upstreams_data_found')}
minRows={6}
defaultPageSize={100}
className="-highlight card-table-overflow--limited stats__table"
/>
</Card>
);
UpstreamResponses.propTypes = {
topUpstreamsResponses: PropTypes.array.isRequired,
refreshButton: PropTypes.node.isRequired,
subtitle: PropTypes.string.isRequired,
t: PropTypes.func.isRequired,
};
export default withTranslation()(UpstreamResponses);

View File

@@ -21,6 +21,8 @@ import PageTitle from '../ui/PageTitle';
import Loading from '../ui/Loading';
import './Dashboard.css';
import Dropdown from '../ui/Dropdown';
import UpstreamResponses from './UpstreamResponses';
import UpstreamAvgTime from './UpstreamAvgTime';
const Dashboard = ({
getAccessList,
@@ -136,12 +138,12 @@ const Dashboard = ({
<PageTitle title={t('dashboard')} containerClass="page-title--dashboard">
<div className="page-title__protection">
<button
type="button"
className={buttonClass}
onClick={() => {
toggleProtection(protectionEnabled);
}}
disabled={processingProtection}
type="button"
className={buttonClass}
onClick={() => {
toggleProtection(protectionEnabled);
}}
disabled={processingProtection}
>
{protectionDisabledDuration
? `${t('enable_protection_timer')} ${getRemaningTimeText(protectionDisabledDuration)}`
@@ -160,9 +162,9 @@ const Dashboard = ({
</Dropdown>}
</div>
<button
type="button"
className="btn btn-outline-primary btn-sm"
onClick={getAllStats}
type="button"
className="btn btn-outline-primary btn-sm"
onClick={getAllStats}
>
<Trans>refresh_statics</Trans>
</button>
@@ -185,53 +187,67 @@ const Dashboard = ({
</div>
)}
<Statistics
interval={msToDays(stats.interval)}
dnsQueries={stats.dnsQueries}
blockedFiltering={stats.blockedFiltering}
replacedSafebrowsing={stats.replacedSafebrowsing}
replacedParental={stats.replacedParental}
numDnsQueries={stats.numDnsQueries}
numBlockedFiltering={stats.numBlockedFiltering}
numReplacedSafebrowsing={stats.numReplacedSafebrowsing}
numReplacedParental={stats.numReplacedParental}
refreshButton={refreshButton}
interval={msToDays(stats.interval)}
dnsQueries={stats.dnsQueries}
blockedFiltering={stats.blockedFiltering}
replacedSafebrowsing={stats.replacedSafebrowsing}
replacedParental={stats.replacedParental}
numDnsQueries={stats.numDnsQueries}
numBlockedFiltering={stats.numBlockedFiltering}
numReplacedSafebrowsing={stats.numReplacedSafebrowsing}
numReplacedParental={stats.numReplacedParental}
refreshButton={refreshButton}
/>
</div>
<div className="col-lg-6">
<Counters
subtitle={subtitle}
refreshButton={refreshButton}
subtitle={subtitle}
refreshButton={refreshButton}
/>
</div>
<div className="col-lg-6">
<Clients
subtitle={subtitle}
dnsQueries={stats.numDnsQueries}
topClients={stats.topClients}
clients={dashboard.clients}
autoClients={dashboard.autoClients}
refreshButton={refreshButton}
processingAccessSet={access.processingSet}
disallowedClients={access.disallowed_clients}
subtitle={subtitle}
dnsQueries={stats.numDnsQueries}
topClients={stats.topClients}
clients={dashboard.clients}
autoClients={dashboard.autoClients}
refreshButton={refreshButton}
processingAccessSet={access.processingSet}
disallowedClients={access.disallowed_clients}
/>
</div>
<div className="col-lg-6">
<QueriedDomains
subtitle={subtitle}
dnsQueries={stats.numDnsQueries}
topQueriedDomains={stats.topQueriedDomains}
refreshButton={refreshButton}
subtitle={subtitle}
dnsQueries={stats.numDnsQueries}
topQueriedDomains={stats.topQueriedDomains}
refreshButton={refreshButton}
/>
</div>
<div className="col-lg-6">
<BlockedDomains
subtitle={subtitle}
topBlockedDomains={stats.topBlockedDomains}
blockedFiltering={stats.numBlockedFiltering}
replacedSafebrowsing={stats.numReplacedSafebrowsing}
replacedSafesearch={stats.numReplacedSafesearch}
replacedParental={stats.numReplacedParental}
refreshButton={refreshButton}
subtitle={subtitle}
topBlockedDomains={stats.topBlockedDomains}
blockedFiltering={stats.numBlockedFiltering}
replacedSafebrowsing={stats.numReplacedSafebrowsing}
replacedSafesearch={stats.numReplacedSafesearch}
replacedParental={stats.numReplacedParental}
refreshButton={refreshButton}
/>
</div>
<div className="col-lg-6">
<UpstreamResponses
subtitle={subtitle}
topUpstreamsResponses={stats.topUpstreamsResponses}
refreshButton={refreshButton}
/>
</div>
<div className="col-lg-6">
<UpstreamAvgTime
subtitle={subtitle}
topUpstreamsAvgTime={stats.topUpstreamsAvgTime}
refreshButton={refreshButton}
/>
</div>
</div>}

View File

@@ -134,7 +134,6 @@ const Form = (props) => {
component={renderInputField}
className="form-control"
placeholder={t('enter_name_hint')}
validate={[validateRequiredValue]}
normalizeOnBlur={(data) => data.trim()}
/>
</div>

View File

@@ -105,6 +105,7 @@ Form.propTypes = {
submitting: PropTypes.bool.isRequired,
processingAdd: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
initialValues: PropTypes.object,
};
export default flow([

View File

@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { Trans, withTranslation } from 'react-i18next';
import ReactModal from 'react-modal';
import { MODAL_TYPE } from '../../../helpers/constants';
import Form from './Form';
const Modal = (props) => {
@@ -12,6 +13,8 @@ const Modal = (props) => {
toggleRewritesModal,
processingAdd,
processingDelete,
modalType,
currentRewrite,
} = props;
return (
@@ -24,13 +27,18 @@ const Modal = (props) => {
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">
<Trans>rewrite_add</Trans>
{modalType === MODAL_TYPE.EDIT_REWRITE ? (
<Trans>rewrite_edit</Trans>
) : (
<Trans>rewrite_add</Trans>
)}
</h4>
<button type="button" className="close" onClick={() => toggleRewritesModal()}>
<span className="sr-only">Close</span>
</button>
</div>
<Form
initialValues={{ ...currentRewrite }}
onSubmit={handleSubmit}
toggleRewritesModal={toggleRewritesModal}
processingAdd={processingAdd}
@@ -47,6 +55,8 @@ Modal.propTypes = {
toggleRewritesModal: PropTypes.func.isRequired,
processingAdd: PropTypes.bool.isRequired,
processingDelete: PropTypes.bool.isRequired,
modalType: PropTypes.string.isRequired,
currentRewrite: PropTypes.object,
};
export default withTranslation()(Modal);

View File

@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import ReactTable from 'react-table';
import { withTranslation } from 'react-i18next';
import { sortIp } from '../../../helpers/helpers';
import { MODAL_TYPE } from '../../../helpers/constants';
class Table extends Component {
cellWrap = ({ value }) => (
@@ -31,24 +32,44 @@ class Table extends Component {
maxWidth: 100,
sortable: false,
resizable: false,
Cell: (value) => (
<div className="logs__row logs__row--center">
<button
type="button"
className="btn btn-icon btn-icon--green btn-outline-secondary btn-sm"
onClick={() => this.props.handleDelete({
answer: value.row.answer,
domain: value.row.domain,
})
}
title={this.props.t('delete_table_action')}
>
<svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button>
</div>
),
Cell: (value) => {
const currentRewrite = {
answer: value.row.answer,
domain: value.row.domain,
};
return (
<div className="logs__row logs__row--center">
<button
type="button"
className="btn btn-icon btn-outline-primary btn-sm mr-2"
onClick={() => {
this.props.toggleRewritesModal({
type: MODAL_TYPE.EDIT_REWRITE,
currentRewrite,
});
}}
disabled={this.props.processingUpdate}
title={this.props.t('edit_table_action')}
>
<svg className="icons icon12">
<use xlinkHref="#edit" />
</svg>
</button>
<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm"
onClick={() => this.props.handleDelete(currentRewrite)}
title={this.props.t('delete_table_action')}
>
<svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button>
</div>
);
},
},
];
@@ -84,7 +105,9 @@ Table.propTypes = {
processing: PropTypes.bool.isRequired,
processingAdd: PropTypes.bool.isRequired,
processingDelete: PropTypes.bool.isRequired,
processingUpdate: PropTypes.bool.isRequired,
handleDelete: PropTypes.func.isRequired,
toggleRewritesModal: PropTypes.func.isRequired,
};
export default withTranslation()(Table);

View File

@@ -6,16 +6,13 @@ import Table from './Table';
import Modal from './Modal';
import Card from '../../ui/Card';
import PageTitle from '../../ui/PageTitle';
import { MODAL_TYPE } from '../../../helpers/constants';
class Rewrites extends Component {
componentDidMount() {
this.props.getRewritesList();
}
handleSubmit = (values) => {
this.props.addRewrite(values);
};
handleDelete = (values) => {
// eslint-disable-next-line no-alert
if (window.confirm(this.props.t('rewrite_confirm_delete', { key: values.domain }))) {
@@ -23,6 +20,19 @@ class Rewrites extends Component {
}
};
handleSubmit = (values) => {
const { modalType, currentRewrite } = this.props.rewrites;
if (modalType === MODAL_TYPE.EDIT_REWRITE && currentRewrite) {
this.props.updateRewrite({
target: currentRewrite,
update: values,
});
} else {
this.props.addRewrite(values);
}
};
render() {
const {
t,
@@ -36,6 +46,9 @@ class Rewrites extends Component {
processing,
processingAdd,
processingDelete,
processingUpdate,
modalType,
currentRewrite,
} = rewrites;
return (
@@ -54,13 +67,15 @@ class Rewrites extends Component {
processing={processing}
processingAdd={processingAdd}
processingDelete={processingDelete}
processingUpdate={processingUpdate}
handleDelete={this.handleDelete}
toggleRewritesModal={toggleRewritesModal}
/>
<button
type="button"
className="btn btn-success btn-standard mt-3"
onClick={() => toggleRewritesModal()}
onClick={() => toggleRewritesModal({ type: MODAL_TYPE.ADD_REWRITE })}
disabled={processingAdd}
>
<Trans>rewrite_add</Trans>
@@ -68,10 +83,13 @@ class Rewrites extends Component {
<Modal
isModalOpen={isModalOpen}
modalType={modalType}
toggleRewritesModal={toggleRewritesModal}
handleSubmit={this.handleSubmit}
processingAdd={processingAdd}
processingDelete={processingDelete}
processingUpdate={processingUpdate}
currentRewrite={currentRewrite}
/>
</Fragment>
</Card>
@@ -86,6 +104,7 @@ Rewrites.propTypes = {
toggleRewritesModal: PropTypes.func.isRequired,
addRewrite: PropTypes.func.isRequired,
deleteRewrite: PropTypes.func.isRequired,
updateRewrite: PropTypes.func.isRequired,
rewrites: PropTypes.object.isRequired,
};

View File

@@ -48,6 +48,7 @@ class Table extends Component {
Header: <Trans>list_url_table_header</Trans>,
accessor: 'url',
minWidth: 180,
// eslint-disable-next-line react/prop-types
Cell: ({ value }) => (
<div className="logs__row">
{isValidAbsolutePath(value) ? value

View File

@@ -32,6 +32,8 @@ const ProtectionTimer = ({
};
ProtectionTimer.propTypes = {
protectionDisabledDuration: PropTypes.number,
toggleProtectionSuccess: PropTypes.func.isRequired,
setProtectionTimerTime: PropTypes.func.isRequired,
};

View File

@@ -57,7 +57,7 @@ const ClientsTable = ({
};
const handleSubmit = (values) => {
const config = values;
const config = { ...values };
if (values) {
if (values.blocked_services) {

View File

@@ -27,7 +27,6 @@ import {
} from '../../../helpers/constants';
import '../FormButton.css';
const getIntervalTitle = (interval, t) => {
switch (interval) {
case RETENTION_CUSTOM:

View File

@@ -7,7 +7,6 @@ import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { connect } from 'react-redux';
import {
renderRadioField,
toNumber,

View File

@@ -1,25 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';
import LogsSearchLink from './LogsSearchLink';
import { formatNumber } from '../../helpers/helpers';
const Cell = ({
value, percent, color, search,
}) => <div className="stats__row">
<div className="stats__row-value mb-1">
<strong><LogsSearchLink search={search}>{formatNumber(value)}</LogsSearchLink></strong>
<small className="ml-3 text-muted">{percent}%</small>
value,
percent,
color,
search,
}) => (
<div className="stats__row">
<div className="stats__row-value mb-1">
<strong>
{search ? (
<LogsSearchLink search={search}>
{formatNumber(value)}
</LogsSearchLink>
) : (
formatNumber(value)
)}
</strong>
<small className="ml-3 text-muted">{percent}%</small>
</div>
<div className="progress progress-xs">
<div
className="progress-bar"
style={{
width: `${percent}%`,
backgroundColor: color,
}}
/>
</div>
</div>
<div className="progress progress-xs">
<div
className="progress-bar"
style={{
width: `${percent}%`,
backgroundColor: color,
}}
/>
</div>
</div>;
);
Cell.propTypes = {
value: PropTypes.number.isRequired,

View File

@@ -1,3 +1,4 @@
/* eslint-disable react/no-unknown-property */
import React from 'react';
import './Icons.css';

View File

@@ -3,6 +3,7 @@ import {
getRewritesList,
addRewrite,
deleteRewrite,
updateRewrite,
toggleRewritesModal,
} from '../actions/rewrites';
import Rewrites from '../components/Filters/Rewrites';
@@ -17,6 +18,7 @@ const mapDispatchToProps = {
getRewritesList,
addRewrite,
deleteRewrite,
updateRewrite,
toggleRewritesModal,
};

View File

@@ -173,6 +173,8 @@ export const MODAL_TYPE = {
ADD_FILTERS: 'ADD_FILTERS',
EDIT_FILTERS: 'EDIT_FILTERS',
CHOOSE_FILTERING_LIST: 'CHOOSE_FILTERING_LIST',
ADD_REWRITE: 'ADD_REWRITE',
EDIT_REWRITE: 'EDIT_REWRITE',
};
export const CLIENT_ID = {

View File

@@ -64,11 +64,11 @@ export default {
"homepage": "https://github.com/MasterKia/PersianBlocker",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_19.txt"
},
"ITA_filtri_dns": {
"name": "ITA: Filtri-DNS",
"ISR_easyList_hebrew": {
"name": "ISR: EasyList Hebrew",
"categoryId": "regional",
"homepage": "https://filtri-dns.ga/",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_18.txt"
"homepage": "https://github.com/easylist/EasyListHebrew",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_43.txt"
},
"KOR_list_kr": {
"name": "KOR: List-KR DNS",
@@ -166,18 +166,48 @@ export default {
"homepage": "https://github.com/DandelionSprout/adfilt",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_12.txt"
},
"dandelion_sprouts_anti_push_notifications": {
"name": "Dandelion Sprout's Anti Push Notifications",
"categoryId": "other",
"homepage": "https://github.com/DandelionSprout/adfilt",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_39.txt"
},
"dandelion_sprouts_game_console_adblock_list": {
"name": "Dandelion Sprout's Game Console Adblock List",
"categoryId": "other",
"homepage": "https://github.com/DandelionSprout/adfilt",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_6.txt"
},
"hagezi_personal": {
"name": "HaGeZi Personal Black \u0026 White",
"hagezi_allowlist_referral": {
"name": "HaGeZi's Allowlist Referral",
"categoryId": "other",
"homepage": "https://github.com/hagezi/dns-blocklists#referral",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_45.txt"
},
"hagezi_antipiracy_blocklist": {
"name": "HaGeZi's Anti-Piracy Blocklist",
"categoryId": "other",
"homepage": "https://github.com/hagezi/dns-blocklists#piracy",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_46.txt"
},
"hagezi_gambling_blocklist": {
"name": "HaGeZi's Gambling Blocklist",
"categoryId": "other",
"homepage": "https://github.com/hagezi/dns-blocklists#gambling",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_47.txt"
},
"hagezi_multinormal": {
"name": "HaGeZi Multi NORMAL",
"categoryId": "general",
"homepage": "https://github.com/hagezi/dns-blocklists",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_34.txt"
},
"hagezi_threat_intelligence_feeds": {
"name": "HaGeZi's Threat Intelligence Feeds",
"categoryId": "security",
"homepage": "https://github.com/hagezi/dns-blocklists",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_44.txt"
},
"no_google": {
"name": "No Google",
"categoryId": "other",
@@ -220,6 +250,12 @@ export default {
"homepage": "https://pgl.yoyo.org/adservers/",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_3.txt"
},
"phishing_army": {
"name": "Phishing Army",
"categoryId": "security",
"homepage": "https://gitlab.com/malware-filter/phishing-filter",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_18.txt"
},
"scam_blocklist_by_durablenapkin": {
"name": "Scam Blocklist by DurableNapkin",
"categoryId": "security",

View File

@@ -845,7 +845,6 @@ export const sortIp = (a, b) => {
}
};
/**
* @param {number} filterId
* @returns {string}

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,27 @@ const rewrites = handleActions(
[actions.deleteRewriteFailure]: (state) => ({ ...state, processingDelete: false }),
[actions.deleteRewriteSuccess]: (state) => ({ ...state, processingDelete: false }),
[actions.toggleRewritesModal]: (state) => {
[actions.updateRewriteRequest]: (state) => ({ ...state, processingUpdate: true }),
[actions.updateRewriteFailure]: (state) => ({ ...state, processingUpdate: false }),
[actions.updateRewriteSuccess]: (state) => {
const newState = {
...state,
processingUpdate: false,
};
return newState;
},
[actions.toggleRewritesModal]: (state, { payload }) => {
if (payload) {
const newState = {
...state,
modalType: payload.type || '',
isModalOpen: !state.isModalOpen,
currentRewrite: payload.currentRewrite,
};
return newState;
}
const newState = {
...state,
isModalOpen: !state.isModalOpen,
@@ -42,7 +62,10 @@ const rewrites = handleActions(
processing: true,
processingAdd: false,
processingDelete: false,
processingUpdate: false,
isModalOpen: false,
modalType: '',
currentRewrite: {},
list: [],
},
);

View File

@@ -58,6 +58,8 @@ const stats = handleActions(
num_replaced_safebrowsing: numReplacedSafebrowsing,
num_replaced_safesearch: numReplacedSafesearch,
avg_processing_time: avgProcessingTime,
top_upstreams_responses: topUpstreamsResponses,
top_upstrems_avg_time: topUpstreamsAvgTime,
} = payload;
const newState = {
@@ -77,6 +79,8 @@ const stats = handleActions(
numReplacedSafebrowsing,
numReplacedSafesearch,
avgProcessingTime,
topUpstreamsResponses,
topUpstreamsAvgTime,
};
return newState;

View File

@@ -1,6 +1,6 @@
# A docker file for scripts/make/build-docker.sh.
FROM alpine:3.17
FROM alpine:3.18
ARG BUILD_DATE
ARG VERSION
@@ -25,8 +25,6 @@ RUN apk --no-cache add ca-certificates libcap tzdata && \
mkdir -p /opt/adguardhome/conf /opt/adguardhome/work && \
chown -R nobody: /opt/adguardhome
RUN apk --no-cache add tini
ARG DIST_DIR
ARG TARGETARCH
ARG TARGETOS
@@ -43,45 +41,19 @@ RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome
# 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)
#
# TODO(a.garipov): Remove the old, non-standard 784 and 8853 ports for
# DNS-over-QUIC in a future release.
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 5443/tcp\
5443/udp 6060/tcp 8853/udp
EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 443/udp 853/tcp\
853/udp 3000/tcp 3000/udp 5443/tcp 5443/udp 6060/tcp
WORKDIR /opt/adguardhome/work
# Install helpers for healthcheck.
COPY --chown=nobody:nogroup\
./${DIST_DIR}/docker/scripts\
/opt/adguardhome/scripts
HEALTHCHECK \
--interval=30s \
--timeout=10s \
--retries=3 \
CMD [ "/opt/adguardhome/scripts/healthcheck.sh" ]
# It seems that the healthckech script sometimes spawns zombie processes, so we
# need a way to handle them, since AdGuard Home doesn't know how to keep track
# of the processes delegated to it by the OS. Use tini as entry point because
# it needs the PID=1 to be the default parent for orphaned processes.
#
# See https://github.com/adguardTeam/adGuardHome/issues/3290.
ENTRYPOINT [ "/sbin/tini", "--" ]
ENTRYPOINT ["/opt/adguardhome/AdGuardHome"]
CMD [ \
"/opt/adguardhome/AdGuardHome", \
"--no-check-update", \
"-c", "/opt/adguardhome/conf/AdGuardHome.yaml", \
"-h", "0.0.0.0", \
"-w", "/opt/adguardhome/work" \
]

View File

@@ -1,29 +0,0 @@
/^[^[:space:]]/ { is_dns = /^dns:/ }
/^[[:space:]]+bind_hosts:/ { if (is_dns) prev_line = FNR }
/^[[:space:]]+- .+/ {
if (FNR - prev_line == 1) {
addrs[$2] = true
prev_line = FNR
if ($2 == "0.0.0.0" || $2 == "'::'") {
# Drop all the other addresses.
delete addrs
addrs[""] = true
prev_line = -1
}
}
}
/^[[:space:]]+port:/ { if (is_dns) port = $2 }
END {
for (addr in addrs) {
if (match(addr, ":")) {
print "[" addr "]:" port
} else {
print addr ":" port
}
}
}

View File

@@ -1,107 +0,0 @@
#!/bin/sh
# AdGuard Home Docker healthcheck script
# Exit the script if a pipeline fails (-e), prevent accidental filename
# expansion (-f), and consider undefined variables as errors (-u).
set -e -f -u
# Function error_exit is an echo wrapper that writes to stderr and stops the
# script execution with code 1.
error_exit() {
echo "$1" 1>&2
exit 1
}
agh_dir="/opt/adguardhome"
readonly agh_dir
filename="${agh_dir}/conf/AdGuardHome.yaml"
readonly filename
if ! [ -f "$filename" ]
then
wget "http://127.0.0.1:3000" -O /dev/null -q || exit 1
exit 0
fi
help_dir="${agh_dir}/scripts"
readonly help_dir
# Parse web host
web_url="$( awk -f "${help_dir}/web-bind.awk" "$filename" )"
readonly web_url
if [ "$web_url" = '' ]
then
error_exit "no web bindings could be retrieved from $filename"
fi
# TODO(e.burkov): Deal with 0 port.
case "$web_url"
in
(*':0')
error_exit '0 in web port is not supported by healthcheck'
;;
(*)
# Go on.
;;
esac
# Parse DNS hosts
dns_hosts="$( awk -f "${help_dir}/dns-bind.awk" "$filename" )"
readonly dns_hosts
if [ "$dns_hosts" = '' ]
then
error_exit "no DNS bindings could be retrieved from $filename"
fi
first_dns="$( echo "$dns_hosts" | head -n 1 )"
readonly first_dns
# TODO(e.burkov): Deal with 0 port.
case "$first_dns"
in
(*':0')
error_exit '0 in DNS port is not supported by healthcheck'
;;
(*)
# Go on.
;;
esac
# Check
# Skip SSL certificate validation since there is no guarantee the container
# trusts the one used. It should be safe to drop the SSL validation since the
# current script intended to be used from inside the container and only checks
# the endpoint availability, ignoring the content of the response.
#
# See https://github.com/AdguardTeam/AdGuardHome/issues/5642.
wget --no-check-certificate "$web_url" -O /dev/null -q || exit 1
test_fqdn="healthcheck.adguardhome.test."
readonly test_fqdn
# The awk script currently returns only port prefixed with colon in case of
# unspecified address.
case "$first_dns"
in
(':'*)
nslookup -type=a "$test_fqdn" "127.0.0.1${first_dns}" > /dev/null ||\
nslookup -type=a "$test_fqdn" "[::1]${first_dns}" > /dev/null ||\
error_exit "nslookup failed for $host"
;;
(*)
echo "$dns_hosts" | while read -r host
do
nslookup -type=a "$test_fqdn" "$host" > /dev/null ||\
error_exit "nslookup failed for $host"
done
;;
esac

View File

@@ -1,13 +0,0 @@
# Don't consider the HTTPS hostname since the enforced HTTPS redirection should
# work if the SSL check skipped. See file docker/healthcheck.sh.
/^bind_host:/ { host = $2 }
/^bind_port:/ { port = $2 }
END {
if (match(host, ":")) {
print "http://[" host "]:" port
} else {
print "http://" host ":" port
}
}

43
go.mod
View File

@@ -1,11 +1,11 @@
module github.com/AdguardTeam/AdGuardHome
go 1.19
go 1.20
require (
github.com/AdguardTeam/dnsproxy v0.50.2
github.com/AdguardTeam/golibs v0.13.3
github.com/AdguardTeam/urlfilter v0.16.1
github.com/AdguardTeam/dnsproxy v0.54.0
github.com/AdguardTeam/golibs v0.15.0
github.com/AdguardTeam/urlfilter v0.17.0
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.7
github.com/bluele/gcache v0.0.2
@@ -15,9 +15,9 @@ require (
github.com/go-ping/ping v1.1.0
github.com/google/go-cmp v0.5.9
github.com/google/gopacket v1.1.19
github.com/google/renameio v1.0.1
github.com/google/uuid v1.3.0
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb
github.com/google/renameio/v2 v2.0.0
github.com/google/uuid v1.3.1
github.com/insomniacslk/dhcp v0.0.0-20230816195147-b3ca2534940d
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86
github.com/kardianos/service v1.2.2
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118
@@ -26,15 +26,15 @@ require (
// TODO(a.garipov): This package is deprecated; find a new one or use our
// own code for that. Perhaps, use gopacket.
github.com/mdlayher/raw v0.1.0
github.com/miekg/dns v1.1.54
github.com/quic-go/quic-go v0.35.1
github.com/miekg/dns v1.1.55
github.com/quic-go/quic-go v0.38.0
github.com/stretchr/testify v1.8.4
github.com/ti-mo/netfilter v0.5.0
go.etcd.io/bbolt v1.3.7
golang.org/x/crypto v0.10.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/net v0.11.0
golang.org/x/sys v0.9.0
golang.org/x/crypto v0.12.0
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/net v0.14.0
golang.org/x/sys v0.11.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
howett.net/plist v1.0.0
@@ -48,19 +48,18 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/onsi/ginkgo/v2 v2.10.0 // indirect
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/tools v0.9.3 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
)

126
go.sum
View File

@@ -1,16 +1,11 @@
github.com/AdguardTeam/dnsproxy v0.50.2 h1:p1471SsMZ6SMo7T51Olw4aNluahvMwSLMorwxYV18ts=
github.com/AdguardTeam/dnsproxy v0.50.2/go.mod h1:CQhZTkqC8X0ID6glrtyaxgqRRdiYfn1gJulC1cZ5Dn8=
github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4=
github.com/AdguardTeam/golibs v0.10.4/go.mod h1:rSfQRGHIdgfxriDDNgNJ7HmE5zRoURq8R+VdR81Zuzw=
github.com/AdguardTeam/golibs v0.13.3 h1:RT3QbzThtaLiFLkIUDS6/hlGEXrh0zYvdf4bd7UWpGo=
github.com/AdguardTeam/golibs v0.13.3/go.mod h1:wkJ6EUsN4np/9Gp7+9QeooY9E2U2WCLJYAioLCzkHsI=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
github.com/AdguardTeam/urlfilter v0.16.1 h1:ZPi0rjqo8cQf2FVdzo6cqumNoHZx2KPXj2yZa1A5BBw=
github.com/AdguardTeam/urlfilter v0.16.1/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
github.com/AdguardTeam/dnsproxy v0.54.0 h1:OgSitM/EKrMMOi+guWZNwaU1cqRqJKWgR3l3fPWWayI=
github.com/AdguardTeam/dnsproxy v0.54.0/go.mod h1:tG/treaQekcKnugYoKOfm8vt3JGi6CliWta0MkQr15U=
github.com/AdguardTeam/golibs v0.15.0 h1:yOv/fdVkJIOWKr0NlUXAE9RA0DK9GKiBbiGzq47vY7o=
github.com/AdguardTeam/golibs v0.15.0/go.mod h1:66ZLs8P7nk/3IfKroQ1rqtieLk+5eXYXMBKXlVL7KeI=
github.com/AdguardTeam/urlfilter v0.17.0 h1:tUzhtR9wMx704GIP3cibsDQJrixlMHfwoQbYJfPdFow=
github.com/AdguardTeam/urlfilter v0.17.0/go.mod h1:bbuZjPUzm/Ip+nz5qPPbwIP+9rZyQbQad8Lt/0fCulU=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
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=
@@ -23,7 +18,6 @@ github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 h1:0b2vaepXIfMsG+
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -34,8 +28,7 @@ github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu9
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@@ -50,16 +43,16 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU=
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ=
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb h1:6fDKEAXwe3rsfS4khW3EZ8kEqmSiV9szhMPcDrD+Y7Q=
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4=
github.com/insomniacslk/dhcp v0.0.0-20230816195147-b3ca2534940d h1:Ka64cclWedOkGzm9M2/XYuwJUdmWRUozmsxW0PyKA3A=
github.com/insomniacslk/dhcp v0.0.0-20230816195147-b3ca2534940d/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
@@ -67,10 +60,8 @@ github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8=
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og=
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
@@ -84,115 +75,99 @@ github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.10.0 h1:sfUl4qgLdvkChZrWCYndY2EAu9BRIw1YphNAzy1VNWs=
github.com/onsi/ginkgo/v2 v2.10.0/go.mod h1:UDQOh5wbQUlMnkLfVaIUMtQ1Vus92oM+P2JX1aulgcE=
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U=
github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
github.com/quic-go/quic-go v0.35.1 h1:b0kzj6b/cQAf05cT0CkQubHM31wiA+xH3IBkxP62poo=
github.com/quic-go/quic-go v0.35.1/go.mod h1:+4CVgVppm0FNjpG3UcX8Joi/frKOH7/ciD5yGcwOO1g=
github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA=
github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ=
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc=
github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg=
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ti-mo/netfilter v0.2.0/go.mod h1:8GbBGsY/8fxtyIdfwy29JiluNcPK4K7wIT+x42ipqUU=
github.com/ti-mo/netfilter v0.5.0 h1:MZmsUw5bFRecOb0AeyjOPxTHg4UxYzyEs0Ek/6Lxoy8=
github.com/ti-mo/netfilter v0.5.0/go.mod h1:nt+8B9hx/QpqHr7Hazq+2qMCCA8u2OTkyc/7+U9ARz8=
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -200,12 +175,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,10 +1,11 @@
package aghio
package aghio_test
import (
"io"
"strings"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -31,7 +32,7 @@ func TestLimitReader(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
_, err := LimitReader(nil, tc.n)
_, err := aghio.LimitReader(nil, tc.n)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
})
}
@@ -57,7 +58,7 @@ func TestLimitedReader_Read(t *testing.T) {
limit: 3,
want: 0,
}, {
err: &LimitReachedError{
err: &aghio.LimitReachedError{
Limit: 0,
},
name: "limit_reached",
@@ -74,7 +75,7 @@ func TestLimitedReader_Read(t *testing.T) {
for _, tc := range testCases {
readCloser := io.NopCloser(strings.NewReader(tc.rStr))
lreader, err := LimitReader(readCloser, tc.limit)
lreader, err := aghio.LimitReader(readCloser, tc.limit)
require.NoError(t, err)
require.NotNil(t, lreader)
@@ -89,7 +90,7 @@ func TestLimitedReader_Read(t *testing.T) {
}
func TestLimitedReader_LimitReachedError(t *testing.T) {
testutil.AssertErrorMsg(t, "attempted to read more than 0 bytes", &LimitReachedError{
testutil.AssertErrorMsg(t, "attempted to read more than 0 bytes", &aghio.LimitReachedError{
Limit: 0,
})
}

43
internal/aghnet/addr.go Normal file
View File

@@ -0,0 +1,43 @@
package aghnet
import (
"fmt"
"strings"
"github.com/AdguardTeam/golibs/stringutil"
)
// NormalizeDomain returns a lowercased version of host without the final dot,
// unless host is ".", in which case it returns it unchanged. That is a special
// case that to allow matching queries like:
//
// dig IN NS '.'
func NormalizeDomain(host string) (norm string) {
if host == "." {
return host
}
return strings.ToLower(strings.TrimSuffix(host, "."))
}
// NewDomainNameSet returns nil and error, if list has duplicate or empty domain
// name. Otherwise returns a set, which contains domain names normalized using
// [NormalizeDomain].
func NewDomainNameSet(list []string) (set *stringutil.Set, err error) {
set = stringutil.NewSet()
for i, host := range list {
if host == "" {
return nil, fmt.Errorf("at index %d: hostname is empty", i)
}
host = NormalizeDomain(host)
if set.Has(host) {
return nil, fmt.Errorf("duplicate hostname %q at index %d", host, i)
}
set.Add(host)
}
return set, nil
}

View File

@@ -0,0 +1,59 @@
package aghnet_test
import (
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
)
func TestNewDomainNameSet(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
wantErrMsg string
in []string
}{{
name: "nil",
wantErrMsg: "",
in: nil,
}, {
name: "success",
wantErrMsg: "",
in: []string{
"Domain.Example",
".",
},
}, {
name: "dups",
wantErrMsg: `duplicate hostname "domain.example" at index 1`,
in: []string{
"Domain.Example",
"domain.example",
},
}, {
name: "bad_domain",
wantErrMsg: "at index 0: hostname is empty",
in: []string{
"",
},
}}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
set, err := aghnet.NewDomainNameSet(tc.in)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
if err != nil {
return
}
for _, host := range tc.in {
assert.Truef(t, set.Has(aghnet.NormalizeDomain(host)), "%q not matched", host)
}
})
}
}

View File

@@ -60,7 +60,7 @@ func ifaceIPv4Subnet(iface *net.Interface) (subnet netip.Prefix, err error) {
}
if ip = ip.To4(); ip != nil {
return netip.PrefixFrom(netip.AddrFrom4(*(*[4]byte)(ip)), maskLen), nil
return netip.PrefixFrom(netip.AddrFrom4([4]byte(ip)), maskLen), nil
}
}

View File

@@ -1,12 +1,8 @@
package aghnet
import (
"fmt"
"net/netip"
"strings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/stringutil"
)
// GenerateHostname generates the hostname from ip. In case of using IPv4 the
@@ -29,32 +25,8 @@ func GenerateHostname(ip netip.Addr) (hostname string) {
hostname = ip.StringExpanded()
if ip.Is4() {
return strings.Replace(hostname, ".", "-", -1)
return strings.ReplaceAll(hostname, ".", "-")
}
return strings.Replace(hostname, ":", "-", -1)
}
// NewDomainNameSet returns nil and error, if list has duplicate or empty
// domain name. Otherwise returns a set, which contains non-FQDN domain names,
// and nil error.
func NewDomainNameSet(list []string) (set *stringutil.Set, err error) {
set = stringutil.NewSet()
for i, v := range list {
host := strings.ToLower(strings.TrimSuffix(v, "."))
// TODO(a.garipov): Think about ignoring empty (".") names in the
// future.
if host == "" {
return nil, errors.Error("host name is empty")
}
if set.Has(host) {
return nil, fmt.Errorf("duplicate host name %q at index %d", host, i)
}
set.Add(host)
}
return set, nil
return strings.ReplaceAll(hostname, ":", "-")
}

View File

@@ -1,25 +1,19 @@
package aghnet
import (
"bufio"
"fmt"
"io"
"io/fs"
"net/netip"
"path"
"strings"
"sync"
"sync/atomic"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/hostsfile"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/AdguardTeam/urlfilter"
"github.com/AdguardTeam/urlfilter/filterlist"
"github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)
// DefaultHostsPaths returns the slice of paths default for the operating system
@@ -29,88 +23,51 @@ func DefaultHostsPaths() (paths []string) {
return defaultHostsPaths()
}
// requestMatcher combines the logic for matching requests and translating the
// appropriate rules.
type requestMatcher struct {
// stateLock protects all the fields of requestMatcher.
stateLock *sync.RWMutex
// rulesStrg stores the rules obtained from the hosts' file.
rulesStrg *filterlist.RuleStorage
// engine serves rulesStrg.
engine *urlfilter.DNSEngine
// translator maps generated $dnsrewrite rules into hosts-syntax rules.
//
// TODO(e.burkov): Store the filename from which the rule was parsed.
translator map[string]string
}
// MatchRequest processes the request rewriting hostnames and addresses read
// from the operating system's hosts files. res is nil for any request having
// not an A/AAAA or PTR type, see man 5 hosts.
//
// It's safe for concurrent use.
func (rm *requestMatcher) MatchRequest(
req *urlfilter.DNSRequest,
) (res *urlfilter.DNSResult, ok bool) {
switch req.DNSType {
case dns.TypeA, dns.TypeAAAA, dns.TypePTR:
log.Debug("%s: handling the request for %s", hostsContainerPrefix, req.Hostname)
default:
return nil, false
// MatchAddr returns the records for the IP address.
func (hc *HostsContainer) MatchAddr(ip netip.Addr) (recs []*hostsfile.Record) {
cur := hc.current.Load()
if cur == nil {
return nil
}
rm.stateLock.RLock()
defer rm.stateLock.RUnlock()
return rm.engine.MatchRequest(req)
return cur.addrs[ip]
}
// Translate returns the source hosts-syntax rule for the generated dnsrewrite
// rule or an empty string if the last doesn't exist. The returned rules are in
// a processed format like:
//
// ip host1 host2 ...
func (rm *requestMatcher) Translate(rule string) (hostRule string) {
rm.stateLock.RLock()
defer rm.stateLock.RUnlock()
// MatchName returns the records for the hostname.
func (hc *HostsContainer) MatchName(name string) (recs []*hostsfile.Record) {
cur := hc.current.Load()
if cur != nil {
recs = cur.names[name]
}
return rm.translator[rule]
}
// resetEng updates container's engine and the translation map.
func (rm *requestMatcher) resetEng(rulesStrg *filterlist.RuleStorage, tr map[string]string) {
rm.stateLock.Lock()
defer rm.stateLock.Unlock()
rm.rulesStrg = rulesStrg
rm.engine = urlfilter.NewDNSEngine(rm.rulesStrg)
rm.translator = tr
return recs
}
// hostsContainerPrefix is a prefix for logging and wrapping errors in
// HostsContainer's methods.
const hostsContainerPrefix = "hosts container"
// Hosts is a map of IP addresses to the records, as it primarily stored in the
// [HostsContainer]. It should not be accessed for writing since it may be read
// concurrently, users should clone it before modifying.
//
// The order of records for each address is preserved from original files, but
// the order of the addresses, being a map key, is not.
//
// TODO(e.burkov): Probably, this should be a sorted slice of records.
type Hosts map[netip.Addr][]*hostsfile.Record
// HostsContainer stores the relevant hosts database provided by the OS and
// processes both A/AAAA and PTR DNS requests for those.
type HostsContainer struct {
// requestMatcher matches the requests and translates the rules. It's
// embedded to implement MatchRequest and Translate for *HostsContainer.
//
// TODO(a.garipov, e.burkov): Consider fully merging into HostsContainer.
requestMatcher
// done is the channel to sign closing the container.
done chan struct{}
// updates is the channel for receiving updated hosts.
updates chan HostsRecords
updates chan Hosts
// last is the set of hosts that was cached within last detected change.
last HostsRecords
// current is the last set of hosts parsed.
current atomic.Pointer[hostsIndex]
// fsys is the working file system to read hosts files from.
fsys fs.FS
@@ -120,30 +77,6 @@ type HostsContainer struct {
// patterns stores specified paths in the fs.Glob-compatible form.
patterns []string
// listID is the identifier for the list of generated rules.
listID int
}
// HostsRecords is a mapping of an IP address to its hosts data.
type HostsRecords map[netip.Addr]*HostsRecord
// HostsRecord represents a single hosts file record.
type HostsRecord struct {
Aliases *stringutil.Set
Canonical string
}
// equal returns true if all fields of rec are equal to field in other or they
// both are nil.
func (rec *HostsRecord) equal(other *HostsRecord) (ok bool) {
if rec == nil {
return other == nil
} else if other == nil {
return false
}
return rec.Canonical == other.Canonical && rec.Aliases.Equal(other.Aliases)
}
// ErrNoHostsPaths is returned when there are no valid paths to watch passed to
@@ -155,7 +88,6 @@ const ErrNoHostsPaths errors.Error = "no valid paths to hosts files provided"
// shouldn't be empty and each of paths should locate either a file or a
// directory in fsys. fsys and w must be non-nil.
func NewHostsContainer(
listID int,
fsys fs.FS,
w aghos.FSWatcher,
paths ...string,
@@ -175,12 +107,8 @@ func NewHostsContainer(
}
hc = &HostsContainer{
requestMatcher: requestMatcher{
stateLock: &sync.RWMutex{},
},
listID: listID,
done: make(chan struct{}, 1),
updates: make(chan HostsRecords, 1),
updates: make(chan Hosts, 1),
fsys: fsys,
watcher: w,
patterns: patterns,
@@ -226,7 +154,7 @@ func (hc *HostsContainer) Close() (err error) {
}
// Upd returns the channel into which the updates are sent.
func (hc *HostsContainer) Upd() (updates <-chan HostsRecords) {
func (hc *HostsContainer) Upd() (updates <-chan Hosts) {
return hc.updates
}
@@ -273,7 +201,7 @@ func (hc *HostsContainer) handleEvents() {
}
if err := hc.refresh(); err != nil {
log.Error("%s: %s", hostsContainerPrefix, err)
log.Error("%s: warning: refreshing: %s", hostsContainerPrefix, err)
}
case _, ok = <-hc.done:
// Go on.
@@ -281,198 +209,83 @@ func (hc *HostsContainer) handleEvents() {
}
}
// hostsParser is a helper type to parse rules from the operating system's hosts
// file. It exists for only a single refreshing session.
type hostsParser struct {
// rulesBuilder builds the resulting rules list content.
rulesBuilder *strings.Builder
// translations maps generated rules into actual hosts file lines.
translations map[string]string
// table stores only the unique IP-hostname pairs. It's also sent to the
// updates channel afterwards.
table HostsRecords
}
// newHostsParser creates a new *hostsParser with buffers of size taken from the
// previous parse.
func (hc *HostsContainer) newHostsParser() (hp *hostsParser) {
return &hostsParser{
rulesBuilder: &strings.Builder{},
translations: map[string]string{},
table: make(HostsRecords, len(hc.last)),
}
}
// parseFile is a aghos.FileWalker for parsing the files with hosts syntax. It
// never signs to stop walking and never returns any additional patterns.
//
// See man hosts(5).
func (hp *hostsParser) parseFile(r io.Reader) (patterns []string, cont bool, err error) {
s := bufio.NewScanner(r)
for s.Scan() {
ip, hosts := hp.parseLine(s.Text())
if ip == (netip.Addr{}) || len(hosts) == 0 {
continue
}
hp.addRecord(ip, hosts)
}
return nil, true, s.Err()
}
// parseLine parses the line having the hosts syntax ignoring invalid ones.
func (hp *hostsParser) parseLine(line string) (ip netip.Addr, hosts []string) {
fields := strings.Fields(line)
if len(fields) < 2 {
return netip.Addr{}, nil
}
ip, err := netip.ParseAddr(fields[0])
if err != nil {
return netip.Addr{}, nil
}
for _, f := range fields[1:] {
hashIdx := strings.IndexByte(f, '#')
if hashIdx == 0 {
// The rest of the fields are a part of the comment so return.
break
} else if hashIdx > 0 {
// Only a part of the field is a comment.
f = f[:hashIdx]
}
// Make sure that invalid hosts aren't turned into rules.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/3946.
//
// TODO(e.burkov): Investigate if hosts may contain DNS-SD domains.
err = netutil.ValidateHostname(f)
if err != nil {
log.Error("%s: host %q is invalid, ignoring", hostsContainerPrefix, f)
continue
}
hosts = append(hosts, f)
}
return ip, hosts
}
// addRecord puts the record for the IP address to the rules builder if needed.
// The first host is considered to be the canonical name for the IP address.
// hosts must have at least one name.
func (hp *hostsParser) addRecord(ip netip.Addr, hosts []string) {
line := strings.Join(append([]string{ip.String()}, hosts...), " ")
rec, ok := hp.table[ip]
if !ok {
rec = &HostsRecord{
Aliases: stringutil.NewSet(),
}
rec.Canonical, hosts = hosts[0], hosts[1:]
hp.addRules(ip, rec.Canonical, line)
hp.table[ip] = rec
}
for _, host := range hosts {
if rec.Canonical == host || rec.Aliases.Has(host) {
continue
}
rec.Aliases.Add(host)
hp.addRules(ip, host, line)
}
}
// addRules adds rules and rule translations for the line.
func (hp *hostsParser) addRules(ip netip.Addr, host, line string) {
rule, rulePtr := hp.writeRules(host, ip)
hp.translations[rule], hp.translations[rulePtr] = line, line
log.Debug("%s: added ip-host pair %q-%q", hostsContainerPrefix, ip, host)
}
// writeRules writes the actual rule for the qtype and the PTR for the host-ip
// pair into internal builders.
func (hp *hostsParser) writeRules(host string, ip netip.Addr) (rule, rulePtr string) {
// TODO(a.garipov): Add a netip.Addr version to netutil.
arpa, err := netutil.IPToReversedAddr(ip.AsSlice())
if err != nil {
return "", ""
}
const (
nl = "\n"
rwSuccess = "^$dnsrewrite=NOERROR;"
rwSuccessPTR = "^$dnsrewrite=NOERROR;PTR;"
modLen = len(rules.MaskPipe) + len(rwSuccess) + len(";")
modLenPTR = len(rules.MaskPipe) + len(rwSuccessPTR)
)
var qtype string
// The validation of the IP address has been performed earlier so it is
// guaranteed to be either an IPv4 or an IPv6.
if ip.Is4() {
qtype = "A"
} else {
qtype = "AAAA"
}
ipStr := ip.String()
fqdn := dns.Fqdn(host)
ruleBuilder := &strings.Builder{}
ruleBuilder.Grow(modLen + len(host) + len(qtype) + len(ipStr))
stringutil.WriteToBuilder(ruleBuilder, rules.MaskPipe, host, rwSuccess, qtype, ";", ipStr)
rule = ruleBuilder.String()
ruleBuilder.Reset()
ruleBuilder.Grow(modLenPTR + len(arpa) + len(fqdn))
stringutil.WriteToBuilder(ruleBuilder, rules.MaskPipe, arpa, rwSuccessPTR, fqdn)
rulePtr = ruleBuilder.String()
hp.rulesBuilder.Grow(len(rule) + len(rulePtr) + 2*len(nl))
stringutil.WriteToBuilder(hp.rulesBuilder, rule, nl, rulePtr, nl)
return rule, rulePtr
}
// sendUpd tries to send the parsed data to the ch.
func (hp *hostsParser) sendUpd(ch chan HostsRecords) {
func (hc *HostsContainer) sendUpd(recs Hosts) {
log.Debug("%s: sending upd", hostsContainerPrefix)
upd := hp.table
ch := hc.updates
select {
case ch <- upd:
case ch <- recs:
// Updates are delivered. Go on.
case <-ch:
ch <- upd
ch <- recs
log.Debug("%s: replaced the last update", hostsContainerPrefix)
case ch <- upd:
case ch <- recs:
// The previous update was just read and the next one pushed. Go on.
default:
log.Error("%s: the updates channel is broken", hostsContainerPrefix)
}
}
// newStrg creates a new rules storage from parsed data.
func (hp *hostsParser) newStrg(id int) (s *filterlist.RuleStorage, err error) {
return filterlist.NewRuleStorage([]filterlist.RuleList{&filterlist.StringRuleList{
ID: id,
RulesText: hp.rulesBuilder.String(),
IgnoreCosmetic: true,
}})
// hostsIndex is a [hostsfile.Set] to enumerate all the records.
type hostsIndex struct {
// addrs maps IP addresses to the records.
addrs Hosts
// names maps hostnames to the records.
names map[string][]*hostsfile.Record
}
// walk is a file walking function for hostsIndex.
func (idx *hostsIndex) walk(r io.Reader) (patterns []string, cont bool, err error) {
return nil, true, hostsfile.Parse(idx, r, nil)
}
// type check
var _ hostsfile.Set = (*hostsIndex)(nil)
// Add implements the [hostsfile.Set] interface for *hostsIndex.
func (idx *hostsIndex) Add(rec *hostsfile.Record) {
idx.addrs[rec.Addr] = append(idx.addrs[rec.Addr], rec)
for _, name := range rec.Names {
idx.names[name] = append(idx.names[name], rec)
}
}
// type check
var _ hostsfile.HandleSet = (*hostsIndex)(nil)
// HandleInvalid implements the [hostsfile.HandleSet] interface for *hostsIndex.
func (idx *hostsIndex) HandleInvalid(src string, _ []byte, err error) {
lineErr := &hostsfile.LineError{}
if !errors.As(err, &lineErr) {
// Must not happen if idx passed to [hostsfile.Parse].
return
} else if errors.Is(lineErr, hostsfile.ErrEmptyLine) {
// Ignore empty lines.
return
}
log.Info("%s: warning: parsing %q: %s", hostsContainerPrefix, src, lineErr)
}
// equalRecs is an equality function for [*hostsfile.Record].
func equalRecs(a, b *hostsfile.Record) (ok bool) {
return a.Addr == b.Addr && a.Source == b.Source && slices.Equal(a.Names, b.Names)
}
// equalRecSlices is an equality function for slices of [*hostsfile.Record].
func equalRecSlices(a, b []*hostsfile.Record) (ok bool) { return slices.EqualFunc(a, b, equalRecs) }
// Equal returns true if indexes are equal.
func (idx *hostsIndex) Equal(other *hostsIndex) (ok bool) {
if idx == nil {
return other == nil
} else if other == nil {
return false
}
return maps.EqualFunc(idx.addrs, other.addrs, equalRecSlices)
}
// refresh gets the data from specified files and propagates the updates if
@@ -482,27 +295,27 @@ func (hp *hostsParser) newStrg(id int) (s *filterlist.RuleStorage, err error) {
func (hc *HostsContainer) refresh() (err error) {
log.Debug("%s: refreshing", hostsContainerPrefix)
hp := hc.newHostsParser()
if _, err = aghos.FileWalker(hp.parseFile).Walk(hc.fsys, hc.patterns...); err != nil {
return fmt.Errorf("refreshing : %w", err)
var addrLen, nameLen int
last := hc.current.Load()
if last != nil {
addrLen, nameLen = len(last.addrs), len(last.names)
}
idx := &hostsIndex{
addrs: make(Hosts, addrLen),
names: make(map[string][]*hostsfile.Record, nameLen),
}
// hc.last is nil on the first refresh, so let that one through.
if hc.last != nil && maps.EqualFunc(hp.table, hc.last, (*HostsRecord).equal) {
log.Debug("%s: no changes detected", hostsContainerPrefix)
return nil
}
defer hp.sendUpd(hc.updates)
hc.last = maps.Clone(hp.table)
var rulesStrg *filterlist.RuleStorage
if rulesStrg, err = hp.newStrg(hc.listID); err != nil {
return fmt.Errorf("initializing rules storage: %w", err)
_, err = aghos.FileWalker(idx.walk).Walk(hc.fsys, hc.patterns...)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
}
hc.resetEng(rulesStrg, hp.translations)
// TODO(e.burkov): Serialize updates using time.
if !last.Equal(idx) {
hc.current.Store(idx)
hc.sendUpd(idx.addrs)
}
return nil
}

View File

@@ -0,0 +1,76 @@
package aghnet
import (
"io/fs"
"path"
"testing"
"testing/fstest"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil/fakefs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const nl = "\n"
func TestHostsContainer_PathsToPatterns(t *testing.T) {
gsfs := fstest.MapFS{
"dir_0/file_1": &fstest.MapFile{Data: []byte{1}},
"dir_0/file_2": &fstest.MapFile{Data: []byte{2}},
"dir_0/dir_1/file_3": &fstest.MapFile{Data: []byte{3}},
}
testCases := []struct {
name string
paths []string
want []string
}{{
name: "no_paths",
paths: nil,
want: nil,
}, {
name: "single_file",
paths: []string{"dir_0/file_1"},
want: []string{"dir_0/file_1"},
}, {
name: "several_files",
paths: []string{"dir_0/file_1", "dir_0/file_2"},
want: []string{"dir_0/file_1", "dir_0/file_2"},
}, {
name: "whole_dir",
paths: []string{"dir_0"},
want: []string{"dir_0/*"},
}, {
name: "file_and_dir",
paths: []string{"dir_0/file_1", "dir_0/dir_1"},
want: []string{"dir_0/file_1", "dir_0/dir_1/*"},
}, {
name: "non-existing",
paths: []string{path.Join("dir_0", "file_3")},
want: nil,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
patterns, err := pathsToPatterns(gsfs, tc.paths)
require.NoError(t, err)
assert.Equal(t, tc.want, patterns)
})
}
t.Run("bad_file", func(t *testing.T) {
const errStat errors.Error = "bad file"
badFS := &fakefs.StatFS{
OnOpen: func(_ string) (f fs.File, err error) { panic("not implemented") },
OnStat: func(name string) (fi fs.FileInfo, err error) {
return nil, errStat
},
}
_, err := pathsToPatterns(badFS, []string{""})
assert.ErrorIs(t, err, errStat)
})
}

View File

@@ -1,32 +1,156 @@
package aghnet
package aghnet_test
import (
"io/fs"
"net"
"net/netip"
"path"
"strings"
"path/filepath"
"sync/atomic"
"testing"
"testing/fstest"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghchan"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/hostsfile"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/urlfilter"
"github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
nl = "\n"
sp = " "
// nl is a newline character.
const nl = "\n"
// Variables mirroring the etc_hosts file from testdata.
var (
addr1000 = netip.MustParseAddr("1.0.0.0")
addr1001 = netip.MustParseAddr("1.0.0.1")
addr1002 = netip.MustParseAddr("1.0.0.2")
addr1003 = netip.MustParseAddr("1.0.0.3")
addr1004 = netip.MustParseAddr("1.0.0.4")
addr1357 = netip.MustParseAddr("1.3.5.7")
addr4216 = netip.MustParseAddr("4.2.1.6")
addr7531 = netip.MustParseAddr("7.5.3.1")
addr0 = netip.MustParseAddr("::")
addr1 = netip.MustParseAddr("::1")
addr2 = netip.MustParseAddr("::2")
addr3 = netip.MustParseAddr("::3")
addr4 = netip.MustParseAddr("::4")
addr42 = netip.MustParseAddr("::42")
addr13 = netip.MustParseAddr("::13")
addr31 = netip.MustParseAddr("::31")
hostsSrc = "./" + filepath.Join("./testdata", "etc_hosts")
testHosts = map[netip.Addr][]*hostsfile.Record{
addr1000: {{
Addr: addr1000,
Source: hostsSrc,
Names: []string{"hello", "hello.world"},
}, {
Addr: addr1000,
Source: hostsSrc,
Names: []string{"hello.world.again"},
}, {
Addr: addr1000,
Source: hostsSrc,
Names: []string{"hello.world"},
}},
addr1001: {{
Addr: addr1001,
Source: hostsSrc,
Names: []string{"simplehost"},
}, {
Addr: addr1001,
Source: hostsSrc,
Names: []string{"simplehost"},
}},
addr1002: {{
Addr: addr1002,
Source: hostsSrc,
Names: []string{"a.whole", "lot.of", "aliases", "for.testing"},
}},
addr1003: {{
Addr: addr1003,
Source: hostsSrc,
Names: []string{"*"},
}},
addr1004: {{
Addr: addr1004,
Source: hostsSrc,
Names: []string{"*.com"},
}},
addr1357: {{
Addr: addr1357,
Source: hostsSrc,
Names: []string{"domain4", "domain4.alias"},
}},
addr7531: {{
Addr: addr7531,
Source: hostsSrc,
Names: []string{"domain4.alias", "domain4"},
}},
addr4216: {{
Addr: addr4216,
Source: hostsSrc,
Names: []string{"domain", "domain.alias"},
}},
addr0: {{
Addr: addr0,
Source: hostsSrc,
Names: []string{"hello", "hello.world"},
}, {
Addr: addr0,
Source: hostsSrc,
Names: []string{"hello.world.again"},
}, {
Addr: addr0,
Source: hostsSrc,
Names: []string{"hello.world"},
}},
addr1: {{
Addr: addr1,
Source: hostsSrc,
Names: []string{"simplehost"},
}, {
Addr: addr1,
Source: hostsSrc,
Names: []string{"simplehost"},
}},
addr2: {{
Addr: addr2,
Source: hostsSrc,
Names: []string{"a.whole", "lot.of", "aliases", "for.testing"},
}},
addr3: {{
Addr: addr3,
Source: hostsSrc,
Names: []string{"*"},
}},
addr4: {{
Addr: addr4,
Source: hostsSrc,
Names: []string{"*.com"},
}},
addr42: {{
Addr: addr42,
Source: hostsSrc,
Names: []string{"domain.alias", "domain"},
}},
addr13: {{
Addr: addr13,
Source: hostsSrc,
Names: []string{"domain6", "domain6.alias"},
}},
addr31: {{
Addr: addr31,
Source: hostsSrc,
Names: []string{"domain6.alias", "domain6"},
}},
}
)
func TestNewHostsContainer(t *testing.T) {
@@ -48,11 +172,11 @@ func TestNewHostsContainer(t *testing.T) {
name: "one_file",
paths: []string{p},
}, {
wantErr: ErrNoHostsPaths,
wantErr: aghnet.ErrNoHostsPaths,
name: "no_files",
paths: []string{},
}, {
wantErr: ErrNoHostsPaths,
wantErr: aghnet.ErrNoHostsPaths,
name: "non-existent_file",
paths: []string{path.Join(dirname, filename+"2")},
}, {
@@ -77,7 +201,7 @@ func TestNewHostsContainer(t *testing.T) {
return eventsCh
}
hc, err := NewHostsContainer(0, testFS, &aghtest.FSWatcher{
hc, err := aghnet.NewHostsContainer(testFS, &aghtest.FSWatcher{
OnEvents: onEvents,
OnAdd: onAdd,
OnClose: func() (err error) { return nil },
@@ -103,7 +227,7 @@ func TestNewHostsContainer(t *testing.T) {
t.Run("nil_fs", func(t *testing.T) {
require.Panics(t, func() {
_, _ = NewHostsContainer(0, nil, &aghtest.FSWatcher{
_, _ = aghnet.NewHostsContainer(nil, &aghtest.FSWatcher{
// Those shouldn't panic.
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
@@ -114,7 +238,7 @@ func TestNewHostsContainer(t *testing.T) {
t.Run("nil_watcher", func(t *testing.T) {
require.Panics(t, func() {
_, _ = NewHostsContainer(0, testFS, nil, p)
_, _ = aghnet.NewHostsContainer(testFS, nil, p)
})
})
@@ -127,7 +251,7 @@ func TestNewHostsContainer(t *testing.T) {
OnClose: func() (err error) { return nil },
}
hc, err := NewHostsContainer(0, testFS, errWatcher, p)
hc, err := aghnet.NewHostsContainer(testFS, errWatcher, p)
require.ErrorIs(t, err, errOnAdd)
assert.Nil(t, hc)
@@ -140,6 +264,9 @@ func TestHostsContainer_refresh(t *testing.T) {
ip := netutil.IPv4Localhost()
ipStr := ip.String()
anotherIPStr := "1.2.3.4"
anotherIP := netip.MustParseAddr(anotherIPStr)
testFS := fstest.MapFS{"dir/file1": &fstest.MapFile{Data: []byte(ipStr + ` hostname` + nl)}}
// event is a convenient alias for an empty struct{} to emit test events.
@@ -158,40 +285,44 @@ func TestHostsContainer_refresh(t *testing.T) {
OnClose: func() (err error) { return nil },
}
hc, err := NewHostsContainer(0, testFS, w, "dir")
hc, err := aghnet.NewHostsContainer(testFS, w, "dir")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, hc.Close)
checkRefresh := func(t *testing.T, want *HostsRecord) {
checkRefresh := func(t *testing.T, want aghnet.Hosts) {
t.Helper()
upd, ok := aghchan.MustReceive(hc.Upd(), 1*time.Second)
require.True(t, ok)
require.NotNil(t, upd)
assert.Len(t, upd, 1)
rec, ok := upd[ip]
require.True(t, ok)
require.NotNil(t, rec)
assert.Truef(t, rec.equal(want), "%+v != %+v", rec, want)
assert.Equal(t, want, upd)
}
t.Run("initial_refresh", func(t *testing.T) {
checkRefresh(t, &HostsRecord{
Aliases: stringutil.NewSet(),
Canonical: "hostname",
checkRefresh(t, aghnet.Hosts{
ip: {{
Addr: ip,
Source: "file1",
Names: []string{"hostname"},
}},
})
})
t.Run("second_refresh", func(t *testing.T) {
testFS["dir/file2"] = &fstest.MapFile{Data: []byte(ipStr + ` alias` + nl)}
testFS["dir/file2"] = &fstest.MapFile{Data: []byte(anotherIPStr + ` alias` + nl)}
eventsCh <- event{}
checkRefresh(t, &HostsRecord{
Aliases: stringutil.NewSet("alias"),
Canonical: "hostname",
checkRefresh(t, aghnet.Hosts{
ip: {{
Addr: ip,
Source: "file1",
Names: []string{"hostname"},
}},
anotherIP: {{
Addr: anotherIP,
Source: "file2",
Names: []string{"alias"},
}},
})
})
@@ -202,12 +333,9 @@ func TestHostsContainer_refresh(t *testing.T) {
// Require the changes are written.
require.Eventually(t, func() bool {
res, ok := hc.MatchRequest(&urlfilter.DNSRequest{
Hostname: "hostname",
DNSType: dns.TypeA,
})
ips := hc.MatchName("hostname")
return !ok && res.DNSRewrites() == nil
return len(ips) == 0
}, 5*time.Second, time.Second/2)
// Make a change again.
@@ -216,411 +344,117 @@ func TestHostsContainer_refresh(t *testing.T) {
// Require the changes are written.
require.Eventually(t, func() bool {
res, ok := hc.MatchRequest(&urlfilter.DNSRequest{
Hostname: "hostname",
DNSType: dns.TypeA,
})
ips := hc.MatchName("hostname")
return !ok && res.DNSRewrites() != nil
return len(ips) > 0
}, 5*time.Second, time.Second/2)
assert.Len(t, hc.Upd(), 1)
})
}
func TestHostsContainer_PathsToPatterns(t *testing.T) {
gsfs := fstest.MapFS{
"dir_0/file_1": &fstest.MapFile{Data: []byte{1}},
"dir_0/file_2": &fstest.MapFile{Data: []byte{2}},
"dir_0/dir_1/file_3": &fstest.MapFile{Data: []byte{3}},
}
func TestHostsContainer_MatchName(t *testing.T) {
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
testCases := []struct {
name string
paths []string
want []string
}{{
name: "no_paths",
paths: nil,
want: nil,
}, {
name: "single_file",
paths: []string{"dir_0/file_1"},
want: []string{"dir_0/file_1"},
}, {
name: "several_files",
paths: []string{"dir_0/file_1", "dir_0/file_2"},
want: []string{"dir_0/file_1", "dir_0/file_2"},
}, {
name: "whole_dir",
paths: []string{"dir_0"},
want: []string{"dir_0/*"},
}, {
name: "file_and_dir",
paths: []string{"dir_0/file_1", "dir_0/dir_1"},
want: []string{"dir_0/file_1", "dir_0/dir_1/*"},
}, {
name: "non-existing",
paths: []string{path.Join("dir_0", "file_3")},
want: nil,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
patterns, err := pathsToPatterns(gsfs, tc.paths)
require.NoError(t, err)
assert.Equal(t, tc.want, patterns)
})
}
t.Run("bad_file", func(t *testing.T) {
const errStat errors.Error = "bad file"
badFS := &aghtest.StatFS{
OnStat: func(name string) (fs.FileInfo, error) {
return nil, errStat
},
}
_, err := pathsToPatterns(badFS, []string{""})
assert.ErrorIs(t, err, errStat)
})
}
func TestHostsContainer_Translate(t *testing.T) {
stubWatcher := aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
OnClose: func() (err error) { return nil },
}
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
hc, err := NewHostsContainer(0, testdata, &stubWatcher, "etc_hosts")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, hc.Close)
testCases := []struct {
name string
rule string
wantTrans []string
}{{
name: "simplehost",
rule: "|simplehost^$dnsrewrite=NOERROR;A;1.0.0.1",
wantTrans: []string{"1.0.0.1", "simplehost"},
}, {
name: "hello",
rule: "|hello^$dnsrewrite=NOERROR;A;1.0.0.0",
wantTrans: []string{"1.0.0.0", "hello", "hello.world"},
}, {
name: "hello-alias",
rule: "|hello.world.again^$dnsrewrite=NOERROR;A;1.0.0.0",
wantTrans: []string{"1.0.0.0", "hello.world.again"},
}, {
name: "simplehost_v6",
rule: "|simplehost^$dnsrewrite=NOERROR;AAAA;::1",
wantTrans: []string{"::1", "simplehost"},
}, {
name: "hello_v6",
rule: "|hello^$dnsrewrite=NOERROR;AAAA;::",
wantTrans: []string{"::", "hello", "hello.world"},
}, {
name: "hello_v6-alias",
rule: "|hello.world.again^$dnsrewrite=NOERROR;AAAA;::",
wantTrans: []string{"::", "hello.world.again"},
}, {
name: "simplehost_ptr",
rule: "|1.0.0.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;simplehost.",
wantTrans: []string{"1.0.0.1", "simplehost"},
}, {
name: "hello_ptr",
rule: "|0.0.0.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;hello.",
wantTrans: []string{"1.0.0.0", "hello", "hello.world"},
}, {
name: "hello_ptr-alias",
rule: "|0.0.0.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;hello.world.again.",
wantTrans: []string{"1.0.0.0", "hello.world.again"},
}, {
name: "simplehost_ptr_v6",
rule: "|1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" +
"^$dnsrewrite=NOERROR;PTR;simplehost.",
wantTrans: []string{"::1", "simplehost"},
}, {
name: "hello_ptr_v6",
rule: "|0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" +
"^$dnsrewrite=NOERROR;PTR;hello.",
wantTrans: []string{"::", "hello", "hello.world"},
}, {
name: "hello_ptr_v6-alias",
rule: "|0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" +
"^$dnsrewrite=NOERROR;PTR;hello.world.again.",
wantTrans: []string{"::", "hello.world.again"},
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got := stringutil.NewSet(strings.Fields(hc.Translate(tc.rule))...)
assert.True(t, stringutil.NewSet(tc.wantTrans...).Equal(got))
})
}
}
func TestHostsContainer(t *testing.T) {
const listID = 1234
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
testCases := []struct {
req *urlfilter.DNSRequest
req string
name string
want []*rules.DNSRewrite
want []*hostsfile.Record
}{{
req: &urlfilter.DNSRequest{
Hostname: "simplehost",
DNSType: dns.TypeA,
},
req: "simplehost",
name: "simple",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
Value: net.IPv4(1, 0, 0, 1),
RRType: dns.TypeA,
}, {
RCode: dns.RcodeSuccess,
Value: net.ParseIP("::1"),
RRType: dns.TypeAAAA,
}},
want: append(testHosts[addr1001], testHosts[addr1]...),
}, {
req: &urlfilter.DNSRequest{
Hostname: "hello.world",
DNSType: dns.TypeA,
},
req: "hello.world",
name: "hello_alias",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
Value: net.IPv4(1, 0, 0, 0),
RRType: dns.TypeA,
}, {
RCode: dns.RcodeSuccess,
Value: net.ParseIP("::"),
RRType: dns.TypeAAAA,
}},
}, {
req: &urlfilter.DNSRequest{
Hostname: "hello.world.again",
DNSType: dns.TypeA,
want: []*hostsfile.Record{
testHosts[addr1000][0],
testHosts[addr1000][2],
testHosts[addr0][0],
testHosts[addr0][2],
},
}, {
req: "hello.world.again",
name: "other_line_alias",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
Value: net.IPv4(1, 0, 0, 0),
RRType: dns.TypeA,
}, {
RCode: dns.RcodeSuccess,
Value: net.ParseIP("::"),
RRType: dns.TypeAAAA,
}},
}, {
req: &urlfilter.DNSRequest{
Hostname: "say.hello",
DNSType: dns.TypeA,
want: []*hostsfile.Record{
testHosts[addr1000][1],
testHosts[addr0][1],
},
}, {
req: "say.hello",
name: "hello_subdomain",
want: []*rules.DNSRewrite{},
}, {
req: &urlfilter.DNSRequest{
Hostname: "say.hello.world",
DNSType: dns.TypeA,
},
name: "hello_alias_subdomain",
want: []*rules.DNSRewrite{},
}, {
req: &urlfilter.DNSRequest{
Hostname: "for.testing",
DNSType: dns.TypeA,
},
name: "lots_of_aliases",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypeA,
Value: net.IPv4(1, 0, 0, 2),
}, {
RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA,
Value: net.ParseIP("::2"),
}},
}, {
req: &urlfilter.DNSRequest{
Hostname: "1.0.0.1.in-addr.arpa",
DNSType: dns.TypePTR,
},
name: "reverse",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypePTR,
Value: "simplehost.",
}},
}, {
req: &urlfilter.DNSRequest{
Hostname: "nonexistent.example",
DNSType: dns.TypeA,
},
name: "non-existing",
want: []*rules.DNSRewrite{},
}, {
req: &urlfilter.DNSRequest{
Hostname: "1.0.0.1.in-addr.arpa",
DNSType: dns.TypeSRV,
},
name: "bad_type",
want: nil,
}, {
req: &urlfilter.DNSRequest{
Hostname: "domain",
DNSType: dns.TypeA,
},
req: "say.hello.world",
name: "hello_alias_subdomain",
want: nil,
}, {
req: "for.testing",
name: "lots_of_aliases",
want: append(testHosts[addr1002], testHosts[addr2]...),
}, {
req: "nonexistent.example",
name: "non-existing",
want: nil,
}, {
req: "domain",
name: "issue_4216_4_6",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypeA,
Value: net.IPv4(4, 2, 1, 6),
}, {
RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA,
Value: net.ParseIP("::42"),
}},
want: append(testHosts[addr4216], testHosts[addr42]...),
}, {
req: &urlfilter.DNSRequest{
Hostname: "domain4",
DNSType: dns.TypeA,
},
req: "domain4",
name: "issue_4216_4",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypeA,
Value: net.IPv4(7, 5, 3, 1),
}, {
RCode: dns.RcodeSuccess,
RRType: dns.TypeA,
Value: net.IPv4(1, 3, 5, 7),
}},
want: append(testHosts[addr1357], testHosts[addr7531]...),
}, {
req: &urlfilter.DNSRequest{
Hostname: "domain6",
DNSType: dns.TypeAAAA,
},
req: "domain6",
name: "issue_4216_6",
want: []*rules.DNSRewrite{{
RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA,
Value: net.ParseIP("::13"),
}, {
RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA,
Value: net.ParseIP("::31"),
}},
want: append(testHosts[addr13], testHosts[addr31]...),
}}
hc, err := aghnet.NewHostsContainer(testdata, &stubWatcher, "etc_hosts")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, hc.Close)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
recs := hc.MatchName(tc.req)
assert.Equal(t, tc.want, recs)
})
}
}
func TestHostsContainer_MatchAddr(t *testing.T) {
require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
stubWatcher := aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
OnClose: func() (err error) { return nil },
}
hc, err := NewHostsContainer(listID, testdata, &stubWatcher, "etc_hosts")
hc, err := aghnet.NewHostsContainer(testdata, &stubWatcher, "etc_hosts")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, hc.Close)
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
res, ok := hc.MatchRequest(tc.req)
require.False(t, ok)
if tc.want == nil {
assert.Nil(t, res)
return
}
require.NotNil(t, res)
rewrites := res.DNSRewrites()
require.Len(t, rewrites, len(tc.want))
for i, rewrite := range rewrites {
require.Equal(t, listID, rewrite.FilterListID)
rw := rewrite.DNSRewrite
require.NotNil(t, rw)
assert.Equal(t, tc.want[i], rw)
}
})
}
}
func TestUniqueRules_ParseLine(t *testing.T) {
ip := netutil.IPv4Localhost()
ipStr := ip.String()
testCases := []struct {
name string
line string
wantIP netip.Addr
wantHosts []string
req netip.Addr
name string
want []*hostsfile.Record
}{{
name: "simple",
line: ipStr + ` hostname`,
wantIP: ip,
wantHosts: []string{"hostname"},
}, {
name: "aliases",
line: ipStr + ` hostname alias`,
wantIP: ip,
wantHosts: []string{"hostname", "alias"},
}, {
name: "invalid_line",
line: ipStr,
wantIP: netip.Addr{},
wantHosts: nil,
}, {
name: "invalid_line_hostname",
line: ipStr + ` # hostname`,
wantIP: ip,
wantHosts: nil,
}, {
name: "commented_aliases",
line: ipStr + ` hostname # alias`,
wantIP: ip,
wantHosts: []string{"hostname"},
}, {
name: "whole_comment",
line: `# ` + ipStr + ` hostname`,
wantIP: netip.Addr{},
wantHosts: nil,
}, {
name: "partial_comment",
line: ipStr + ` host#name`,
wantIP: ip,
wantHosts: []string{"host"},
}, {
name: "empty",
line: ``,
wantIP: netip.Addr{},
wantHosts: nil,
}, {
name: "bad_hosts",
line: ipStr + ` bad..host bad._tld empty.tld. ok.host`,
wantIP: ip,
wantHosts: []string{"ok.host"},
req: netip.AddrFrom4([4]byte{1, 0, 0, 1}),
name: "reverse",
want: testHosts[addr1001],
}}
for _, tc := range testCases {
hp := hostsParser{}
t.Run(tc.name, func(t *testing.T) {
got, hosts := hp.parseLine(tc.line)
assert.Equal(t, tc.wantIP, got)
assert.Equal(t, tc.wantHosts, hosts)
recs := hc.MatchAddr(tc.req)
assert.Equal(t, tc.want, recs)
})
}
}

View File

@@ -4,7 +4,6 @@ package aghnet
import (
"context"
"fmt"
"net"
"os"
"syscall"
@@ -24,20 +23,9 @@ func reuseAddrCtrl(_, _ string, c syscall.RawConn) (err error) {
}
})
const (
errMsg = "setting control options"
errMsgFmt = errMsg + ": %w"
)
err = errors.Join(err, cerr)
if err != nil && cerr != nil {
err = errors.List(errMsg, err, cerr)
} else if err != nil {
err = fmt.Errorf(errMsgFmt, err)
} else if cerr != nil {
err = fmt.Errorf(errMsgFmt, cerr)
}
return err
return errors.Annotate(err, "setting control options: %w")
}
// listenPacketReusable announces on the local network address additionally

View File

@@ -390,9 +390,5 @@ func (m *ipsetMgr) Close() (err error) {
errs = append(errs, err)
}
if len(errs) != 0 {
return errors.List("closing ipsets", errs...)
}
return nil
return errors.Annotate(errors.Join(errs...), "closing ipsets: %w")
}

View File

@@ -3,6 +3,7 @@ package aghnet
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
@@ -15,6 +16,10 @@ import (
"github.com/AdguardTeam/golibs/log"
)
// DialContextFunc is the semantic alias for dialing functions, such as
// [http.Transport.DialContext].
type DialContextFunc = func(ctx context.Context, network, addr string) (conn net.Conn, err error)
// Variables and functions to substitute in tests.
var (
// aghosRunCommand is the function to run shell commands.

View File

@@ -5,9 +5,9 @@ import (
"testing"
"testing/fstest"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/golibs/testutil/fakefs"
"github.com/stretchr/testify/assert"
)
@@ -118,7 +118,7 @@ func TestIfaceSetStaticIP(t *testing.T) {
Data: []byte(`nameserver 1.1.1.1`),
},
}
panicFsys := &aghtest.FS{
panicFsys := &fakefs.FS{
OnOpen: func(name string) (fs.File, error) { panic("not implemented") },
}

View File

@@ -0,0 +1,330 @@
package aghnet
import (
"bytes"
"encoding/json"
"fmt"
"io/fs"
"net"
"net/netip"
"strings"
"testing"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// substRootDirFS replaces the aghos.RootDirFS function used throughout the
// package with fsys for tests ran under t.
func substRootDirFS(t testing.TB, fsys fs.FS) {
t.Helper()
prev := rootDirFS
t.Cleanup(func() { rootDirFS = prev })
rootDirFS = fsys
}
// RunCmdFunc is the signature of aghos.RunCommand function.
type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err error)
// substShell replaces the the aghos.RunCommand function used throughout the
// package with rc for tests ran under t.
func substShell(t testing.TB, rc RunCmdFunc) {
t.Helper()
prev := aghosRunCommand
t.Cleanup(func() { aghosRunCommand = prev })
aghosRunCommand = rc
}
// mapShell is a substitution of aghos.RunCommand that maps the command to it's
// execution result. It's only needed to simplify testing.
//
// TODO(e.burkov): Perhaps put all the shell interactions behind an interface.
type mapShell map[string]struct {
err error
out string
code int
}
// theOnlyCmd returns mapShell that only handles a single command and arguments
// combination from cmd.
func theOnlyCmd(cmd string, code int, out string, err error) (s mapShell) {
return mapShell{cmd: {code: code, out: out, err: err}}
}
// RunCmd is a RunCmdFunc handled by s.
func (s mapShell) RunCmd(cmd string, args ...string) (code int, out []byte, err error) {
key := strings.Join(append([]string{cmd}, args...), " ")
ret, ok := s[key]
if !ok {
return 0, nil, fmt.Errorf("unexpected shell command %q", key)
}
return ret.code, []byte(ret.out), ret.err
}
// ifaceAddrsFunc is the signature of net.InterfaceAddrs function.
type ifaceAddrsFunc func() (ifaces []net.Addr, err error)
// substNetInterfaceAddrs replaces the the net.InterfaceAddrs function used
// throughout the package with f for tests ran under t.
func substNetInterfaceAddrs(t *testing.T, f ifaceAddrsFunc) {
t.Helper()
prev := netInterfaceAddrs
t.Cleanup(func() { netInterfaceAddrs = prev })
netInterfaceAddrs = f
}
func TestGatewayIP(t *testing.T) {
const ifaceName = "ifaceName"
const cmd = "ip route show dev " + ifaceName
testCases := []struct {
shell mapShell
want netip.Addr
name string
}{{
shell: theOnlyCmd(cmd, 0, `default via 1.2.3.4 onlink`, nil),
want: netip.MustParseAddr("1.2.3.4"),
name: "success_v4",
}, {
shell: theOnlyCmd(cmd, 0, `default via ::ffff onlink`, nil),
want: netip.MustParseAddr("::ffff"),
name: "success_v6",
}, {
shell: theOnlyCmd(cmd, 0, `non-default via 1.2.3.4 onlink`, nil),
want: netip.Addr{},
name: "bad_output",
}, {
shell: theOnlyCmd(cmd, 0, "", errors.Error("can't run command")),
want: netip.Addr{},
name: "err_runcmd",
}, {
shell: theOnlyCmd(cmd, 1, "", nil),
want: netip.Addr{},
name: "bad_code",
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
substShell(t, tc.shell.RunCmd)
assert.Equal(t, tc.want, GatewayIP(ifaceName))
})
}
}
func TestInterfaceByIP(t *testing.T) {
ifaces, err := GetValidNetInterfacesForWeb()
require.NoError(t, err)
require.NotEmpty(t, ifaces)
for _, iface := range ifaces {
t.Run(iface.Name, func(t *testing.T) {
require.NotEmpty(t, iface.Addresses)
for _, ip := range iface.Addresses {
ifaceName := InterfaceByIP(ip)
require.Equal(t, iface.Name, ifaceName)
}
})
}
}
func TestBroadcastFromIPNet(t *testing.T) {
known4 := netip.MustParseAddr("192.168.0.1")
fullBroadcast4 := netip.MustParseAddr("255.255.255.255")
known6 := netip.MustParseAddr("102:304:506:708:90a:b0c:d0e:f10")
testCases := []struct {
pref netip.Prefix
want netip.Addr
name string
}{{
pref: netip.PrefixFrom(known4, 0),
want: fullBroadcast4,
name: "full",
}, {
pref: netip.PrefixFrom(known4, 20),
want: netip.MustParseAddr("192.168.15.255"),
name: "full",
}, {
pref: netip.PrefixFrom(known6, netutil.IPv6BitLen),
want: known6,
name: "ipv6_no_mask",
}, {
pref: netip.PrefixFrom(known4, netutil.IPv4BitLen),
want: known4,
name: "ipv4_no_mask",
}, {
pref: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
want: fullBroadcast4,
name: "unspecified",
}, {
pref: netip.Prefix{},
want: netip.Addr{},
name: "invalid",
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.want, BroadcastFromPref(tc.pref))
})
}
}
func TestCheckPort(t *testing.T) {
laddr := netip.AddrPortFrom(netutil.IPv4Localhost(), 0)
t.Run("tcp_bound", func(t *testing.T) {
l, err := net.Listen("tcp", laddr.String())
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
ipp := testutil.RequireTypeAssert[*net.TCPAddr](t, l.Addr()).AddrPort()
require.Equal(t, laddr.Addr(), ipp.Addr())
require.NotZero(t, ipp.Port())
err = CheckPort("tcp", ipp)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("udp_bound", func(t *testing.T) {
conn, err := net.ListenPacket("udp", laddr.String())
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, conn.Close)
ipp := testutil.RequireTypeAssert[*net.UDPAddr](t, conn.LocalAddr()).AddrPort()
require.Equal(t, laddr.Addr(), ipp.Addr())
require.NotZero(t, ipp.Port())
err = CheckPort("udp", ipp)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("bad_network", func(t *testing.T) {
err := CheckPort("bad_network", netip.AddrPortFrom(netip.Addr{}, 0))
assert.NoError(t, err)
})
t.Run("can_bind", func(t *testing.T) {
err := CheckPort("udp", netip.AddrPortFrom(netip.IPv4Unspecified(), 0))
assert.NoError(t, err)
})
}
func TestCollectAllIfacesAddrs(t *testing.T) {
testCases := []struct {
name string
wantErrMsg string
addrs []net.Addr
wantAddrs []string
}{{
name: "success",
wantErrMsg: ``,
addrs: []net.Addr{&net.IPNet{
IP: net.IP{1, 2, 3, 4},
Mask: net.CIDRMask(24, netutil.IPv4BitLen),
}, &net.IPNet{
IP: net.IP{4, 3, 2, 1},
Mask: net.CIDRMask(16, netutil.IPv4BitLen),
}},
wantAddrs: []string{"1.2.3.4", "4.3.2.1"},
}, {
name: "not_cidr",
wantErrMsg: `parsing cidr: invalid CIDR address: 1.2.3.4`,
addrs: []net.Addr{&net.IPAddr{
IP: net.IP{1, 2, 3, 4},
}},
wantAddrs: nil,
}, {
name: "empty",
wantErrMsg: ``,
addrs: []net.Addr{},
wantAddrs: nil,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return tc.addrs, nil })
addrs, err := CollectAllIfacesAddrs()
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
assert.Equal(t, tc.wantAddrs, addrs)
})
}
t.Run("internal_error", func(t *testing.T) {
const errAddrs errors.Error = "can't get addresses"
const wantErrMsg string = `getting interfaces addresses: ` + string(errAddrs)
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return nil, errAddrs })
_, err := CollectAllIfacesAddrs()
testutil.AssertErrorMsg(t, wantErrMsg, err)
})
}
func TestIsAddrInUse(t *testing.T) {
t.Run("addr_in_use", func(t *testing.T) {
l, err := net.Listen("tcp", "0.0.0.0:0")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
_, err = net.Listen(l.Addr().Network(), l.Addr().String())
assert.True(t, IsAddrInUse(err))
})
t.Run("another", func(t *testing.T) {
const anotherErr errors.Error = "not addr in use"
assert.False(t, IsAddrInUse(anotherErr))
})
}
func TestNetInterface_MarshalJSON(t *testing.T) {
const want = `{` +
`"hardware_address":"aa:bb:cc:dd:ee:ff",` +
`"flags":"up|multicast",` +
`"ip_addresses":["1.2.3.4","aaaa::1"],` +
`"name":"iface0",` +
`"mtu":1500` +
`}` + "\n"
ip4, ok := netip.AddrFromSlice([]byte{1, 2, 3, 4})
require.True(t, ok)
ip6, ok := netip.AddrFromSlice([]byte{0xAA, 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
require.True(t, ok)
net4 := netip.PrefixFrom(ip4, 24)
net6 := netip.PrefixFrom(ip6, 8)
iface := &NetInterface{
Addresses: []netip.Addr{ip4, ip6},
Subnets: []netip.Prefix{net4, net6},
Name: "iface0",
HardwareAddr: net.HardwareAddr{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
Flags: net.FlagUp | net.FlagMulticast,
MTU: 1500,
}
b := &bytes.Buffer{}
err := json.NewEncoder(b).Encode(iface)
require.NoError(t, err)
assert.Equal(t, want, b.String())
}

View File

@@ -14,7 +14,7 @@ import (
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/stringutil"
"github.com/google/renameio/maybe"
"github.com/google/renameio/v2/maybe"
"golang.org/x/sys/unix"
)

View File

@@ -1,21 +1,11 @@
package aghnet
package aghnet_test
import (
"bytes"
"encoding/json"
"fmt"
"io/fs"
"net"
"net/netip"
"os"
"strings"
"testing"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -24,315 +14,3 @@ func TestMain(m *testing.M) {
// testdata is the filesystem containing data for testing the package.
var testdata fs.FS = os.DirFS("./testdata")
// substRootDirFS replaces the aghos.RootDirFS function used throughout the
// package with fsys for tests ran under t.
func substRootDirFS(t testing.TB, fsys fs.FS) {
t.Helper()
prev := rootDirFS
t.Cleanup(func() { rootDirFS = prev })
rootDirFS = fsys
}
// RunCmdFunc is the signature of aghos.RunCommand function.
type RunCmdFunc func(cmd string, args ...string) (code int, out []byte, err error)
// substShell replaces the the aghos.RunCommand function used throughout the
// package with rc for tests ran under t.
func substShell(t testing.TB, rc RunCmdFunc) {
t.Helper()
prev := aghosRunCommand
t.Cleanup(func() { aghosRunCommand = prev })
aghosRunCommand = rc
}
// mapShell is a substitution of aghos.RunCommand that maps the command to it's
// execution result. It's only needed to simplify testing.
//
// TODO(e.burkov): Perhaps put all the shell interactions behind an interface.
type mapShell map[string]struct {
err error
out string
code int
}
// theOnlyCmd returns mapShell that only handles a single command and arguments
// combination from cmd.
func theOnlyCmd(cmd string, code int, out string, err error) (s mapShell) {
return mapShell{cmd: {code: code, out: out, err: err}}
}
// RunCmd is a RunCmdFunc handled by s.
func (s mapShell) RunCmd(cmd string, args ...string) (code int, out []byte, err error) {
key := strings.Join(append([]string{cmd}, args...), " ")
ret, ok := s[key]
if !ok {
return 0, nil, fmt.Errorf("unexpected shell command %q", key)
}
return ret.code, []byte(ret.out), ret.err
}
// ifaceAddrsFunc is the signature of net.InterfaceAddrs function.
type ifaceAddrsFunc func() (ifaces []net.Addr, err error)
// substNetInterfaceAddrs replaces the the net.InterfaceAddrs function used
// throughout the package with f for tests ran under t.
func substNetInterfaceAddrs(t *testing.T, f ifaceAddrsFunc) {
t.Helper()
prev := netInterfaceAddrs
t.Cleanup(func() { netInterfaceAddrs = prev })
netInterfaceAddrs = f
}
func TestGatewayIP(t *testing.T) {
const ifaceName = "ifaceName"
const cmd = "ip route show dev " + ifaceName
testCases := []struct {
shell mapShell
want netip.Addr
name string
}{{
shell: theOnlyCmd(cmd, 0, `default via 1.2.3.4 onlink`, nil),
want: netip.MustParseAddr("1.2.3.4"),
name: "success_v4",
}, {
shell: theOnlyCmd(cmd, 0, `default via ::ffff onlink`, nil),
want: netip.MustParseAddr("::ffff"),
name: "success_v6",
}, {
shell: theOnlyCmd(cmd, 0, `non-default via 1.2.3.4 onlink`, nil),
want: netip.Addr{},
name: "bad_output",
}, {
shell: theOnlyCmd(cmd, 0, "", errors.Error("can't run command")),
want: netip.Addr{},
name: "err_runcmd",
}, {
shell: theOnlyCmd(cmd, 1, "", nil),
want: netip.Addr{},
name: "bad_code",
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
substShell(t, tc.shell.RunCmd)
assert.Equal(t, tc.want, GatewayIP(ifaceName))
})
}
}
func TestInterfaceByIP(t *testing.T) {
ifaces, err := GetValidNetInterfacesForWeb()
require.NoError(t, err)
require.NotEmpty(t, ifaces)
for _, iface := range ifaces {
t.Run(iface.Name, func(t *testing.T) {
require.NotEmpty(t, iface.Addresses)
for _, ip := range iface.Addresses {
ifaceName := InterfaceByIP(ip)
require.Equal(t, iface.Name, ifaceName)
}
})
}
}
func TestBroadcastFromIPNet(t *testing.T) {
known4 := netip.MustParseAddr("192.168.0.1")
fullBroadcast4 := netip.MustParseAddr("255.255.255.255")
known6 := netip.MustParseAddr("102:304:506:708:90a:b0c:d0e:f10")
testCases := []struct {
pref netip.Prefix
want netip.Addr
name string
}{{
pref: netip.PrefixFrom(known4, 0),
want: fullBroadcast4,
name: "full",
}, {
pref: netip.PrefixFrom(known4, 20),
want: netip.MustParseAddr("192.168.15.255"),
name: "full",
}, {
pref: netip.PrefixFrom(known6, netutil.IPv6BitLen),
want: known6,
name: "ipv6_no_mask",
}, {
pref: netip.PrefixFrom(known4, netutil.IPv4BitLen),
want: known4,
name: "ipv4_no_mask",
}, {
pref: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
want: fullBroadcast4,
name: "unspecified",
}, {
pref: netip.Prefix{},
want: netip.Addr{},
name: "invalid",
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.want, BroadcastFromPref(tc.pref))
})
}
}
func TestCheckPort(t *testing.T) {
laddr := netip.AddrPortFrom(netutil.IPv4Localhost(), 0)
t.Run("tcp_bound", func(t *testing.T) {
l, err := net.Listen("tcp", laddr.String())
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
ipp := testutil.RequireTypeAssert[*net.TCPAddr](t, l.Addr()).AddrPort()
require.Equal(t, laddr.Addr(), ipp.Addr())
require.NotZero(t, ipp.Port())
err = CheckPort("tcp", ipp)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("udp_bound", func(t *testing.T) {
conn, err := net.ListenPacket("udp", laddr.String())
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, conn.Close)
ipp := testutil.RequireTypeAssert[*net.UDPAddr](t, conn.LocalAddr()).AddrPort()
require.Equal(t, laddr.Addr(), ipp.Addr())
require.NotZero(t, ipp.Port())
err = CheckPort("udp", ipp)
target := &net.OpError{}
require.ErrorAs(t, err, &target)
assert.Equal(t, "listen", target.Op)
})
t.Run("bad_network", func(t *testing.T) {
err := CheckPort("bad_network", netip.AddrPortFrom(netip.Addr{}, 0))
assert.NoError(t, err)
})
t.Run("can_bind", func(t *testing.T) {
err := CheckPort("udp", netip.AddrPortFrom(netip.IPv4Unspecified(), 0))
assert.NoError(t, err)
})
}
func TestCollectAllIfacesAddrs(t *testing.T) {
testCases := []struct {
name string
wantErrMsg string
addrs []net.Addr
wantAddrs []string
}{{
name: "success",
wantErrMsg: ``,
addrs: []net.Addr{&net.IPNet{
IP: net.IP{1, 2, 3, 4},
Mask: net.CIDRMask(24, netutil.IPv4BitLen),
}, &net.IPNet{
IP: net.IP{4, 3, 2, 1},
Mask: net.CIDRMask(16, netutil.IPv4BitLen),
}},
wantAddrs: []string{"1.2.3.4", "4.3.2.1"},
}, {
name: "not_cidr",
wantErrMsg: `parsing cidr: invalid CIDR address: 1.2.3.4`,
addrs: []net.Addr{&net.IPAddr{
IP: net.IP{1, 2, 3, 4},
}},
wantAddrs: nil,
}, {
name: "empty",
wantErrMsg: ``,
addrs: []net.Addr{},
wantAddrs: nil,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return tc.addrs, nil })
addrs, err := CollectAllIfacesAddrs()
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
assert.Equal(t, tc.wantAddrs, addrs)
})
}
t.Run("internal_error", func(t *testing.T) {
const errAddrs errors.Error = "can't get addresses"
const wantErrMsg string = `getting interfaces addresses: ` + string(errAddrs)
substNetInterfaceAddrs(t, func() ([]net.Addr, error) { return nil, errAddrs })
_, err := CollectAllIfacesAddrs()
testutil.AssertErrorMsg(t, wantErrMsg, err)
})
}
func TestIsAddrInUse(t *testing.T) {
t.Run("addr_in_use", func(t *testing.T) {
l, err := net.Listen("tcp", "0.0.0.0:0")
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, l.Close)
_, err = net.Listen(l.Addr().Network(), l.Addr().String())
assert.True(t, IsAddrInUse(err))
})
t.Run("another", func(t *testing.T) {
const anotherErr errors.Error = "not addr in use"
assert.False(t, IsAddrInUse(anotherErr))
})
}
func TestNetInterface_MarshalJSON(t *testing.T) {
const want = `{` +
`"hardware_address":"aa:bb:cc:dd:ee:ff",` +
`"flags":"up|multicast",` +
`"ip_addresses":["1.2.3.4","aaaa::1"],` +
`"name":"iface0",` +
`"mtu":1500` +
`}` + "\n"
ip4, ok := netip.AddrFromSlice([]byte{1, 2, 3, 4})
require.True(t, ok)
ip6, ok := netip.AddrFromSlice([]byte{0xAA, 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
require.True(t, ok)
net4 := netip.PrefixFrom(ip4, 24)
net6 := netip.PrefixFrom(ip6, 8)
iface := &NetInterface{
Addresses: []netip.Addr{ip4, ip6},
Subnets: []netip.Prefix{net4, net6},
Name: "iface0",
HardwareAddr: net.HardwareAddr{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
Flags: net.FlagUp | net.FlagMulticast,
MTU: 1500,
}
b := &bytes.Buffer{}
err := json.NewEncoder(b).Encode(iface)
require.NoError(t, err)
assert.Equal(t, want, b.String())
}

View File

@@ -0,0 +1,52 @@
// Package aghrenameio is a wrapper around package github.com/google/renameio/v2
// that provides a similar stream-based API for both Unix and Windows systems.
// While the Windows API is not technically atomic, it still provides a
// consistent stream-based interface, and atomic renames of files do not seem to
// be possible in all cases anyway.
//
// See https://github.com/google/renameio/issues/1.
//
// TODO(a.garipov): Consider moving to golibs/renameioutil once tried and
// tested.
package aghrenameio
import (
"io/fs"
"github.com/AdguardTeam/golibs/errors"
)
// PendingFile is the interface for pending temporary files.
type PendingFile interface {
// Cleanup closes the file, and removes it without performing the renaming.
// To close and rename the file, use CloseReplace.
Cleanup() (err error)
// CloseReplace closes the temporary file and replaces the destination file
// with it, possibly atomically.
//
// This method is not safe for concurrent use by multiple goroutines.
CloseReplace() (err error)
// Write writes len(b) bytes from b to the File. It returns the number of
// bytes written and an error, if any. Write returns a non-nil error when n
// != len(b).
Write(b []byte) (n int, err error)
}
// NewPendingFile is a wrapper around [renameio.NewPendingFile] on Unix systems
// and [os.CreateTemp] on Windows.
func NewPendingFile(filePath string, mode fs.FileMode) (f PendingFile, err error) {
return newPendingFile(filePath, mode)
}
// WithDeferredCleanup is a helper that performs the necessary cleanups and
// finalizations of the temporary files based on the returned error.
func WithDeferredCleanup(returned error, file PendingFile) (err error) {
// Make sure that any error returned from here is marked as a deferred one.
if returned != nil {
return errors.WithDeferred(returned, file.Cleanup())
}
return errors.WithDeferred(nil, file.CloseReplace())
}

View File

@@ -0,0 +1,101 @@
package aghrenameio_test
import (
"io/fs"
"os"
"path/filepath"
"testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghrenameio"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// testPerm is the common permission mode for tests.
const testPerm fs.FileMode = 0o644
// Common file data for tests.
var (
initialData = []byte("initial data\n")
newData = []byte("new data\n")
)
func TestPendingFile(t *testing.T) {
t.Parallel()
targetPath := newInitialFile(t)
f, err := aghrenameio.NewPendingFile(targetPath, testPerm)
require.NoError(t, err)
_, err = f.Write(newData)
require.NoError(t, err)
err = f.CloseReplace()
require.NoError(t, err)
gotData, err := os.ReadFile(targetPath)
require.NoError(t, err)
assert.Equal(t, newData, gotData)
}
// newInitialFile is a test helper that returns the path to the file containing
// [initialData].
func newInitialFile(t *testing.T) (targetPath string) {
t.Helper()
dir := t.TempDir()
targetPath = filepath.Join(dir, "target")
err := os.WriteFile(targetPath, initialData, 0o644)
require.NoError(t, err)
return targetPath
}
func TestWithDeferredCleanup(t *testing.T) {
t.Parallel()
const testError errors.Error = "test error"
testCases := []struct {
error error
name string
wantErrMsg string
wantData []byte
}{{
name: "success",
error: nil,
wantErrMsg: "",
wantData: newData,
}, {
name: "error",
error: testError,
wantErrMsg: testError.Error(),
wantData: initialData,
}}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
targetPath := newInitialFile(t)
f, err := aghrenameio.NewPendingFile(targetPath, testPerm)
require.NoError(t, err)
_, err = f.Write(newData)
require.NoError(t, err)
err = aghrenameio.WithDeferredCleanup(tc.error, f)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
gotData, err := os.ReadFile(targetPath)
require.NoError(t, err)
assert.Equal(t, tc.wantData, gotData)
})
}
}

View File

@@ -0,0 +1,48 @@
//go:build unix
package aghrenameio
import (
"io/fs"
"github.com/google/renameio/v2"
)
// pendingFile is a wrapper around [*renameio.PendingFile] making it an
// [io.WriteCloser].
type pendingFile struct {
file *renameio.PendingFile
}
// type check
var _ PendingFile = pendingFile{}
// Cleanup implements the [PendingFile] interface for pendingFile.
func (f pendingFile) Cleanup() (err error) {
return f.file.Cleanup()
}
// CloseReplace implements the [PendingFile] interface for pendingFile.
func (f pendingFile) CloseReplace() (err error) {
return f.file.CloseAtomicallyReplace()
}
// Write implements the [PendingFile] interface for pendingFile.
func (f pendingFile) Write(b []byte) (n int, err error) {
return f.file.Write(b)
}
// NewPendingFile is a wrapper around [renameio.NewPendingFile].
//
// f.Close must be called to finish the renaming.
func newPendingFile(filePath string, mode fs.FileMode) (f PendingFile, err error) {
file, err := renameio.NewPendingFile(filePath, renameio.WithPermissions(mode))
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}
return pendingFile{
file: file,
}, nil
}

View File

@@ -0,0 +1,74 @@
//go:build windows
package aghrenameio
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/AdguardTeam/golibs/errors"
)
// pendingFile is a wrapper around [*os.File] calling [os.Rename] in its Close
// method.
type pendingFile struct {
file *os.File
targetPath string
}
// type check
var _ PendingFile = (*pendingFile)(nil)
// Cleanup implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) Cleanup() (err error) {
closeErr := f.file.Close()
err = os.Remove(f.file.Name())
// Put closeErr into the deferred error because that's where it is usually
// expected.
return errors.WithDeferred(err, closeErr)
}
// CloseReplace implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) CloseReplace() (err error) {
err = f.file.Close()
if err != nil {
return fmt.Errorf("closing: %w", err)
}
err = os.Rename(f.file.Name(), f.targetPath)
if err != nil {
return fmt.Errorf("renaming: %w", err)
}
return nil
}
// Write implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) Write(b []byte) (n int, err error) {
return f.file.Write(b)
}
// NewPendingFile is a wrapper around [os.CreateTemp].
//
// f.Close must be called to finish the renaming.
func newPendingFile(filePath string, mode fs.FileMode) (f PendingFile, err error) {
// Use the same directory as the file itself, because moves across
// filesystems can be especially problematic.
file, err := os.CreateTemp(filepath.Dir(filePath), "")
if err != nil {
return nil, fmt.Errorf("opening pending file: %w", err)
}
err = file.Chmod(mode)
if err != nil {
return nil, fmt.Errorf("preparing pending file: %w", err)
}
return &pendingFile{
file: file,
targetPath: filePath,
}, nil
}

View File

@@ -2,12 +2,22 @@
package aghtest
import (
"crypto/sha256"
"io"
"net/netip"
"testing"
"github.com/AdguardTeam/golibs/log"
)
const (
// ReqHost is the common request host for filtering tests.
ReqHost = "www.host.example"
// ReqFQDN is the common request FQDN for filtering tests.
ReqFQDN = ReqHost + "."
)
// ReplaceLogWriter moves logger output to w and uses Cleanup method of t to
// revert changes.
func ReplaceLogWriter(t testing.TB, w io.Writer) {
@@ -34,3 +44,10 @@ func ReplaceLogLevel(t testing.TB, l log.Level) {
t.Cleanup(func() { log.SetLevel(prev) })
log.SetLevel(l)
}
// HostToIPs is a helper that generates one IPv4 and one IPv6 address from host.
func HostToIPs(host string) (ipv4, ipv6 netip.Addr) {
hash := sha256.Sum256([]byte(host))
return netip.AddrFrom4([4]byte(hash[:4])), netip.AddrFrom16([16]byte(hash[4:20]))
}

View File

@@ -2,11 +2,15 @@ package aghtest
import (
"context"
"io/fs"
"net"
"net/netip"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
"github.com/AdguardTeam/AdGuardHome/internal/client"
"github.com/AdguardTeam/AdGuardHome/internal/next/agh"
"github.com/AdguardTeam/AdGuardHome/internal/rdns"
"github.com/AdguardTeam/AdGuardHome/internal/whois"
"github.com/AdguardTeam/dnsproxy/upstream"
"github.com/miekg/dns"
)
@@ -15,94 +19,20 @@ import (
//
// Keep entities in this file in alphabetic order.
// Standard Library
// Package fs
// type check
var _ fs.FS = &FS{}
// FS is a mock [fs.FS] implementation for tests.
type FS struct {
OnOpen func(name string) (fs.File, error)
}
// Open implements the [fs.FS] interface for *FS.
func (fsys *FS) Open(name string) (fs.File, error) {
return fsys.OnOpen(name)
}
// type check
var _ fs.GlobFS = &GlobFS{}
// GlobFS is a mock [fs.GlobFS] implementation for tests.
type GlobFS struct {
// FS is embedded here to avoid implementing all it's methods.
FS
OnGlob func(pattern string) ([]string, error)
}
// Glob implements the [fs.GlobFS] interface for *GlobFS.
func (fsys *GlobFS) Glob(pattern string) ([]string, error) {
return fsys.OnGlob(pattern)
}
// type check
var _ fs.StatFS = &StatFS{}
// StatFS is a mock [fs.StatFS] implementation for tests.
type StatFS struct {
// FS is embedded here to avoid implementing all it's methods.
FS
OnStat func(name string) (fs.FileInfo, error)
}
// Stat implements the [fs.StatFS] interface for *StatFS.
func (fsys *StatFS) Stat(name string) (fs.FileInfo, error) {
return fsys.OnStat(name)
}
// Package net
// type check
var _ net.Listener = (*Listener)(nil)
// Listener is a mock [net.Listener] implementation for tests.
type Listener struct {
OnAccept func() (conn net.Conn, err error)
OnAddr func() (addr net.Addr)
OnClose func() (err error)
}
// Accept implements the [net.Listener] interface for *Listener.
func (l *Listener) Accept() (conn net.Conn, err error) {
return l.OnAccept()
}
// Addr implements the [net.Listener] interface for *Listener.
func (l *Listener) Addr() (addr net.Addr) {
return l.OnAddr()
}
// Close implements the [net.Listener] interface for *Listener.
func (l *Listener) Close() (err error) {
return l.OnClose()
}
// Module adguard-home
// Package aghos
// type check
var _ aghos.FSWatcher = (*FSWatcher)(nil)
// FSWatcher is a mock [aghos.FSWatcher] implementation for tests.
// FSWatcher is a fake [aghos.FSWatcher] implementation for tests.
type FSWatcher struct {
OnEvents func() (e <-chan struct{})
OnAdd func(name string) (err error)
OnClose func() (err error)
}
// type check
var _ aghos.FSWatcher = (*FSWatcher)(nil)
// Events implements the [aghos.FSWatcher] interface for *FSWatcher.
func (w *FSWatcher) Events() (e <-chan struct{}) {
return w.OnEvents()
@@ -120,16 +50,16 @@ func (w *FSWatcher) Close() (err error) {
// Package agh
// type check
var _ agh.ServiceWithConfig[struct{}] = (*ServiceWithConfig[struct{}])(nil)
// ServiceWithConfig is a mock [agh.ServiceWithConfig] implementation for tests.
// ServiceWithConfig is a fake [agh.ServiceWithConfig] implementation for tests.
type ServiceWithConfig[ConfigType any] struct {
OnStart func() (err error)
OnShutdown func(ctx context.Context) (err error)
OnConfig func() (c ConfigType)
}
// type check
var _ agh.ServiceWithConfig[struct{}] = (*ServiceWithConfig[struct{}])(nil)
// Start implements the [agh.ServiceWithConfig] interface for
// *ServiceWithConfig.
func (s *ServiceWithConfig[_]) Start() (err error) {
@@ -148,14 +78,76 @@ func (s *ServiceWithConfig[ConfigType]) Config() (c ConfigType) {
return s.OnConfig()
}
// Package client
// AddressProcessor is a fake [client.AddressProcessor] implementation for
// tests.
type AddressProcessor struct {
OnProcess func(ip netip.Addr)
OnClose func() (err error)
}
// type check
var _ client.AddressProcessor = (*AddressProcessor)(nil)
// Process implements the [client.AddressProcessor] interface for
// *AddressProcessor.
func (p *AddressProcessor) Process(ip netip.Addr) {
p.OnProcess(ip)
}
// Close implements the [client.AddressProcessor] interface for
// *AddressProcessor.
func (p *AddressProcessor) Close() (err error) {
return p.OnClose()
}
// AddressUpdater is a fake [client.AddressUpdater] implementation for tests.
type AddressUpdater struct {
OnUpdateAddress func(ip netip.Addr, host string, info *whois.Info)
}
// type check
var _ client.AddressUpdater = (*AddressUpdater)(nil)
// UpdateAddress implements the [client.AddressUpdater] interface for
// *AddressUpdater.
func (p *AddressUpdater) UpdateAddress(ip netip.Addr, host string, info *whois.Info) {
p.OnUpdateAddress(ip, host, info)
}
// Package filtering
// Resolver is a fake [filtering.Resolver] implementation for tests.
type Resolver struct {
OnLookupIP func(ctx context.Context, network, host string) (ips []net.IP, err error)
}
// LookupIP implements the [filtering.Resolver] interface for *Resolver.
func (r *Resolver) LookupIP(ctx context.Context, network, host string) (ips []net.IP, err error) {
return r.OnLookupIP(ctx, network, host)
}
// Package rdns
// Exchanger is a fake [rdns.Exchanger] implementation for tests.
type Exchanger struct {
OnExchange func(ip netip.Addr) (host string, ttl time.Duration, err error)
}
// type check
var _ rdns.Exchanger = (*Exchanger)(nil)
// Exchange implements [rdns.Exchanger] interface for *Exchanger.
func (e *Exchanger) Exchange(ip netip.Addr) (host string, ttl time.Duration, err error) {
return e.OnExchange(ip)
}
// Module dnsproxy
// Package upstream
// type check
var _ upstream.Upstream = (*UpstreamMock)(nil)
// UpstreamMock is a mock [upstream.Upstream] implementation for tests.
// UpstreamMock is a fake [upstream.Upstream] implementation for tests.
//
// TODO(a.garipov): Replace with all uses of Upstream with UpstreamMock and
// rename it to just Upstream.
@@ -165,6 +157,9 @@ type UpstreamMock struct {
OnClose func() (err error)
}
// type check
var _ upstream.Upstream = (*UpstreamMock)(nil)
// Address implements the [upstream.Upstream] interface for *UpstreamMock.
func (u *UpstreamMock) Address() (addr string) {
return u.OnAddress()

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