diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bc865a3..ca7d27ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,8 +30,11 @@ and this project adheres to ### Changed +- Filtering rules with the `dnsrewrite` modifier that create SVCB or HTTPS + responses should use `ech` instead of `echconfig` to conform with the [latest + drafts][svcb-draft-08]. - The default DNS-over-QUIC port number is now `853` instead of `754` in - accoradance with the latest [RFC draft][doq-draft-10] ([#4276]). + accordance with the latest [RFC draft][doq-draft-10] ([#4276]). - Reverse DNS now has a greater priority as the source of runtime clients' information than ARP neighborhood. - Improved detection of runtime clients through more resilient ARP processing @@ -79,6 +82,9 @@ In this release, the schema version has changed from 12 to 13. ### Deprecated +- SVCB/HTTPS parameter name `echconfig` in filtering rules with the `dnsrewrite` + modifier. Use `ech` instead. v0.109.0 will remove support for the outdated + name `echconfig`. - Obsolete `--no-mem-optimization` option ([#4437]). v0.109.0 will remove the flag completely. - Go 1.17 support. v0.109.0 will require at least Go 1.18 to build. @@ -115,8 +121,9 @@ In this release, the schema version has changed from 12 to 13. [#4276]: https://github.com/AdguardTeam/AdGuardHome/issues/4276 [#4437]: https://github.com/AdguardTeam/AdGuardHome/issues/4437 -[repr]: https://reproducible-builds.org/docs/source-date-epoch/ -[doq-draft-10]: https://datatracker.ietf.org/doc/html/draft-ietf-dprive-dnsoquic-10#section-10.2 +[repr]: https://reproducible-builds.org/docs/source-date-epoch/ +[doq-draft-10]: https://datatracker.ietf.org/doc/html/draft-ietf-dprive-dnsoquic-10#section-10.2 +[svcb-draft-08]: https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-08.html @@ -176,7 +183,7 @@ See also the [v0.107.3 GitHub milestone][ms-v0.107.3]. ### Added -- Support for a `$dnsrewrite` modifier with an empty `NOERROR` response +- Support for a `dnsrewrite` modifier with an empty `NOERROR` response ([#4133]). ### Fixed @@ -292,7 +299,7 @@ See also the [v0.107.0 GitHub milestone][ms-v0.107.0]. - Better error message for ED25519 private keys, which are not widely supported ([#3737]). - Cache now follows RFC more closely for negative answers ([#3707]). -- `$dnsrewrite` rules and other DNS rewrites will now be applied even when the +- `dnsrewrite` rules and other DNS rewrites will now be applied even when the protection is disabled ([#1558]). - DHCP gateway address, subnet mask, IP address range, and leases validations ([#3529]). @@ -365,7 +372,7 @@ In this release, the schema version has changed from 10 to 12. ### Fixed - EDNS0 TCP keepalive option handling ([#3778]). -- Rules with the `$denyallow` modifier applying to IP addresses when they +- Rules with the `denyallow` modifier applying to IP addresses when they shouldn't ([#3175]). - The length of the EDNS0 client subnet option appearing too long for some upstream servers ([#3887]). @@ -373,8 +380,8 @@ In this release, the schema version has changed from 10 to 12. settings ([#3558]). - Incomplete propagation of the client's IP anonymization setting to the statistics ([#3890]). -- Incorrect `$dnsrewrite` results for entries from the operating system's hosts - file ([#3815]). +- Incorrect results with the `dnsrewrite` modifier for entries from the + operating system's hosts file ([#3815]). - Matching against rules with `|` at the end of the domain name ([#3371]). - Incorrect assignment of explicitly configured DHCP options ([#3744]). - Occasional panic during shutdown ([#3655]). @@ -401,8 +408,8 @@ In this release, the schema version has changed from 10 to 12. - Letter case mismatches in `CNAME` filtering ([#3335]). - Occasional breakages on network errors with DNS-over-HTTP upstreams ([#3217]). - Errors when setting static IP on Linux ([#3257]). -- Treatment of domain names and FQDNs in custom rules with `$dnsrewrite` that - use the `PTR` type ([#3256]). +- Treatment of domain names and FQDNs in custom rules with the `dnsrewrite` + modifier that use the `PTR` type ([#3256]). - Redundant hostname generating while loading static leases with empty hostname ([#3166]). - Domain name case in responses ([#3194]). @@ -566,7 +573,7 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0]. - The ability to block user for login after configurable number of unsuccessful attempts for configurable time ([#2826]). -- `$denyallow` modifier for filters ([#2923]). +- `denyallow` modifier for filters ([#2923]). - Hostname uniqueness validation in the DHCP server ([#2952]). - Hostname generating for DHCP clients which don't provide their own ([#2723]). - New flag `--no-etc-hosts` to disable client domain name lookups in the @@ -581,7 +588,8 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0]. network ([#2393], [#2961]). - The ability to serve DNS queries on multiple hosts and interfaces ([#1401]). - `ips` and `text` DHCP server options ([#2385]). -- `SRV` records support in `$dnsrewrite` filters ([#2533]). +- `SRV` records support in filtering rules with the `dnsrewrite` modifier + ([#2533]). ### Changed @@ -595,7 +603,8 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0]. ([#2704]). - Stricter validation of the IP addresses of static leases in the DHCP server with regards to the netmask ([#2838]). -- Stricter validation of `$dnsrewrite` filter modifier parameters ([#2498]). +- Stricter validation of `dnsrewrite` filtering rule modifier parameters + ([#2498]). - New, more correct versioning scheme ([#2412]). ### Deprecated @@ -604,7 +613,7 @@ See also the [v0.106.0 GitHub milestone][ms-v0.106.0]. ### Fixed -- Multiple answers for `$dnsrewrite` rule matching requests with repeating +- Multiple answers for a `dnsrewrite` rule matching requests with repeating patterns in it ([#2981]). - Root server resolving when custom upstreams for hosts are specified ([#2994]). - Inconsistent resolving of DHCP clients when the DHCP server is disabled @@ -743,7 +752,7 @@ See also the [v0.105.0 GitHub milestone][ms-v0.105.0]. - `ipset` subdomain matching, just like `dnsmasq` does ([#2179]). - ClientID support for DNS-over-HTTPS, DNS-over-QUIC, and DNS-over-TLS ([#1383]). -- `$dnsrewrite` modifier for filters ([#2102]). +- The new `dnsrewrite` modifier for filters ([#2102]). - The host checking API and the query logs API can now return multiple matched rules ([#2102]). - Detecting of network interface configured to have static IP address via @@ -751,7 +760,7 @@ See also the [v0.105.0 GitHub milestone][ms-v0.105.0]. - DNSCrypt protocol support ([#1361]). - A 5 second wait period until a DHCP server's network interface gets an IP address ([#2304]). -- `$dnstype` modifier for filters ([#2337]). +- `dnstype` modifier for filters ([#2337]). - HTTP API request body size limit ([#2305]). ### Changed diff --git a/go.mod b/go.mod index 8cfd5475..1886d519 100644 --- a/go.mod +++ b/go.mod @@ -20,14 +20,14 @@ require ( github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 github.com/mdlayher/netlink v1.5.0 github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b - github.com/miekg/dns v1.1.45 + github.com/miekg/dns v1.1.48 github.com/satori/go.uuid v1.2.0 github.com/stretchr/testify v1.7.0 github.com/ti-mo/netfilter v0.4.0 go.etcd.io/bbolt v1.3.6 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 - golang.org/x/net v0.0.0-20211216030914-fe4d6282115f - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e + golang.org/x/net v0.0.0-20220403103023-749bd193bc2b + golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/yaml.v2 v2.4.0 howett.net/plist v1.0.0 @@ -55,10 +55,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/objx v0.1.1 // indirect github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 // indirect - golang.org/x/mod v0.5.1 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.8 // indirect + golang.org/x/tools v0.1.10 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/go.sum b/go.sum index 5e5ef775..1e8c5022 100644 --- a/go.sum +++ b/go.sum @@ -197,8 +197,8 @@ github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00v github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.44/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk= -github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -301,6 +301,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -311,8 +312,9 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -353,8 +355,9 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0= +golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -424,9 +427,11 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 h1:QyVthZKMsyaQwBTJE04jdNN0Pp5Fn9Qga0mrgxyERQM= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -451,8 +456,9 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/dnsforward/svcbmsg.go b/internal/dnsforward/svcbmsg.go index 99413ed3..3d25f05b 100644 --- a/internal/dnsforward/svcbmsg.go +++ b/internal/dnsforward/svcbmsg.go @@ -32,12 +32,16 @@ func (s *Server) genAnswerHTTPS(req *dns.Msg, svcb *rules.DNSSVCB) (ans *dns.HTT // github.com/miekg/dns module. var strToSVCBKey = map[string]dns.SVCBKey{ "alpn": dns.SVCB_ALPN, - "echconfig": dns.SVCB_ECHCONFIG, + "ech": dns.SVCB_ECHCONFIG, "ipv4hint": dns.SVCB_IPV4HINT, "ipv6hint": dns.SVCB_IPV6HINT, "mandatory": dns.SVCB_MANDATORY, "no-default-alpn": dns.SVCB_NO_DEFAULT_ALPN, "port": dns.SVCB_PORT, + + // TODO(a.garipov): This is the previous name for the parameter that has + // since been changed. Remove this in v0.109.0. + "echconfig": dns.SVCB_ECHCONFIG, } // svcbKeyHandler is a handler for one SVCB parameter key. @@ -51,10 +55,10 @@ var svcbKeyHandlers = map[string]svcbKeyHandler{ } }, - "echconfig": func(valStr string) (val dns.SVCBKeyValue) { + "ech": func(valStr string) (val dns.SVCBKeyValue) { ech, err := base64.StdEncoding.DecodeString(valStr) if err != nil { - log.Debug("can't parse svcb/https echconfig: %s; ignoring", err) + log.Debug("can't parse svcb/https ech: %s; ignoring", err) return nil } @@ -119,6 +123,26 @@ var svcbKeyHandlers = map[string]svcbKeyHandler{ Port: uint16(port64), } }, + + // TODO(a.garipov): This is the previous name for the parameter that has + // since been changed. Remove this in v0.109.0. + "echconfig": func(valStr string) (val dns.SVCBKeyValue) { + log.Info( + `warning: svcb/https record parameter name "echconfig" is deprecated; ` + + `use "ech" instead`, + ) + + ech, err := base64.StdEncoding.DecodeString(valStr) + if err != nil { + log.Debug("can't parse svcb/https ech: %s; ignoring", err) + + return nil + } + + return &dns.SVCBECHConfig{ + ECH: ech, + } + }, } // genAnswerSVCB returns a properly initialized SVCB resource record. diff --git a/internal/dnsforward/svcbmsg_test.go b/internal/dnsforward/svcbmsg_test.go index db6994c3..28794531 100644 --- a/internal/dnsforward/svcbmsg_test.go +++ b/internal/dnsforward/svcbmsg_test.go @@ -87,14 +87,18 @@ func TestGenAnswerHTTPS_andSVCB(t *testing.T) { svcb: dnssvcb("alpn", "h3"), want: wantsvcb(&dns.SVCBAlpn{Alpn: []string{"h3"}}), name: "alpn", + }, { + svcb: dnssvcb("ech", "AAAA"), + want: wantsvcb(&dns.SVCBECHConfig{ECH: []byte{0, 0, 0}}), + name: "ech", }, { svcb: dnssvcb("echconfig", "AAAA"), want: wantsvcb(&dns.SVCBECHConfig{ECH: []byte{0, 0, 0}}), - name: "echconfig", + name: "ech_deprecated", }, { svcb: dnssvcb("echconfig", "%BAD%"), want: wantsvcb(nil), - name: "echconfig_invalid", + name: "ech_invalid", }, { svcb: dnssvcb("ipv4hint", "127.0.0.1"), want: wantsvcb(&dns.SVCBIPv4Hint{Hint: []net.IP{ip4}}),