Pull request: 2875 fix client filtering settings

Merge in DNS/adguard-home from 2875-client-filtering to master

Updates #2875.

Squashed commit of the following:

commit b3b9582b7dde826005ba79d499ed7e82af067e93
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Mon May 24 14:22:29 2021 +0300

    all: use atomic, log changes

commit 9304d8b96d0d064d7741c85165ab885f5547fd4c
Author: Eugene Burkov <e.burkov@adguard.com>
Date:   Mon May 24 13:43:22 2021 +0300

    all: fix client filtering settings
This commit is contained in:
Eugene Burkov 2021-05-24 14:48:42 +03:00
parent 52e6a63d8c
commit 14250821ab
9 changed files with 57 additions and 20 deletions

View File

@ -27,6 +27,10 @@ released by then.
- Go 1.16 support. v0.108.0 will require at least Go 1.17 to build. - Go 1.16 support. v0.108.0 will require at least Go 1.17 to build.
### Fixed
- Incorrect client-based filtering applying logic ([#2875]).
### Removed ### Removed
- Go 1.15 support. - Go 1.15 support.

View File

@ -317,7 +317,7 @@ Here is a link to AdGuard Home project: https://crowdin.com/project/adguard-appl
Here's what you can also do to contribute: Here's what you can also do to contribute:
1. [Look for issues](https://github.com/AdguardTeam/AdGuardHome/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) marked as "help wanted". 1. [Look for issues](https://github.com/AdguardTeam/AdGuardHome/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) marked as "help wanted".
2. Actualize the list of *Blocked services*. It it can be found in [filtering/blocked.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/internal/filtering/blocked.go). 2. Actualize the list of *Blocked services*. It can be found in [filtering/blocked.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/internal/filtering/blocked.go).
3. Actualize the list of known *trackers*. It it can be found in [client/src/helpers/trackers/adguard.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/trackers/adguard.json). 3. Actualize the list of known *trackers*. It it can be found in [client/src/helpers/trackers/adguard.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/trackers/adguard.json).
4. Actualize the list of vetted *blocklists*. It it can be found in [client/src/helpers/filters/filters.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/filters/filters.json). 4. Actualize the list of vetted *blocklists*. It it can be found in [client/src/helpers/filters/filters.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/filters/filters.json).

View File

@ -68,6 +68,7 @@ func createTestServer(
}} }}
f := filtering.New(filterConf, filters) f := filtering.New(filterConf, filters)
f.SetEnabled(true)
snd, err := aghnet.NewSubnetDetector() snd, err := aghnet.NewSubnetDetector()
require.NoError(t, err) require.NoError(t, err)
@ -734,10 +735,11 @@ func TestBlockedCustomIP(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, snd) require.NotNil(t, snd)
f := filtering.New(&filtering.Config{}, filters)
var s *Server var s *Server
s, err = NewServer(DNSCreateParams{ s, err = NewServer(DNSCreateParams{
DHCPServer: &testDHCP{}, DHCPServer: &testDHCP{},
DNSFilter: filtering.New(&filtering.Config{}, filters), DNSFilter: f,
SubnetDetector: snd, SubnetDetector: snd,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -763,6 +765,7 @@ func TestBlockedCustomIP(t *testing.T) {
err = s.Prepare(conf) err = s.Prepare(conf)
require.NoError(t, err) require.NoError(t, err)
f.SetEnabled(true)
startDeferStop(t, s) startDeferStop(t, s)
addr := s.dnsProxy.Addr(proxy.ProtoUDP) addr := s.dnsProxy.Addr(proxy.ProtoUDP)
@ -798,6 +801,7 @@ func TestBlockedByHosts(t *testing.T) {
ProtectionEnabled: true, ProtectionEnabled: true,
}, },
} }
s := createTestServer(t, &filtering.Config{}, forwardConf, nil) s := createTestServer(t, &filtering.Config{}, forwardConf, nil)
startDeferStop(t, s) startDeferStop(t, s)
addr := s.dnsProxy.Addr(proxy.ProtoUDP) addr := s.dnsProxy.Addr(proxy.ProtoUDP)

View File

@ -38,7 +38,6 @@ func (s *Server) beforeRequestHandler(_ *proxy.Proxy, d *proxy.DNSContext) (bool
// the client's IP address and ID, if any, from ctx. // the client's IP address and ID, if any, from ctx.
func (s *Server) getClientRequestFilteringSettings(ctx *dnsContext) *filtering.Settings { func (s *Server) getClientRequestFilteringSettings(ctx *dnsContext) *filtering.Settings {
setts := s.dnsFilter.GetConfig() setts := s.dnsFilter.GetConfig()
setts.FilteringEnabled = true
if s.conf.FilterHandler != nil { if s.conf.FilterHandler != nil {
s.conf.FilterHandler(IPFromAddr(ctx.proxyCtx.Addr), ctx.clientID, &setts) s.conf.FilterHandler(IPFromAddr(ctx.proxyCtx.Addr), ctx.clientID, &setts)
} }

View File

@ -11,6 +11,7 @@ import (
"runtime/debug" "runtime/debug"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings" "github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
@ -50,6 +51,11 @@ type Resolver interface {
// Config allows you to configure DNS filtering with New() or just change variables directly. // Config allows you to configure DNS filtering with New() or just change variables directly.
type Config struct { type Config struct {
// enabled is used to be returned within Settings.
//
// It is of type uint32 to be accessed by atomic.
enabled uint32
ParentalEnabled bool `yaml:"parental_enabled"` ParentalEnabled bool `yaml:"parental_enabled"`
SafeSearchEnabled bool `yaml:"safesearch_enabled"` SafeSearchEnabled bool `yaml:"safesearch_enabled"`
SafeBrowsingEnabled bool `yaml:"safebrowsing_enabled"` SafeBrowsingEnabled bool `yaml:"safebrowsing_enabled"`
@ -118,7 +124,8 @@ type DNSFilter struct {
parentalUpstream upstream.Upstream parentalUpstream upstream.Upstream
safeBrowsingUpstream upstream.Upstream safeBrowsingUpstream upstream.Upstream
Config // for direct access by library users, even a = assignment Config // for direct access by library users, even a = assignment
// confLock protects Config.
confLock sync.RWMutex confLock sync.RWMutex
// Channel for passing data to filters-initializer goroutine // Channel for passing data to filters-initializer goroutine
@ -223,15 +230,26 @@ func (r Reason) In(reasons ...Reason) bool {
return false return false
} }
// SetEnabled sets the status of the *DNSFilter.
func (d *DNSFilter) SetEnabled(enabled bool) {
var i int32
if enabled {
i = 1
}
atomic.StoreUint32(&d.enabled, uint32(i))
}
// GetConfig - get configuration // GetConfig - get configuration
func (d *DNSFilter) GetConfig() Settings { func (d *DNSFilter) GetConfig() (s Settings) {
c := Settings{} d.confLock.RLock()
// d.confLock.RLock() defer d.confLock.RUnlock()
c.SafeSearchEnabled = d.Config.SafeSearchEnabled
c.SafeBrowsingEnabled = d.Config.SafeBrowsingEnabled return Settings{
c.ParentalEnabled = d.Config.ParentalEnabled FilteringEnabled: atomic.LoadUint32(&d.Config.enabled) == 1,
// d.confLock.RUnlock() SafeSearchEnabled: d.Config.SafeSearchEnabled,
return c SafeBrowsingEnabled: d.Config.SafeBrowsingEnabled,
ParentalEnabled: d.Config.ParentalEnabled,
}
} }
// WriteDiskConfig - write configuration // WriteDiskConfig - write configuration

View File

@ -134,7 +134,6 @@ func handleStatus(w http.ResponseWriter, _ *http.Request) {
} }
var resp statusResponse var resp statusResponse
func() { func() {
config.RLock() config.RLock()
defer config.RUnlock() defer config.RUnlock()

View File

@ -351,8 +351,14 @@ func (f *Filtering) handleFilteringConfig(w http.ResponseWriter, r *http.Request
return return
} }
config.DNS.FilteringEnabled = req.Enabled func() {
config.DNS.FiltersUpdateIntervalHours = req.Interval config.Lock()
defer config.Unlock()
config.DNS.FilteringEnabled = req.Enabled
config.DNS.FiltersUpdateIntervalHours = req.Interval
}()
onConfigModified() onConfigModified()
enableFilters(true) enableFilters(true)
} }
@ -364,7 +370,6 @@ type checkHostRespRule struct {
type checkHostResp struct { type checkHostResp struct {
Reason string `json:"reason"` Reason string `json:"reason"`
// FilterID is the ID of the rule's filter list. // FilterID is the ID of the rule's filter list.
// //
// Deprecated: Use Rules[*].FilterListID. // Deprecated: Use Rules[*].FilterListID.

View File

@ -307,7 +307,6 @@ func applyAdditionalFiltering(clientAddr net.IP, clientID string, setts *filteri
setts.ClientName = c.Name setts.ClientName = c.Name
setts.ClientTags = c.Tags setts.ClientTags = c.Tags
if !c.UseOwnSettings { if !c.UseOwnSettings {
return return
} }
@ -319,14 +318,14 @@ func applyAdditionalFiltering(clientAddr net.IP, clientID string, setts *filteri
} }
func startDNSServer() error { func startDNSServer() error {
config.Lock() config.RLock()
defer config.Unlock() defer config.RUnlock()
if isRunning() { if isRunning() {
return fmt.Errorf("unable to start forwarding DNS server: Already running") return fmt.Errorf("unable to start forwarding DNS server: Already running")
} }
enableFilters(false) enableFiltersLocked(false)
Context.clients.Start() Context.clients.Start()

View File

@ -664,6 +664,13 @@ func (filter *filter) Path() string {
} }
func enableFilters(async bool) { func enableFilters(async bool) {
config.RLock()
defer config.RUnlock()
enableFiltersLocked(async)
}
func enableFiltersLocked(async bool) {
var whiteFilters []filtering.Filter var whiteFilters []filtering.Filter
filters := []filtering.Filter{{ filters := []filtering.Filter{{
Data: []byte(strings.Join(config.UserRules, "\n")), Data: []byte(strings.Join(config.UserRules, "\n")),
@ -693,4 +700,6 @@ func enableFilters(async bool) {
if err := Context.dnsFilter.SetFilters(filters, whiteFilters, async); err != nil { if err := Context.dnsFilter.SetFilters(filters, whiteFilters, async); err != nil {
log.Debug("enabling filters: %s", err) log.Debug("enabling filters: %s", err)
} }
Context.dnsFilter.SetEnabled(config.DNS.FilteringEnabled)
} }