Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report zonefile parsing & signing progress to the caller. #448

Draft
wants to merge 25 commits into
base: initial-nsec3-generation
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5ba8f8d
Rough hack to support reporting zonefile parsing progress to the caller.
ximon18 Nov 25, 2024
bc14779
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Nov 25, 2024
444788a
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 2, 2024
88d639f
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 2, 2024
eb68c39
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 3, 2024
f04f8a9
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 3, 2024
d3c3783
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 3, 2024
2a8816f
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 5, 2024
17717b5
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 5, 2024
f7a7a2c
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 5, 2024
a89d1ec
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 6, 2024
ccfae8c
Add a tab before the RDATA as well as within it, to match LDNS tabbed…
ximon18 Dec 6, 2024
41c78f2
Update changelog.
ximon18 Dec 6, 2024
b29a349
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 7, 2024
bae914c
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 9, 2024
83898e4
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 9, 2024
0a09d11
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 9, 2024
889dfdd
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 16, 2024
e30d3e5
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 16, 2024
59cd4bf
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 16, 2024
64a44b2
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 17, 2024
f805866
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 18, 2024
00b217d
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 18, 2024
17e0bfb
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 18, 2024
6ca119a
Merge branch 'byo-signing-sorter-impl' into report-signing-progress
ximon18 Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/read-zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() {
);
eprintln!(" Error: {err}");
if let Some(entry) = &last_entry {
if let Entry::Record(record) = &entry {
if let Entry::Record(record, _) = &entry {
eprintln!(
"\nThe last record read was:\n{record}."
);
Expand Down
2 changes: 1 addition & 1 deletion src/rdata/zonemd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ ns2 3600 IN AAAA 2001:db8::63
zone.set_origin(Name::root());
while let Some(entry) = zone.next_entry().unwrap() {
match entry {
Entry::Record(record) => {
Entry::Record(record, _) => {
if record.rtype() != Rtype::ZONEMD {
continue;
}
Expand Down
98 changes: 91 additions & 7 deletions src/sign/records.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ where
self.records.iter()
}

pub fn len(&self) -> usize {
self.records.len()
}

pub fn is_empty(&self) -> bool {
self.records.is_empty()
}

pub fn as_slice(&self) -> &[Record<N, D>] {
self.records.as_slice()
}
Expand Down Expand Up @@ -279,16 +287,18 @@ where
/// [RFC 5155]: https://www.rfc-editor.org/rfc/rfc5155.html
/// [RFC 9077]: https://www.rfc-editor.org/rfc/rfc9077.html
/// [RFC 9276]: https://www.rfc-editor.org/rfc/rfc9276.html
#[allow(clippy::too_many_arguments)]
// TODO: Move to Signer and do HashProvider = OnDemandNsec3HashProvider
// TODO: Does it make sense to take both Nsec3param AND HashProvider as input?
pub fn nsec3s<Octets, OctetsMut, HashProvider>(
pub fn nsec3s<Octets, OctetsMut, CB, HashProvider>(
&self,
apex: &FamilyName<N>,
ttl: Ttl,
params: Nsec3param<Octets>,
opt_out: Nsec3OptOut,
assume_dnskeys_will_be_added: bool,
hash_provider: &mut HashProvider,
progress_cb: CB,
) -> Result<Nsec3Records<N, Octets>, Nsec3HashError>
where
N: ToName + Clone + From<Name<Octets>> + Display + Ord + Hash,
Expand All @@ -303,6 +313,7 @@ where
+ EmptyBuilder
+ FreezeBuilder,
<OctetsMut as FreezeBuilder>::Octets: AsRef<[u8]>,
CB: Fn(usize, usize, Option<&'static str>),
HashProvider: Nsec3HashProvider<N, Octets>,
Nsec3<Octets>: Into<D>,
{
Expand Down Expand Up @@ -332,6 +343,9 @@ where
// The owner name of a zone cut if we currently are at or below one.
let mut cut: Option<FamilyName<N>> = None;

let num_families = self.families().count();
(progress_cb)(0, num_families, Some("Creating NSEC3 RRs"));

let mut families = self.families();

// Since the records are ordered, the first family is the apex --
Expand All @@ -353,12 +367,14 @@ where
// If the owner is out of zone, we have moved out of our zone and
// are done.
if !family.is_in_zone(apex) {
(progress_cb)(1, 0, None);
break;
}

// If the family is below a zone cut, we must ignore it.
if let Some(ref cut) = cut {
if family.owner().ends_with(cut.owner()) {
(progress_cb)(1, 0, None);
continue;
}
}
Expand All @@ -380,6 +396,7 @@ where
// delegations MAY be excluded."
let has_ds = family.records().any(|rec| rec.rtype() == Rtype::DS);
if cut.is_some() && !has_ds && opt_out == Nsec3OptOut::OptOut {
(progress_cb)(1, 0, None);
continue;
}

Expand Down Expand Up @@ -435,6 +452,7 @@ where
builder.append_origin(&apex_owner).unwrap().into();

if let Err(pos) = ents.binary_search(&name) {
(progress_cb)(n, 1, None);
ents.insert(pos, name);
}
}
Expand Down Expand Up @@ -487,8 +505,10 @@ where
last_nent_stack.push(last_nent);
}
last_nent_stack.push(name.owner().clone());
(progress_cb)(1, 1, None);
}

(progress_cb)(0, 0, Some("Creating ENTs NSEC3 RRs"));
for name in ents {
// Create the type bitmap, empty for an ENT NSEC3.
let bitmap = RtypeBitmap::<Octets>::builder();
Expand All @@ -511,14 +531,18 @@ where

// Store the record by order of its owner name.
nsec3s.push(rec);

(progress_cb)(1, 1, None);
}

// RFC 5155 7.1 step 7:
// "In each NSEC3 RR, insert the next hashed owner name by using the
// value of the next NSEC3 RR in hash order. The next hashed owner
// name of the last NSEC3 RR in the zone contains the value of the
// hashed owner name of the first NSEC3 RR in the hash order."
(progress_cb)(0, 0, Some("Sorting"));
let mut nsec3s = SortedRecords::<N, Nsec3<Octets>, S>::from(nsec3s);
(progress_cb)(0, 0, Some("Hashing NSEC3 owner names"));
for i in 1..=nsec3s.records.len() {
// TODO: Detect duplicate hashes.
let next_i = if i == nsec3s.records.len() { 0 } else { i };
Expand All @@ -536,6 +560,7 @@ where
let last_rec = &mut nsec3s.records[i - 1];
let last_nsec3: &mut Nsec3<Octets> = last_rec.data_mut();
last_nsec3.set_next_owner(owner_hash.clone());
(progress_cb)(1, 0, None);
}

// RFC 5155 7.1 step 8:
Expand Down Expand Up @@ -1287,50 +1312,78 @@ impl<Octs, Inner: SignRaw> SigningKeyUsageStrategy<Octs, Inner>
const NAME: &'static str = "Default key usage strategy";
}

pub trait ProgressReporter {
fn make_progress(&self, _increment: usize) {}

fn add_work(&self, _increment: usize) {}

fn change_phase(&self, _new_phase: &'static str) {}
}

impl ProgressReporter for () {}

pub struct Signer<
Octs,
Inner,
KeyStrat = DefaultSigningKeyUsageStrategy,
Sort = DefaultSorter,
Progress = (),
> where
Inner: SignRaw,
KeyStrat: SigningKeyUsageStrategy<Octs, Inner>,
Sort: Sorter,
Progress: ProgressReporter,
{
progress_reporter: Option<Progress>,

_phantom: PhantomData<(Octs, Inner, KeyStrat, Sort)>,
}

impl<Octs, Inner, KeyStrat, Sort> Default
for Signer<Octs, Inner, KeyStrat, Sort>
impl<Octs, Inner, KeyStrat, Sort, Progress> Default
for Signer<Octs, Inner, KeyStrat, Sort, Progress>
where
Inner: SignRaw,
KeyStrat: SigningKeyUsageStrategy<Octs, Inner>,
Sort: Sorter,
Progress: ProgressReporter,
{
fn default() -> Self {
Self::new()
}
}

impl<Octs, Inner, KeyStrat, Sort> Signer<Octs, Inner, KeyStrat, Sort>
impl<Octs, Inner, KeyStrat, Sort, Progress>
Signer<Octs, Inner, KeyStrat, Sort, Progress>
where
Inner: SignRaw,
KeyStrat: SigningKeyUsageStrategy<Octs, Inner>,
Sort: Sorter,
Progress: ProgressReporter,
{
pub fn new() -> Self {
Self {
progress_reporter: None,
_phantom: PhantomData,
}
}

pub fn with_progress_reporter(
mut self,
progress_reporter: Progress,
) -> Self {
self.progress_reporter = Some(progress_reporter);
self
}
}

impl<Octs, Inner, KeyStrat, Sort> Signer<Octs, Inner, KeyStrat, Sort>
impl<Octs, Inner, KeyStrat, Sort, Progress>
Signer<Octs, Inner, KeyStrat, Sort, Progress>
where
Octs: AsRef<[u8]> + From<Box<[u8]>> + OctetsFrom<Vec<u8>>,
Inner: SignRaw,
KeyStrat: SigningKeyUsageStrategy<Octs, Inner>,
Sort: Sorter,
Progress: ProgressReporter,
{
/// Sign a zone using the given keys.
///
Expand Down Expand Up @@ -1424,6 +1477,17 @@ where
}
}

if let Some(reporter) = &self.progress_reporter {
let (num_families_low, num_families_high) = families.size_hint();
let estimated_num_families = std::cmp::max(
num_families_low,
num_families_high.unwrap_or_default(),
);
reporter.add_work(estimated_num_families);
reporter.add_work(keys_in_use_idxs.len());
reporter.change_phase("Creating DNSKEYs");
}

let mut res: Vec<Record<N, ZoneRecordData<Octs, N>>> = Vec::new();
let mut buf = Vec::new();
let mut cut: Option<FamilyName<N>> = None;
Expand Down Expand Up @@ -1545,19 +1609,29 @@ where
);
}
}

if let Some(progress) = &self.progress_reporter {
progress.make_progress(1);
}
}

// For all RRSETs below the apex
for family in families {
// If the owner is out of zone, we have moved out of our zone and
// are done.
if !family.is_in_zone(apex) {
if let Some(progress) = &self.progress_reporter {
progress.make_progress(1);
}
break;
}

// If the family is below a zone cut, we must ignore it.
if let Some(ref cut) = cut {
if family.owner().ends_with(cut.owner()) {
if let Some(progress) = &self.progress_reporter {
progress.make_progress(1);
}
continue;
}
}
Expand Down Expand Up @@ -1605,6 +1679,10 @@ where
);
}
}

if let Some(progress) = &self.progress_reporter {
progress.make_progress(1);
}
}

debug!("Returning {} records from signing", res.len());
Expand Down Expand Up @@ -1726,7 +1804,10 @@ where
//------------ Nsec3HashProvider ---------------------------------------------

pub trait Nsec3HashProvider<N, Octs> {
fn get_or_create(&mut self, unhashed_owner_name: &N) -> Result<N, Nsec3HashError>;
fn get_or_create(
&mut self,
unhashed_owner_name: &N,
) -> Result<N, Nsec3HashError>;
}

pub struct OnDemandNsec3HashProvider<N, SaltOcts> {
Expand Down Expand Up @@ -1772,7 +1853,10 @@ where
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
SaltOcts: AsRef<[u8]>,
{
fn get_or_create(&mut self, unhashed_owner_name: &N) -> Result<N, Nsec3HashError> {
fn get_or_create(
&mut self,
unhashed_owner_name: &N,
) -> Result<N, Nsec3HashError> {
mk_hashed_nsec3_owner_name(
unhashed_owner_name,
self.alg,
Expand Down
4 changes: 2 additions & 2 deletions src/stelline/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,13 +778,13 @@ fn entry2msg(entry: &Entry) -> (&Sections, Reply, Message<Vec<u8>>) {
}
let mut msg = msg.authority();
for zone_file_entry in &sections.authority {
if let Record(rec) = zone_file_entry {
if let Record(rec, _) = zone_file_entry {
msg.push(rec).unwrap();
}
}
let mut msg = msg.additional();
for zone_file_entry in &sections.additional.zone_entries {
if let Record(rec) = zone_file_entry {
if let Record(rec, _) = zone_file_entry {
msg.push(rec).unwrap();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/stelline/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ fn match_section<
}
for (index, mat_rr) in match_section.iter().enumerate() {
// Remove outer Record
let mat_rr = if let ZonefileEntry::Record(record) = mat_rr {
let mat_rr = if let ZonefileEntry::Record(record, _) = mat_rr {
record
} else {
panic!("include not expected");
Expand Down
6 changes: 3 additions & 3 deletions src/stelline/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ where
}
let mut msg = msg.answer();
for a in &sections.answer[0] {
let rec = if let ZonefileEntry::Record(record) = a {
let rec = if let ZonefileEntry::Record(record, _) = a {
record
} else {
panic!("include not expected")
Expand All @@ -104,7 +104,7 @@ where
}
let mut msg = msg.authority();
for a in &sections.authority {
let rec = if let ZonefileEntry::Record(record) = a {
let rec = if let ZonefileEntry::Record(record, _) = a {
record
} else {
panic!("include not expected")
Expand All @@ -113,7 +113,7 @@ where
}
let mut msg = msg.additional();
for a in &sections.additional.zone_entries {
let rec = if let ZonefileEntry::Record(record) = a {
let rec = if let ZonefileEntry::Record(record, _) = a {
record
} else {
panic!("include not expected")
Expand Down
6 changes: 3 additions & 3 deletions src/validator/anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl TrustAnchors {
for e in zonefile {
let e = e?;
match e {
Entry::Record(r) => {
Entry::Record(r, _) => {
new_self.add(r);
}
Entry::Include { path: _, origin: _ } => continue, // Just ignore include
Expand All @@ -123,7 +123,7 @@ impl TrustAnchors {
for e in zonefile {
let e = e?;
match e {
Entry::Record(r) => {
Entry::Record(r, _) => {
new_self.add(r);
}
Entry::Include { path: _, origin: _ } => continue, // Just ignore include
Expand All @@ -142,7 +142,7 @@ impl TrustAnchors {
for e in zonefile {
let e = e?;
match e {
Entry::Record(r) => {
Entry::Record(r, _) => {
self.add(r);
}
Entry::Include { path: _, origin: _ } => continue, // Just ignore include
Expand Down
Loading
Loading