Expand description
Minimal DNS message parser scoped to what the SEAM-1 / L2-04 proxy needs.
Pure logic, no I/O. The proxy parses the wire-format query, makes an
allowlist decision against crate::dns_proxy::DnsProxyConfig::hostname_allowlist,
then either forwards the bytes verbatim upstream (allow path) or builds a
REFUSED response from the parsed view (deny path).
§Phase 2 scope (multi-question)
- Exactly one question on the hot path. A DNS message with
QDCOUNT == 0is rejected as malformed (nothing to evaluate). HIGH-D1 hardened the single-question API (parse_query) further: any packet declaringQDCOUNT != 1is rejected at the parser layer withDnsParseError::QdcountUnsupported. RFC 1035 §4.1.2 permitsQDCOUNT > 1, but real-world recursive resolvers (Unbound, Knot, BIND) serve at most the first question and the supervisor’s threat model (hostile guests) does not justify the policy-bypass / log-evasion surface that “parse first question, forward all bytes” exposes. The typed offline APIparse_query_multistill returns oneQuestionOutcomeper declared question for tools that legitimately need to walk multi-question packets (e.g. fixture inspection). - No pointer-compression in QNAME. RFC 1035 §4.1.4 allows a label to be replaced by a 2-byte pointer to an earlier label. Real workload-side queries almost never use compression — the questions section is the only labels the message carries — so the parser rejects pointers as a defense against malformed/adversarial inputs that could otherwise drive the parser into a cycle. Compression in responses is handled by passing the wire bytes through untouched on the allow path.
- IN class only.
qclass != 1is rejected for any question. - RFC 1035 length bounds. Labels capped at 63 octets; total QNAME capped at 253 octets (the RFC 1035 §3.1 maximum once you remove the trailing root label and the length prefixes).
§What the parser surfaces
DnsQueryView carries the transaction id (echoed back in the proxy’s
response when denying), the flags word (so the proxy can OR in QR=1 +
RCODE=REFUSED for the deny path), the lowercased trailing-dot-stripped
query name, and the raw wire-format qtype / qclass fields. The proxy
maps the raw qtype to the bounded cellos_core::DnsQueryType enum
via cellos_core::qtype_to_dns_query_type; query types outside that set
produce a denied_query_type decision rather than a parser error.
Structs§
- DnsQuery
View - Minimal view of a parsed single-question DNS query.
Enums§
- DnsParse
Error - Errors the parser can surface. Each maps to a
reasonCodeon the emitteddns_queryevent: - Question
Outcome - Per-question outcome returned by
parse_query_multi.
Functions§
- parse_
query - Parse the question section of a workload DNS query (single-question API).
- parse_
query_ multi - Parse every question declared by
QDCOUNTand return oneQuestionOutcomeper question.