Pull request 1966: 6050 upd urlfilter

Merge in DNS/adguard-home from upd-urlfilter to master

Updates #6050.

Squashed commit of the following:

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

    Merge branch 'master' into upd-urlfilter

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

    dnsforward: imp code, docs

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

    Merge branch 'master' into upd-urlfilter

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

    all: log changes

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

    Merge branch 'master' into upd-urlfilter

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

    all: upd urlfilter

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

    Merge branch 'master' into upd-urlfilter

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

    all: imp code, docs

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

    all: upd urlfilter
This commit is contained in:
Eugene Burkov 2023-08-23 16:58:24 +03:00
parent 31f7aaecc3
commit 28cfde9212
28 changed files with 335 additions and 314 deletions

View file

@ -38,6 +38,8 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Changed ### Changed
- `$dnsrewrite` rules containing IPv4-mapped IPv6 addresses are now working
consistently with legacy DNS rewrites and match the `AAAA` requests.
- For non-A and non-AAAA requests, which has been filtered, the NODATA response - For non-A and non-AAAA requests, which has been filtered, the NODATA response
is returned if the blocking mode isn't set to `Null IP`. In previous versions is returned if the blocking mode isn't set to `Null IP`. In previous versions
it returned NXDOMAIN response in such cases. it returned NXDOMAIN response in such cases.
@ -67,6 +69,8 @@ In this release, the schema version has changed from 24 to 25.
### Fixed ### Fixed
- Legacy DNS rewrites containing IPv4-mapped IPv6 addresses are now matching the
`AAAA` requests, not `A` ([#6050]).
- File log configuration, such as `max_size`, being ignored ([#6093]). - File log configuration, such as `max_size`, being ignored ([#6093]).
- Panic on using a single-slash filtering rule. - Panic on using a single-slash filtering rule.
- Panic on shutting down while DNS requests are in process of filtering - Panic on shutting down while DNS requests are in process of filtering
@ -76,6 +80,7 @@ In this release, the schema version has changed from 24 to 25.
[#3701]: https://github.com/AdguardTeam/AdGuardHome/issues/3701 [#3701]: https://github.com/AdguardTeam/AdGuardHome/issues/3701
[#5948]: https://github.com/AdguardTeam/AdGuardHome/issues/5948 [#5948]: https://github.com/AdguardTeam/AdGuardHome/issues/5948
[#6020]: https://github.com/AdguardTeam/AdGuardHome/issues/6020 [#6020]: https://github.com/AdguardTeam/AdGuardHome/issues/6020
[#6050]: https://github.com/AdguardTeam/AdGuardHome/issues/6050
[#6053]: https://github.com/AdguardTeam/AdGuardHome/issues/6053 [#6053]: https://github.com/AdguardTeam/AdGuardHome/issues/6053
[#6093]: https://github.com/AdguardTeam/AdGuardHome/issues/6093 [#6093]: https://github.com/AdguardTeam/AdGuardHome/issues/6093
[#6122]: https://github.com/AdguardTeam/AdGuardHome/issues/6122 [#6122]: https://github.com/AdguardTeam/AdGuardHome/issues/6122

6
go.mod
View file

@ -5,7 +5,7 @@ go 1.20
require ( require (
github.com/AdguardTeam/dnsproxy v0.54.0 github.com/AdguardTeam/dnsproxy v0.54.0
github.com/AdguardTeam/golibs v0.15.0 github.com/AdguardTeam/golibs v0.15.0
github.com/AdguardTeam/urlfilter v0.16.2 github.com/AdguardTeam/urlfilter v0.17.0
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.2.7 github.com/ameshkov/dnscrypt/v2 v2.2.7
github.com/bluele/gcache v0.0.2 github.com/bluele/gcache v0.0.2
@ -32,7 +32,7 @@ require (
github.com/ti-mo/netfilter v0.5.0 github.com/ti-mo/netfilter v0.5.0
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
golang.org/x/crypto v0.12.0 golang.org/x/crypto v0.12.0
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/net v0.14.0 golang.org/x/net v0.14.0
golang.org/x/sys v0.11.0 golang.org/x/sys v0.11.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1
@ -61,5 +61,5 @@ require (
golang.org/x/mod v0.12.0 // indirect golang.org/x/mod v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect golang.org/x/sync v0.3.0 // indirect
golang.org/x/text v0.12.0 // indirect golang.org/x/text v0.12.0 // indirect
golang.org/x/tools v0.12.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
) )

54
go.sum
View file

@ -1,16 +1,11 @@
github.com/AdguardTeam/dnsproxy v0.54.0 h1:OgSitM/EKrMMOi+guWZNwaU1cqRqJKWgR3l3fPWWayI= github.com/AdguardTeam/dnsproxy v0.54.0 h1:OgSitM/EKrMMOi+guWZNwaU1cqRqJKWgR3l3fPWWayI=
github.com/AdguardTeam/dnsproxy v0.54.0/go.mod h1:tG/treaQekcKnugYoKOfm8vt3JGi6CliWta0MkQr15U= github.com/AdguardTeam/dnsproxy v0.54.0/go.mod h1:tG/treaQekcKnugYoKOfm8vt3JGi6CliWta0MkQr15U=
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.15.0 h1:yOv/fdVkJIOWKr0NlUXAE9RA0DK9GKiBbiGzq47vY7o= github.com/AdguardTeam/golibs v0.15.0 h1:yOv/fdVkJIOWKr0NlUXAE9RA0DK9GKiBbiGzq47vY7o=
github.com/AdguardTeam/golibs v0.15.0/go.mod h1:66ZLs8P7nk/3IfKroQ1rqtieLk+5eXYXMBKXlVL7KeI= github.com/AdguardTeam/golibs v0.15.0/go.mod h1:66ZLs8P7nk/3IfKroQ1rqtieLk+5eXYXMBKXlVL7KeI=
github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU= github.com/AdguardTeam/urlfilter v0.17.0 h1:tUzhtR9wMx704GIP3cibsDQJrixlMHfwoQbYJfPdFow=
github.com/AdguardTeam/urlfilter v0.16.2 h1:k9m9dUYVJ3sTswYa2/ukVNjicfGcz0oqFDO13hPmfHE= github.com/AdguardTeam/urlfilter v0.17.0/go.mod h1:bbuZjPUzm/Ip+nz5qPPbwIP+9rZyQbQad8Lt/0fCulU=
github.com/AdguardTeam/urlfilter v0.16.2/go.mod h1:46YZDOV1+qtdRDuhZKVPSSp7JWWes0KayqHrKAFBdEI=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= 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 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
@ -23,7 +18,6 @@ github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 h1:0b2vaepXIfMsG+
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA= github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -34,8 +28,7 @@ github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu9
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-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.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@ -67,10 +60,8 @@ github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8= github.com/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 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= 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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE= github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=
github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og= 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-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
@ -84,11 +75,9 @@ github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E= github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= 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.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
@ -102,40 +91,38 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4= github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA= github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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.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 h1:MZmsUw5bFRecOb0AeyjOPxTHg4UxYzyEs0Ek/6Lxoy8=
github.com/ti-mo/netfilter v0.5.0/go.mod h1:nt+8B9hx/QpqHr7Hazq+2qMCCA8u2OTkyc/7+U9ARz8= github.com/ti-mo/netfilter v0.5.0/go.mod h1:nt+8B9hx/QpqHr7Hazq+2qMCCA8u2OTkyc/7+U9ARz8=
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
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-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg= 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/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= 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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/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.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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -146,10 +133,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -160,16 +145,11 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-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-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -179,18 +159,15 @@ golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/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.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.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.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-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.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.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -198,12 +175,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -4,7 +4,7 @@ package aghtest
import ( import (
"crypto/sha256" "crypto/sha256"
"io" "io"
"net" "net/netip"
"testing" "testing"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
@ -46,8 +46,8 @@ func ReplaceLogLevel(t testing.TB, l log.Level) {
} }
// HostToIPs is a helper that generates one IPv4 and one IPv6 address from host. // HostToIPs is a helper that generates one IPv4 and one IPv6 address from host.
func HostToIPs(host string) (ipv4, ipv6 net.IP) { func HostToIPs(host string) (ipv4, ipv6 netip.Addr) {
hash := sha256.Sum256([]byte(host)) hash := sha256.Sum256([]byte(host))
return net.IP(hash[:4]), net.IP(hash[4:20]) return netip.AddrFrom4([4]byte(hash[:4])), netip.AddrFrom16([16]byte(hash[4:20]))
} }

View file

@ -131,7 +131,6 @@ func (a *accessManager) isBlockedClientID(id string) (ok bool) {
func (a *accessManager) isBlockedHost(host string, qt rules.RRType) (ok bool) { func (a *accessManager) isBlockedHost(host string, qt rules.RRType) (ok bool) {
_, ok = a.blockedHostsEng.MatchRequest(&urlfilter.DNSRequest{ _, ok = a.blockedHostsEng.MatchRequest(&urlfilter.DNSRequest{
Hostname: host, Hostname: host,
ClientIP: "0.0.0.0",
DNSType: qt, DNSType: qt,
}) })

View file

@ -55,7 +55,7 @@ type FilteringConfig struct {
// Callbacks for other modules // Callbacks for other modules
// FilterHandler is an optional additional filtering callback. // FilterHandler is an optional additional filtering callback.
FilterHandler func(clientAddr net.IP, clientID string, settings *filtering.Settings) `yaml:"-"` FilterHandler func(cliAddr netip.Addr, clientID string, settings *filtering.Settings) `yaml:"-"`
// GetCustomUpstreamByClient is a callback that returns upstreams // GetCustomUpstreamByClient is a callback that returns upstreams
// configuration based on the client IP address or ClientID. It returns // configuration based on the client IP address or ClientID. It returns
@ -71,11 +71,11 @@ type FilteringConfig struct {
BlockingMode BlockingMode `yaml:"blocking_mode"` BlockingMode BlockingMode `yaml:"blocking_mode"`
// BlockingIPv4 is the IP address to be returned for a blocked A request. // BlockingIPv4 is the IP address to be returned for a blocked A request.
BlockingIPv4 net.IP `yaml:"blocking_ipv4"` BlockingIPv4 netip.Addr `yaml:"blocking_ipv4"`
// BlockingIPv6 is the IP address to be returned for a blocked AAAA // BlockingIPv6 is the IP address to be returned for a blocked AAAA
// request. // request.
BlockingIPv6 net.IP `yaml:"blocking_ipv6"` BlockingIPv6 netip.Addr `yaml:"blocking_ipv6"`
// BlockedResponseTTL is the time-to-live value for blocked responses. If // BlockedResponseTTL is the time-to-live value for blocked responses. If
// 0, then default value is used (3600). // 0, then default value is used (3600).

View file

@ -645,7 +645,7 @@ func (s *Server) setupAddrProc() {
} }
// validateBlockingMode returns an error if the blocking mode data aren't valid. // validateBlockingMode returns an error if the blocking mode data aren't valid.
func validateBlockingMode(mode BlockingMode, blockingIPv4, blockingIPv6 net.IP) (err error) { func validateBlockingMode(mode BlockingMode, blockingIPv4, blockingIPv6 netip.Addr) (err error) {
switch mode { switch mode {
case case
BlockingModeDefault, BlockingModeDefault,
@ -654,10 +654,10 @@ func validateBlockingMode(mode BlockingMode, blockingIPv4, blockingIPv6 net.IP)
BlockingModeNullIP: BlockingModeNullIP:
return nil return nil
case BlockingModeCustomIP: case BlockingModeCustomIP:
if blockingIPv4 == nil { if !blockingIPv4.Is4() {
return fmt.Errorf("blocking_ipv4 must be set when blocking_mode is custom_ip") return fmt.Errorf("blocking_ipv4 must be valid ipv4 on custom_ip blocking_mode")
} else if blockingIPv6 == nil { } else if !blockingIPv6.Is6() {
return fmt.Errorf("blocking_ipv6 must be set when blocking_mode is custom_ip") return fmt.Errorf("blocking_ipv6 must be valid ipv6 on custom_ip blocking_mode")
} }
return nil return nil

View file

@ -243,17 +243,17 @@ func newResp(rcode int, req *dns.Msg, ans []dns.RR) (resp *dns.Msg) {
} }
func assertGoogleAResponse(t *testing.T, reply *dns.Msg) { func assertGoogleAResponse(t *testing.T, reply *dns.Msg) {
assertResponse(t, reply, net.IP{8, 8, 8, 8}) assertResponse(t, reply, netip.AddrFrom4([4]byte{8, 8, 8, 8}))
} }
func assertResponse(t *testing.T, reply *dns.Msg, ip net.IP) { func assertResponse(t *testing.T, reply *dns.Msg, ip netip.Addr) {
t.Helper() t.Helper()
require.Lenf(t, reply.Answer, 1, "dns server returned reply with wrong number of answers - %d", len(reply.Answer)) require.Lenf(t, reply.Answer, 1, "dns server returned reply with wrong number of answers - %d", len(reply.Answer))
a, ok := reply.Answer[0].(*dns.A) a, ok := reply.Answer[0].(*dns.A)
require.Truef(t, ok, "dns server returned wrong answer type instead of A: %v", reply.Answer[0]) require.Truef(t, ok, "dns server returned wrong answer type instead of A: %v", reply.Answer[0])
assert.Truef(t, a.A.Equal(ip), "dns server returned wrong answer instead of %s: %s", ip, a.A) assert.Equal(t, net.IP(ip.AsSlice()), a.A)
} }
// sendTestMessagesAsync sends messages in parallel to check for race issues. // sendTestMessagesAsync sends messages in parallel to check for race issues.
@ -473,7 +473,7 @@ func TestSafeSearch(t *testing.T) {
OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) { OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) {
ip4, ip6 := aghtest.HostToIPs(host) ip4, ip6 := aghtest.HostToIPs(host)
return []net.IP{ip4, ip6}, nil return []net.IP{ip4.AsSlice(), ip6.AsSlice()}, nil
}, },
} }
@ -514,12 +514,12 @@ func TestSafeSearch(t *testing.T) {
addr := s.dnsProxy.Addr(proxy.ProtoUDP).String() addr := s.dnsProxy.Addr(proxy.ProtoUDP).String()
client := &dns.Client{} client := &dns.Client{}
yandexIP := net.IP{213, 180, 193, 56} yandexIP := netip.AddrFrom4([4]byte{213, 180, 193, 56})
googleIP, _ := aghtest.HostToIPs("forcesafesearch.google.com") googleIP, _ := aghtest.HostToIPs("forcesafesearch.google.com")
testCases := []struct { testCases := []struct {
host string host string
want net.IP want netip.Addr
}{{ }{{
host: "yandex.com.", host: "yandex.com.",
want: yandexIP, want: yandexIP,
@ -776,7 +776,7 @@ func TestClientRulesForCNAMEMatching(t *testing.T) {
TCPListenAddrs: []*net.TCPAddr{{}}, TCPListenAddrs: []*net.TCPAddr{{}},
FilteringConfig: FilteringConfig{ FilteringConfig: FilteringConfig{
ProtectionEnabled: true, ProtectionEnabled: true,
FilterHandler: func(_ net.IP, _ string, settings *filtering.Settings) { FilterHandler: func(_ netip.Addr, _ string, settings *filtering.Settings) {
settings.FilteringEnabled = false settings.FilteringEnabled = false
}, },
EDNSClientSubnet: &EDNSClientSubnet{ EDNSClientSubnet: &EDNSClientSubnet{
@ -876,7 +876,8 @@ func TestBlockedCustomIP(t *testing.T) {
FilteringConfig: FilteringConfig{ FilteringConfig: FilteringConfig{
ProtectionEnabled: true, ProtectionEnabled: true,
BlockingMode: BlockingModeCustomIP, BlockingMode: BlockingModeCustomIP,
BlockingIPv4: nil, BlockingIPv4: netip.Addr{},
BlockingIPv6: netip.Addr{},
UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"}, UpstreamDNS: []string{"8.8.8.8:53", "8.8.4.4:53"},
EDNSClientSubnet: &EDNSClientSubnet{ EDNSClientSubnet: &EDNSClientSubnet{
Enabled: false, Enabled: false,
@ -888,8 +889,8 @@ func TestBlockedCustomIP(t *testing.T) {
err = s.Prepare(conf) err = s.Prepare(conf)
assert.Error(t, err) assert.Error(t, err)
conf.BlockingIPv4 = net.IP{0, 0, 0, 1} conf.BlockingIPv4 = netip.AddrFrom4([4]byte{0, 0, 0, 1})
conf.BlockingIPv6 = net.ParseIP("::1") conf.BlockingIPv6 = netip.MustParseAddr("::1")
err = s.Prepare(conf) err = s.Prepare(conf)
require.NoError(t, err) require.NoError(t, err)
@ -991,9 +992,7 @@ func TestBlockedBySafeBrowsing(t *testing.T) {
require.NoErrorf(t, err, "couldn't talk to server %s: %s", addr, err) require.NoErrorf(t, err, "couldn't talk to server %s: %s", addr, err)
require.Lenf(t, reply.Answer, 1, "dns server %s returned reply with wrong number of answers - %d", addr, len(reply.Answer)) require.Lenf(t, reply.Answer, 1, "dns server %s returned reply with wrong number of answers - %d", addr, len(reply.Answer))
a, ok := reply.Answer[0].(*dns.A) assertResponse(t, reply, ans4)
require.Truef(t, ok, "dns server %s returned wrong answer type instead of A: %v", addr, reply.Answer[0])
assert.Equal(t, ans4, a.A, "dns server %s returned wrong answer: %v", addr, a.A)
} }
func TestRewrite(t *testing.T) { func TestRewrite(t *testing.T) {

View file

@ -2,7 +2,7 @@ package dnsforward
import ( import (
"fmt" "fmt"
"net" "net/netip"
"github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
@ -44,13 +44,13 @@ func (s *Server) ansFromDNSRewriteIP(
rr rules.RRType, rr rules.RRType,
req *dns.Msg, req *dns.Msg,
) (ans dns.RR, err error) { ) (ans dns.RR, err error) {
ip, ok := v.(net.IP) ip, ok := v.(netip.Addr)
if !ok { if !ok {
return nil, fmt.Errorf("value for rr type %s has type %T, not net.IP", dns.Type(rr), v) return nil, fmt.Errorf("value for rr type %s has type %T, not netip.Addr", dns.Type(rr), v)
} }
if rr == dns.TypeA { if rr == dns.TypeA {
return s.genAnswerA(req, ip.To4()), nil return s.genAnswerA(req, ip), nil
} }
return s.genAnswerAAAA(req, ip), nil return s.genAnswerAAAA(req, ip), nil
@ -160,13 +160,13 @@ func (s *Server) filterDNSRewrite(
return errors.Error("no dns rewrite rule responses") return errors.Error("no dns rewrite rule responses")
} }
rr := req.Question[0].Qtype qtype := req.Question[0].Qtype
values := dnsrr.Response[rr] values := dnsrr.Response[qtype]
for i, v := range values { for i, v := range values {
var ans dns.RR var ans dns.RR
ans, err = s.filterDNSRewriteResponse(req, rr, v) ans, err = s.filterDNSRewriteResponse(req, qtype, v)
if err != nil { if err != nil {
return fmt.Errorf("dns rewrite response for %d[%d]: %w", rr, i, err) return fmt.Errorf("dns rewrite response for %s[%d]: %w", dns.Type(qtype), i, err)
} }
resp.Answer = append(resp.Answer, ans) resp.Answer = append(resp.Answer, ans)

View file

@ -6,6 +6,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/dnsproxy/proxy" "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -15,8 +16,7 @@ import (
func TestServer_FilterDNSRewrite(t *testing.T) { func TestServer_FilterDNSRewrite(t *testing.T) {
// Helper data. // Helper data.
const domain = "example.com" const domain = "example.com"
ip4 := net.IP{127, 0, 0, 1} ip4, ip6 := netutil.IPv4Localhost(), netutil.IPv6Localhost()
ip6 := net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
mxVal := &rules.DNSMX{ mxVal := &rules.DNSMX{
Exchange: "mail.example.com", Exchange: "mail.example.com",
Preference: 32, Preference: 32,
@ -89,7 +89,7 @@ func TestServer_FilterDNSRewrite(t *testing.T) {
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1) require.Len(t, d.Res.Answer, 1)
assert.Equal(t, ip4, d.Res.Answer[0].(*dns.A).A) assert.Equal(t, net.IP(ip4.AsSlice()), d.Res.Answer[0].(*dns.A).A)
}) })
t.Run("noerror_aaaa", func(t *testing.T) { t.Run("noerror_aaaa", func(t *testing.T) {
@ -103,7 +103,7 @@ func TestServer_FilterDNSRewrite(t *testing.T) {
assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode) assert.Equal(t, dns.RcodeSuccess, d.Res.Rcode)
require.Len(t, d.Res.Answer, 1) require.Len(t, d.Res.Answer, 1)
assert.Equal(t, ip6, d.Res.Answer[0].(*dns.AAAA).AAAA) assert.Equal(t, net.IP(ip6.AsSlice()), d.Res.Answer[0].(*dns.AAAA).AAAA)
}) })
t.Run("noerror_ptr", func(t *testing.T) { t.Run("noerror_ptr", func(t *testing.T) {

View file

@ -59,8 +59,8 @@ func (s *Server) clientRequestFilteringSettings(dctx *dnsContext) (setts *filter
setts = s.dnsFilter.Settings() setts = s.dnsFilter.Settings()
setts.ProtectionEnabled = dctx.protectionEnabled setts.ProtectionEnabled = dctx.protectionEnabled
if s.conf.FilterHandler != nil { if s.conf.FilterHandler != nil {
ip, _ := netutil.IPAndPortFromAddr(dctx.proxyCtx.Addr) addrPort := netutil.NetAddrToAddrPort(dctx.proxyCtx.Addr)
s.conf.FilterHandler(ip, dctx.clientID, setts) s.conf.FilterHandler(addrPort.Addr(), dctx.clientID, setts)
} }
return setts return setts
@ -125,7 +125,7 @@ func (s *Server) filterRewritten(
for _, ip := range res.IPList { for _, ip := range res.IPList {
switch qt { switch qt {
case dns.TypeA: case dns.TypeA:
a := s.genAnswerA(req, ip.To4()) a := s.genAnswerA(req, ip)
a.Hdr.Name = dns.Fqdn(name) a.Hdr.Name = dns.Fqdn(name)
resp.Answer = append(resp.Answer, a) resp.Answer = append(resp.Answer, a)
case dns.TypeAAAA: case dns.TypeAAAA:

View file

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/netip" "net/netip"
"strings" "strings"
@ -83,10 +82,10 @@ type jsonDNSConfig struct {
LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"` LocalPTRUpstreams *[]string `json:"local_ptr_upstreams"`
// BlockingIPv4 is custom IPv4 address for blocked A requests. // BlockingIPv4 is custom IPv4 address for blocked A requests.
BlockingIPv4 net.IP `json:"blocking_ipv4"` BlockingIPv4 netip.Addr `json:"blocking_ipv4"`
// BlockingIPv6 is custom IPv6 address for blocked AAAA requests. // BlockingIPv6 is custom IPv6 address for blocked AAAA requests.
BlockingIPv6 net.IP `json:"blocking_ipv6"` BlockingIPv6 netip.Addr `json:"blocking_ipv6"`
// DisabledUntil is a timestamp until when the protection is disabled. // DisabledUntil is a timestamp until when the protection is disabled.
DisabledUntil *time.Time `json:"protection_disabled_until"` DisabledUntil *time.Time `json:"protection_disabled_until"`
@ -297,8 +296,8 @@ func (s *Server) setConfig(dc *jsonDNSConfig) (shouldRestart bool) {
if dc.BlockingMode != nil { if dc.BlockingMode != nil {
s.conf.BlockingMode = *dc.BlockingMode s.conf.BlockingMode = *dc.BlockingMode
if *dc.BlockingMode == BlockingModeCustomIP { if *dc.BlockingMode == BlockingModeCustomIP {
s.conf.BlockingIPv4 = dc.BlockingIPv4.To4() s.conf.BlockingIPv4 = dc.BlockingIPv4
s.conf.BlockingIPv6 = dc.BlockingIPv6.To16() s.conf.BlockingIPv6 = dc.BlockingIPv6
} }
} }

View file

@ -177,7 +177,7 @@ func TestDNSForwardHTTP_handleSetConfig(t *testing.T) {
wantSet: "", wantSet: "",
}, { }, {
name: "blocking_mode_bad", name: "blocking_mode_bad",
wantSet: "blocking_ipv4 must be set when blocking_mode is custom_ip", wantSet: "blocking_ipv4 must be valid ipv4 on custom_ip blocking_mode",
}, { }, {
name: "ratelimit", name: "ratelimit",
wantSet: "", wantSet: "",

View file

@ -1,7 +1,7 @@
package dnsforward package dnsforward
import ( import (
"net" "net/netip"
"time" "time"
"github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering"
@ -9,6 +9,7 @@ import (
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
"golang.org/x/exp/slices"
) )
// makeResponse creates a DNS response by req and sets necessary flags. It also // makeResponse creates a DNS response by req and sets necessary flags. It also
@ -26,24 +27,13 @@ func (s *Server) makeResponse(req *dns.Msg) (resp *dns.Msg) {
return resp return resp
} }
// containsIP returns true if the IP is already in the list.
func containsIP(ips []net.IP, ip net.IP) bool {
for _, a := range ips {
if a.Equal(ip) {
return true
}
}
return false
}
// ipsFromRules extracts unique non-IP addresses from the filtering result // ipsFromRules extracts unique non-IP addresses from the filtering result
// rules. // rules.
func ipsFromRules(resRules []*filtering.ResultRule) (ips []net.IP) { func ipsFromRules(resRules []*filtering.ResultRule) (ips []netip.Addr) {
for _, r := range resRules { for _, r := range resRules {
// len(resRules) and len(ips) are actually small enough for O(n^2) to do // len(resRules) and len(ips) are actually small enough for O(n^2) to do
// not raise performance questions. // not raise performance questions.
if ip := r.IP; ip != nil && !containsIP(ips, ip) { if ip := r.IP; ip != (netip.Addr{}) && !slices.Contains(ips, ip) {
ips = append(ips, ip) ips = append(ips, ip)
} }
} }
@ -84,7 +74,7 @@ func (s *Server) genDNSFilterMessage(
// genForBlockingMode generates a filtered response to req based on the server's // genForBlockingMode generates a filtered response to req based on the server's
// blocking mode. // blocking mode.
func (s *Server) genForBlockingMode(req *dns.Msg, ips []net.IP) (resp *dns.Msg) { func (s *Server) genForBlockingMode(req *dns.Msg, ips []netip.Addr) (resp *dns.Msg) {
qt := req.Question[0].Qtype qt := req.Question[0].Qtype
switch m := s.conf.BlockingMode; m { switch m := s.conf.BlockingMode; m {
case BlockingModeCustomIP: case BlockingModeCustomIP:
@ -126,13 +116,13 @@ func (s *Server) genServerFailure(request *dns.Msg) *dns.Msg {
return &resp return &resp
} }
func (s *Server) genARecord(request *dns.Msg, ip net.IP) *dns.Msg { func (s *Server) genARecord(request *dns.Msg, ip netip.Addr) *dns.Msg {
resp := s.makeResponse(request) resp := s.makeResponse(request)
resp.Answer = append(resp.Answer, s.genAnswerA(request, ip)) resp.Answer = append(resp.Answer, s.genAnswerA(request, ip))
return resp return resp
} }
func (s *Server) genAAAARecord(request *dns.Msg, ip net.IP) *dns.Msg { func (s *Server) genAAAARecord(request *dns.Msg, ip netip.Addr) *dns.Msg {
resp := s.makeResponse(request) resp := s.makeResponse(request)
resp.Answer = append(resp.Answer, s.genAnswerAAAA(request, ip)) resp.Answer = append(resp.Answer, s.genAnswerAAAA(request, ip))
return resp return resp
@ -147,17 +137,17 @@ func (s *Server) hdr(req *dns.Msg, rrType rules.RRType) (h dns.RR_Header) {
} }
} }
func (s *Server) genAnswerA(req *dns.Msg, ip net.IP) (ans *dns.A) { func (s *Server) genAnswerA(req *dns.Msg, ip netip.Addr) (ans *dns.A) {
return &dns.A{ return &dns.A{
Hdr: s.hdr(req, dns.TypeA), Hdr: s.hdr(req, dns.TypeA),
A: ip, A: ip.AsSlice(),
} }
} }
func (s *Server) genAnswerAAAA(req *dns.Msg, ip net.IP) (ans *dns.AAAA) { func (s *Server) genAnswerAAAA(req *dns.Msg, ip netip.Addr) (ans *dns.AAAA) {
return &dns.AAAA{ return &dns.AAAA{
Hdr: s.hdr(req, dns.TypeAAAA), Hdr: s.hdr(req, dns.TypeAAAA),
AAAA: ip, AAAA: ip.AsSlice(),
} }
} }
@ -204,22 +194,24 @@ func (s *Server) genAnswerTXT(req *dns.Msg, strs []string) (ans *dns.TXT) {
// addresses and an appropriate resource record type. If any of the IPs cannot // addresses and an appropriate resource record type. If any of the IPs cannot
// be converted to the correct protocol, genResponseWithIPs returns an empty // be converted to the correct protocol, genResponseWithIPs returns an empty
// response. // response.
func (s *Server) genResponseWithIPs(req *dns.Msg, ips []net.IP) (resp *dns.Msg) { func (s *Server) genResponseWithIPs(req *dns.Msg, ips []netip.Addr) (resp *dns.Msg) {
var ans []dns.RR var ans []dns.RR
switch req.Question[0].Qtype { switch req.Question[0].Qtype {
case dns.TypeA: case dns.TypeA:
for _, ip := range ips { for _, ip := range ips {
if ip4 := ip.To4(); ip4 == nil { if ip.Is4() {
ans = append(ans, s.genAnswerA(req, ip))
} else {
ans = nil ans = nil
break break
} }
ans = append(ans, s.genAnswerA(req, ip))
} }
case dns.TypeAAAA: case dns.TypeAAAA:
for _, ip := range ips { for _, ip := range ips {
ans = append(ans, s.genAnswerAAAA(req, ip.To16())) if ip.Is6() {
ans = append(ans, s.genAnswerAAAA(req, ip))
}
} }
default: default:
// Go on and return an empty response. // Go on and return an empty response.
@ -240,9 +232,9 @@ func (s *Server) makeResponseNullIP(req *dns.Msg) (resp *dns.Msg) {
// converted into an empty slice instead of the zero IPv4. // converted into an empty slice instead of the zero IPv4.
switch req.Question[0].Qtype { switch req.Question[0].Qtype {
case dns.TypeA: case dns.TypeA:
resp = s.genResponseWithIPs(req, []net.IP{{0, 0, 0, 0}}) resp = s.genResponseWithIPs(req, []netip.Addr{netip.IPv4Unspecified()})
case dns.TypeAAAA: case dns.TypeAAAA:
resp = s.genResponseWithIPs(req, []net.IP{net.IPv6zero}) resp = s.genResponseWithIPs(req, []netip.Addr{netip.IPv6Unspecified()})
default: default:
resp = s.makeResponse(req) resp = s.makeResponse(req)
} }
@ -251,9 +243,9 @@ func (s *Server) makeResponseNullIP(req *dns.Msg) (resp *dns.Msg) {
} }
func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg { func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg {
ip := net.ParseIP(newAddr) ip, err := netip.ParseAddr(newAddr)
if ip != nil { if err == nil {
return s.genResponseWithIPs(request, []net.IP{ip}) return s.genResponseWithIPs(request, []netip.Addr{ip})
} }
// look up the hostname, TODO: cache // look up the hostname, TODO: cache
@ -275,7 +267,7 @@ func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSCo
return s.genServerFailure(request) return s.genServerFailure(request)
} }
err := prx.Resolve(newContext) err = prx.Resolve(newContext)
if err != nil { if err != nil {
log.Printf("couldn't look up replacement host %q: %s", newAddr, err) log.Printf("couldn't look up replacement host %q: %s", newAddr, err)

View file

@ -10,6 +10,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest" "github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil" "github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
@ -22,13 +23,13 @@ func TestDNSFilter_CheckHostRules_dnsrewrite(t *testing.T) {
|cname^$dnsrewrite=new-cname |cname^$dnsrewrite=new-cname
|a-record^$dnsrewrite=127.0.0.1 |a-record^$dnsrewrite=127.0.0.1
|aaaa-record^$dnsrewrite=::1 |aaaa-record^$dnsrewrite=::1
|txt-record^$dnsrewrite=NOERROR;TXT;hello-world |txt-record^$dnsrewrite=NOERROR;TXT;hello-world
|refused^$dnsrewrite=REFUSED |refused^$dnsrewrite=REFUSED
|mapped^$dnsrewrite=NOERROR;AAAA;::ffff:127.0.0.1
|a-records^$dnsrewrite=127.0.0.1 |a-records^$dnsrewrite=127.0.0.1
|a-records^$dnsrewrite=127.0.0.2 |a-records^$dnsrewrite=127.0.0.2
@ -61,10 +62,11 @@ func TestDNSFilter_CheckHostRules_dnsrewrite(t *testing.T) {
FilteringEnabled: true, FilteringEnabled: true,
} }
ipv4p1 := net.IPv4(127, 0, 0, 1) ipv4p1 := netutil.IPv4Localhost()
ipv4p2 := net.IPv4(127, 0, 0, 2) ipv4p2 := ipv4p1.Next()
ipv6p1 := net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} ipv6p1 := netutil.IPv6Localhost()
ipv6p2 := net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} ipv6p2 := ipv6p1.Next()
mapped := netip.AddrFrom16(ipv4p1.As16())
testCasesA := []struct { testCasesA := []struct {
name string name string
@ -111,6 +113,11 @@ func TestDNSFilter_CheckHostRules_dnsrewrite(t *testing.T) {
want: []any{ipv4p1}, want: []any{ipv4p1},
rcode: dns.RcodeSuccess, rcode: dns.RcodeSuccess,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, {
name: "mapped",
want: []any{mapped},
rcode: dns.RcodeSuccess,
dtyp: dns.TypeAAAA,
}} }}
for _, tc := range testCasesA { for _, tc := range testCasesA {

View file

@ -54,7 +54,7 @@ type ServiceEntry struct {
// Settings are custom filtering settings for a client. // Settings are custom filtering settings for a client.
type Settings struct { type Settings struct {
ClientName string ClientName string
ClientIP net.IP ClientIP netip.Addr
ClientTags []string ClientTags []string
ServicesRules []ServiceEntry ServicesRules []ServiceEntry
@ -404,7 +404,7 @@ type ResultRule struct {
Text string `json:",omitempty"` Text string `json:",omitempty"`
// IP is the host IP. It is nil unless the rule uses the // IP is the host IP. It is nil unless the rule uses the
// /etc/hosts syntax or the reason is FilteredSafeSearch. // /etc/hosts syntax or the reason is FilteredSafeSearch.
IP net.IP `json:",omitempty"` IP netip.Addr `json:",omitempty"`
// FilterListID is the ID of the rule's filter list. // FilterListID is the ID of the rule's filter list.
FilterListID int64 `json:",omitempty"` FilterListID int64 `json:",omitempty"`
} }
@ -430,7 +430,7 @@ type Result struct {
// IPList is the lookup rewrite result. It is empty unless Reason is set to // IPList is the lookup rewrite result. It is empty unless Reason is set to
// Rewritten. // Rewritten.
IPList []net.IP `json:",omitempty"` IPList []netip.Addr `json:",omitempty"`
// Rules are applied rules. If Rules are not empty, each rule is not nil. // Rules are applied rules. If Rules are not empty, each rule is not nil.
Rules []*ResultRule `json:",omitempty"` Rules []*ResultRule `json:",omitempty"`
@ -787,23 +787,28 @@ func (d *DNSFilter) matchHostProcessDNSResult(
return makeResult([]rules.Rule{dnsres.NetworkRule}, reason) return makeResult([]rules.Rule{dnsres.NetworkRule}, reason)
} }
if qtype == dns.TypeA && dnsres.HostRulesV4 != nil { switch qtype {
case dns.TypeA:
if dnsres.HostRulesV4 != nil {
res = makeResult(hostRulesToRules(dnsres.HostRulesV4), FilteredBlockList) res = makeResult(hostRulesToRules(dnsres.HostRulesV4), FilteredBlockList)
for i, hr := range dnsres.HostRulesV4 { for i, hr := range dnsres.HostRulesV4 {
res.Rules[i].IP = hr.IP.To4() res.Rules[i].IP = hr.IP
} }
return res return res
} }
case dns.TypeAAAA:
if qtype == dns.TypeAAAA && dnsres.HostRulesV6 != nil { if dnsres.HostRulesV6 != nil {
res = makeResult(hostRulesToRules(dnsres.HostRulesV6), FilteredBlockList) res = makeResult(hostRulesToRules(dnsres.HostRulesV6), FilteredBlockList)
for i, hr := range dnsres.HostRulesV6 { for i, hr := range dnsres.HostRulesV6 {
res.Rules[i].IP = hr.IP.To16() res.Rules[i].IP = hr.IP
} }
return res return res
} }
default:
// Go on.
}
return hostResultForOtherQType(dnsres) return hostResultForOtherQType(dnsres)
} }
@ -837,7 +842,7 @@ func (d *DNSFilter) matchHost(
Hostname: host, Hostname: host,
SortedClientTags: setts.ClientTags, SortedClientTags: setts.ClientTags,
// TODO(e.burkov): Wait for urlfilter update to pass net.IP. // TODO(e.burkov): Wait for urlfilter update to pass net.IP.
ClientIP: setts.ClientIP.String(), ClientIP: setts.ClientIP,
ClientName: setts.ClientName, ClientName: setts.ClientName,
DNSType: rrtype, DNSType: rrtype,
} }

View file

@ -3,12 +3,13 @@ package filtering
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"net" "net/netip"
"testing" "testing"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest" "github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/AdGuardHome/internal/filtering/hashprefix" "github.com/AdguardTeam/AdGuardHome/internal/filtering/hashprefix"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil" "github.com/AdguardTeam/golibs/testutil"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
@ -149,8 +150,8 @@ func TestDNSFilter_CheckHost_hostRules(t *testing.T) {
require.Len(t, res.Rules, 2) require.Len(t, res.Rules, 2)
assert.Equal(t, res.Rules[0].IP, net.IP{0, 0, 0, 1}) assert.Equal(t, res.Rules[0].IP, netip.AddrFrom4([4]byte{0, 0, 0, 1}))
assert.Equal(t, res.Rules[1].IP, net.IP{0, 0, 0, 2}) assert.Equal(t, res.Rules[1].IP, netip.AddrFrom4([4]byte{0, 0, 0, 2}))
// One IPv6 address. // One IPv6 address.
res, err = d.CheckHost("host2", dns.TypeAAAA, setts) res, err = d.CheckHost("host2", dns.TypeAAAA, setts)
@ -160,7 +161,7 @@ func TestDNSFilter_CheckHost_hostRules(t *testing.T) {
require.Len(t, res.Rules, 1) require.Len(t, res.Rules, 1)
assert.Equal(t, res.Rules[0].IP, net.IPv6loopback) assert.Equal(t, res.Rules[0].IP, netutil.IPv6Localhost())
} }
// Safe Browsing. // Safe Browsing.

View file

@ -3,8 +3,8 @@ package filtering
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net"
"net/http" "net/http"
"net/netip"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -405,7 +405,7 @@ type checkHostResp struct {
// for Rewrite: // for Rewrite:
CanonName string `json:"cname"` // CNAME value CanonName string `json:"cname"` // CNAME value
IPList []net.IP `json:"ip_addrs"` // list of IP addresses IPList []netip.Addr `json:"ip_addrs"` // list of IP addresses
// FilterID is the ID of the rule's filter list. // FilterID is the ID of the rule's filter list.
// //

View file

@ -1,9 +1,10 @@
package rewrite package rewrite
import ( import (
"net" "net/netip"
"testing" "testing"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/urlfilter" "github.com/AdguardTeam/urlfilter"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
@ -45,33 +46,43 @@ func TestDefaultStorage_CRUD(t *testing.T) {
} }
func TestDefaultStorage_MatchRequest(t *testing.T) { func TestDefaultStorage_MatchRequest(t *testing.T) {
var (
addr1v4 = netip.AddrFrom4([4]byte{1, 2, 3, 4})
addr2v4 = netip.AddrFrom4([4]byte{1, 2, 3, 5})
addr3v4 = netip.AddrFrom4([4]byte{1, 2, 3, 6})
addr4v4 = netip.AddrFrom4([4]byte{1, 2, 3, 7})
addr1v6 = netip.MustParseAddr("1:2:3::4")
addr2v6 = netip.MustParseAddr("1234::5678")
)
items := []*Item{{ items := []*Item{{
// This one and below are about CNAME, A and AAAA. // This one and below are about CNAME, A and AAAA.
Domain: "somecname", Domain: "somecname",
Answer: "somehost.com", Answer: "somehost.com",
}, { }, {
Domain: "somehost.com", Domain: "somehost.com",
Answer: "0.0.0.0", Answer: netip.IPv4Unspecified().String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1.2.3.4", Answer: addr1v4.String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1.2.3.5", Answer: addr2v4.String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1:2:3::4", Answer: addr1v6.String(),
}, { }, {
Domain: "www.host.com", Domain: "www.host.com",
Answer: "host.com", Answer: "host.com",
}, { }, {
// This one is a wildcard. // This one is a wildcard.
Domain: "*.host.com", Domain: "*.host.com",
Answer: "1.2.3.5", Answer: addr2v4.String(),
}, { }, {
// This one and below are about wildcard overriding. // This one and below are about wildcard overriding.
Domain: "a.host.com", Domain: "a.host.com",
Answer: "1.2.3.4", Answer: addr1v4.String(),
}, { }, {
// This one is about CNAME and wildcard interacting. // This one is about CNAME and wildcard interacting.
Domain: "*.host2.com", Domain: "*.host2.com",
@ -89,13 +100,13 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
Answer: "x.host.com", Answer: "x.host.com",
}, { }, {
Domain: "*.hostboth.com", Domain: "*.hostboth.com",
Answer: "1.2.3.6", Answer: addr3v4.String(),
}, { }, {
Domain: "*.hostboth.com", Domain: "*.hostboth.com",
Answer: "1234::5678", Answer: addr2v6.String(),
}, { }, {
Domain: "BIGHOST.COM", Domain: "BIGHOST.COM",
Answer: "1.2.3.7", Answer: addr4v4.String(),
}, { }, {
Domain: "*.issue4016.com", Domain: "*.issue4016.com",
Answer: "sub.issue4016.com", Answer: "sub.issue4016.com",
@ -123,12 +134,12 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "rewritten_a", name: "rewritten_a",
host: "www.host.com", host: "www.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 4}.To16(), Value: addr1v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
}, { }, {
Value: net.IP{1, 2, 3, 5}.To16(), Value: addr2v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -138,7 +149,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "rewritten_aaaa", name: "rewritten_aaaa",
host: "www.host.com", host: "www.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.ParseIP("1:2:3::4"), Value: addr1v6,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA, RRType: dns.TypeAAAA,
@ -148,7 +159,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "wildcard_match", name: "wildcard_match",
host: "abc.host.com", host: "abc.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 5}.To16(), Value: addr2v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -169,12 +180,12 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "wildcard_cname_interaction", name: "wildcard_cname_interaction",
host: "www.host2.com", host: "www.host2.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 4}.To16(), Value: addr1v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
}, { }, {
Value: net.IP{1, 2, 3, 5}.To16(), Value: addr2v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -184,7 +195,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "two_cnames", name: "two_cnames",
host: "b.host.com", host: "b.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{0, 0, 0, 0}.To16(), Value: netip.IPv4Unspecified(),
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -194,7 +205,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "two_cnames_and_wildcard", name: "two_cnames_and_wildcard",
host: "b.host3.com", host: "b.host3.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 5}.To16(), Value: addr2v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -204,7 +215,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "issue3343", name: "issue3343",
host: "www.hostboth.com", host: "www.hostboth.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.ParseIP("1234::5678"), Value: addr2v6,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA, RRType: dns.TypeAAAA,
@ -214,7 +225,7 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
name: "issue3351", name: "issue3351",
host: "bighost.com", host: "bighost.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 7}.To16(), Value: addr4v4,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -255,16 +266,22 @@ func TestDefaultStorage_MatchRequest(t *testing.T) {
} }
func TestDefaultStorage_MatchRequest_Levels(t *testing.T) { func TestDefaultStorage_MatchRequest_Levels(t *testing.T) {
var (
addr1 = netip.AddrFrom4([4]byte{1, 1, 1, 1})
addr2 = netip.AddrFrom4([4]byte{2, 2, 2, 2})
addr3 = netip.AddrFrom4([4]byte{3, 3, 3, 3})
)
// Exact host, wildcard L2, wildcard L3. // Exact host, wildcard L2, wildcard L3.
items := []*Item{{ items := []*Item{{
Domain: "host.com", Domain: "host.com",
Answer: "1.1.1.1", Answer: addr1.String(),
}, { }, {
Domain: "*.host.com", Domain: "*.host.com",
Answer: "2.2.2.2", Answer: addr2.String(),
}, { }, {
Domain: "*.sub.host.com", Domain: "*.sub.host.com",
Answer: "3.3.3.3", Answer: addr3.String(),
}} }}
s, err := NewDefaultStorage(-1, items) s, err := NewDefaultStorage(-1, items)
@ -279,7 +296,7 @@ func TestDefaultStorage_MatchRequest_Levels(t *testing.T) {
name: "exact_match", name: "exact_match",
host: "host.com", host: "host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 1, 1, 1}.To16(), Value: addr1,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -289,7 +306,7 @@ func TestDefaultStorage_MatchRequest_Levels(t *testing.T) {
name: "l2_match", name: "l2_match",
host: "sub.host.com", host: "sub.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{2, 2, 2, 2}.To16(), Value: addr2,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -300,7 +317,7 @@ func TestDefaultStorage_MatchRequest_Levels(t *testing.T) {
// name: "l3_match", // name: "l3_match",
// host: "my.sub.host.com", // host: "my.sub.host.com",
// wantDNSRewrites: []*rules.DNSRewrite{{ // wantDNSRewrites: []*rules.DNSRewrite{{
// Value: net.IP{3, 3, 3, 3}.To16(), // Value: addr3,
// NewCNAME: "", // NewCNAME: "",
// RCode: dns.RcodeSuccess, // RCode: dns.RcodeSuccess,
// RRType: dns.TypeA, // RRType: dns.TypeA,
@ -321,10 +338,12 @@ func TestDefaultStorage_MatchRequest_Levels(t *testing.T) {
} }
func TestDefaultStorage_MatchRequest_ExceptionCNAME(t *testing.T) { func TestDefaultStorage_MatchRequest_ExceptionCNAME(t *testing.T) {
addr := netip.AddrFrom4([4]byte{2, 2, 2, 2})
// Wildcard and exception for a sub-domain. // Wildcard and exception for a sub-domain.
items := []*Item{{ items := []*Item{{
Domain: "*.host.com", Domain: "*.host.com",
Answer: "2.2.2.2", Answer: addr.String(),
}, { }, {
Domain: "sub.host.com", Domain: "sub.host.com",
Answer: "sub.host.com", Answer: "sub.host.com",
@ -345,7 +364,7 @@ func TestDefaultStorage_MatchRequest_ExceptionCNAME(t *testing.T) {
name: "match_subdomain", name: "match_subdomain",
host: "my.host.com", host: "my.host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{2, 2, 2, 2}.To16(), Value: addr,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -377,16 +396,18 @@ func TestDefaultStorage_MatchRequest_ExceptionCNAME(t *testing.T) {
} }
func TestDefaultStorage_MatchRequest_ExceptionIP(t *testing.T) { func TestDefaultStorage_MatchRequest_ExceptionIP(t *testing.T) {
addr := netip.AddrFrom4([4]byte{1, 2, 3, 4})
// Exception for AAAA record. // Exception for AAAA record.
items := []*Item{{ items := []*Item{{
Domain: "host.com", Domain: "host.com",
Answer: "1.2.3.4", Answer: addr.String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "AAAA", Answer: "AAAA",
}, { }, {
Domain: "host2.com", Domain: "host2.com",
Answer: "::1", Answer: netutil.IPv6Localhost().String(),
}, { }, {
Domain: "host2.com", Domain: "host2.com",
Answer: "A", Answer: "A",
@ -407,7 +428,7 @@ func TestDefaultStorage_MatchRequest_ExceptionIP(t *testing.T) {
name: "match_A", name: "match_A",
host: "host.com", host: "host.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.IP{1, 2, 3, 4}.To16(), Value: addr,
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeA, RRType: dns.TypeA,
@ -427,7 +448,7 @@ func TestDefaultStorage_MatchRequest_ExceptionIP(t *testing.T) {
name: "match_AAAA_host2.com", name: "match_AAAA_host2.com",
host: "host2.com", host: "host2.com",
wantDNSRewrites: []*rules.DNSRewrite{{ wantDNSRewrites: []*rules.DNSRewrite{{
Value: net.ParseIP("::1"), Value: netutil.IPv6Localhost(),
NewCNAME: "", NewCNAME: "",
RCode: dns.RcodeSuccess, RCode: dns.RcodeSuccess,
RRType: dns.TypeAAAA, RRType: dns.TypeAAAA,

View file

@ -2,7 +2,7 @@ package filtering
import ( import (
"fmt" "fmt"
"net" "net/netip"
"strings" "strings"
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
@ -27,22 +27,12 @@ type LegacyRewrite struct {
// IP is the IP address that should be used in the response if Type is // IP is the IP address that should be used in the response if Type is
// dns.TypeA or dns.TypeAAAA. // dns.TypeA or dns.TypeAAAA.
IP net.IP `yaml:"-"` IP netip.Addr `yaml:"-"`
// Type is the DNS record type: A, AAAA, or CNAME. // Type is the DNS record type: A, AAAA, or CNAME.
Type uint16 `yaml:"-"` Type uint16 `yaml:"-"`
} }
// clone returns a deep clone of rw.
func (rw *LegacyRewrite) clone() (cloneRW *LegacyRewrite) {
return &LegacyRewrite{
Domain: rw.Domain,
Answer: rw.Answer,
IP: slices.Clone(rw.IP),
Type: rw.Type,
}
}
// equal returns true if the rw is equal to the other. // equal returns true if the rw is equal to the other.
func (rw *LegacyRewrite) equal(other *LegacyRewrite) (ok bool) { func (rw *LegacyRewrite) equal(other *LegacyRewrite) (ok bool) {
return rw.Domain == other.Domain && rw.Answer == other.Answer return rw.Domain == other.Domain && rw.Answer == other.Answer
@ -62,11 +52,11 @@ func (rw *LegacyRewrite) matchesQType(qt uint16) (ok bool) {
// If the types match or the entry is set to allow only the other type, // If the types match or the entry is set to allow only the other type,
// include them. // include them.
return rw.Type == qt || rw.IP == nil return rw.Type == qt || rw.IP == netip.Addr{}
} }
// normalize makes sure that the a new or decoded entry is normalized with // normalize makes sure that the new or decoded entry is normalized with regards
// regards to domain name case, IP length, and so on. // to domain name case, IP length, and so on.
// //
// If rw is nil, it returns an errors. // If rw is nil, it returns an errors.
func (rw *LegacyRewrite) normalize() (err error) { func (rw *LegacyRewrite) normalize() (err error) {
@ -81,12 +71,12 @@ func (rw *LegacyRewrite) normalize() (err error) {
switch rw.Answer { switch rw.Answer {
case "AAAA": case "AAAA":
rw.IP = nil rw.IP = netip.Addr{}
rw.Type = dns.TypeAAAA rw.Type = dns.TypeAAAA
return nil return nil
case "A": case "A":
rw.IP = nil rw.IP = netip.Addr{}
rw.Type = dns.TypeA rw.Type = dns.TypeA
return nil return nil
@ -94,19 +84,18 @@ func (rw *LegacyRewrite) normalize() (err error) {
// Go on. // Go on.
} }
ip := net.ParseIP(rw.Answer) ip, err := netip.ParseAddr(rw.Answer)
if ip == nil { if err != nil {
log.Debug("normalizing legacy rewrite: %s", err)
rw.Type = dns.TypeCNAME rw.Type = dns.TypeCNAME
return nil return nil
} }
ip4 := ip.To4() rw.IP = ip
if ip4 != nil { if ip.Is4() {
rw.IP = ip4
rw.Type = dns.TypeA rw.Type = dns.TypeA
} else { } else {
rw.IP = ip
rw.Type = dns.TypeAAAA rw.Type = dns.TypeAAAA
} }
@ -207,7 +196,7 @@ func findRewrites(
func setRewriteResult(res *Result, host string, rewrites []*LegacyRewrite, qtype uint16) { func setRewriteResult(res *Result, host string, rewrites []*LegacyRewrite, qtype uint16) {
for _, rw := range rewrites { for _, rw := range rewrites {
if rw.Type == qtype && (qtype == dns.TypeA || qtype == dns.TypeAAAA) { if rw.Type == qtype && (qtype == dns.TypeA || qtype == dns.TypeAAAA) {
if rw.IP == nil { if rw.IP == (netip.Addr{}) {
// "A"/"AAAA" exception: allow getting from upstream. // "A"/"AAAA" exception: allow getting from upstream.
res.Reason = NotFilteredNotFound res.Reason = NotFilteredNotFound
@ -225,7 +214,12 @@ func setRewriteResult(res *Result, host string, rewrites []*LegacyRewrite, qtype
func cloneRewrites(entries []*LegacyRewrite) (clone []*LegacyRewrite) { func cloneRewrites(entries []*LegacyRewrite) (clone []*LegacyRewrite) {
clone = make([]*LegacyRewrite, len(entries)) clone = make([]*LegacyRewrite, len(entries))
for i, rw := range entries { for i, rw := range entries {
clone[i] = rw.clone() clone[i] = &LegacyRewrite{
Domain: rw.Domain,
Answer: rw.Answer,
IP: rw.IP,
Type: rw.Type,
}
} }
return clone return clone

View file

@ -2,6 +2,7 @@ package filtering
import ( import (
"net" "net"
"net/netip"
"testing" "testing"
"github.com/miekg/dns" "github.com/miekg/dns"
@ -15,33 +16,43 @@ func TestRewrites(t *testing.T) {
d, _ := newForTest(t, nil, nil) d, _ := newForTest(t, nil, nil)
t.Cleanup(d.Close) t.Cleanup(d.Close)
var (
addr1v4 = netip.AddrFrom4([4]byte{1, 2, 3, 4})
addr2v4 = netip.AddrFrom4([4]byte{1, 2, 3, 5})
addr3v4 = netip.AddrFrom4([4]byte{1, 2, 3, 6})
addr4v4 = netip.AddrFrom4([4]byte{1, 2, 3, 7})
addr1v6 = netip.MustParseAddr("1:2:3::4")
addr2v6 = netip.MustParseAddr("1234::5678")
)
d.Rewrites = []*LegacyRewrite{{ d.Rewrites = []*LegacyRewrite{{
// This one and below are about CNAME, A and AAAA. // This one and below are about CNAME, A and AAAA.
Domain: "somecname", Domain: "somecname",
Answer: "somehost.com", Answer: "somehost.com",
}, { }, {
Domain: "somehost.com", Domain: "somehost.com",
Answer: "0.0.0.0", Answer: netip.IPv4Unspecified().String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1.2.3.4", Answer: addr1v4.String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1.2.3.5", Answer: addr2v4.String(),
}, { }, {
Domain: "host.com", Domain: "host.com",
Answer: "1:2:3::4", Answer: addr1v6.String(),
}, { }, {
Domain: "www.host.com", Domain: "www.host.com",
Answer: "host.com", Answer: "host.com",
}, { }, {
// This one is a wildcard. // This one is a wildcard.
Domain: "*.host.com", Domain: "*.host.com",
Answer: "1.2.3.5", Answer: addr2v4.String(),
}, { }, {
// This one and below are about wildcard overriding. // This one and below are about wildcard overriding.
Domain: "a.host.com", Domain: "a.host.com",
Answer: "1.2.3.4", Answer: addr1v4.String(),
}, { }, {
// This one is about CNAME and wildcard interacting. // This one is about CNAME and wildcard interacting.
Domain: "*.host2.com", Domain: "*.host2.com",
@ -59,13 +70,13 @@ func TestRewrites(t *testing.T) {
Answer: "x.host.com", Answer: "x.host.com",
}, { }, {
Domain: "*.hostboth.com", Domain: "*.hostboth.com",
Answer: "1.2.3.6", Answer: addr3v4.String(),
}, { }, {
Domain: "*.hostboth.com", Domain: "*.hostboth.com",
Answer: "1234::5678", Answer: addr2v6.String(),
}, { }, {
Domain: "BIGHOST.COM", Domain: "BIGHOST.COM",
Answer: "1.2.3.7", Answer: addr4v4.String(),
}, { }, {
Domain: "*.issue4016.com", Domain: "*.issue4016.com",
Answer: "sub.issue4016.com", Answer: "sub.issue4016.com",
@ -77,7 +88,7 @@ func TestRewrites(t *testing.T) {
name string name string
host string host string
wantCName string wantCName string
wantIPs []net.IP wantIPs []netip.Addr
wantReason Reason wantReason Reason
dtyp uint16 dtyp uint16
}{{ }{{
@ -91,63 +102,63 @@ func TestRewrites(t *testing.T) {
name: "rewritten_a", name: "rewritten_a",
host: "www.host.com", host: "www.host.com",
wantCName: "host.com", wantCName: "host.com",
wantIPs: []net.IP{{1, 2, 3, 4}, {1, 2, 3, 5}}, wantIPs: []netip.Addr{addr1v4, addr2v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "rewritten_aaaa", name: "rewritten_aaaa",
host: "www.host.com", host: "www.host.com",
wantCName: "host.com", wantCName: "host.com",
wantIPs: []net.IP{net.ParseIP("1:2:3::4")}, wantIPs: []netip.Addr{addr1v6},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeAAAA, dtyp: dns.TypeAAAA,
}, { }, {
name: "wildcard_match", name: "wildcard_match",
host: "abc.host.com", host: "abc.host.com",
wantCName: "", wantCName: "",
wantIPs: []net.IP{{1, 2, 3, 5}}, wantIPs: []netip.Addr{addr2v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "wildcard_override", name: "wildcard_override",
host: "a.host.com", host: "a.host.com",
wantCName: "", wantCName: "",
wantIPs: []net.IP{{1, 2, 3, 4}}, wantIPs: []netip.Addr{addr1v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "wildcard_cname_interaction", name: "wildcard_cname_interaction",
host: "www.host2.com", host: "www.host2.com",
wantCName: "host.com", wantCName: "host.com",
wantIPs: []net.IP{{1, 2, 3, 4}, {1, 2, 3, 5}}, wantIPs: []netip.Addr{addr1v4, addr2v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "two_cnames", name: "two_cnames",
host: "b.host.com", host: "b.host.com",
wantCName: "somehost.com", wantCName: "somehost.com",
wantIPs: []net.IP{{0, 0, 0, 0}}, wantIPs: []netip.Addr{netip.IPv4Unspecified()},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "two_cnames_and_wildcard", name: "two_cnames_and_wildcard",
host: "b.host3.com", host: "b.host3.com",
wantCName: "x.host.com", wantCName: "x.host.com",
wantIPs: []net.IP{{1, 2, 3, 5}}, wantIPs: []netip.Addr{addr2v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
name: "issue3343", name: "issue3343",
host: "www.hostboth.com", host: "www.hostboth.com",
wantCName: "", wantCName: "",
wantIPs: []net.IP{net.ParseIP("1234::5678")}, wantIPs: []netip.Addr{addr2v6},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeAAAA, dtyp: dns.TypeAAAA,
}, { }, {
name: "issue3351", name: "issue3351",
host: "bighost.com", host: "bighost.com",
wantCName: "", wantCName: "",
wantIPs: []net.IP{{1, 2, 3, 7}}, wantIPs: []netip.Addr{addr4v4},
wantReason: Rewritten, wantReason: Rewritten,
dtyp: dns.TypeA, dtyp: dns.TypeA,
}, { }, {
@ -254,25 +265,25 @@ func TestRewritesExceptionCNAME(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
host string host string
want net.IP want netip.Addr
}{{ }{{
name: "match_subdomain", name: "match_subdomain",
host: "my.host.com", host: "my.host.com",
want: net.IP{2, 2, 2, 2}, want: netip.AddrFrom4([4]byte{2, 2, 2, 2}),
}, { }, {
name: "exception_cname", name: "exception_cname",
host: "sub.host.com", host: "sub.host.com",
want: nil, want: netip.Addr{},
}, { }, {
name: "exception_wildcard", name: "exception_wildcard",
host: "my.sub.host.com", host: "my.sub.host.com",
want: nil, want: netip.Addr{},
}} }}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
r := d.processRewrites(tc.host, dns.TypeA) r := d.processRewrites(tc.host, dns.TypeA)
if tc.want == nil { if tc.want == (netip.Addr{}) {
assert.Equal(t, NotFilteredNotFound, r.Reason, "got %s", r.Reason) assert.Equal(t, NotFilteredNotFound, r.Reason, "got %s", r.Reason)
return return
@ -280,7 +291,7 @@ func TestRewritesExceptionCNAME(t *testing.T) {
assert.Equal(t, Rewritten, r.Reason) assert.Equal(t, Rewritten, r.Reason)
require.Len(t, r.IPList, 1) require.Len(t, r.IPList, 1)
assert.True(t, tc.want.Equal(r.IPList[0])) assert.Equal(t, tc.want, r.IPList[0])
}) })
} }
} }
@ -316,56 +327,56 @@ func TestRewritesExceptionIP(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
host string host string
want []net.IP want []netip.Addr
dtyp uint16 dtyp uint16
wantReason Reason
}{{ }{{
name: "match_A", name: "match_A",
host: "host.com", host: "host.com",
want: []net.IP{{1, 2, 3, 4}}, want: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
dtyp: dns.TypeA, dtyp: dns.TypeA,
wantReason: Rewritten,
}, { }, {
name: "exception_AAAA_host.com", name: "exception_AAAA_host.com",
host: "host.com", host: "host.com",
want: nil, want: nil,
dtyp: dns.TypeAAAA, dtyp: dns.TypeAAAA,
wantReason: NotFilteredNotFound,
}, { }, {
name: "exception_A_host2.com", name: "exception_A_host2.com",
host: "host2.com", host: "host2.com",
want: nil, want: nil,
dtyp: dns.TypeA, dtyp: dns.TypeA,
wantReason: NotFilteredNotFound,
}, { }, {
name: "match_AAAA_host2.com", name: "match_AAAA_host2.com",
host: "host2.com", host: "host2.com",
want: []net.IP{net.ParseIP("::1")}, want: []netip.Addr{netip.MustParseAddr("::1")},
dtyp: dns.TypeAAAA, dtyp: dns.TypeAAAA,
wantReason: Rewritten,
}, { }, {
name: "exception_A_host3.com", name: "exception_A_host3.com",
host: "host3.com", host: "host3.com",
want: nil, want: nil,
dtyp: dns.TypeA, dtyp: dns.TypeA,
wantReason: NotFilteredNotFound,
}, { }, {
name: "match_AAAA_host3.com", name: "match_AAAA_host3.com",
host: "host3.com", host: "host3.com",
want: []net.IP{}, want: nil,
dtyp: dns.TypeAAAA, dtyp: dns.TypeAAAA,
wantReason: Rewritten,
}} }}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name+"_"+tc.host, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if tc.name != "match_AAAA_host3.com" {
t.SkipNow()
}
r := d.processRewrites(tc.host, tc.dtyp) r := d.processRewrites(tc.host, tc.dtyp)
if tc.want == nil { assert.Equal(t, tc.want, r.IPList)
assert.Equal(t, NotFilteredNotFound, r.Reason) assert.Equal(t, tc.wantReason, r.Reason)
return
}
assert.Equalf(t, Rewritten, r.Reason, "got %s", r.Reason)
require.Len(t, r.IPList, len(tc.want))
for _, ip := range tc.want {
assert.True(t, ip.Equal(r.IPList[0]))
}
}) })
} }
} }

View file

@ -8,6 +8,7 @@ import (
"encoding/gob" "encoding/gob"
"fmt" "fmt"
"net" "net"
"net/netip"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -239,10 +240,9 @@ func (ss *Default) newResult(
} }
if rewrite.RRType == qtype { if rewrite.RRType == qtype {
v := rewrite.Value ip, ok := rewrite.Value.(netip.Addr)
ip, ok := v.(net.IP) if !ok || ip == (netip.Addr{}) {
if !ok || ip == nil { return nil, fmt.Errorf("expected ip rewrite value, got %T(%[1]v)", rewrite.Value)
return nil, fmt.Errorf("expected ip rewrite value, got %T(%[1]v)", v)
} }
res.Rules[0].IP = ip res.Rules[0].IP = ip
@ -267,12 +267,13 @@ func (ss *Default) newResult(
for _, ip := range ips { for _, ip := range ips {
// TODO(a.garipov): Remove this filtering once the resolver we use // TODO(a.garipov): Remove this filtering once the resolver we use
// actually learns about network. // actually learns about network.
ip = fitToProto(ip, qtype) addr := fitToProto(ip, qtype)
if ip == nil { if addr == (netip.Addr{}) {
continue continue
} }
res.Rules[0].IP = ip // TODO(e.burkov): Rules[0]?
res.Rules[0].IP = addr
} }
return res, nil return res, nil
@ -293,17 +294,16 @@ func qtypeToProto(qtype rules.RRType) (proto string) {
// fitToProto returns a non-nil IP address if ip is the correct protocol version // fitToProto returns a non-nil IP address if ip is the correct protocol version
// for qtype. qtype is expected to be either [dns.TypeA] or [dns.TypeAAAA]. // for qtype. qtype is expected to be either [dns.TypeA] or [dns.TypeAAAA].
func fitToProto(ip net.IP, qtype rules.RRType) (res net.IP) { func fitToProto(ip net.IP, qtype rules.RRType) (res netip.Addr) {
ip4 := ip.To4() if ip4 := ip.To4(); qtype == dns.TypeA {
if qtype == dns.TypeA { if ip4 != nil {
return ip4 return netip.AddrFrom4([4]byte(ip4))
}
} else if ip = ip.To16(); ip != nil && qtype == dns.TypeAAAA {
return netip.AddrFrom16([16]byte(ip))
} }
if ip4 == nil { return netip.Addr{}
return ip
}
return nil
} }
// setCacheResult stores data in cache for host. qtype is expected to be either // setCacheResult stores data in cache for host. qtype is expected to be either

View file

@ -3,6 +3,7 @@ package safesearch
import ( import (
"context" "context"
"net" "net"
"net/netip"
"testing" "testing"
"time" "time"
@ -33,7 +34,7 @@ var defaultSafeSearchConf = filtering.SafeSearchConfig{
YouTube: true, YouTube: true,
} }
var yandexIP = net.IPv4(213, 180, 193, 56) var yandexIP = netip.AddrFrom4([4]byte{213, 180, 193, 56})
func newForTest(t testing.TB, ssConf filtering.SafeSearchConfig) (ss *Default) { func newForTest(t testing.TB, ssConf filtering.SafeSearchConfig) (ss *Default) {
ss, err := NewDefault(ssConf, "", testCacheSize, testCacheTTL) ss, err := NewDefault(ssConf, "", testCacheSize, testCacheTTL)
@ -93,7 +94,7 @@ func TestSafeSearchCacheGoogle(t *testing.T) {
OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) { OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) {
ip4, ip6 := aghtest.HostToIPs(host) ip4, ip6 := aghtest.HostToIPs(host)
return []net.IP{ip4, ip6}, nil return []net.IP{ip4.AsSlice(), ip6.AsSlice()}, nil
}, },
} }
@ -109,14 +110,14 @@ func TestSafeSearchCacheGoogle(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Len(t, res.Rules, 1) require.Len(t, res.Rules, 1)
assert.True(t, res.Rules[0].IP.Equal(wantIP)) assert.Equal(t, wantIP, res.Rules[0].IP)
// Check cache. // Check cache.
cachedValue, isFound := ss.getCachedResult(domain, testQType) cachedValue, isFound := ss.getCachedResult(domain, testQType)
require.True(t, isFound) require.True(t, isFound)
require.Len(t, cachedValue.Rules, 1) require.Len(t, cachedValue.Rules, 1)
assert.True(t, cachedValue.Rules[0].IP.Equal(wantIP)) assert.Equal(t, wantIP, cachedValue.Rules[0].IP)
} }
const googleHost = "www.google.com" const googleHost = "www.google.com"

View file

@ -3,6 +3,7 @@ package safesearch_test
import ( import (
"context" "context"
"net" "net"
"net/netip"
"testing" "testing"
"time" "time"
@ -43,7 +44,7 @@ var testConf = filtering.SafeSearchConfig{
// yandexIP is the expected IP address of Yandex safe search results. Keep in // yandexIP is the expected IP address of Yandex safe search results. Keep in
// sync with the rules data. // sync with the rules data.
var yandexIP = net.IPv4(213, 180, 193, 56) var yandexIP = netip.AddrFrom4([4]byte{213, 180, 193, 56})
func TestDefault_CheckHost_yandex(t *testing.T) { func TestDefault_CheckHost_yandex(t *testing.T) {
conf := testConf conf := testConf
@ -87,7 +88,7 @@ func TestDefault_CheckHost_yandexAAAA(t *testing.T) {
// once the TODO in [safesearch.Default.newResult] is resolved. // once the TODO in [safesearch.Default.newResult] is resolved.
require.Len(t, res.Rules, 1) require.Len(t, res.Rules, 1)
assert.Nil(t, res.Rules[0].IP) assert.Empty(t, res.Rules[0].IP)
assert.EqualValues(t, filtering.SafeSearchListID, res.Rules[0].FilterListID) assert.EqualValues(t, filtering.SafeSearchListID, res.Rules[0].FilterListID)
} }
@ -96,7 +97,7 @@ func TestDefault_CheckHost_google(t *testing.T) {
OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) { OnLookupIP: func(_ context.Context, _, host string) (ips []net.IP, err error) {
ip4, ip6 := aghtest.HostToIPs(host) ip4, ip6 := aghtest.HostToIPs(host)
return []net.IP{ip4, ip6}, nil return []net.IP{ip4.AsSlice(), ip6.AsSlice()}, nil
}, },
} }
@ -178,7 +179,7 @@ func TestDefault_CheckHost_duckduckgoAAAA(t *testing.T) {
// once the TODO in [safesearch.Default.newResult] is resolved. // once the TODO in [safesearch.Default.newResult] is resolved.
require.Len(t, res.Rules, 1) require.Len(t, res.Rules, 1)
assert.Nil(t, res.Rules[0].IP) assert.Empty(t, res.Rules[0].IP)
assert.EqualValues(t, filtering.SafeSearchListID, res.Rules[0].FilterListID) assert.EqualValues(t, filtering.SafeSearchListID, res.Rules[0].FilterListID)
} }

View file

@ -378,7 +378,7 @@ func getDNSEncryption() (de dnsEncryption) {
// applyAdditionalFiltering adds additional client information and settings if // applyAdditionalFiltering adds additional client information and settings if
// the client has them. // the client has them.
func applyAdditionalFiltering(clientIP net.IP, clientID string, setts *filtering.Settings) { func applyAdditionalFiltering(clientIP netip.Addr, clientID string, setts *filtering.Settings) {
// pref is a prefix for logging messages around the scope. // pref is a prefix for logging messages around the scope.
const pref = "applying filters" const pref = "applying filters"
@ -386,7 +386,7 @@ func applyAdditionalFiltering(clientIP net.IP, clientID string, setts *filtering
log.Debug("%s: looking for client with ip %s and clientid %q", pref, clientIP, clientID) log.Debug("%s: looking for client with ip %s and clientid %q", pref, clientIP, clientID)
if clientIP == nil { if !clientIP.IsValid() {
return return
} }

View file

@ -1,7 +1,7 @@
package home package home
import ( import (
"net" "net/netip"
"testing" "testing"
"github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering"
@ -10,6 +10,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var testIPv4 = netip.AddrFrom4([4]byte{1, 2, 3, 4})
func TestApplyAdditionalFiltering(t *testing.T) { func TestApplyAdditionalFiltering(t *testing.T) {
var err error var err error
@ -78,7 +80,7 @@ func TestApplyAdditionalFiltering(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
setts := &filtering.Settings{} setts := &filtering.Settings{}
applyAdditionalFiltering(net.IP{1, 2, 3, 4}, tc.id, setts) applyAdditionalFiltering(testIPv4, tc.id, setts)
tc.FilteringEnabled(t, setts.FilteringEnabled) tc.FilteringEnabled(t, setts.FilteringEnabled)
tc.SafeSearchEnabled(t, setts.SafeSearchEnabled) tc.SafeSearchEnabled(t, setts.SafeSearchEnabled)
tc.SafeBrowsingEnabled(t, setts.SafeBrowsingEnabled) tc.SafeBrowsingEnabled(t, setts.SafeBrowsingEnabled)
@ -169,7 +171,7 @@ func TestApplyAdditionalFiltering_blockedServices(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
setts := &filtering.Settings{} setts := &filtering.Settings{}
applyAdditionalFiltering(net.IP{1, 2, 3, 4}, tc.id, setts) applyAdditionalFiltering(testIPv4, tc.id, setts)
require.Len(t, setts.ServicesRules, tc.wantLen) require.Len(t, setts.ServicesRules, tc.wantLen)
}) })
} }

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"net/netip"
"strings" "strings"
"time" "time"
@ -183,7 +184,11 @@ func decodeResultRuleKey(key string, i int, dec *json.Decoder, ent *logEntry) {
case "IP": case "IP":
ent.Result.Rules, vToken = decodeVTokenAndAddRule(key, i, dec, ent.Result.Rules) ent.Result.Rules, vToken = decodeVTokenAndAddRule(key, i, dec, ent.Result.Rules)
if ipStr, ok := vToken.(string); ok { if ipStr, ok := vToken.(string); ok {
ent.Result.Rules[i].IP = net.ParseIP(ipStr) if ip, err := netip.ParseAddr(ipStr); err == nil {
ent.Result.Rules[i].IP = ip
} else {
log.Debug("querylog: decoding ipStr value: %s", err)
}
} }
case "Text": case "Text":
ent.Result.Rules, vToken = decodeVTokenAndAddRule(key, i, dec, ent.Result.Rules) ent.Result.Rules, vToken = decodeVTokenAndAddRule(key, i, dec, ent.Result.Rules)
@ -362,8 +367,9 @@ func decodeResultIPList(dec *json.Decoder, ent *logEntry) {
return return
case string: case string:
ip := net.ParseIP(v) var ip netip.Addr
if ip != nil { ip, err = netip.ParseAddr(v)
if err == nil {
ent.Result.IPList = append(ent.Result.IPList, ip) ent.Result.IPList = append(ent.Result.IPList, ip)
} }
default: default:
@ -462,7 +468,7 @@ func translateResult(ent *logEntry) {
resp := res.DNSRewriteResult.Response resp := res.DNSRewriteResult.Response
for _, ip := range res.IPList { for _, ip := range res.IPList {
qType := dns.TypeAAAA qType := dns.TypeAAAA
if ip.To4() != nil { if ip.Is4() {
qType = dns.TypeA qType = dns.TypeA
} }

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"net" "net"
"net/netip"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -11,6 +12,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghtest" "github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/AdguardTeam/AdGuardHome/internal/filtering" "github.com/AdguardTeam/AdGuardHome/internal/filtering"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/urlfilter/rules" "github.com/AdguardTeam/urlfilter/rules"
"github.com/miekg/dns" "github.com/miekg/dns"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -71,15 +73,15 @@ func TestDecodeLogEntry(t *testing.T) {
}, },
CanonName: "example.com", CanonName: "example.com",
ServiceName: "example.org", ServiceName: "example.org",
IPList: []net.IP{net.IPv4(127, 0, 0, 2)}, IPList: []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 2})},
Rules: []*filtering.ResultRule{{ Rules: []*filtering.ResultRule{{
FilterListID: 42, FilterListID: 42,
Text: "||an.yandex.ru", Text: "||an.yandex.ru",
IP: net.IPv4(127, 0, 0, 2), IP: netip.AddrFrom4([4]byte{127, 0, 0, 2}),
}, { }, {
FilterListID: 43, FilterListID: 43,
Text: "||an2.yandex.ru", Text: "||an2.yandex.ru",
IP: net.IPv4(127, 0, 0, 3), IP: netip.AddrFrom4([4]byte{127, 0, 0, 3}),
}}, }},
Reason: filtering.FilteredBlockList, Reason: filtering.FilteredBlockList,
IsFiltered: true, IsFiltered: true,
@ -192,8 +194,10 @@ func TestDecodeLogEntry(t *testing.T) {
func TestDecodeLogEntry_backwardCompatability(t *testing.T) { func TestDecodeLogEntry_backwardCompatability(t *testing.T) {
var ( var (
a1, a2 = net.IP{127, 0, 0, 1}.To16(), net.IP{127, 0, 0, 2}.To16() a1 = netutil.IPv4Localhost()
aaaa1, aaaa2 = net.ParseIP("::1"), net.ParseIP("::2") a2 = a1.Next()
aaaa1 = netutil.IPv6Localhost()
aaaa2 = aaaa1.Next()
) )
testCases := []struct { testCases := []struct {
@ -230,7 +234,7 @@ func TestDecodeLogEntry_backwardCompatability(t *testing.T) {
entry: `{"Result":{"IPList":["127.0.0.1","127.0.0.2","::1","::2"],"Reason":9}}`, entry: `{"Result":{"IPList":["127.0.0.1","127.0.0.2","::1","::2"],"Reason":9}}`,
want: &logEntry{ want: &logEntry{
Result: filtering.Result{ Result: filtering.Result{
IPList: []net.IP{ IPList: []netip.Addr{
a1, a1,
a2, a2,
aaaa1, aaaa1,