diff --git a/acmed/src/certificate.rs b/acmed/src/certificate.rs index 739936a..28e245d 100644 --- a/acmed/src/certificate.rs +++ b/acmed/src/certificate.rs @@ -70,14 +70,14 @@ impl Certificate { Err(format!("{identifier}: identifier not found").into()) } - fn is_expiring(&self, cert: &X509Certificate) -> Result { + fn renew_in(&self, cert: &X509Certificate) -> Result { let expires_in = cert.expires_in()?; self.debug(&format!( "certificate expires in {} days ({} days delay)", expires_in.as_secs() / 86400, self.renew_delay.as_secs() / 86400, )); - Ok(expires_in <= self.renew_delay) + Ok(expires_in.saturating_sub(self.renew_delay)) } fn has_missing_identifiers(&self, cert: &X509Certificate) -> bool { @@ -110,33 +110,22 @@ impl Certificate { .join(",") } - pub async fn should_renew(&self) -> Result { + pub async fn schedule_renewal(&self) -> Result { self.debug(&format!( "checking for renewal (identifiers: {})", self.identifier_list() )); if !certificate_files_exists(&self.file_manager) { self.debug("certificate does not exist: requesting one"); - return Ok(true); + return Ok(Duration::ZERO); } let cert = get_certificate(&self.file_manager).await?; - let renew_ident = self.has_missing_identifiers(&cert); - if renew_ident { + if self.has_missing_identifiers(&cert) { self.debug("the current certificate doesn't include all the required identifiers"); + return Ok(Duration::ZERO); } - let renew_exp = self.is_expiring(&cert)?; - if renew_exp { - self.debug("the certificate is expiring"); - } - let renew = renew_ident || renew_exp; - - if renew { - self.debug("the certificate will be renewed now"); - } else { - self.debug("the certificate will not be renewed now"); - } - Ok(renew) + Ok(self.renew_in(&cert)?) } pub async fn call_challenge_hooks( diff --git a/acmed/src/main.rs b/acmed/src/main.rs index a933867..3cbe93e 100644 --- a/acmed/src/main.rs +++ b/acmed/src/main.rs @@ -33,7 +33,6 @@ pub const DEFAULT_CERT_DIR: &str = env!("ACMED_DEFAULT_CERT_DIR"); pub const DEFAULT_CERT_FORMAT: &str = env!("ACMED_DEFAULT_CERT_FORMAT"); pub const DEFAULT_CONFIG_FILE: &str = env!("ACMED_DEFAULT_CONFIG_FILE"); pub const DEFAULT_PID_FILE: &str = env!("ACMED_DEFAULT_PID_FILE"); -pub const DEFAULT_SLEEP_TIME: u64 = 3600; pub const DEFAULT_POOL_TIME: u64 = 5000; pub const DEFAULT_CSR_DIGEST: HashFunction = HashFunction::Sha256; pub const DEFAULT_CERT_KEY_TYPE: KeyType = KeyType::Rsa2048; diff --git a/acmed/src/main_event_loop.rs b/acmed/src/main_event_loop.rs index 85456c2..c3c2c4d 100644 --- a/acmed/src/main_event_loop.rs +++ b/acmed/src/main_event_loop.rs @@ -179,15 +179,23 @@ async fn renew_certificate( account_s: AccountSync, endpoint_s: EndpointSync, ) -> (&mut Certificate, AccountSync, EndpointSync) { + let backoff = [60, 10 * 60, 100 * 60, 24 * 60 * 60]; + let mut scheduling_retries = 0; loop { - match certificate.should_renew().await { - Ok(true) => break, - Ok(false) => {} + match certificate.schedule_renewal().await { + Ok(duration) => { + sleep(duration).await; + break; + } Err(e) => { certificate.warn(&e.message); + sleep(Duration::from_secs( + backoff[scheduling_retries.min(backoff.len() - 1)], + )) + .await; + scheduling_retries += 1; } } - sleep(Duration::from_secs(crate::DEFAULT_SLEEP_TIME)).await; } let (status, is_success) = match request_certificate(certificate, account_s.clone(), endpoint_s.clone()).await {