diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d1dcd2..06a6272 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/doc/debughttp.md b/doc/debughttp.md
index e23caab..f20e3c6 100644
--- a/doc/debughttp.md
+++ b/doc/debughttp.md
@@ -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:
}
```
+## `POST /debug/panic`
+
+A debugging endpoint that forces service panic.
+
## `POST /dnsdb/csv`
The CSV dump of the current DNSDB statistics. Example of the output:
diff --git a/doc/environment.md b/doc/environment.md
index 0284d03..8bb1e4b 100644
--- a/doc/environment.md
+++ b/doc/environment.md
@@ -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
+## `PROFILES_CACHE_TYPE`
+
+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.
+
## `PROFILES_MAX_RESP_SIZE`
The maximum size of the response from the profiles API in a human-readable format.
diff --git a/doc/http.md b/doc/http.md
index 2fbc062..eaf8b76 100644
--- a/doc/http.md
+++ b/doc/http.md
@@ -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
## Linked IP Proxy
diff --git a/go.mod b/go.mod
index 6772ff1..ee95ae4 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 531acf2..0b0ddd7 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/go.work.sum b/go.work.sum
index c4df943..075f7a3 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -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=
diff --git a/internal/backendpb/dns_grpc.pb.go b/internal/backendpb/dns_grpc.pb.go
index fcd09a4..2bfb5c9 100644
--- a/internal/backendpb/dns_grpc.pb.go
+++ b/internal/backendpb/dns_grpc.pb.go
@@ -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.
diff --git a/internal/cmd/builder.go b/internal/cmd/builder.go
index da226b1..d90287c 100644
--- a/internal/cmd/builder.go
+++ b/internal/cmd/builder.go
@@ -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),
diff --git a/internal/cmd/env.go b/internal/cmd/env.go
index 7d9e47f..8bc9432 100644
--- a/internal/cmd/env.go
+++ b/internal/cmd/env.go
@@ -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...)
}
diff --git a/internal/debugsvc/route.go b/internal/debugsvc/route.go
index 8950840..ebda942 100644
--- a/internal/debugsvc/route.go
+++ b/internal/debugsvc/route.go
@@ -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 {
diff --git a/internal/dnscheck/remotekv.go b/internal/dnscheck/remotekv.go
index 489325d..f70fb1e 100644
--- a/internal/dnscheck/remotekv.go
+++ b/internal/dnscheck/remotekv.go
@@ -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"`
}
diff --git a/internal/dnscheck/remotekv_test.go b/internal/dnscheck/remotekv_test.go
index 2006af5..a4876f8 100644
--- a/internal/dnscheck/remotekv_test.go
+++ b/internal/dnscheck/remotekv_test.go
@@ -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) {
diff --git a/internal/dnsserver/context.go b/internal/dnsserver/context.go
index 69cf8b1..7822f45 100644
--- a/internal/dnsserver/context.go
+++ b/internal/dnsserver/context.go
@@ -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
diff --git a/internal/dnsserver/dnsservertest/handler.go b/internal/dnsserver/dnsservertest/handler.go
index 0eedd51..e92c8d2 100644
--- a/internal/dnsserver/dnsservertest/handler.go
+++ b/internal/dnsserver/dnsservertest/handler.go
@@ -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)
diff --git a/internal/dnsserver/go.mod b/internal/dnsserver/go.mod
index c2fca1d..c25d3a4 100644
--- a/internal/dnsserver/go.mod
+++ b/internal/dnsserver/go.mod
@@ -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
diff --git a/internal/dnsserver/go.sum b/internal/dnsserver/go.sum
index 156888a..b5343c5 100644
--- a/internal/dnsserver/go.sum
+++ b/internal/dnsserver/go.sum
@@ -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=
diff --git a/internal/dnsserver/serverdnstcp.go b/internal/dnsserver/serverdnstcp.go
index 3bfdc04..40010de 100644
--- a/internal/dnsserver/serverdnstcp.go
+++ b/internal/dnsserver/serverdnstcp.go
@@ -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())
diff --git a/internal/dnsserver/serverhttps.go b/internal/dnsserver/serverhttps.go
index 3eca3c8..25735e0 100644
--- a/internal/dnsserver/serverhttps.go
+++ b/internal/dnsserver/serverhttps.go
@@ -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 {
diff --git a/internal/dnsserver/serverhttps_test.go b/internal/dnsserver/serverhttps_test.go
index 68258dd..d542b7d 100644
--- a/internal/dnsserver/serverhttps_test.go
+++ b/internal/dnsserver/serverhttps_test.go
@@ -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,
diff --git a/internal/dnsserver/serverquic.go b/internal/dnsserver/serverquic.go
index 4329309..041e188 100644
--- a/internal/dnsserver/serverquic.go
+++ b/internal/dnsserver/serverquic.go
@@ -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())
diff --git a/internal/dnssvc/integration_test.go b/internal/dnssvc/integration_test.go
index 03ec393..11cb155 100644
--- a/internal/dnssvc/integration_test.go
+++ b/internal/dnssvc/integration_test.go
@@ -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)
diff --git a/internal/dnssvc/internal/devicefinder/device_test.go b/internal/dnssvc/internal/devicefinder/device_test.go
index 53bb539..b498804 100644
--- a/internal/dnssvc/internal/devicefinder/device_test.go
+++ b/internal/dnssvc/internal/devicefinder/device_test.go
@@ -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)
diff --git a/internal/dnssvc/internal/devicefinder/devicedata.go b/internal/dnssvc/internal/devicefinder/devicedata.go
index 94729b9..a26c67d 100644
--- a/internal/dnssvc/internal/devicefinder/devicedata.go
+++ b/internal/dnssvc/internal/devicefinder/devicedata.go
@@ -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")
}
diff --git a/internal/dnssvc/internal/devicefinder/devicedata_test.go b/internal/dnssvc/internal/devicefinder/devicedata_test.go
index 31edb4a..967c1a3 100644
--- a/internal/dnssvc/internal/devicefinder/devicedata_test.go
+++ b/internal/dnssvc/internal/devicefinder/devicedata_test.go
@@ -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)
diff --git a/internal/dnssvc/internal/devicefinder/devicefinder_test.go b/internal/dnssvc/internal/devicefinder/devicefinder_test.go
index 4e67f66..d473b5f 100644
--- a/internal/dnssvc/internal/devicefinder/devicefinder_test.go
+++ b/internal/dnssvc/internal/devicefinder/devicefinder_test.go
@@ -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
}
diff --git a/internal/dnssvc/internal/devicefinder/humanid_test.go b/internal/dnssvc/internal/devicefinder/humanid_test.go
index 7db0aac..4219b28 100644
--- a/internal/dnssvc/internal/devicefinder/humanid_test.go
+++ b/internal/dnssvc/internal/devicefinder/humanid_test.go
@@ -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)
diff --git a/internal/dnssvc/internal/dnssvctest/dnssvctest.go b/internal/dnssvc/internal/dnssvctest/dnssvctest.go
index b992e05..d5d02c6 100644
--- a/internal/dnssvc/internal/dnssvctest/dnssvctest.go
+++ b/internal/dnssvc/internal/dnssvctest/dnssvctest.go
@@ -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(),
+ }
+}
diff --git a/internal/errcoll/sentry.go b/internal/errcoll/sentry.go
index 4210bca..56e639b 100644
--- a/internal/errcoll/sentry.go
+++ b/internal/errcoll/sentry.go
@@ -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.
diff --git a/internal/profiledb/config.go b/internal/profiledb/config.go
index 68d9bcf..24e66b5 100644
--- a/internal/profiledb/config.go
+++ b/internal/profiledb/config.go
@@ -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
}
diff --git a/internal/profiledb/default.go b/internal/profiledb/default.go
index 2a466bb..20415ed 100644
--- a/internal/profiledb/default.go
+++ b/internal/profiledb/default.go
@@ -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{
diff --git a/internal/profiledb/internal/fcpb/fc.pb.go b/internal/profiledb/internal/fcpb/fc.pb.go
index efd0c7b..ee142f6 100644
--- a/internal/profiledb/internal/fcpb/fc.pb.go
+++ b/internal/profiledb/internal/fcpb/fc.pb.go
@@ -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() }
diff --git a/internal/profiledb/internal/fcpb/fc.proto b/internal/profiledb/internal/fcpb/fc.proto
index 555d733..6d65bfd 100644
--- a/internal/profiledb/internal/fcpb/fc.proto
+++ b/internal/profiledb/internal/fcpb/fc.proto
@@ -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 {
diff --git a/internal/profiledb/internal/filecacheopb/profile.go b/internal/profiledb/internal/filecacheopb/profile.go
index 302956f..c5cdad5 100644
--- a/internal/profiledb/internal/filecacheopb/profile.go
+++ b/internal/profiledb/internal/filecacheopb/profile.go
@@ -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()
}
diff --git a/internal/profiledb/internal/filecachepb/filecache.pb.go b/internal/profiledb/internal/filecachepb/filecache.pb.go
index 9d8f229..8757d40 100644
--- a/internal/profiledb/internal/filecachepb/filecache.pb.go
+++ b/internal/profiledb/internal/filecachepb/filecache.pb.go
@@ -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() }
diff --git a/internal/profiledb/internal/filecachepb/filecache.proto b/internal/profiledb/internal/filecachepb/filecache.proto
index fb4fd54..94ce0db 100644
--- a/internal/profiledb/internal/filecachepb/filecache.proto
+++ b/internal/profiledb/internal/filecachepb/filecache.proto
@@ -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 {
diff --git a/internal/profiledb/internal/filecachepb/filecachepb.go b/internal/profiledb/internal/filecachepb/filecachepb.go
index 5fdc340..48cc34b 100644
--- a/internal/profiledb/internal/filecachepb/filecachepb.go
+++ b/internal/profiledb/internal/filecachepb/filecachepb.go
@@ -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,
),