Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
106 changes: 82 additions & 24 deletions crates/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,6 @@ pub enum ZoneReviewStatus {

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SigningReport {
pub current_action: String,
pub stage_report: SigningStageReport,
}

Expand All @@ -554,40 +553,99 @@ pub struct SigningRequestedReport {
pub requested_at: SystemTime,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum SigningStep {
Full(FullSigningStep),
Incremental(IncrementalSigningStep),
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum FullSigningStep {
CollectingRecords,
FetchingKeys,
SortingRecords,
GeneratingDenialRecords,
GeneratingSignatureRecords,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum IncrementalSigningStep {
CollectingRecords,
GeneratingSignatures,
GeneratingDiffs,
DeterminingMinExpirationTime,
}

impl SigningStep {
pub fn as_str(&self) -> &str {
match self {
SigningStep::Full(s) => match s {
FullSigningStep::CollectingRecords => "collecting records",
FullSigningStep::FetchingKeys => "fetching keys",
FullSigningStep::SortingRecords => "sorting records",
FullSigningStep::GeneratingDenialRecords => "generating denial records",
FullSigningStep::GeneratingSignatureRecords => "generating signature records",
},
SigningStep::Incremental(s) => match s {
IncrementalSigningStep::CollectingRecords => "collecting records",
IncrementalSigningStep::GeneratingSignatures => "generating signatures",
IncrementalSigningStep::GeneratingDiffs => "generating diffs",
IncrementalSigningStep::DeterminingMinExpirationTime => {
"determining min expiration time"
}
},
}
}

pub fn signing_strategy(&self) -> &str {
match self {
SigningStep::Full(_) => "full",
SigningStep::Incremental(_) => "incremental",
}
}

pub fn get_current_step(&self) -> usize {
match self {
SigningStep::Full(s) => match s {
FullSigningStep::CollectingRecords => 1,
FullSigningStep::FetchingKeys => 2,
FullSigningStep::SortingRecords => 3,
FullSigningStep::GeneratingDenialRecords => 4,
FullSigningStep::GeneratingSignatureRecords => 5,
},
SigningStep::Incremental(s) => match s {
IncrementalSigningStep::CollectingRecords => 1,
IncrementalSigningStep::GeneratingSignatures => 2,
IncrementalSigningStep::GeneratingDiffs => 3,
IncrementalSigningStep::DeterminingMinExpirationTime => 4,
},
}
}

pub fn get_total_steps(&self) -> usize {
match self {
SigningStep::Full(_) => 5,
SigningStep::Incremental(_) => 4,
}
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SigningInProgressReport {
pub step: SigningStep,
pub requested_at: SystemTime,
pub zone_serial: Serial,
pub loaded_serial: Serial,
pub signed_serial: Serial,
pub started_at: SystemTime,
pub unsigned_rr_count: Option<usize>,
pub walk_time: Option<Duration>,
pub sort_time: Option<Duration>,
pub denial_rr_count: Option<usize>,
pub denial_time: Option<Duration>,
pub rrsig_count: Option<usize>,
pub rrsig_reused_count: Option<usize>,
pub rrsig_time: Option<Duration>,
pub total_time: Option<Duration>,
pub threads_used: Option<usize>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SigningFinishedReport {
pub requested_at: SystemTime,
pub zone_serial: Serial,
pub loaded_serial: Serial,
pub signed_serial: Serial,
pub started_at: SystemTime,
pub unsigned_rr_count: usize,
pub walk_time: Duration,
pub sort_time: Duration,
pub denial_rr_count: usize,
pub denial_time: Duration,
pub rrsig_count: usize,
pub rrsig_reused_count: usize,
pub rrsig_time: Duration,
pub total_time: Duration,
pub threads_used: usize,
pub finished_at: SystemTime,
pub succeeded: bool,
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
Expand Down
12 changes: 6 additions & 6 deletions crates/cli/src/commands/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,24 +105,24 @@ impl Status {
println!(" {:>2}: {:<25} {:<16} Action", "#", "When", "Zone");
for (i, report) in response.signing_queue.iter().enumerate() {
let zone_name = report.zone_name.to_string();
let action = &report.signing_report.current_action;
let (colour, state, when) = match &report.signing_report.stage_report {
let (colour, state, when, step) = match &report.signing_report.stage_report
{
SigningStageReport::Requested(r) => {
(ansi::GRAY, "\u{23F8}", r.requested_at)
(ansi::GRAY, "\u{23F8}", r.requested_at, "requested")
}
SigningStageReport::InProgress(r) => {
(ansi::YELLOW, "\u{23F5}", r.started_at)
(ansi::YELLOW, "\u{23F5}", r.started_at, r.step.as_str())
}
SigningStageReport::Finished(r) => {
(ansi::GREEN, "\u{2714}", r.finished_at)
(ansi::GREEN, "\u{2714}", r.finished_at, "finished")
}
};
let when = jiff::Timestamp::try_from(when)
.unwrap()
.round(jiff::Unit::Second)
.unwrap();
println!(
" {i:>2}: {colour}{state}{} {when:<25} {zone_name:<16} {action}",
" {i:>2}: {colour}{state}{} {when:<25} {zone_name:<16} {step}",
ansi::RESET
);
}
Expand Down
32 changes: 25 additions & 7 deletions crates/cli/src/commands/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,12 +725,7 @@ pub fn print_status(zone: &ZoneStatus, policy: &PolicyInfo) {
current,
&zone.unsigned_review_addr,
);
print_sign_phase(
current,
zone.unsigned_serial,
zone.signed_serial,
&zone.signing_report,
);
print_sign_phase(current, zone.unsigned_serial, &zone.signing_report);
print_signed_review_phase(
&zone.name,
zone.signed_serial,
Expand Down Expand Up @@ -849,9 +844,14 @@ fn print_loaded_review_phase(
fn print_sign_phase(
current: Progress,
unsigned_serial: Option<Serial>,
signed_serial: Option<Serial>,
signing_report: &Option<SigningReport>,
) {
let signed_serial = signing_report.as_ref().and_then(|r| match &r.stage_report {
SigningStageReport::Requested(_) => None,
SigningStageReport::InProgress(s) => Some(s.signed_serial),
SigningStageReport::Finished(s) => Some(s.signed_serial),
});

if current < Progress::Signing {
println!(" {Pending} sign");
} else if current > Progress::Signing {
Expand All @@ -864,6 +864,22 @@ fn print_sign_phase(
Some(SigningStageReport::Requested(_)) => None,
Some(SigningStageReport::Finished(r)) => Some(r.started_at),
};

let (strategy, step) = match &signing_report.as_ref().map(|r| &r.stage_report) {
None => ("not started yet", "step: not started yet".into()),
Some(SigningStageReport::Requested(_)) => {
("not started yet", "step: not started yet".into())
}
Some(SigningStageReport::InProgress(SigningInProgressReport { step, .. })) => {
let step_num = step.get_current_step();
let step_total = step.get_total_steps();
let strategy = step.signing_strategy();
let step = format!("step {step_num}/{step_total}: {}", step.as_str());
(strategy, step)
}
Some(SigningStageReport::Finished(_)) => ("finished", "step: finished".into()),
};

let unsigned_serial = serial_to_string(unsigned_serial);

let short_signed_serial = if let Some(signed_serial) = signed_serial {
Expand All @@ -875,6 +891,8 @@ fn print_sign_phase(
println!(" {Ongoing} sign{short_signed_serial}");
println!(" | loaded serial: {unsigned_serial}");
println!(" | signed serial: {signed_serial}");
println!(" | strategy: {strategy}");
println!(" | {step}");
println!(
" | start time: {}",
to_rfc3339_ago(start_time, "<not started yet>")
Expand Down
86 changes: 25 additions & 61 deletions src/signer/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use crate::{
SigningTrigger,
incremental::LocalState,
keys::ZoneSigningKeys,
status::{SigningStatusPerZone, ZoneSigningStatus},
status::{FullSigningStep, SigningStatusPerZone, SigningStep},
},
units::{
key_manager::mk_dnst_keyset_state_file_path,
Expand Down Expand Up @@ -112,18 +112,6 @@ pub fn sign_zone(
policy.signer.serial_policy
);

//
// Record the start of signing for this zone.
//
{
status
.write()
.unwrap()
.status
.start(loaded_serial)
.map_err(|_| SignerError::InternalError("Invalid status".to_string()))?;
}

//
// Create a signing configuration.
//
Expand All @@ -133,7 +121,13 @@ pub fn sign_zone(
//
// Convert zone records into a form we can sign.
//
status.write().unwrap().current_action = "Collecting records to sign".to_string();
{
let mut status = status.write().unwrap();
// Record the start of signing for this zone.
status.status.start(loaded_serial, serial).unwrap();
status.step = SigningStep::Full(FullSigningStep::CollectingRecords);
}

debug!("[ZS]: Collecting records to sign for zone '{zone_name}'.");
let walk_start = Instant::now();
let mut records = loaded
Expand All @@ -144,19 +138,12 @@ pub fn sign_zone(
.collect::<Vec<_>>();
records.push(new_soa.clone().into());
let walk_time = walk_start.elapsed();
let unsigned_rr_count = records.len();

debug!("Reading dnst keyset DNSKEY RRs and RRSIG RRs");
{
let mut v = status.write().unwrap();
let v2 = &mut v.status;
if let ZoneSigningStatus::InProgress(s) = v2 {
s.unsigned_rr_count = Some(unsigned_rr_count);
s.walk_time = Some(walk_time);
}
let mut status = status.write().unwrap();
status.step = SigningStep::Full(FullSigningStep::FetchingKeys);
}

debug!("Reading dnst keyset DNSKEY RRs and RRSIG RRs");
status.write().unwrap().current_action = "Fetching apex RRs from the key manager".to_string();
// Read the DNSKEY RRs and DNSKEY RRSIG RR from the keyset state.
let state_path = mk_dnst_keyset_state_file_path(&center.config.keys_dir, &zone.name);
let state = std::fs::read_to_string(&state_path)
Expand All @@ -181,7 +168,7 @@ pub fn sign_zone(

debug!("Loading dnst keyset signing keys");
// Load the signing keys indicated by the keyset state.
let signing_keys = ZoneSigningKeys::load(center, zone, &state, &status)?;
let signing_keys = ZoneSigningKeys::load(center, zone, &state)?;

// Save the current zone signing keys and clear key_roll
let mut key_tags = HashSet::new();
Expand All @@ -206,26 +193,24 @@ pub fn sign_zone(
// Sort them into DNSSEC order ready for NSEC(3) generation.
//
debug!("[ZS]: Sorting collected records for zone '{zone_name}'.");
status.write().unwrap().current_action = "Sorting records".to_string();
{
let mut status = status.write().unwrap();
status.step = SigningStep::Full(FullSigningStep::SortingRecords);
}
let sort_start = Instant::now();
// Note: This may briefly use lots of CPU and many CPU cores.
records.par_sort_by(CanonicalOrd::canonical_cmp);
let sort_time = sort_start.elapsed();
let unsigned_rr_count = records.len();

{
let mut v = status.write().unwrap();
let v2 = &mut v.status;
if let ZoneSigningStatus::InProgress(s) = v2 {
s.sort_time = Some(sort_time);
}
}

//
// Generate NSEC(3) RRs.
//
debug!("[ZS]: Generating denial records for zone '{zone_name}'.");
status.write().unwrap().current_action = "Generating denial records".to_string();
{
let mut status = status.write().unwrap();
status.step = SigningStep::Full(FullSigningStep::GeneratingDenialRecords);
}
let denial_start = Instant::now();
match &signing_config.denial {
DenialConfig::AlreadyPresent => {}
Expand Down Expand Up @@ -275,15 +260,6 @@ pub fn sign_zone(
let denial_time = denial_start.elapsed();
let denial_rr_count = unsigned_records.len() - unsigned_rr_count;

{
let mut v = status.write().unwrap();
let v2 = &mut v.status;
if let ZoneSigningStatus::InProgress(s) = v2 {
s.denial_rr_count = Some(denial_rr_count);
s.denial_time = Some(denial_time);
}
}

//
// Generate RRSIG RRs concurrently.
//
Expand All @@ -293,20 +269,15 @@ pub fn sign_zone(
// mpsc::channel and accumulates them into the signed zone.
//
debug!("[ZS]: Generating RRSIG records.");
status.write().unwrap().current_action = "Generating signature records".to_string();
{
let mut status = status.write().unwrap();
status.step = SigningStep::Full(FullSigningStep::GeneratingSignatureRecords);
}

// TODO: Configure Rayon's thread pool to set the number of threads. By
// default, it relies on 'std::thread::available_parallelism()'.
let parallelism = rayon::current_num_threads();

{
let mut v = status.write().unwrap();
let v2 = &mut v.status;
if let ZoneSigningStatus::InProgress(s) = v2 {
s.threads_used = Some(parallelism);
}
}

let generation_start = Instant::now();

// Get the keys to sign with. Domain's 'sign_sorted_zone_records()'
Expand Down Expand Up @@ -418,14 +389,7 @@ pub fn sign_zone(

{
let mut v = status.write().unwrap();
let v2 = &mut v.status;
if let ZoneSigningStatus::InProgress(s) = v2 {
s.rrsig_count = Some(total_signatures);
s.rrsig_reused_count = Some(0); // Not implemented yet
s.rrsig_time = Some(generation_time);
s.total_time = Some(total_time);
}
v.status.finish(true);
v.status.finish();
}

// Log signing statistics.
Expand Down
Loading
Loading