20260506_2 为CIR增加reject list基础能力

This commit is contained in:
2026-05-06 20:53:57 +08:00
parent 51663a9410
commit 752e746b97
15 changed files with 510 additions and 53 deletions

View File

@@ -0,0 +1,95 @@
use std::path::PathBuf;
#[derive(Debug, Default, PartialEq, Eq)]
struct Args {
cir_path: Option<PathBuf>,
limit: usize,
}
fn usage() -> &'static str {
"Usage: cir_dump_reject_list --cir <path> [--limit <n>]"
}
fn parse_args(argv: &[String]) -> Result<Args, String> {
let mut args = Args {
cir_path: None,
limit: 10,
};
let mut index = 1usize;
while index < argv.len() {
match argv[index].as_str() {
"--cir" => {
index += 1;
let value = argv.get(index).ok_or("--cir requires a value")?;
args.cir_path = Some(PathBuf::from(value));
}
"--limit" => {
index += 1;
let value = argv.get(index).ok_or("--limit requires a value")?;
args.limit = value
.parse::<usize>()
.map_err(|_| format!("invalid --limit: {value}"))?;
}
"-h" | "--help" => return Err(usage().to_string()),
other => return Err(format!("unknown argument: {other}\n{}", usage())),
}
index += 1;
}
if args.cir_path.is_none() {
return Err(format!("--cir is required\n{}", usage()));
}
Ok(args)
}
fn main() {
if let Err(err) = real_main() {
eprintln!("{err}");
std::process::exit(1);
}
}
fn real_main() -> Result<(), String> {
let argv: Vec<String> = std::env::args().collect();
let args = parse_args(&argv)?;
let cir_path = args.cir_path.expect("validated");
let bytes = std::fs::read(&cir_path)
.map_err(|e| format!("read cir failed: {}: {e}", cir_path.display()))?;
let cir = rpki::cir::decode_cir(&bytes).map_err(|e| format!("decode cir failed: {e}"))?;
println!("reject_list_sha256={}", hex::encode(&cir.reject_list_sha256));
println!("reject_count={}", cir.rejected_objects.len());
for (index, item) in cir.rejected_objects.iter().take(args.limit).enumerate() {
println!(
"{:04} uri={} reason={}",
index + 1,
item.object_uri,
item.reason.as_deref().unwrap_or("<none>")
);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_requires_cir_path() {
let err = parse_args(&["cir_dump_reject_list".to_string()]).expect_err("missing cir");
assert!(err.contains("--cir is required"), "{err}");
}
#[test]
fn parse_accepts_limit() {
let args = parse_args(&[
"cir_dump_reject_list".to_string(),
"--cir".to_string(),
"input.cir".to_string(),
"--limit".to_string(),
"5".to_string(),
])
.expect("parse args");
assert_eq!(args.cir_path.as_deref(), Some(std::path::Path::new("input.cir")));
assert_eq!(args.limit, 5);
}
}

View File

@@ -2,7 +2,8 @@ use std::path::PathBuf;
use rpki::blob_store::ExternalRepoBytesDb;
use rpki::cir::{
CIR_VERSION_V1, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal, encode_cir,
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
compute_reject_list_sha256, encode_cir,
};
use sha2::Digest;
@@ -108,7 +109,7 @@ fn main() -> Result<(), String> {
.map_err(|e| format!("write repo bytes db failed: {e}"))?;
let cir = CanonicalInputRepresentation {
version: CIR_VERSION_V1,
version: CIR_VERSION_V2,
hash_alg: CirHashAlgorithm::Sha256,
validation_time,
objects: vec![CirObject {
@@ -116,6 +117,8 @@ fn main() -> Result<(), String> {
sha256: sha.to_vec(),
}],
tals: vec![CirTal { tal_uri, tal_bytes }],
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
rejected_objects: Vec::new(),
};
let der = encode_cir(&cir).map_err(|e| format!("encode cir failed: {e}"))?;
if let Some(parent) = cir_out.parent() {