20260626 优化PP缓存索引与证书缓存长尾
This commit is contained in:
@@ -7,6 +7,8 @@ use crate::validation::objects::{
|
||||
AspaAttestation, ObjectsOutput, RoaValidationCacheStats, RouterKeyPayload, Vrp,
|
||||
};
|
||||
use crate::validation::publication_point::PublicationPointSnapshot;
|
||||
use std::borrow::Cow;
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct TreeRunConfig {
|
||||
@@ -22,6 +24,8 @@ pub struct TreeRunConfig {
|
||||
pub build_ccr_accumulator: bool,
|
||||
/// Reuse accepted ROA validation outputs from previous VCIR when explicitly enabled.
|
||||
pub enable_roa_validation_cache: bool,
|
||||
/// Reuse validated child certificate discovery results when explicitly enabled.
|
||||
pub enable_child_certificate_validation_cache: bool,
|
||||
/// Evaluate publication-point cache eligibility without changing validation results.
|
||||
pub publication_point_cache_observe_only: bool,
|
||||
/// Reuse complete publication-point validation projections when explicitly enabled.
|
||||
@@ -39,6 +43,7 @@ impl Default for TreeRunConfig {
|
||||
persist_vcir: true,
|
||||
build_ccr_accumulator: true,
|
||||
enable_roa_validation_cache: false,
|
||||
enable_child_certificate_validation_cache: false,
|
||||
publication_point_cache_observe_only: false,
|
||||
enable_publication_point_validation_cache: false,
|
||||
enable_transport_request_prefetch: false,
|
||||
@@ -46,13 +51,85 @@ impl Default for TreeRunConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CaCertificateRef {
|
||||
InlineDer(Vec<u8>),
|
||||
RepoBytes {
|
||||
sha256_hex: String,
|
||||
cached_der: Arc<OnceLock<Arc<[u8]>>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl PartialEq for CaCertificateRef {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::InlineDer(left), Self::InlineDer(right)) => left == right,
|
||||
(
|
||||
Self::RepoBytes {
|
||||
sha256_hex: left, ..
|
||||
},
|
||||
Self::RepoBytes {
|
||||
sha256_hex: right, ..
|
||||
},
|
||||
) => left == right,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CaCertificateRef {}
|
||||
|
||||
impl CaCertificateRef {
|
||||
pub fn inline_der(bytes: Vec<u8>) -> Self {
|
||||
Self::InlineDer(bytes)
|
||||
}
|
||||
|
||||
pub fn repo_bytes(sha256_hex: String) -> Self {
|
||||
Self::RepoBytes {
|
||||
sha256_hex,
|
||||
cached_der: Arc::new(OnceLock::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sha256_hex(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::InlineDer(_) => None,
|
||||
Self::RepoBytes { sha256_hex, .. } => Some(sha256_hex.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn der<'a>(&'a self, store: &crate::storage::RocksStore) -> Result<Cow<'a, [u8]>, String> {
|
||||
match self {
|
||||
Self::InlineDer(bytes) => Ok(Cow::Borrowed(bytes.as_slice())),
|
||||
Self::RepoBytes {
|
||||
sha256_hex,
|
||||
cached_der,
|
||||
} => {
|
||||
if cached_der.get().is_none() {
|
||||
let bytes = store
|
||||
.get_blob_bytes(sha256_hex)
|
||||
.map_err(|e| format!("load CA certificate bytes failed: {e}"))?
|
||||
.ok_or_else(|| {
|
||||
format!("missing CA certificate repo bytes for sha256={sha256_hex}")
|
||||
})?;
|
||||
let _ = cached_der.set(Arc::from(bytes));
|
||||
}
|
||||
let bytes = cached_der.get().ok_or_else(|| {
|
||||
format!("missing cached CA certificate bytes for sha256={sha256_hex}")
|
||||
})?;
|
||||
Ok(Cow::Borrowed(bytes.as_ref()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CaInstanceHandle {
|
||||
pub depth: usize,
|
||||
pub tal_id: String,
|
||||
pub parent_manifest_rsync_uri: Option<String>,
|
||||
/// DER bytes of the CA certificate for this CA instance.
|
||||
pub ca_certificate_der: Vec<u8>,
|
||||
/// CA certificate bytes or a lazy repo-bytes reference for this CA instance.
|
||||
pub ca_certificate: CaCertificateRef,
|
||||
/// rsync URI of this CA certificate object (where it is published).
|
||||
///
|
||||
/// This is used for strict AIA binding checks (RFC 6487 §4.8.7) when validating
|
||||
@@ -74,6 +151,32 @@ impl CaInstanceHandle {
|
||||
self.depth = depth;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ca_certificate_der<'a>(
|
||||
&'a self,
|
||||
store: &crate::storage::RocksStore,
|
||||
) -> Result<Cow<'a, [u8]>, String> {
|
||||
self.ca_certificate.der(store)
|
||||
}
|
||||
|
||||
pub fn ca_certificate_sha256_hex(&self) -> Option<&str> {
|
||||
self.ca_certificate.sha256_hex()
|
||||
}
|
||||
|
||||
pub fn ca_certificate_sha256_32(&self) -> Option<[u8; 32]> {
|
||||
match &self.ca_certificate {
|
||||
CaCertificateRef::InlineDer(bytes) => {
|
||||
use sha2::Digest as _;
|
||||
let digest = sha2::Sha256::digest(bytes);
|
||||
Some(digest.into())
|
||||
}
|
||||
CaCertificateRef::RepoBytes { sha256_hex, .. } => {
|
||||
let mut out = [0u8; 32];
|
||||
hex::decode_to_slice(sha256_hex, &mut out).ok()?;
|
||||
Some(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -337,7 +440,7 @@ mod tests {
|
||||
use crate::validation::objects::{ObjectsOutput, ObjectsStats};
|
||||
|
||||
use super::{
|
||||
CaInstanceHandle, DiscoveredChildCaInstance, PublicationPointRunResult,
|
||||
CaCertificateRef, CaInstanceHandle, DiscoveredChildCaInstance, PublicationPointRunResult,
|
||||
PublicationPointRunner, TreeRunConfig, run_tree_serial_audit,
|
||||
run_tree_serial_audit_multi_root,
|
||||
};
|
||||
@@ -347,7 +450,7 @@ mod tests {
|
||||
depth: 0,
|
||||
tal_id: "arin".to_string(),
|
||||
parent_manifest_rsync_uri: None,
|
||||
ca_certificate_der: vec![1, 2, 3],
|
||||
ca_certificate: CaCertificateRef::inline_der(vec![1, 2, 3]),
|
||||
ca_certificate_rsync_uri: None,
|
||||
effective_ip_resources: None,
|
||||
effective_as_resources: None,
|
||||
|
||||
Reference in New Issue
Block a user