diff --git a/src/authoritative_name_server.rs b/src/authoritative_name_server.rs index 1e2a9563..8a911da7 100644 --- a/src/authoritative_name_server.rs +++ b/src/authoritative_name_server.rs @@ -2,13 +2,13 @@ use std::net::Ipv4Addr; use std::process::Child; use crate::container::Container; -use crate::record::{self, Referral, SoaSettings, Zone}; +use crate::record::{self, Referral, SoaSettings, ZoneFile}; use crate::{Domain, Result, CHMOD_RW_EVERYONE}; pub struct AuthoritativeNameServer<'a> { child: Child, container: Container, - zone: Zone<'a>, + zone_file: ZoneFile<'a>, } impl<'a> AuthoritativeNameServer<'a> { @@ -24,6 +24,7 @@ impl<'a> AuthoritativeNameServer<'a> { }) } + /// This is short-hand for `Self::reserve().start(/* .. */)` pub fn start( domain: Domain<'a>, referrals: &[Referral<'a>], @@ -37,11 +38,11 @@ impl<'a> AuthoritativeNameServer<'a> { } pub fn nameserver(&self) -> &Domain<'a> { - &self.zone.soa.ns + &self.zone_file.soa.ns } - pub fn zone(&self) -> &Zone<'a> { - &self.zone + pub fn zone_file(&self) -> &ZoneFile<'a> { + &self.zone_file } } @@ -74,9 +75,22 @@ impl StoppedAuthoritativeNameServer { &self.nameserver } + /// Starts a primary name server that has authority over the given `zone` + /// + /// The domain of the name server will have the form `primary{count}.nameservers.com.` where + /// `{count}` is a unique, monotonically increasing integer + /// + /// The zone will contain these records + /// + /// - one SOA record, with the primary name server set to the name server domain + /// - one NS record, with the name server domain set as the only available name server for + /// `zone` + /// - one A record, that maps the name server domain to its IPv4 address + /// - one NS + A record pair, for each referral in the `referrals` list + /// - the A records in the `a_records` list pub fn start<'a>( self, - domain: Domain<'a>, + zone: Domain<'a>, referrals: &[Referral<'a>], a_records: &[record::A<'a>], ) -> Result> { @@ -90,42 +104,42 @@ impl StoppedAuthoritativeNameServer { container.status_ok(&["mkdir", "-p", "/run/nsd/"])?; container.status_ok(&["mkdir", "-p", "/etc/nsd/zones"])?; - let zone_path = "/etc/nsd/zones/main.zone"; - container.cp("/etc/nsd/nsd.conf", &nsd_conf(&domain), CHMOD_RW_EVERYONE)?; + let zone_file_path = "/etc/nsd/zones/main.zone"; + container.cp("/etc/nsd/nsd.conf", &nsd_conf(&zone), CHMOD_RW_EVERYONE)?; let soa = record::Soa { - domain: domain.clone(), + domain: zone.clone(), ns: nameserver.clone(), admin: admin_ns(ns_count), settings: SoaSettings::default(), }; - let mut zone = Zone::new(domain.clone(), soa); + let mut zone_file = ZoneFile::new(zone.clone(), soa); - zone.record(record::Ns { - domain: domain.clone(), - ns: nameserver, + zone_file.record(record::Ns { + domain: zone.clone(), + ns: nameserver.clone(), }); - zone.record(record::A { - domain, + zone_file.record(record::A { + domain: nameserver, ipv4_addr: container.ipv4_addr(), }); for referral in referrals { - zone.referral(referral) + zone_file.referral(referral) } for a in a_records { - zone.record(a.clone()) + zone_file.record(a.clone()) } - container.cp(zone_path, &zone.to_string(), CHMOD_RW_EVERYONE)?; + container.cp(zone_file_path, &zone_file.to_string(), CHMOD_RW_EVERYONE)?; let child = container.spawn(&["nsd", "-d"])?; Ok(AuthoritativeNameServer { child, container, - zone, + zone_file, }) } } diff --git a/src/record.rs b/src/record.rs index c659e93a..0c3b7eb0 100644 --- a/src/record.rs +++ b/src/record.rs @@ -7,14 +7,14 @@ use std::net::Ipv4Addr; use crate::Domain; -pub struct Zone<'a> { +pub struct ZoneFile<'a> { pub origin: Domain<'a>, pub ttl: u32, pub soa: Soa<'a>, pub records: Vec>, } -impl<'a> Zone<'a> { +impl<'a> ZoneFile<'a> { /// Convenience constructor that uses "reasonable" defaults pub fn new(origin: Domain<'a>, soa: Soa<'a>) -> Self { Self { @@ -49,7 +49,7 @@ impl<'a> Zone<'a> { } } -impl fmt::Display for Zone<'_> { +impl fmt::Display for ZoneFile<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { origin, @@ -260,7 +260,7 @@ $TTL 1800 com. IN NS e.gtld-servers.net. e.gtld-servers.net. IN A 192.12.94.30 "; - let mut zone = Zone::new(Domain::ROOT, example_soa()?); + let mut zone = ZoneFile::new(Domain::ROOT, example_soa()?); zone.record(example_ns()?); zone.record(example_a()?); diff --git a/src/recursive_resolver.rs b/src/recursive_resolver.rs index c246fadc..c54afda8 100644 --- a/src/recursive_resolver.rs +++ b/src/recursive_resolver.rs @@ -74,7 +74,7 @@ mod tests { ], )?; - eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone()); + eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone_file()); let com_domain = Domain("com.")?; let com_ns = com_ns.start( @@ -87,7 +87,7 @@ mod tests { &[], )?; - eprintln!("com.zone:\n{}", com_ns.zone()); + eprintln!("com.zone:\n{}", com_ns.zone_file()); let root_ns = root_ns.start( Domain::ROOT, @@ -99,7 +99,7 @@ mod tests { &[], )?; - eprintln!("root.zone:\n{}", root_ns.zone()); + eprintln!("root.zone:\n{}", root_ns.zone_file()); let roots = &[Root::new(root_ns.nameserver().clone(), root_ns.ipv4_addr())]; let resolver = RecursiveResolver::start(roots)?;