pub struct ResolverRefresh<'a> {
pub policy: Option<&'a DnsRefreshPolicy>,
pub rebinding_policy: Option<&'a DnsRebindingPolicy>,
pub resolvers: &'a [DnsResolver],
pub hostnames: &'a [String],
pub keyset_id: Option<&'a str>,
pub issuer_kid: Option<&'a str>,
pub policy_digest: Option<&'a str>,
pub correlation_id: Option<&'a str>,
pub source: Option<&'a str>,
pub dnssec_policy: Option<&'a DnsResolverDnssecPolicy>,
pub trust_anchors: Option<&'a TrustAnchors>,
}Expand description
One refresh-tick execution.
Borrows the spec-side configuration (no allocation), runs each declared hostname through the injected resolver, and produces drift CloudEvents the caller publishes via the configured event sink.
Fields§
§policy: Option<&'a DnsRefreshPolicy>Refresh policy from spec.authority.dnsAuthority.refreshPolicy.
None → defaults: no floor, no ceiling, ttl-honor strategy.
rebinding_policy: Option<&'a DnsRebindingPolicy>SEC-21 Phase 3e — DNS rebinding mitigation policy from
spec.authority.dnsAuthority.rebindingPolicy. None → no
per-hostname response-IP tracking. Combined with the P3a TTL floor
(policy.min_ttl_seconds), this structurally closes the v0.4.0
rebinding residual.
resolvers: &'a [DnsResolver]Declared resolvers from spec.authority.dnsAuthority.resolvers[].
The first entry’s resolverId is used as the event’s resolverId
when present; the empty string is used when none are declared.
hostnames: &'a [String]Hostnames the supervisor may refresh — typically derived from
spec.authority.egressRules[].host ∪
spec.authority.dnsAuthority.hostnameAllowlist.
keyset_id: Option<&'a str>Optional keysetId to bind into emitted events.
issuer_kid: Option<&'a str>Optional issuerKid to bind into emitted events.
policy_digest: Option<&'a str>Optional policy-bundle digest (sha256:<hex>) to bind into emitted events.
correlation_id: Option<&'a str>Optional pass-through correlation id.
source: Option<&'a str>CloudEvent source field — defaults to cellos-supervisor when the
caller passes None.
dnssec_policy: Option<&'a DnsResolverDnssecPolicy>SEC-21 Phase 3h — opt-in DNSSEC validation policy. None (default)
preserves P3a/P3e behaviour exactly: no validation, no
dns_authority_dnssec_failed events, no dnssec_status tagging on
drift events. When Some, the Self::tick_with_dnssec method
honours validate / failClosed per resolver — see method docs.
trust_anchors: Option<&'a TrustAnchors>Trust anchors loaded from the env / spec / IANA-default precedence
chain. Used purely for stamping the source descriptor into emitted
events; hickory 0.24’s resolver does not accept custom anchors via
public API. See [super::dnssec] module docs for the residual.
Implementations§
Source§impl<'a> ResolverRefresh<'a>
impl<'a> ResolverRefresh<'a>
Sourcepub fn tick(
&self,
state: &mut ResolverState,
resolver: &ResolverFn<'_>,
now: SystemTime,
cell_id: &str,
run_id: &str,
) -> Vec<CloudEventV1>
pub fn tick( &self, state: &mut ResolverState, resolver: &ResolverFn<'_>, now: SystemTime, cell_id: &str, run_id: &str, ) -> Vec<CloudEventV1>
Run one refresh tick.
For each declared hostname:
- If the strategy is
manual, skip (operator must opt in). - If
min_ttl_secondssays we refreshed recently, skip — unlessmax_stale_secondshas been exceeded (ceiling overrides floor). - Call the injected resolver. On error: leave prior state untouched and emit no event (transient failures are not drift).
- Canonicalize, hash, compare against prior digest.
- On change, build a
DnsAuthorityDriftpayload, wrap it in a CloudEvent envelope, and append to the returned vector. - Update
statewith the new observation.
Returns the events the caller should publish — possibly empty.
Sourcepub fn tick_with_rebinding(
&self,
state: &mut ResolverState,
rebinding_state: &mut RebindingState,
resolver: &ResolverFn<'_>,
now: SystemTime,
cell_id: &str,
run_id: &str,
) -> Vec<CloudEventV1>
pub fn tick_with_rebinding( &self, state: &mut ResolverState, rebinding_state: &mut RebindingState, resolver: &ResolverFn<'_>, now: SystemTime, cell_id: &str, run_id: &str, ) -> Vec<CloudEventV1>
SEC-21 Phase 3e variant of Self::tick that also threads a
per-cell RebindingState for DNS rebinding mitigation.
Behaves identically to tick when self.rebinding_policy is
None: emits only dns_authority_drift events, never touches
rebinding_state. When rebinding_policy is Some:
- Resolves every hostname (same as
tick). - For each successful resolution, calls
RebindingState::evaluateto decide which IPs are novel, whether the per-hostname cap is exceeded, and which IPs violate the operator allowlist. - Emits one
dns_authority_rebind_thresholdper hostname when the cap is exceeded, and onedns_authority_rebind_rejectedper allowlist violation. - Stamps the EFFECTIVE targets (post-rejection when
reject_on_rebind=true) into the subsequentdns_authority_driftevent so the drift digest reflects what the workload actually resolves to. - Calls
RebindingState::commitwith the effective targets so the per-cell history persists across ticks.
Source§impl<'a> ResolverRefresh<'a>
impl<'a> ResolverRefresh<'a>
Sourcepub fn tick_with_dnssec(
&self,
state: &mut ResolverState,
rebinding_state: &mut RebindingState,
validated_resolved: &HashMap<String, Result<ValidatedResolvedAnswer>>,
now: SystemTime,
cell_id: &str,
run_id: &str,
) -> Vec<CloudEventV1>
pub fn tick_with_dnssec( &self, state: &mut ResolverState, rebinding_state: &mut RebindingState, validated_resolved: &HashMap<String, Result<ValidatedResolvedAnswer>>, now: SystemTime, cell_id: &str, run_id: &str, ) -> Vec<CloudEventV1>
SEC-21 Phase 3h variant of Self::tick_with_rebinding that
also processes DNSSEC validation outcomes per hostname.
Behaviour:
- When
self.dnssec_policyisNone, this method behaves exactly likeSelf::tick_with_rebindingexcept it pulls per-hostname answers fromvalidated_resolvedand stampsdnssec_status: not_attemptedon every emitted drift event. - When
self.dnssec_policyisSome(policy):Validated→dnssec_status: validated, normal flow.Failed{reason}→ emitdns_authority_dnssec_failed(reason:validation_failed); whenpolicy.fail_closed, dropanswer.targetsto empty BEFORE the rebinding evaluator runs and tag driftdnssec_status: validation_failed.Unsigned→ emitdns_authority_dnssec_failed(reason:unsigned_zone); samefail_closedsemantics.
Order: dnssec_failed events are emitted BEFORE the drift / rebinding events for that hostname so a SIEM sees them in causal order (“dnssec_failed → drift”).
Auto Trait Implementations§
impl<'a> Freeze for ResolverRefresh<'a>
impl<'a> RefUnwindSafe for ResolverRefresh<'a>
impl<'a> Send for ResolverRefresh<'a>
impl<'a> Sync for ResolverRefresh<'a>
impl<'a> Unpin for ResolverRefresh<'a>
impl<'a> UnsafeUnpin for ResolverRefresh<'a>
impl<'a> UnwindSafe for ResolverRefresh<'a>
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