Context and Policy Matchers
These matchers branch on marks, environment, time, probability, rate limits, or string expressions.
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.
time
Purpose
Matches the current wall-clock time against daily windows, weekdays, and days of the month.
Example Configuration
- tag: work_hours
type: time
args:
timezone: Asia/Shanghai
periods:
- start: "09:00"
end: "18:00"
weekdays: [mon, tue, wed, thu, fri]
- start: "22:00"
end: "02:00"
weekdays: [sat, sun]
- monthdays: [1, 15]
Configuration Details
timezone
- Type:
string; Required: no; Default: system timezone - Uses an IANA timezone name such as
Asia/ShanghaiorUTC. - When omitted, OxiDNS resolves the system timezone. Initialization fails if it is unavailable; the matcher never silently falls back to UTC.
periods
- Type:
array; Required: yes; Count:1..=64 - Each item may configure
start,end,weekdays, andmonthdays. - Items are ORed; all configured conditions inside one item are ANDed.
startandenduseHH:MMand must either both be set or both be omitted. Omitting both means all day, but requires a weekday or month-day condition.- Intervals use
[start, end); equal boundaries are invalid. Anendearlier thanstartcrosses midnight, and weekday/month-day conditions apply to the start date. weekdaysaccepts case-insensitivemonthroughsunor ISO weekday numbers1..=7(1is Monday and7is Sunday);monthdaysaccepts1..=31. A date absent from a month does not match.
quick setup
- matches: "time 09:00-18:00"
Quick setup supports one daily window in the system timezone. Use the full configuration for weekdays, days of the month, or an explicit timezone.
Behavior
- The matcher reads the real wall clock when it executes, so system clock corrections affect subsequent decisions immediately.
- A skipped local time during daylight saving time never occurs; both real instants in a repeated hour use the same local-clock rule.
- Linux and minimal containers using explicit IANA zones should provide
tzdata.
Typical Uses
- Route weekday office-hour traffic to a specific upstream.
- Switch cache, routing, or parental-control policies at night or on weekends.
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.