20260626 优化PP缓存索引与证书缓存长尾

This commit is contained in:
2026-06-26 07:19:11 +08:00
parent af25316d68
commit 9e339e63e7
24 changed files with 3158 additions and 329 deletions

View File

@@ -213,6 +213,9 @@ pub enum ManifestFreshError {
#[error("manifest file hash mismatch: {rsync_uri} (RFC 9286 §6.5; RFC 9286 §6.6)")]
HashMismatch { rsync_uri: String },
#[error("issuer CA certificate bytes unavailable: {detail} (RFC 6487 §4; RFC 9286 §6.2)")]
IssuerCaLoadFailed { detail: String },
}
impl ManifestFreshError {

View File

@@ -6,7 +6,7 @@ use crate::storage::RocksStore;
use crate::sync::rrdp::Fetcher as HttpFetcher;
use crate::validation::manifest::PublicationPointSource;
use crate::validation::objects::ObjectsOutput;
use crate::validation::tree::{CaInstanceHandle, PublicationPointRunner};
use crate::validation::tree::{CaCertificateRef, CaInstanceHandle, PublicationPointRunner};
use crate::validation::tree_runner::Rpkiv1PublicationPointRunner;
use std::collections::HashMap;
use std::sync::Mutex;
@@ -49,7 +49,7 @@ pub fn run_publication_point_once(
depth: 0,
tal_id: "single-publication-point".to_string(),
parent_manifest_rsync_uri: None,
ca_certificate_der: issuer_ca_der.to_vec(),
ca_certificate: CaCertificateRef::inline_der(issuer_ca_der.to_vec()),
ca_certificate_rsync_uri: issuer_ca_rsync_uri.map(str::to_string),
effective_ip_resources: issuer_effective_ip.cloned(),
effective_as_resources: issuer_effective_as.cloned(),
@@ -80,6 +80,7 @@ pub fn run_publication_point_once(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: false,
enable_child_certificate_validation_cache: false,
publication_point_cache_observe_only: false,
enable_publication_point_validation_cache: false,
};

View File

@@ -33,6 +33,7 @@ use crate::validation::from_tal::{
discover_root_ca_instance_from_tal_with_fetchers_strict_name,
};
use crate::validation::objects::ParallelRoaWorkerPool;
use crate::validation::tree::CaCertificateRef;
use crate::validation::tree::{
CaInstanceHandle, TreeRunAuditOutput, TreeRunConfig, TreeRunError, TreeRunOutput,
run_tree_serial, run_tree_serial_audit, run_tree_serial_audit_multi_root,
@@ -136,6 +137,7 @@ fn make_live_runner<'a>(
ccr_accumulator: Option<CcrAccumulator>,
persist_vcir: bool,
enable_roa_validation_cache: bool,
enable_child_certificate_validation_cache: bool,
publication_point_cache_observe_only: bool,
enable_publication_point_validation_cache: bool,
) -> Rpkiv1PublicationPointRunner<'a> {
@@ -163,6 +165,7 @@ fn make_live_runner<'a>(
ccr_accumulator: ccr_accumulator.map(Mutex::new),
persist_vcir,
enable_roa_validation_cache,
enable_child_certificate_validation_cache,
publication_point_cache_observe_only,
enable_publication_point_validation_cache,
}
@@ -537,7 +540,7 @@ pub fn root_handle_from_trust_anchor(
depth: 0,
tal_id,
parent_manifest_rsync_uri: None,
ca_certificate_der: trust_anchor.ta_certificate.raw_der.clone(),
ca_certificate: CaCertificateRef::inline_der(trust_anchor.ta_certificate.raw_der.clone()),
ca_certificate_rsync_uri,
effective_ip_resources: ta_rc.tbs.extensions.ip_resources.clone(),
effective_as_resources: ta_rc.tbs.extensions.as_resources.clone(),
@@ -578,6 +581,7 @@ pub fn run_tree_from_tal_url_serial(
None,
config.persist_vcir,
config.enable_roa_validation_cache,
config.enable_child_certificate_validation_cache,
config.publication_point_cache_observe_only,
config.enable_publication_point_validation_cache,
);
@@ -624,6 +628,7 @@ pub fn run_tree_from_tal_url_serial_audit(
None,
config.persist_vcir,
config.enable_roa_validation_cache,
config.enable_child_certificate_validation_cache,
config.publication_point_cache_observe_only,
config.enable_publication_point_validation_cache,
);
@@ -692,6 +697,7 @@ pub fn run_tree_from_tal_url_serial_audit_with_timing(
None,
config.persist_vcir,
config.enable_roa_validation_cache,
config.enable_child_certificate_validation_cache,
config.publication_point_cache_observe_only,
config.enable_publication_point_validation_cache,
);
@@ -782,6 +788,7 @@ where
.then(|| CcrAccumulator::new(vec![discovery.trust_anchor.clone()])),
config.persist_vcir,
config.enable_roa_validation_cache,
config.enable_child_certificate_validation_cache,
config.publication_point_cache_observe_only,
config.enable_publication_point_validation_cache,
);
@@ -910,6 +917,7 @@ where
}),
config.persist_vcir,
config.enable_roa_validation_cache,
config.enable_child_certificate_validation_cache,
config.publication_point_cache_observe_only,
config.enable_publication_point_validation_cache,
);
@@ -1350,6 +1358,7 @@ pub fn run_tree_from_tal_and_ta_der_serial(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1405,6 +1414,7 @@ pub fn run_tree_from_tal_bytes_serial_audit(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1482,6 +1492,7 @@ pub fn run_tree_from_tal_bytes_serial_audit_with_timing(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1558,6 +1569,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1635,6 +1647,7 @@ pub fn run_tree_from_tal_and_ta_der_serial_audit_with_timing(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1719,6 +1732,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1784,6 +1798,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1871,6 +1886,7 @@ pub fn run_tree_from_tal_and_ta_der_payload_replay_serial_audit_with_timing(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache: config.enable_roa_validation_cache,
enable_child_certificate_validation_cache: config.enable_child_certificate_validation_cache,
publication_point_cache_observe_only: config.publication_point_cache_observe_only,
enable_publication_point_validation_cache: config.enable_publication_point_validation_cache,
};
@@ -1938,6 +1954,7 @@ fn build_payload_replay_runner<'a>(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
enable_child_certificate_validation_cache: false,
publication_point_cache_observe_only: false,
enable_publication_point_validation_cache: false,
}
@@ -1975,6 +1992,7 @@ fn build_payload_delta_replay_runner<'a>(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
enable_child_certificate_validation_cache: false,
publication_point_cache_observe_only: false,
enable_publication_point_validation_cache: false,
}
@@ -2012,6 +2030,7 @@ fn build_payload_delta_replay_current_store_runner<'a>(
ccr_accumulator: None,
persist_vcir: true,
enable_roa_validation_cache,
enable_child_certificate_validation_cache: false,
publication_point_cache_observe_only: false,
enable_publication_point_validation_cache: false,
}
@@ -2577,6 +2596,7 @@ mod replay_api_tests {
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,
@@ -2616,6 +2636,7 @@ mod replay_api_tests {
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,
@@ -2665,6 +2686,7 @@ mod replay_api_tests {
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,
@@ -2715,6 +2737,7 @@ mod replay_api_tests {
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,
@@ -2775,6 +2798,7 @@ mod replay_api_tests {
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,
@@ -2811,6 +2835,7 @@ mod replay_api_tests {
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,
@@ -2867,6 +2892,7 @@ mod replay_api_tests {
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,
@@ -2932,6 +2958,7 @@ mod replay_api_tests {
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,

View File

@@ -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,

View File

@@ -994,6 +994,11 @@ fn stage_ready_publication_point(
result.discovered_children.clone(),
);
metrics.child_enqueue_ms = elapsed_ms(child_enqueue_started);
runner.record_publication_point_step_ms(
metrics.manifest_rsync_uri.as_deref().unwrap_or_default(),
"publication_point_cache_child_enqueue",
metrics.child_enqueue_ms,
);
finished.push(FinishedPublicationPoint {
node: FinishedPublicationPointNode::from_queued(ready.node),
result: compact_phase2_finished_result(result, compact_audit),
@@ -1182,7 +1187,7 @@ fn stage_ready_publication_point(
ready.node.id,
&fresh_stage.fresh_point,
runner.policy,
&ready.node.handle.ca_certificate_der,
fresh_stage.issuer_ca_der.as_ref(),
ready.node.handle.ca_certificate_rsync_uri.as_deref(),
ready.node.handle.effective_ip_resources.as_ref(),
ready.node.handle.effective_as_resources.as_ref(),
@@ -2420,7 +2425,7 @@ mod tests {
.push(crate::validation::tree::DiscoveredChildCaInstance {
handle: crate::validation::tree::CaInstanceHandle {
tal_id: "test".to_string(),
ca_certificate_der: vec![1],
ca_certificate: crate::validation::tree::CaCertificateRef::inline_der(vec![1]),
ca_certificate_rsync_uri: Some(
"rsync://example.test/repo/child.cer".to_string(),
),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff