Pull request 2464: AGDNS-3157-upd-urlfilter

Squashed commit of the following:

commit 8e46fdd569
Merge: 614879f2c ef5fad69f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Sep 8 15:52:23 2025 +0300

    Merge branch 'master' into AGDNS-3157-upd-urlfilter

commit 614879f2c8
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Sep 2 19:11:14 2025 +0300

    all: imp code

commit 4215551bb3
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Sep 2 17:38:09 2025 +0300

    all: upd urlfilter
This commit is contained in:
Stanislav Chzhen 2025-09-08 17:20:36 +03:00
parent ef5fad69f6
commit 0e6a55efa0
11 changed files with 55 additions and 43 deletions

View File

@ -24,6 +24,7 @@ NOTE: Add new changes BELOW THIS COMMENT.
### Changed
- Optimized matching of filtering rules.
- Our snap package now uses the `core24` image as its base.
- Outgoing HTTP requests now use the `User-Agent` header `AdGuardHome/v0.107.66` (where `v0.107.66` is the current version) instead of `Go-http-client/1.1` ([#7979]).

4
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/AdguardTeam/dnsproxy v0.76.1
// TODO(s.chzhen): Use osutil/executil and fakeos/fakeexec.
github.com/AdguardTeam/golibs v0.34.0
github.com/AdguardTeam/urlfilter v0.20.0
github.com/AdguardTeam/urlfilter v0.21.0
github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.4.0
github.com/bluele/gcache v0.0.2
@ -28,7 +28,7 @@ require (
// TODO(a.garipov): This package is deprecated; find a new one or use our
// own code for that. Perhaps, use gopacket.
github.com/mdlayher/raw v0.1.0
github.com/miekg/dns v1.1.66
github.com/miekg/dns v1.1.68
github.com/quic-go/quic-go v0.53.0
github.com/stretchr/testify v1.11.1
github.com/ti-mo/netfilter v0.5.3

8
go.sum
View File

@ -14,8 +14,8 @@ github.com/AdguardTeam/dnsproxy v0.76.1 h1:ms5vgdbYYXrKGPEpMFqUeql2j3aSfK1tGbCKj
github.com/AdguardTeam/dnsproxy v0.76.1/go.mod h1:9Mw3wQMTYwM/HR9FdtatQAd+m0S8mbwq2J+UZiy/gXc=
github.com/AdguardTeam/golibs v0.34.0 h1:JQK024DkTYxE7vsPVsYsoyDHW/53Nun7OYb9qscniK8=
github.com/AdguardTeam/golibs v0.34.0/go.mod h1:K4C2EbfSEM1zY5YXoti9SfbTAHN/kIX97LpDtCwORrM=
github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs=
github.com/AdguardTeam/urlfilter v0.20.0/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk=
github.com/AdguardTeam/urlfilter v0.21.0 h1:ThIxiP7yoaXt8JTEroGQeU5ftQSoFpUq+t1L+TIx2pA=
github.com/AdguardTeam/urlfilter v0.21.0/go.mod h1:xoZ3AF5qpE9ngbbeSShY9hgVeyHtm9MdH5xH1u714Wg=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
@ -126,8 +126,8 @@ github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=

View File

@ -24,11 +24,13 @@ type IgnoreEngine struct {
// NewIgnoreEngine creates a new instance of the IgnoreEngine and stores the
// list of rules for ignoring hostnames.
func NewIgnoreEngine(ignored []string) (e *IgnoreEngine, err error) {
ruleList := &filterlist.StringRuleList{
RulesText: strings.ToLower(strings.Join(ignored, "\n")),
IgnoreCosmetic: true,
ruleLists := []filterlist.Interface{
filterlist.NewString(&filterlist.StringConfig{
RulesText: strings.ToLower(strings.Join(ignored, "\n")),
IgnoreCosmetic: true,
}),
}
ruleStorage, err := filterlist.NewRuleStorage([]filterlist.RuleList{ruleList})
ruleStorage, err := filterlist.NewRuleStorage(ruleLists)
if err != nil {
return nil, err
}

View File

@ -88,12 +88,12 @@ func newAccessCtx(allowed, blocked, blockedHosts []string) (a *accessManager, er
stringutil.WriteToBuilder(b, strings.ToLower(h), "\n")
}
lists := []filterlist.RuleList{
&filterlist.StringRuleList{
lists := []filterlist.Interface{
filterlist.NewString(&filterlist.StringConfig{
ID: 0,
RulesText: b.String(),
IgnoreCosmetic: true,
},
}),
}
rulesStrg, err := filterlist.NewRuleStorage(lists)

View File

@ -766,9 +766,9 @@ func (d *DNSFilter) matchBlockedServicesRules(
//
func newRuleStorage(filters []Filter) (rs *filterlist.RuleStorage, err error) {
lists := make([]filterlist.RuleList, 0, len(filters))
lists := make([]filterlist.Interface, 0, len(filters))
for _, f := range filters {
var rl filterlist.RuleList
var rl filterlist.Interface
var skip bool
rl, skip, err = ruleListFromFilter(f)
if skip {
@ -792,15 +792,15 @@ func newRuleStorage(filters []Filter) (rs *filterlist.RuleStorage, err error) {
}
// ruleListFromFilter returns a rule list from a Filter.
func ruleListFromFilter(f Filter) (rl filterlist.RuleList, skip bool, err error) {
func ruleListFromFilter(f Filter) (rl filterlist.Interface, skip bool, err error) {
id := int(f.ID)
if len(f.Data) != 0 {
return &filterlist.StringRuleList{
return filterlist.NewBytes(&filterlist.BytesConfig{
ID: id,
RulesText: string(f.Data),
RulesText: f.Data,
IgnoreCosmetic: true,
}, false, nil
}), false, nil
}
if f.FilePath == "" {
@ -818,22 +818,25 @@ func ruleListFromFilter(f Filter) (rl filterlist.RuleList, skip bool, err error)
return nil, false, fmt.Errorf("reading filter content: %w", err)
}
return &filterlist.StringRuleList{
return filterlist.NewBytes(&filterlist.BytesConfig{
ID: id,
RulesText: string(data),
RulesText: data,
IgnoreCosmetic: true,
}, false, nil
}), false, nil
}
var list *filterlist.FileRuleList
list, err = filterlist.NewFileRuleList(id, f.FilePath, true)
rl, err = filterlist.NewFile(&filterlist.FileConfig{
ID: id,
Path: f.FilePath,
IgnoreCosmetic: true,
})
if errors.Is(err, fs.ErrNotExist) {
return nil, true, nil
} else if err != nil {
return nil, false, fmt.Errorf("creating file rule list with %q: %w", f.FilePath, err)
}
return list, false, nil
return rl, false, nil
}
// Initialize urlfilter objects.

View File

@ -55,7 +55,7 @@ type DefaultStorage struct {
engine *urlfilter.DNSEngine
// ruleList is the filtering rule ruleList used by the engine.
ruleList filterlist.RuleList
ruleList filterlist.Interface
// rewrites stores the rewrite entries from configuration.
rewrites []*Item
@ -249,13 +249,13 @@ func (s *DefaultStorage) resetRules() (err error) {
rulesText = append(rulesText, rewrite.toRule())
}
strList := &filterlist.StringRuleList{
strList := filterlist.NewString(&filterlist.StringConfig{
ID: s.urlFilterID,
RulesText: strings.Join(rulesText, "\n"),
IgnoreCosmetic: true,
}
})
rs, err := filterlist.NewRuleStorage([]filterlist.RuleList{strList})
rs, err := filterlist.NewRuleStorage([]filterlist.Interface{strList})
if err != nil {
return fmt.Errorf("creating list storage: %w", err)
}

View File

@ -203,8 +203,8 @@ type engineRefresh struct {
func (r *engineRefresh) process(
ctx context.Context,
filters []*Filter,
) (ruleLists []filterlist.RuleList, errs []error) {
ruleLists = make([]filterlist.RuleList, 0, len(filters))
) (ruleLists []filterlist.Interface, errs []error) {
ruleLists = make([]filterlist.Interface, 0, len(filters))
for i, f := range filters {
select {
case <-ctx.Done():

View File

@ -30,7 +30,7 @@ type Filter struct {
url *url.URL
// ruleList is the last successfully compiled [filterlist.RuleList].
ruleList filterlist.RuleList
ruleList filterlist.Interface
// updated is the time of the last successful update.
updated time.Time
@ -161,11 +161,11 @@ func (f *Filter) setFromHTTP(
}
// TODO(a.garipov): Add filterlist.BytesRuleList.
f.ruleList = &filterlist.StringRuleList{
f.ruleList = filterlist.NewString(&filterlist.StringConfig{
ID: f.urlFilterID,
RulesText: text,
IgnoreCosmetic: true,
}
})
return parseRes, nil
}
@ -255,7 +255,11 @@ func (f *Filter) setFromFile(
return nil, fmt.Errorf("closing old rule list: %w", err)
}
rl, err := filterlist.NewFileRuleList(f.urlFilterID, cachePath, true)
rl, err := filterlist.NewFile(&filterlist.FileConfig{
ID: f.urlFilterID,
Path: cachePath,
IgnoreCosmetic: true,
})
if err != nil {
return nil, fmt.Errorf("opening new rule list: %w", err)
}

View File

@ -42,12 +42,12 @@ type TextEngineConfig struct {
// directly. The engine is ready to use and should not be refreshed.
func NewTextEngine(c *TextEngineConfig) (e *TextEngine, err error) {
text := strings.Join(c.Rules, "\n")
storage, err := filterlist.NewRuleStorage([]filterlist.RuleList{
&filterlist.StringRuleList{
storage, err := filterlist.NewRuleStorage([]filterlist.Interface{
filterlist.NewString(&filterlist.StringConfig{
RulesText: text,
ID: c.ID,
IgnoreCosmetic: true,
},
}),
})
if err != nil {
return nil, fmt.Errorf("creating rule storage: %w", err)

View File

@ -149,13 +149,15 @@ func (ss *Default) resetEngine(
}
}
strList := &filterlist.StringRuleList{
ID: listID,
RulesText: sb.String(),
IgnoreCosmetic: true,
strList := []filterlist.Interface{
filterlist.NewString(&filterlist.StringConfig{
ID: listID,
RulesText: sb.String(),
IgnoreCosmetic: true,
}),
}
rs, err := filterlist.NewRuleStorage([]filterlist.RuleList{strList})
rs, err := filterlist.NewRuleStorage(strList)
if err != nil {
return fmt.Errorf("creating rule storage: %w", err)
}