use cfg_if::cfg_if;
#[cfg(feature = "dnssec")]
use crate::proto::rr::{
dnssec::{rdata::key::KEY, DnsSecResult, SigSigner, SupportedAlgorithms},
Name,
};
use crate::{
authority::{LookupError, MessageRequest, UpdateResult, ZoneType},
proto::rr::{LowerName, RecordSet, RecordType, RrsetRecords},
server::RequestInfo,
};
#[derive(Clone, Copy, Debug, Default)]
pub struct LookupOptions {
is_dnssec: bool,
#[cfg(feature = "dnssec")]
supported_algorithms: SupportedAlgorithms,
}
impl LookupOptions {
#[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
pub fn for_dnssec(is_dnssec: bool, supported_algorithms: SupportedAlgorithms) -> Self {
Self {
is_dnssec,
supported_algorithms,
}
}
#[allow(clippy::needless_update)]
pub fn set_is_dnssec(self, val: bool) -> Self {
Self {
is_dnssec: val,
..self
}
}
pub fn is_dnssec(&self) -> bool {
self.is_dnssec
}
#[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
pub fn set_supported_algorithms(self, val: SupportedAlgorithms) -> Self {
Self {
supported_algorithms: val,
..self
}
}
#[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
pub fn supported_algorithms(&self) -> SupportedAlgorithms {
self.supported_algorithms
}
pub fn rrset_with_supported_algorithms<'r>(
&self,
record_set: &'r RecordSet,
) -> RrsetRecords<'r> {
cfg_if! {
if #[cfg(feature = "dnssec")] {
record_set.records(
self.is_dnssec(),
self.supported_algorithms(),
)
} else {
record_set.records_without_rrsigs()
}
}
}
}
#[async_trait::async_trait]
pub trait Authority: Send + Sync {
type Lookup: Send + Sync + Sized + 'static;
fn zone_type(&self) -> ZoneType;
fn is_axfr_allowed(&self) -> bool;
async fn update(&self, update: &MessageRequest) -> UpdateResult<bool>;
fn origin(&self) -> &LowerName;
async fn lookup(
&self,
name: &LowerName,
rtype: RecordType,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError>;
async fn search(
&self,
request: RequestInfo<'_>,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError>;
async fn ns(&self, lookup_options: LookupOptions) -> Result<Self::Lookup, LookupError> {
self.lookup(self.origin(), RecordType::NS, lookup_options)
.await
}
async fn get_nsec_records(
&self,
name: &LowerName,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError>;
async fn soa(&self) -> Result<Self::Lookup, LookupError> {
self.lookup(self.origin(), RecordType::SOA, LookupOptions::default())
.await
}
async fn soa_secure(&self, lookup_options: LookupOptions) -> Result<Self::Lookup, LookupError> {
self.lookup(self.origin(), RecordType::SOA, lookup_options)
.await
}
}
#[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
#[async_trait::async_trait]
pub trait DnssecAuthority: Authority {
async fn add_update_auth_key(&self, name: Name, key: KEY) -> DnsSecResult<()>;
async fn add_zone_signing_key(&self, signer: SigSigner) -> DnsSecResult<()>;
async fn secure_zone(&self) -> DnsSecResult<()>;
}