Matcher Plugins
Matcher plugins return true or false. They are mainly used by sequence.matches.
Matcher Expression Rules
Inside sequence, quick-setup matcher expressions are usually the clearest form to start with:
- matches:
- "client_ip $lan_ip_set"
- "qtype A,28"
exec: "$forward_main"
Other quick-setup matchers can be combined in the same way:
- matches:
- "qname domain:example.com"
- "qclass IN,3"
exec: "$forward_main"
Negation:
- matches: "!has_resp"
exec: "$forward_main"
any_match
Purpose
Composes multiple matcher expressions and returns true when any one of them matches.
Example Configuration
- tag: any_policy_hit
type: any_match
args:
- "$lan_clients"
- "qtype AAAA"
- "!$blocked_qname"
Configuration Details
any_match uses an array[string] args list.
- Type:
array[string]; Required: yes; Default: none - Supported entries:
- matcher tag references (for example
"$match_tag") - quick-setup matcher expressions (for example
"qname domain:example.com") - negated matcher expressions (for example
"!has_resp"or"!$blocked_qname")
- matcher tag references (for example
- Runtime impact:
- Evaluates entries in order and short-circuits on the first matched entry.
- Returns
falseonly when all entries fail.
Typical Uses
- Reuse one logical OR matcher across multiple sequence rules.
- Keep complex branching readable by moving OR conditions into one matcher.
qname
Purpose
Matches the query name in the request.
Example Configuration
- tag: match_domain
type: qname
args:
# Exact match
- "full:login.example.com"
# Suffix match
- "domain:example.com"
# Keyword match
- "keyword:cdn"
# Regex match
- "regexp:^api[0-9]+\\.example\\.net$"
# Reuse an existing domain-capable provider
- "$core_domains"
# Load rules from file
- "&/etc/oxidns/domains.txt"
Configuration Details
args is a rule list.
- Type:
array; Required: yes; Default: none - Supported items:
- domain expressions, supporting
full:,domain:,keyword:,regexp:, and bare domains without a prefix asdomain:rules - provider references with domain match capability, such as
domain_setorgeosite - file references
- domain expressions, supporting
- Runtime impact:
- Returns
truewhen any question name matches any configured rule.
- Returns
quick setup
- matches: "qname domain:example.com"
Typical Uses
- Route by suffix, keyword, or regex.
question
Purpose
Matches request questions using provider implementations of contains_question.
The matcher scans every question in the current request. It returns true as
soon as any question is matched by any referenced provider.
Example Configuration
- tag: match_ad
type: question
args:
- "$ad_rules"
- "$shared_domains"
Configuration Details
args- Type:
array[string]; Required: yes; Default: none - Purpose: References providers that implement
contains_questionusing"$provider_tag"entries.
- Type:
quick setup
- matches: "question $ad_rules"
Behavior
- Scans all questions in the request.
- Returns
truewhen any question is matched by any referenced provider. - quick setup supports the same
"$provider_tag"entries.
Typical Uses
- Let providers such as
adguard_rule,domain_set, orgeositeparticipate directly in question-level matching. - Branch in
sequence, then hand off toblack_hole,reject, or another executor.
qtype
Purpose
Matches request qtypes.
Example Configuration
This example mixes text and numeric forms. Both formats are equivalent and can be used together.
- tag: only_a_aaaa
type: qtype
args:
- "A"
- "28"
Configuration Details
- Type:
array; Required: yes; Default: none - Supports both enum text and decimal numeric codes; text matching is case-insensitive, and both formats can be mixed in the same list.
- Common mappings and meanings are listed in the DNS Code Reference.
- Unknown or future qtypes can still be matched with numeric codes.
- Runtime impact:
- Returns
trueif any question type matches the configured set.
- Returns
quick setup
- matches: "qtype A,28"
Typical Uses
- Split A, AAAA, PTR, TXT, and other query classes of traffic.
qclass
Purpose
Matches request qclasses.
Example Configuration
This example mixes text and numeric forms. Both formats are equivalent and can be used together.
- tag: in_or_ch
type: qclass
args:
- "IN"
- "3"
Configuration Details
- Type:
array; Required: yes; Default: none - Supports both enum text and decimal numeric codes; text matching is case-insensitive, and both formats can be mixed in the same list.
- Common mappings and meanings are listed in the DNS Code Reference.
- Unknown or future qclasses can still be matched with numeric codes.
- Runtime impact:
- Returns
trueif any question class matches the configured set.
- Returns
quick setup
- matches: "qclass IN,3"
Typical Uses
- Restrict handling to
INqueries.
client_ip
Purpose
Matches the client source IP.
Example Configuration
- tag: lan_clients
type: client_ip
args:
# Inline CIDR
- "192.168.0.0/16"
# Reference an IP-capable provider
- "$lan_ip_set"
Configuration Details
- Type:
array; Required: yes; Default: none - Supported items:
- single IPs
- CIDRs
- provider references with IP match capability, such as
ip_setorgeoip
- Runtime impact:
- Returns
truewhen the client source address matches any rule.
- Returns
quick setup
- matches: "client_ip 192.168.1.0/24"
Typical Uses
- Split policies by source subnet.
resp_ip
Purpose
Matches A and AAAA addresses in the response answers.
Example Configuration
- tag: matched_resp_ip
type: resp_ip
args:
- "100.64.0.0/10"
- "$special_targets"
Configuration Details
- Type:
array; Required: yes; Default: none - Supported items:
- single IPs
- CIDRs
- provider references with IP match capability, such as
ip_setorgeoip
- Runtime impact:
- Returns
truewhen any A or AAAA answer IP matches any rule.
- Returns
quick setup
- matches: "resp_ip 10.0.0.0/8"
Typical Uses
- Trigger side effects based on returned answer addresses.
ptr_ip
Purpose
Matches the IP encoded in a PTR query name.
Example Configuration
Similar to client_ip and resp_ip, it supports IP rules and IP-capable providers such as ip_set and geoip.
Configuration Details
- Type:
array; Required: yes; Default: none - Supported items:
- single IPs
- CIDRs
- provider references with IP match capability, such as
ip_setorgeoip
- Runtime impact:
- Extracts the reverse-mapped IP from the PTR name and matches it against the configured rules.
quick setup
- matches: "ptr_ip 192.168.0.0/16"
Typical Uses
- Separate handling for reverse-lookups of specific address spaces.
cname
Purpose
Matches CNAME targets in the response.
Example Configuration
- tag: cname_target
type: cname
args:
- "full:alias.example.com"
- "domain:example.com"
- "keyword:cdn"
- "regexp:^edge[0-9]+\\.example\\.net$"
- "$core_domains"
- "&/etc/oxidns/cnames.txt"
Configuration Details
- Type:
array; Required: yes; Default: none - Supported items:
- domain expressions, supporting
full:,domain:,keyword:,regexp:, and bare domains without a prefix asdomain:rules - provider references with domain match capability, such as
domain_setorgeosite - file references
- domain expressions, supporting
- Runtime impact:
- Returns
truewhen any CNAME target in the response matches.
- Returns
quick setup
- matches: "cname keyword:cdn"
Typical Uses
- Branch on canonical names returned by upstreams.
rcode
Purpose
Matches the current response code.
Example Configuration
This example mixes text and numeric forms. Both formats are equivalent and can be used together.
- tag: failure_rcodes
type: rcode
args:
- "SERVFAIL"
- "3"
Configuration Details
- Type:
array; Required: yes; Default: none - Supports both enum text and decimal numeric codes; text matching is case-insensitive, and both formats can be mixed in the same list.
- Common mappings and meanings are listed in the DNS Code Reference.
- Unknown or future rcodes can still be matched with numeric codes.
- Runtime impact:
- Returns
truewhen the response rcode matches the configured set.
- Returns
quick setup
- matches: "rcode SERVFAIL,3"
Typical Uses
- Follow-up handling for upstream failures or negative responses.
has_resp
Purpose
Matches whether a response already exists in the context.
Example Configuration
- tag: has_resp_flag
type: has_resp
Configuration Details
No standalone configuration fields.
quick setup
- matches: "has_resp"
Typical Uses
- Guard forwarding so it only runs when no earlier plugin has answered.
has_wanted_ans
Purpose
Matches whether the response already contains wanted answers.
Example Configuration
- tag: has_wanted_answer
type: has_wanted_ans
Configuration Details
No standalone configuration fields.
quick setup
- matches: "has_wanted_ans"
Typical Uses
- Build follow-up logic only when a meaningful answer is already present.
mark
Purpose
Matches marks already written into the DNS context.
Example Configuration
- tag: marked_100
type: mark
args:
- "100"
- "200"
Configuration Details
- Type:
array; Required: yes; Default: none - Supports integer mark values.
- Multiple marks can be separated by commas or whitespace.
- Runtime impact:
- Returns
trueif any configured mark exists in the context.
- Returns
quick setup
- matches: "mark 100 200"
Typical Uses
- Branch across phases after earlier decisions set marks.
env
Purpose
Matches environment variables.
Example Configuration
- tag: env_profile_prod
type: env
args:
- "PROFILE=prod"
- "FEATURE_X"
Or check only existence:
args:
- "FEATURE_X"
Configuration Details
- Type:
array; Required: yes; Default: none - Each item is an environment expression; all expressions must match.
- Typical forms:
KEY=VALUEfor exact value matching; recommended for environment variables.KEY:VALUEas an equivalent rule-expression-style alias.KEYKEY:orKEY=for explicit existence checks.
- Each string item in the array is parsed as one complete expression and is not split on commas or whitespace, so values such as
NO_PROXY=localhost,127.0.0.1orGREETING=hello worldshould be written as their own quoted array item. - Runtime impact:
- Lets one config behave differently across environments without editing the policy graph itself.
quick setup
- matches: "env PROFILE=prod FEATURE_X"
Behavior
KEY=VALUEandKEY:VALUErequire an exact match.KEYchecks only for existence.KEY:andKEY=also check only for existence.["PROFILE", "prod"]checks that bothPROFILEandprodexist; it does not meanPROFILE == prod.- quick setup separates expressions with whitespace; use the full
argsarray when a value itself contains spaces. - Values are cached during plugin initialization and are not re-read per request.
Typical Uses
- Toggle policy branches by deployment environment.
random
Purpose
Matches probabilistically for rollout or sampling.
Example Configuration
- tag: rollout_10p
type: random
args:
- "0.1"
Configuration Details
- Type:
number; Required: yes; Default: none - Meaning: Probability between
0and1. - Runtime impact:
- Returns
trueaccording to the configured sampling ratio.
- Returns
quick setup
- matches: "random 0.05"
Typical Uses
- Gradual rollout.
- Sampling for observability or experiments.
rate_limiter
Purpose
Matches based on per-source rate-limit state.
Example Configuration
- tag: qps_guard
type: rate_limiter
args:
qps: 20
burst: 40
mask4: 32
mask6: 48
Configuration Details
qps
- Type:
integer; Required: yes - Meaning: Steady-state queries per second.
burst
- Type:
integer; Required: no - Meaning: Burst allowance above steady-state rate.
mask4
- Type:
integer; Required: no - Meaning: IPv4 aggregation mask for clients.
mask6
- Type:
integer; Required: no - Meaning: IPv6 aggregation mask for clients.
quick setup
Prefer the full configuration so qps, burst, and mask stay explicit.
Behavior
- Applies rate limiting per source prefix rather than only per exact IP.
- Useful for protecting upstreams or constraining abusive traffic.
Metrics
Exported through the global GET /api/metrics endpoint:
ratelimit_allowed_totalratelimit_rejected_total
Typical Uses
- Query throttling.
- Split normal traffic and over-limit traffic into different branches.
string_exp
Purpose
Matches using a string expression over request and response context.
Example Configuration
- tag: match_http_path
type: string_exp
args: "url_path prefix /dns-"
It also supports a string array:
args:
- "client_ip"
- "prefix"
- "192.168."
Configuration Details
-
string_expargscan be a string or a string array. -
Type:
stringorarray -
Required: yes
-
Default: none
-
Purpose: Defines the complete string expression.
-
Expression parts:
- data source
source - matching operator
op - one or more arguments
- data source
-
Runtime impact:
- Reads values from the context according to the expression and performs string matching.
Expression Format
<source> <op> <arg...>
Supported source values:
qnameqtypeqclassrcoderesp_ipmarkclient_ipserver_nameurl_path$ENV_KEY
Supported op values:
eqprefixsuffixcontainsregexpzl
zlmeans zero length and is used to determine whether a string is empty.regexpsupports one or more regex arguments.
quick setup
- matches: "string_exp server_name suffix .example.net"
Typical Uses
- Perform flexible matching on DoH paths, SNI, mark sets, and response IP strings.
- In scenarios where a dedicated matcher can be used, prefer the dedicated matcher.
string_expprovides greater flexibility, but the readability and maintainability of the expression are usually lower than those of dedicated plugins.
_true
Purpose
Always returns true.
Example Configuration
- tag: always_true
type: _true
Configuration Details
No standalone configuration fields.
quick setup
- matches: "_true"
Typical Uses
- Fallback match condition.
- Testing rule order in a
sequence.
_false
Purpose
Always returns false.
Example Configuration
- tag: always_false
type: _false
Configuration Details
No standalone configuration fields.
quick setup
- matches: "_false"
Typical Uses
- Temporarily disable a branch.