rules

package
v0.23.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2026 License: GPL-3.0 Imports: 16 Imported by: 7

Documentation

Overview

Package rules contains implementation of all kinds of blocking rules.

Index

Constants

View Source
const (
	// ErrTooWideRule is returned if the rule matches all URLs but has no
	// domain, denyallow, client, or ctag restrictions.
	ErrTooWideRule errors.Error = "the rule is too wide, add domain, denyallow, client, " +
		"or ctag restrictions or make it more specific"

	// ErrUnsupportedRule signals that this might be a valid rule type, but it
	// is not yet supported by this module.
	ErrUnsupportedRule errors.Error = "this type of rules is unsupported"
)
View Source
const (
	// MaskAnyCharacter is a wildcard character.  It is used to represent any
	// set of characters.  This can also be an empty string or a string of any
	// length.
	MaskAnyCharacter = "*"

	// MaskPipe points to the beginning or the end of address.  The value
	// depends on the character placement in the mask.  For example, a rule
	// like "swf|" matches "http://example.com/annoyingflash.swf", but not
	// "http://example.com/swf/index.html".  "|http://example.org" matches
	// "http://example.org", but not "http://domain.com?url=http://example.org".
	MaskPipe = "|"

	// MaskSeparator is any character that isn't a letter, a digit, or one of
	// the following: '_', '-', '.', '%'.
	MaskSeparator = "^"

	// MaskStartURL matches the beginning of an address. It is used to not
	// specify a particular protocol and subdomain in address mask.  That is,
	// "||" stands for "http://*.", "https://*.", "ws://*.", and "wss://*." all
	// at once.
	MaskStartURL = "||"
)
View Source
const (
	// RegexAnyCharacter corresponds to [MaskAnyCharacter].
	RegexAnyCharacter = ".*"

	// RegexEndString corresponds to [MaskPipe] when it is at the end of a
	// pattern.
	RegexEndString = "$"

	// RegexSeparator corresponds to [MaskSeparator].
	RegexSeparator = "([^ a-zA-Z0-9.%_-]|$)"

	// RegexStartString corresponds to [MaskPipe] when it is at the beginning of
	// a pattern.
	RegexStartString = "^"

	// RegexStartURL corresponds to [MaskStartURL].
	RegexStartURL = `^(http|https|ws|wss)://([a-z0-9-_.]+\.)?`
)

TODO(a.garipov): Rename consistently.

Variables

This section is empty.

Functions

func FillRequestForHostname added in v0.17.1

func FillRequestForHostname(r *Request, hostname string)

FillRequestForHostname fills the given instance of request r for matching the hostname. It uses "http://" as a protocol for request URL and TypeDocument as request type.

Types

type CosmeticOption

type CosmeticOption uint32

CosmeticOption is the bitset of various content script options.

const (
	// CosmeticOptionGenericCSS is set if generic elemhide and CSS rules are
	// enabled.  It can be disabled by a $generichide rule.
	CosmeticOptionGenericCSS CosmeticOption = 1 << iota

	// CosmeticOptionCSS is set if elemhide and CSS rules are enabled.  It can
	// be disabled by an $elemhide rule.
	CosmeticOptionCSS

	// CosmeticOptionJS is set if JS rules and scriptlets are enabled.  It can
	// be disabled by a $jsinject rule.
	CosmeticOptionJS

	CosmeticOptionSourceGenericCSS
	CosmeticOptionSourceCSS
	CosmeticOptionSourceJS

	CosmeticOptionAll  = CosmeticOptionGenericCSS | CosmeticOptionCSS | CosmeticOptionJS
	CosmeticOptionNone = CosmeticOption(0)
)

Valid CosmeticOption masks.

type CosmeticRule

type CosmeticRule struct {

	// Content meaning depends on the rule type:
	//  - Element hiding: content is just a selector;
	//  - CSS: content is a selector + style definition;
	//  - JS: text of the script to be injected.
	Content string

	// Type of the rule.
	Type CosmeticRuleType

	// Whitelist means that this rule is meant to disable rules with the same
	// content on the specified domains.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#elemhide-exceptions
	//
	// TODO(a.garipov):  Consider unexporting.
	Whitelist bool

	// ExtendedCSS means that this rule is supposed to be applied by the
	// Javascript library.
	//
	// See https://github.com/AdguardTeam/ExtendedCss.
	ExtendedCSS bool
	// contains filtered or unexported fields
}

CosmeticRule represents a cosmetic rule (element hiding, CSS, scriptlet).

func NewCosmeticRule

func NewCosmeticRule(ruleText string, id ListID) (r *CosmeticRule, err error)

NewCosmeticRule parses the rule text and creates a rule.

func (*CosmeticRule) GetFilterListID

func (r *CosmeticRule) GetFilterListID() (id ListID)

GetFilterListID implements the Rule interface for *CosmeticRule.

func (*CosmeticRule) GetPermittedDomains

func (r *CosmeticRule) GetPermittedDomains() []string

GetPermittedDomains returns a slice of permitted domains.

func (*CosmeticRule) IsGeneric

func (r *CosmeticRule) IsGeneric() (ok bool)

IsGeneric returns true if r is not limited to a specific domain.

func (*CosmeticRule) Match

func (r *CosmeticRule) Match(hostname string) (ok bool)

Match returns true if this rule can be used on the specified hostname.

func (*CosmeticRule) String

func (r *CosmeticRule) String() (s string)

String returns original rule text.

func (*CosmeticRule) Text

func (r *CosmeticRule) Text() (s string)

Text implements the Rule interface for *CosmeticRule.

type CosmeticRuleType

type CosmeticRuleType uint8

CosmeticRuleType is the enumeration of different cosmetic rule types.

const (
	// CosmeticElementHiding is for ## rules.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#cosmetic-elemhide-rules.
	CosmeticElementHiding CosmeticRuleType = iota

	// CosmeticCSS is for #$# rules.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#cosmetic-css-rules.
	CosmeticCSS

	// CosmeticJS is for #%# rules.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#javascript-rules.
	CosmeticJS

	// CosmeticHTML is for $$ rules.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#html-filtering-rules.
	//
	// TODO(ameshkov):  Move HTML filtering rules to a separate file/structure.
	CosmeticHTML
)

Valid CosmeticRuleType values.

type DNSMX added in v0.14.1

type DNSMX struct {
	Exchange   string
	Preference uint16
}

DNSMX is the type of RRValue values returned for MX records in DNS rewrites.

type DNSRewrite added in v0.14.0

type DNSRewrite struct {
	// Value is the value for the record.  See [RRValue] documentation for more
	// details.
	Value RRValue

	// NewCNAME is the new CNAME.  If set, clients must ignore other fields,
	// resolve the CNAME, and set the new records accordingly.
	NewCNAME string

	// RCode is the new DNS RCODE.
	RCode RCode

	// RRType is the new DNS resource record (RR) type.  It is only non-zero
	// if RCode is dns.RCodeSuccess.
	RRType RRType
}

DNSRewrite is a DNS rewrite ($dnsrewrite) rule.

type DNSSRV added in v0.14.4

type DNSSRV struct {
	Target   string
	Priority uint16
	Weight   uint16
	Port     uint16
}

DNSSRV is the type of RRValue values returned for SRV records in DNS rewrites.

type DNSSVCB added in v0.14.1

type DNSSVCB struct {
	Params   map[string]string
	Target   string
	Priority uint16
}

DNSSVCB is the type of RRValue values returned for HTTPS and SVCB records in dns rewrites.

See https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-02.

type HostRule

type HostRule struct {
	// IP is the address of the rule.
	IP netip.Addr

	// Hostnames is the slice of hostnames associated with IP.
	Hostnames []string
	// contains filtered or unexported fields
}

HostRule is a structure for simple host-level rules, i.e. /etc/hosts syntax.

See http://man7.org/linux/man-pages/man5/hosts.5.html. It also supports "just domain" syntax; in that case, the IP will be set to 0.0.0.0.

TODO(a.garipov): Consider using [hostsfile.Record].

func NewHostRule

func NewHostRule(ruleText string, id ListID) (h *HostRule, err error)

NewHostRule parses the rule and creates a new *HostRule.

func (*HostRule) GetFilterListID

func (f *HostRule) GetFilterListID() (id ListID)

GetFilterListID implements the Rule interface for *HostRule.

func (*HostRule) Match

func (f *HostRule) Match(hostname string) (ok bool)

Match returns true if this filtering rule matches the specified hostname.

func (*HostRule) String

func (f *HostRule) String() (s string)

String returns original rule text.

func (*HostRule) Text

func (f *HostRule) Text() (s string)

Text implements the Rule interface for *HostRule.

type ListID added in v0.22.0

type ListID uint64

ListID is the unique ID of a filtering-rule list.

TODO(a.garipov): See if there are better types for this. Currently, it is a uint64 to make it possible to use maphash and the similar hashing functions and also for performance reasons.

type MatchingResult

type MatchingResult struct {
	// BasicRule is a rule matching the request.  It could lead to one of the
	// following:
	//   - block the request;
	//   - unblock the request (a regular whitelist rule or a document-level
	//     whitelist rule);
	//   - modify the way cosmetic rules work for this request;
	//   - modify the response (see $redirect rules).
	BasicRule *NetworkRule

	// DocumentRule is a rule matching the request's referrer and having one of
	// the following modifiers:
	//   - $document: this one basically disables everything;
	//   - $urlblock: disables network-level rules (not cosmetic);
	//   - $genericblock: disables generic network-level rules.
	//
	// Other document-level modifiers like $jsinject or $content will be ignored
	// here as they don't do anything
	DocumentRule *NetworkRule

	// StealthRule is a whitelist rule that negates stealth-mode features.  Note
	// that the stealth rule can be received from both rules and sourceRules.
	//
	// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#stealth-modifier.
	StealthRule *NetworkRule

	// CspRules are rules modifying the response's content-security-policy.  See
	// modifier $csp.
	CspRules []*NetworkRule

	// CookieRules are rules modifying the request's and response's cookies.
	// See modifier $cookie.
	CookieRules []*NetworkRule

	// ReplaceRules are rules modifying the response's content.  See modifier
	// $replace.
	ReplaceRules []*NetworkRule
}

MatchingResult contains all rules matching a web request and provides methods for processing of the request.

func NewMatchingResult

func NewMatchingResult(rules, sourceRules []*NetworkRule) (res *MatchingResult)

NewMatchingResult returns a new properly initialized *MatchingResult. rules are the rules matching the request URL. sourceRules are the rules matching the referrer. Items of rules and sourceRules must not be nil.

func (*MatchingResult) GetBasicResult

func (m *MatchingResult) GetBasicResult() (r *NetworkRule)

GetBasicResult returns a rule that should be applied to the web request.

Possible outcomes are:

  • If r is nil, bypass the request.
  • If r is a whitelist rule, bypass the request.
  • If r is a blocking rule, block the request.

func (*MatchingResult) GetCosmeticOption

func (m *MatchingResult) GetCosmeticOption() (o CosmeticOption)

GetCosmeticOption returns the cosmetic options.

type NetworkRule

type NetworkRule struct {

	// DNSRewrite is the DNS rewrite rule, if any.
	DNSRewrite *DNSRewrite

	// Shortcut is the longest substring of the rule pattern with no special
	// characters.
	Shortcut string

	// Whitelist is true if this is an exception rule.
	//
	// TODO(a.garipov):  Consider unexporting.
	Whitelist bool
	// contains filtered or unexported fields
}

NetworkRule is a basic filtering rule.

See https://adguard.com/kb/general/ad-filtering/create-own-filters/#basic-rules.

func GetDNSBasicRule added in v0.17.1

func GetDNSBasicRule(rules []*NetworkRule) (basicRule *NetworkRule)

GetDNSBasicRule returns a rule that should be applied to the DNS request. Elements of rules must not be nil.

func NewNetworkRule

func NewNetworkRule(ruleText string, id ListID) (r *NetworkRule, err error)

NewNetworkRule parses the rule text and returns a filter rule.

func (*NetworkRule) GetFilterListID

func (r *NetworkRule) GetFilterListID() (id ListID)

GetFilterListID implements the Rule interface for *NetworkRule.

func (*NetworkRule) GetPermittedDomains

func (r *NetworkRule) GetPermittedDomains() (domains []string)

GetPermittedDomains returns the domains this rule is allowed on.

func (*NetworkRule) IsGeneric

func (r *NetworkRule) IsGeneric() (ok bool)

IsGeneric returns true if the rule is considered generic. A generic rule is not restricted to a set of domains. Note that it might be forbidden on some domains, though.

func (*NetworkRule) IsHigherPriority

func (r *NetworkRule) IsHigherPriority(other *NetworkRule) (ok bool)

IsHigherPriority checks if the rule has higher priority than the specified rule. The priority rules are:

  1. whitelist + $important;
  2. $important;
  3. whitelist;
  4. basic rules.

func (*NetworkRule) IsHostLevelNetworkRule

func (r *NetworkRule) IsHostLevelNetworkRule() (ok bool)

IsHostLevelNetworkRule checks if this rule can be used for hosts-level blocking.

func (*NetworkRule) IsOptionDisabled

func (r *NetworkRule) IsOptionDisabled(option NetworkRuleOption) (ok bool)

IsOptionDisabled returns true if the specified option is disabled.

func (*NetworkRule) IsOptionEnabled

func (r *NetworkRule) IsOptionEnabled(option NetworkRuleOption) (ok bool)

IsOptionEnabled returns true if the specified option is enabled.

func (*NetworkRule) IsRegexRule

func (r *NetworkRule) IsRegexRule() (ok bool)

IsRegexRule returns true if the rule is a regular expression rule.

func (*NetworkRule) Match

func (r *NetworkRule) Match(req *Request) (ok bool)

Match checks if this filtering rule matches the specified request. req must not be nil.

func (*NetworkRule) String

func (r *NetworkRule) String() (s string)

String returns original rule text.

func (*NetworkRule) Text

func (r *NetworkRule) Text() (s string)

Text implements the Rule interface for *NetworkRule.

type NetworkRuleOption

type NetworkRuleOption uint64

NetworkRuleOption is the bitset of various rule options.

const (
	// OptionThirdParty means that the $third-party modifier is set.
	OptionThirdParty NetworkRuleOption = 1 << iota

	// OptionMatchCase means that the $match-case modifier is set.
	OptionMatchCase

	// OptionImportant means that the $important modifier is set.
	OptionImportant

	// OptionBadfilter means that the $badfilter modifier is set.
	OptionBadfilter

	// OptionElemhide means that the $elemhide modifier is set.
	OptionElemhide

	// OptionGenerichide means that the $generichide modifier is set.
	OptionGenerichide

	// OptionGenericblock means that the $genericblock modifier is set.
	OptionGenericblock

	// OptionJsinject means that the $jsinject modifier is set.
	OptionJsinject

	// OptionUrlblock means that the $urlblock modifier is set.
	OptionUrlblock

	// OptionContent means that the $content modifier is set.
	OptionContent

	// OptionExtension means that the $extension modifier is set.
	OptionExtension

	// OptionStealth means that the $stealth modifier is set.
	OptionStealth

	// OptionEmpty means that the $empty modifier is set.
	//
	// TODO(ameshkov):  Get rid of it, as it is deprecated in favor of
	// $redirect.
	OptionEmpty

	// OptionMp4 means that the $mp4 modifier is set.
	//
	// TODO(ameshkov):  Get rid of it, as it is deprecated in favor of
	// $redirect.
	OptionMp4

	// OptionPopup means that the $popup modifier is set.
	OptionPopup

	// OptionCsp means that the $csp modifier is set.
	//
	// TODO(ameshkov):  Implement.
	OptionCsp

	// OptionReplace means that the $replace modifier is set.
	//
	// TODO(ameshkov):  Implement.
	OptionReplace

	// OptionCookie means that the $cookie modifier is set.
	//
	// TODO(ameshkov):  Implement.
	OptionCookie

	// OptionRedirect means that the $redirect modifier is set.
	//
	// TODO(ameshkov):  Implement.
	OptionRedirect

	// OptionBlacklistOnly are the blacklist-only options.
	OptionBlacklistOnly = OptionEmpty |
		OptionMp4 |
		OptionPopup

	// OptionWhitelistOnly are the whitelist-only options.
	OptionWhitelistOnly = OptionContent |
		OptionElemhide |
		OptionExtension |
		OptionGenericblock |
		OptionGenerichide |
		OptionJsinject |
		OptionStealth |
		OptionUrlblock

	// OptionHostLevelRulesOnly are the options supported by host-level network
	// rules.
	OptionHostLevelRulesOnly = OptionImportant | OptionBadfilter
)

NetworkRuleOption masks.

TODO(a.garipov): Rename to NetworkOptionFoo etc.

func (NetworkRuleOption) Count

func (o NetworkRuleOption) Count() (n int)

Count returns the number of enabled options.

type RCode added in v0.14.0

type RCode = int

RCode is a semantic alias for int when used as a DNS response code RCODE.

type RRType added in v0.14.0

type RRType = uint16

RRType is a semantic alias for uint16 when used as a DNS resource record (RR) type.

type RRValue added in v0.14.0

type RRValue = any

RRValue is the value of a resource record. Depending on the RRType, it will have different types:

type Request

type Request struct {
	// ClientTags is the set of tags to match against $ctag modifiers.
	ClientTags *container.SortedSliceSet[string]

	// ClientIdentifiers is the list of client IDs to match against $client
	// modifiers, if any.
	ClientIdentifiers *container.SortedSliceSet[string]

	// ClientIP is the IP address to match against $client modifiers, if any.
	ClientIP netip.Addr

	// URL is the full request URL.
	URL string

	// URLLowerCase is the full request URL in lower case.
	URLLowerCase string

	// Hostname is the hostname to filter.
	Hostname string

	// Domain is the effective top-level domain of the request with an
	// additional label.
	Domain string

	// SourceURL is the full URL of the source.
	SourceURL string

	// SourceHostname is the hostname of the source.
	SourceHostname string

	// SourceDomain is the effective top-level domain of the source with an
	// additional label.
	SourceDomain string

	// RequestType is the type of the filtering request.
	RequestType RequestType

	// DNSType is the type of the resource record (RR) of a DNS request, for
	// example A or AAAA.  See [RRValue] for all acceptable constants and their
	// corresponding values.
	DNSType uint16

	// ThirdParty is true if the filtering request should consider $third-party
	// modifier.
	ThirdParty bool

	// IsHostnameRequest means that the request is for a given Hostname, and not
	// for a URL, and we don't really know what protocol it is.  This can be
	// true for DNS requests, for HTTP CONNECT, or for SNI matching.
	IsHostnameRequest bool
}

Request is a web filtering request.

func NewRequest

func NewRequest(url, sourceURL string, requestType RequestType) (r *Request)

NewRequest returns a properly initialized *Request.

func NewRequestForHostname

func NewRequestForHostname(hostname string) (r *Request)

NewRequestForHostname creates a new instance of Request for matching the hostname. It uses "http://" as a protocol and TypeDocument as a request type.

type RequestType

type RequestType uint32

RequestType is a bitset of the types of a request to be filtered.

TODO(a.garipov): Consider switching to uint16.

const (
	// TypeDocument means the main frame.
	TypeDocument RequestType = 1 << iota

	// TypeSubdocument means iframe requests; see the $subdocument modifier.
	TypeSubdocument

	// TypeScript means JavaScript and other script requests; see the $script
	// modifier.
	TypeScript

	// TypeStylesheet means CSS requests; see the $stylesheet modifier.
	TypeStylesheet

	// TypeObject means Flash and similar objects; see the $object modifier.
	TypeObject

	// TypeImage means images; see the $image modifier.
	TypeImage

	// TypeXmlhttprequest means AJAX or fetch requests, see the $xmlhttprequest
	// modifier.
	TypeXmlhttprequest

	// TypeMedia means video, music, etc.; see the $media modifier.
	TypeMedia

	// TypeFont means any custom font; see the $font modifier.
	TypeFont

	// TypeWebsocket means a WebSocket connection; see the $websocket modifier.
	TypeWebsocket

	// TypePing means navigator.sendBeacon() or ping attribute on links; see the
	// $ping modifier.
	TypePing

	// TypeOther means any other request type.
	TypeOther
)

RequestType masks.

See https://adguard.com/kb/general/ad-filtering/create-own-filters/#content-type-modifiers.

TODO(a.garipov): Rename consistently.

func (RequestType) Count

func (t RequestType) Count() (n int)

Count returns the number of the enabled request types.

type Rule

type Rule interface {
	// Text returns the original rule text.
	//
	// TODO(a.garipov):  Replace with String.
	Text() (s string)

	// GetFilterListID returns ID of the filter list this rule belongs to.
	//
	// TODO(a.garipov):  Rename to ListID.
	GetFilterListID() (id ListID)
}

Rule is a base interface for all filtering rules.

TODO(a.garipov): Rename to Interface.

func NewRule

func NewRule(line string, id ListID) (r Rule, err error)

NewRule creates a new filtering rule from the specified line. It returns nil if the line is empty or if it is a comment.

type RuleSyntaxError

type RuleSyntaxError struct {
	// contains filtered or unexported fields
}

RuleSyntaxError represents an error while parsing a filtering rule.

TODO(a.garipov): Consider implementing errors.Wrapper.

func (*RuleSyntaxError) Error

func (e *RuleSyntaxError) Error() (s string)

Error implements the error interface for *RuleSyntaxError.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL