Compare commits

..

93 Commits

Author SHA1 Message Date
Dimitry Kolyshev
94458c5658 Merge remote-tracking branch 'origin/master' into 3389-querylog-export
# Conflicts:
#	CHANGELOG.md
2023-06-22 13:28:17 +04:00
Ainar Garipov
123ca87388 Pull request 1885: AG-23334-fix-snap-plan
Merge in DNS/adguard-home from AG-23334-fix-snap-plan to master

Squashed commit of the following:

commit 5d632d1d63c56911e005d0e772e82a509302e948
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 21 17:42:36 2023 +0300

    bamboo-specs: fix snap build; fmt
2023-06-21 17:47:16 +03:00
Ainar Garipov
994906fbd4 Pull request 1884: AG-23334-split-snap
Merge in DNS/adguard-home from AG-23334-split-snap to master

Squashed commit of the following:

commit 5a3d0f105d6930a0868f342821618a2a4acae282
Merge: bba693db6 06d465b0d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 21 17:10:15 2023 +0300

    Merge branch 'master' into AG-23334-split-snap

commit bba693db60fc7e154df3bc6bf186292ee9bc4ed5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 21 16:50:45 2023 +0300

    scripts/snap: fix docs; imp data

commit cb4a1d5bed147a41dda69b80b7ae6c3902c26538
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 21 14:03:48 2023 +0300

    all: fix scripts; imp docs

commit f88320b16ed7679e151a5358f4ac8e0212b4a827
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 18:52:21 2023 +0300

    all: split snap ci
2023-06-21 17:14:10 +03:00
Stanislav Chzhen
06d465b0d1 Pull request 1858: AG-22594-imp-whois
Merge in DNS/adguard-home from AG-22594-imp-whois to master

Squashed commit of the following:

commit 093feed53291d02469fb1bd8d99472597ebd5015
Merge: 956d20dc4 ca313521d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 21 12:42:40 2023 +0300

    Merge branch 'master' into AG-22594-imp-whois

commit 956d20dc473dcec90895b6f618fc56e96e9ff833
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 18:30:48 2023 +0300

    whois: imp code more

commit c771fd9c5e4d90e76d079a0d25ab097ab5652a42
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 15:05:45 2023 +0300

    whois: imp code

commit 21900fd468e10d9aee22149a6312b8596ff39810
Merge: 8dbe132c0 371261b2c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 11:34:06 2023 +0300

    Merge branch 'master' into AG-22594-imp-whois

commit 8dbe132c08d3ad4a63b0d4bdb9d00a5bc25971f4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 20 11:33:26 2023 +0300

    whois: imp code more

commit f5e761a260237579c67cbd48f01ea90499bff6b0
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 19 16:04:35 2023 +0300

    whois: imp code

commit 2780f7e16aacddad8736f83b77ef9bfa1271f8b1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 16 17:33:47 2023 +0300

    all: imp code

commit 1fc67016068b745a46b3d0d341ab14f9f5bdc9aa
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 16 17:29:19 2023 +0300

    whois: imp tests

commit 204761870764fb10feea20065d79dee8c321e70b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 16 11:55:37 2023 +0300

    all: upd deps

commit ded4f59498c5c544277b9c8e249567626547680e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 14 20:43:32 2023 +0300

    all: imp tests

commit 0eed9834ff9dd94d0788ce69d0bb0521fa725410
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 14 19:31:49 2023 +0300

    all: imp code

commit 9f867587c8ad87363b8c8b061ead536c1ec59c5d
Merge: 504e9484d 681c604c2
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 13 14:20:44 2023 +0300

    Merge branch 'master' into AG-22594-imp-whois

commit 504e9484dd84ab9d7c84a3f8399993d6422d3b67
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 13 14:18:06 2023 +0300

    all: imp cache

commit c492abe41ace7ad76fcd4e297c22b910a90fec30
Merge: db36adb9c 826b314f1
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 9 16:06:12 2023 +0300

    Merge branch 'master' into AG-22594-imp-whois

commit db36adb9c14ce92b3971db0d87ec313d5bcd787e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 9 15:53:33 2023 +0300

    all: add todo

commit 5cf192de9f93cd0d8521a3a6b4ded7f2bc5e0031
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 8 14:59:26 2023 +0300

    all: imp docs

commit 021aa3eb5b9476a93b4af5fc90cc9ccf014ca152
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Jun 5 18:35:25 2023 +0300

    all: imp naming

commit 4626c3a7fa3f2543501806c9fa1a19531547f394
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 2 17:41:00 2023 +0300

    all: imp tests

commit 1afcc9605ca176e4c7f76a03a2c996cf7d6bde13
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 2 12:44:32 2023 +0300

    all: imp docs

commit cdd0544ff1a63faed5ced3dae6bfb3b783e45428
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 1 17:21:37 2023 +0300

    all: add docs

... and 2 more commits
2023-06-21 12:53:53 +03:00
Ainar Garipov
ca313521dc Pull request 1881: 5913-fix-safesearch-ipv6-better
Updates #5913.

Squashed commit of the following:

commit 6bff5ee1b77ae1812e2803361e60ef12148da5c7
Merge: 0a6f49008 2902f030b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 14:14:47 2023 +0300

    Merge branch 'master' into 5913-fix-safesearch-ipv6-better

commit 0a6f49008ac1c786ba380cc3c9a4c2c0c1f60815
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 14:11:18 2023 +0300

    safesearch: imp tests

commit 3f9056d26816fb753a394a7bcf86f2ae1201d19c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jun 19 23:01:03 2023 +0300

    safesearch: fix ipv6 more
2023-06-20 14:48:36 +03:00
Ainar Garipov
2902f030be Pull request 1879: nextapi-opts
Merge in DNS/adguard-home from nextapi-opts to master

Squashed commit of the following:

commit 01f27e374785f47f41470126ddc17cf447e84dd7
Merge: 17d3b06e0 371261b2c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 13:43:08 2023 +0300

    Merge branch 'master' into nextapi-opts

commit 17d3b06e0551908b06be67233181ce4067b6c1cc
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 13:15:31 2023 +0300

    next: imp chlog

commit 19d5ea9db0ee077c55c9f1d54a07a3c6b56b4e2e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 20 12:58:48 2023 +0300

    cmd: typo

commit 082ad5b5fc634a1533127e428680ccf55c0811ab
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jun 19 22:49:16 2023 +0300

    cmd: imp api, docs, names

commit a49b3cbcc591f36530306c2e08cf1ea7dc8f6d30
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jun 19 17:13:50 2023 +0300

    next/cmd: add opt parsing
2023-06-20 14:11:34 +03:00
Dimitry Kolyshev
371261b2c6 Pull request: dnsforward: stat empty queries
Merge in DNS/adguard-home from 5910-stats-malformed-entry to master

Squashed commit of the following:

commit ea6718daf0d65dc4b13cd08430da7fdeb6f7fd5b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 17:34:50 2023 +0400

    all: imp docs

commit 5341c5b351c87556b91a7f692960edc76f44b21a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 16:47:13 2023 +0400

    all: docs

commit 1703c421f501484a80ddcf4ca1ba24f71fa5d225
Merge: f56b62490 d26c480d0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 16:46:13 2023 +0400

    Merge remote-tracking branch 'origin/master' into 5910-stats-malformed-entry

    # Conflicts:
    #	CHANGELOG.md

commit f56b62490c7033e1d0b620a9cb4ba8de64862de0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 14:49:43 2023 +0400

    all: docs

commit be954a8cab950d038c8cf08b95158069fa0747ba
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 14:44:05 2023 +0400

    querylog: empty queries

commit 0cda309d402156e750c7387e471da6795aa43bd6
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon Jun 19 14:26:41 2023 +0400

    dnsforward: stat empty queries
2023-06-20 10:36:20 +03:00
Ainar Garipov
d26c480d03 Pull request 1877: 5913-fix-safesearch-ipv6
Updates #5913.

Squashed commit of the following:

commit a0ab1320ea22dc1b4e2804ef2d14e0091daa6a1e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jun 19 15:23:44 2023 +0300

    all: fmt; typo

commit 3a2e561c535bbbd2b2eeeaa1a6f423bc123b1a6b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jun 19 15:16:28 2023 +0300

    all: fix safesearch for ipv6
2023-06-19 15:45:01 +03:00
Ainar Garipov
b6d00f774b Pull request 1875: next-gocognit
Merge in DNS/adguard-home from next-gocognit to master

Squashed commit of the following:

commit 554458a63b44e71244b4364168e6e9903b880638
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 16 19:58:14 2023 +0300

    all: add tool; typo

commit 1b97f93811d1ea826762cfa43fef49ae43e06939
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 16 19:49:40 2023 +0300

    all: add gocognit
2023-06-19 12:21:32 +03:00
Dimitry Kolyshev
6fea435d89 Merge remote-tracking branch 'origin/master' into 3389-querylog-export
# Conflicts:
#	CHANGELOG.md
2023-06-15 14:40:06 +04:00
Dimitry Kolyshev
05706bd7ea querylog: bench search 2023-06-15 14:38:44 +04:00
Stanislav Chzhen
d3ada9881a Pull request 1854: 951-blocked-services-schedule
Merge in DNS/adguard-home from 951-blocked-services-schedule to master

Squashed commit of the following:

commit 0f0770292f8aa9dc0dddc05edefacf6655f329b8
Merge: 2705fbcfb 7309a5335
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 14 15:00:56 2023 +0300

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

commit 2705fbcfba57392bcc0fa9b6e1f1dfdce9796963
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 14 14:56:01 2023 +0300

    schedule: imp field alignment

commit ff8fa040558e97192a5a2c91c1d5722c67d88b3d
Merge: f99936f36 9fda7bfd3
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Jun 13 11:49:15 2023 +0300

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

commit f99936f36be3453b50d772ce10bfdc1ad14879c5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 9 19:14:06 2023 +0300

    schedule: add tests

commit 8436c2c5675d5cc22a3554ded2ce4a49eeeefc91
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 8 20:10:03 2023 +0300

    schedule: imp code

commit 850a3d93e659e0584bd449cf5af3f13b36be9e62
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 8 18:57:23 2023 +0300

    schedule: imp tests

commit d54c42b782a4a806d2f35abbea1826ba6394a64c
Merge: 21dfa51ea 156c199bb
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 8 18:12:03 2023 +0300

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

commit 21dfa51ea7441c655ac39f2cbceeaa598d364bff
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Jun 8 18:02:47 2023 +0300

    all: add todo

commit d0d4532c8911fb6365f6af66ceb72a70b158b77d
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 7 18:54:44 2023 +0300

    all: upd chlog

commit dc1d55fa23c0ec8e7f7b7cd25d3d0cbf3e51e236
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 7 17:34:28 2023 +0300

    all: add tests

commit 601775307c2b23fa9d6cf2aa271793e8fd5f1797
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Jun 7 13:20:00 2023 +0300

    all: add schedule pkg

commit e0bcad0193a559a89f5f5052f5a985fa730d23be
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Jun 2 13:03:04 2023 +0300

    filtering: add test case

commit da7a7c20c84151ff83414cb5d576a91740a1be7e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 31 15:31:48 2023 +0300

    filtering: imp code

commit 9845a11cdae25eafe39a50f8cdc408fefe1fd746
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon May 29 17:46:24 2023 +0300

    filtering: add type check

commit f4bcea8ad90d584ceff236ccce4f246e391e0e33
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon May 29 17:37:25 2023 +0300

    all: imp code

commit 9de3a0f37eb65d0db2431c27dd4d69136c1485a7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon May 29 15:20:33 2023 +0300

    filtering: imp err msg

commit 1befab59cf2a12a3bc8296066ce1115dff5a8843
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon May 29 14:31:14 2023 +0300

    filtering: imp tests

commit 09506f924f363f1563009cec0c44ad40d08b8ddd
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri May 26 18:44:12 2023 +0300

    filtering: add tests

commit 36c42f523fcfe7fa6dca5f6f13e6c79f491c1ad5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri May 26 17:57:01 2023 +0300

    all: fix typos

commit 69399cd3ea17691ff0848baf43ff09b18b82114c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu May 25 18:50:51 2023 +0300

    all: upd chlog

... and 2 more commits
2023-06-14 15:08:57 +03:00
Ainar Garipov
7309a53356 Pull request 1874: upd-github-templates
Merge in DNS/adguard-home from upd-github-templates to master

Squashed commit of the following:

commit 713a98668e5ee1fa3d64881496043b499ad6ac09
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 13 20:10:35 2023 +0300

    all: imp github issue templates more

commit 308a3fcd5564d7536b6ae1192cd17c04b6752ea1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 13 19:38:28 2023 +0300

    all: imp issue tmpls
2023-06-14 13:09:09 +03:00
Dimitry Kolyshev
00327757e1 querylog: bench search 2023-06-14 12:07:16 +04:00
Dimitry Kolyshev
5f0e53ded7 home: write timeout middleware 2023-06-14 10:51:17 +04:00
Dimitry Kolyshev
5cd4ce766d Merge remote-tracking branch 'origin/master' into 3389-querylog-export 2023-06-14 10:08:11 +04:00
Dimitry Kolyshev
e695fd9885 querylog: timeout revert 2023-06-14 10:07:22 +04:00
Ainar Garipov
15b937d68b Pull request 1873: upd-chlog
Merge in DNS/adguard-home from upd-chlog to master

Squashed commit of the following:

commit feef14c20617f664832e4b99f9854e1fc7faba9f
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 13 17:47:44 2023 +0300

    all: upd chlog
2023-06-13 17:51:41 +03:00
Ainar Garipov
681c604c22 Pull request 1870: nextapi-frontend-fs
Merge in DNS/adguard-home from nextapi-frontend-fs to master

Squashed commit of the following:

commit 3ed959f21939cf5590c27426af46906cbffed502
Merge: e60bbdd04 9fda7bfd3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 13 13:37:00 2023 +0300

    Merge branch 'master' into nextapi-frontend-fs

commit e60bbdd04ce841c1aaaa198cc9dc85ae14799ffa
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 9 14:53:09 2023 +0300

    next: support frontend fs
2023-06-13 13:41:13 +03:00
Dimitry Kolyshev
c43053e7d2 querylog: timeout 2023-06-13 14:36:31 +04:00
Dimitry Kolyshev
86e25944b3 querylog: imp code 2023-06-13 13:08:15 +04:00
Dimitry Kolyshev
fd7260f6de Merge remote-tracking branch 'origin/master' into 3389-querylog-export
# Conflicts:
#	CHANGELOG.md
2023-06-13 10:38:17 +04:00
Eugene Burkov
9fda7bfd34 Pull request 1871: upd-proxy
Merge in DNS/adguard-home from upd-proxy to master

Updates #5872.

Squashed commit of the following:

commit fac8d1cdeb53cb5cfe867c7a3521bb5ca76331ef
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jun 9 19:18:35 2023 +0300

    all: fix chlog

commit 10f64ba5683422ecc3cb5d0bd6c679ed4e80e0cc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jun 9 19:14:07 2023 +0300

    all: log changes

commit 14410c4997c674a4f8a4adf8b77c1cf692131d24
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jun 9 18:48:09 2023 +0300

    all: upd proxy
2023-06-09 19:22:10 +03:00
Ainar Garipov
826b314f19 Pull request 1869: upd-chlog
Merge in DNS/adguard-home from upd-chlog to master

Squashed commit of the following:

commit dafdadea12f9c2324649ed06973d7bd818d4b815
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 8 20:04:38 2023 +0300

    all: upd chlog
2023-06-08 20:09:45 +03:00
Eugene Burkov
156c199bbb Pull request 1868: 5874-fix-tcp-fallback
Merge in DNS/adguard-home from 5874-fix-tcp-fallback to master

Updates #5783.
Updates #5784.

Squashed commit of the following:

commit b57ca38d21308d71c3a2dd5c5d4b87a31e845930
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jun 8 16:22:36 2023 +0300

    all: upd proxy
2023-06-08 16:28:01 +03:00
Ainar Garipov
040596f3a0 Pull request 1867: 5874-openwrt-setsockopt
Updates #5874.

Squashed commit of the following:

commit 297839fc2f95c6602fc5d571d382d2bd5c08b0cf
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 8 12:38:37 2023 +0300

    all: upd dnsproxy
2023-06-08 12:47:40 +03:00
Ainar Garipov
fde082af44 Pull request 1866: upd-chlog
Merge in DNS/adguard-home from upd-chlog to master

Squashed commit of the following:

commit 73e90eb68edeb82d99637b51bd99ff12cf590e25
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 7 20:45:45 2023 +0300

    all: upd chlog
2023-06-08 12:16:13 +03:00
Ainar Garipov
329e144b4f Pull request 1865: upd-all
Merge in DNS/adguard-home from upd-all to master

Squashed commit of the following:

commit daa594cef7a741d2d43ca0602274aa04b9d2ea80
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 7 19:37:56 2023 +0300

    all: upd flts, i18n, svcs, trackers
2023-06-07 19:42:19 +03:00
Ainar Garipov
367b319f10 Pull request 1864: upd-go
Merge in DNS/adguard-home from upd-go to master

Squashed commit of the following:

commit 688019427edac3346bbf49bb3d58a5df3c4f30d6
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jun 7 18:19:17 2023 +0300

    all: upd go, deps, tools
2023-06-07 19:18:23 +03:00
Eugene Burkov
d6fe0bd740 Pull request 1862: upd-proxy
Merge in DNS/adguard-home from upd-proxy to master

Squashed commit of the following:

commit b258697cdac6a6ac83c94814dbe8551c5685fa3b
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Jun 6 13:22:17 2023 +0300

    all: upd proxy
2023-06-06 13:30:25 +03:00
Eugene Burkov
ae7bd79a6c Pull request 1860: upd-proxy
Merge in DNS/adguard-home from upd-proxy to master

Squashed commit of the following:

commit abb1f27954bf8c20461d86b382f59479a75a9958
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Jun 2 16:57:53 2023 +0300

    all: upd dnsproxy
2023-06-02 17:19:44 +03:00
Dimitry Kolyshev
c591e46254 querylog: imp code 2023-06-02 15:26:04 +03:00
Dimitry Kolyshev
66d9ea7cca querylog: imp docs 2023-06-02 15:15:37 +03:00
Dimitry Kolyshev
dafc785845 querylog: imp code docs 2023-06-02 12:09:50 +03:00
Dimitry Kolyshev
e9b17891bb Merge remote-tracking branch 'origin/master' into 3389-querylog-export 2023-06-02 12:00:57 +03:00
Andrey Meshkov
0211424191 Pull request 1859: doc: add AdGuardian-Term to readme
Merge in DNS/adguard-home from fix-5858 to master

Closes #5858

Squashed commit of the following:

commit 3a5866bdff9bd087c6165b0356fa05bcd5e9d88d
Author: Andrey Meshkov <am@adguard.com>
Date:   Wed May 31 14:28:37 2023 +0300

    doc: add AdGuardian-Term to readme

    Closes #5858
2023-05-31 20:42:39 +03:00
Dimitry Kolyshev
0b27f048a7 querylog: imp code 2023-05-31 16:26:56 +03:00
Dimitry Kolyshev
649454e77b querylog: imp code 2023-05-31 15:11:33 +03:00
Dimitry Kolyshev
ca22d8524d all: imp docs 2023-05-31 15:11:15 +03:00
Dimitry Kolyshev
07f4f0474c all: imp docs 2023-05-31 12:06:13 +03:00
Dimitry Kolyshev
8813e135b6 querylog: export 2023-05-31 11:49:15 +03:00
Dimitry Kolyshev
f4f2c11eb9 all: export querylog docs 2023-05-29 13:29:41 +03:00
Dimitry Kolyshev
ea8d634f65 Pull request: dhcpd imp code
Merge in DNS/adguard-home from dhcpd-imp-code to master

Squashed commit of the following:

commit 413403c169bd3f6b5f2ed63b783d078dbb15e054
Merge: eed183850 0fec990bc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 26 12:46:25 2023 +0300

    Merge remote-tracking branch 'origin/master' into dhcpd-imp-code

commit eed1838502add1e16e5d3ada03778f21913fd5e5
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 26 12:16:46 2023 +0300

    dhcpd: imp docs

commit fa4fe036f7b1f2b49201bf0b5b904f99989082f0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 25 11:32:34 2023 +0300

    all: lint script

commit a4022b3d4bbfa709e5096397bbe64ea406c8a366
Merge: e08ff3a26 cbc7985e7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 25 11:29:57 2023 +0300

    Merge remote-tracking branch 'origin/master' into dhcpd-imp-code

    # Conflicts:
    #	scripts/make/go-lint.sh

commit e08ff3a26414e201d6e75608363db941fa2f5b39
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 15:43:11 2023 +0300

    dhcpd: imp code

commit 970b538f8ea94d3732d77bfb648e402a1d28ab06
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 15:40:36 2023 +0300

    dhcpd: imp code

commit 0e5916ddd7514af983e8557080d55d6aeb6fbbc0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 15:37:17 2023 +0300

    dhcpd: imp code

commit e06a6c6031b232e76ae2be3e3b8fe1a2ffa715e0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 16:40:09 2023 +0300

    dhcpd: imp code

commit eed4ff10ff1b29c71d70fb7978706efde89afee1
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 15:45:06 2023 +0300

    all: lint script

commit 87f84ace5f6f34dbc28befa8257d1d2492c5e0a4
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 15:44:23 2023 +0300

    dhcpd: imp code

commit a54c9929d51de1f1e6807d650fd08dd80ddbf147
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 14:29:42 2023 +0300

    dhcpd: imp code

commit 1bbea342f7f55587724aa9a29d9657e5ce75f5d8
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 14:12:09 2023 +0300

    dhcpd: imp code

commit 48fb4eff73683e799ddb3076afdcf7b067ca24b6
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 13:57:59 2023 +0300

    dhcpd: imp code

commit f6cd7fcb8d4c1c815a20875d777ea1eca2c8ea89
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 13:17:54 2023 +0300

    dhcpd: imp code

commit 2b91dc25bbaa16dba6d9389a4e2224cf91eb4554
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Tue May 23 12:57:46 2023 +0300

    dhcpd: imp code

commit 34f5dd58764080f6202fc9a1abd751a15dbf7090
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 15:31:39 2023 +0300

    dhcpd: imp code

commit 12ef0d225064a1b78adf7b2cfca21a8dba92ca8e
Merge: 6b62a7665 24b41100c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 13:03:41 2023 +0300

    Merge remote-tracking branch 'origin/master' into dhcpd-imp-code

commit 6b62a7665720b85398d65a1926518a63e6bb6403
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 12:55:43 2023 +0300

    dhcpd: imp code

commit 18c5cdf0480fac7711282027a64d58704c75af5f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 12:48:30 2023 +0300

    dhcpd: imp code

commit e7c1f4324cba3fe86cf56df6b971791a5a8790de
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 12:37:15 2023 +0300

    dhcpd: imp code

... and 1 more commit
2023-05-26 12:50:03 +03:00
Eugene Burkov
0fec990bcf Pull request 1856: fix-dhcpd-tags
Merge in DNS/adguard-home from fix-dhcpd-tags to master

Updates #5615.

Squashed commit of the following:

commit 386b5a67b07cf8b06f4e4003870fbf3db5dfc94d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri May 26 12:23:41 2023 +0300

    dhcpd: fix bsd tags
2023-05-26 12:31:55 +03:00
Stanislav Chzhen
a7680a593a Pull request 1855: fix-clients-races
Merge in DNS/adguard-home from fix-clients-races to master

Squashed commit of the following:

commit 2b29271b4c04b1c3046bd4cb3fb82f82fff0973b
Merge: 7f553feff cbc7985e7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu May 25 17:43:07 2023 +0300

    Merge branch 'master' into fix-clients-races

commit 7f553feff3aa46ae124a984776b60ed625148a1f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu May 25 16:25:43 2023 +0300

    home: imp docs more

commit aaf74666cf069fc6cdd5a5e64915fef5675e0382
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu May 25 13:57:42 2023 +0300

    home: imp docs

commit 50085085da3ae07b58bcc471906725339eec353e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 24 15:41:52 2023 +0300

    home: imp code more

commit 9dc001640ec4bef62b2ccaed307a9daeeb3a8d3a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue May 23 15:30:53 2023 +0300

    home: imp code

commit fa906e78ec0777c8c585622873addd0f4791554e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue May 23 14:17:16 2023 +0300

    home: fix clients races
2023-05-25 17:45:55 +03:00
Dimitry Kolyshev
cbc7985e75 Pull request: querylog imp code
Merge in DNS/adguard-home from querylog-imp-code to master

Squashed commit of the following:

commit a58ad36508a2355b686d314dec51ac0b5e357281
Merge: df5494f2c 941eb1dd7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 15:26:55 2023 +0300

    Merge remote-tracking branch 'origin/master' into querylog-imp-code

commit df5494f2c337736690a3c2a547c2d71858d0378f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 15:24:43 2023 +0300

    querylog: imp code

commit 8c3c2b76dd5858e7b107f222c112e9cde2477fb3
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 12:14:15 2023 +0300

    all: lint script

commit be04a4decfaf20a1649d32ecaab3c1c6bb205ffd
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 12:03:12 2023 +0300

    querylog: imp code

commit fe7beacff3a5cfcf2332c4998b9c65820284eaf7
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 11:57:33 2023 +0300

    querylog: imp docs

commit 2ae239c57d12524fbc092f582842af2ad726c1d0
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 11:46:54 2023 +0300

    querylog: imp code

commit 417216cefbf154fa870f8f43468f35e0e345971f
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 11:25:44 2023 +0300

    querylog: imp code

commit 514b6ee99113844a4e0dad30dc53703e3220c289
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 24 11:14:13 2023 +0300

    querylog: imp docs

commit 321351a3abb524208daacd5a3a7fbf5f07ab259d
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 16:38:31 2023 +0300

    querylog: imp code

commit ee91de5c43210b5bc213f933d411adb894d2e586
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 16:01:32 2023 +0300

    querylog: imp code

commit 862ff12177fb769d5cb2ec250eaee538dc91d70a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 15:07:24 2023 +0300

    querylog: imp code

commit cc62c1c4ae8b813d03ccf51b596ba1ebf44d9a1f
Merge: 37ace34e9 24b41100c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 13:09:10 2023 +0300

    Merge remote-tracking branch 'origin/master' into querylog-imp-code

commit 37ace34e91e5189bef6e774db960f40cdaa18270
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 11:23:08 2023 +0300

    querylog: imp code

commit 8417815a6349f10b5dbad410ce28aab98bc479fa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Mon May 22 11:08:29 2023 +0300

    querylog: imp docs

commit 4e5cde74d25713f78675aa3e18083b4fb5e619f3
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 16:41:34 2023 +0300

    querylog: imp code

commit 3494eab7006240f652a0217d305ac916bd6c3c83
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 16:13:08 2023 +0300

    all: lint script

commit 704534ce6278e7d9b1bef30a3acc4e59f25693bc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 16:12:04 2023 +0300

    querylog: imp code

commit 48510102a2fa5187f78067d2b9157dac62f8bb56
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 15:52:57 2023 +0300

    querylog: imp code

commit 89c273aea0e6758eb749a2d3bbaf1bc385a57797
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 15:40:50 2023 +0300

    querylog: imp code

commit 0057fe64553ad38de0fda10efb9d3512c9a00e45
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 19 13:54:46 2023 +0300

    querylog: imp code

... and 1 more commit
2023-05-24 16:33:15 +03:00
Ainar Garipov
941eb1dd73 Pull request 1851: upd-golang-ubuntu-2
Merge in DNS/adguard-home from upd-golang-ubuntu-2 to master

Squashed commit of the following:

commit 9fdd86a0d352cd3a046bca19d6acf0f549adfc53
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon May 22 17:36:06 2023 +0300

    all: upd golang-ubuntu again
2023-05-22 17:40:09 +03:00
Ainar Garipov
fc64e0089e Pull request 1850: upd-golang-ubuntu
Merge in DNS/adguard-home from upd-golang-ubuntu to master

Squashed commit of the following:

commit d4c79a1ddbf732f2d8500830b9f53f547ce33f23
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon May 22 16:29:48 2023 +0300

    all: upd golang-ubuntu
2023-05-22 16:34:41 +03:00
Ainar Garipov
24b41100c3 Pull request 1848: fix-snap
Merge in DNS/adguard-home from fix-snap to master

Squashed commit of the following:

commit 4a12b2709229150e1b896b71b2b0a99249f94fde
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Sat May 20 11:51:25 2023 +0300

    bamboo-specs: upd snap script
2023-05-22 12:43:01 +03:00
Stanislav Chzhen
b72a3d01b8 Pull request 1845: AG-21324-update-dhcp
Merge in DNS/adguard-home from AG-21324-update-dhcp to master

Squashed commit of the following:

commit 20499d71ffe62f34576f9328db5dc6fb5c929c28
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 17 14:23:09 2023 +0300

    dhcpd: imp tests

commit fa6add1410a98d1b9dfd833bcb20ef9fb7ff57ca
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue May 16 09:52:38 2023 +0100

    all: update dhcp
2023-05-17 15:16:02 +03:00
Dimitry Kolyshev
0393e41096 Pull request: 1577: rewrite edit http api
Merge in DNS/adguard-home from 1577-rewrite-edit to master

Squashed commit of the following:

commit d03bee2a14337d169eea950b3df18a447c02b422
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 12 12:54:15 2023 +0300

    filtering: imp tests

commit bd68320df6dc057d922d91551cd00c74ebfaad6c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Fri May 12 10:38:12 2023 +0300

    filtering: rewrite http tests

commit 0d8bbcd0194c0db89a6d4b45927669423c9bbb59
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 11 12:06:30 2023 +0300

    filtering: rewrite http tests

commit 29080384dd8fa80d5286d2fac1a4429d712bbafa
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 17:24:00 2023 +0300

    filtering: imp code

commit 96c6b1c98debfae565c5e6254746959a4307744e
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 16:56:32 2023 +0300

    filtering: imp code

commit b5d0c50ea11f9d829ba9d2b188fcc471a965e012
Merge: 5fa9e1c37 c77b2a0ce
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 16:37:19 2023 +0300

    Merge remote-tracking branch 'origin/master' into 1577-rewrite-edit

commit 5fa9e1c3714e107f893c03efa72227f3ed88691c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 16:35:19 2023 +0300

    filtering: imp code

commit dd9dce8fbf0ce4bd200f2fc2fbf580e025920cd5
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 13:06:43 2023 +0300

    docs: rewrite http update

commit 0c67b040e80787b084c4669bb20db8d6d145fc1b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 13:04:31 2023 +0300

    filtering: rewrite http update
2023-05-12 13:04:19 +03:00
Dimitry Kolyshev
c77b2a0ce5 Pull request: home: imp code
Merge in DNS/adguard-home from home-imp-code to master

Squashed commit of the following:

commit 459297e189c55393bf0340dd51ec9608d3475e55
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 11:42:34 2023 +0300

    home: imp code

commit ab38e1e80fed7b24fe57d4afdc57b70608f65d73
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 11:01:23 2023 +0300

    all: lint script

commit 7df68b128bf32172ef2e3bf7116f4f72a97baa2b
Merge: bcb482714 db52f7a3a
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 10 10:59:40 2023 +0300

    Merge remote-tracking branch 'origin/master' into home-imp-code

commit bcb482714780da882e69c261be08511ea4f36f3b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 13:48:27 2023 +0300

    all: lint script

commit 1c017f27715202ec1f40881f069a96f11f9822e8
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 13:45:25 2023 +0300

    all: lint script

commit ee3d427a7d6ee7e377e67c5eb99eebc7fb1e6acc
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 13:44:53 2023 +0300

    home: imp code

commit bc50430469123415216e60e178bd8e30fc229300
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 13:12:10 2023 +0300

    home: imp code

commit fc07e416aeab2612e68cf0e3f933aaed95931115
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 11:42:32 2023 +0300

    aghos: service precheck

commit a68480fd9c4cd6f3c89210bee6917c53074f7a82
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Thu May 4 11:07:05 2023 +0300

    home: imp code

commit 61b743a340ac1564c48212452c7a9acd1808d352
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 17:17:21 2023 +0300

    all: lint script

commit c6fe620510c4af5b65456e90cb3424831334e004
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 17:16:37 2023 +0300

    home: imp code

commit 4b2fb47ea9c932054ccc72b1fd1d11793c93e39c
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 16:55:44 2023 +0300

    home: imp code

commit 63df3e2ab58482920a074cfd5f4188e49a0f8448
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 16:25:38 2023 +0300

    home: imp code

commit c7f1502f976482c2891e0c64426218b549585e83
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 15:54:30 2023 +0300

    home: imp code

commit c64cdaf1c82495bb70d9cdcaf7be9eeee9a7c773
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 14:35:04 2023 +0300

    home: imp code

commit a50436e040b3a064ef51d5f936b879fe8de72d41
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 14:24:02 2023 +0300

    home: imp code

commit 2b66464f472df732ea27cbbe5ac5c673a13bc14b
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 14:11:53 2023 +0300

    home: imp code

commit 713ce2963c210887faa0a06e41e01e4ebbf96894
Author: Dimitry Kolyshev <dkolyshev@adguard.com>
Date:   Wed May 3 14:10:54 2023 +0300

    home: imp code
2023-05-10 16:30:03 +03:00
Stanislav Chzhen
db52f7a3ac Pull request 1841: AG-21462-safebrowsing-parental-http-tests
Merge in DNS/adguard-home from AG-21462-safebrowsing-parental-http-tests to master

Squashed commit of the following:

commit 22a83ebad08a27939a443530137a7c195f512ee4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 3 17:39:46 2023 +0300

    filtering: fix test

commit c3ca8b4987245cdd552f6f09759804e716bcae80
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 3 16:43:35 2023 +0300

    filtering: imp tests even more

commit 7643bfae350373b5b6dfb61b64e57da66c6ab952
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 3 16:17:42 2023 +0300

    filtering: imp tests more

commit 399c05ee4d479a727b61378b7a07158a568d0181
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed May 3 14:45:41 2023 +0300

    filtering: imp tests

commit f361df39e784ec9c5191666736a6c64b332928e8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue May 2 12:49:26 2023 +0300

    filtering: add tests
2023-05-03 19:52:06 +03:00
Stanislav Chzhen
381f2f651d Pull request 1837: AG-21462-imp-safebrowsing-parental
Merge in DNS/adguard-home from AG-21462-imp-safebrowsing-parental to master

Squashed commit of the following:

commit 85016d4f1105e21a407efade0bd45b8362808061
Merge: 0e61edade 620b51e3e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 27 16:36:30 2023 +0300

    Merge branch 'master' into AG-21462-imp-safebrowsing-parental

commit 0e61edadeff34f6305e941c1db94575c82f238d9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 27 14:51:37 2023 +0300

    filtering: imp tests

commit 994255514cc0f67dfe33d5a0892432e8924d1e36
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 27 11:13:19 2023 +0300

    filtering: fix typo

commit 96d1069573171538333330d6af94ef0f4208a9c4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 27 11:00:18 2023 +0300

    filtering: imp code more

commit c2a5620b04c4a529eea69983f1520cd2bc82ea9b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 26 19:13:26 2023 +0300

    all: add todo

commit e5dcc2e9701f8bccfde6ef8c01a4a2e7eb31599e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 26 14:36:08 2023 +0300

    all: imp code more

commit b6e734ccbeda82669023f6578481260b7c1f7161
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 25 15:01:56 2023 +0300

    filtering: imp code

commit 530648dadf836c1a4bd9917e0d3b47256fa8ff52
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 24 20:06:36 2023 +0300

    all: imp code

commit 49fa6e587052a40bb431fea457701ee860493527
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 24 14:57:19 2023 +0300

    all: rm safe browsing ctx

commit bbcb66cb03e18fa875e3c33cf16295892739e507
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 21 17:54:18 2023 +0300

    filtering: add cache item

commit cb7c9fffe8c4ff5e7a21ca912c223c799f61385f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 20 18:43:02 2023 +0300

    filtering: fix hashes

commit 153fec46270212af03f3631bfb42c5d680c4e142
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 20 16:15:15 2023 +0300

    filtering: add test cases

commit 09372f92bbb1fc082f1b1283594ee589100209c5
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 20 15:38:05 2023 +0300

    filtering: imp code

commit 466bc26d524ea6d1c3efb33692a7785d39e491ca
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 19 18:38:40 2023 +0300

    filtering: add tests

commit 24365ecf8c60512fdac65833ee603c80864ae018
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 19 11:38:57 2023 +0300

    filtering: add hashprefix
2023-04-27 16:39:35 +03:00
Eugene Burkov
620b51e3ea Pull request 1840: 5752-unspec-ipv6
Merge in DNS/adguard-home from 5752-unspec-ipv6 to master

Closes #5752.

Squashed commit of the following:

commit 654b808d17c6d2374b6be919515113b361fc5ff7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 21 18:11:34 2023 +0300

    home: imp docs

commit 28b4c36df790f1eaa05b11a1f0a7b986894d37dc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 21 16:50:16 2023 +0300

    all: fix empty bind host
2023-04-21 18:57:53 +03:00
Ainar Garipov
757ddb06f8 Pull request 1839: 5716-write-json
Updates #5716.

Squashed commit of the following:

commit 8cf7c4f404fffb646c9df8643924eb8dc1d8f49d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 19 18:09:35 2023 +0300

    aghhttp: write json properly
2023-04-19 18:15:17 +03:00
Ainar Garipov
d6043e2352 Pull request 1838: 5716-content-type
Updates #5716.

Squashed commit of the following:

commit 584e6771c82b92857e3c13232e942cad5c183682
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 19 14:54:43 2023 +0300

    all: fix content types
2023-04-19 14:58:56 +03:00
Eugene Burkov
aeec9a86e2 Pull request 1836: 5714-handle-zeroes-health
Merge in DNS/adguard-home from 5714-handle-zeroes-health to master

Updates #5714.

Squashed commit of the following:

commit 24faab01faf723e313050294b3a35e249c3cd3e3
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Apr 19 13:10:24 2023 +0300

    docker: add curly brackets

commit 67365d02856200685551a79aa23cf59df4a3484b
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 18 20:16:12 2023 +0300

    docker: imp zeroes check
2023-04-19 13:48:59 +03:00
Eugene Burkov
584182e264 Pull request 1835: bootstrap-plain
Merge in DNS/adguard-home from bootstrap-plain to master

Updates AdguardTeam/dnsproxy#324.

Squashed commit of the following:

commit bd5d569dc26154985857977e81650eb0a51559a5
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 18 17:41:53 2023 +0300

    querylog: rm proxyutil dep

commit 9db4053555e06eba264f7d3e6c75c747f8d73b56
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Apr 18 17:34:29 2023 +0300

    all: upd proxy
2023-04-18 17:52:22 +03:00
Ainar Garipov
96cd512d32 Pull request 1834: upd-chlog
Merge in DNS/adguard-home from upd-chlog to master

Squashed commit of the following:

commit 0afc6fe1d2500a54ae9cea50249f6c4904f418db
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 18 17:00:10 2023 +0300

    all: upd chlog
2023-04-18 17:03:27 +03:00
Ainar Garipov
11898a3f73 Pull request 1833: upd-all
Merge in DNS/adguard-home from upd-all to master

Squashed commit of the following:

commit e5acaddd5cec1a53f2aa1f48d16af53052341d31
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 18 15:43:36 2023 +0300

    all: upd i18n, svcs, tools
2023-04-18 15:49:03 +03:00
Stanislav Chzhen
a91a257b15 Pull request 1817: AG-20352-imp-leases-db
Merge in DNS/adguard-home from AG-20352-imp-leases-db to master

Squashed commit of the following:

commit 2235fb4671bb3f80c933847362cd35b5704dd18d
Merge: 0c4d76d4f 76a74b271
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 18 15:09:34 2023 +0300

    Merge branch 'master' into AG-20352-imp-leases-db

commit 0c4d76d4f6222ae06c568864d366df866dc55a54
Merge: e586b82c7 4afd39b22
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 18 11:07:27 2023 +0300

    Merge branch 'master' into AG-20352-imp-leases-db

commit e586b82c700c4d432e34f36400519eb08b2653ad
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 18 11:06:40 2023 +0300

    dhcpd: imp docs

commit 411d4e6f6e36051bf6a66c709380ed268c161c41
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 17 16:56:56 2023 +0300

    dhcpd: imp code

commit e457dc2c385ab62b36df7f96c949e6b90ed2034a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 17 14:29:29 2023 +0300

    all: imp code more

commit c2df20d0125d368d0155af0808af979921763e1f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 14 15:07:53 2023 +0300

    all: imp code

commit a4e9ffb9ae769c828c22d62ddf231f7bcfea14db
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 12 19:19:35 2023 +0300

    dhcpd: fix test more

commit 138d89414f1a89558b23962acb7174dce28346d9
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 12 18:08:29 2023 +0300

    dhcpd: fix test

commit e07e7a23e7c913951c8ecb38c12a3345ebe473be
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 12 17:22:27 2023 +0300

    all: upd chlog

commit 1b6a76e79cf4beed9ca980766ce97930b375bfde
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 12 13:24:11 2023 +0300

    all: migrate leases db
2023-04-18 15:12:11 +03:00
Artem Krisanov
76a74b271b AG-21485 - Login theme bugfix.
Squashed commit of the following:

commit 521aedc5bc
Merge: 40ff26ea2 1842f7d88
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 18 14:27:28 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into AG-21485

commit 40ff26ea21
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 18 14:11:28 2023 +0300

    Login theme bugfix.
2023-04-18 14:31:20 +03:00
Ainar Garipov
1842f7d888 Pull request 1831: home: imp depr option doc
Merge in DNS/adguard-home from imp-option-doc to master

Squashed commit of the following:

commit 267410fcc2c9e757c7d8fb7d9059a709932dda9d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Apr 17 14:30:12 2023 +0300

    home: imp depr option doc
2023-04-18 14:18:28 +03:00
Artem Krisanov
4afd39b22f AG-21136 - Added local storage theme key.
Updates#5444

Squashed commit of the following:

commit 7b0b108f41ebb5e98861cdd20029c12d3a3fc5f4
Merge: 38df28db0 e43ba1788
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Mon Apr 17 15:58:15 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into 5444-white-screen

commit 38df28db0739e47d3fb605f648fa493b58709d77
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Fri Apr 14 17:54:00 2023 +0300

    Deleted useless tag.

commit 78ef9d911ccf74b69a9ae5626ea8f31cb9338ae0
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Fri Apr 14 17:53:17 2023 +0300

    Set initial body data-theme.

commit f470b3aa79500edd0726b7ed37e6e5940b6ce3ff
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Thu Apr 13 16:42:25 2023 +0300

    Revert login changes.

commit 7c4734ed02a670a59d0b9ff04e06bc1d396223a8
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Thu Apr 13 15:51:24 2023 +0300

    Added setting theme into html.Changed overlay background color to variable.

commit a3743be0e69489489755db8ff55541b9a6281300
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Wed Apr 12 17:58:47 2023 +0300

    Added local storage theme key.
2023-04-17 16:07:20 +03:00
Artem Krisanov
e43ba17884 AG-21212 - Custom logs and stats retention
Updates#3404

Squashed commit of the following:

commit b68a1d08b0676ebb7abbb13c9274c8d509cd6eed
Merge: 81265147 6d402dc8
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Mon Apr 17 15:48:33 2023 +0300

    Merge master

commit 81265147b5613be11a6621a416f9588c0e1c0ef5
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Thu Apr 13 10:54:39 2023 +0300

    Changed query log 'retention' --> 'rotation'.

commit 02c5dc0b54bca9ec293ee8629d769489bc5dc533
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Wed Apr 12 13:22:22 2023 +0300

    Custom inputs for query log and stats configs.

commit 21dbfbd8aac868baeea0f8b25d14786aecf09a0d
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 11 18:12:40 2023 +0300

    Temporary changes.
2023-04-17 15:57:57 +03:00
Eugene Burkov
6d402dc86c Pull request 1830: 5712-rollback-dhcp
Merge in DNS/adguard-home from 5712-rollback-dhcp to master

Updates #5712.

Squashed commit of the following:

commit 3d53a6385ad08dfad0b7ac28bb057cf25608554d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 14 16:30:18 2023 +0300

    dhcpd: imp import

commit 86bd55b0225b5d9067bd0bf9e6def1e52dd27124
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 14 16:26:41 2023 +0300

    all: return todo

commit 629c548989a464a9cf461fffc0815b99a00c4851
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 14 16:24:10 2023 +0300

    all: log changes

commit e4c369e55cbcc7c73d73d8df333996862e1e146a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Apr 14 16:03:03 2023 +0300

    dhcpd: revert raw for darwin
2023-04-14 16:58:07 +03:00
Stanislav Chzhen
18acdf9b09 Pull request 1809: 4299-querylog-stats-clients-api
Merge in DNS/adguard-home from 4299-querylog-stats-clients-api to master

Squashed commit of the following:

commit 066100a7869d7572c4ae65b3c7b1487ac50baf15
Merge: 95bc00c0 5da77514
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 14 13:57:30 2023 +0300

    Merge branch 'master' into 4299-querylog-stats-clients-api

commit 95bc00c0b3d05b262ee0b90be9757e61cac0778c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 13 11:48:39 2023 +0300

    all: fix typo

commit 4b868da48f0c976d204346e40ba948803be6397f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 13 11:42:52 2023 +0300

    all: fix text label

commit 7a3ba5c7f688bd53cf761b5e8e614fbe251bd006
Merge: 315256e3 6c8d89a4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 13 11:34:59 2023 +0300

    Merge branch 'master' into 4299-querylog-stats-clients-api

commit 315256e3f3861b5116962f7c47384b7c72e41813
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 11 19:07:18 2023 +0300

    all: ignore search, unit

commit 28c6ffec9558e7c38d7bd12055eabddb8f5675c2
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 11 15:08:35 2023 +0300

    Added 'Protection' and 'Query Log and statistics' sections to client settings. Added checkboxes to ignore client in (query log/statistics)

commit 2657bd2b820d8b2b3d71d23e4545c867b9ae6cdf
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 10 17:28:59 2023 +0300

    all: add todo

commit e151fcbc0c36d8e6a5c091fbf374bf0e35804699
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 10 15:15:46 2023 +0300

    openapi: imp docs

commit 31875cbbd1bd09a73baa3636d0cc242b5ac35059
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 10 13:02:31 2023 +0300

    all: add querylog stats client ignore api
2023-04-14 15:25:04 +03:00
Ainar Garipov
5da7751463 Pull request 1829: 5725-querylog-orig-ans
Closes #5725.

Squashed commit of the following:

commit a9e5fc47fc0a752f427e006ab1c59e260239ee5a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 13 20:25:12 2023 +0300

    querylog: fix orig ans assignment
2023-04-13 20:51:57 +03:00
Ainar Garipov
7631ca4ab3 Pull request 1828: AG-21377-default-safe-search
Merge in DNS/adguard-home from AG-21377-default-safe-search to master

Squashed commit of the following:

commit 35c66b97c787d02fe6f2ffb6902dcd9b6f9b9569
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 13 20:05:13 2023 +0300

    home: fix default safe search svcs
2023-04-13 20:17:59 +03:00
Ainar Garipov
c6d4f2317e Pull request 1827: upd-deps
Merge in DNS/adguard-home from upd-deps to master

Squashed commit of the following:

commit 4892dc4ed6df76d8733e6799744b095c5db1db6c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 13 18:22:10 2023 +0300

    all: upd dnscrypt, skel
2023-04-13 19:13:11 +03:00
Eugene Burkov
0ea224a9e4 Pull request 1826: 5714 fix-docker-health
Merge in DNS/adguard-home from 5714-fix-docker-health to master

Updates #5714.

Squashed commit of the following:

commit 61251bffd7a21f1ceb867cc89de0a171645ca4c2
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Apr 13 16:45:41 2023 +0300

    docker: use localhost for unspecified
2023-04-13 17:40:45 +03:00
Ainar Garipov
d78a3edb22 Pull request 1825: 5721-dnscrypt-panic
Updates #5721.

Squashed commit of the following:

commit edf7801e2028aa31d59440158d3fcf2ef95d7013
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 13 15:44:18 2023 +0300

    all: fix dnscrypt panic
2023-04-13 15:50:01 +03:00
Stanislav Chzhen
bbbdea2635 Pull request 1824: fix-chlog
Merge in DNS/adguard-home from fix-chlog to master

Squashed commit of the following:

commit 98e8f5e1436f6c2049f002a4c2211dd2a2e9920c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 13 12:39:11 2023 +0300

    all: fix chlog more

commit deef876541877bc7773e596b39f40c3341ae903a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 13 11:57:10 2023 +0300

    all: fix chlog
2023-04-13 13:07:50 +03:00
Artem Krisanov
6c8d89a4da AG-20835 - Deleted unused methods and variable.
Squashed commit of the following:

commit 3d633703fc60e42d26ccf3b5697370c49ffa1a82
Merge: 09119e2e f082312e
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Thu Apr 13 10:58:31 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into AG-20835

commit 09119e2ec6f3116986d3ddeb48ee2eb18c1cd9d7
Merge: 085bbb5c 67d8b7df
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Wed Apr 12 14:55:22 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into AG-20835

commit 085bbb5cabb14d5388e45ab2022840d44ae42874
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Wed Apr 12 14:12:28 2023 +0300

    Deleted unused methods and variable.
2023-04-13 11:07:13 +03:00
Ainar Garipov
f082312e49 Pull request 1822: upd-deps
Merge in DNS/adguard-home from upd-deps to master

Squashed commit of the following:

commit 7ce7532d4a914c678557a6cd9e31c707da8a1a66
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 12 17:14:58 2023 +0300

    all: upd deps
2023-04-12 17:20:29 +03:00
Ainar Garipov
ea03d1af93 Pull request 1821: all: upd chlog
Merge in DNS/adguard-home from upd-chlog to master

Squashed commit of the following:

commit a1a550ec26227c2050eb192e1ae53577d699e0ea
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 12 16:50:53 2023 +0300

    all: upd chlog
2023-04-12 16:56:33 +03:00
Ainar Garipov
67d8b7df90 Pull request 1820: upd-all
Merge in DNS/adguard-home from upd-all to master

Squashed commit of the following:

commit 88aee29c6685816eaef8ff63af380d609f308ead
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 12 14:25:19 2023 +0300

    all: upd i18n, svcs
2023-04-12 14:29:56 +03:00
Ainar Garipov
b23ea0a690 Pull request 1816: 5704-rm-endian
Updates #5704.

Squashed commit of the following:

commit 927faf8c3ae0a5deea651ea4249a90ffc80a21c9
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 11 20:02:52 2023 +0300

    all: rm our copy of endian
2023-04-11 20:07:39 +03:00
Ainar Garipov
a186b5c436 Pull request 1815: 5701-log-ip
Updates #5701.

Squashed commit of the following:

commit 332530cbae602e9b0e4c89351bde6b0da017fc67
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 11 18:56:27 2023 +0300

    home: imp docs

commit 35a649ffed9ca736e63842f077411c5f5cbb57f3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 11 18:27:25 2023 +0300

    home: fix login attempt logging
2023-04-11 19:43:38 +03:00
Artem Krisanov
6da7392345 AG-20897 - Fixed bug with checkbox's actual state on filter adding.
Updates#5647

Squashed commit of the following:

commit 610f4dae6f7e0e2576669489030eb43bd06d6da6
Merge: fb0c0472 c1924a8b
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 11 18:16:44 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into 5647-filter-adding

commit fb0c04725c41707ca6a1e4ce36a8e17a6898ee27
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Mon Apr 10 16:51:45 2023 +0300

    Fixed bug with checkbox's actual state on filter adding.
2023-04-11 18:39:46 +03:00
Artem Krisanov
c1924a8b8a AG-21184 - Added transforming protection_disabled_duration field value from 0 to null;
Updates#5689

Squashed commit of the following:

commit 4de24101622c8c76be8e2f1eb1b670c36a1e74c8
Merge: fd9ee1fb 0376afb3
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 11 18:12:57 2023 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home into 5689-protection-status

commit fd9ee1fba4e507875dd8b2b605d14cd78aa4e918
Author: Artem Krisanov <a.krisanov@adguard.com>
Date:   Tue Apr 11 14:10:44 2023 +0300

    Added transforming protection_disabled_duration field value from 0 to null;
2023-04-11 18:16:24 +03:00
Ainar Garipov
0376afb38e Pull request 1814: AG-21291-web-races
Merge in DNS/adguard-home from AG-21291-web-races to master

Squashed commit of the following:

commit 1134013f928aa5e186db3b6d0450e425cb053e9c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 11 16:52:52 2023 +0300

    home: fix web api races
2023-04-11 17:22:51 +03:00
Stanislav Chzhen
230d7b8c17 Pull request 1813: fix-chlog
Merge in DNS/adguard-home from fix-chlog to master

Squashed commit of the following:

commit 47f6b33780d7c1d99a6fc36ddf435db068938174
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Apr 11 16:38:04 2023 +0300

    all: fix chlog
2023-04-11 16:43:47 +03:00
Ainar Garipov
950ecb1f5e Pull request 1812: AG-21286
Merge in DNS/adguard-home from AG-21286 to master

Squashed commit of the following:

commit 587b4a3704fd63aa3da6c1be83f8a49bf4e27b00
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Apr 11 14:15:05 2023 +0300

    all: fix negative pause duration
2023-04-11 15:02:29 +03:00
Ildar Kamalov
9e14d5f99f Pull request: fix missing icons on login page
Updates #5620

Squashed commit of the following:

commit 61969c83c3dd6bd6688f0aabc9d6160b53701866
Author: Ildar Kamalov <ik@adguard.com>
Date:   Mon Apr 10 14:50:47 2023 +0300

    AG-20691 fix theme select on login page

commit c87b6c37284021f33f440dcd31be5b653e8e689d
Merge: aa744756 89bf3721
Author: Ildar Kamalov <ik@adguard.com>
Date:   Mon Apr 10 14:21:01 2023 +0300

    Merge branch 'master' into AG-20691

commit aa744756d18d9ed3bc7f60108235d8403e7cb5e0
Author: Ildar Kamalov <ik@adguard.com>
Date:   Fri Apr 7 15:53:38 2023 +0300

    AG-20691 fix missing icons on login page
2023-04-10 17:12:52 +03:00
Stanislav Chzhen
89bf3721b5 Pull request 1800: AG-20352-dhcpd-lease-is-static
Merge in DNS/adguard-home from AG-20352-dhcpd-lease-is-static to master

Squashed commit of the following:

commit e4f4278a7ffa0f084ed41472dd3e7de4466c9f50
Merge: b6e3b62e 15bba281
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Apr 10 11:13:05 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-is-static

commit b6e3b62ed4e7bc17fc3fdd2f4faa940a7f4334c2
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 6 15:20:42 2023 +0300

    dhcpd: imp naming

commit e2d9ed0832b329f4cebcf8cbfcfadc5755fe441b
Merge: ecd244a6 10bffd89
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 5 16:53:55 2023 +0300

    Merge branch 'master' into AG-20352-dhcpd-lease-is-static

commit ecd244a60841d3cb96d292da688e353650baf645
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 5 16:53:15 2023 +0300

    dhcpd: add lease json form

commit 9ebc246ed4711ff46091326a7cb35ea90b880cff
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 5 13:11:25 2023 +0300

    dhcpd: imp code

commit fc3d0cdaebf9e32e73d57e80296f9891896259cf
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 5 13:00:59 2023 +0300

    all: fix json

commit d722578543b98b1fefabecd6486f3bc102263d71
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Apr 5 12:23:34 2023 +0300

    dhcpd: add lease is static
2023-04-10 11:17:05 +03:00
Ainar Garipov
15bba281ee Pull request 1807: upd-golibs
Merge in DNS/adguard-home from upd-golibs to master

Squashed commit of the following:

commit cde42a72c2140245f345681cbb936ed3bc4645a1
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Apr 7 13:57:02 2023 +0300

    all: upd golibs, use hdrs
2023-04-07 14:21:37 +03:00
Stanislav Chzhen
f9fe3172c4 Pull request 1791: 4299-querylog-stats-clients
Merge in DNS/adguard-home from 4299-querylog-stats-clients to master

Squashed commit of the following:

commit 33b80b67224f7c1a15bee8e6a23d9d5bab6ac629
Merge: 61964fdd 5d5a7295
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 7 12:43:22 2023 +0300

    Merge branch 'master' into 4299-querylog-stats-clients

commit 61964fdd02221abbddedf2d6d02bb0bce6845362
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 7 12:42:01 2023 +0300

    dnsforward: imp code

commit 7382168500bab6ca7494d39aabfc2d7bfceb5d24
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Apr 7 11:13:07 2023 +0300

    all: imp code, chlog

commit c7852902f635af6c296dcb6735f7b0bfb83f4e87
Merge: aa4dc0a5 a55cbbe7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 6 14:34:24 2023 +0300

    Merge branch 'master' into 4299-querylog-stats-clients

commit aa4dc0a54e95bc5b24718ec158340b631a822801
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Apr 6 12:54:02 2023 +0300

    all: imp code

commit dd541f0cd7ecbf0afcf10ccbd130fd1d1fa4c1c4
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 31 13:01:53 2023 +0300

    querylog: fix typo

commit d2c8fdb35b04d27c8957fa027882fde704cc07be
Merge: 83d0baa1 2eb3bf6e
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 31 12:36:49 2023 +0300

    Merge branch 'master' into 4299-querylog-stats-clients

commit 83d0baa1f1202f9c62d4be2041d7aed12ee9ab2c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Fri Mar 31 12:35:15 2023 +0300

    all: add tests

commit a459f19f25cf9646d145813fe7834b2d9979c516
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Wed Mar 29 16:51:53 2023 +0300

    all: add clients querylog stats ignore
2023-04-07 13:17:40 +03:00
Ainar Garipov
5d5a729569 Pull request 1806: 5661-fix-protection-update-lock
Updates #5661.

Squashed commit of the following:

commit 02e83c75c8f44f084c0cb8d33b7d6a524c8c1b0e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 19:28:17 2023 +0300

    dnsforward: imp logs

commit 0f27265fc94f0e3b8e2dee79dbf9ab5344416c61
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 19:18:19 2023 +0300

    dnsforward: imp locks
2023-04-06 19:33:25 +03:00
Ainar Garipov
b1120221c7 Pull request 1805: imp-pprof
Merge in DNS/adguard-home from imp-pprof to master

Squashed commit of the following:

commit 2d56e0820fd26720c87978d0096405257100f3f3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 15:10:12 2023 +0300

    home: imp rate

commit 97611a26e224f354d42ea16f3193c6cb72de3a48
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 15:03:33 2023 +0300

    home: imp pprof block, mutex profiles
2023-04-06 15:14:30 +03:00
Ainar Garipov
f553eee842 Pull request 1804: newline-lint
Merge in DNS/adguard-home from newline-lint to master

Squashed commit of the following:

commit 2fc0b662b9ac9d954275c5ebe8c140be4cd365be
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 14:16:14 2023 +0300

    client: rm line

commit 10246727179a84094edd17fad5cd6f0a5c38b821
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 13:51:06 2023 +0300

    all: add newline lint
2023-04-06 14:21:46 +03:00
Ainar Garipov
61b4043775 Pull request 1803: 5685-fix-safe-search
Updates #5685.

Squashed commit of the following:

commit 5312147abfa0914c896acbf1e88f8c8f1af90f2b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Apr 6 14:09:44 2023 +0300

    safesearch: imp tests, logs

commit 298b5d24ce292c5f83ebe33d1e92329e4b3c1acc
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 5 20:36:16 2023 +0300

    safesearch: fix filters, logging

commit 63d6ca5d694d45705473f2f0410e9e0b49cf7346
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 5 20:24:47 2023 +0300

    all: dry; fix logs

commit fdbf2f364fd0484b47b3161bf6f4581856fdf47b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Apr 5 20:01:08 2023 +0300

    all: fix safe search update
2023-04-06 14:12:50 +03:00
233 changed files with 9995 additions and 4218 deletions

View File

@@ -10,52 +10,58 @@
- 'label': >
I have checked the
[Wiki](https://github.com/AdguardTeam/AdGuardHome/wiki) and
[Discussions](https://github.com/AdguardTeam/AdGuardHome/discussions)
[Discussions](https://github.com/AdguardTeam/AdGuardHome/discussions/categories/q-a)
and found no answer
'required': true
- 'label': >
I have searched other issues and found no duplicates
'required': true
- 'label': >
I want to report a bug and not ask a question
I want to report a bug and not [ask a question or ask for
help](https://github.com/AdguardTeam/AdGuardHome/discussions/categories/q-a)
'required': true
- 'label': >
I have set up AdGuard Home correctly and [configured clients to
use it](https://github.com/AdguardTeam/AdGuardHome/wiki/Clients).
(Use the
[Discussions](https://github.com/AdguardTeam/AdGuardHome/discussions/categories/q-a)
for help with installing and configuring clients.)
'required': true
'id': 'prerequisites'
'type': 'checkboxes'
- 'attributes':
'description': 'On which operating system type does the issue occur?'
'label': 'Operating system type'
'description': 'On which Platform does the issue occur?'
'label': 'Platform (OS and CPU architecture)'
'options':
- 'FreeBSD'
- 'Linux, OpenWrt'
- 'Linux, Other (please mention the version in the description)'
- 'macOS (aka Darwin)'
- 'OpenBSD'
- 'Windows'
- 'Other (please mention in the description)'
- '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'
- 'Custom (please mention in the description)'
'id': 'os'
'type': 'dropdown'
'validations':
'required': true
- 'attributes':
'description': 'On which CPU architecture does the issue occur?'
'label': 'CPU architecture'
'options':
- 'AMD64'
- 'x86'
- '64-bit ARM'
- 'ARMv5'
- 'ARMv6'
- 'ARMv7'
- '64-bit MIPS'
- '64-bit MIPS LE'
- '32-bit MIPS'
- '32-bit MIPS LE'
- '64-bit PowerPC LE'
- 'Other (please mention in the description)'
'id': 'arch'
'type': 'dropdown'
'validations':
'required': true
- 'attributes':
'description': 'How did you install AdGuard Home?'
'label': 'Installation'
@@ -63,7 +69,7 @@
- 'GitHub releases or script from README'
- 'Docker'
- 'Snapcraft'
- 'Custom port'
- 'Custom package (OpenWrt, HomeAssistant, etc; please mention in the description)'
- 'Other (please mention in the description)'
'id': 'install'
'type': 'dropdown'
@@ -89,21 +95,55 @@
'validations':
'required': true
- 'attributes':
'description': 'Please describe the bug'
'label': 'Description'
'description': >
Please describe what you did. An `nslookup` or a `dig` command is
the best way. For crashes, please provide a full failure log.
'label': 'Action'
'value': |
#### What did you do?
#### Expected result
#### Actual result
#### Screenshots (if applicable)
#### Additional information
'id': 'description'
```sh
nslookup -debug -type=a 'www.example.com' '$YOUR_AGH_ADDRESS'
```
'id': 'failing_action'
'type': 'textarea'
'validations':
'required': true
'description': 'File a bug report'
- 'attributes':
'description': >
What did you expect to see? Please add a description and/or
screenshots, if applicable.
'label': 'Expected result'
'placeholder': >
What did you expect to see?
'id': 'expected'
'type': 'textarea'
'validations':
'required': true
- 'attributes':
'description': >
What happened instead? Please add a description and/or screenshots,
if applicable.
'label': 'Actual result'
'placeholder': >
What did you see instead?
'id': 'result'
'type': 'textarea'
'validations':
'required': true
- 'attributes':
'description': >
Please add additional information, such as non-standard OS or port,
here. You can also put screenshots here, if applicable. For
example, it is better to copy and paste text from a terminal instead
of posting a screenshot of the terminal.
'label': 'Additional information and/or screenshots'
'placeholder': >
Additional OS information, screenshots of the UI, etc.
'id': 'additional'
'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.
'name': 'Bug'

View File

@@ -23,19 +23,32 @@
'id': 'prerequisites'
'type': 'checkboxes'
- 'attributes':
'description': 'Please describe the request'
'label': 'Description'
'value': |
#### What problem are you trying to solve?
#### Proposed solution
#### Alternatives considered
#### Additional information
'id': 'description'
'description': 'Please describe the problem you are trying to solve'
'label': 'The problem'
'placeholder': >
Please describe the problem you are trying to solve
'id': 'problem'
'type': 'textarea'
'validations':
'required': true
- 'attributes':
'description': 'What feature are you proposing to solve this problem?'
'label': 'Proposed solution'
'placeholder': >
What feature are you proposing to solve this problem?
'id': 'proposed_solution'
'type': 'textarea'
'validations':
'required': true
- 'attributes':
'label': 'Alternatives considered and additional information'
'placeholder': >
Are there any other ways to solve the problem?
'id': 'additional'
'type': 'textarea'
'validations':
'required': false
'description': 'Suggest a feature or an enhancement for AdGuard Home'
'labels':
- 'feature request'
'name': 'Feature request or enhancement'

20
.github/PULL_REQUEST_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,20 @@
Before submitting a PR please make sure that:
1. You have discussed your solution in an issue and have got an
approval from a maintainer.
2. This isn't a localization fix; please send those to our
[CrowdIn](https://crowdin.com/project/adguard-applications/en#/adguard-home)
page.
3. Your code follows our
[code guidelines](https://github.com/AdguardTeam/CodeGuidelines/blob/master/Go/Go.md).
Add a short description here. The description should include:
1. Which issue this PR closes (`Closes #NNNN.`) or updates (`Updates
#NNNN.`).
2. A short description of how the change achieves that.
Do not forget to remove these instructions.

View File

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

View File

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

View File

@@ -0,0 +1,18 @@
'name': 'potential-duplicates'
'on':
'issues':
'types':
- 'opened'
'jobs':
'run':
'runs-on': 'ubuntu-latest'
'steps':
- 'uses': 'wow-actions/potential-duplicates@v1'
'with':
'GITHUB_TOKEN': '${{ secrets.GITHUB_TOKEN }}'
'state': 'all'
'threshold': 0.6
'comment': |
Potential duplicates: {{#issues}}
* [#{{ number }}] {{ title }} ({{ accuracy }}%)
{{/issues}}

1
.gitignore vendored
View File

@@ -21,7 +21,6 @@
/snapcraft_login
AdGuardHome*
coverage.txt
leases.db
node_modules/
!/build/gitkeep

View File

@@ -14,17 +14,195 @@ and this project adheres to
<!--
## [v0.108.0] - TBA
## [v0.107.28] - 2023-04-12 (APPROX.)
## [v0.107.33] - 2023-06-28 (APPROX.)
See also the [v0.107.28 GitHub milestone][ms-v0.107.28].
See also the [v0.107.33 GitHub milestone][ms-v0.107.33].
[ms-v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/milestone/64?closed=1
[ms-v0.107.33]: https://github.com/AdguardTeam/AdGuardHome/milestone/68?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.
- The ability to edit rewrite rules via `PUT /control/rewrite/update` HTTP API
([#1577]).
### Changed
#### Configuration Changes
In this release, the schema version has changed from 20 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:
```yaml
# BEFORE:
'blocked_services':
- id_1
- id_2
# AFTER:
'blocked_services':
'ids':
- id_1
- id_2
'schedule':
'time_zone': 'Local'
'sun':
'start': '0s'
'end': '24h'
'mon':
'start': '10m'
'end': '23h30m'
'tue':
'start': '20m'
'end': '23h'
'wed':
'start': '30m'
'end': '22h30m'
'thu':
'start': '40m'
'end': '22h'
'fri':
'start': '50m'
'end': '21h30m'
'sat':
'start': '1h'
'end': '21h'
```
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`.
### Fixed
- 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`
records ([#5913]).
[#951]: https://github.com/AdguardTeam/AdGuardHome/issues/951
[#1577]: https://github.com/AdguardTeam/AdGuardHome/issues/1577
[#3389]: https://github.com/AdguardTeam/AdGuardHome/issues/3389
[#5910]: https://github.com/AdguardTeam/AdGuardHome/issues/5910
[#5913]: https://github.com/AdguardTeam/AdGuardHome/issues/5913
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->
## [v0.107.32] - 2023-06-13
### Fixed
- DNSCrypt upstream not resetting the client and resolver information on
dialing errors ([#5872]).
## [v0.107.31] - 2023-06-08
See also the [v0.107.31 GitHub milestone][ms-v0.107.31].
### Fixed
- Startup errors on OpenWrt ([#5872]).
- Plain-UDP upstreams always falling back to TCP, causing outages and slowdowns
([#5873], [#5874]).
[#5872]: https://github.com/AdguardTeam/AdGuardHome/issues/5872
[#5873]: https://github.com/AdguardTeam/AdGuardHome/issues/5873
[#5874]: https://github.com/AdguardTeam/AdGuardHome/issues/5874
[ms-v0.107.31]: https://github.com/AdguardTeam/AdGuardHome/milestone/67?closed=1
## [v0.107.30] - 2023-06-07
See also the [v0.107.30 GitHub milestone][ms-v0.107.30].
### Security
- Go version has been updated to prevent the possibility of exploiting the
CVE-2023-29402, CVE-2023-29403, and CVE-2023-29404 Go vulnerabilities fixed in
[Go 1.19.10][go-1.19.10].
### Fixed
- Unquoted IPv6 bind hosts with trailing colons erroneously considered
unspecified addresses are now properly validated ([#5752]).
**NOTE:** the Docker healthcheck script now also doesn't interpret the `""`
value as unspecified address.
- Incorrect `Content-Type` header value in `POST /control/version.json` and `GET
/control/dhcp/interfaces` HTTP APIs ([#5716]).
- Provided bootstrap servers are now used to resolve the hostnames of plain
UDP/TCP upstream servers.
[#5716]: https://github.com/AdguardTeam/AdGuardHome/issues/5716
[go-1.19.10]: https://groups.google.com/g/golang-announce/c/q5135a9d924/m/j0ZoAJOHAwAJ
[ms-v0.107.30]: https://github.com/AdguardTeam/AdGuardHome/milestone/66?closed=1
## [v0.107.29] - 2023-04-18
See also the [v0.107.29 GitHub milestone][ms-v0.107.29].
### Added
- The ability to exclude client activity from the query log or statistics by
editing client's settings on the respective page in the UI ([#1717], [#4299]).
### Changed
- Stored DHCP leases moved from `leases.db` to `data/leases.json`. The file
format has also been optimized.
### Fixed
- The `github.com/mdlayher/raw` dependency has been temporarily returned to
support raw connections on Darwin ([#5712]).
- Incorrect recording of blocked results as “Blocked by CNAME or IP” in the
query log ([#5725]).
- All Safe Search services being unchecked by default.
- Panic when a DNSCrypt stamp is invalid ([#5721]).
[#5712]: https://github.com/AdguardTeam/AdGuardHome/issues/5712
[#5721]: https://github.com/AdguardTeam/AdGuardHome/issues/5721
[#5725]: https://github.com/AdguardTeam/AdGuardHome/issues/5725
[#5752]: https://github.com/AdguardTeam/AdGuardHome/issues/5752
[ms-v0.107.29]: https://github.com/AdguardTeam/AdGuardHome/milestone/65?closed=1
## [v0.107.28] - 2023-04-12
See also the [v0.107.28 GitHub milestone][ms-v0.107.28].
### Added
- The ability to exclude client activity from the query log or statistics by
using the new properties `ignore_querylog` and `ignore_statistics` of the
items of the `clients.persistent` array ([#1717], [#4299]). The UI changes
are coming in the upcoming releases.
- Better profiling information when `debug_pprof` is set to `true`.
- IPv6 support in Safe Search for some services.
- The ability to make bootstrap DNS lookups prefer IPv6 addresses to IPv4 ones
using the new `dns.bootstrap_prefer_ipv6` configuration file property
([#4262]).
@@ -32,20 +210,20 @@ NOTE: Add new changes BELOW THIS COMMENT.
- The new HTTP API `POST /control/protection`, that updates protection state
and adds an optional pause duration ([#1333]). The format of request body
is described in `openapi/openapi.yaml`. The duration of this pause could
also be set with the config field `protection_disabled_until` in `dns`
section of the YAML configuration file.
also be set with the property `protection_disabled_until` in the `dns` object
of the YAML configuration file.
- The ability to create a static DHCP lease from a dynamic one more easily
([#3459]).
- Two new HTTP APIs, `PUT /control/stats/config/update` and `GET
control/stats/config`, which can be used to set and receive the query log
configuration. See openapi/openapi.yaml for the full description.
configuration. See `openapi/openapi.yaml` for the full description.
- Two new HTTP APIs, `PUT /control/querylog/config/update` and `GET
control/querylog/config`, which can be used to set and receive the statistics
configuration. See openapi/openapi.yaml for the full description.
configuration. See `openapi/openapi.yaml` for the full description.
- The ability to set custom IP for EDNS Client Subnet by using the DNS-server
configuration section on the DNS settings page in the UI ([#1472]).
- The ability to manage safesearch for each service by using the new
`safe_search` field ([#1163]).
- The ability to manage Safe Search for each service by using the new
`safe_search` property ([#1163]).
### Changed
@@ -74,9 +252,9 @@ In this release, the schema version has changed from 17 to 20.
To rollback this change, convert the property back into days and change the
`schema_version` back to `19`.
- The `dns.safesearch_enabled` field has been replaced with `safe_search`
- The `dns.safesearch_enabled` property has been replaced with `safe_search`
object containing per-service settings.
- The `clients.persistent.safesearch_enabled` field has been replaced with
- The `clients.persistent.safesearch_enabled` property has been replaced with
`safe_search` object containing per-service settings.
```yaml
@@ -95,7 +273,7 @@ In this release, the schema version has changed from 17 to 20.
```
To rollback this change, move the value of `dns.safe_search.enabled` into the
`dns.safesearch_enabled`, then remove `dns.safe_search` field. Do the same
`dns.safesearch_enabled`, then remove `dns.safe_search` property. Do the same
client's specific `clients.persistent.safesearch` and then change the
`schema_version` back to `17`.
@@ -105,7 +283,7 @@ In this release, the schema version has changed from 17 to 20.
`PUT /control/safesearch/settings` API.
- The `POST /control/safesearch/disable` HTTP API is deprecated. Use the new
`PUT /control/safesearch/settings` API
- The `safesearch_enabled` field is deprecated in the following HTTP APIs:
- The `safesearch_enabled` property is deprecated in the following HTTP APIs:
- `GET /control/clients`;
- `POST /control/clients/add`;
- `POST /control/clients/update`;
@@ -116,17 +294,21 @@ In this release, the schema version has changed from 17 to 20.
/control/stats/config` API instead.
**NOTE:** If interval is custom then it will be equal to `90` days for
compatibility reasons. See openapi/openapi.yaml and `openapi/CHANGELOG.md`.
compatibility reasons. See `openapi/openapi.yaml` and `openapi/CHANGELOG.md`.
- The `POST /control/stats_config` HTTP API; use the new `PUT
/control/stats/config/update` API instead.
- The `GET /control/querylog_info` HTTP API; use the new `GET
/control/querylog/config` API instead.
**NOTE:** If interval is custom then it will be equal to `90` days for
compatibility reasons. See openapi/openapi.yaml and `openapi/CHANGELOG.md`.
compatibility reasons. See `openapi/openapi.yaml` and `openapi/CHANGELOG.md`.
- The `POST /control/querylog_config` HTTP API; use the new `PUT
/control/querylog/config/update` API instead.
### Fixed
- Logging of the client's IP address after failed login attempts ([#5701]).
[#1163]: https://github.com/AdguardTeam/AdGuardHome/issues/1163
[#1333]: https://github.com/AdguardTeam/AdGuardHome/issues/1333
[#1472]: https://github.com/AdguardTeam/AdGuardHome/issues/1472
@@ -134,12 +316,11 @@ In this release, the schema version has changed from 17 to 20.
[#3459]: https://github.com/AdguardTeam/AdGuardHome/issues/3459
[#4262]: https://github.com/AdguardTeam/AdGuardHome/issues/4262
[#5567]: https://github.com/AdguardTeam/AdGuardHome/issues/5567
[#5701]: https://github.com/AdguardTeam/AdGuardHome/issues/5701
[rfc6761]: https://www.rfc-editor.org/rfc/rfc6761
[ms-v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/milestone/64?closed=1
[rfc6761]: https://www.rfc-editor.org/rfc/rfc6761
<!--
NOTE: Add new changes ABOVE THIS COMMENT.
-->
@@ -183,7 +364,7 @@ See also the [v0.107.26 GitHub milestone][ms-v0.107.26].
- The ability to set custom IP for EDNS Client Subnet by using the new
`dns.edns_client_subnet.use_custom` and `dns.edns_client_subnet.custom_ip`
fields ([#1472]). The UI changes are coming in the upcoming releases.
properties ([#1472]). The UI changes are coming in the upcoming releases.
- The ability to use `dnstype` rules in the disallowed domains list ([#5468]).
This allows dropping requests based on their question types.
@@ -211,7 +392,7 @@ See also the [v0.107.26 GitHub milestone][ms-v0.107.26].
```
To rollback this change, move the value of `dns.edns_client_subnet.enabled`
into the `dns.edns_client_subnet`, remove the fields
into the `dns.edns_client_subnet`, remove the properties
`dns.edns_client_subnet.enabled`, `dns.edns_client_subnet.use_custom`,
`dns.edns_client_subnet.custom_ip`, and change the `schema_version` back to
`16`.
@@ -271,11 +452,11 @@ See also the [v0.107.24 GitHub milestone][ms-v0.107.24].
### Added
- The ability to disable statistics by using the new `statistics.enabled`
field. Previously it was necessary to set the `statistics_interval` to 0,
property. Previously it was necessary to set the `statistics_interval` to 0,
losing the previous value ([#1717], [#4299]).
- The ability to exclude domain names from the query log or statistics by using
the new `querylog.ignored` or `statistics.ignored` fields ([#1717], [#4299]).
The UI changes are coming in the upcoming releases.
the new `querylog.ignored` or `statistics.ignored` properties ([#1717],
[#4299]). The UI changes are coming in the upcoming releases.
### Changed
@@ -300,7 +481,7 @@ In this release, the schema version has changed from 14 to 16.
To rollback this change, move the property back into the `dns` object and
change the `schema_version` back to `15`.
- The fields `dns.querylog_enabled`, `dns.querylog_file_enabled`,
- The properties `dns.querylog_enabled`, `dns.querylog_file_enabled`,
`dns.querylog_interval`, and `dns.querylog_size_memory` have been moved to the
new `querylog` object.
@@ -358,8 +539,8 @@ See also the [v0.107.23 GitHub milestone][ms-v0.107.23].
### Added
- DNS64 support ([#5117]). The function may be enabled with new `use_dns64`
field under `dns` object in the configuration along with `dns64_prefixes`, the
set of exclusion prefixes to filter AAAA responses. The Well-Known Prefix
property under `dns` object in the configuration along with `dns64_prefixes`,
the set of exclusion prefixes to filter AAAA responses. The Well-Known Prefix
(`64:ff9b::/96`) is used if no custom prefixes are specified.
### Fixed
@@ -1017,7 +1198,7 @@ In this release, the schema version has changed from 12 to 14.
hosts: true
```
The value for `clients.runtime_sources.rdns` field is taken from
The value for `clients.runtime_sources.rdns` property is taken from
`dns.resolve_clients` property. To rollback this change, remove the
`runtime_sources` property, move the contents of `persistent` into the
`clients` itself, the value of `clients.runtime_sources.rdns` into the
@@ -1267,7 +1448,7 @@ See also the [v0.107.0 GitHub milestone][ms-v0.107.0].
log entries concerning cached responses won't include that information.
- Finnish and Ukrainian localizations.
- Setting the timeout for IP address pinging in the "Fastest IP address" mode
through the new `fastest_timeout` field in the configuration file ([#1992]).
through the new `fastest_timeout` property in the configuration file ([#1992]).
- Static IP address detection on FreeBSD ([#3289]).
- Optimistic cache ([#2145]).
- New possible value of `6h` for `querylog_interval` property ([#2504]).
@@ -1683,7 +1864,7 @@ See also the [v0.105.2 GitHub milestone][ms-v0.105.2].
- Inconsistent responses for messages with EDNS0 and AD when DNS caching is
enabled ([#2600]).
- Incomplete OpenWrt detection ([#2757]).
- DHCP lease's `expired` field incorrect time format ([#2692]).
- DHCP lease's `expired` property incorrect time format ([#2692]).
- Incomplete DNS upstreams validation ([#2674]).
- Wrong parsing of DHCP options of the `ip` type ([#2688]).
@@ -1720,8 +1901,8 @@ See also the [v0.105.1 GitHub milestone][ms-v0.105.1].
the machine has a static IP.
- Optical issue on custom rules ([#2641]).
- Occasional crashes during startup.
- The field `"range_start"` in the `GET /control/dhcp/status` HTTP API response
is now correctly named again ([#2678]).
- The property `"range_start"` in the `GET /control/dhcp/status` HTTP API
response is now correctly named again ([#2678]).
- DHCPv6 server's `ra_slaac_only` and `ra_allow_slaac` properties aren't reset
to `false` on update anymore ([#2653]).
- The `Vary` header is now added along with `Access-Control-Allow-Origin` to
@@ -1791,7 +1972,7 @@ See also the [v0.105.0 GitHub milestone][ms-v0.105.0].
- Go 1.14 support. v0.106.0 will require at least Go 1.15 to build.
- The `darwin/386` port. It will be removed in v0.106.0.
- The `"rule"` and `"filter_id"` fields in `GET /filtering/check_host` and
- The `"rule"` and `"filter_id"` property in `GET /filtering/check_host` and
`GET /querylog` responses. They will be removed in v0.106.0 ([#2102]).
### Fixed
@@ -1899,11 +2080,16 @@ See also the [v0.104.2 GitHub milestone][ms-v0.104.2].
<!--
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.28...HEAD
[v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.27...v0.107.28
[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.27...HEAD
[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.32...HEAD
[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
[v0.107.29]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.28...v0.107.29
[v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.27...v0.107.28
[v0.107.27]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.26...v0.107.27
[v0.107.26]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.25...v0.107.26
[v0.107.25]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.24...v0.107.25

View File

@@ -466,6 +466,10 @@ bug or implementing the feature.
Home](https://github.com/ebrianne/adguard-exporter) by
[@ebrianne](https://github.com/ebrianne).
* [Terminal-based, real-time traffic monitoring and statistics for your AdGuard Home
instance](https://github.com/Lissy93/AdGuardian-Term) by
[@Lissy93](https://github.com/Lissy93)
* [AdGuard Home on GLInet
routers](https://forum.gl-inet.com/t/adguardhome-on-gl-routers/10664) by
[Gl-Inet](https://gl-inet.com/).

View File

@@ -1,5 +1,8 @@
---
!include test.yaml
---
!include release.yaml
---
!include snapcraft.yaml
---
!include test.yaml

View File

@@ -1,349 +1,290 @@
---
'version': 2
'plan':
'project-key': 'AGH'
'key': 'AGHBSNAPSPECS'
'name': 'AdGuard Home - Build and publish release'
'project-key': 'AGH'
'key': 'AGHBSNAPSPECS'
'name': 'AdGuard Home - Build and publish release'
# Make sure to sync any changes with the branch overrides below.
'variables':
'channel': 'edge'
'dockerGo': 'adguard/golang-ubuntu:6.3'
'channel': 'edge'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'stages':
- 'Build frontend':
'manual': false
'final': false
'jobs':
- 'Build frontend'
- 'Build frontend':
'manual': false
'final': false
'jobs':
- 'Build frontend'
- 'Make release':
'manual': false
'final': false
'jobs':
- 'Make release'
- 'Make release':
'manual': false
'final': false
'jobs':
- 'Make release'
- 'Make and publish docker':
'manual': false
'final': false
'jobs':
- 'Make and publish docker'
- 'Make and publish docker':
'manual': false
'final': false
'jobs':
- 'Make and publish docker'
- 'Publish to static storage':
'manual': false
'final': false
'jobs':
- 'Publish to static storage'
- 'Publish to static storage':
'manual': false
'final': false
'jobs':
- 'Publish to static storage'
- 'Publish to Snapstore':
'manual': false
'final': false
'jobs':
- 'Publish to Snapstore'
- 'Publish to GitHub Releases':
'manual': false
'final': false
'jobs':
- 'Publish to GitHub Releases'
- 'Publish to GitHub Releases':
'manual': false
'final': false
'jobs':
- 'Publish to GitHub Releases'
'Build frontend':
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.YARN_DIR}': '${bamboo.cacheYarn}'
'key': 'BF'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.YARN_DIR}': '${bamboo.cacheYarn}'
'key': 'BF'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
# Explicitly checkout the revision that we need.
git checkout "${bamboo.repository.revision.number}"
# Explicitly checkout the revision that we need.
git checkout "${bamboo.repository.revision.number}"
make js-deps js-build
'artifacts':
- 'name': 'AdGuardHome frontend'
'pattern': 'build*/**'
'shared': true
'required': true
'requirements':
- 'adg-docker': 'true'
make js-deps js-build
'artifacts':
- 'name': 'AdGuardHome frontend'
'pattern': 'build/**'
'shared': true
'required': true
'requirements':
- 'adg-docker': 'true'
'Make release':
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'key': 'MR'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'key': 'MR'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
# Explicitly checkout the revision that we need.
git checkout "${bamboo.repository.revision.number}"
# Explicitly checkout the revision that we need.
git checkout "${bamboo.repository.revision.number}"
# Run the build with the specified channel.
echo "${bamboo.gpgSecretKeyPart1}${bamboo.gpgSecretKeyPart2}"\
| awk '{ gsub(/\\n/, "\n"); print; }'\
| gpg --import --batch --yes
# Run the build with the specified channel.
echo "${bamboo.gpgSecretKeyPart1}${bamboo.gpgSecretKeyPart2}"\
| awk '{ gsub(/\\n/, "\n"); print; }'\
| gpg --import --batch --yes
make\
CHANNEL=${bamboo.channel}\
GPG_KEY_PASSPHRASE=${bamboo.gpgPassword}\
FRONTEND_PREBUILT=1\
PARALLELISM=1\
VERBOSE=2\
build-release
# TODO(a.garipov): Use more fine-grained artifact rules.
'artifacts':
- 'name': 'AdGuardHome dists'
'pattern': 'dist/**'
'shared': true
'required': true
'requirements':
- 'adg-docker': 'true'
make\
CHANNEL=${bamboo.channel}\
GPG_KEY_PASSPHRASE=${bamboo.gpgPassword}\
FRONTEND_PREBUILT=1\
PARALLELISM=1\
VERBOSE=2\
build-release
# TODO(a.garipov): Use more fine-grained artifact rules.
'artifacts':
- 'name': 'AdGuardHome dists'
'pattern': 'dist/**'
'shared': true
'required': true
'requirements':
- 'adg-docker': 'true'
'Make and publish docker':
'key': 'MPD'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'key': 'MPD'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
COMMIT="${bamboo.repository.revision.number}"
export COMMIT
readonly COMMIT
COMMIT="${bamboo.repository.revision.number}"
export COMMIT
readonly COMMIT
# Explicitly checkout the revision that we need.
git checkout "$COMMIT"
# Explicitly checkout the revision that we need.
git checkout "$COMMIT"
# Install Qemu, create builder.
docker version -f '{{ .Server.Experimental }}'
docker buildx rm buildx-builder || :
docker buildx create --name buildx-builder --driver docker-container\
--use
docker buildx inspect --bootstrap
# Install Qemu, create builder.
docker version -f '{{ .Server.Experimental }}'
docker buildx rm buildx-builder || :
docker buildx create --name buildx-builder --driver docker-container\
--use
docker buildx inspect --bootstrap
# Login to DockerHub.
docker login -u="${bamboo.dockerHubUsername}"\
-p="${bamboo.dockerHubPassword}"
# Login to DockerHub.
docker login -u="${bamboo.dockerHubUsername}"\
-p="${bamboo.dockerHubPassword}"
# Boot the builder.
docker buildx inspect --bootstrap
# Boot the builder.
docker buildx inspect --bootstrap
# Print Docker info.
docker info
# Print Docker info.
docker info
# Prepare and push the build.
env\
CHANNEL="${bamboo.channel}"\
DIST_DIR='dist'\
DOCKER_IMAGE_NAME='adguard/adguardhome'\
DOCKER_OUTPUT="type=image,name=adguard/adguardhome,push=true"\
VERBOSE='1'\
sh ./scripts/make/build-docker.sh
'environment':
DOCKER_CLI_EXPERIMENTAL=enabled
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
# Prepare and push the build.
env\
CHANNEL="${bamboo.channel}"\
DIST_DIR='dist'\
DOCKER_IMAGE_NAME='adguard/adguardhome'\
DOCKER_OUTPUT="type=image,name=adguard/adguardhome,push=true"\
VERBOSE='1'\
sh ./scripts/make/build-docker.sh
'environment':
DOCKER_CLI_EXPERIMENTAL=enabled
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'Publish to static storage':
'key': 'PUB'
'other':
'clean-working-dir': true
'tasks':
- 'clean'
- 'checkout':
'repository': 'bamboo-deploy-publisher'
'path': 'bamboo-deploy-publisher'
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'key': 'PUB'
'other':
'clean-working-dir': true
'tasks':
- 'clean'
- 'checkout':
'repository': 'bamboo-deploy-publisher'
'path': 'bamboo-deploy-publisher'
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
cd ./dist/
cd ./dist/
CHANNEL="${bamboo.channel}"
export CHANNEL
CHANNEL="${bamboo.channel}"
export CHANNEL
../bamboo-deploy-publisher/deploy.sh adguard-home-"$CHANNEL"
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'Publish to Snapstore':
'docker':
'image': '${bamboo.dockerGo}'
'key': 'PTS'
'other':
'clean-working-dir': true
'tasks':
- 'clean'
- 'checkout':
'repository': 'bamboo-deploy-publisher'
'path': 'bamboo-deploy-publisher'
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
cd ./dist/
channel="${bamboo.channel}"
readonly channel
case "$channel"
in
('release')
snapchannel='candidate'
;;
('beta')
snapchannel='beta'
;;
('edge')
snapchannel='edge'
;;
(*)
echo "invalid channel '$channel'"
exit 1
;;
esac
env\
SNAPCRAFT_CHANNEL="$snapchannel"\
SNAPCRAFT_EMAIL="${bamboo.snapcraftEmail}"\
SNAPCRAFT_MACAROON="${bamboo.snapcraftMacaroonPassword}"\
SNAPCRAFT_UBUNTU_DISCHARGE="${bamboo.snapcraftUbuntuDischargePassword}"\
../bamboo-deploy-publisher/deploy.sh adguard-home-snap
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
../bamboo-deploy-publisher/deploy.sh adguard-home-"$CHANNEL"
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'Publish to GitHub Releases':
'key': 'PTGR'
'other':
'clean-working-dir': true
'tasks':
- 'clean'
- 'checkout':
'repository': 'bamboo-deploy-publisher'
'path': 'bamboo-deploy-publisher'
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'key': 'PTGR'
'other':
'clean-working-dir': true
'tasks':
- 'clean'
- 'checkout':
'repository': 'bamboo-deploy-publisher'
'path': 'bamboo-deploy-publisher'
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
channel="${bamboo.channel}"
readonly channel
channel="${bamboo.channel}"
readonly channel
if [ "$channel" != 'release' ] && [ "${channel}" != 'beta' ]
then
echo "don't publish to GitHub Releases for this channel"
if [ "$channel" != 'release' ] && [ "${channel}" != 'beta' ]
then
echo "don't publish to GitHub Releases for this channel"
exit 0
fi
exit 0
fi
cd ./dist/
cd ./dist/
env\
GITHUB_TOKEN="${bamboo.githubPublicRepoPassword}"\
../bamboo-deploy-publisher/deploy.sh adguard-home-github
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
env\
GITHUB_TOKEN="${bamboo.githubPublicRepoPassword}"\
../bamboo-deploy-publisher/deploy.sh adguard-home-github
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'triggers':
# Don't use minute values that end with a zero or a five as these are often used
# in CI and so resources during these minutes can be quite busy.
- 'cron': '0 42 13 ? * MON-FRI *'
# Don't use minute values that end with a zero or a five as these are often
# used in CI and so resources during these minutes can be quite busy.
- 'cron': '0 42 13 ? * MON-FRI *'
'branches':
'create': 'manually'
'delete':
'after-deleted-days': 1
'after-inactive-days': 30
'integration':
'push-on-success': false
'merge-from': 'AdGuard Home - Build and publish release'
'link-to-jira': true
'create': 'manually'
'delete':
'after-deleted-days': 1
'after-inactive-days': 30
'integration':
'push-on-success': false
'merge-from': 'AdGuard Home - Build and publish release'
'link-to-jira': true
'notifications':
- 'events':
- 'plan-completed'
'recipients':
- 'webhook':
'name': 'Build webhook'
'url': 'http://prod.jirahub.service.eu.consul/v1/webhook/bamboo?channel=adguard-qa'
- 'events':
- 'plan-completed'
'recipients':
- 'webhook':
'name': 'Build webhook'
'url': 'http://prod.jirahub.service.eu.consul/v1/webhook/bamboo?channel=adguard-qa'
'labels': []
'other':
'concurrent-build-plugin': 'system-default'
'concurrent-build-plugin': 'system-default'
'branch-overrides':
# beta-vX.Y branches are the branches into which the commits that are needed to
# release a new patch version are initially cherry-picked.
- '^beta-v[0-9]+\.[0-9]+':
# Build betas on release branches manually.
'triggers': []
# Set the default release channel on the release branch to beta, as we may
# need to build a few of these.
'variables':
'channel': 'beta'
'dockerGo': 'adguard/golang-ubuntu:6.3'
# release-vX.Y.Z branches are the branches from which the actual final release
# is built.
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
# Disable integration branches for release branches.
'branch-config':
'integration':
'push-on-success': false
'merge-from': 'beta-v0.107'
# Build final releases on release branches manually.
'triggers': []
# Set the default release channel on the final branch to release, as these
# are the ones that actually get released.
'variables':
'channel': 'release'
'dockerGo': 'adguard/golang-ubuntu:6.3'
# beta-vX.Y branches are the branches into which the commits that are needed
# to release a new patch version are initially cherry-picked.
- '^beta-v[0-9]+\.[0-9]+':
# Build betas on release branches manually.
'triggers': []
# Set the default release channel on the release branch to beta, as we may
# need to build a few of these.
'variables':
'channel': 'beta'
'dockerGo': 'adguard/golang-ubuntu:6.7'
# release-vX.Y.Z branches are the branches from which the actual final
# release is built.
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
# Disable integration branches for release branches.
'branch-config':
'integration':
'push-on-success': false
'merge-from': 'beta-v0.107'
# Build final releases on release branches manually.
'triggers': []
# Set the default release channel on the final branch to release, as these
# are the ones that actually get released.
'variables':
'channel': 'release'
'dockerGo': 'adguard/golang-ubuntu:6.7'

211
bamboo-specs/snapcraft.yaml Normal file
View File

@@ -0,0 +1,211 @@
---
# This part of the release build is separate from the one described in
# release.yaml, because the Snapcraft infrastructure is brittle, and timeouts
# during logins and uploads often lead to release blocking.
'version': 2
'plan':
'project-key': 'AGH'
'key': 'AGHSNAP'
'name': 'AdGuard Home - Build and publish Snapcraft release'
# Make sure to sync any changes with the branch overrides below.
'variables':
'channel': 'edge'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'snapcraftChannel': 'edge'
'stages':
- 'Download release':
'manual': false
'final': false
'jobs':
- 'Download release'
- 'Build packages':
'manual': false
'final': false
'jobs':
- 'Build packages'
- 'Publish to Snapstore':
'manual': false
'final': false
'jobs':
- 'Publish to Snapstore'
# TODO(a.garipov): Consider using the Artifact Downloader Task if it ever learns
# about plan branches.
'Download release':
'artifacts':
- 'name': 'i386_binary'
'pattern': 'AdGuardHome_i386'
'shared': true
'required': true
- 'name': 'amd64_binary'
'pattern': 'AdGuardHome_amd64'
'shared': true
'required': true
- 'name': 'armhf_binary'
'pattern': 'AdGuardHome_armhf'
'shared': true
'required': true
- 'name': 'arm64_binary'
'pattern': 'AdGuardHome_arm64'
'shared': true
'required': true
'docker':
'image': '${bamboo.dockerGo}'
'key': 'DR'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
env\
CHANNEL="${bamboo.channel}"\
VERBOSE='1'\
sh ./scripts/snap/download.sh
'requirements':
- 'adg-docker': 'true'
'Build packages':
'artifact-subscriptions':
- 'artifact': 'i386_binary'
- 'artifact': 'amd64_binary'
- 'artifact': 'armhf_binary'
- 'artifact': 'arm64_binary'
'artifacts':
- 'name': 'i386_snap'
'pattern': 'AdGuardHome_i386.snap'
'shared': true
'required': true
- 'name': 'amd64_snap'
'pattern': 'AdGuardHome_amd64.snap'
'shared': true
'required': true
- 'name': 'armhf_snap'
'pattern': 'AdGuardHome_armhf.snap'
'shared': true
'required': true
- 'name': 'arm64_snap'
'pattern': 'AdGuardHome_arm64.snap'
'shared': true
'required': true
'docker':
'image': '${bamboo.dockerGo}'
'key': 'BP'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
env\
VERBOSE='1'\
sh ./scripts/snap/build.sh
'requirements':
- 'adg-docker': 'true'
'Publish to Snapstore':
'artifact-subscriptions':
- 'artifact': 'i386_snap'
- 'artifact': 'amd64_snap'
- 'artifact': 'armhf_snap'
- 'artifact': 'arm64_snap'
'docker':
'image': '${bamboo.dockerGo}'
'key': 'PTS'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
env\
SNAPCRAFT_CHANNEL="${bamboo.snapcraftChannel}"\
SNAPCRAFT_STORE_CREDENTIALS="${bamboo.snapcraftMacaroonPassword}"\
VERBOSE='1'\
sh ./scripts/snap/upload.sh
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'triggers':
# Don't use minute values that end with a zero or a five as these are often
# used in CI and so resources during these minutes can be quite busy.
#
# NOTE: The time is chosen to be exactly one hour after the main release
# build as defined as in release.yaml.
- 'cron': '0 42 14 ? * MON-FRI *'
'branches':
'create': 'manually'
'delete':
'after-deleted-days': 1
'after-inactive-days': 30
'integration':
'push-on-success': false
'merge-from': 'AdGuard Home - Build and publish Snapcraft release'
'link-to-jira': true
'notifications':
- 'events':
- 'plan-completed'
'recipients':
- 'webhook':
'name': 'Build webhook'
'url': 'http://prod.jirahub.service.eu.consul/v1/webhook/bamboo?channel=adguard-qa'
'labels': []
'other':
'concurrent-build-plugin': 'system-default'
'branch-overrides':
# beta-vX.Y branches are the branches into which the commits that are needed
# to release a new patch version are initially cherry-picked.
- '^beta-v[0-9]+\.[0-9]+':
# Build betas on release branches manually.
'triggers': []
# Set the default release channel on the release branch to beta, as we may
# need to build a few of these.
'variables':
'channel': 'beta'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'snapcraftChannel': 'beta'
# release-vX.Y.Z branches are the branches from which the actual final
# release is built.
- '^release-v[0-9]+\.[0-9]+\.[0-9]+':
# Disable integration branches for release branches.
'branch-config':
'integration':
'push-on-success': false
'merge-from': 'beta-v0.107'
# Build final releases on release branches manually.
'triggers': []
# Set the default release channel on the final branch to release, as these
# are the ones that actually get released.
'variables':
'channel': 'release'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'snapcraftChannel': 'candidate'

View File

@@ -1,64 +1,64 @@
---
'version': 2
'plan':
'project-key': 'AGH'
'key': 'AHBRTSPECS'
'name': 'AdGuard Home - Build and run tests'
'project-key': 'AGH'
'key': 'AHBRTSPECS'
'name': 'AdGuard Home - Build and run tests'
'variables':
'dockerGo': 'adguard/golang-ubuntu:6.3'
'dockerGo': 'adguard/golang-ubuntu:6.7'
'stages':
- 'Tests':
'manual': false
'final': false
'jobs':
- 'Test'
- 'Tests':
'manual': false
'final': false
'jobs':
- 'Test'
'Test':
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.YARN_DIR}': '${bamboo.cacheYarn}'
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'key': 'TEST'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
'docker':
'image': '${bamboo.dockerGo}'
'volumes':
'${system.YARN_DIR}': '${bamboo.cacheYarn}'
'${system.GO_CACHE_DIR}': '${bamboo.cacheGo}'
'${system.GO_PKG_CACHE_DIR}': '${bamboo.cacheGoPkg}'
'key': 'TEST'
'other':
'clean-working-dir': true
'tasks':
- 'checkout':
'force-clean-build': true
- 'script':
'interpreter': 'SHELL'
'scripts':
- |
#!/bin/sh
set -e -f -u -x
set -e -f -u -x
make VERBOSE=1 ci go-tools lint
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
make VERBOSE=1 ci go-tools lint
'final-tasks':
- 'clean'
'requirements':
- 'adg-docker': 'true'
'branches':
'create': 'for-pull-request'
'delete':
'after-deleted-days': 1
'after-inactive-days': 5
'integration':
'push-on-success': false
'merge-from': 'AdGuard Home - Build and run tests'
'link-to-jira': true
'create': 'for-pull-request'
'delete':
'after-deleted-days': 1
'after-inactive-days': 5
'integration':
'push-on-success': false
'merge-from': 'AdGuard Home - Build and run tests'
'link-to-jira': true
'notifications':
- 'events':
- 'plan-status-changed'
'recipients':
- 'webhook':
'name': 'Build webhook'
'url': 'http://prod.jirahub.service.eu.consul/v1/webhook/bamboo'
- 'events':
- 'plan-status-changed'
'recipients':
- 'webhook':
'name': 'Build webhook'
'url': 'http://prod.jirahub.service.eu.consul/v1/webhook/bamboo'
'labels': []
'other':
'concurrent-build-plugin': 'system-default'
'concurrent-build-plugin': 'system-default'

2
client/dev.eslintrc vendored
View File

@@ -3,4 +3,4 @@
"rules": {
"no-debugger":"warn",
}
}
}

View File

@@ -12,11 +12,40 @@
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#67B279">
<link rel="icon" type="image/png" href="assets/favicon.png" sizes="48x48">
<title>AdGuard Home</title>
<style>
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
}
[data-theme="DARK"] .wrapper {
background-color: #f5f7fb;
}
</style>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<div id="root">
<div class="wrapper"></div>
</div>
<script>
(function() {
var LOCAL_STORAGE_THEME_KEY = 'account_theme';
var theme = 'light';
try {
theme = window.localStorage.getItem(LOCAL_STORAGE_THEME_KEY);
} catch(e) {
console.error(e);
}
document.body.dataset.theme = theme;
})();
</script>
</body>
</html>

View File

@@ -17,5 +17,12 @@
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<script>
(function() {
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
var currentTheme = prefersDark ? 'dark' : 'light';
document.body.dataset.theme = currentTheme;
})();
</script>
</body>
</html>

View File

@@ -635,5 +635,6 @@
"parental_control": "الرقابة الابويه",
"safe_browsing": "تصفح آمن",
"served_from_cache": "{{value}} <i>(يتم تقديمه من ذاكرة التخزين المؤقت)</i>",
"form_error_password_length": "يجب أن تتكون كلمة المرور من {{value}} من الأحرف على الأقل"
"form_error_password_length": "يجب أن تتكون كلمة المرور من {{value}} من الأحرف على الأقل",
"protection_section_label": "الحماية"
}

View File

@@ -150,7 +150,7 @@
"dns_allowlists": "Белыя спісы DNS",
"dns_blocklists_desc": "AdGuard Home будзе блакаваць дамены з чорных спісаў.",
"dns_allowlists_desc": "Дамены з белых спісаў DNS будуць дазволены, нават калі яны знаходзяцца ў любым з чорных спісаў.",
"custom_filtering_rules": "Карыстацкія правілы фільтрацыі",
"custom_filtering_rules": "Карыстальніцкія правілы фільтрацыі",
"encryption_settings": "Налады шыфравання",
"dhcp_settings": "Налады DHCP",
"upstream_dns": "Upstream DNS-серверы",
@@ -247,7 +247,7 @@
"loading_table_status": "Загрузка...",
"page_table_footer_text": "Старонка",
"rows_table_footer_text": "радкоў",
"updated_custom_filtering_toast": "Занесены змены ў карыстацкія правілы",
"updated_custom_filtering_toast": "Карыстальніцкія правілы паспяхова захаваны",
"rule_removed_from_custom_filtering_toast": "Карыстацкае правіла выдалена: {{rule}}",
"rule_added_to_custom_filtering_toast": "Карыстацкае правіла дададзена: {{rule}}",
"query_log_response_status": "Статус: {{value}}",
@@ -568,7 +568,7 @@
"check_desc": "Праверыць фільтрацыю імя хаста",
"check": "Праверыць",
"form_enter_host": "Увядзіце імя хаста",
"filtered_custom_rules": "Адфільтраваны з дапамогай карыстацкіх правілаў фільтрацыі",
"filtered_custom_rules": "Адфільтраваны з дапамогай карыстальніцкіх правіл фільтрацыі",
"choose_from_list": "Абраць са спіса",
"add_custom_list": "Дадаць свой спіс",
"host_whitelisted": "Хост занесены ў белы спіс",
@@ -642,5 +642,6 @@
"anonymizer_notification": "<0>Заўвага:</0> Ананімізацыя IP уключана. Вы можаце адключыць яе ў <1>Агульных наладах</1>.",
"confirm_dns_cache_clear": "Вы ўпэўнены, што хочаце ачысціць кэш DNS?",
"cache_cleared": "Кэш DNS паспяхова ачышчаны",
"clear_cache": "Ачысціць кэш"
"clear_cache": "Ачысціць кэш",
"protection_section_label": "Ахова"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Protokol dotazů byl úspěšně vymazán",
"query_log_updated": "Protokol dotazů byl úspěšně aktualizován",
"query_log_clear": "Vymazat protokoly dotazů",
"query_log_retention": "Uchování protokolů dotazů",
"query_log_retention": "Rotace protokolů dotazů",
"query_log_enable": "Povolit protokol",
"query_log_configuration": "Konfigurace protokolů",
"query_log_disabled": "Protokol dotazu je zakázán a lze jej nakonfigurovat v <0>nastavení</0>",
"query_log_strict_search": "Pro striktní vyhledávání použijte dvojité uvozovky",
"query_log_retention_confirm": "Opravdu chcete změnit uchovávání protokolu dotazů? Pokud snížíte hodnotu intervalu, některá data budou ztracena",
"query_log_retention_confirm": "Opravdu chcete změnit rotaci protokolu dotazů? Pokud snížíte hodnotu intervalu, některá data budou ztracena",
"anonymize_client_ip": "Anonymizovat IP klienta",
"anonymize_client_ip_desc": "Neukládat úplnou IP adresu klienta do protokolů a statistik",
"dns_config": "Konfigurace DNS serveru",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Vypnout ochranu na {{count}} hod.",
"disable_notify_for_hours_plural": "Vypnout ochranu na {{count}} hod.",
"disable_notify_until_tomorrow": "Vypnout ochranu do zítřka",
"enable_protection_timer": "Ochrana bude zapnuta za {{time}}"
"enable_protection_timer": "Ochrana bude zapnuta za {{time}}",
"custom_retention_input": "Zadejte retenci v hodinách",
"custom_rotation_input": "Zadejte rotaci v hodinách",
"protection_section_label": "Ochrana",
"log_and_stats_section_label": "Protokol dotazů a statistiky",
"ignore_query_log": "Ignorovat tohoto klienta v protokolu dotazů",
"ignore_statistics": "Ignorovat tohoto klienta ve statistikách"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Forespørgselsloggen er blevet ryddet",
"query_log_updated": "Forespørgselsloggen er blevet opdateret",
"query_log_clear": "Ryd forespørgselslogfiler",
"query_log_retention": "Opbevar forespørgselslogger i",
"query_log_retention": "Rotation af forespørgselslog",
"query_log_enable": "Aktivér log",
"query_log_configuration": "Opsætning af logger",
"query_log_disabled": "Forespørgselsloggen er deaktiveret og kan opsættes i <0>indstillingerne</0>",
"query_log_strict_search": "Brug dobbelt anførselstegn til stringent søgning",
"query_log_retention_confirm": "Sikker på, at du vil ændre forespørgselsloggens opbevaringperiode? Mindskes intervalværdien, mistes data",
"query_log_retention_confirm": "Sikker på, at forespørgselsloggens rotationstid skal ændres? Mindskes intervalværdien, mistes nogle data",
"anonymize_client_ip": "Anonymisér klient-IP",
"anonymize_client_ip_desc": "Gem ikke fuld klient IP-adresse i logfiler eller statistikker",
"dns_config": "DNS-serveropsætning",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Deaktivere beskyttelse i {{count}} time",
"disable_notify_for_hours_plural": "Deaktivere beskyttelse i {{count}} timer",
"disable_notify_until_tomorrow": "Deaktiver beskyttelse indtil i morgen",
"enable_protection_timer": "Beskyttelse deaktiveres om {{time}}"
"enable_protection_timer": "Beskyttelse deaktiveres om {{time}}",
"custom_retention_input": "Angiv opbevaringstid i timer",
"custom_rotation_input": "Angiv rotationstid i timer",
"protection_section_label": "Beskyttelse",
"log_and_stats_section_label": "Forespørgselslog og statistik",
"ignore_query_log": "Ignorér denne klient i forespørgselslog",
"ignore_statistics": "Ignorér denne klient i statistik"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Das Abfrageprotokoll wurde erfolgreich gelöscht",
"query_log_updated": "Das Abfrageprotokoll wurde erfolgreich aktualisiert",
"query_log_clear": "Abfrageprotokolle leeren",
"query_log_retention": "Abfrageprotokolle aufbewahren",
"query_log_retention": "Rotation der Abfrageprotokolle",
"query_log_enable": "Protokoll aktivieren",
"query_log_configuration": "Konfiguration der Protokolle",
"query_log_disabled": "Das Abfrageprotokoll ist deaktiviert und kann in den <0>Einstellungen</0> konfiguriert werden.",
"query_log_strict_search": "Doppelte Anführungszeichen für die strikte Suche verwenden",
"query_log_retention_confirm": "Möchten Sie die Aufbewahrung des Abfrageprotokolls wirklich ändern? Wenn Sie den Zeitabstand verringern, gehen einige Daten verloren.",
"query_log_retention_confirm": "Möchten Sie die Abfrageprotokollrotation wirklich ändern? Wenn Sie den Intervallwert verringern, gehen einige Daten verloren",
"anonymize_client_ip": "Client-IP anonymisieren",
"anonymize_client_ip_desc": "Vollständige IP-Adresse des Clients nicht in Protokollen und Statistiken speichern",
"dns_config": "DNS-Serverkonfiguration",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Schutz für {{count}} Stunde deaktivieren",
"disable_notify_for_hours_plural": "Schutz für {{count}} Stunden deaktivieren",
"disable_notify_until_tomorrow": "Schutz bis morgen deaktivieren",
"enable_protection_timer": "Der Schutz wird in {{time}} wieder aktiviert"
"enable_protection_timer": "Der Schutz wird in {{time}} wieder aktiviert",
"custom_retention_input": "Rückhaltezeit in Stunden eingeben",
"custom_rotation_input": "Rotation in Stunden eingeben",
"protection_section_label": "Schutz",
"log_and_stats_section_label": "Abfrageprotokoll und Statistik",
"ignore_query_log": "Diesen Client im Abfrageprotokoll ignorieren",
"ignore_statistics": "Diesen Client in der Statistik ignorieren"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "The query log has been successfully cleared",
"query_log_updated": "The query log has been successfully updated",
"query_log_clear": "Clear query logs",
"query_log_retention": "Query logs retention",
"query_log_retention": "Query logs rotation",
"query_log_enable": "Enable log",
"query_log_configuration": "Logs configuration",
"query_log_disabled": "The query log is disabled and can be configured in the <0>settings</0>",
"query_log_strict_search": "Use double quotes for strict search",
"query_log_retention_confirm": "Are you sure you want to change query log retention? If you decrease the interval value, some data will be lost",
"query_log_retention_confirm": "Are you sure you want to change query log rotation? If you decrease the interval value, some data will be lost",
"anonymize_client_ip": "Anonymize client IP",
"anonymize_client_ip_desc": "Don't save the client's full IP address to logs or statistics",
"dns_config": "DNS server configuration",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Disable protection for {{count}} hour",
"disable_notify_for_hours_plural": "Disable protection for {{count}} hours",
"disable_notify_until_tomorrow": "Disable protection until tomorrow",
"enable_protection_timer": "Protection will be enabled in {{time}}"
"enable_protection_timer": "Protection will be enabled in {{time}}",
"custom_retention_input": "Enter retention in hours",
"custom_rotation_input": "Enter rotation in hours",
"protection_section_label": "Protection",
"log_and_stats_section_label": "Query log and statistics",
"ignore_query_log": "Ignore this client in query log",
"ignore_statistics": "Ignore this client in statistics"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "El registro de consultas se ha borrado correctamente",
"query_log_updated": "El registro de consultas se ha actualizado correctamente",
"query_log_clear": "Borrar registros de consultas",
"query_log_retention": "Retención de registros de consultas",
"query_log_retention": "Rotanción de registros de consultas",
"query_log_enable": "Habilitar registro",
"query_log_configuration": "Configuración de registros",
"query_log_disabled": "El registro de consultas está deshabilitado y se puede configurar en la <0>configuración</0>",
"query_log_strict_search": "Usar comillas dobles para una búsqueda estricta",
"query_log_retention_confirm": "¿Estás seguro de que deseas cambiar la retención del registro de consultas? Si disminuye el valor del intervalo, se perderán algunos datos",
"query_log_retention_confirm": "¿Está seguro de que deseas cambiar la rotación del registro de consultas? Si reduces el valor del intervalo, se perderán algunos datos",
"anonymize_client_ip": "Anonimizar IP del cliente",
"anonymize_client_ip_desc": "No guarda la dirección IP completa del cliente en registros o estadísticas",
"dns_config": "Configuración del servidor DNS",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Desactivar la protección por {{count}} hora",
"disable_notify_for_hours_plural": "Desactivar la protección por {{count}} horas",
"disable_notify_until_tomorrow": "Desactivar la protección hasta mañana",
"enable_protection_timer": "La protección se activará en {{time}}"
"enable_protection_timer": "La protección se activará en {{time}}",
"custom_retention_input": "Ingresa la retención en horas",
"custom_rotation_input": "Ingresa la rotación en horas",
"protection_section_label": "Protección",
"log_and_stats_section_label": "Registro de consultas y estadísticas",
"ignore_query_log": "Ignorar este cliente en el registro de consultas",
"ignore_statistics": "Ignorar este cliente en las estadísticas"
}

View File

@@ -268,6 +268,8 @@
"blocking_mode_nxdomain": "NXDOMAIN: پاسخ با کُد NXDOMAIN",
"blocking_mode_null_ip": "Null IP: پاسخ با آدرس آی پی صفر(0.0.0.0 برای A; :: برای AAAA)",
"blocking_mode_custom_ip": "آی پی دستی: پاسخ با آدرس آی پی دستی تنظیم شده",
"theme_light": "پوسته روشن",
"theme_dark": "پوسته تیره",
"upstream_dns_client_desc": "اگر این فیلد را خالی نگه دارید، AdGuard Home از سرور پیکربندی شده در <0> تنظیماتDNS </0> استفاده می کند.",
"tracker_source": "منبع ردیاب",
"source_label": "منبع",
@@ -567,5 +569,6 @@
"use_saved_key": "از کلید ذخیره شده قبلی استفاده کنید",
"parental_control": "نظارت والدین",
"safe_browsing": "وب گردی اَمن",
"form_error_password_length": "رمزعبور باید حداقل {{value}} کاراکتر باشد."
"form_error_password_length": "رمزعبور باید حداقل {{value}} کاراکتر باشد.",
"protection_section_label": "حفاظت"
}

View File

@@ -86,7 +86,7 @@
"request_details": "Pyynnön tiedot",
"client_details": "Päätelaitteen tiedot",
"details": "Yksityiskohdat",
"back": "Takaisin",
"back": "Palaa takaisin",
"dashboard": "Tila",
"settings": "Asetukset",
"filters": "Suodattimet",
@@ -146,8 +146,8 @@
"no_servers_specified": "Palvelimia ei ole määritetty",
"general_settings": "Yleiset asetukset",
"dns_settings": "DNS-asetukset",
"dns_blocklists": "DNS-estolistat",
"dns_allowlists": "DNS-sallittujen listat",
"dns_blocklists": "DNS-estot",
"dns_allowlists": "DNS-sallinnat",
"dns_blocklists_desc": "AdGuard Home estää estolistalla olevat verkkotunnukset.",
"dns_allowlists_desc": "DNS-sallittujen listalla olevat verkkotunnukset sallitaan myös silloin, jos ne ovat jollain muulla estolistalla.",
"custom_filtering_rules": "Omat suodatussäännöt",
@@ -257,12 +257,12 @@
"query_log_cleared": "Pyyntöhistorian tyhjennys onnistui",
"query_log_updated": "Pyyntöhistorian päivitys onnistui",
"query_log_clear": "Tyhjennä pyyntöhistoria",
"query_log_retention": "Pyyntöhistorian säilytys",
"query_log_retention": "Kyselylokien kierto",
"query_log_enable": "Käytä historiaa",
"query_log_configuration": "Historian määritys",
"query_log_disabled": "Pyyntöhistoria ei ole käytössä. Voit ottaa sen käyttöön <0>asetuksissa</0>",
"query_log_strict_search": "Käytä tarkalle haulle lainausmerkkejä",
"query_log_retention_confirm": "Haluatko varmasti muuttaa pyyntöhistoriasi säilytysaikaa? Jos lyhennät aikaa, joitakin tietoja menetetään",
"query_log_retention_confirm": "Haluatko varmasti muuttaa kyselylokin kiertoa? Jos pienennät intervalliarvoa, osa tiedoista menetetään",
"anonymize_client_ip": "Piilota päätelaitteen IP-osoite",
"anonymize_client_ip_desc": "Älä tallenna päätelaitteen täydellistä IP-osoitetta historiaan ja tilastoihin.",
"dns_config": "DNS-palvelimen määritys",
@@ -627,7 +627,7 @@
"cache_optimistic": "Optimistinen välimuisti",
"cache_optimistic_desc": "Pakota AdGuard Home vastaamaan välimuistista vaikka tiedot olisivat vanhentuneet. Pyri samalla myös päivittämään tiedot.",
"filter_category_general": "Yleiset",
"filter_category_security": "Turvallisuus",
"filter_category_security": "Tietoturva",
"filter_category_regional": "Alueelliset",
"filter_category_other": "Muut",
"filter_category_general_desc": "Listat, jotka estävät seurannan ja mainokset useimmilla laitteilla",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Poista suojaus käytöstä {{count}} tunniksi",
"disable_notify_for_hours_plural": "Poista suojaus käytöstä {{count}} tunniksi",
"disable_notify_until_tomorrow": "Poista suojaus käytöstä huomiseen asti",
"enable_protection_timer": "Suojaus otetaan käyttöön {{time}} kuluttua"
"enable_protection_timer": "Suojaus otetaan käyttöön {{time}} kuluttua",
"custom_retention_input": "Syötä säilytysaika tunteina",
"custom_rotation_input": "Syötä uudistusaika tunteina",
"protection_section_label": "Suojaus",
"log_and_stats_section_label": "Kyselyhistoria ja tilastot",
"ignore_query_log": "Älä huomioi tätä päätettä kyselyhistoriassa",
"ignore_statistics": "Älä huomioi tätä päätettä tilastoissa"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Le journal des requêtes a été effacé",
"query_log_updated": "Le journal des requêtes a été mis à jour",
"query_log_clear": "Effacer journal des requêtes",
"query_log_retention": "Rétention du journal des requêtes",
"query_log_retention": "Rotation des journaux de requêtes",
"query_log_enable": "Activer le journal",
"query_log_configuration": "Configuration du journal",
"query_log_disabled": "Le journal des requêtes est désactivé et peut être configuré dans les <0>paramètres</0>",
"query_log_strict_search": "Utilisez les doubles guillemets pour une recherche stricte",
"query_log_retention_confirm": "Êtes-vous sûr de vouloir modifier la rétention des journaux de requêtes ? Si vous diminuez la valeur de l'intervalle, certaines données seront perdues",
"query_log_retention_confirm": "Êtes-vous sûr de souhaiter modifier la rotation des journaux de requêtes ? Si vous diminuez la valeur de l'intervalle, certaines données seront perdues",
"anonymize_client_ip": "Anonymiser lIP du client",
"anonymize_client_ip_desc": "Ne pas enregistrer ladresse IP complète du client dans les journaux et statistiques",
"dns_config": "Configuration du serveur DNS",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Désactiver la protection pendant {{count}} heure",
"disable_notify_for_hours_plural": "Désactiver la protection pendant {{count}} heures",
"disable_notify_until_tomorrow": "Désactiver la protection jusqu'à demain",
"enable_protection_timer": "La protection sera activée dans {{time}}"
"enable_protection_timer": "La protection sera activée dans {{time}}",
"custom_retention_input": "Saisir la rétention en heures",
"custom_rotation_input": "Saisir la rotation en heures",
"protection_section_label": "Protection",
"log_and_stats_section_label": "Journal des requêtes et statistiques",
"ignore_query_log": "Ignorer ce client dans le journal des requêtes",
"ignore_statistics": "Ignorer ce client dans les statistiques"
}

View File

@@ -167,6 +167,7 @@
"enabled_parental_toast": "Omogućen roditeljski nadzor",
"disabled_safe_search_toast": "Onemogućeno sigurno pretraživanje",
"enabled_save_search_toast": "Omogućeno sigurno pretraživanje",
"updated_save_search_toast": "Ažurirane postavke sigurnog pretraživanja",
"enabled_table_header": "Omogućeno",
"name_table_header": "Naziv",
"list_url_table_header": "URL popisa",
@@ -256,12 +257,12 @@
"query_log_cleared": "Zapisnik upita je uspješno uklonjen",
"query_log_updated": "Zapisnik upita je uspješno ažuriran",
"query_log_clear": "Očisti zapisnik upita",
"query_log_retention": "Spremanje zapisnika upita",
"query_log_retention": "Rotacija dnevnika upita",
"query_log_enable": "Omogući zapise",
"query_log_configuration": "Postavke zapisa",
"query_log_disabled": "Zapisnik upita je onemogućen i može se postaviti u <0>postavkama</0>",
"query_log_strict_search": "Koristite dvostruke navodnike za strogo pretraživanje",
"query_log_retention_confirm": "Jeste li sigurni da želite promijeniti zadržavanje zapisnika upita? Ako smanjite vrijednost intervala, neki će podaci biti izgubljeni",
"query_log_retention_confirm": "Jeste li sigurni da želite promijeniti rotaciju dnevnika upita? Ako smanjite vrijednost intervala, neki će se podaci izgubiti",
"anonymize_client_ip": "Anonimiraj IP klijenta",
"anonymize_client_ip_desc": "Ne spremajte cijelu IP adresu klijenta u zapisnike i statistike",
"dns_config": "DNS postavke poslužitelja",
@@ -290,6 +291,8 @@
"rate_limit": "Ograničenje",
"edns_enable": "Omogući podmrežu klijenta EDNS-a",
"edns_cs_desc": "Dodajte opciju EDNS klijentske podmreže (ECS) uzvodnim zahtjevima i zabilježite vrijednosti koje su klijenti poslali u dnevnik upita.",
"edns_use_custom_ip": "Koristi prilagođeni IP za EDNS",
"edns_use_custom_ip_desc": "Dopusti korištenje prilagođenog IP-a za EDNS",
"rate_limit_desc": "Broj zahtjeva u sekundi koji su dopušteni po jednom klijentu. Postavljanje na 0 znači neograničeno.",
"blocking_ipv4_desc": "Povratna IP adresa za blokirane A zahtjeve",
"blocking_ipv6_desc": "Povratna IP adresa za blokirane AAAA zahtjeve",
@@ -523,6 +526,10 @@
"statistics_retention_confirm": "Jeste li sigurni da želite promijeniti zadržavanje statistike? Ako smanjite vrijednost intervala, neki će podaci biti izgubljeni",
"statistics_cleared": "Statistika je uspješno uklonjenja",
"statistics_enable": "Omogući statistiku",
"ignore_domains": "Zanemarene domene (odvojene novim retkom)",
"ignore_domains_title": "Zanemarene domene",
"ignore_domains_desc_stats": "Upiti za ove domene ne upisuju se u statistiku",
"ignore_domains_desc_query": "Upiti za te domene nisu zapisani u zapisnik upita",
"interval_hours": "{{count}} sata/i",
"interval_hours_plural": "{{count}} sata/i",
"filters_configuration": "Postavke filtara",
@@ -642,5 +649,30 @@
"anonymizer_notification": "<0>Napomena:</0>IP anonimizacija je omogućena. Možete ju onemogućiti u <1>općim postavkama</1>.",
"confirm_dns_cache_clear": "Jeste li sigurni da želite očistiti DNS predmemoriju?",
"cache_cleared": "DNS predmemorija je uspješno izbrisana",
"clear_cache": "Očisti predmemoriju"
"clear_cache": "Očisti predmemoriju",
"make_static": "Učini statičnim",
"theme_auto_desc": "Automatski (na temelju sheme boja vašeg uređaja)",
"theme_dark_desc": "Tamna tema",
"theme_light_desc": "Svijetla tema",
"disable_for_seconds": "Za {{count}} sekundi",
"disable_for_seconds_plural": "Za {{count}} sekundi",
"disable_for_minutes": "Za {{count}} minuta",
"disable_for_minutes_plural": "Za {{count}} minuta",
"disable_for_hours": "Za {{count}} sati",
"disable_for_hours_plural": "Za {{count}} sati",
"disable_until_tomorrow": "Do sutra",
"disable_notify_for_seconds": "Isključi zaštitu na {{count}} sekundi",
"disable_notify_for_seconds_plural": "Onemogući zaštitu na {{count}} sekundi",
"disable_notify_for_minutes": "Isključi zaštitu na {{count}} minuta",
"disable_notify_for_minutes_plural": "Isključi zaštitu na {{count}} minuta",
"disable_notify_for_hours": "Isključi zaštitu na {{count}} sati",
"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 omogućena u {{time}}",
"custom_retention_input": "Unesite zadržavanje u satima",
"custom_rotation_input": "Unesite rotaciju u satima",
"protection_section_label": "Zaštita",
"log_and_stats_section_label": "Zapisnik upita i statistika",
"ignore_query_log": "Zanemari ovog klijenta u zapisniku upita",
"ignore_statistics": "Ignorirajte ovog klijenta u statistici"
}

View File

@@ -642,5 +642,6 @@
"anonymizer_notification": "<0>Megjegyzés:</0> Az IP anonimizálás engedélyezve van. Az <1>Általános beállításoknál letilthatja</1> .",
"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"
"clear_cache": "Gyorsítótár törlése",
"protection_section_label": "Védelem"
}

View File

@@ -641,5 +641,6 @@
"anonymizer_notification": "<0>Catatan:</0> Anonimisasi IP diaktifkan. Anda dapat menonaktifkannya di <1>Pengaturan umum</1> .",
"confirm_dns_cache_clear": "Apakah Anda yakin ingin menghapus cache DNS?",
"cache_cleared": "Cache DNS berhasil dibersihkan",
"clear_cache": "Hapus cache"
"clear_cache": "Hapus cache",
"protection_section_label": "Perlindungan"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Il registro richieste è stato correttamente cancellato",
"query_log_updated": "Il registro richieste è stato correttamente aggiornato",
"query_log_clear": "Cancella registri richieste",
"query_log_retention": "Conservazione dei registri richieste",
"query_log_retention": "Rotazione dei registri richieste",
"query_log_enable": "Attiva registro",
"query_log_configuration": "Configurazione registri",
"query_log_disabled": "Il registro richieste è stato disattivato e può essere configurata dalle <0>impostazioni</0>",
"query_log_strict_search": "Utilizzare le doppie virgolette per una ricerca precisa",
"query_log_retention_confirm": "Sei sicuro di voler modificare il registro delle richieste? Se il valore di intervallo dovesse diminuire, alcuni dati andranno persi",
"query_log_retention_confirm": "Sei sicuro di voler modificare il registro delle richieste? Se si riduce il valore dell'intervallo, alcuni dati andranno persi",
"anonymize_client_ip": "Anonimizza client IP",
"anonymize_client_ip_desc": "Non salvare l'indirizzo IP completo del client nel registro o nelle statistiche",
"dns_config": "Configurazione server DNS",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Disattiva la protezione per {{count}} ora",
"disable_notify_for_hours_plural": "Disattiva la protezione per {{count}} ore",
"disable_notify_until_tomorrow": "Disattiva la protezione fino a domani",
"enable_protection_timer": "La protezione verrà attivata in {{time}}"
"enable_protection_timer": "La protezione verrà attivata in {{time}}",
"custom_retention_input": "Inserisci la conservazione in ore",
"custom_rotation_input": "Inserisci la rotazione in ore",
"protection_section_label": "Protezione",
"log_and_stats_section_label": "Registro richieste e statistiche",
"ignore_query_log": "Ignora questo client nel registro delle richieste",
"ignore_statistics": "Ignora questo cliente nelle statistiche"
}

View File

@@ -257,12 +257,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": "ログと統計にクライアントのフルIPアドレスを保存しないようにします。",
"dns_config": "DNSサーバ設定",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "保護を {{count}} 時間無効にする",
"disable_notify_for_hours_plural": "保護を {{count}} 時間無効にする",
"disable_notify_until_tomorrow": "明日まで保護を無効にする",
"enable_protection_timer": "保護は後 {{time}} で有効になります"
"enable_protection_timer": "保護は後 {{time}} で有効になります",
"custom_retention_input": "保持期間を入力してください(時間単位)",
"custom_rotation_input": "ローテーションを入力してください(時間単位)",
"protection_section_label": "AdGuardによる保護",
"log_and_stats_section_label": "クエリ・ログと統計情報",
"ignore_query_log": "クエリ・ログでこのクライアントを無視する",
"ignore_statistics": "統計でこのクライアントを無視する"
}

View File

@@ -257,12 +257,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": "클라이언트의 전체 IP 주소를 로그와 통계에 저장하저장하지 마세요",
"dns_config": "DNS 서버 설정",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "{{count}}시간 동안 보호 기능 비활성화",
"disable_notify_for_hours_plural": "{{count}}시간 동안 보호 기능 비활성화",
"disable_notify_until_tomorrow": "내일까지 보호 기능 비활성화",
"enable_protection_timer": "{{time}}에 보호 기능이 활성화됩니다."
"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

@@ -257,12 +257,12 @@
"query_log_cleared": "Het query logboek is succesvol geleegd",
"query_log_updated": "Het query logboek is succesvol bijgewerkt",
"query_log_clear": "Leeg query logs",
"query_log_retention": "Query logs bewaartermijn",
"query_log_retention": "Query logs rotatie",
"query_log_enable": "Log bestanden inschakelen",
"query_log_configuration": "Logbestanden instellingen",
"query_log_disabled": "Het query logboek is uitgeschakeld en kan worden geconfigureerd in de <0>instellingen</0>",
"query_log_strict_search": "Gebruik dubbele aanhalingstekens voor strikt zoeken",
"query_log_retention_confirm": "Weet u zeker dat u de bewaartermijn van het query logboek wilt wijzigen? Als u de intervalwaarde verlaagt, gaan sommige gegevens verloren",
"query_log_retention_confirm": "Weet u zeker dat u de rotatie van het querylogboek wilt wijzigen? Als u de intervalwaarde verlaagt, gaan sommige gegevens verloren",
"anonymize_client_ip": "Cliënt IP anonimiseren",
"anonymize_client_ip_desc": "Het volledige IP-adres van de cliënt niet opnemen in logboeken en statistiekbestanden",
"dns_config": "DNS-server configuratie",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Beveiliging uitschakelen voor {{count}} uur",
"disable_notify_for_hours_plural": "Beveiliging uitschakelen voor {{count}} uren",
"disable_notify_until_tomorrow": "Beveiliging uitschakelen tot morgen",
"enable_protection_timer": "Bescherming wordt ingeschakeld over {{time}}"
"enable_protection_timer": "Bescherming wordt ingeschakeld over {{time}}",
"custom_retention_input": "Voer retentie in uren in",
"custom_rotation_input": "Voer rotatie in uren in",
"protection_section_label": "Bescherming",
"log_and_stats_section_label": "Aanvragenlogboek en statistieken",
"ignore_query_log": "Deze client negeren in het aanvragenlogboek",
"ignore_statistics": "Deze client negeren in de statistieken"
}

View File

@@ -282,6 +282,8 @@
"blocking_mode_null_ip": "Null IP: Svar med en 0-IP-adresse (0.0.0.0 for A; :: for AAAA)",
"blocking_mode_custom_ip": "Tilpasset IP: Svar med en manuelt valgt IP-adresse",
"theme_auto": "Auto",
"theme_light": "Lyst tema",
"theme_dark": "Mørkt tema",
"upstream_dns_client_desc": "Hvis dette feltet holdes tomt, vil AdGuard Home bruke tjenerne som er satt opp i <0>DNS-innstillingene</0>.",
"tracker_source": "Sporerkilde",
"source_label": "Kilde",
@@ -614,5 +616,6 @@
"use_saved_key": "Bruk den tidligere lagrede nøkkelen",
"parental_control": "Foreldrekontroll",
"safe_browsing": "Sikker surfing",
"served_from_cache": "{{value}} <i>(formidlet fra mellomlageret)</i>"
"served_from_cache": "{{value}} <i>(formidlet fra mellomlageret)</i>",
"protection_section_label": "Beskyttelse"
}

View File

@@ -167,6 +167,7 @@
"enabled_parental_toast": "Włączona Kontrola Rodzicielska",
"disabled_safe_search_toast": "Wyłączone bezpieczne wyszukiwanie",
"enabled_save_search_toast": "Włączone bezpieczne wyszukiwanie",
"updated_save_search_toast": "Zaktualizowano ustawienia bezpiecznego wyszukiwania",
"enabled_table_header": "Włączone",
"name_table_header": "Nazwa",
"list_url_table_header": "Adres URL listy",
@@ -221,7 +222,7 @@
"all_lists_up_to_date_toast": "Wszystkie listy są już aktualne",
"updated_upstream_dns_toast": "Serwery nadrzędne zostały pomyślnie zapisane",
"dns_test_ok_toast": "Określone serwery DNS działają poprawnie",
"dns_test_not_ok_toast": "Serwer \"{{key}}\": nie można go użyć, sprawdź, czy napisałeś go poprawnie",
"dns_test_not_ok_toast": "Serwer \"{{key}}\": nie może być użyte, sprawdź, czy zapisano go poprawnie",
"dns_test_warning_toast": "Upstream \"{{key}}\" nie odpowiada na zapytania testowe i może nie działać prawidłowo",
"unblock": "Odblokuj",
"block": "Zablokuj",
@@ -256,12 +257,12 @@
"query_log_cleared": "Dziennik zapytań został pomyślnie wyczyszczony",
"query_log_updated": "Dziennik zapytań został zaktualizowany",
"query_log_clear": "Wyczyść dzienniki zapytań",
"query_log_retention": "Przechowywanie dzienników zapytań",
"query_log_retention": "Rotacja dzienników zapytań",
"query_log_enable": "Włącz dziennik",
"query_log_configuration": "Konfiguracja dzienników",
"query_log_disabled": "Dziennik zapytań jest wyłączony i można go skonfigurować w <0>ustawieniach</0>",
"query_log_strict_search": "Używaj podwójnych cudzysłowów do ścisłego wyszukiwania",
"query_log_retention_confirm": "Czy na pewno chcesz zmienić sposób przechowywania dziennika zapytań? Jeśli zmniejszysz wartość interwału, niektóre dane zostaną utracone",
"query_log_retention_confirm": "Czy na pewno chcesz zmienić rotację dziennika zapytań? Jeśli zmniejszysz wartość interwału, niektóre dane zostaną utracone",
"anonymize_client_ip": "Anonimizuj adres IP klienta",
"anonymize_client_ip_desc": "Nie zapisuj pełnego adresu IP w dziennikach i statystykach",
"dns_config": "Konfiguracja serwera DNS",
@@ -290,6 +291,8 @@
"rate_limit": "Limit ilościowy",
"edns_enable": "Włącz podsieć klienta EDNS",
"edns_cs_desc": "Dodaj opcję podsieci klienta EDNS (ECS) do żądań nadrzędnych i rejestruj wartości wysyłane przez klientów w dzienniku zapytań.",
"edns_use_custom_ip": "Użyj niestandardowego adresu IP dla EDNS",
"edns_use_custom_ip_desc": "Zezwól na użycie niestandardowego adresu IP dla EDNS",
"rate_limit_desc": "Liczba żądań na sekundę dozwolona na klienta. Ustawienie wartości 0 oznacza brak ograniczeń.",
"blocking_ipv4_desc": "Adres IP, który ma zostać zwrócony w przypadku zablokowanego żądania A",
"blocking_ipv6_desc": "Adres IP, który ma zostać zwrócony w przypadku zablokowanego żądania AAAA",
@@ -343,7 +346,7 @@
"install_devices_windows_list_2": "Przejdź do kategorii Sieć i Internet, a następnie do Centrum sieci i udostępniania.",
"install_devices_windows_list_3": "W lewym panelu kliknij \"Zmień ustawienia adaptera\".",
"install_devices_windows_list_4": "Kliknij prawym przyciskiem myszy aktywne połączenie i wybierz Właściwości.",
"install_devices_windows_list_5": "Znajdź na liście \"Protokół internetowy w wersji 4 (TCP/IPv4)\" (lub w przypadku IPv6 \"Protokół internetowy w wersji 6 (TCP/IPv6)\"), zaznacz go i ponownie kliknij na Właściwości.",
"install_devices_windows_list_5": "Znajdź na liście \"Protokół internetowy w wersji 4 (TCP/IPv4)\" (lub w przypadku IPv6 \"Protokół internetowy w wersji 6 (TCP/IPv6)\"), zaznacz go i ponownie kliknij Właściwości.",
"install_devices_windows_list_6": "Wybierz opcję \"Użyj następujących adresów serwerów DNS\" i wprowadź adresy serwerów AdGuard Home.",
"install_devices_macos_list_1": "Kliknij ikonę Apple i przejdź do Preferencje systemowe.",
"install_devices_macos_list_2": "Kliknij Sieć.",
@@ -393,7 +396,7 @@
"encryption_issuer": "Zgłaszający",
"encryption_hostnames": "Nazwy hostów",
"encryption_reset": "Czy na pewno chcesz zresetować ustawienia szyfrowania?",
"encryption_warning": "Uwaga!",
"encryption_warning": "Uwaga",
"topline_expiring_certificate": "Twój certyfikat SSL wkrótce wygaśnie. Zaktualizuj <0>Ustawienia szyfrowania</0>.",
"topline_expired_certificate": "Twój certyfikat SSL wygasł. Zaktualizuj <0>Ustawienia szyfrowania</0>.",
"form_error_port_range": "Wpisz numer portu z zakresu 80-65535",
@@ -523,6 +526,10 @@
"statistics_retention_confirm": "Czy chcesz zmienić sposób przechowania statystyk? Jeżeli obniżysz wartość interwału, niektóre dane będą utracone",
"statistics_cleared": "Statystyki zostały pomyślnie wyczyszczone",
"statistics_enable": "Włącz statystyki",
"ignore_domains": "Ignorowane domeny (każda w nowym wierszu)",
"ignore_domains_title": "Ignorowane domeny",
"ignore_domains_desc_stats": "Zapytania dla tych domen nie są zapisywane do statystyk",
"ignore_domains_desc_query": "Zapytania dla tych domen nie są zapisywane do dziennika",
"interval_hours": "{{count}} godzina",
"interval_hours_plural": "{{count}} godziny",
"filters_configuration": "Konfiguracja filtrów",
@@ -535,7 +542,7 @@
"password_placeholder": "Wpisz hasło",
"sign_in": "Zaloguj się",
"sign_out": "Wyloguj się",
"forgot_password": "Zapomniałeś hasła?",
"forgot_password": "Zapomniano hasła?",
"forgot_password_desc": "Wykonaj <0>te kroki</0>, aby utworzyć nowe hasło do konta użytkownika.",
"location": "Lokalizacja",
"orgname": "Nazwa firmy",
@@ -642,5 +649,30 @@
"anonymizer_notification": "<0>Uwaga:</0> Anonimizacja IP jest włączona. Możesz ją wyłączyć w <1>Ustawieniach ogólnych</1>.",
"confirm_dns_cache_clear": "Czy na pewno chcesz wyczyścić pamięć podręczną DNS?",
"cache_cleared": "Pamięć podręczna DNS została pomyślnie wyczyszczona",
"clear_cache": "Wyczyść pamięć podręczną"
"clear_cache": "Wyczyść pamięć podręczną",
"make_static": "Ustaw adres statyczny",
"theme_auto_desc": "Automatycznie (na podstawie schematu kolorów Twojego urządzenia)",
"theme_dark_desc": "Ciemny motyw",
"theme_light_desc": "Jasny motyw",
"disable_for_seconds": "Na {{count}} sekundę",
"disable_for_seconds_plural": "Na {{count}} sekund",
"disable_for_minutes": "Na {{count}} minutę",
"disable_for_minutes_plural": "Na {{count}} minut",
"disable_for_hours": "Na {{count}} godzinę",
"disable_for_hours_plural": "Na {{count}} godziny",
"disable_until_tomorrow": "Do jutra",
"disable_notify_for_seconds": "Wyłącz ochronę na {{count}} sekundę",
"disable_notify_for_seconds_plural": "Wyłącz ochronę na {{count}} sekund",
"disable_notify_for_minutes": "Wyłącz ochronę na {{count}} minutę",
"disable_notify_for_minutes_plural": "Wyłącz ochronę na {{count}} minut",
"disable_notify_for_hours": "Wyłącz ochronę na {{count}} godzinę",
"disable_notify_for_hours_plural": "Wyłącz ochronę na {{count}} godziny",
"disable_notify_until_tomorrow": "Wyłącz ochronę do jutra",
"enable_protection_timer": "Ochrona zostanie włączona za {{time}}",
"custom_retention_input": "Wprowadź retencję w godzinach",
"custom_rotation_input": "Wprowadź rotację w godzinach",
"protection_section_label": "Ochrona",
"log_and_stats_section_label": "Dziennik zapytań i statystyki",
"ignore_query_log": "Zignoruj tego klienta w dzienniku zapytań",
"ignore_statistics": "Ignoruj tego klienta w statystykach"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "O registro de consulta foi limpo com sucesso",
"query_log_updated": "O registro da consulta foi atualizado com sucesso",
"query_log_clear": "Limpar registros de consulta",
"query_log_retention": "Arquivamento de registros de consultas",
"query_log_retention": "Rotação de registros de consulta",
"query_log_enable": "Ativar registro",
"query_log_configuration": "Configuração de registros",
"query_log_disabled": "O registro de consulta está desativado e pode ser configurado em <0>configurações</0>",
"query_log_strict_search": "Use aspas duplas para uma pesquisa mais criteriosa",
"query_log_retention_confirm": "Você tem certeza de que deseja alterar o arquivamento do registro de consulta? Se diminuir o valor de intervalo, alguns dados serão perdidos",
"query_log_retention_confirm": "Tem a certeza de que quer alterar a rotação do registo de consulta? Se diminuir o valor do intervalo, alguns dados serão perdidos",
"anonymize_client_ip": "Tornar anônimo o IP do cliente",
"anonymize_client_ip_desc": "Não salva o endereço de IP completo do cliente em registros ou estatísticas",
"dns_config": "Configuração do servidor DNS",
@@ -529,7 +529,7 @@
"ignore_domains": "Domínios ignorados (separados por nova linha)",
"ignore_domains_title": "Domínios ignorados",
"ignore_domains_desc_stats": "As consultas para esses domínios não são gravadas nas estatísticas",
"ignore_domains_desc_query": "As consultas para esses domínios não são gravadas no log de consulta",
"ignore_domains_desc_query": "As consultas para esses domínios não são gravadas no registro de consulta",
"interval_hours": "{{count}} hora",
"interval_hours_plural": "{{count}} horas",
"filters_configuration": "Configuração de filtros",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Desativar proteção por {{count}} hora",
"disable_notify_for_hours_plural": "Desativar proteção por {{count}} horas",
"disable_notify_until_tomorrow": "Desativar a proteção até amanhã",
"enable_protection_timer": "A proteção será ativada em {{time}}"
"enable_protection_timer": "A proteção será ativada em {{time}}",
"custom_retention_input": "Insira a retenção em horas",
"custom_rotation_input": "Insira a rotação em horas",
"protection_section_label": "Proteção",
"log_and_stats_section_label": "Registro de consultas e estatísticas",
"ignore_query_log": "Ignorar este cliente no registo de consultas",
"ignore_statistics": "Ignorar este cliente nas estatísticas"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "O registo de consulta foi limpo com sucesso",
"query_log_updated": "O registo da consulta foi atualizado com sucesso",
"query_log_clear": "Limpar registos de consulta",
"query_log_retention": "Retenção de registos de consulta",
"query_log_retention": "Rotação de registros de consulta",
"query_log_enable": "Ativar registo",
"query_log_configuration": "Definições do registo",
"query_log_disabled": "O registo de consulta está desativado e pode ser configurado em <0>definições</0>",
"query_log_strict_search": "Usar aspas duplas para uma pesquisa rigorosa",
"query_log_retention_confirm": "Tem a certeza de que deseja alterar a retenção do registo de consulta? Se diminuir o valor do intervalo, alguns dados serão perdidos",
"query_log_retention_confirm": "Tem a certeza de que quer alterar a rotação do registo de consulta? Se diminuir o valor do intervalo, alguns dados serão perdidos",
"anonymize_client_ip": "Tornar anónimo o IP do cliente",
"anonymize_client_ip_desc": "Não gurda o endereço de IP completo do cliente em registo ou estatísticas",
"dns_config": "Definição do servidor DNS",
@@ -529,7 +529,7 @@
"ignore_domains": "Domínios ignorados (separados por nova linha)",
"ignore_domains_title": "Domínios ignorados",
"ignore_domains_desc_stats": "As consultas para estes domínios não aparecem nas estatísticas",
"ignore_domains_desc_query": "As consultas para estes domínios nãoaparecem no registo de consultas",
"ignore_domains_desc_query": "As consultas para estes domínios não aparecem no registo de consultas",
"interval_hours": "{{count}} hora",
"interval_hours_plural": "{{count}} horas",
"filters_configuration": "Definição dos filtros",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Desativar proteção por {{count}} hora",
"disable_notify_for_hours_plural": "Desativar proteção por {{count}} horas",
"disable_notify_until_tomorrow": "Desativar a proteção até amanhã",
"enable_protection_timer": "A proteção será habilitada em {{time}}"
"enable_protection_timer": "A proteção será habilitada em {{time}}",
"custom_retention_input": "Insira a retenção em horas",
"custom_rotation_input": "Insira a rotação em horas",
"protection_section_label": "Proteção",
"log_and_stats_section_label": "Log de consulta e estatísticas",
"ignore_query_log": "Ignorar este cliente no log de consulta",
"ignore_statistics": "Ignorar este cliente nas estatísticas"
}

View File

@@ -642,5 +642,6 @@
"anonymizer_notification": "<0>Nota:</0> Anonimizarea IP este activată. Puteți să o dezactivați în <1>Setări generale</1>.",
"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"
"clear_cache": "Goliți memoria cache",
"protection_section_label": "Protecție"
}

View File

@@ -257,12 +257,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": "Не сохранять полный IP-адрес клиента в журналах и статистике",
"dns_config": "Настройки DNS-сервера",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Отключить защиту на {{count}} час",
"disable_notify_for_hours_plural": "Отключить защиту на {{count}} часов",
"disable_notify_until_tomorrow": "Отключить защиту до завтра",
"enable_protection_timer": "Защита будет включена в {{time}}"
"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

@@ -257,12 +257,12 @@
"query_log_cleared": "Denník dopytov bol úspešne vymazaný",
"query_log_updated": "Denník dopytov bol úspešne aktualizovaný",
"query_log_clear": "Vymazať denníky dopytov",
"query_log_retention": "Obdobie záznamu denníka dopytov",
"query_log_retention": "Rotácia denníkov dopytov",
"query_log_enable": "Zapnúť denník",
"query_log_configuration": "Konfigurácia denníka",
"query_log_disabled": "Protokol dopytov je vypnutý a možno ho nakonfigurovať v <0>nastaveniach</0>",
"query_log_strict_search": "Na prísne vyhľadávanie použite dvojité úvodzovky",
"query_log_retention_confirm": "Naozaj chcete zmeniť uchovávanie denníku dopytov? Ak znížite hodnotu intervalu, niektoré údaje sa stratia",
"query_log_retention_confirm": "Naozaj chcete zmeniť rotáciu denníka dopytov? Ak znížite hodnotu intervalu, niektoré údaje sa stratia",
"anonymize_client_ip": "Anonymizujte IP klienta",
"anonymize_client_ip_desc": "Neukladať úplnú IP adresu klienta do protokolov a štatistík",
"dns_config": "Konfigurácia DNS servera",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Vypnite ochranu na {{count}} hodinu",
"disable_notify_for_hours_plural": "Vypnite ochranu na {{count}} hodín",
"disable_notify_until_tomorrow": "Vypnúť ochranu do zajtra",
"enable_protection_timer": "Ochrana bude zapnutá o {{time}}"
"enable_protection_timer": "Ochrana bude zapnutá o {{time}}",
"custom_retention_input": "Zadajte retenciu v hodinách",
"custom_rotation_input": "Zadajte rotáciu v hodinách",
"protection_section_label": "Ochrana",
"log_and_stats_section_label": "Protokol dopytov a štatistiky",
"ignore_query_log": "Ignorovať tohto klienta v denníku dopytov",
"ignore_statistics": "Ignorovanie tohto klienta v štatistikách"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Dnevnik poizvedb je uspešno izbrisan",
"query_log_updated": "Dnevnik poizvedb je bil uspešno posodobljen",
"query_log_clear": "Počisti dnevnike poizvedb",
"query_log_retention": "Zadrževanje dnevnikov poizvedb",
"query_log_retention": "Rotacija dnevnikov poizvedb",
"query_log_enable": "Omogoči dnevni",
"query_log_configuration": "Konfiguracija dnevnikov",
"query_log_disabled": "Dnevnik poizvedb je onemogočen in ga je mogoče konfigurirati v <0>nastavitvah</0>",
"query_log_strict_search": "Za strogo iskanje uporabite dvojne narekovaje",
"query_log_retention_confirm": "Ali ste prepričani, da želite spremeniti zadrževanje dnevnika poizvedb? Če zmanjšate vrednost intervala, bodo nekateri podatki izgubljeni",
"query_log_retention_confirm": "Ali ste prepričani, da želite spremeniti rotacijo dnevnika poizvedb? Če zmanjšate vrednost intervala, bodo nekateri podatki izgubljeni",
"anonymize_client_ip": "Anonimiziraj odjemalca IP",
"anonymize_client_ip_desc": "Ne shrani celotnega naslova IP odjemalca v dnevnikih ali statistiki",
"dns_config": "Konfiguracija strežnika DNS",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Onemogoči zaščito za {{count}} uro",
"disable_notify_for_hours_plural": "Onemogoči zaščito za {{count}} ur",
"disable_notify_until_tomorrow": "Onemogoči zaščito do jutri",
"enable_protection_timer": "Zaščita bo omogočena ob {{time}}"
"enable_protection_timer": "Zaščita bo omogočena ob {{time}}",
"custom_retention_input": "Vnesite zadrževanje v urah",
"custom_rotation_input": "Vnesite rotacijo v urah",
"protection_section_label": "Zaščita",
"log_and_stats_section_label": "Dnevnik poizvedb in statistika",
"ignore_query_log": "Ignorirajte tega odjemalca v dnevniku poizvedb",
"ignore_statistics": "Ignoriranje tega odjemalca v statistiki"
}

View File

@@ -642,5 +642,6 @@
"anonymizer_notification": "<0>Nota:</0> IP prepoznavanje je omogućeno. Možete ga onemogućiti u opštim <1>postavkama</1>.",
"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"
"clear_cache": "Obriši keš memoriju",
"protection_section_label": "Zaštita"
}

View File

@@ -257,12 +257,12 @@
"query_log_cleared": "Sorgu günlüğü başarıyla temizlendi",
"query_log_updated": "Sorgu günlüğü başarıyla güncellendi",
"query_log_clear": "Sorgu günlüklerini temizle",
"query_log_retention": "Sorgu günlüklerini sakla",
"query_log_retention": "Sorgu günlükleri rotasyonu",
"query_log_enable": "Günlüğü etkinleştir",
"query_log_configuration": "Günlük yapılandırması",
"query_log_disabled": "Sorgu günlüğü devre dışı bırakıldı, bunu <0>ayarlar</0> kısmından yapılandırılabilirsiniz",
"query_log_strict_search": "Tam arama için çift tırnak işareti kullanın",
"query_log_retention_confirm": "Sorgu günlüğü saklama süresini değiştirmek istediğinize emin misiniz? Aralık değerini azaltırsanız, bazı veriler kaybolacaktır",
"query_log_retention_confirm": "Sorgu günlüğü rotasyonunu değiştirmek istediğinizden emin misiniz? Aralık değerini düşürürseniz, bazı veriler kaybolacaktır.",
"anonymize_client_ip": "İstemcinin IP adresini gizle",
"anonymize_client_ip_desc": "İstemcinin tam IP adresini günlüklere veya istatistiklere kaydetmeyin",
"dns_config": "DNS sunucu yapılandırması",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "Korumayı {{count}} saatliğine devre dışı bırak",
"disable_notify_for_hours_plural": "Korumayı {{count}} saatliğine devre dışı bırak",
"disable_notify_until_tomorrow": "Korumayı yarına kadar devre dışı bırak",
"enable_protection_timer": "Koruma {{time}} içinde etkinleştirilecektir"
"enable_protection_timer": "Koruma {{time}} içinde etkinleştirilecektir",
"custom_retention_input": "Saklama süresini saat olarak girin",
"custom_rotation_input": "Rotasyonu saat cinsinden girin",
"protection_section_label": "Koruma",
"log_and_stats_section_label": "Sorgu günlüğü ve istatistikler",
"ignore_query_log": "Sorgu günlüğünde bu istemciyi yoksay",
"ignore_statistics": "İstatistiklerde bu istemciyi yoksay"
}

View File

@@ -167,6 +167,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 списку",
@@ -290,6 +291,8 @@
"rate_limit": "Обмеження швидкості",
"edns_enable": "Увімкнути відправку EDNS Client Subnet",
"edns_cs_desc": "Додавати параметр EDNS Client Subnet (ECS) до запитів до upstream-серверів, а також записувати в журнал значення, що надсилаються клієнтами.",
"edns_use_custom_ip": "Використання користувацької IP-адреси для EDNS",
"edns_use_custom_ip_desc": "Дозволити використовувати користувацьку IP-адресу для EDNS",
"rate_limit_desc": "Кількість запитів в секунду, які може робити один клієнт. Встановлене значення «0» означатиме необмежену кількість.",
"blocking_ipv4_desc": "IP-адреса, яку потрібно видати для заблокованого A запиту",
"blocking_ipv6_desc": "IP-адреса, яку потрібно видати для заблокованого АААА запиту",
@@ -523,6 +526,10 @@
"statistics_retention_confirm": "Ви впевнені, що хочете змінити тривалість статистики? Якщо зменшити значення інтервалу, деякі дані будуть втрачені",
"statistics_cleared": "Статистику успішно очищено",
"statistics_enable": "Увімкнути статистику",
"ignore_domains": "Ігноровані домени (по одному на рядок)",
"ignore_domains_title": "Ігноровані домени",
"ignore_domains_desc_stats": "Запити для цих доменів в статистику не пишуться",
"ignore_domains_desc_query": "Запити для цих доменів не записуються до журналу запитів",
"interval_hours": "{{count}} година",
"interval_hours_plural": "{{count}} годин(и)",
"filters_configuration": "Конфігурація фільтрів",
@@ -642,5 +649,30 @@
"anonymizer_notification": "<0>Примітка:</0> IP-анонімізацію ввімкнено. Ви можете вимкнути його в <1>Загальні налаштування</1> .",
"confirm_dns_cache_clear": "Ви впевнені, що бажаєте очистити кеш DNS?",
"cache_cleared": "Кеш DNS успішно очищено",
"clear_cache": "Очистити кеш"
"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

@@ -642,5 +642,6 @@
"anonymizer_notification": "<0> Lưu ý:</0> Tính năng ẩn danh IP được bật. Bạn có thể tắt nó trong <1> Cài đặt chung</1>.",
"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"
"clear_cache": "Xóa bộ nhớ cache",
"protection_section_label": "Sự bảo vệ"
}

View File

@@ -257,12 +257,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": "不要在日志和统计信息中保存客户端的完整 IP 地址",
"dns_config": "DNS 服务配置",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "禁用保护 {{count}} 小时",
"disable_notify_for_hours_plural": "禁用保护 {{count}} 小时",
"disable_notify_until_tomorrow": "禁用保护直到明天",
"enable_protection_timer": "保护将于 {{time}} 启用"
"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

@@ -257,12 +257,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": "不要儲存用戶端之完整的 IP 位址到記錄或統計資料裡",
"dns_config": "DNS 伺服器配置",
@@ -668,5 +668,11 @@
"disable_notify_for_hours": "計 {{count}} 小時禁用防護",
"disable_notify_for_hours_plural": "計 {{count}} 小時禁用防護",
"disable_notify_until_tomorrow": "禁用防護直到明天",
"enable_protection_timer": "防護將於 {{time}} 被啟用"
"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

@@ -49,6 +49,9 @@ export const setTlsConfig = (config) => async (dispatch, getState) => {
const dnsStatus = await apiClient.getGlobalStatus();
if (dnsStatus) {
if (dnsStatus.protection_disabled_duration === 0) {
dnsStatus.protection_disabled_duration = null;
}
dispatch(dnsStatusSuccess(dnsStatus));
}

View File

@@ -2,21 +2,6 @@ import { createAction } from 'redux-actions';
import apiClient from '../api/Api';
import { addErrorToast, addSuccessToast } from './toasts';
export const getBlockedServicesAvailableServicesRequest = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_REQUEST');
export const getBlockedServicesAvailableServicesFailure = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_FAILURE');
export const getBlockedServicesAvailableServicesSuccess = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_SUCCESS');
export const getBlockedServicesAvailableServices = () => async (dispatch) => {
dispatch(getBlockedServicesAvailableServicesRequest());
try {
const data = await apiClient.getBlockedServicesAvailableServices();
dispatch(getBlockedServicesAvailableServicesSuccess(data));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(getBlockedServicesAvailableServicesFailure());
}
};
export const getBlockedServicesRequest = createAction('GET_BLOCKED_SERVICES_REQUEST');
export const getBlockedServicesFailure = createAction('GET_BLOCKED_SERVICES_FAILURE');
export const getBlockedServicesSuccess = createAction('GET_BLOCKED_SERVICES_SUCCESS');

View File

@@ -479,19 +479,12 @@ class Api {
}
// Blocked services
BLOCKED_SERVICES_SERVICES = { path: 'blocked_services/services', method: 'GET' };
BLOCKED_SERVICES_LIST = { path: 'blocked_services/list', method: 'GET' };
BLOCKED_SERVICES_SET = { path: 'blocked_services/set', method: 'POST' };
BLOCKED_SERVICES_ALL = { path: 'blocked_services/all', method: 'GET' };
getBlockedServicesAvailableServices() {
const { path, method } = this.BLOCKED_SERVICES_SERVICES;
return this.makeRequest(path, method);
}
getAllBlockedServices() {
const { path, method } = this.BLOCKED_SERVICES_ALL;
return this.makeRequest(path, method);

View File

@@ -165,8 +165,7 @@ const App = () => {
}
const colorSchemeMedia = window.matchMedia('(prefers-color-scheme: dark)');
const prefersDark = colorSchemeMedia.matches;
setUITheme(prefersDark ? THEMES.dark : THEMES.light);
setUITheme(theme);
if (colorSchemeMedia.addEventListener !== undefined) {
colorSchemeMedia.addEventListener('change', (e) => {

View File

@@ -12,7 +12,6 @@ import { MODAL_TYPE } from '../../helpers/constants';
import {
getCurrentFilter,
getObjDiff,
} from '../../helpers/helpers';
import filtersCatalog from '../../helpers/filters/filters';
@@ -22,7 +21,7 @@ class DnsBlocklist extends Component {
this.props.getFilteringStatus();
}
handleSubmit = (values, _, { initialValues }) => {
handleSubmit = (values) => {
const { modalFilterUrl, modalType } = this.props.filtering;
switch (modalType) {
@@ -35,7 +34,12 @@ class DnsBlocklist extends Component {
break;
}
case MODAL_TYPE.CHOOSE_FILTERING_LIST: {
const changedValues = getObjDiff(initialValues, values);
const changedValues = Object.entries(values)?.reduce((acc, [key, value]) => {
if (value && key in filtersCatalog.filters) {
acc[key] = value;
}
return acc;
}, {});
Object.keys(changedValues)
.forEach((fieldName) => {

View File

@@ -41,6 +41,17 @@ const settingsCheckboxes = [
placeholder: 'use_adguard_parental',
},
];
const logAndStatsCheckboxes = [
{
name: 'ignore_querylog',
placeholder: 'ignore_query_log',
},
{
name: 'ignore_statistics',
placeholder: 'ignore_statistics',
},
];
const validate = (values) => {
const errors = {};
const { name, ids } = values;
@@ -148,6 +159,9 @@ let Form = (props) => {
settings: {
title: 'settings',
component: <div label="settings" title={props.t('main_settings')}>
<div className="form__label--bot form__label--bold">
{t('protection_section_label')}
</div>
{settingsCheckboxes.map((setting) => (
<div className="form__group" key={setting.name}>
<Field
@@ -185,6 +199,19 @@ let Form = (props) => {
</div>
))}
</div>
<div className="form__label--bold form__label--top form__label--bot">
{t('log_and_stats_section_label')}
</div>
{logAndStatsCheckboxes.map((setting) => (
<div className="form__group" key={setting.name}>
<Field
name={setting.name}
type="checkbox"
component={CheckboxField}
placeholder={t(setting.placeholder)}
/>
</div>
))}
</div>,
},
block_services: {

View File

@@ -1,25 +1,37 @@
import React from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import {
change,
Field,
formValueSelector,
reduxForm,
} from 'redux-form';
import { connect } from 'react-redux';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import {
CheckboxField,
renderRadioField,
toFloatNumber,
renderTextareaField,
renderTextareaField, renderInputField, renderRadioField,
} from '../../../helpers/form';
import {
FORM_NAME,
QUERY_LOG_INTERVALS_DAYS,
HOUR,
DAY,
RETENTION_CUSTOM,
RETENTION_CUSTOM_INPUT,
RETENTION_RANGE,
CUSTOM_INTERVAL,
} from '../../../helpers/constants';
import '../FormButton.css';
const getIntervalTitle = (interval, t) => {
switch (interval) {
case RETENTION_CUSTOM:
return t('settings_custom');
case 6 * HOUR:
return t('interval_6_hour');
case DAY:
@@ -42,11 +54,26 @@ const getIntervalFields = (processing, t, toNumber) => QUERY_LOG_INTERVALS_DAYS.
/>
));
const Form = (props) => {
let Form = (props) => {
const {
handleSubmit, submitting, invalid, processing, processingClear, handleClear, t,
handleSubmit,
submitting,
invalid,
processing,
processingClear,
handleClear,
t,
interval,
customInterval,
dispatch,
} = props;
useEffect(() => {
if (QUERY_LOG_INTERVALS_DAYS.includes(interval)) {
dispatch(change(FORM_NAME.LOG_CONFIG, CUSTOM_INTERVAL, null));
}
}, [interval]);
return (
<form onSubmit={handleSubmit}>
<div className="form__group form__group--settings">
@@ -73,6 +100,37 @@ const Form = (props) => {
</label>
<div className="form__group form__group--settings">
<div className="custom-controls-stacked">
<Field
key={RETENTION_CUSTOM}
name="interval"
type="radio"
component={renderRadioField}
value={QUERY_LOG_INTERVALS_DAYS.includes(interval)
? RETENTION_CUSTOM
: interval
}
placeholder={getIntervalTitle(RETENTION_CUSTOM, t)}
normalize={toFloatNumber}
disabled={processing}
/>
{!QUERY_LOG_INTERVALS_DAYS.includes(interval) && (
<div className="form__group--input">
<div className="form__desc form__desc--top">
{t('custom_rotation_input')}
</div>
<Field
key={RETENTION_CUSTOM_INPUT}
name={CUSTOM_INTERVAL}
type="number"
className="form-control"
component={renderInputField}
disabled={processing}
normalize={toFloatNumber}
min={RETENTION_RANGE.MIN}
max={RETENTION_RANGE.MAX}
/>
</div>
)}
{getIntervalFields(processing, t, toFloatNumber)}
</div>
</div>
@@ -96,7 +154,12 @@ const Form = (props) => {
<button
type="submit"
className="btn btn-success btn-standard btn-large"
disabled={submitting || invalid || processing}
disabled={
submitting
|| invalid
|| processing
|| (!QUERY_LOG_INTERVALS_DAYS.includes(interval) && !customInterval)
}
>
<Trans>save_btn</Trans>
</button>
@@ -121,8 +184,22 @@ Form.propTypes = {
processing: PropTypes.bool.isRequired,
processingClear: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
interval: PropTypes.number,
customInterval: PropTypes.number,
dispatch: PropTypes.func.isRequired,
};
const selector = formValueSelector(FORM_NAME.LOG_CONFIG);
Form = connect((state) => {
const interval = selector(state, 'interval');
const customInterval = selector(state, CUSTOM_INTERVAL);
return {
interval,
customInterval,
};
})(Form);
export default flow([
withTranslation(),
reduxForm({ form: FORM_NAME.LOG_CONFIG }),

View File

@@ -4,15 +4,22 @@ import { withTranslation } from 'react-i18next';
import Card from '../../ui/Card';
import Form from './Form';
import { HOUR } from '../../../helpers/constants';
class LogsConfig extends Component {
handleFormSubmit = (values) => {
const { t, interval: prevInterval } = this.props;
const { interval } = values;
const { interval, customInterval, ...rest } = values;
const data = { ...values, ignored: values.ignored ? values.ignored.split('\n') : [] };
const newInterval = customInterval ? customInterval * HOUR : interval;
if (interval !== prevInterval) {
const data = {
...rest,
ignored: values.ignored ? values.ignored.split('\n') : [],
interval: newInterval,
};
if (newInterval < prevInterval) {
// eslint-disable-next-line no-alert
if (window.confirm(t('query_log_retention_confirm'))) {
this.props.setLogsConfig(data);
@@ -32,7 +39,14 @@ class LogsConfig extends Component {
render() {
const {
t, enabled, interval, processing, processingClear, anonymize_client_ip, ignored,
t,
enabled,
interval,
processing,
processingClear,
anonymize_client_ip,
ignored,
customInterval,
} = this.props;
return (
@@ -46,6 +60,7 @@ class LogsConfig extends Component {
initialValues={{
enabled,
interval,
customInterval,
anonymize_client_ip,
ignored: ignored.join('\n'),
}}
@@ -62,6 +77,7 @@ class LogsConfig extends Component {
LogsConfig.propTypes = {
interval: PropTypes.number.isRequired,
customInterval: PropTypes.number,
enabled: PropTypes.bool.isRequired,
anonymize_client_ip: PropTypes.bool.isRequired,
processing: PropTypes.bool.isRequired,

View File

@@ -18,6 +18,11 @@
font-size: 14px;
}
.form__group--input {
max-width: 300px;
margin: 0 1.5rem 10px;
}
.form__group--checkbox {
margin-bottom: 25px;
}
@@ -100,6 +105,14 @@
margin-bottom: 0;
}
.form__label--bot {
margin-bottom: 10px;
}
.form__label--top {
margin-top: 10px;
}
.form__status {
margin-top: 10px;
font-size: 14px;

View File

@@ -1,32 +1,44 @@
import React from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import {
change, Field, formValueSelector, reduxForm,
} from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { connect } from 'react-redux';
import {
renderRadioField,
toNumber,
CheckboxField,
renderTextareaField,
toFloatNumber,
renderInputField,
} from '../../../helpers/form';
import {
FORM_NAME,
STATS_INTERVALS_DAYS,
DAY,
RETENTION_CUSTOM,
RETENTION_CUSTOM_INPUT,
CUSTOM_INTERVAL,
RETENTION_RANGE,
} from '../../../helpers/constants';
import '../FormButton.css';
const getIntervalTitle = (intervalMs, t) => {
switch (intervalMs / DAY) {
case 1:
switch (intervalMs) {
case RETENTION_CUSTOM:
return t('settings_custom');
case DAY:
return t('interval_24_hour');
default:
return t('interval_days', { count: intervalMs / DAY });
}
};
const Form = (props) => {
let Form = (props) => {
const {
handleSubmit,
processing,
@@ -35,8 +47,17 @@ const Form = (props) => {
handleReset,
processingReset,
t,
interval,
customInterval,
dispatch,
} = props;
useEffect(() => {
if (STATS_INTERVALS_DAYS.includes(interval)) {
dispatch(change(FORM_NAME.STATS_CONFIG, CUSTOM_INTERVAL, null));
}
}, [interval]);
return (
<form onSubmit={handleSubmit}>
<div className="form__group form__group--settings">
@@ -56,6 +77,37 @@ const Form = (props) => {
</div>
<div className="form__group form__group--settings mt-2">
<div className="custom-controls-stacked">
<Field
key={RETENTION_CUSTOM}
name="interval"
type="radio"
component={renderRadioField}
value={STATS_INTERVALS_DAYS.includes(interval)
? RETENTION_CUSTOM
: interval
}
placeholder={getIntervalTitle(RETENTION_CUSTOM, t)}
normalize={toFloatNumber}
disabled={processing}
/>
{!STATS_INTERVALS_DAYS.includes(interval) && (
<div className="form__group--input">
<div className="form__desc form__desc--top">
{t('custom_retention_input')}
</div>
<Field
key={RETENTION_CUSTOM_INPUT}
name={CUSTOM_INTERVAL}
type="number"
className="form-control"
component={renderInputField}
disabled={processing}
normalize={toFloatNumber}
min={RETENTION_RANGE.MIN}
max={RETENTION_RANGE.MAX}
/>
</div>
)}
{STATS_INTERVALS_DAYS.map((interval) => (
<Field
key={interval}
@@ -90,7 +142,12 @@ const Form = (props) => {
<button
type="submit"
className="btn btn-success btn-standard btn-large"
disabled={submitting || invalid || processing}
disabled={
submitting
|| invalid
|| processing
|| (!STATS_INTERVALS_DAYS.includes(interval) && !customInterval)
}
>
<Trans>save_btn</Trans>
</button>
@@ -116,8 +173,22 @@ Form.propTypes = {
processing: PropTypes.bool.isRequired,
processingReset: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
interval: PropTypes.number,
customInterval: PropTypes.number,
dispatch: PropTypes.func.isRequired,
};
const selector = formValueSelector(FORM_NAME.STATS_CONFIG);
Form = connect((state) => {
const interval = selector(state, 'interval');
const customInterval = selector(state, CUSTOM_INTERVAL);
return {
interval,
customInterval,
};
})(Form);
export default flow([
withTranslation(),
reduxForm({ form: FORM_NAME.STATS_CONFIG }),

View File

@@ -4,13 +4,18 @@ import { withTranslation } from 'react-i18next';
import Card from '../../ui/Card';
import Form from './Form';
import { HOUR } from '../../../helpers/constants';
class StatsConfig extends Component {
handleFormSubmit = ({ enabled, interval, ignored }) => {
handleFormSubmit = ({
enabled, interval, ignored, customInterval,
}) => {
const { t, interval: prevInterval } = this.props;
const newInterval = customInterval ? customInterval * HOUR : interval;
const config = {
enabled,
interval,
interval: newInterval,
ignored: ignored ? ignored.split('\n') : [],
};
@@ -33,7 +38,13 @@ class StatsConfig extends Component {
render() {
const {
t, interval, processing, processingReset, ignored, enabled,
t,
interval,
customInterval,
processing,
processingReset,
ignored,
enabled,
} = this.props;
return (
@@ -46,6 +57,7 @@ class StatsConfig extends Component {
<Form
initialValues={{
interval,
customInterval,
enabled,
ignored: ignored.join('\n'),
}}
@@ -62,6 +74,7 @@ class StatsConfig extends Component {
StatsConfig.propTypes = {
interval: PropTypes.number.isRequired,
customInterval: PropTypes.number,
ignored: PropTypes.array.isRequired,
enabled: PropTypes.bool.isRequired,
processing: PropTypes.bool.isRequired,

View File

@@ -124,6 +124,7 @@ class Settings extends Component {
enabled={queryLogs.enabled}
ignored={queryLogs.ignored}
interval={queryLogs.interval}
customInterval={queryLogs.customInterval}
anonymize_client_ip={queryLogs.anonymize_client_ip}
processing={queryLogs.processingSetConfig}
processingClear={queryLogs.processingClear}
@@ -134,6 +135,7 @@ class Settings extends Component {
<div className="col-md-12">
<StatsConfig
interval={stats.interval}
customInterval={stats.customInterval}
ignored={stats.ignored}
enabled={stats.enabled}
processing={stats.processingSetConfig}
@@ -166,6 +168,7 @@ Settings.propTypes = {
stats: PropTypes.shape({
processingGetConfig: PropTypes.bool,
interval: PropTypes.number,
customInterval: PropTypes.number,
enabled: PropTypes.bool,
ignored: PropTypes.array,
processingSetConfig: PropTypes.bool,
@@ -174,6 +177,7 @@ Settings.propTypes = {
queryLogs: PropTypes.shape({
enabled: PropTypes.bool,
interval: PropTypes.number,
customInterval: PropTypes.number,
anonymize_client_ip: PropTypes.bool,
processingSetConfig: PropTypes.bool,
processingClear: PropTypes.bool,

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import cn from 'classnames';
@@ -33,16 +33,14 @@ const Footer = () => {
const { t } = useTranslation();
const dispatch = useDispatch();
const currentTheme = useSelector((state) => (state.dashboard ? state.dashboard.theme : 'auto'));
const profileName = useSelector((state) => (state.dashboard ? state.dashboard.name : ''));
const currentTheme = useSelector((state) => (
state.dashboard ? state.dashboard.theme : THEMES.auto
));
const profileName = useSelector((state) => (
state.dashboard ? state.dashboard.name : ''
));
const isLoggedIn = profileName !== '';
const [currentThemeLocal, setCurrentThemeLocal] = useState('auto');
useEffect(() => {
if (!isLoggedIn) {
setUITheme(window.matchMedia('(prefers-color-scheme: dark)').matches ? THEMES.dark : THEMES.light);
}
}, []);
const [currentThemeLocal, setCurrentThemeLocal] = useState(THEMES.auto);
const getYear = () => {
const today = new Date();

View File

@@ -13,7 +13,7 @@
font-size: 28px;
font-weight: 600;
text-align: center;
background-color: rgba(255, 255, 255, 0.8);
background-color: var(--rt-nodata-bgcolor);
}
.overlay--visible {

View File

@@ -220,6 +220,12 @@ export const STATS_INTERVALS_DAYS = [DAY, DAY * 7, DAY * 30, DAY * 90];
export const QUERY_LOG_INTERVALS_DAYS = [HOUR * 6, DAY, DAY * 7, DAY * 30, DAY * 90];
export const RETENTION_CUSTOM = 1;
export const RETENTION_CUSTOM_INPUT = 'custom_retention_input';
export const CUSTOM_INTERVAL = 'customInterval';
export const FILTERS_INTERVALS_HOURS = [0, 1, 12, 24, 72, 168];
// Note that translation strings contain these modes (blocking_mode_CONSTANT)
@@ -462,6 +468,11 @@ export const UINT32_RANGE = {
MAX: 4294967295,
};
export const RETENTION_RANGE = {
MIN: 1,
MAX: 365 * 24,
};
export const DHCP_VALUES_PLACEHOLDERS = {
ipv4: {
subnet_mask: '255.255.255.0',
@@ -537,3 +548,5 @@ export const DISABLE_PROTECTION_TIMINGS = {
HOUR: 60 * 60 * 1000,
TOMORROW: 24 * 60 * 60 * 1000,
};
export const LOCAL_STORAGE_THEME_KEY = 'account_theme';

View File

@@ -100,6 +100,12 @@ export default {
"homepage": "https://github.com/DandelionSprout/adfilt",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_13.txt"
},
"POL_cert_polska_list_of_malicious_domains": {
"name": "POL: CERT Polska List of malicious domains",
"categoryId": "regional",
"homepage": "https://cert.pl/posts/2020/03/ostrzezenia_phishing/",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_41.txt"
},
"POL_polish_filters_for_pi_hole": {
"name": "POL: Polish filters for Pi-hole",
"categoryId": "regional",
@@ -118,6 +124,12 @@ export default {
"homepage": "https://github.com/bkrucarci/turk-adlist",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_26.txt"
},
"TUR_turkish_ad_hosts": {
"name": "TUR: Turkish Ad Hosts",
"categoryId": "regional",
"homepage": "https://github.com/symbuzzer/Turkish-Ad-Hosts",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_40.txt"
},
"VNM_abpvn": {
"name": "VNM: ABPVN List",
"categoryId": "regional",
@@ -214,6 +226,12 @@ export default {
"homepage": "https://github.com/durablenapkin/scamblocklist",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_10.txt"
},
"shadowwhisperers_malware_list": {
"name": "ShadowWhisperer's Malware List",
"categoryId": "security",
"homepage": "https://github.com/ShadowWhisperer/BlockLists",
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_42.txt"
},
"staklerware_indicators_list": {
"name": "Stalkerware Indicators List",
"categoryId": "security",

View File

@@ -25,6 +25,8 @@ import {
STANDARD_HTTPS_PORT,
STANDARD_WEB_PORT,
SPECIAL_FILTER_ID,
THEMES,
LOCAL_STORAGE_THEME_KEY,
} from './constants';
/**
@@ -678,13 +680,61 @@ export const setHtmlLangAttr = (language) => {
window.document.documentElement.lang = language;
};
/**
* Set local storage field
*
* @param {string} key
* @param {string} value
*/
export const setStorageItem = (key, value) => {
if (window.localStorage) {
window.localStorage.setItem(key, value);
}
};
/**
* Get local storage field
*
* @param {string} key
*/
export const getStorageItem = (key) => (window.localStorage
? window.localStorage.getItem(key)
: null);
/**
* Set local storage theme field
*
* @param {string} theme
*/
export const setTheme = (theme) => {
setStorageItem(LOCAL_STORAGE_THEME_KEY, theme);
};
/**
* Get local storage theme field
*
* @returns {string}
*/
export const getTheme = () => getStorageItem(LOCAL_STORAGE_THEME_KEY) || THEMES.light;
/**
* Sets UI theme.
*
* @param theme
*/
export const setUITheme = (theme) => {
document.body.dataset.theme = theme;
let currentTheme = theme || getTheme();
if (currentTheme === THEMES.auto) {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
currentTheme = prefersDark ? THEMES.dark : THEMES.light;
}
setTheme(currentTheme);
document.body.dataset.theme = currentTheme;
};
/**

View File

@@ -1,5 +1,5 @@
{
"timeUpdated": "2023-03-29T00:10:35.167Z",
"timeUpdated": "2023-06-01T00:12:12.660Z",
"categories": {
"0": "audio_video_player",
"1": "comments",
@@ -19526,6 +19526,13 @@
"companyId": "qualcomm",
"source": "AdGuard"
},
"qualcomm_location_service": {
"name": "Qualcomm Location Service",
"categoryId": 15,
"url": "https://www.qualcomm.com/site/privacy/services",
"companyId": "qualcomm",
"source": "AdGuard"
},
"recaptcha": {
"name": "reCAPTCHA",
"categoryId": 8,
@@ -19533,6 +19540,55 @@
"companyId": "google",
"source": "AdGuard"
},
"samsung": {
"name": "Samsung",
"categoryId": 8,
"url": "https://www.samsung.com/",
"companyId": "samsung",
"source": "AdGuard"
},
"samsungads": {
"name": "Samsung Ads",
"categoryId": 4,
"url": "https://www.samsung.com/business/samsungads/",
"companyId": "samsung",
"source": "AdGuard"
},
"samsungapps": {
"name": "Samsung Apps",
"categoryId": 101,
"url": "https://www.samsung.com/au/apps/",
"companyId": "samsung",
"source": "AdGuard"
},
"samsungmobile": {
"name": "Samsung Mobile",
"categoryId": 101,
"url": "https://www.samsung.com/mobile/",
"companyId": "samsung",
"source": "AdGuard"
},
"samsungpush": {
"name": "Samsung Push",
"categoryId": 8,
"url": null,
"companyId": "samsung",
"source": "AdGuard"
},
"samsungsds": {
"name": "Samsung SDS",
"categoryId": 10,
"url": "https://www.samsungsds.com/",
"companyId": "samsung",
"source": "AdGuard"
},
"samsungtv": {
"name": "Samsung TV",
"categoryId": 15,
"url": "https://www.samsung.com/au/tvs/",
"companyId": "samsung",
"source": "AdGuard"
},
"sectigo": {
"name": "Sectigo Limited",
"categoryId": 5,
@@ -19589,6 +19645,13 @@
"companyId": "telstra",
"source": "AdGuard"
},
"ubuntu": {
"name": "Ubuntu",
"categoryId": 8,
"url": "https://ubuntu.com/",
"companyId": "ubuntu",
"source": "AdGuard"
},
"unity_ads": {
"name": "Unity Ads",
"categoryId": 4,
@@ -19651,6 +19714,13 @@
"url": "https://www.3gpp.org/",
"companyId": "3gpp",
"source": "AdGuard"
},
"7plus": {
"name": "7plus",
"categoryId": 0,
"url": "https://7plus.com.au/",
"companyId": "7plus",
"source": "AdGuard"
}
},
"trackerDomains": {
@@ -19843,8 +19913,8 @@
"adfreestyle.pl": "adfreestyle",
"adfront.org": "adfront",
"adfrontiers.com": "adfrontiers",
"adgear.com": "adgear",
"adgrx.com": "adgear",
"adgear.com": "samsungads",
"adgrx.com": "samsungads",
"adgebra.co.in": "adgebra",
"adgenie.co.uk": "adgenie",
"ad.adgile.com": "adgile",
@@ -24056,6 +24126,10 @@
"safebrowsing.g.applimg.com": "apple",
"applvn.com": "applovin",
"applovin.com": "applovin",
"bitbucket.org": "atlassian.net",
"jira.com": "atlassian.net",
"ss-inf.net": "atlassian.net",
"stspg-customer.com": "statuspage.io",
"blob.core.windows.net": "azure_blob_storage",
"azure.com": "azure",
"trafficmanager.net": "azure",
@@ -24063,6 +24137,21 @@
"mobileapptracking.com": "branch",
"bttn.io": "button",
"cloudflare-dns.com": "cloudflare",
"cloudflare-dm-cmpimg.com": "cloudflare",
"cloudflare-ipfs.com": "cloudflare",
"cloudflare-quic.com": "cloudflare",
"cloudflare-terms-of-service-abuse.com": "cloudflare",
"cloudflare.tv": "cloudflare",
"cloudflareaccess.com": "cloudflare",
"cloudflareclient.com": "cloudflare",
"cloudflareinsights.com": "cloudflare",
"cloudflareok.com": "cloudflare",
"cloudflareportal.com": "cloudflare",
"cloudflareresolve.com": "cloudflare",
"cloudflaressl.com": "cloudflare",
"cloudflarestatus.com": "cloudflare",
"pacloudflare.com": "cloudflare",
"sn-cloudflare.com": "cloudflare",
"crashlytics.com": "crashlytics",
"phicdn.net": "digicert_trust_seal",
"domain.glass": "domainglass",
@@ -24092,6 +24181,9 @@
"qy.net": "iqiyi",
"iqiyi.com": "iqiyi",
"iq.com": "iqiyi",
"ironsrc.com": "ironsource",
"ironsrc.net": "ironsource",
"supersonicads.com": "ironsource",
"karambasecurity.com": "karambasecurity",
"kik.com": "kik",
"apikik.com": "kik",
@@ -24121,6 +24213,23 @@
"mozilla.com": "mozilla",
"mozilla.net": "mozilla",
"mozilla.org": "mozilla",
"flxvpn.net": "netflix",
"netflix.ca": "netflix",
"netflix.com.au": "netflix",
"netflix.net": "netflix",
"netflixdnstest1.com": "netflix",
"netflixdnstest10.com": "netflix",
"netflixdnstest2.com": "netflix",
"netflixdnstest3.com": "netflix",
"netflixdnstest4.com": "netflix",
"netflixdnstest5.com": "netflix",
"netflixdnstest6.com": "netflix",
"netflixdnstest7.com": "netflix",
"netflixdnstest8.com": "netflix",
"netflixdnstest9.com": "netflix",
"netflixinvestor.com": "netflix",
"netflixstudios.com": "netflix",
"netflixtechblog.com": "netflix",
"nflximg.com": "netflix",
"netify.ai": "netify",
"nab.com": "nab",
@@ -24144,9 +24253,69 @@
"oztam.com.au": "oztam",
"plex.tv": "plex",
"plex.direct": "plex",
"xtracloud.net": "qualcomm",
"qualcomm.com": "qualcomm",
"gpsonextra.net": "qualcomm_location_service",
"izatcloud.net": "qualcomm_location_service",
"xtracloud.net": "qualcomm_location_service",
"recaptcha.net": "recaptcha",
"samsungacr.com": "samsungads",
"samsungadhub.com": "samsungads",
"samsungads.com": "samsungads",
"samsungtifa.com": "samsungads",
"game-mode.net": "samsung",
"gos-gsp.io": "samsung",
"lldns.net": "samsung",
"pavv.co.kr": "samsung",
"remotesamsung.com": "samsung",
"samsung-gamelauncher.com": "samsung",
"samsung.co.kr": "samsung",
"samsung.com": "samsung",
"samsung.com.cn": "samsung",
"samsungcloud.com": "samsung",
"samsungcloudcdn.com": "samsung",
"samsungcloudprint.com": "samsung",
"samsungcloudsolution.com": "samsung",
"samsungcloudsolution.net": "samsung",
"samsungelectronics.com": "samsung",
"samsunghealth.com": "samsung",
"samsungiotcloud.com": "samsung",
"samsungknox.com": "samsung",
"samsungnyc.com": "samsung",
"samsungosp.com": "samsung",
"samsungotn.net": "samsung",
"samsungpositioning.com": "samsung",
"samsungqbe.com": "samsung",
"samsungrm.net": "samsung",
"samsungrs.com": "samsung",
"samsungsemi.com": "samsung",
"samsungsetup.com": "samsung",
"samsungusa.com": "samsung",
"secb2b.com": "samsung",
"smartthings.com": "samsung",
"ospserver.net": "samsungmobile",
"samsungdms.net": "samsungmobile",
"samsungmax.com": "samsungmobile",
"samsungmobile.com": "samsungmobile",
"secmobilesvc.com": "samsungmobile",
"internetat.tv": "samsungtv",
"samsungcloud.tv": "samsungtv",
"samsungsds.com": "samsungsds",
"push.samsungosp.com": "samsungpush",
"pushmessage.samsung.com": "samsungpush",
"scs.samsungqbe.com": "samsungpush",
"ssp.samsung.com": "samsungpush",
"aibixby.com": "samsungapps",
"findmymobile.samsung.com": "samsungapps",
"samsapps.cust.lldns.net": "samsungapps",
"samsung-omc.com": "samsungapps",
"samsungapps.com": "samsungapps",
"samsungdiroute.net": "samsungapps",
"samsungdive.com": "samsungapps",
"samsungdm.com": "samsungapps",
"samsungdmroute.com": "samsungapps",
"samsungmdec.com": "samsungapps",
"samsungvisioncloud.com": "samsungapps",
"sbixby.com": "samsungapps",
"sectigo.com": "sectigo",
"showrss.info": "showrss",
"similarweb.io": "similarweb",
@@ -24171,6 +24340,13 @@
"telstra.com.au": "telstra",
"telstra.com": "telstra",
"usertrust.com": "trustlogo",
"canonical.com": "ubuntu",
"launchpad.net": "ubuntu",
"launchpadcontent.net": "ubuntu",
"snapcraft.io": "ubuntu",
"snapcraftcontent.com": "ubuntu",
"ubuntu.com": "ubuntu",
"ubuntucompanyservices.co.za": "ubuntu",
"unityads.unity3d.com": "unity_ads",
"exp-tas.com": "vscode",
"vscode-unpkg.net": "vscode",
@@ -24190,6 +24366,7 @@
"yandex.kz": "yandex",
"appmetrica.yandex.com": "yandex_appmetrica",
"3gppnetwork.org": "3gpp",
"3gpp.org": "3gpp"
"3gpp.org": "3gpp",
"swm.digital": "7plus"
}
}
}

View File

@@ -8,6 +8,7 @@ import * as actionCreators from '../../actions/login';
import logo from '../../components/ui/svg/logo.svg';
import Toasts from '../../components/Toasts';
import Footer from '../../components/ui/Footer';
import Icons from '../../components/ui/Icons';
import Form from './Form';
import './Login.css';
@@ -69,6 +70,7 @@ class Login extends Component {
</div>
<Footer />
<Toasts />
<Icons />
</div>
);
}

View File

@@ -177,7 +177,7 @@ const dashboard = handleActions(
autoClients: [],
supportedTags: [],
name: '',
theme: 'auto',
theme: undefined,
checkUpdateFlag: false,
},
);

View File

@@ -1,7 +1,9 @@
import { handleActions } from 'redux-actions';
import * as actions from '../actions/queryLogs';
import { DEFAULT_LOGS_FILTER, DAY } from '../helpers/constants';
import {
DEFAULT_LOGS_FILTER, DAY, QUERY_LOG_INTERVALS_DAYS, HOUR,
} from '../helpers/constants';
const queryLogs = handleActions(
{
@@ -59,6 +61,9 @@ const queryLogs = handleActions(
[actions.getLogsConfigSuccess]: (state, { payload }) => ({
...state,
...payload,
customInterval: !QUERY_LOG_INTERVALS_DAYS.includes(payload.interval)
? payload.interval / HOUR
: null,
processingGetConfig: false,
}),
@@ -95,6 +100,7 @@ const queryLogs = handleActions(
anonymize_client_ip: false,
isDetailed: true,
isEntireLog: false,
customInterval: null,
},
);

View File

@@ -1,6 +1,6 @@
import { handleActions } from 'redux-actions';
import { normalizeTopClients } from '../helpers/helpers';
import { DAY } from '../helpers/constants';
import { DAY, HOUR, STATS_INTERVALS_DAYS } from '../helpers/constants';
import * as actions from '../actions/stats';
@@ -27,6 +27,9 @@ const stats = handleActions(
[actions.getStatsConfigSuccess]: (state, { payload }) => ({
...state,
...payload,
customInterval: !STATS_INTERVALS_DAYS.includes(payload.interval)
? payload.interval / HOUR
: null,
processingGetConfig: false,
}),
@@ -93,6 +96,7 @@ const stats = handleActions(
processingStats: true,
processingReset: false,
interval: DAY,
customInterval: null,
...defaultStats,
},
);

View File

@@ -4,19 +4,26 @@
/^[[:space:]]+- .+/ {
if (FNR - prev_line == 1) {
addrs[addrsnum++] = $2
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 (i in addrs) {
if (match(addrs[i], ":")) {
print "[" addrs[i] "]:" port
for (addr in addrs) {
if (match(addr, ":")) {
print "[" addr "]:" port
} else {
print addrs[i] ":" port
print addr ":" port
}
}
}
}

View File

@@ -61,8 +61,11 @@ 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 "$( echo "$dns_hosts" | head -n 1 )"
case "$first_dns"
in
(*':0')
error_exit '0 in DNS port is not supported by healthcheck'
@@ -82,8 +85,23 @@ esac
# See https://github.com/AdguardTeam/AdGuardHome/issues/5642.
wget --no-check-certificate "$web_url" -O /dev/null -q || exit 1
echo "$dns_hosts" | while read -r host
do
nslookup -type=a healthcheck.adguardhome.test. "$host" > /dev/null ||\
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"
done
;;
(*)
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

@@ -10,4 +10,4 @@ END {
} else {
print "http://" host ":" port
}
}
}

52
go.mod
View File

@@ -3,11 +3,12 @@ module github.com/AdguardTeam/AdGuardHome
go 1.19
require (
github.com/AdguardTeam/dnsproxy v0.48.3
github.com/AdguardTeam/golibs v0.13.1
github.com/AdguardTeam/dnsproxy v0.50.2
github.com/AdguardTeam/golibs v0.13.3
github.com/AdguardTeam/urlfilter v0.16.1
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.6
github.com/ameshkov/dnscrypt/v2 v2.2.7
github.com/bluele/gcache v0.0.2
github.com/digineo/go-ipset/v2 v2.2.1
github.com/dimfeld/httptreemux/v5 v5.5.0
github.com/fsnotify/fsnotify v1.6.0
@@ -16,20 +17,24 @@ require (
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-20221215072855-de60144f33f8
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb
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
github.com/mdlayher/netlink v1.7.1
github.com/mdlayher/packet v1.1.1
github.com/miekg/dns v1.1.53
github.com/quic-go/quic-go v0.33.0
github.com/stretchr/testify v1.8.2
github.com/mdlayher/netlink v1.7.2
github.com/mdlayher/packet v1.1.2
// 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/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.7.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
golang.org/x/net v0.8.0
golang.org/x/sys v0.6.0
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
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
howett.net/plist v1.0.0
@@ -40,25 +45,22 @@ require (
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
github.com/ameshkov/dnsstamps v1.0.3 // indirect
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
github.com/bluele/gcache v0.0.2 // indirect
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-20230323073829-e72429f035bd // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/mdlayher/raw v0.1.0 // indirect
github.com/mdlayher/socket v0.4.0 // indirect
github.com/onsi/ginkgo/v2 v2.9.2 // indirect
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/onsi/ginkgo/v2 v2.10.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.17 // 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.0 // indirect
github.com/quic-go/qtls-go1-20 v0.2.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/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.7.0 // 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
)

140
go.sum
View File

@@ -1,9 +1,9 @@
github.com/AdguardTeam/dnsproxy v0.48.3 h1:h9xgDSmd1MqsPFNApyaPVXolmSTtzOWOcfWvPeDEP6s=
github.com/AdguardTeam/dnsproxy v0.48.3/go.mod h1:Y7g7jRTd/u7+KJ/QvnGI2PCE8vnisp6EsW47/Sz0DZw=
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.1 h1:x6ChoXk2jborbCWJ01TyBAEY3SilHts0SCG7yjnf6Sc=
github.com/AdguardTeam/golibs v0.13.1/go.mod h1:7ylQLv2Lqsc3UW3jHoITynYk6Y1tYtgEMkR09ppfsN8=
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=
@@ -15,8 +15,8 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
github.com/ameshkov/dnscrypt/v2 v2.2.6 h1:rE7AFbPWebq7me7RVS66Cipd1m7ef1yf2+C8QzjQXXE=
github.com/ameshkov/dnscrypt/v2 v2.2.6/go.mod h1:qPWhwz6FdSmuK7W4sMyvogrez4MWdtzosdqlr0Rg3ow=
github.com/ameshkov/dnscrypt/v2 v2.2.7 h1:aEitLIR8HcxVodZ79mgRcCiC0A0I5kZPBuWGFwwulAw=
github.com/ameshkov/dnscrypt/v2 v2.2.7/go.mod h1:qPWhwz6FdSmuK7W4sMyvogrez4MWdtzosdqlr0Rg3ow=
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 h1:0b2vaepXIfMsG++IsjHiI2p4bxALD1Y2nQKGMR5zDQM=
@@ -31,10 +31,9 @@ github.com/digineo/go-ipset/v2 v2.2.1 h1:k6skY+0fMqeUjjeWO/m5OuWPSZUAn7AucHMnQ1M
github.com/digineo/go-ipset/v2 v2.2.1/go.mod h1:wBsNzJlZlABHUITkesrggFnZQtgW5wkqw1uo8Qxe0VU=
github.com/dimfeld/httptreemux/v5 v5.5.0 h1:p8jkiMrCuZ0CmhwYLcbNbl7DDo21fozhKHQ2PccwOFQ=
github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw=
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
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.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
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-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
@@ -45,72 +44,54 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
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-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
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/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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
github.com/insomniacslk/dhcp v0.0.0-20221215072855-de60144f33f8 h1:Z72DOke2yOK0Ms4Z2LK1E1OrRJXOxSj5DllTz2FYTRg=
github.com/insomniacslk/dhcp v0.0.0-20221215072855-de60144f33f8/go.mod h1:m5WMe03WCvWcXjRnhvaAbAAXdCnu20J5P+mmH44ZzpE=
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/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=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
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/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og=
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
github.com/mdlayher/netlink v1.7.1 h1:FdUaT/e33HjEXagwELR8R3/KL1Fq5x3G5jgHLp/BTmg=
github.com/mdlayher/netlink v1.7.1/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU=
github.com/mdlayher/packet v1.1.1 h1:7Fv4OEMYqPl7//uBm04VgPpnSNi8fbBZznppgh6WMr8=
github.com/mdlayher/packet v1.1.1/go.mod h1:DRvYY5mH4M4lUqAnMg04E60U4fjUKMZ/4g2cHElZkKo=
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4=
github.com/mdlayher/raw v0.1.0 h1:K4PFMVy+AFsp0Zdlrts7yNhxc/uXoPVHi9RzRvtZF2Y=
github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5s9Sg=
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
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.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/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.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
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/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=
@@ -123,28 +104,22 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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.0 h1:aUBoQdpHzUWtPw5tQZbsD2GnrWCNu7/RIX1PtqGeLYY=
github.com/quic-go/qtls-go1-19 v0.3.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.2.0 h1:jUHn+obJ6WI5JudqBO0Iy1ra5Vh5vsitQ1gXQvkmN+E=
github.com/quic-go/qtls-go1-20 v0.2.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0=
github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA=
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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
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=
@@ -152,7 +127,6 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/u-root/uio v0.0.0-20221213070652-c3537552635f/go.mod h1:IogEAUBXDEwX7oR/BMmCctShYs80ql4hF0ySdzGxf7E=
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=
@@ -160,52 +134,36 @@ 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.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
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/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.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
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/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-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-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.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
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/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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/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/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-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/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=
@@ -218,23 +176,23 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
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.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/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/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.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
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.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
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/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=

View File

@@ -8,6 +8,7 @@ import (
"net/http"
"github.com/AdguardTeam/AdGuardHome/internal/version"
"github.com/AdguardTeam/golibs/httphdr"
"github.com/AdguardTeam/golibs/log"
)
@@ -52,7 +53,7 @@ const textPlainDeprMsg = `using this api with the text/plain content-type is dep
// deprecation and removal of a plain-text API if the request is made with the
// "text/plain" content-type.
func WriteTextPlainDeprecated(w http.ResponseWriter, r *http.Request) (isPlainText bool) {
if r.Header.Get(HdrNameContentType) != HdrValTextPlain {
if r.Header.Get(httphdr.ContentType) != HdrValTextPlain {
return false
}
@@ -71,8 +72,8 @@ func WriteJSONResponse(w http.ResponseWriter, r *http.Request, resp any) (err er
// WriteJSONResponseCode is like [WriteJSONResponse] but adds the ability to
// redefine the status code.
func WriteJSONResponseCode(w http.ResponseWriter, r *http.Request, code int, resp any) (err error) {
w.Header().Set(httphdr.ContentType, HdrValApplicationJSON)
w.WriteHeader(code)
w.Header().Set(HdrNameContentType, HdrValApplicationJSON)
err = json.NewEncoder(w).Encode(resp)
if err != nil {
Error(r, w, http.StatusInternalServerError, "encoding resp: %s", err)

View File

@@ -1,22 +1,6 @@
package aghhttp
// HTTP Headers
// HTTP header name constants.
//
// TODO(a.garipov): Remove unused.
const (
HdrNameAcceptEncoding = "Accept-Encoding"
HdrNameAccessControlAllowOrigin = "Access-Control-Allow-Origin"
HdrNameAltSvc = "Alt-Svc"
HdrNameContentEncoding = "Content-Encoding"
HdrNameContentType = "Content-Type"
HdrNameOrigin = "Origin"
HdrNameServer = "Server"
HdrNameTrailer = "Trailer"
HdrNameUserAgent = "User-Agent"
HdrNameVary = "Vary"
)
// HTTP headers
// HTTP header value constants.
const (

View File

@@ -304,7 +304,7 @@ func tryConn6(req *dhcpv6.Message, c net.PacketConn) (ok, next bool, err error)
if !(response.Type() == dhcpv6.MessageTypeAdvertise &&
msg.TransactionID == req.TransactionID &&
rcid != nil &&
cid.Equal(*rcid)) {
cid.Equal(rcid)) {
log.Debug("dhcpv6: received message from server doesn't match our request")

View File

@@ -1,17 +0,0 @@
//go:build windows
package aghnet
import (
"net"
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
)
// listenPacketReusable announces on the local network address additionally
// configuring the socket to have a reusable binding.
func listenPacketReusable(_, _, _ string) (c net.PacketConn, err error) {
// TODO(e.burkov): Check if we are able to control sockets on Windows
// in the same way as on Unix.
return nil, aghos.Unsupported("listening packet reusable")
}

View File

@@ -35,4 +35,4 @@
1.3.5.7 domain4 domain4.alias
7.5.3.1 domain4.alias domain4
::13 domain6 domain6.alias
::31 domain6.alias domain6
::31 domain6.alias domain6

View File

@@ -1 +1 @@
iface sample_name inet static
iface sample_name inet static

View File

@@ -2,4 +2,4 @@
# parent directory. Real interface files usually contain only absolute paths.
source ./testdata/ifaces
source ./testdata/*
source ./testdata/*

View File

@@ -3,4 +3,4 @@ IP address HW type Flags HW address Mask Device
::ffff:ffff 0x1 0x0 ef:cd:ab:ef:cd:ab * br-lan
0.0.0.0 0x0 0x0 00:00:00:00:00:00 * unspec
1.2.3.4.5 0x1 0x2 aa:bb:cc:dd:ee:ff * wan
1.2.3.4 0x1 0x2 12:34:56:78:910 * wan
1.2.3.4 0x1 0x2 12:34:56:78:910 * wan

View File

@@ -1,10 +0,0 @@
//go:build mips || mips64
// This file is an adapted version of github.com/josharian/native.
package aghos
import "encoding/binary"
// NativeEndian is the native endianness of this system.
var NativeEndian = binary.BigEndian

View File

@@ -1,10 +0,0 @@
//go:build amd64 || 386 || arm || arm64 || mipsle || mips64le || ppc64le
// This file is an adapted version of github.com/josharian/native.
package aghos
import "encoding/binary"
// NativeEndian is the native endianness of this system.
var NativeEndian = binary.LittleEndian

View File

@@ -0,0 +1,6 @@
package aghos
// PreCheckActionStart performs the service start action pre-check.
func PreCheckActionStart() (err error) {
return preCheckActionStart()
}

View File

@@ -0,0 +1,32 @@
//go:build darwin
package aghos
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/AdguardTeam/golibs/log"
)
// preCheckActionStart performs the service start action pre-check. It warns
// user that the service should be installed into Applications directory.
func preCheckActionStart() (err error) {
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("getting executable path: %v", err)
}
exe, err = filepath.EvalSymlinks(exe)
if err != nil {
return fmt.Errorf("evaluating executable symlinks: %v", err)
}
if !strings.HasPrefix(exe, "/Applications/") {
log.Info("warning: service must be started from within the /Applications directory")
}
return err
}

View File

@@ -0,0 +1,8 @@
//go:build !darwin
package aghos
// preCheckActionStart performs the service start action pre-check.
func preCheckActionStart() (err error) {
return nil
}

View File

@@ -1,46 +1,60 @@
# DHCP server
# Testing DHCP Server
Contents:
* [Test setup with Virtual Box](#vbox)
* [Test setup with Virtual Box](#vbox)
* [Quick test with DHCPTest](#dhcptest)
<a id="vbox"></a>
## Test setup with Virtual Box
## <a href="#vbox" id="vbox" name="vbox">Test setup with Virtual Box</a>
To set up a test environment for DHCP server you need:
### Prerequisites
* Linux host machine
* Virtual Box
* Virtual machine (guest OS doesn't matter)
To set up a test environment for DHCP server you will need:
### Configure client
* Linux AG Home host machine (Virtual).
* Virtual Box.
* Virtual machine (guest OS doesn't matter).
1. Install Virtual Box and run the following command to create a Host-Only network:
### Configure Virtual Box
$ VBoxManage hostonlyif create
1. Install Virtual Box and run the following command to create a Host-Only
network:
You can check its status by `ip a` command.
```sh
$ VBoxManage hostonlyif create
```
You can check its status by `ip a` command.
You can also set up Host-Only network using Virtual Box menu:
You can also set up Host-Only network using Virtual Box menu:
```
File -> Host Network Manager...
```
File -> Host Network Manager...
2. Create your virtual machine and set up its network:
2. Create your virtual machine and set up its network:
```
VM Settings -> Network -> Host-only Adapter
```
VM Settings -> Network -> Host-only Adapter
3. Start your VM, install an OS. Configure your network interface to use
DHCP and the OS should ask for a IP address from our DHCP server.
3. Start your VM, install an OS. Configure your network interface to use DHCP and the OS should ask for a IP address from our DHCP server.
4. To see the current IP addresses on client OS you can use `ip a` command on
Linux or `ipconfig` on Windows.
4. To see the current IP address on client OS you can use `ip a` command on Linux or `ipconfig` on Windows.
5. To force the client OS to request an IP from DHCP server again, you can
use `dhclient` on Linux or `ipconfig /release` on Windows.
5. To force the client OS to request an IP from DHCP server again, you can use `dhclient` on Linux or `ipconfig /release` on Windows.
### Configure server
### Configure server
1. Edit server configuration file `AdGuardHome.yaml`, for example:
1. Edit server configuration file 'AdGuardHome.yaml', for example:
dhcp:
```yaml
dhcp:
enabled: true
interface_name: vboxnet0
local_domain_name: lan
dhcpv4:
gateway_ip: 192.168.56.1
subnet_mask: 255.255.255.0
@@ -54,11 +68,29 @@ To set up a test environment for DHCP server you need:
lease_duration: 86400
ra_slaac_only: false
ra_allow_slaac: false
```
2. Start the server
2. Start the server
./AdGuardHome
```sh
./AdGuardHome -v
```
There should be a message in log which shows that DHCP server is ready:
There should be a message in log which shows that DHCP server is ready:
[info] DHCP: listening on 0.0.0.0:67
```
[info] DHCP: listening on 0.0.0.0:67
```
## <a href="#dhcptest" id="dhcptest" name="dhcptest">Quick test with DHCPTest utility</a>
### Prerequisites
* [DHCP test utility][dhcptest-gh].
### Quick test
The DHCP server could be tested for DISCOVER-OFFER packets with in
interactive mode.
[dhcptest-gh]: https://github.com/CyberShadow/dhcptest

View File

@@ -31,8 +31,16 @@ type ServerConfig struct {
Conf4 V4ServerConf `yaml:"dhcpv4"`
Conf6 V6ServerConf `yaml:"dhcpv6"`
WorkDir string `yaml:"-"`
DBFilePath string `yaml:"-"`
// WorkDir is used to store DHCP leases.
//
// Deprecated: Remove it when migration of DHCP leases will not be needed.
WorkDir string `yaml:"-"`
// DataDir is used to store DHCP leases.
DataDir string `yaml:"-"`
// dbFilePath is the path to the file with stored DHCP leases.
dbFilePath string `yaml:"-"`
}
// DHCPServer - DHCP server interface

293
internal/dhcpd/conn_bsd.go Normal file
View File

@@ -0,0 +1,293 @@
//go:build darwin || freebsd || openbsd
package dhcpd
import (
"fmt"
"net"
"os"
"time"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv4/server4"
"github.com/mdlayher/ethernet"
//lint:ignore SA1019 See the TODO in go.mod.
"github.com/mdlayher/raw"
)
// dhcpUnicastAddr is the combination of MAC and IP addresses for responding to
// the unconfigured host.
type dhcpUnicastAddr struct {
// raw.Addr is embedded here to make *dhcpUcastAddr a net.Addr without
// actually implementing all methods. It also contains the client's
// hardware address.
raw.Addr
// yiaddr is an IP address just allocated by server for the host.
yiaddr net.IP
}
// dhcpConn is the net.PacketConn capable of handling both net.UDPAddr and
// net.HardwareAddr.
type dhcpConn struct {
// udpConn is the connection for UDP addresses.
udpConn net.PacketConn
// bcastIP is the broadcast address specific for the configured
// interface's subnet.
bcastIP net.IP
// rawConn is the connection for MAC addresses.
rawConn net.PacketConn
// srcMAC is the hardware address of the configured network interface.
srcMAC net.HardwareAddr
// srcIP is the IP address of the configured network interface.
srcIP net.IP
}
// newDHCPConn creates the special connection for DHCP server.
func (s *v4Server) newDHCPConn(iface *net.Interface) (c net.PacketConn, err error) {
var ucast net.PacketConn
if ucast, err = raw.ListenPacket(iface, uint16(ethernet.EtherTypeIPv4), nil); err != nil {
return nil, fmt.Errorf("creating raw udp connection: %w", err)
}
// Create the UDP connection.
var bcast net.PacketConn
bcast, err = server4.NewIPv4UDPConn(iface.Name, &net.UDPAddr{
// TODO(e.burkov): Listening on zeroes makes the server handle
// requests from all the interfaces. Inspect the ways to
// specify the interface-specific listening addresses.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/3539.
IP: net.IP{0, 0, 0, 0},
Port: dhcpv4.ServerPort,
})
if err != nil {
return nil, fmt.Errorf("creating ipv4 udp connection: %w", err)
}
return &dhcpConn{
udpConn: bcast,
bcastIP: s.conf.broadcastIP.AsSlice(),
rawConn: ucast,
srcMAC: iface.HardwareAddr,
srcIP: s.conf.dnsIPAddrs[0].AsSlice(),
}, nil
}
// wrapErrs is a helper to wrap the errors from two independent underlying
// connections.
func (*dhcpConn) wrapErrs(action string, udpConnErr, rawConnErr error) (err error) {
switch {
case udpConnErr != nil && rawConnErr != nil:
return errors.List(fmt.Sprintf("%s both connections", action), udpConnErr, rawConnErr)
case udpConnErr != nil:
return fmt.Errorf("%s udp connection: %w", action, udpConnErr)
case rawConnErr != nil:
return fmt.Errorf("%s raw connection: %w", action, rawConnErr)
default:
return nil
}
}
// WriteTo implements net.PacketConn for *dhcpConn. It selects the underlying
// connection to write to based on the type of addr.
func (c *dhcpConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
switch addr := addr.(type) {
case *dhcpUnicastAddr:
// Unicast the message to the client's MAC address. Use the raw
// connection.
//
// Note: unicasting is performed on the only network interface
// that is configured. For now it may be not what users expect
// so additionally broadcast the message via UDP connection.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/3539.
var rerr error
n, rerr = c.unicast(p, addr)
_, uerr := c.broadcast(p, &net.UDPAddr{
IP: netutil.IPv4bcast(),
Port: dhcpv4.ClientPort,
})
return n, c.wrapErrs("writing to", uerr, rerr)
case *net.UDPAddr:
if addr.IP.Equal(net.IPv4bcast) {
// Broadcast the message for the client which supports
// it. Use the UDP connection.
return c.broadcast(p, addr)
}
// Unicast the message to the client's IP address. Use the UDP
// connection.
return c.udpConn.WriteTo(p, addr)
default:
return 0, fmt.Errorf("addr has an unexpected type %T", addr)
}
}
// ReadFrom implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return c.udpConn.ReadFrom(p)
}
// unicast wraps respData with required frames and writes it to the peer.
func (c *dhcpConn) unicast(respData []byte, peer *dhcpUnicastAddr) (n int, err error) {
var data []byte
data, err = c.buildEtherPkt(respData, peer)
if err != nil {
return 0, err
}
return c.rawConn.WriteTo(data, &peer.Addr)
}
// Close implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) Close() (err error) {
rerr := c.rawConn.Close()
if errors.Is(rerr, os.ErrClosed) {
// Ignore the error since the actual file is closed already.
rerr = nil
}
return c.wrapErrs("closing", c.udpConn.Close(), rerr)
}
// LocalAddr implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) LocalAddr() (a net.Addr) {
return c.udpConn.LocalAddr()
}
// SetDeadline implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) SetDeadline(t time.Time) (err error) {
return c.wrapErrs("setting deadline on", c.udpConn.SetDeadline(t), c.rawConn.SetDeadline(t))
}
// SetReadDeadline implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) SetReadDeadline(t time.Time) error {
return c.wrapErrs(
"setting reading deadline on",
c.udpConn.SetReadDeadline(t),
c.rawConn.SetReadDeadline(t),
)
}
// SetWriteDeadline implements net.PacketConn for *dhcpConn.
func (c *dhcpConn) SetWriteDeadline(t time.Time) error {
return c.wrapErrs(
"setting writing deadline on",
c.udpConn.SetWriteDeadline(t),
c.rawConn.SetWriteDeadline(t),
)
}
// ipv4DefaultTTL is the default Time to Live value in seconds as recommended by
// RFC-1700.
//
// See https://datatracker.ietf.org/doc/html/rfc1700.
const ipv4DefaultTTL = 64
// buildEtherPkt wraps the payload with IPv4, UDP and Ethernet frames.
// Validation of the payload is a caller's responsibility.
func (c *dhcpConn) buildEtherPkt(payload []byte, peer *dhcpUnicastAddr) (pkt []byte, err error) {
udpLayer := &layers.UDP{
SrcPort: dhcpv4.ServerPort,
DstPort: dhcpv4.ClientPort,
}
ipv4Layer := &layers.IPv4{
Version: uint8(layers.IPProtocolIPv4),
Flags: layers.IPv4DontFragment,
TTL: ipv4DefaultTTL,
Protocol: layers.IPProtocolUDP,
SrcIP: c.srcIP,
DstIP: peer.yiaddr,
}
// Ignore the error since it's only returned for invalid network layer's
// type.
_ = udpLayer.SetNetworkLayerForChecksum(ipv4Layer)
ethLayer := &layers.Ethernet{
SrcMAC: c.srcMAC,
DstMAC: peer.HardwareAddr,
EthernetType: layers.EthernetTypeIPv4,
}
buf := gopacket.NewSerializeBuffer()
setts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
err = gopacket.SerializeLayers(
buf,
setts,
ethLayer,
ipv4Layer,
udpLayer,
gopacket.Payload(payload),
)
if err != nil {
return nil, fmt.Errorf("serializing layers: %w", err)
}
return buf.Bytes(), nil
}
// send writes resp for peer to conn considering the req's parameters according
// to RFC-2131.
//
// See https://datatracker.ietf.org/doc/html/rfc2131#section-4.1.
func (s *v4Server) send(peer net.Addr, conn net.PacketConn, req, resp *dhcpv4.DHCPv4) {
switch giaddr, ciaddr, mtype := req.GatewayIPAddr, req.ClientIPAddr, resp.MessageType(); {
case giaddr != nil && !giaddr.IsUnspecified():
// Send any return messages to the server port on the BOOTP
// relay agent whose address appears in giaddr.
peer = &net.UDPAddr{
IP: giaddr,
Port: dhcpv4.ServerPort,
}
if mtype == dhcpv4.MessageTypeNak {
// Set the broadcast bit in the DHCPNAK, so that the relay agent
// broadcasts it to the client, because the client may not have
// a correct network address or subnet mask, and the client may not
// be answering ARP requests.
resp.SetBroadcast()
}
case mtype == dhcpv4.MessageTypeNak:
// Broadcast any DHCPNAK messages to 0xffffffff.
case ciaddr != nil && !ciaddr.IsUnspecified():
// Unicast DHCPOFFER and DHCPACK messages to the address in
// ciaddr.
peer = &net.UDPAddr{
IP: ciaddr,
Port: dhcpv4.ClientPort,
}
case !req.IsBroadcast() && req.ClientHWAddr != nil:
// Unicast DHCPOFFER and DHCPACK messages to the client's
// hardware address and yiaddr.
peer = &dhcpUnicastAddr{
Addr: raw.Addr{HardwareAddr: req.ClientHWAddr},
yiaddr: resp.YourIPAddr,
}
default:
// Go on since peer is already set to broadcast.
}
pktData := resp.ToBytes()
log.Debug("dhcpv4: sending %d bytes to %s: %s", len(pktData), peer, resp.Summary())
_, err := conn.WriteTo(pktData, peer)
if err != nil {
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
}
}

View File

@@ -0,0 +1,219 @@
//go:build darwin || freebsd || openbsd
package dhcpd
import (
"net"
"testing"
"github.com/AdguardTeam/golibs/testutil"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
//lint:ignore SA1019 See the TODO in go.mod.
"github.com/mdlayher/raw"
)
func TestDHCPConn_WriteTo_common(t *testing.T) {
respData := (&dhcpv4.DHCPv4{}).ToBytes()
udpAddr := &net.UDPAddr{
IP: net.IP{1, 2, 3, 4},
Port: dhcpv4.ClientPort,
}
t.Run("unicast_ip", func(t *testing.T) {
writeTo := func(_ []byte, addr net.Addr) (_ int, _ error) {
assert.Equal(t, udpAddr, addr)
return 0, nil
}
conn := &dhcpConn{udpConn: &fakePacketConn{writeTo: writeTo}}
_, err := conn.WriteTo(respData, udpAddr)
assert.NoError(t, err)
})
t.Run("unexpected_addr_type", func(t *testing.T) {
type unexpectedAddrType struct {
net.Addr
}
conn := &dhcpConn{}
n, err := conn.WriteTo(nil, &unexpectedAddrType{})
require.Error(t, err)
testutil.AssertErrorMsg(t, "addr has an unexpected type *dhcpd.unexpectedAddrType", err)
assert.Zero(t, n)
})
}
func TestBuildEtherPkt(t *testing.T) {
conn := &dhcpConn{
srcMAC: net.HardwareAddr{1, 2, 3, 4, 5, 6},
srcIP: net.IP{1, 2, 3, 4},
}
peer := &dhcpUnicastAddr{
Addr: raw.Addr{HardwareAddr: net.HardwareAddr{6, 5, 4, 3, 2, 1}},
yiaddr: net.IP{4, 3, 2, 1},
}
payload := (&dhcpv4.DHCPv4{}).ToBytes()
t.Run("success", func(t *testing.T) {
pkt, err := conn.buildEtherPkt(payload, peer)
require.NoError(t, err)
assert.NotEmpty(t, pkt)
actualPkt := gopacket.NewPacket(pkt, layers.LayerTypeEthernet, gopacket.DecodeOptions{
NoCopy: true,
})
require.NotNil(t, actualPkt)
wantTypes := []gopacket.LayerType{
layers.LayerTypeEthernet,
layers.LayerTypeIPv4,
layers.LayerTypeUDP,
layers.LayerTypeDHCPv4,
}
actualLayers := actualPkt.Layers()
require.Len(t, actualLayers, len(wantTypes))
for i, wantType := range wantTypes {
layer := actualLayers[i]
require.NotNil(t, layer)
assert.Equal(t, wantType, layer.LayerType())
}
})
t.Run("bad_payload", func(t *testing.T) {
// Create an invalid DHCP packet.
invalidPayload := []byte{1, 2, 3, 4}
pkt, err := conn.buildEtherPkt(invalidPayload, peer)
require.NoError(t, err)
assert.NotEmpty(t, pkt)
})
t.Run("serializing_error", func(t *testing.T) {
// Create a peer with invalid MAC.
badPeer := &dhcpUnicastAddr{
Addr: raw.Addr{HardwareAddr: net.HardwareAddr{5, 4, 3, 2, 1}},
yiaddr: net.IP{4, 3, 2, 1},
}
pkt, err := conn.buildEtherPkt(payload, badPeer)
require.Error(t, err)
assert.Empty(t, pkt)
})
}
func TestV4Server_Send(t *testing.T) {
s := &v4Server{}
var (
defaultIP = net.IP{99, 99, 99, 99}
knownIP = net.IP{4, 2, 4, 2}
knownMAC = net.HardwareAddr{6, 5, 4, 3, 2, 1}
)
defaultPeer := &net.UDPAddr{
IP: defaultIP,
// Use neither client nor server port to check it actually
// changed.
Port: dhcpv4.ClientPort + dhcpv4.ServerPort,
}
defaultResp := &dhcpv4.DHCPv4{}
testCases := []struct {
want net.Addr
req *dhcpv4.DHCPv4
resp *dhcpv4.DHCPv4
name string
}{{
name: "giaddr",
req: &dhcpv4.DHCPv4{GatewayIPAddr: knownIP},
resp: defaultResp,
want: &net.UDPAddr{
IP: knownIP,
Port: dhcpv4.ServerPort,
},
}, {
name: "nak",
req: &dhcpv4.DHCPv4{},
resp: &dhcpv4.DHCPv4{
Options: dhcpv4.OptionsFromList(
dhcpv4.OptMessageType(dhcpv4.MessageTypeNak),
),
},
want: defaultPeer,
}, {
name: "ciaddr",
req: &dhcpv4.DHCPv4{ClientIPAddr: knownIP},
resp: &dhcpv4.DHCPv4{},
want: &net.UDPAddr{
IP: knownIP,
Port: dhcpv4.ClientPort,
},
}, {
name: "chaddr",
req: &dhcpv4.DHCPv4{ClientHWAddr: knownMAC},
resp: &dhcpv4.DHCPv4{YourIPAddr: knownIP},
want: &dhcpUnicastAddr{
Addr: raw.Addr{HardwareAddr: knownMAC},
yiaddr: knownIP,
},
}, {
name: "who_are_you",
req: &dhcpv4.DHCPv4{},
resp: &dhcpv4.DHCPv4{},
want: defaultPeer,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
conn := &fakePacketConn{
writeTo: func(_ []byte, addr net.Addr) (_ int, _ error) {
assert.Equal(t, tc.want, addr)
return 0, nil
},
}
s.send(cloneUDPAddr(defaultPeer), conn, tc.req, tc.resp)
})
}
t.Run("giaddr_nak", func(t *testing.T) {
req := &dhcpv4.DHCPv4{
GatewayIPAddr: knownIP,
}
// Ensure the request is for unicast.
req.SetUnicast()
resp := &dhcpv4.DHCPv4{
Options: dhcpv4.OptionsFromList(
dhcpv4.OptMessageType(dhcpv4.MessageTypeNak),
),
}
want := &net.UDPAddr{
IP: req.GatewayIPAddr,
Port: dhcpv4.ServerPort,
}
conn := &fakePacketConn{
writeTo: func(_ []byte, addr net.Addr) (n int, err error) {
assert.Equal(t, want, addr)
return 0, nil
},
}
s.send(cloneUDPAddr(defaultPeer), conn, req, resp)
assert.True(t, resp.IsBroadcast())
})
}

View File

@@ -1,4 +1,4 @@
//go:build darwin || freebsd || linux || openbsd
//go:build linux
package dhcpd
@@ -9,6 +9,7 @@ import (
"time"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
@@ -238,3 +239,53 @@ func (c *dhcpConn) buildEtherPkt(payload []byte, peer *dhcpUnicastAddr) (pkt []b
return buf.Bytes(), nil
}
// send writes resp for peer to conn considering the req's parameters according
// to RFC-2131.
//
// See https://datatracker.ietf.org/doc/html/rfc2131#section-4.1.
func (s *v4Server) send(peer net.Addr, conn net.PacketConn, req, resp *dhcpv4.DHCPv4) {
switch giaddr, ciaddr, mtype := req.GatewayIPAddr, req.ClientIPAddr, resp.MessageType(); {
case giaddr != nil && !giaddr.IsUnspecified():
// Send any return messages to the server port on the BOOTP
// relay agent whose address appears in giaddr.
peer = &net.UDPAddr{
IP: giaddr,
Port: dhcpv4.ServerPort,
}
if mtype == dhcpv4.MessageTypeNak {
// Set the broadcast bit in the DHCPNAK, so that the relay agent
// broadcasts it to the client, because the client may not have
// a correct network address or subnet mask, and the client may not
// be answering ARP requests.
resp.SetBroadcast()
}
case mtype == dhcpv4.MessageTypeNak:
// Broadcast any DHCPNAK messages to 0xffffffff.
case ciaddr != nil && !ciaddr.IsUnspecified():
// Unicast DHCPOFFER and DHCPACK messages to the address in
// ciaddr.
peer = &net.UDPAddr{
IP: ciaddr,
Port: dhcpv4.ClientPort,
}
case !req.IsBroadcast() && req.ClientHWAddr != nil:
// Unicast DHCPOFFER and DHCPACK messages to the client's
// hardware address and yiaddr.
peer = &dhcpUnicastAddr{
Addr: packet.Addr{HardwareAddr: req.ClientHWAddr},
yiaddr: resp.YourIPAddr,
}
default:
// Go on since peer is already set to broadcast.
}
pktData := resp.ToBytes()
log.Debug("dhcpv4: sending %d bytes to %s: %s", len(pktData), peer, resp.Summary())
_, err := conn.WriteTo(pktData, peer)
if err != nil {
log.Error("dhcpv4: conn.Write to %s failed: %s", peer, err)
}
}

View File

@@ -1,4 +1,4 @@
//go:build darwin || freebsd || linux || openbsd
//go:build linux
package dhcpd
@@ -110,3 +110,108 @@ func TestBuildEtherPkt(t *testing.T) {
assert.Empty(t, pkt)
})
}
func TestV4Server_Send(t *testing.T) {
s := &v4Server{}
var (
defaultIP = net.IP{99, 99, 99, 99}
knownIP = net.IP{4, 2, 4, 2}
knownMAC = net.HardwareAddr{6, 5, 4, 3, 2, 1}
)
defaultPeer := &net.UDPAddr{
IP: defaultIP,
// Use neither client nor server port to check it actually
// changed.
Port: dhcpv4.ClientPort + dhcpv4.ServerPort,
}
defaultResp := &dhcpv4.DHCPv4{}
testCases := []struct {
want net.Addr
req *dhcpv4.DHCPv4
resp *dhcpv4.DHCPv4
name string
}{{
name: "giaddr",
req: &dhcpv4.DHCPv4{GatewayIPAddr: knownIP},
resp: defaultResp,
want: &net.UDPAddr{
IP: knownIP,
Port: dhcpv4.ServerPort,
},
}, {
name: "nak",
req: &dhcpv4.DHCPv4{},
resp: &dhcpv4.DHCPv4{
Options: dhcpv4.OptionsFromList(
dhcpv4.OptMessageType(dhcpv4.MessageTypeNak),
),
},
want: defaultPeer,
}, {
name: "ciaddr",
req: &dhcpv4.DHCPv4{ClientIPAddr: knownIP},
resp: &dhcpv4.DHCPv4{},
want: &net.UDPAddr{
IP: knownIP,
Port: dhcpv4.ClientPort,
},
}, {
name: "chaddr",
req: &dhcpv4.DHCPv4{ClientHWAddr: knownMAC},
resp: &dhcpv4.DHCPv4{YourIPAddr: knownIP},
want: &dhcpUnicastAddr{
Addr: packet.Addr{HardwareAddr: knownMAC},
yiaddr: knownIP,
},
}, {
name: "who_are_you",
req: &dhcpv4.DHCPv4{},
resp: &dhcpv4.DHCPv4{},
want: defaultPeer,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
conn := &fakePacketConn{
writeTo: func(_ []byte, addr net.Addr) (_ int, _ error) {
assert.Equal(t, tc.want, addr)
return 0, nil
},
}
s.send(cloneUDPAddr(defaultPeer), conn, tc.req, tc.resp)
})
}
t.Run("giaddr_nak", func(t *testing.T) {
req := &dhcpv4.DHCPv4{
GatewayIPAddr: knownIP,
}
// Ensure the request is for unicast.
req.SetUnicast()
resp := &dhcpv4.DHCPv4{
Options: dhcpv4.OptionsFromList(
dhcpv4.OptMessageType(dhcpv4.MessageTypeNak),
),
}
want := &net.UDPAddr{
IP: req.GatewayIPAddr,
Port: dhcpv4.ServerPort,
}
conn := &fakePacketConn{
writeTo: func(_ []byte, addr net.Addr) (n int, err error) {
assert.Equal(t, want, addr)
return 0, nil
},
}
s.send(cloneUDPAddr(defaultPeer), conn, req, resp)
assert.True(t, resp.IsBroadcast())
})
}

View File

@@ -5,43 +5,34 @@ package dhcpd
import (
"encoding/json"
"fmt"
"net"
"net/netip"
"os"
"time"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/google/renameio/maybe"
"golang.org/x/exp/slices"
)
const dbFilename = "leases.db"
const (
// dataFilename contains saved leases.
dataFilename = "leases.json"
type leaseJSON struct {
HWAddr []byte `json:"mac"`
IP []byte `json:"ip"`
Hostname string `json:"host"`
Expiry int64 `json:"exp"`
// dataVersion is the current version of the stored DHCP leases structure.
dataVersion = 1
)
// dataLeases is the structure of the stored DHCP leases.
type dataLeases struct {
// Version is the current version of the structure.
Version int `json:"version"`
// Leases is the list containing stored DHCP leases.
Leases []*Lease `json:"leases"`
}
func normalizeIP(ip net.IP) net.IP {
ip4 := ip.To4()
if ip4 != nil {
return ip4
}
return ip
}
// Load lease table from DB
//
// TODO(s.chzhen): Decrease complexity.
// dbLoad loads stored leases.
func (s *server) dbLoad() (err error) {
dynLeases := []*Lease{}
staticLeases := []*Lease{}
v6StaticLeases := []*Lease{}
v6DynLeases := []*Lease{}
data, err := os.ReadFile(s.conf.DBFilePath)
data, err := os.ReadFile(s.conf.dbFilePath)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("reading db: %w", err)
@@ -50,51 +41,30 @@ func (s *server) dbLoad() (err error) {
return nil
}
obj := []leaseJSON{}
err = json.Unmarshal(data, &obj)
dl := &dataLeases{}
err = json.Unmarshal(data, dl)
if err != nil {
return fmt.Errorf("decoding db: %w", err)
}
numLeases := len(obj)
for i := range obj {
obj[i].IP = normalizeIP(obj[i].IP)
leases := dl.Leases
ip, ok := netip.AddrFromSlice(obj[i].IP)
if !ok {
log.Info("dhcp: invalid IP: %s", obj[i].IP)
continue
}
leases4 := []*Lease{}
leases6 := []*Lease{}
lease := Lease{
HWAddr: obj[i].HWAddr,
IP: ip,
Hostname: obj[i].Hostname,
Expiry: time.Unix(obj[i].Expiry, 0),
}
if len(obj[i].IP) == 16 {
if obj[i].Expiry == leaseExpireStatic {
v6StaticLeases = append(v6StaticLeases, &lease)
} else {
v6DynLeases = append(v6DynLeases, &lease)
}
for _, l := range leases {
if l.IP.Is4() {
leases4 = append(leases4, l)
} else {
if obj[i].Expiry == leaseExpireStatic {
staticLeases = append(staticLeases, &lease)
} else {
dynLeases = append(dynLeases, &lease)
}
leases6 = append(leases6, l)
}
}
leases4 := normalizeLeases(staticLeases, dynLeases)
err = s.srv4.ResetLeases(leases4)
if err != nil {
return fmt.Errorf("resetting dhcpv4 leases: %w", err)
}
leases6 := normalizeLeases(v6StaticLeases, v6DynLeases)
if s.srv6 != nil {
err = s.srv6.ResetLeases(leases6)
if err != nil {
@@ -103,90 +73,54 @@ func (s *server) dbLoad() (err error) {
}
log.Info("dhcp: loaded leases v4:%d v6:%d total-read:%d from DB",
len(leases4), len(leases6), numLeases)
len(leases4), len(leases6), len(leases))
return nil
}
// Skip duplicate leases
// Static leases have a priority over dynamic leases
func normalizeLeases(staticLeases, dynLeases []*Lease) []*Lease {
leases := []*Lease{}
index := map[string]int{}
for i, lease := range staticLeases {
_, ok := index[lease.HWAddr.String()]
if ok {
continue // skip the lease with the same HW address
}
index[lease.HWAddr.String()] = i
leases = append(leases, lease)
}
for i, lease := range dynLeases {
_, ok := index[lease.HWAddr.String()]
if ok {
continue // skip the lease with the same HW address
}
index[lease.HWAddr.String()] = i
leases = append(leases, lease)
}
return leases
}
// Store lease table in DB
// dbStore stores DHCP leases.
func (s *server) dbStore() (err error) {
// Use an empty slice here as opposed to nil so that it doesn't write
// "null" into the database file if leases are empty.
leases := []leaseJSON{}
leases := []*Lease{}
leases4 := s.srv4.getLeasesRef()
for _, l := range leases4 {
if l.Expiry.Unix() == 0 {
continue
}
lease := leaseJSON{
HWAddr: l.HWAddr,
IP: l.IP.AsSlice(),
Hostname: l.Hostname,
Expiry: l.Expiry.Unix(),
}
leases = append(leases, lease)
}
leases = append(leases, leases4...)
if s.srv6 != nil {
leases6 := s.srv6.getLeasesRef()
for _, l := range leases6 {
if l.Expiry.Unix() == 0 {
continue
}
lease := leaseJSON{
HWAddr: l.HWAddr,
IP: l.IP.AsSlice(),
Hostname: l.Hostname,
Expiry: l.Expiry.Unix(),
}
leases = append(leases, lease)
}
leases = append(leases, leases6...)
}
var data []byte
data, err = json.Marshal(leases)
return writeDB(s.conf.dbFilePath, leases)
}
// writeDB writes leases to file at path.
func writeDB(path string, leases []*Lease) (err error) {
defer func() { err = errors.Annotate(err, "writing db: %w") }()
slices.SortFunc(leases, func(a, b *Lease) bool {
return a.Hostname < b.Hostname
})
dl := &dataLeases{
Version: dataVersion,
Leases: leases,
}
buf, err := json.Marshal(dl)
if err != nil {
return fmt.Errorf("encoding db: %w", err)
// Don't wrap the error since it's informative enough as is.
return err
}
err = maybe.WriteFile(s.conf.DBFilePath, data, 0o644)
err = maybe.WriteFile(path, buf, 0o644)
if err != nil {
return fmt.Errorf("writing db: %w", err)
// Don't wrap the error since it's informative enough as is.
return err
}
log.Info("dhcp: stored %d leases in db", len(leases))
log.Info("dhcp: stored %d leases in %q", len(leases), path)
return nil
}

View File

@@ -15,13 +15,6 @@ import (
)
const (
// leaseExpireStatic is used to define the Expiry field for static
// leases.
//
// TODO(e.burkov): Remove it when static leases determining mechanism
// will be improved.
leaseExpireStatic = 1
// DefaultDHCPLeaseTTL is the default time-to-live for leases.
DefaultDHCPLeaseTTL = uint32(timeutil.Day / time.Second)
@@ -35,10 +28,10 @@ const (
defaultBackoff time.Duration = 500 * time.Millisecond
)
// Lease contains the necessary information about a DHCP lease
// Lease contains the necessary information about a DHCP lease. It's used in
// various places. So don't change it without good reason.
type Lease struct {
// Expiry is the expiration time of the lease. The unix timestamp value
// of 1 means that this is a static lease.
// Expiry is the expiration time of the lease.
Expiry time.Time `json:"expires"`
// Hostname of the client.
@@ -51,6 +44,9 @@ type Lease struct {
//
// TODO(a.garipov): Migrate leases.db.
IP netip.Addr `json:"ip"`
// IsStatic defines if the lease is static.
IsStatic bool `json:"static"`
}
// Clone returns a deep copy of l.
@@ -64,6 +60,7 @@ func (l *Lease) Clone() (clone *Lease) {
Hostname: l.Hostname,
HWAddr: slices.Clone(l.HWAddr),
IP: l.IP,
IsStatic: l.IsStatic,
}
}
@@ -84,17 +81,10 @@ func (l *Lease) IsBlocklisted() (ok bool) {
return true
}
// IsStatic returns true if the lease is static.
//
// TODO(a.garipov): Just make it a boolean field.
func (l *Lease) IsStatic() (ok bool) {
return l != nil && l.Expiry.Unix() == leaseExpireStatic
}
// MarshalJSON implements the json.Marshaler interface for Lease.
func (l Lease) MarshalJSON() ([]byte, error) {
var expiryStr string
if !l.IsStatic() {
if !l.IsStatic {
// The front-end is waiting for RFC 3999 format of the time
// value. It also shouldn't got an Expiry field for static
// leases.
@@ -241,7 +231,7 @@ func Create(conf *ServerConfig) (s *server, err error) {
LocalDomainName: conf.LocalDomainName,
DBFilePath: filepath.Join(conf.WorkDir, dbFilename),
dbFilePath: filepath.Join(conf.DataDir, dataFilename),
},
}
@@ -249,39 +239,26 @@ func Create(conf *ServerConfig) (s *server, err error) {
// [aghhttp.RegisterFunc].
s.registerHandlers()
v4conf := conf.Conf4
v4conf.InterfaceName = s.conf.InterfaceName
v4conf.notify = s.onNotify
v4conf.Enabled = s.conf.Enabled && v4conf.RangeStart.IsValid()
s.srv4, err = v4Create(&v4conf)
v4Enabled, v6Enabled, err := s.setServers(conf)
if err != nil {
if v4conf.Enabled {
return nil, fmt.Errorf("creating dhcpv4 srv: %w", err)
}
log.Debug("dhcpd: warning: creating dhcpv4 srv: %s", err)
}
v6conf := conf.Conf6
v6conf.Enabled = s.conf.Enabled
if len(v6conf.RangeStart) == 0 {
v6conf.Enabled = false
}
v6conf.InterfaceName = s.conf.InterfaceName
v6conf.notify = s.onNotify
s.srv6, err = v6Create(v6conf)
if err != nil {
return nil, fmt.Errorf("creating dhcpv6 srv: %w", err)
// Don't wrap the error, because it's informative enough as is.
return nil, err
}
s.conf.Conf4 = conf.Conf4
s.conf.Conf6 = conf.Conf6
if s.conf.Enabled && !v4conf.Enabled && !v6conf.Enabled {
if s.conf.Enabled && !v4Enabled && !v6Enabled {
return nil, fmt.Errorf("neither dhcpv4 nor dhcpv6 srv is configured")
}
// Migrate leases db if needed.
err = migrateDB(conf)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}
// Don't delay database loading until the DHCP server is started,
// because we need static leases functionality available beforehand.
err = s.dbLoad()
@@ -292,6 +269,39 @@ func Create(conf *ServerConfig) (s *server, err error) {
return s, nil
}
// setServers updates DHCPv4 and DHCPv6 servers created from the provided
// configuration conf.
func (s *server) setServers(conf *ServerConfig) (v4Enabled, v6Enabled bool, err error) {
v4conf := conf.Conf4
v4conf.InterfaceName = s.conf.InterfaceName
v4conf.notify = s.onNotify
v4conf.Enabled = s.conf.Enabled && v4conf.RangeStart.IsValid()
s.srv4, err = v4Create(&v4conf)
if err != nil {
if v4conf.Enabled {
return true, false, fmt.Errorf("creating dhcpv4 srv: %w", err)
}
log.Debug("dhcpd: warning: creating dhcpv4 srv: %s", err)
}
v6conf := conf.Conf6
v6conf.InterfaceName = s.conf.InterfaceName
v6conf.notify = s.onNotify
v6conf.Enabled = s.conf.Enabled
if len(v6conf.RangeStart) == 0 {
v6conf.Enabled = false
}
s.srv6, err = v6Create(v6conf)
if err != nil {
return v4conf.Enabled, v6conf.Enabled, fmt.Errorf("creating dhcpv6 srv: %w", err)
}
return v4conf.Enabled, v6conf.Enabled, nil
}
// Enabled returns true when the server is enabled.
func (s *server) Enabled() (ok bool) {
return s.conf.Enabled

View File

@@ -5,7 +5,7 @@ package dhcpd
import (
"net"
"net/netip"
"os"
"path/filepath"
"testing"
"time"
@@ -27,7 +27,7 @@ func TestDB(t *testing.T) {
var err error
s := server{
conf: &ServerConfig{
DBFilePath: dbFilename,
dbFilePath: filepath.Join(t.TempDir(), dataFilename),
},
}
@@ -67,8 +67,6 @@ func TestDB(t *testing.T) {
err = s.dbStore()
require.NoError(t, err)
testutil.CleanupAndRequireSuccess(t, func() (err error) { return os.Remove(dbFilename) })
err = s.srv4.ResetLeases(nil)
require.NoError(t, err)
@@ -78,36 +76,13 @@ func TestDB(t *testing.T) {
ll := s.srv4.GetLeases(LeasesAll)
require.Len(t, ll, len(leases))
assert.Equal(t, leases[1].HWAddr, ll[0].HWAddr)
assert.Equal(t, leases[1].IP, ll[0].IP)
assert.True(t, ll[0].IsStatic())
assert.Equal(t, leases[0].HWAddr, ll[0].HWAddr)
assert.Equal(t, leases[0].IP, ll[0].IP)
assert.Equal(t, leases[0].Expiry.Unix(), ll[0].Expiry.Unix())
assert.Equal(t, leases[0].HWAddr, ll[1].HWAddr)
assert.Equal(t, leases[0].IP, ll[1].IP)
assert.Equal(t, leases[0].Expiry.Unix(), ll[1].Expiry.Unix())
}
func TestNormalizeLeases(t *testing.T) {
dynLeases := []*Lease{{
HWAddr: net.HardwareAddr{1, 2, 3, 4},
}, {
HWAddr: net.HardwareAddr{1, 2, 3, 5},
}}
staticLeases := []*Lease{{
HWAddr: net.HardwareAddr{1, 2, 3, 4},
IP: netip.MustParseAddr("0.2.3.4"),
}, {
HWAddr: net.HardwareAddr{2, 2, 3, 4},
}}
leases := normalizeLeases(staticLeases, dynLeases)
require.Len(t, leases, 3)
assert.Equal(t, leases[0].HWAddr, dynLeases[0].HWAddr)
assert.Equal(t, leases[0].IP, staticLeases[0].IP)
assert.Equal(t, leases[1].HWAddr, staticLeases[1].HWAddr)
assert.Equal(t, leases[2].HWAddr, dynLeases[1].HWAddr)
assert.Equal(t, leases[1].HWAddr, ll[1].HWAddr)
assert.Equal(t, leases[1].IP, ll[1].IP)
assert.True(t, ll[1].IsStatic)
}
func TestV4Server_badRange(t *testing.T) {

View File

@@ -9,12 +9,14 @@ import (
"net/http"
"net/netip"
"os"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
)
type v4ServerConfJSON struct {
@@ -57,12 +59,77 @@ func v6JSONToServerConf(j *v6ServerConfJSON) V6ServerConf {
// dhcpStatusResponse is the response for /control/dhcp/status endpoint.
type dhcpStatusResponse struct {
IfaceName string `json:"interface_name"`
V4 V4ServerConf `json:"v4"`
V6 V6ServerConf `json:"v6"`
Leases []*Lease `json:"leases"`
StaticLeases []*Lease `json:"static_leases"`
Enabled bool `json:"enabled"`
IfaceName string `json:"interface_name"`
V4 V4ServerConf `json:"v4"`
V6 V6ServerConf `json:"v6"`
Leases []*leaseDynamic `json:"leases"`
StaticLeases []*leaseStatic `json:"static_leases"`
Enabled bool `json:"enabled"`
}
// leaseStatic is the JSON form of static DHCP lease.
type leaseStatic struct {
HWAddr string `json:"mac"`
IP netip.Addr `json:"ip"`
Hostname string `json:"hostname"`
}
// leasesToStatic converts list of leases to their JSON form.
func leasesToStatic(leases []*Lease) (static []*leaseStatic) {
static = make([]*leaseStatic, len(leases))
for i, l := range leases {
static[i] = &leaseStatic{
HWAddr: l.HWAddr.String(),
IP: l.IP,
Hostname: l.Hostname,
}
}
return static
}
// toLease converts leaseStatic to Lease or returns error.
func (l *leaseStatic) toLease() (lease *Lease, err error) {
addr, err := net.ParseMAC(l.HWAddr)
if err != nil {
return nil, fmt.Errorf("couldn't parse MAC address: %w", err)
}
return &Lease{
HWAddr: addr,
IP: l.IP,
Hostname: l.Hostname,
IsStatic: true,
}, nil
}
// leaseDynamic is the JSON form of dynamic DHCP lease.
type leaseDynamic struct {
HWAddr string `json:"mac"`
IP netip.Addr `json:"ip"`
Hostname string `json:"hostname"`
Expiry string `json:"expires"`
}
// leasesToDynamic converts list of leases to their JSON form.
func leasesToDynamic(leases []*Lease) (dynamic []*leaseDynamic) {
dynamic = make([]*leaseDynamic, len(leases))
for i, l := range leases {
dynamic[i] = &leaseDynamic{
HWAddr: l.HWAddr.String(),
IP: l.IP,
Hostname: l.Hostname,
// The front-end is waiting for RFC 3999 format of the time
// value.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/2692.
Expiry: l.Expiry.Format(time.RFC3339),
}
}
return dynamic
}
func (s *server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
@@ -76,8 +143,8 @@ func (s *server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
s.srv4.WriteDiskConfig4(&status.V4)
s.srv6.WriteDiskConfig6(&status.V6)
status.Leases = s.Leases(LeasesDynamic)
status.StaticLeases = s.Leases(LeasesStatic)
status.Leases = leasesToDynamic(s.Leases(LeasesDynamic))
status.StaticLeases = leasesToStatic(s.Leases(LeasesStatic))
_ = aghhttp.WriteJSONResponse(w, r, status)
}
@@ -197,6 +264,28 @@ func (s *server) handleDHCPSetConfigV6(
return srv6, enabled, err
}
// createServers returns DHCPv4 and DHCPv6 servers created from the provided
// configuration conf.
func (s *server) createServers(conf *dhcpServerConfigJSON) (srv4, srv6 DHCPServer, err error) {
srv4, v4Enabled, err := s.handleDHCPSetConfigV4(conf)
if err != nil {
return nil, nil, fmt.Errorf("bad dhcpv4 configuration: %s", err)
}
srv6, v6Enabled, err := s.handleDHCPSetConfigV6(conf)
if err != nil {
return nil, nil, fmt.Errorf("bad dhcpv6 configuration: %s", err)
}
if conf.Enabled == aghalg.NBTrue && !v4Enabled && !v6Enabled {
return nil, nil, fmt.Errorf("dhcpv4 or dhcpv6 configuration must be complete")
}
return srv4, srv6, nil
}
// handleDHCPSetConfig is the handler for the POST /control/dhcp/set_config
// HTTP API.
func (s *server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
conf := &dhcpServerConfigJSON{}
conf.Enabled = aghalg.BoolToNullBool(s.conf.Enabled)
@@ -209,22 +298,9 @@ func (s *server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
return
}
srv4, v4Enabled, err := s.handleDHCPSetConfigV4(conf)
srv4, srv6, err := s.createServers(conf)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "bad dhcpv4 configuration: %s", err)
return
}
srv6, v6Enabled, err := s.handleDHCPSetConfigV6(conf)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "bad dhcpv6 configuration: %s", err)
return
}
if conf.Enabled == aghalg.NBTrue && !v4Enabled && !v6Enabled {
aghhttp.Error(r, w, http.StatusBadRequest, "dhcpv4 or dhcpv6 configuration must be complete")
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
return
}
@@ -284,8 +360,10 @@ type netInterfaceJSON struct {
Addrs6 []netip.Addr `json:"ipv6_addresses"`
}
// handleDHCPInterfaces is the handler for the GET /control/dhcp/interfaces
// HTTP API.
func (s *server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
response := map[string]netInterfaceJSON{}
resp := map[string]*netInterfaceJSON{}
ifaces, err := net.Interfaces()
if err != nil {
@@ -296,82 +374,86 @@ func (s *server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
for _, iface := range ifaces {
if iface.Flags&net.FlagLoopback != 0 {
// it's a loopback, skip it
continue
}
if iface.Flags&net.FlagBroadcast == 0 {
// this interface doesn't support broadcast, skip it
// It's a loopback, skip it.
continue
}
var addrs []net.Addr
addrs, err = iface.Addrs()
if err != nil {
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"Failed to get addresses for interface %s: %s",
iface.Name,
err,
)
if iface.Flags&net.FlagBroadcast == 0 {
// This interface doesn't support broadcast, skip it.
continue
}
jsonIface, iErr := newNetInterfaceJSON(iface)
if iErr != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", iErr)
return
}
jsonIface := netInterfaceJSON{
Name: iface.Name,
HardwareAddr: iface.HardwareAddr.String(),
}
if iface.Flags != 0 {
jsonIface.Flags = iface.Flags.String()
}
// we don't want link-local addresses in json, so skip them
for _, addr := range addrs {
ipnet, ok := addr.(*net.IPNet)
if !ok {
// not an IPNet, should not happen
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"got iface.Addrs() element %[1]s that is not net.IPNet, it is %[1]T",
addr)
return
}
// ignore link-local
//
// TODO(e.burkov): Try to listen DHCP on LLA as well.
if ipnet.IP.IsLinkLocalUnicast() {
continue
}
if ip4 := ipnet.IP.To4(); ip4 != nil {
addr := netip.AddrFrom4(*(*[4]byte)(ip4))
jsonIface.Addrs4 = append(jsonIface.Addrs4, addr)
} else {
addr := netip.AddrFrom16(*(*[16]byte)(ipnet.IP))
jsonIface.Addrs6 = append(jsonIface.Addrs6, addr)
}
}
if len(jsonIface.Addrs4)+len(jsonIface.Addrs6) != 0 {
jsonIface.GatewayIP = aghnet.GatewayIP(iface.Name)
response[iface.Name] = jsonIface
if jsonIface != nil {
resp[iface.Name] = jsonIface
}
}
err = json.NewEncoder(w).Encode(response)
_ = aghhttp.WriteJSONResponse(w, r, resp)
}
// newNetInterfaceJSON creates a JSON object from a [net.Interface] iface.
func newNetInterfaceJSON(iface net.Interface) (out *netInterfaceJSON, err error) {
addrs, err := iface.Addrs()
if err != nil {
aghhttp.Error(
r,
w,
http.StatusInternalServerError,
"Failed to marshal json with available interfaces: %s",
return nil, fmt.Errorf(
"failed to get addresses for interface %s: %s",
iface.Name,
err,
)
}
out = &netInterfaceJSON{
Name: iface.Name,
HardwareAddr: iface.HardwareAddr.String(),
}
if iface.Flags != 0 {
out.Flags = iface.Flags.String()
}
// We don't want link-local addresses in JSON, so skip them.
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if !ok {
// Not an IPNet, should not happen.
return nil, fmt.Errorf("got iface.Addrs() element %[1]s that is not"+
" net.IPNet, it is %[1]T", addr)
}
// Ignore link-local.
//
// TODO(e.burkov): Try to listen DHCP on LLA as well.
if ipNet.IP.IsLinkLocalUnicast() {
continue
}
vAddr, iErr := netutil.IPToAddrNoMapped(ipNet.IP)
if iErr != nil {
// Not an IPNet, should not happen.
return nil, fmt.Errorf("failed to convert IP address %[1]s: %w", addr, iErr)
}
if vAddr.Is4() {
out.Addrs4 = append(out.Addrs4, vAddr)
} else {
out.Addrs6 = append(out.Addrs6, vAddr)
}
}
if len(out.Addrs4)+len(out.Addrs6) == 0 {
return nil, nil
}
out.GatewayIP = aghnet.GatewayIP(iface.Name)
return out, nil
}
// dhcpSearchOtherResult contains information about other DHCP server for
@@ -488,7 +570,7 @@ func setOtherDHCPResult(ifaceName string, result *dhcpSearchResult) {
}
func (s *server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
l := &Lease{}
l := &leaseStatic{}
err := json.NewDecoder(r.Body).Decode(l)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "json.Decode: %s", err)
@@ -511,7 +593,14 @@ func (s *server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
srv = s.srv6
}
err = srv.AddStaticLease(l)
lease, err := l.toLease()
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "parsing: %s", err)
return
}
err = srv.AddStaticLease(lease)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
@@ -520,7 +609,7 @@ func (s *server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request
}
func (s *server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
l := &Lease{}
l := &leaseStatic{}
err := json.NewDecoder(r.Body).Decode(l)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "json.Decode: %s", err)
@@ -543,7 +632,14 @@ func (s *server) handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Requ
srv = s.srv6
}
err = srv.RemoveStaticLease(l)
lease, err := l.toLease()
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "parsing: %s", err)
return
}
err = srv.RemoveStaticLease(lease)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
@@ -559,7 +655,7 @@ func (s *server) handleReset(w http.ResponseWriter, r *http.Request) {
return
}
err = os.Remove(s.conf.DBFilePath)
err = os.Remove(s.conf.dbFilePath)
if err != nil && !errors.Is(err, os.ErrNotExist) {
log.Error("dhcp: removing db: %s", err)
}
@@ -571,8 +667,8 @@ func (s *server) handleReset(w http.ResponseWriter, r *http.Request) {
LocalDomainName: s.conf.LocalDomainName,
WorkDir: s.conf.WorkDir,
DBFilePath: s.conf.DBFilePath,
DataDir: s.conf.DataDir,
dbFilePath: s.conf.dbFilePath,
}
v4conf := &V4ServerConf{

View File

@@ -5,35 +5,33 @@ package dhcpd
import (
"bytes"
"encoding/json"
"net"
"net/http"
"net/http/httptest"
"net/netip"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestServer_handleDHCPStatus(t *testing.T) {
const staticName = "static-client"
const (
staticName = "static-client"
staticMAC = "aa:aa:aa:aa:aa:aa"
)
staticIP := netip.MustParseAddr("192.168.10.10")
staticMAC := net.HardwareAddr{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}
staticLease := &Lease{
Expiry: time.Unix(leaseExpireStatic, 0),
Hostname: staticName,
staticLease := &leaseStatic{
HWAddr: staticMAC,
IP: staticIP,
Hostname: staticName,
}
s, err := Create(&ServerConfig{
Enabled: true,
Conf4: *defaultV4ServerConf(),
WorkDir: t.TempDir(),
DBFilePath: dbFilename,
DataDir: t.TempDir(),
ConfigModified: func() {},
})
require.NoError(t, err)
@@ -65,8 +63,8 @@ func TestServer_handleDHCPStatus(t *testing.T) {
resp := &dhcpStatusResponse{
V4: *conf4,
V6: V6ServerConf{},
Leases: []*Lease{},
StaticLeases: []*Lease{},
Leases: []*leaseDynamic{},
StaticLeases: []*leaseStatic{},
Enabled: true,
}
@@ -95,7 +93,7 @@ func TestServer_handleDHCPStatus(t *testing.T) {
assert.Equal(t, http.StatusOK, w.Code)
resp := defaultResponse()
resp.StaticLeases = []*Lease{staticLease}
resp.StaticLeases = []*leaseStatic{staticLease}
checkStatus(t, resp)
})
@@ -106,7 +104,7 @@ func TestServer_handleDHCPStatus(t *testing.T) {
b := &bytes.Buffer{}
err = json.NewEncoder(b).Encode(&Lease{})
err = json.NewEncoder(b).Encode(&leaseStatic{})
require.NoError(t, err)
var r *http.Request

106
internal/dhcpd/migrate.go Normal file
View File

@@ -0,0 +1,106 @@
package dhcpd
import (
"encoding/json"
"net"
"net/netip"
"os"
"path/filepath"
"time"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
)
const (
// leaseExpireStatic is used to define the Expiry field for static
// leases.
//
// Deprecated: Remove it when migration of DHCP leases will be not needed.
leaseExpireStatic = 1
// dbFilename contains saved leases.
//
// Deprecated: Use dataFilename.
dbFilename = "leases.db"
)
// leaseJSON is the structure of stored lease.
//
// Deprecated: Use [Lease].
type leaseJSON struct {
HWAddr []byte `json:"mac"`
IP []byte `json:"ip"`
Hostname string `json:"host"`
Expiry int64 `json:"exp"`
}
func normalizeIP(ip net.IP) net.IP {
ip4 := ip.To4()
if ip4 != nil {
return ip4
}
return ip
}
// migrateDB migrates stored leases if necessary.
func migrateDB(conf *ServerConfig) (err error) {
defer func() { err = errors.Annotate(err, "migrating db: %w") }()
oldLeasesPath := filepath.Join(conf.WorkDir, dbFilename)
dataDirPath := filepath.Join(conf.DataDir, dataFilename)
file, err := os.Open(oldLeasesPath)
if errors.Is(err, os.ErrNotExist) {
// Nothing to migrate.
return nil
} else if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
}
ljs := []leaseJSON{}
err = json.NewDecoder(file).Decode(&ljs)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
}
err = file.Close()
if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
}
leases := []*Lease{}
for _, lj := range ljs {
lj.IP = normalizeIP(lj.IP)
ip, ok := netip.AddrFromSlice(lj.IP)
if !ok {
log.Info("dhcp: invalid IP: %s", lj.IP)
continue
}
lease := &Lease{
Expiry: time.Unix(lj.Expiry, 0),
Hostname: lj.Hostname,
HWAddr: lj.HWAddr,
IP: ip,
IsStatic: lj.Expiry == leaseExpireStatic,
}
leases = append(leases, lease)
}
err = writeDB(dataDirPath, leases)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return err
}
return os.Remove(oldLeasesPath)
}

View File

@@ -0,0 +1,73 @@
package dhcpd
import (
"encoding/json"
"net"
"net/netip"
"os"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const testData = `[
{"mac":"ESIzRFVm","ip":"AQIDBA==","host":"test1","exp":1},
{"mac":"ZlVEMyIR","ip":"BAMCAQ==","host":"test2","exp":1231231231}
]`
func TestMigrateDB(t *testing.T) {
dir := t.TempDir()
oldLeasesPath := filepath.Join(dir, dbFilename)
dataDirPath := filepath.Join(dir, dataFilename)
err := os.WriteFile(oldLeasesPath, []byte(testData), 0o644)
require.NoError(t, err)
wantLeases := []*Lease{{
Expiry: time.Time{},
Hostname: "test1",
HWAddr: net.HardwareAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
IP: netip.MustParseAddr("1.2.3.4"),
IsStatic: true,
}, {
Expiry: time.Unix(1231231231, 0),
Hostname: "test2",
HWAddr: net.HardwareAddr{0x66, 0x55, 0x44, 0x33, 0x22, 0x11},
IP: netip.MustParseAddr("4.3.2.1"),
IsStatic: false,
}}
conf := &ServerConfig{
WorkDir: dir,
DataDir: dir,
}
err = migrateDB(conf)
require.NoError(t, err)
_, err = os.Stat(oldLeasesPath)
require.ErrorIs(t, err, os.ErrNotExist)
var data []byte
data, err = os.ReadFile(dataDirPath)
require.NoError(t, err)
dl := &dataLeases{}
err = json.Unmarshal(data, dl)
require.NoError(t, err)
leases := dl.Leases
for i, wl := range wantLeases {
assert.Equal(t, wl.Hostname, leases[i].Hostname)
assert.Equal(t, wl.HWAddr, leases[i].HWAddr)
assert.Equal(t, wl.IP, leases[i].IP)
assert.Equal(t, wl.IsStatic, leases[i].IsStatic)
require.True(t, wl.Expiry.Equal(leases[i].Expiry))
}
}

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