pub struct DataplaneDnssecValidator { /* private fields */ }Expand description
Dataplane DNSSEC validator handed to the proxy via
super::DnsProxyConfig::dnssec_validator.
Construct via DataplaneDnssecValidator::from_authority in
production (returns Ok(None) for mode = off so the proxy hot
path is unchanged), or via the test-only
DataplaneDnssecValidator::with_backend for unit tests.
Implementations§
Source§impl DataplaneDnssecValidator
impl DataplaneDnssecValidator
SEC-21 Phase 3h.1 — construct a validator from a parsed
DnsAuthority.
Returns:
Ok(None)when the first declared resolver has nodnssecblock or hasdnssec.validate = false— i.e. the cell opted out (mode = off). The proxy hot path stays byte-identical to today.Ok(Some(..))whendnssec.validate = true. The validator is ready to evaluate workload queries.fail_closedis taken fromdnssec.fail_closed(true → require, false → best_effort).Err(CellosError::InvalidSpec)whendnssec.trust_anchors_pathis set but the file is missing, symlinked, or oversized — the trust-anchor loader (reused fromcrate::resolver_refresh::dnssec::TrustAnchors) refuses to construct the validator silently. Surfacing this at activation time prevents a cell from running with a broken validator and a half-enforced policy.
Resolver selection: the first entry of auth.resolvers is
consulted; this matches the proxy’s existing
super::DnsProxyConfig::upstream_resolver_id convention (the
proxy talks to one upstream resolver per cell). Cells with multiple
resolvers and per-resolver DNSSEC policies are out of scope for
P3h.1.
Tokio context: this constructor does NOT call Handle::current()
— the production backend captures the handle lazily on the first
validate() call. This keeps from_authority callable from unit
tests that don’t have a runtime, while still letting production
(which always has a runtime) drive hickory.
Sourcepub fn is_require_mode(&self) -> bool
pub fn is_require_mode(&self) -> bool
true when the validator was constructed in require mode
(cell’s DnsAuthority set dnssec.fail_closed = true). Drives the
proxy’s SERVFAIL decision for Unsigned and Skip outcomes.
Sourcepub fn trust_anchor_source(&self) -> &str
pub fn trust_anchor_source(&self) -> &str
Trust-anchor source descriptor stamped into emitted events
("iana-default" or the basename of an operator-supplied file).
Sourcepub fn validate(
&self,
query: &[u8],
_upstream_answer: &[u8],
) -> DataplaneDnssecOutcome
pub fn validate( &self, query: &[u8], _upstream_answer: &[u8], ) -> DataplaneDnssecOutcome
Validate a single workload query.
query is the raw UDP payload the workload sent. _upstream_answer
is the raw upstream response — ignored under Option B: the
validator re-resolves the same (qname, qtype) through hickory
to produce an independent verdict (see module docs for why we
chose Option B over Option A).
The parameter is plumbed for forward-compat to a future Option-A migration that injects the raw answer into hickory’s validator (when hickory exposes such a knob).
§Type dispatch (post-A2)
validate() switches over the parsed qtype:
| Query type | Backend dispatched |
|---|---|
| A, AAAA | self.backend (hickory lookup_ip strategy) |
| CNAME, HTTPS, SVCB, MX, TXT | self.typed_backend (hickory generic lookup) |
| All others | Skip (call site policy: SERVFAIL in require, forward in best_effort) |
When self.typed_backend is None (validators built via the
pre-A2 Self::with_backend test constructor), CNAME/HTTPS/SVCB/MX/TXT
also Skip — preserving backward compatibility with the existing
P3h.1 test surface that asserts TXT + require → SERVFAIL.
§Outcomes
DataplaneDnssecOutcome::Skipfor query types outside the first-class set, or for first-class types when the typed-record backend is absent. Caller policy decides what to do (see module docs).DataplaneDnssecOutcome::Validatedwhen hickory’s bundled validator chained the response back to the configured anchors.DataplaneDnssecOutcome::Unsignedwhen the zone has no DNSSEC chain.DataplaneDnssecOutcome::Failedwhen the validator rejected the chain (RRSIG missing, signature bogus, or chained to a non-anchor key) OR the backend returned an I/O error (network timeout / SERVFAIL from upstream — fail-safe to Failed).
Trait Implementations§
Auto Trait Implementations§
impl Freeze for DataplaneDnssecValidator
impl !RefUnwindSafe for DataplaneDnssecValidator
impl Send for DataplaneDnssecValidator
impl Sync for DataplaneDnssecValidator
impl Unpin for DataplaneDnssecValidator
impl UnsafeUnpin for DataplaneDnssecValidator
impl !UnwindSafe for DataplaneDnssecValidator
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more