Profile Compilation¶
Profile compilation transforms the declarative configuration (service names, blocklist URLs, domain lists) into optimized runtime data structures for fast DNS query evaluation.
Compilation Process¶
flowchart LR
subgraph Input
S[Blocked Services]
BL[Blocklist URLs]
CR[Custom Rules]
AL[Allowlist]
RW[Rewrites]
end
subgraph Resolution
S --> |ServiceRegistry| SD[Service Domains]
BL --> |BlockListManager| BLD[Blocklist Domains]
CR --> |Parse| BLOCK[Block Rules]
CR --> |Parse @@| EXCEPT[Exception Rules]
end
subgraph Compiled Profile
SD --> BD[BlockedDomains<br/>HashSet]
BLD --> BD
BLOCK --> BD
AL --> AD[AllowedDomains<br/>HashSet]
EXCEPT --> AD
RW --> RWD[Rewrites<br/>Dictionary]
end
Service Expansion¶
When a profile includes blockedServices: ["youtube"], the ServiceRegistry resolves youtube to its domain list:
All service domains are added to BlockedDomains.
Blocklist Resolution¶
Blocklist URLs reference global entries in config.blockLists. The BlockListManager maintains a local cache of downloaded lists. During compilation:
- For each URL in the profile's
blockLists, look up the cached domain set - Add all domains to
BlockedDomains - Skip disabled blocklists
Custom Rule Parsing¶
Custom rules are split into block and allow rules:
- Lines starting with
@@have the prefix stripped and are added toAllowedDomains - Lines starting with
#are comments (ignored) - All other non-empty lines are added to
BlockedDomains
Base Profile Merging¶
When a base profile is configured and the profile being compiled is not the base itself:
- Compile the base profile first
- Merge
BlockedDomains: union of base + profile - Merge
AllowedDomains: union of base + profile - Merge
Rewrites: union, with the child profile's entries winning on conflict
This happens at compile time, not at query time. The resulting compiled profile contains all inherited data.
Recompilation Triggers¶
Profiles are recompiled when:
- Configuration is reloaded (any change via web UI)
- Blocklists are refreshed (background timer or manual refresh)
Recompilation produces a new Dictionary<string, CompiledProfile> that is swapped in atomically via a volatile reference. In-flight queries continue using the old compiled data until they complete.