Sync v2.19.0

This commit is contained in:
Andrey Meshkov
2025-12-22 15:15:56 +03:00
parent 0860d38469
commit ba93f90618
37 changed files with 442 additions and 223 deletions

View File

@@ -7,6 +7,10 @@ The format is **not** based on [Keep a Changelog][kec], since the project **does
[kec]: https://keepachangelog.com/en/1.0.0/
[sem]: https://semver.org/spec/v2.0.0.html
## AGDNS-2603 / Build 1114
- The new environment variable `PROFILES_CACHE_TYPE` has been added.
## AGDNS-3491 / Build 1109
- The new environment variable `CATEGORY_FILTER_ENABLED` has been added.

View File

@@ -9,6 +9,7 @@ The AdGuard DNS debug HTTP API is served on [`LISTEN_PORT`][env-listen_port] and
- [`GET /debug/pprof`](#pprof)
- [`POST /debug/api/cache/clear`](#api-cache-clear)
- [`POST /debug/api/refresh`](#api-refresh)
- [`POST /debug/panic`](#panic)
- [`POST /dnsdb/csv`](#dnsdb-csv)
[env-listen_port]: environment.md#LISTEN_PORT
@@ -132,6 +133,10 @@ Response body example:
}
```
## <a href="#panic" id="panic" name="panic">`POST /debug/panic`</a>
A debugging endpoint that forces service panic.
## <a href="#dnsdb-csv" id="dnsdb-csv" name="dnsdb-csv">`POST /dnsdb/csv`</a>
The CSV dump of the current DNSDB statistics. Example of the output:

View File

@@ -48,6 +48,7 @@ AdGuard DNS uses [environment variables][wiki-env] to store some of the more sen
- [`NODE_NAME`](#NODE_NAME)
- [`PROFILES_API_KEY`](#PROFILES_API_KEY)
- [`PROFILES_CACHE_PATH`](#PROFILES_CACHE_PATH)
- [`PROFILES_CACHE_TYPE`](#PROFILES_CACHE_TYPE)
- [`PROFILES_URL`](#PROFILES_URL)
- [`REDIS_DB`](#REDIS_DB)
- [`REDIS_HOST`](#REDIS_HOST)
@@ -411,7 +412,7 @@ The path to the profile cache file:
```sh
protoc\
--decode\
profiledb.FileCache\
filecachepb.FileCache\
./internal/profiledb/internal/filecachepb/filecache.proto\
< /path/to/profilecache.pb
```
@@ -422,6 +423,12 @@ The profile cache is read on start and is later updated on every [full refresh][
[conf-backend-full_refresh_interval]: configuration.md#backend-full_refresh_interval
## <a href="#PROFILES_CACHE_TYPE" id="PROFILES_CACHE_TYPE" name="PROFILES_CACHE_TYPE">`PROFILES_CACHE_TYPE`</a>
Type of the profile cache. Allowed values are: `default` and `opaque`.
**Default:** No default value, the variable is required, if [PROFILES_CACHE_PATH](#PROFILES_CACHE_PATH) isn't set to `none` and configuration contains profiles.
## <a href="#PROFILES_MAX_RESP_SIZE" id="PROFILES_MAX_RESP_SIZE" name="PROFILES_MAX_RESP_SIZE">`PROFILES_MAX_RESP_SIZE`</a>
The maximum size of the response from the profiles API in a human-readable format.

View File

@@ -52,7 +52,8 @@ Example of the output:
"node_name": "eu-1.dns.example.com",
"server_group_name": "adguard_dns_default",
"server_name": "default_dns",
"server_type": "private"
"server_type": "private",
"tls_curve_id": "X25519MLKEM768"
}
```
@@ -73,6 +74,8 @@ The `server_type` field can have one of the following values:
- `"public"`: A public AdGuard DNS server is used.
The `tls_curve_id` field is the key exchange mechanism used for the connection. If a legacy RSA key exchange is used, this field is empty.
[conf-check-domains]: configuration.md#check-domains
## <a href="#linked-ip-proxy" id="linked-ip-proxy" name="linked-ip-proxy">Linked IP Proxy</a>

10
go.mod
View File

@@ -5,7 +5,7 @@ go 1.25.5
require (
// NOTE: Do not change the pseudoversion.
github.com/AdguardTeam/AdGuardDNS/internal/dnsserver v0.0.0-00010101000000-000000000000
github.com/AdguardTeam/golibs v0.35.3
github.com/AdguardTeam/golibs v0.35.4
github.com/AdguardTeam/urlfilter v0.22.1
github.com/ameshkov/dnscrypt/v2 v2.4.0
github.com/axiomhq/hyperloglog v0.2.5
@@ -22,7 +22,7 @@ require (
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
github.com/prometheus/common v0.67.2
github.com/quic-go/quic-go v0.56.0
github.com/quic-go/quic-go v0.57.1
github.com/stretchr/testify v1.11.1
github.com/viktordanov/golang-lru v0.5.6
go.yaml.in/yaml/v4 v4.0.0-rc.3
@@ -67,7 +67,7 @@ require (
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/securego/gosec/v2 v2.22.10 // indirect
@@ -87,12 +87,12 @@ require (
golang.org/x/exp/typeparams v0.0.0-20251125195548-87e1e737ad39 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/telemetry v0.0.0-20251128220624-abf20d0e57ec // indirect
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect
golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/tools v0.39.0 // indirect
golang.org/x/vuln v1.1.4 // indirect
google.golang.org/genai v1.36.0 // indirect
google.golang.org/genai v1.37.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

20
go.sum
View File

@@ -4,8 +4,8 @@ cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
github.com/AdguardTeam/golibs v0.35.3 h1:DI0ffHyL3tFZ2UBEji3Aah7IvFwM5nY5yZoGvs1bnPY=
github.com/AdguardTeam/golibs v0.35.3/go.mod h1:9Y0yqUpwDNyHxCv4AaI42x5+qxYc7k5DWAfxtFOTn8o=
github.com/AdguardTeam/golibs v0.35.4 h1:7uvSIurqlyiKTSwTlefbOM8Bp7swgI+yb3+gL9al1Ac=
github.com/AdguardTeam/golibs v0.35.4/go.mod h1:meFdRqMtG/PLW6LD20MYAlcRbwAVowlbunHgE17xz9s=
github.com/AdguardTeam/urlfilter v0.22.1 h1:nC2x0MSNwmTsXMTPfs1Gv6GZXKmK7prlzgjCdnE4fR8=
github.com/AdguardTeam/urlfilter v0.22.1/go.mod h1:+wUx7GApNWvFPALjNd5fTLix4PFvQF5Gprx6JDYwxfE=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
@@ -132,10 +132,10 @@ github.com/prometheus/common v0.67.2 h1:PcBAckGFTIHt2+L3I33uNRTlKTplNzFctXcWhPyA
github.com/prometheus/common v0.67.2/go.mod h1:63W3KZb1JOKgcjlIr64WW/LvFGAqKPj0atm+knVGEko=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.56.0 h1:q/TW+OLismmXAehgFLczhCDTYB3bFmua4D9lsNBWxvY=
github.com/quic-go/quic-go v0.56.0/go.mod h1:9gx5KsFQtw2oZ6GZTyh+7YEvOxWCL9WZAepnHxgAo6c=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10=
github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
@@ -203,8 +203,8 @@ golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/telemetry v0.0.0-20251128220624-abf20d0e57ec h1:dRVkWZl6bUOp+oxnOe4BuyhWSIPmt29N4ooHarm7Ic8=
golang.org/x/telemetry v0.0.0-20251128220624-abf20d0e57ec/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ=
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA=
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
@@ -221,8 +221,8 @@ golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genai v1.36.0 h1:sJCIjqTAmwrtAIaemtTiKkg2TO1RxnYEusTmEQ3nGxM=
google.golang.org/genai v1.36.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
google.golang.org/genai v1.37.0 h1:dgp71k1wQ+/+APdZrN3LFgAGnVnr5IdTF1Oj0Dg+BQc=
google.golang.org/genai v1.37.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=

View File

@@ -540,6 +540,7 @@ github.com/AdguardTeam/golibs v0.31.2/go.mod h1:DzCfc0HFaaKv7sV17gZnSMUiHRtUJ1yp
github.com/AdguardTeam/golibs v0.32.7/go.mod h1:bE8KV1zqTzgZjmjFyBJ9f9O5DEKO717r7e57j1HclJA=
github.com/AdguardTeam/golibs v0.32.11 h1:75EquS8SWvzsM3JFJY0359ZBw66jDjAegteHzh9nSw8=
github.com/AdguardTeam/golibs v0.32.11/go.mod h1:LXr0gqqZuVpt+L+bP3Nnr0/CecLmm3rxkdgyyW5JXXM=
github.com/AdguardTeam/golibs v0.35.3/go.mod h1:9Y0yqUpwDNyHxCv4AaI42x5+qxYc7k5DWAfxtFOTn8o=
github.com/AdguardTeam/gomitmproxy v0.2.0 h1:rvCOf17pd1/CnMyMQW891zrEiIQBpQ8cIGjKN9pinUU=
github.com/AdguardTeam/gomitmproxy v0.2.1 h1:p9gr8Er1TYvf+7ic81Ax1sZ62UNCsMTZNbm7tC59S9o=
github.com/AdguardTeam/gomitmproxy v0.2.1/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU=
@@ -1387,6 +1388,7 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg=
github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
@@ -2239,6 +2241,8 @@ golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc-gen-go-grpc v1.6.0
// - protoc v6.33.1
// source: dns.proto
@@ -144,13 +144,13 @@ type DNSServiceServer interface {
type UnimplementedDNSServiceServer struct{}
func (UnimplementedDNSServiceServer) GetDNSProfiles(*DNSProfilesRequest, grpc.ServerStreamingServer[DNSProfile]) error {
return status.Errorf(codes.Unimplemented, "method GetDNSProfiles not implemented")
return status.Error(codes.Unimplemented, "method GetDNSProfiles not implemented")
}
func (UnimplementedDNSServiceServer) SaveDevicesBillingStat(grpc.ClientStreamingServer[DeviceBillingStat, emptypb.Empty]) error {
return status.Errorf(codes.Unimplemented, "method SaveDevicesBillingStat not implemented")
return status.Error(codes.Unimplemented, "method SaveDevicesBillingStat not implemented")
}
func (UnimplementedDNSServiceServer) CreateDeviceByHumanId(context.Context, *CreateDeviceRequest) (*CreateDeviceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateDeviceByHumanId not implemented")
return nil, status.Error(codes.Unimplemented, "method CreateDeviceByHumanId not implemented")
}
func (UnimplementedDNSServiceServer) mustEmbedUnimplementedDNSServiceServer() {}
func (UnimplementedDNSServiceServer) testEmbeddedByValue() {}
@@ -163,7 +163,7 @@ type UnsafeDNSServiceServer interface {
}
func RegisterDNSServiceServer(s grpc.ServiceRegistrar, srv DNSServiceServer) {
// If the following call pancis, it indicates UnimplementedDNSServiceServer was
// If the following call panics, it indicates UnimplementedDNSServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
@@ -298,10 +298,10 @@ type RateLimitServiceServer interface {
type UnimplementedRateLimitServiceServer struct{}
func (UnimplementedRateLimitServiceServer) GetRateLimitSettings(context.Context, *RateLimitSettingsRequest) (*RateLimitSettingsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetRateLimitSettings not implemented")
return nil, status.Error(codes.Unimplemented, "method GetRateLimitSettings not implemented")
}
func (UnimplementedRateLimitServiceServer) GetGlobalAccessSettings(context.Context, *GlobalAccessSettingsRequest) (*GlobalAccessSettingsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetGlobalAccessSettings not implemented")
return nil, status.Error(codes.Unimplemented, "method GetGlobalAccessSettings not implemented")
}
func (UnimplementedRateLimitServiceServer) mustEmbedUnimplementedRateLimitServiceServer() {}
func (UnimplementedRateLimitServiceServer) testEmbeddedByValue() {}
@@ -314,7 +314,7 @@ type UnsafeRateLimitServiceServer interface {
}
func RegisterRateLimitServiceServer(s grpc.ServiceRegistrar, srv RateLimitServiceServer) {
// If the following call pancis, it indicates UnimplementedRateLimitServiceServer was
// If the following call panics, it indicates UnimplementedRateLimitServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
@@ -460,10 +460,10 @@ type RemoteKVServiceServer interface {
type UnimplementedRemoteKVServiceServer struct{}
func (UnimplementedRemoteKVServiceServer) Get(context.Context, *RemoteKVGetRequest) (*RemoteKVGetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
return nil, status.Error(codes.Unimplemented, "method Get not implemented")
}
func (UnimplementedRemoteKVServiceServer) Set(context.Context, *RemoteKVSetRequest) (*RemoteKVSetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Set not implemented")
return nil, status.Error(codes.Unimplemented, "method Set not implemented")
}
func (UnimplementedRemoteKVServiceServer) mustEmbedUnimplementedRemoteKVServiceServer() {}
func (UnimplementedRemoteKVServiceServer) testEmbeddedByValue() {}
@@ -476,7 +476,7 @@ type UnsafeRemoteKVServiceServer interface {
}
func RegisterRemoteKVServiceServer(s grpc.ServiceRegistrar, srv RemoteKVServiceServer) {
// If the following call pancis, it indicates UnimplementedRemoteKVServiceServer was
// If the following call panics, it indicates UnimplementedRemoteKVServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
@@ -601,7 +601,7 @@ type CustomDomainServiceServer interface {
type UnimplementedCustomDomainServiceServer struct{}
func (UnimplementedCustomDomainServiceServer) GetCustomDomainCertificate(context.Context, *CustomDomainCertificateRequest) (*CustomDomainCertificateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCustomDomainCertificate not implemented")
return nil, status.Error(codes.Unimplemented, "method GetCustomDomainCertificate not implemented")
}
func (UnimplementedCustomDomainServiceServer) mustEmbedUnimplementedCustomDomainServiceServer() {}
func (UnimplementedCustomDomainServiceServer) testEmbeddedByValue() {}
@@ -614,7 +614,7 @@ type UnsafeCustomDomainServiceServer interface {
}
func RegisterCustomDomainServiceServer(s grpc.ServiceRegistrar, srv CustomDomainServiceServer) {
// If the following call pancis, it indicates UnimplementedCustomDomainServiceServer was
// If the following call panics, it indicates UnimplementedCustomDomainServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
@@ -711,7 +711,7 @@ type SessionTicketServiceServer interface {
type UnimplementedSessionTicketServiceServer struct{}
func (UnimplementedSessionTicketServiceServer) GetSessionTickets(context.Context, *SessionTicketRequest) (*SessionTicketResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetSessionTickets not implemented")
return nil, status.Error(codes.Unimplemented, "method GetSessionTickets not implemented")
}
func (UnimplementedSessionTicketServiceServer) mustEmbedUnimplementedSessionTicketServiceServer() {}
func (UnimplementedSessionTicketServiceServer) testEmbeddedByValue() {}
@@ -724,7 +724,7 @@ type UnsafeSessionTicketServiceServer interface {
}
func RegisterSessionTicketServiceServer(s grpc.ServiceRegistrar, srv SessionTicketServiceServer) {
// If the following call pancis, it indicates UnimplementedSessionTicketServiceServer was
// If the following call panics, it indicates UnimplementedSessionTicketServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.

View File

@@ -1542,6 +1542,7 @@ func (b *builder) initProfileDB(ctx context.Context) (err error) {
ErrColl: b.errColl,
ProfileMetrics: profileMtrc,
Metrics: profDBMtrc,
Opaque: b.env.ProfilesCacheType == profileCacheTypeOpaque,
Storage: strg,
CacheFilePath: b.env.ProfilesCachePath,
CacheFileIvl: time.Duration(b.env.ProfilesCacheIvl),

View File

@@ -28,6 +28,16 @@ import (
"github.com/getsentry/sentry-go"
)
const (
// profileCacheTypeDefault is a profile cache type that uses protobuf
// Open Struct API.
profileCacheTypeDefault = "default"
// profileCacheTypeOpaque is a profile cache type that uses protobuf opaque
// API.
profileCacheTypeOpaque = "opaque"
)
// environment represents the configuration that is kept in the environment.
//
// TODO(e.burkov, a.garipov): Name variables more consistently.
@@ -80,6 +90,7 @@ type environment struct {
SessionTicketType string `env:"SESSION_TICKET_TYPE"`
StandardAccessAPIKey string `env:"STANDARD_ACCESS_API_KEY"`
StandardAccessType string `env:"STANDARD_ACCESS_TYPE"`
ProfilesCacheType string `env:"PROFILES_CACHE_TYPE"`
// TODO(a.garipov): Consider renaming to "WEB_STATIC_PATH" or something
// similar.
@@ -482,6 +493,22 @@ func (envs *environment) validateProfilesConf(profilesEnabled bool) (err error)
validate.Positive("PROFILES_CACHE_INTERVAL", envs.ProfilesCacheIvl),
)
if envs.ProfilesCachePath == "none" {
return errors.Join(errs...)
}
errs = append(errs, validate.NotEmpty("PROFILES_CACHE_TYPE", envs.ProfilesCacheType))
switch typ := envs.ProfilesCacheType; typ {
case
profileCacheTypeDefault,
profileCacheTypeOpaque,
"":
default:
err = fmt.Errorf("env PROFILES_CACHE_TYPE: %w: %q", errors.ErrBadEnumValue, typ)
errs = append(errs, err)
}
return errors.Join(errs...)
}

View File

@@ -5,16 +5,21 @@ import (
"net/http"
"github.com/AdguardTeam/AdGuardDNS/internal/agdhttp"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil/httputil"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// ErrDebugPanic is a default error for panic handler.
const ErrDebugPanic errors.Error = "debug panic"
// Path pattern constants.
const (
PathPatternDNSDBCSV = "/dnsdb/csv"
PathPatternDebugAPICache = "/debug/api/cache/clear"
PathPatternDebugAPIRefresh = "/debug/api/refresh"
PathPatternDebugPanic = "/debug/panic"
PathPatternHealthCheck = "/health-check"
PathPatternMetrics = "/metrics"
)
@@ -24,6 +29,7 @@ const (
routePatternDNSDBCSV = http.MethodPost + " " + PathPatternDNSDBCSV
routePatternDebugAPICache = http.MethodPost + " " + PathPatternDebugAPICache
routePatternDebugAPIRefresh = http.MethodPost + " " + PathPatternDebugAPIRefresh
routePatternDebugPanic = http.MethodPost + " " + PathPatternDebugPanic
routePatternHealthCheck = http.MethodGet + " " + PathPatternHealthCheck
routePatternMetrics = http.MethodGet + " " + PathPatternMetrics
)
@@ -47,6 +53,7 @@ func (svc *Service) route(c *Config) {
infoLogMw := httputil.NewLogMiddleware(l, slog.LevelInfo)
router.Handle(routePatternDebugAPIRefresh, infoLogMw.Wrap(svc.refrHdlr))
router.Handle(routePatternDebugAPICache, infoLogMw.Wrap(svc.cacheHdlr))
router.Handle(routePatternDebugPanic, infoLogMw.Wrap(httputil.PanicHandler(ErrDebugPanic)))
}
if srv := svc.servers[c.DNSDBAddr]; srv != nil {

View File

@@ -2,6 +2,7 @@ package dnscheck
import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"log/slog"
@@ -14,6 +15,7 @@ import (
"github.com/AdguardTeam/AdGuardDNS/internal/agd"
"github.com/AdguardTeam/AdGuardDNS/internal/agdhttp"
"github.com/AdguardTeam/AdGuardDNS/internal/dnsmsg"
"github.com/AdguardTeam/AdGuardDNS/internal/dnsserver"
"github.com/AdguardTeam/AdGuardDNS/internal/errcoll"
"github.com/AdguardTeam/AdGuardDNS/internal/remotekv"
"github.com/AdguardTeam/AdGuardDNS/internal/remotekv/consulkv"
@@ -113,7 +115,8 @@ func NewRemoteKV(c *RemoteKVConfig) (dc *RemoteKV) {
// type check
var _ Interface = (*RemoteKV)(nil)
// Check implements the Interface interface for *RemoteKV.
// Check implements the Interface interface for *RemoteKV. ctx must contain
// request info (retrieved by [dnsserver.MustRequestInfoFromContext]).
func (dc *RemoteKV) Check(
ctx context.Context,
req *dns.Msg,
@@ -142,7 +145,7 @@ func (dc *RemoteKV) Check(
return dc.resp(ri, req)
}
inf := dc.newInfo(ri)
inf := dc.newInfo(ctx, ri)
b, err := json.Marshal(inf)
if err != nil {
return nil, fmt.Errorf("encoding value for key %q for remote kv: %w", randomID, err)
@@ -178,8 +181,9 @@ const (
)
// newInfo returns an information record with all available data about the
// server and the request. ri must not be nil.
func (dc *RemoteKV) newInfo(ri *agd.RequestInfo) (inf *info) {
// server and the request. ri must not be nil. ctx must contain request info
// (retrieved by [dnsserver.MustRequestInfoFromContext]).
func (dc *RemoteKV) newInfo(ctx context.Context, ri *agd.RequestInfo) (inf *info) {
srvInfo := ri.ServerInfo
srvType := serverTypePublic
@@ -188,15 +192,16 @@ func (dc *RemoteKV) newInfo(ri *agd.RequestInfo) (inf *info) {
}
inf = &info{
ClientIP: ri.RemoteIP,
ServerGroupName: srvInfo.GroupName,
ServerName: srvInfo.Name,
ServerType: srvType,
Protocol: srvInfo.Protocol.String(),
NodeLocation: dc.nodeLocation,
NodeName: dc.nodeName,
ClientIP: ri.RemoteIP,
Protocol: srvInfo.Protocol.String(),
TLSCurveID: tlsCurveID(ctx),
}
if p, d := ri.DeviceData(); p != nil {
@@ -207,6 +212,23 @@ func (dc *RemoteKV) newInfo(ri *agd.RequestInfo) (inf *info) {
return inf
}
// tlsCurveID returns the TLS curve ID string representation from the request
// context. ctx must contain request info (retrieved by
// [dnsserver.MustRequestInfoFromContext]).
func tlsCurveID(ctx context.Context) (curveIDStr string) {
srvReqInfo := dnsserver.MustRequestInfoFromContext(ctx)
if srvReqInfo.TLS == nil {
return ""
}
curveID := srvReqInfo.TLS.CurveID
if curveID != tls.CurveID(0) {
return curveID.String()
}
return ""
}
// resp returns the corresponding response.
//
// TODO(e.burkov): Inspect the reason for using different message constructors
@@ -343,7 +365,8 @@ type info struct {
ServerName agd.ServerName `json:"server_name"`
ServerType serverType `json:"server_type"`
Protocol string `json:"protocol"`
NodeLocation string `json:"node_location"`
NodeName string `json:"node_name"`
Protocol string `json:"protocol"`
TLSCurveID string `json:"tls_curve_id"`
}

View File

@@ -2,6 +2,7 @@ package dnscheck_test
import (
"context"
"crypto/tls"
"encoding/json"
"net"
"net/http"
@@ -16,6 +17,7 @@ import (
"github.com/AdguardTeam/AdGuardDNS/internal/agdtest"
"github.com/AdguardTeam/AdGuardDNS/internal/dnscheck"
"github.com/AdguardTeam/AdGuardDNS/internal/dnsmsg"
"github.com/AdguardTeam/AdGuardDNS/internal/dnsserver"
"github.com/AdguardTeam/AdGuardDNS/internal/remotekv"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil/urlutil"
@@ -44,6 +46,7 @@ func TestConsul_ServeHTTP(t *testing.T) {
"node_name": "some-node-name",
"client_ip": "1.2.3.4",
"server_type": "private",
"tls_curve_id": "X25519",
}
conf := &dnscheck.RemoteKVConfig{
@@ -59,6 +62,11 @@ func TestConsul_ServeHTTP(t *testing.T) {
dnsCk := dnscheck.NewRemoteKV(conf)
ctx := context.Background()
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLS: &tls.ConnectionState{
CurveID: tls.X25519,
},
})
var resp *dns.Msg
resp, err := dnsCk.Check(
@@ -187,6 +195,11 @@ func TestConsul_Check(t *testing.T) {
dnsCk := dnscheck.NewRemoteKV(conf)
ctx := context.Background()
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLS: &tls.ConnectionState{
CurveID: tls.X25519,
},
})
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

View File

@@ -2,6 +2,7 @@ package dnsserver
import (
"context"
"crypto/tls"
"fmt"
"net/url"
"time"
@@ -78,6 +79,11 @@ func MustServerInfoFromContext(ctx context.Context) (si *ServerInfo) {
// RequestInfo is a structure that contains basic request information. It is
// attached to every context.Context linked to processing a DNS request.
type RequestInfo struct {
// TLS is the TLS connection state. It is set only if the protocol of the
// server is either DoQ, DoT or DoH. It must not be nil if the protocol is
// DoQ or DoT.
TLS *tls.ConnectionState
// URL is the request URL. It is set only if the protocol of the server is
// DoH.
URL *url.URL
@@ -88,13 +94,6 @@ type RequestInfo struct {
// StartTime is the request's start time. It's never zero value.
StartTime time.Time
// TLSServerName is the original, non-lowercased server name field of the
// client's TLS hello request. It is set only if the protocol of the server
// is either DoQ, DoT or DoH.
//
// TODO(ameshkov): use r.TLS with DoH3 (see addRequestInfo).
TLSServerName string
}
// ContextWithRequestInfo attaches RequestInfo to the specified context. ri

View File

@@ -27,8 +27,8 @@ func NewDefaultHandlerWithCount(recordsCount int) (h dnsserver.Handler) {
// Check that necessary context keys are set.
si := dnsserver.MustServerInfoFromContext(ctx)
ri := dnsserver.MustRequestInfoFromContext(ctx)
if si.Proto.IsStdEncrypted() && ri.TLSServerName == "" {
return errors.Error("client info does not contain server name")
if si.Proto.IsStdEncrypted() && ri.TLS == nil {
return errors.Error("client info does not contain tls connection info")
}
ans := make(SectionAnswer, 0, recordsCount)

View File

@@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardDNS/internal/dnsserver
go 1.25.5
require (
github.com/AdguardTeam/golibs v0.35.3
github.com/AdguardTeam/golibs v0.35.4
github.com/ameshkov/dnscrypt/v2 v2.4.0
github.com/ameshkov/dnsstamps v1.0.3
github.com/bluele/gcache v0.0.2
@@ -12,7 +12,7 @@ require (
github.com/panjf2000/ants/v2 v2.11.3
github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible
github.com/prometheus/client_golang v1.23.2
github.com/quic-go/quic-go v0.56.0
github.com/quic-go/quic-go v0.57.1
github.com/stretchr/testify v1.11.1
golang.org/x/net v0.47.0
golang.org/x/sys v0.38.0
@@ -28,7 +28,7 @@ require (
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.2 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
go.uber.org/mock v0.6.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect

View File

@@ -1,4 +1,5 @@
github.com/AdguardTeam/golibs v0.35.3 h1:DI0ffHyL3tFZ2UBEji3Aah7IvFwM5nY5yZoGvs1bnPY=
github.com/AdguardTeam/golibs v0.35.4 h1:7uvSIurqlyiKTSwTlefbOM8Bp7swgI+yb3+gL9al1Ac=
github.com/AdguardTeam/golibs v0.35.4/go.mod h1:meFdRqMtG/PLW6LD20MYAlcRbwAVowlbunHgE17xz9s=
github.com/ameshkov/dnscrypt/v2 v2.4.0 h1:if6ZG2cuQmcP2TwSY+D0+8+xbPfoatufGlOQTMNkI9o=
github.com/ameshkov/dnscrypt/v2 v2.4.0/go.mod h1:WpEFV2uhebXb8Jhes/5/fSdpmhGV8TL22RDaeWwV6hI=
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
@@ -35,10 +36,13 @@ github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UH
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.2 h1:PcBAckGFTIHt2+L3I33uNRTlKTplNzFctXcWhPyAEN8=
github.com/prometheus/common v0.67.2/go.mod h1:63W3KZb1JOKgcjlIr64WW/LvFGAqKPj0atm+knVGEko=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.56.0 h1:q/TW+OLismmXAehgFLczhCDTYB3bFmua4D9lsNBWxvY=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10=
github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
@@ -52,14 +56,23 @@ go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -183,7 +183,8 @@ func (s *ServerDNS) acceptTCPMsg(
StartTime: time.Now(),
}
if cs, ok := conn.(tlsConnectionStater); ok {
ri.TLSServerName = cs.ConnectionState().ServerName
tlsConnState := cs.ConnectionState()
ri.TLS = &tlsConnState
}
reqCtx, reqCancel := s.requestContext(context.Background())

View File

@@ -563,12 +563,9 @@ func addRequestInfo(parent context.Context, r *http.Request) (ctx context.Contex
ctx = parent
ri := &RequestInfo{
StartTime: time.Now(),
TLS: r.TLS,
URL: netutil.CloneURL(r.URL),
}
if r.TLS != nil {
ri.TLSServerName = r.TLS.ServerName
StartTime: time.Now(),
}
if username, pass, ok := r.BasicAuth(); ok {

View File

@@ -106,7 +106,11 @@ func TestServerHTTPS_integration_serveRequests(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tlsConfig := dnsservertest.CreateServerTLSConfig("example.org")
var tlsConfig *tls.Config
if tc.tls {
tlsConfig = dnsservertest.CreateServerTLSConfig("example.org")
}
srv, err := dnsservertest.RunLocalHTTPSServer(
dnsservertest.NewDefaultHandler(),
tlsConfig,

View File

@@ -364,9 +364,10 @@ func (s *ServerQUIC) serveQUICConn(ctx context.Context, conn *quic.Conn) (err er
return err
}
tlsConnState := conn.ConnectionState().TLS
ri := &RequestInfo{
StartTime: time.Now(),
TLSServerName: conn.ConnectionState().TLS.ServerName,
TLS: &tlsConnState,
StartTime: time.Now(),
}
reqCtx, reqCancel := s.requestContext(context.Background())

View File

@@ -359,10 +359,9 @@ func TestService_Wrap(t *testing.T) {
clientAddr,
)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
StartTime: time.Now(),
TLSServerName: dnssvctest.DeviceIDSrvName,
})
ctx = dnsserver.ContextWithRequestInfo(ctx, dnssvctest.NewRequestInfo(
dnssvctest.DeviceIDSrvName,
))
err := svc.Handle(ctx, dnssvctest.ServerGroupName, dnssvctest.ServerName, rw, req)
require.NoError(t, err)
@@ -428,10 +427,9 @@ func TestService_Wrap(t *testing.T) {
clientAddr,
)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
StartTime: time.Now(),
TLSServerName: dnssvctest.DeviceIDSrvName,
})
ctx = dnsserver.ContextWithRequestInfo(ctx, dnssvctest.NewRequestInfo(
dnssvctest.DeviceIDSrvName,
))
err := svc.Handle(ctx, dnssvctest.ServerGroupName, dnssvctest.ServerName, rw, req)
require.NoError(t, err)

View File

@@ -216,9 +216,9 @@ func TestDefault_Find_byHumanID(t *testing.T) {
})
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: extIDStr + "." + dnssvctest.DomainForDevices,
})
ctx = dnsserver.ContextWithRequestInfo(ctx, dnssvctest.NewRequestInfo(
extIDStr+"."+dnssvctest.DomainForDevices,
))
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
require.Equal(t, resAuto, got)

View File

@@ -125,16 +125,22 @@ func (f *Default) deviceDataFromEncrypted(
ctx context.Context,
srvReqInfo *dnsserver.RequestInfo,
) (dd deviceData, err error) {
var customDomain string
var requiredProfileIDs []agd.ProfileID
if cliSrvName := strings.ToLower(srvReqInfo.TLSServerName); cliSrvName != "" {
customDomain, requiredProfileIDs = f.customDomainDB.Match(ctx, cliSrvName)
if customDomain != "" {
f.metrics.IncrementCustomDomainRequests(ctx, customDomain)
}
cliSrvName := ""
if srvReqInfo.TLS != nil {
cliSrvName = srvReqInfo.TLS.ServerName
}
dd, err = f.deviceDataFromSrvReqInfo(ctx, srvReqInfo, customDomain)
customDomain := ""
var requiredProfileIDs []agd.ProfileID
if cliSrvName != "" {
customDomain, requiredProfileIDs = f.customDomainDB.Match(ctx, strings.ToLower(cliSrvName))
}
if customDomain != "" {
f.metrics.IncrementCustomDomainRequests(ctx, customDomain)
}
dd, err = f.deviceDataFromSrvReqInfo(ctx, srvReqInfo, customDomain, cliSrvName)
if err != nil {
return nil, fmt.Errorf("extracting device data: %w", err)
}
@@ -159,11 +165,12 @@ func (f *Default) deviceDataFromEncrypted(
// Any returned errors will have the underlying type of [*deviceDataError].
//
// If customDomain is not empty, it must be a domain name or wildcard matching
// srvReqInfo.TLSServerName.
// srvReqInfo.TLS.ServerName. srvReqInfo must not be nil.
func (f *Default) deviceDataFromSrvReqInfo(
ctx context.Context,
srvReqInfo *dnsserver.RequestInfo,
customDomain string,
cliSrvName string,
) (dd deviceData, err error) {
if f.srv.Protocol == agd.ProtoDoH {
dd, err = f.deviceDataForDoH(srvReqInfo)
@@ -196,7 +203,7 @@ func (f *Default) deviceDataFromSrvReqInfo(
customDomain = strings.TrimPrefix(customDomain, "*.")
dd, err = f.deviceDataFromCliSrvName(ctx, srvReqInfo.TLSServerName, customDomain)
dd, err = f.deviceDataFromCliSrvName(ctx, cliSrvName, customDomain)
if err != nil {
return nil, newDeviceDataError(err, "tls server name")
}

View File

@@ -2,6 +2,7 @@ package devicefinder_test
import (
"context"
"crypto/tls"
"net/url"
"path"
"slices"
@@ -104,11 +105,15 @@ func TestDefault_Find_DoHAuth(t *testing.T) {
ProfileDB: profDB,
})
tlsConnState := &tls.ConnectionState{
ServerName: dnssvctest.DomainForDevices,
}
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: dnssvctest.DomainForDevices,
URL: tc.reqURL,
Userinfo: tc.reqURL.User,
TLS: tlsConnState,
URL: tc.reqURL,
Userinfo: tc.reqURL.User,
})
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
@@ -198,9 +203,12 @@ func TestDefault_Find_DoHAuthOnly(t *testing.T) {
DeviceDomains: []string{dnssvctest.DomainForDevices},
})
tlsConnState := &tls.ConnectionState{
ServerName: tc.cliSrvName,
}
srvReqInfo := &dnsserver.RequestInfo{
TLSServerName: tc.cliSrvName,
URL: tc.reqURL,
TLS: tlsConnState,
URL: tc.reqURL,
}
if tc.reqURL != nil {
srvReqInfo.Userinfo = tc.reqURL.User
@@ -297,10 +305,13 @@ func TestDefault_Find_DoH(t *testing.T) {
ProfileDB: profDB,
})
tlsConnState := &tls.ConnectionState{
ServerName: dnssvctest.DomainForDevices,
}
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: dnssvctest.DomainForDevices,
URL: tc.reqURL,
TLS: tlsConnState,
URL: tc.reqURL,
})
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
@@ -388,10 +399,14 @@ func TestDefault_Find_stdEncrypted(t *testing.T) {
DeviceDomains: tc.deviceDomains,
})
tlsConnState := &tls.ConnectionState{
ServerName: tc.cliSrvName,
}
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: tc.cliSrvName,
URL: sd.reqURL,
TLS: tlsConnState,
URL: sd.reqURL,
})
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
@@ -559,9 +574,7 @@ func TestDefault_Find_customDomainDoT(t *testing.T) {
})
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: tc.cliSrvName,
})
ctx = dnsserver.ContextWithRequestInfo(ctx, dnssvctest.NewRequestInfo(tc.cliSrvName))
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
assertEqualResult(t, tc.wantRes, got)

View File

@@ -3,6 +3,7 @@ package devicefinder_test
import (
"cmp"
"context"
"crypto/tls"
"net/netip"
"net/url"
"os"
@@ -356,11 +357,9 @@ func BenchmarkDefault(b *testing.B) {
ProfileDB: profDB,
DeviceDomains: []string{dnssvctest.DomainForDevices},
},
req: reqNormal,
srvReqInfo: &dnsserver.RequestInfo{
TLSServerName: dnssvctest.DeviceIDSrvName,
},
name: "dot",
req: reqNormal,
srvReqInfo: dnssvctest.NewRequestInfo(dnssvctest.DeviceIDSrvName),
name: "dot",
}, {
conf: &devicefinder.Config{
ProfileDB: profDB,
@@ -368,7 +367,9 @@ func BenchmarkDefault(b *testing.B) {
},
req: reqNormal,
srvReqInfo: &dnsserver.RequestInfo{
TLSServerName: dnssvctest.DeviceIDSrvName,
TLS: &tls.ConnectionState{
ServerName: dnssvctest.DeviceIDSrvName,
},
URL: &url.URL{
Path: dnsserver.PathDoH,
},
@@ -381,7 +382,9 @@ func BenchmarkDefault(b *testing.B) {
},
req: reqNormal,
srvReqInfo: &dnsserver.RequestInfo{
TLSServerName: dnssvctest.DomainForDevices,
TLS: &tls.ConnectionState{
ServerName: dnssvctest.DomainForDevices,
},
URL: &url.URL{
Path: path.Join(dnsserver.PathDoH, dnssvctest.DeviceIDStr),
},
@@ -441,14 +444,14 @@ func BenchmarkDefault(b *testing.B) {
// Most recent results:
//
// goos: linux
// goarch: amd64
// pkg: github.com/AdguardTeam/AdGuardDNS/internal/dnssvc/internal/devicefinder
// cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
// BenchmarkDefault/dot-16 2654976 406.5 ns/op 32 B/op 2 allocs/op
// BenchmarkDefault/doh_domain-16 1560818 758.5 ns/op 80 B/op 4 allocs/op
// BenchmarkDefault/doh_path-16 1922390 639.2 ns/op 96 B/op 4 allocs/op
// BenchmarkDefault/dns_edns-16 3430594 396.1 ns/op 40 B/op 3 allocs/op
// BenchmarkDefault/dns_laddr-16 6179818 206.0 ns/op 16 B/op 1 allocs/op
// BenchmarkDefault/dns_raddr-16 6360699 184.4 ns/op 16 B/op 1 allocs/op
// goos: darwin
// goarch: arm64
// pkg: github.com/AdguardTeam/AdGuardDNS/internal/dnssvc/internal/devicefinder
// cpu: Apple M1 Pro
// BenchmarkDefault/dot-8 6804558 164.8 ns/op 32 B/op 2 allocs/op
// BenchmarkDefault/doh_domain-8 5155173 233.5 ns/op 80 B/op 4 allocs/op
// BenchmarkDefault/doh_path-8 6002018 197.6 ns/op 96 B/op 4 allocs/op
// BenchmarkDefault/dns_edns-8 12959406 91.83 ns/op 40 B/op 3 allocs/op
// BenchmarkDefault/dns_laddr-8 26600607 44.65 ns/op 16 B/op 1 allocs/op
// BenchmarkDefault/dns_raddr-8 28741998 42.14 ns/op 16 B/op 1 allocs/op
}

View File

@@ -58,9 +58,9 @@ func TestDefault_Find_humanID(t *testing.T) {
})
ctx := testutil.ContextWithTimeout(t, dnssvctest.Timeout)
ctx = dnsserver.ContextWithRequestInfo(ctx, &dnsserver.RequestInfo{
TLSServerName: tc.in + "." + dnssvctest.DomainForDevices,
})
ctx = dnsserver.ContextWithRequestInfo(ctx, dnssvctest.NewRequestInfo(
tc.in+"."+dnssvctest.DomainForDevices,
))
got := df.Find(ctx, reqNormal, dnssvctest.ClientAddrPort, dnssvctest.ServerAddrPort)
assertEqualResult(t, tc.wantRes, got)

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/AdguardTeam/AdGuardDNS/internal/agd"
"github.com/AdguardTeam/AdGuardDNS/internal/dnsserver"
"github.com/AdguardTeam/AdGuardDNS/internal/filter"
"github.com/miekg/dns"
)
@@ -169,3 +170,13 @@ func NewServer(
return srv
}
// NewRequestInfo returns a new *dnsserver.RequestInfo for tests.
func NewRequestInfo(tlsSrvName string) (ri *dnsserver.RequestInfo) {
return &dnsserver.RequestInfo{
TLS: &tls.ConnectionState{
ServerName: tlsSrvName,
},
StartTime: time.Now(),
}
}

View File

@@ -216,7 +216,12 @@ func tagsFromCtx(ctx context.Context) (tags sentryTags) {
}
if ri, ok := dnsserver.RequestInfoFromContext(ctx); ok {
tags["dns_client_tls_server_name"] = toASCII(ri.TLSServerName)
tlsSrvName := ""
if ri.TLS != nil {
tlsSrvName = ri.TLS.ServerName
}
tags["dns_client_tls_server_name"] = toASCII(tlsSrvName)
if ri.URL != nil {
// Provide only the path and the query to fit into Sentry's 200
// characters limit.

View File

@@ -65,4 +65,8 @@ type Config struct {
// the purposes of custom ratelimiting. Responses over this estimate are
// counted as several responses. It must be positive.
ResponseSizeEstimate datasize.ByteSize
// Opaque determines whether the profile cache will use the protobuf opaque
// API.
Opaque bool
}

View File

@@ -6,7 +6,6 @@ import (
"log/slog"
"maps"
"net/netip"
"path/filepath"
"slices"
"sync"
"time"
@@ -14,6 +13,7 @@ import (
"github.com/AdguardTeam/AdGuardDNS/internal/agd"
"github.com/AdguardTeam/AdGuardDNS/internal/errcoll"
"github.com/AdguardTeam/AdGuardDNS/internal/profiledb/internal"
"github.com/AdguardTeam/AdGuardDNS/internal/profiledb/internal/filecacheopb"
"github.com/AdguardTeam/AdGuardDNS/internal/profiledb/internal/filecachepb"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/logutil/slogutil"
@@ -127,7 +127,15 @@ func New(c *Config) (db *Default, err error) {
var cacheStorage internal.FileCacheStorage
if c.CacheFilePath == "none" {
cacheStorage = internal.EmptyFileCacheStorage{}
} else if ext := filepath.Ext(c.CacheFilePath); ext == ".pb" {
} else if c.Opaque {
cacheStorage = filecacheopb.New(&filecacheopb.Config{
Logger: c.Logger.With("cache_type", "opb"),
BaseCustomLogger: c.BaseCustomLogger,
ProfileAccessConstructor: c.ProfileAccessConstructor,
CacheFilePath: c.CacheFilePath,
ResponseSizeEstimate: c.ResponseSizeEstimate,
})
} else {
cacheStorage = filecachepb.New(&filecachepb.Config{
Logger: c.Logger.With("cache_type", "pb"),
BaseCustomLogger: c.BaseCustomLogger,
@@ -135,8 +143,6 @@ func New(c *Config) (db *Default, err error) {
CacheFilePath: c.CacheFilePath,
ResponseSizeEstimate: c.ResponseSizeEstimate,
})
} else {
return nil, fmt.Errorf("file %q is not protobuf", c.CacheFilePath)
}
db = &Default{

View File

@@ -1433,6 +1433,7 @@ func (x *FilterConfig) GetSafeBrowsing() *FilterConfig_SafeBrowsing {
return nil
}
// Deprecated: Marked as deprecated in fc.proto.
func (x *FilterConfig) GetCategoryFilter() *FilterConfig_CategoryFilter {
if x != nil {
return x.xxx_hidden_CategoryFilter
@@ -1456,6 +1457,7 @@ func (x *FilterConfig) SetSafeBrowsing(v *FilterConfig_SafeBrowsing) {
x.xxx_hidden_SafeBrowsing = v
}
// Deprecated: Marked as deprecated in fc.proto.
func (x *FilterConfig) SetCategoryFilter(v *FilterConfig_CategoryFilter) {
x.xxx_hidden_CategoryFilter = v
}
@@ -1488,6 +1490,7 @@ func (x *FilterConfig) HasSafeBrowsing() bool {
return x.xxx_hidden_SafeBrowsing != nil
}
// Deprecated: Marked as deprecated in fc.proto.
func (x *FilterConfig) HasCategoryFilter() bool {
if x == nil {
return false
@@ -1511,6 +1514,7 @@ func (x *FilterConfig) ClearSafeBrowsing() {
x.xxx_hidden_SafeBrowsing = nil
}
// Deprecated: Marked as deprecated in fc.proto.
func (x *FilterConfig) ClearCategoryFilter() {
x.xxx_hidden_CategoryFilter = nil
}
@@ -1518,10 +1522,11 @@ func (x *FilterConfig) ClearCategoryFilter() {
type FilterConfig_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
Custom *FilterConfig_Custom
Parental *FilterConfig_Parental
RuleList *FilterConfig_RuleList
SafeBrowsing *FilterConfig_SafeBrowsing
Custom *FilterConfig_Custom
Parental *FilterConfig_Parental
RuleList *FilterConfig_RuleList
SafeBrowsing *FilterConfig_SafeBrowsing
// Deprecated: Marked as deprecated in fc.proto.
CategoryFilter *FilterConfig_CategoryFilter
}
@@ -2670,13 +2675,14 @@ func (b0 FilterConfig_Custom_builder) Build() *FilterConfig_Custom {
}
type FilterConfig_Parental struct {
state protoimpl.MessageState `protogen:"opaque.v1"`
xxx_hidden_PauseSchedule *FilterConfig_Schedule `protobuf:"bytes,1,opt,name=pause_schedule,json=pauseSchedule,proto3"`
xxx_hidden_BlockedServices []string `protobuf:"bytes,2,rep,name=blocked_services,json=blockedServices,proto3"`
xxx_hidden_Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3"`
xxx_hidden_AdultBlockingEnabled bool `protobuf:"varint,4,opt,name=adult_blocking_enabled,json=adultBlockingEnabled,proto3"`
xxx_hidden_SafeSearchGeneralEnabled bool `protobuf:"varint,5,opt,name=safe_search_general_enabled,json=safeSearchGeneralEnabled,proto3"`
xxx_hidden_SafeSearchYoutubeEnabled bool `protobuf:"varint,6,opt,name=safe_search_youtube_enabled,json=safeSearchYoutubeEnabled,proto3"`
state protoimpl.MessageState `protogen:"opaque.v1"`
xxx_hidden_PauseSchedule *FilterConfig_Schedule `protobuf:"bytes,1,opt,name=pause_schedule,json=pauseSchedule,proto3"`
xxx_hidden_CategoryFilter *FilterConfig_CategoryFilter `protobuf:"bytes,7,opt,name=category_filter,json=categoryFilter,proto3"`
xxx_hidden_BlockedServices []string `protobuf:"bytes,2,rep,name=blocked_services,json=blockedServices,proto3"`
xxx_hidden_Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3"`
xxx_hidden_AdultBlockingEnabled bool `protobuf:"varint,4,opt,name=adult_blocking_enabled,json=adultBlockingEnabled,proto3"`
xxx_hidden_SafeSearchGeneralEnabled bool `protobuf:"varint,5,opt,name=safe_search_general_enabled,json=safeSearchGeneralEnabled,proto3"`
xxx_hidden_SafeSearchYoutubeEnabled bool `protobuf:"varint,6,opt,name=safe_search_youtube_enabled,json=safeSearchYoutubeEnabled,proto3"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -2713,6 +2719,13 @@ func (x *FilterConfig_Parental) GetPauseSchedule() *FilterConfig_Schedule {
return nil
}
func (x *FilterConfig_Parental) GetCategoryFilter() *FilterConfig_CategoryFilter {
if x != nil {
return x.xxx_hidden_CategoryFilter
}
return nil
}
func (x *FilterConfig_Parental) GetBlockedServices() []string {
if x != nil {
return x.xxx_hidden_BlockedServices
@@ -2752,6 +2765,10 @@ func (x *FilterConfig_Parental) SetPauseSchedule(v *FilterConfig_Schedule) {
x.xxx_hidden_PauseSchedule = v
}
func (x *FilterConfig_Parental) SetCategoryFilter(v *FilterConfig_CategoryFilter) {
x.xxx_hidden_CategoryFilter = v
}
func (x *FilterConfig_Parental) SetBlockedServices(v []string) {
x.xxx_hidden_BlockedServices = v
}
@@ -2779,14 +2796,26 @@ func (x *FilterConfig_Parental) HasPauseSchedule() bool {
return x.xxx_hidden_PauseSchedule != nil
}
func (x *FilterConfig_Parental) HasCategoryFilter() bool {
if x == nil {
return false
}
return x.xxx_hidden_CategoryFilter != nil
}
func (x *FilterConfig_Parental) ClearPauseSchedule() {
x.xxx_hidden_PauseSchedule = nil
}
func (x *FilterConfig_Parental) ClearCategoryFilter() {
x.xxx_hidden_CategoryFilter = nil
}
type FilterConfig_Parental_builder struct {
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
PauseSchedule *FilterConfig_Schedule
CategoryFilter *FilterConfig_CategoryFilter
BlockedServices []string
Enabled bool
AdultBlockingEnabled bool
@@ -2799,6 +2828,7 @@ func (b0 FilterConfig_Parental_builder) Build() *FilterConfig_Parental {
b, x := &b0, m0
_, _ = b, x
x.xxx_hidden_PauseSchedule = b.PauseSchedule
x.xxx_hidden_CategoryFilter = b.CategoryFilter
x.xxx_hidden_BlockedServices = b.BlockedServices
x.xxx_hidden_Enabled = b.Enabled
x.xxx_hidden_AdultBlockingEnabled = b.AdultBlockingEnabled
@@ -3396,19 +3426,19 @@ const file_fc_proto_rawDesc = "" +
"\fStatePending\x122\n" +
"\x06expire\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x06expire\x12&\n" +
"\x0fwell_known_path\x18\x02 \x01(\tR\rwellKnownPathB\a\n" +
"\x05state\"\xf2\n" +
"\n" +
"\x05state\"\xc2\v\n" +
"\fFilterConfig\x121\n" +
"\x06custom\x18\x01 \x01(\v2\x19.fcpb.FilterConfig.CustomR\x06custom\x127\n" +
"\bparental\x18\x02 \x01(\v2\x1b.fcpb.FilterConfig.ParentalR\bparental\x128\n" +
"\trule_list\x18\x03 \x01(\v2\x1b.fcpb.FilterConfig.RuleListR\bruleList\x12D\n" +
"\rsafe_browsing\x18\x04 \x01(\v2\x1f.fcpb.FilterConfig.SafeBrowsingR\fsafeBrowsing\x12J\n" +
"\x0fcategory_filter\x18\x05 \x01(\v2!.fcpb.FilterConfig.CategoryFilterR\x0ecategoryFilter\x1aD\n" +
"\rsafe_browsing\x18\x04 \x01(\v2\x1f.fcpb.FilterConfig.SafeBrowsingR\fsafeBrowsing\x12N\n" +
"\x0fcategory_filter\x18\x05 \x01(\v2!.fcpb.FilterConfig.CategoryFilterB\x02\x18\x01R\x0ecategoryFilter\x1aD\n" +
"\x06Custom\x12\x14\n" +
"\x05rules\x18\x03 \x03(\tR\x05rules\x12\x18\n" +
"\aenabled\x18\x04 \x01(\bR\aenabledJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03\x1a\xc7\x02\n" +
"\aenabled\x18\x04 \x01(\bR\aenabledJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03\x1a\x93\x03\n" +
"\bParental\x12B\n" +
"\x0epause_schedule\x18\x01 \x01(\v2\x1b.fcpb.FilterConfig.ScheduleR\rpauseSchedule\x12)\n" +
"\x0epause_schedule\x18\x01 \x01(\v2\x1b.fcpb.FilterConfig.ScheduleR\rpauseSchedule\x12J\n" +
"\x0fcategory_filter\x18\a \x01(\v2!.fcpb.FilterConfig.CategoryFilterR\x0ecategoryFilter\x12)\n" +
"\x10blocked_services\x18\x02 \x03(\tR\x0fblockedServices\x12\x18\n" +
"\aenabled\x18\x03 \x01(\bR\aenabled\x124\n" +
"\x16adult_blocking_enabled\x18\x04 \x01(\bR\x14adultBlockingEnabled\x12=\n" +
@@ -3539,19 +3569,20 @@ var file_fc_proto_depIdxs = []int32{
24, // 33: fcpb.CustomDomainConfig.StateCurrent.not_after:type_name -> google.protobuf.Timestamp
24, // 34: fcpb.CustomDomainConfig.StatePending.expire:type_name -> google.protobuf.Timestamp
19, // 35: fcpb.FilterConfig.Parental.pause_schedule:type_name -> fcpb.FilterConfig.Schedule
20, // 36: fcpb.FilterConfig.Schedule.week:type_name -> fcpb.FilterConfig.WeeklySchedule
5, // 37: fcpb.FilterConfig.WeeklySchedule.mon:type_name -> fcpb.DayInterval
5, // 38: fcpb.FilterConfig.WeeklySchedule.tue:type_name -> fcpb.DayInterval
5, // 39: fcpb.FilterConfig.WeeklySchedule.wed:type_name -> fcpb.DayInterval
5, // 40: fcpb.FilterConfig.WeeklySchedule.thu:type_name -> fcpb.DayInterval
5, // 41: fcpb.FilterConfig.WeeklySchedule.fri:type_name -> fcpb.DayInterval
5, // 42: fcpb.FilterConfig.WeeklySchedule.sat:type_name -> fcpb.DayInterval
5, // 43: fcpb.FilterConfig.WeeklySchedule.sun:type_name -> fcpb.DayInterval
44, // [44:44] is the sub-list for method output_type
44, // [44:44] is the sub-list for method input_type
44, // [44:44] is the sub-list for extension type_name
44, // [44:44] is the sub-list for extension extendee
0, // [0:44] is the sub-list for field type_name
23, // 36: fcpb.FilterConfig.Parental.category_filter:type_name -> fcpb.FilterConfig.CategoryFilter
20, // 37: fcpb.FilterConfig.Schedule.week:type_name -> fcpb.FilterConfig.WeeklySchedule
5, // 38: fcpb.FilterConfig.WeeklySchedule.mon:type_name -> fcpb.DayInterval
5, // 39: fcpb.FilterConfig.WeeklySchedule.tue:type_name -> fcpb.DayInterval
5, // 40: fcpb.FilterConfig.WeeklySchedule.wed:type_name -> fcpb.DayInterval
5, // 41: fcpb.FilterConfig.WeeklySchedule.thu:type_name -> fcpb.DayInterval
5, // 42: fcpb.FilterConfig.WeeklySchedule.fri:type_name -> fcpb.DayInterval
5, // 43: fcpb.FilterConfig.WeeklySchedule.sat:type_name -> fcpb.DayInterval
5, // 44: fcpb.FilterConfig.WeeklySchedule.sun:type_name -> fcpb.DayInterval
45, // [45:45] is the sub-list for method output_type
45, // [45:45] is the sub-list for method input_type
45, // [45:45] is the sub-list for extension type_name
45, // [45:45] is the sub-list for extension extendee
0, // [0:45] is the sub-list for field type_name
}
func init() { file_fc_proto_init() }

View File

@@ -97,6 +97,7 @@ message FilterConfig {
message Parental {
Schedule pause_schedule = 1;
CategoryFilter category_filter = 7;
repeated string blocked_services = 2;
bool enabled = 3;
bool adult_blocking_enabled = 4;
@@ -139,7 +140,7 @@ message FilterConfig {
Parental parental = 2;
RuleList rule_list = 3;
SafeBrowsing safe_browsing = 4;
CategoryFilter category_filter = 5;
CategoryFilter category_filter = 5 [deprecated=true];
}
message DayInterval {

View File

@@ -173,12 +173,19 @@ func configClientToInternal(
}
// categoryFilterToInternal converts filter config's protobuf category filter
// structure to internal one. If pbCatFlt is nil, returns a disabled config.
func categoryFilterToInternal(
pbCatFlt *fcpb.FilterConfig_CategoryFilter,
) (c *filter.ConfigCategories) {
// structure to internal one. If categories filter is not specified, returns a
// disabled config.
func categoryFilterToInternal(pbFltConf *fcpb.FilterConfig) (c *filter.ConfigCategories) {
pbCatFlt := pbFltConf.GetParental().GetCategoryFilter()
if pbCatFlt == nil {
return &filter.ConfigCategories{}
// TODO(d.kolyshev): Remove after moving deprecated profile categories
// in [internal/profiledb/internal.FileCacheVersion] 19.
//
//lint:ignore SA1019 Use deprecated field for compatibility.
pbCatFlt = pbFltConf.GetCategoryFilter()
if pbCatFlt == nil {
return &filter.ConfigCategories{}
}
}
// Consider the categories to have been prevalidated.
@@ -198,7 +205,7 @@ func configParentalToInternal(
parental := pbFltConf.GetParental()
return &filter.ConfigParental{
Categories: categoryFilterToInternal(pbFltConf.GetCategoryFilter()),
Categories: categoryFilterToInternal(pbFltConf),
PauseSchedule: schedule,
// Consider blocked-service IDs to have been prevalidated.
BlockedServices: agdprotobuf.UnsafelyConvertStrSlice[string, filter.BlockedServiceID](
@@ -615,8 +622,17 @@ func filterConfigToProtobuf(c *filter.ConfigClient) (fc *fcpb.FilterConfig) {
Enabled: c.Custom.Enabled,
}.Build()
categoryFilter := fcpb.FilterConfig_CategoryFilter_builder{
Ids: agdprotobuf.UnsafelyConvertStrSlice[
filter.CategoryID,
string,
](c.Parental.Categories.IDs),
Enabled: c.Parental.Categories.Enabled,
}.Build()
parental := fcpb.FilterConfig_Parental_builder{
PauseSchedule: scheduleToProtobuf(c.Parental.PauseSchedule),
PauseSchedule: scheduleToProtobuf(c.Parental.PauseSchedule),
CategoryFilter: categoryFilter,
BlockedServices: agdprotobuf.UnsafelyConvertStrSlice[filter.BlockedServiceID, string](
c.Parental.BlockedServices,
),
@@ -637,20 +653,11 @@ func filterConfigToProtobuf(c *filter.ConfigClient) (fc *fcpb.FilterConfig) {
NewlyRegisteredDomainsEnabled: c.SafeBrowsing.NewlyRegisteredDomainsEnabled,
}.Build()
categories := fcpb.FilterConfig_CategoryFilter_builder{
Ids: agdprotobuf.UnsafelyConvertStrSlice[
filter.CategoryID,
string,
](c.Parental.Categories.IDs),
Enabled: c.Parental.Categories.Enabled,
}.Build()
return fcpb.FilterConfig_builder{
Custom: custom,
Parental: parental,
RuleList: ruleList,
SafeBrowsing: safeBrowsing,
CategoryFilter: categories,
Custom: custom,
Parental: parental,
RuleList: ruleList,
SafeBrowsing: safeBrowsing,
}.Build()
}

View File

@@ -636,11 +636,12 @@ func (*CustomDomainConfig_StateCurrent_) isCustomDomainConfig_State() {}
func (*CustomDomainConfig_StatePending_) isCustomDomainConfig_State() {}
type FilterConfig struct {
state protoimpl.MessageState `protogen:"open.v1"`
Custom *FilterConfig_Custom `protobuf:"bytes,1,opt,name=custom,proto3" json:"custom,omitempty"`
Parental *FilterConfig_Parental `protobuf:"bytes,2,opt,name=parental,proto3" json:"parental,omitempty"`
RuleList *FilterConfig_RuleList `protobuf:"bytes,3,opt,name=rule_list,json=ruleList,proto3" json:"rule_list,omitempty"`
SafeBrowsing *FilterConfig_SafeBrowsing `protobuf:"bytes,4,opt,name=safe_browsing,json=safeBrowsing,proto3" json:"safe_browsing,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
Custom *FilterConfig_Custom `protobuf:"bytes,1,opt,name=custom,proto3" json:"custom,omitempty"`
Parental *FilterConfig_Parental `protobuf:"bytes,2,opt,name=parental,proto3" json:"parental,omitempty"`
RuleList *FilterConfig_RuleList `protobuf:"bytes,3,opt,name=rule_list,json=ruleList,proto3" json:"rule_list,omitempty"`
SafeBrowsing *FilterConfig_SafeBrowsing `protobuf:"bytes,4,opt,name=safe_browsing,json=safeBrowsing,proto3" json:"safe_browsing,omitempty"`
// Deprecated: Marked as deprecated in filecache.proto.
CategoryFilter *FilterConfig_CategoryFilter `protobuf:"bytes,5,opt,name=category_filter,json=categoryFilter,proto3" json:"category_filter,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
@@ -704,6 +705,7 @@ func (x *FilterConfig) GetSafeBrowsing() *FilterConfig_SafeBrowsing {
return nil
}
// Deprecated: Marked as deprecated in filecache.proto.
func (x *FilterConfig) GetCategoryFilter() *FilterConfig_CategoryFilter {
if x != nil {
return x.CategoryFilter
@@ -1458,13 +1460,14 @@ func (x *FilterConfig_Custom) GetEnabled() bool {
}
type FilterConfig_Parental struct {
state protoimpl.MessageState `protogen:"open.v1"`
PauseSchedule *FilterConfig_Schedule `protobuf:"bytes,1,opt,name=pause_schedule,json=pauseSchedule,proto3" json:"pause_schedule,omitempty"`
BlockedServices []string `protobuf:"bytes,2,rep,name=blocked_services,json=blockedServices,proto3" json:"blocked_services,omitempty"`
Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"`
AdultBlockingEnabled bool `protobuf:"varint,4,opt,name=adult_blocking_enabled,json=adultBlockingEnabled,proto3" json:"adult_blocking_enabled,omitempty"`
SafeSearchGeneralEnabled bool `protobuf:"varint,5,opt,name=safe_search_general_enabled,json=safeSearchGeneralEnabled,proto3" json:"safe_search_general_enabled,omitempty"`
SafeSearchYoutubeEnabled bool `protobuf:"varint,6,opt,name=safe_search_youtube_enabled,json=safeSearchYoutubeEnabled,proto3" json:"safe_search_youtube_enabled,omitempty"`
state protoimpl.MessageState `protogen:"open.v1"`
PauseSchedule *FilterConfig_Schedule `protobuf:"bytes,1,opt,name=pause_schedule,json=pauseSchedule,proto3" json:"pause_schedule,omitempty"`
CategoryFilter *FilterConfig_CategoryFilter `protobuf:"bytes,7,opt,name=category_filter,json=categoryFilter,proto3" json:"category_filter,omitempty"`
BlockedServices []string `protobuf:"bytes,2,rep,name=blocked_services,json=blockedServices,proto3" json:"blocked_services,omitempty"`
Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"`
AdultBlockingEnabled bool `protobuf:"varint,4,opt,name=adult_blocking_enabled,json=adultBlockingEnabled,proto3" json:"adult_blocking_enabled,omitempty"`
SafeSearchGeneralEnabled bool `protobuf:"varint,5,opt,name=safe_search_general_enabled,json=safeSearchGeneralEnabled,proto3" json:"safe_search_general_enabled,omitempty"`
SafeSearchYoutubeEnabled bool `protobuf:"varint,6,opt,name=safe_search_youtube_enabled,json=safeSearchYoutubeEnabled,proto3" json:"safe_search_youtube_enabled,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -1506,6 +1509,13 @@ func (x *FilterConfig_Parental) GetPauseSchedule() *FilterConfig_Schedule {
return nil
}
func (x *FilterConfig_Parental) GetCategoryFilter() *FilterConfig_CategoryFilter {
if x != nil {
return x.CategoryFilter
}
return nil
}
func (x *FilterConfig_Parental) GetBlockedServices() []string {
if x != nil {
return x.BlockedServices
@@ -1911,18 +1921,19 @@ const file_filecache_proto_rawDesc = "" +
"\fStatePending\x122\n" +
"\x06expire\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x06expire\x12&\n" +
"\x0fwell_known_path\x18\x02 \x01(\tR\rwellKnownPathB\a\n" +
"\x05state\"\xd4\v\n" +
"\x05state\"\xab\f\n" +
"\fFilterConfig\x128\n" +
"\x06custom\x18\x01 \x01(\v2 .filecachepb.FilterConfig.CustomR\x06custom\x12>\n" +
"\bparental\x18\x02 \x01(\v2\".filecachepb.FilterConfig.ParentalR\bparental\x12?\n" +
"\trule_list\x18\x03 \x01(\v2\".filecachepb.FilterConfig.RuleListR\bruleList\x12K\n" +
"\rsafe_browsing\x18\x04 \x01(\v2&.filecachepb.FilterConfig.SafeBrowsingR\fsafeBrowsing\x12Q\n" +
"\x0fcategory_filter\x18\x05 \x01(\v2(.filecachepb.FilterConfig.CategoryFilterR\x0ecategoryFilter\x1aD\n" +
"\rsafe_browsing\x18\x04 \x01(\v2&.filecachepb.FilterConfig.SafeBrowsingR\fsafeBrowsing\x12U\n" +
"\x0fcategory_filter\x18\x05 \x01(\v2(.filecachepb.FilterConfig.CategoryFilterB\x02\x18\x01R\x0ecategoryFilter\x1aD\n" +
"\x06Custom\x12\x14\n" +
"\x05rules\x18\x03 \x03(\tR\x05rules\x12\x18\n" +
"\aenabled\x18\x04 \x01(\bR\aenabledJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03\x1a\xce\x02\n" +
"\aenabled\x18\x04 \x01(\bR\aenabledJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03\x1a\xa1\x03\n" +
"\bParental\x12I\n" +
"\x0epause_schedule\x18\x01 \x01(\v2\".filecachepb.FilterConfig.ScheduleR\rpauseSchedule\x12)\n" +
"\x0epause_schedule\x18\x01 \x01(\v2\".filecachepb.FilterConfig.ScheduleR\rpauseSchedule\x12Q\n" +
"\x0fcategory_filter\x18\a \x01(\v2(.filecachepb.FilterConfig.CategoryFilterR\x0ecategoryFilter\x12)\n" +
"\x10blocked_services\x18\x02 \x03(\tR\x0fblockedServices\x12\x18\n" +
"\aenabled\x18\x03 \x01(\bR\aenabled\x124\n" +
"\x16adult_blocking_enabled\x18\x04 \x01(\bR\x14adultBlockingEnabled\x12=\n" +
@@ -2065,19 +2076,20 @@ var file_filecache_proto_depIdxs = []int32{
24, // 33: filecachepb.CustomDomainConfig.StateCurrent.not_after:type_name -> google.protobuf.Timestamp
24, // 34: filecachepb.CustomDomainConfig.StatePending.expire:type_name -> google.protobuf.Timestamp
19, // 35: filecachepb.FilterConfig.Parental.pause_schedule:type_name -> filecachepb.FilterConfig.Schedule
20, // 36: filecachepb.FilterConfig.Schedule.week:type_name -> filecachepb.FilterConfig.WeeklySchedule
5, // 37: filecachepb.FilterConfig.WeeklySchedule.mon:type_name -> filecachepb.DayInterval
5, // 38: filecachepb.FilterConfig.WeeklySchedule.tue:type_name -> filecachepb.DayInterval
5, // 39: filecachepb.FilterConfig.WeeklySchedule.wed:type_name -> filecachepb.DayInterval
5, // 40: filecachepb.FilterConfig.WeeklySchedule.thu:type_name -> filecachepb.DayInterval
5, // 41: filecachepb.FilterConfig.WeeklySchedule.fri:type_name -> filecachepb.DayInterval
5, // 42: filecachepb.FilterConfig.WeeklySchedule.sat:type_name -> filecachepb.DayInterval
5, // 43: filecachepb.FilterConfig.WeeklySchedule.sun:type_name -> filecachepb.DayInterval
44, // [44:44] is the sub-list for method output_type
44, // [44:44] is the sub-list for method input_type
44, // [44:44] is the sub-list for extension type_name
44, // [44:44] is the sub-list for extension extendee
0, // [0:44] is the sub-list for field type_name
23, // 36: filecachepb.FilterConfig.Parental.category_filter:type_name -> filecachepb.FilterConfig.CategoryFilter
20, // 37: filecachepb.FilterConfig.Schedule.week:type_name -> filecachepb.FilterConfig.WeeklySchedule
5, // 38: filecachepb.FilterConfig.WeeklySchedule.mon:type_name -> filecachepb.DayInterval
5, // 39: filecachepb.FilterConfig.WeeklySchedule.tue:type_name -> filecachepb.DayInterval
5, // 40: filecachepb.FilterConfig.WeeklySchedule.wed:type_name -> filecachepb.DayInterval
5, // 41: filecachepb.FilterConfig.WeeklySchedule.thu:type_name -> filecachepb.DayInterval
5, // 42: filecachepb.FilterConfig.WeeklySchedule.fri:type_name -> filecachepb.DayInterval
5, // 43: filecachepb.FilterConfig.WeeklySchedule.sat:type_name -> filecachepb.DayInterval
5, // 44: filecachepb.FilterConfig.WeeklySchedule.sun:type_name -> filecachepb.DayInterval
45, // [45:45] is the sub-list for method output_type
45, // [45:45] is the sub-list for method input_type
45, // [45:45] is the sub-list for extension type_name
45, // [45:45] is the sub-list for extension extendee
0, // [0:45] is the sub-list for field type_name
}
func init() { file_filecache_proto_init() }

View File

@@ -96,6 +96,7 @@ message FilterConfig {
message Parental {
Schedule pause_schedule = 1;
CategoryFilter category_filter = 7;
repeated string blocked_services = 2;
bool enabled = 3;
bool adult_blocking_enabled = 4;
@@ -138,7 +139,7 @@ message FilterConfig {
Parental parental = 2;
RuleList rule_list = 3;
SafeBrowsing safe_browsing = 4;
CategoryFilter category_filter = 5;
CategoryFilter category_filter = 5 [deprecated=true];
}
message DayInterval {

View File

@@ -138,7 +138,7 @@ func (x *Profile) toInternal(
Enabled: pbFltConf.Custom.Enabled,
},
Parental: &filter.ConfigParental{
Categories: categoryFilterToInternal(pbFltConf.CategoryFilter),
Categories: categoriesToInternal(pbFltConf),
PauseSchedule: schedule,
// Consider blocked-service IDs to have been prevalidated.
BlockedServices: agdprotobuf.UnsafelyConvertStrSlice[string, filter.BlockedServiceID](
@@ -193,22 +193,33 @@ func (x *Profile) toInternal(
}, nil
}
// categoryFilterToInternal converts filter config's protobuf category filter
// structure to internal one. If pbCatFlt is nil, returns a disabled config.
func categoryFilterToInternal(
pbCatFlt *FilterConfig_CategoryFilter,
) (c *filter.ConfigCategories) {
if pbCatFlt == nil {
// categoriesToInternal converts filter config's protobuf category filter to
// internal one. pbFltConf must not be nil.
func categoriesToInternal(pbFltConf *FilterConfig) (c *filter.ConfigCategories) {
pbCatFltr := pbFltConf.Parental.CategoryFilter
if pbCatFltr == nil && pbFltConf.CategoryFilter != nil {
// TODO(d.kolyshev): Remove after moving deprecated profile categories
// in [internal/profiledb/internal.FileCacheVersion] 19.
pbCatFltr = pbFltConf.CategoryFilter
}
return pbCatFltr.toInternal()
}
// toInternal converts filter config's protobuf category filter structure to
// internal one. If x is nil, returns a disabled config.
func (x *FilterConfig_CategoryFilter) toInternal() (c *filter.ConfigCategories) {
if x == nil {
return &filter.ConfigCategories{
Enabled: false,
}
}
// Consider the categories to have been prevalidated.
ids := agdprotobuf.UnsafelyConvertStrSlice[string, filter.CategoryID](pbCatFlt.GetIds())
ids := agdprotobuf.UnsafelyConvertStrSlice[string, filter.CategoryID](x.GetIds())
return &filter.ConfigCategories{
IDs: ids,
Enabled: pbCatFlt.GetEnabled(),
Enabled: x.GetEnabled(),
}
}
@@ -676,21 +687,21 @@ func filterConfigToProtobuf(c *filter.ConfigClient) (fc *FilterConfig) {
rules = agdprotobuf.UnsafelyConvertStrSlice[filter.RuleText, string](c.Custom.Filter.Rules())
}
parentalCategories := &FilterConfig_CategoryFilter{
Ids: agdprotobuf.UnsafelyConvertStrSlice[filter.CategoryID, string](
c.Parental.Categories.IDs,
),
Enabled: c.Parental.Categories.Enabled,
}
return &FilterConfig{
// TODO(a.garipov): Move to parental.
CategoryFilter: &FilterConfig_CategoryFilter{
Enabled: c.Parental.Categories.Enabled,
Ids: agdprotobuf.UnsafelyConvertStrSlice[
filter.CategoryID,
string,
](c.Parental.Categories.IDs),
},
Custom: &FilterConfig_Custom{
Rules: rules,
Enabled: c.Custom.Enabled,
},
Parental: &FilterConfig_Parental{
PauseSchedule: scheduleToProtobuf(c.Parental.PauseSchedule),
PauseSchedule: scheduleToProtobuf(c.Parental.PauseSchedule),
CategoryFilter: parentalCategories,
BlockedServices: agdprotobuf.UnsafelyConvertStrSlice[filter.BlockedServiceID, string](
c.Parental.BlockedServices,
),