删除无用代码
This commit is contained in:
parent
cdf9372929
commit
13f29843db
@ -1,5 +1,3 @@
|
|||||||
version: "3.9"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
rpki-rtr:
|
rpki-rtr:
|
||||||
build:
|
build:
|
||||||
@ -9,12 +7,12 @@ services:
|
|||||||
container_name: rpki-rtr-tls
|
container_name: rpki-rtr-tls
|
||||||
restart: no
|
restart: no
|
||||||
ports:
|
ports:
|
||||||
- "323:323"
|
# - "323:323"
|
||||||
- "324:324"
|
- "324:324"
|
||||||
environment:
|
environment:
|
||||||
RPKI_RTR_ENABLE_TLS: "true"
|
RPKI_RTR_ENABLE_TLS: "true"
|
||||||
RPKI_RTR_ENABLE_SSH: "false"
|
RPKI_RTR_ENABLE_SSH: "false"
|
||||||
RPKI_RTR_TCP_ADDR: "0.0.0.0:323"
|
# RPKI_RTR_TCP_ADDR: "0.0.0.0:323"
|
||||||
RPKI_RTR_TLS_ADDR: "0.0.0.0:324"
|
RPKI_RTR_TLS_ADDR: "0.0.0.0:324"
|
||||||
RPKI_RTR_TLS_CERT_PATH: "${RPKI_RTR_TLS_CERT_PATH:-/app/certs/server-dns.crt}"
|
RPKI_RTR_TLS_CERT_PATH: "${RPKI_RTR_TLS_CERT_PATH:-/app/certs/server-dns.crt}"
|
||||||
RPKI_RTR_TLS_KEY_PATH: "${RPKI_RTR_TLS_KEY_PATH:-/app/certs/server-dns.key}"
|
RPKI_RTR_TLS_KEY_PATH: "${RPKI_RTR_TLS_KEY_PATH:-/app/certs/server-dns.key}"
|
||||||
|
|||||||
@ -1,304 +0,0 @@
|
|||||||
use std::fs;
|
|
||||||
use std::net::IpAddr;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use anyhow::{Context, Result, anyhow};
|
|
||||||
|
|
||||||
use crate::data_model::resources::as_resources::Asn;
|
|
||||||
use crate::data_model::resources::ip_resources::{IPAddress, IPAddressPrefix};
|
|
||||||
use crate::rtr::payload::{Aspa, Payload, RouteOrigin, RouterKey, Ski};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct ParsedVrp {
|
|
||||||
pub prefix_addr: IpAddr,
|
|
||||||
pub prefix_len: u8,
|
|
||||||
pub max_len: u8,
|
|
||||||
pub asn: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct ParsedAspa {
|
|
||||||
pub customer_asn: u32,
|
|
||||||
pub provider_asns: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct ParsedRouterKey {
|
|
||||||
pub ski: [u8; 20],
|
|
||||||
pub asn: u32,
|
|
||||||
pub spki: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 从文本文件中加载 VRP,并转换成 RTR Payload::RouteOrigin。
|
|
||||||
///
|
|
||||||
/// 文件格式:
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// # prefix,max_len,asn
|
|
||||||
/// 10.0.0.0/24,24,65001
|
|
||||||
/// 10.0.1.0/24,24,65002
|
|
||||||
/// 2001:db8::/32,48,65003
|
|
||||||
/// ```
|
|
||||||
pub fn load_vrps_from_file(path: impl AsRef<Path>) -> Result<Vec<Payload>> {
|
|
||||||
let path = path.as_ref();
|
|
||||||
|
|
||||||
let content = fs::read_to_string(path)
|
|
||||||
.with_context(|| format!("failed to read VRP file: {}", path.display()))?;
|
|
||||||
|
|
||||||
let mut payloads = Vec::new();
|
|
||||||
|
|
||||||
for (idx, raw_line) in content.lines().enumerate() {
|
|
||||||
let line_no = idx + 1;
|
|
||||||
let line = raw_line.trim();
|
|
||||||
|
|
||||||
if line.is_empty() || line.starts_with('#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let vrp = parse_vrp_line(line)
|
|
||||||
.with_context(|| format!("invalid VRP line {}: {}", line_no, raw_line))?;
|
|
||||||
|
|
||||||
payloads.push(Payload::RouteOrigin(build_route_origin(vrp)?));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(payloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_aspas_from_file(path: impl AsRef<Path>) -> Result<Vec<Payload>> {
|
|
||||||
let path = path.as_ref();
|
|
||||||
|
|
||||||
let content = fs::read_to_string(path)
|
|
||||||
.with_context(|| format!("failed to read ASPA file: {}", path.display()))?;
|
|
||||||
|
|
||||||
let mut payloads = Vec::new();
|
|
||||||
|
|
||||||
for (idx, raw_line) in content.lines().enumerate() {
|
|
||||||
let line_no = idx + 1;
|
|
||||||
let line = raw_line.trim();
|
|
||||||
|
|
||||||
if line.is_empty() || line.starts_with('#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let aspa = parse_aspa_line(line)
|
|
||||||
.with_context(|| format!("invalid ASPA line {}: {}", line_no, raw_line))?;
|
|
||||||
|
|
||||||
payloads.push(Payload::Aspa(build_aspa(aspa)?));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(payloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_router_keys_from_file(path: impl AsRef<Path>) -> Result<Vec<Payload>> {
|
|
||||||
let path = path.as_ref();
|
|
||||||
|
|
||||||
let content = fs::read_to_string(path)
|
|
||||||
.with_context(|| format!("failed to read Router Key file: {}", path.display()))?;
|
|
||||||
|
|
||||||
let mut payloads = Vec::new();
|
|
||||||
|
|
||||||
for (idx, raw_line) in content.lines().enumerate() {
|
|
||||||
let line_no = idx + 1;
|
|
||||||
let line = raw_line.trim();
|
|
||||||
|
|
||||||
if line.is_empty() || line.starts_with('#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let router_key = parse_router_key_line(line)
|
|
||||||
.with_context(|| format!("invalid Router Key line {}: {}", line_no, raw_line))?;
|
|
||||||
|
|
||||||
payloads.push(Payload::RouterKey(build_router_key(router_key)?));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(payloads)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 解析单行 VRP。
|
|
||||||
///
|
|
||||||
/// 格式:
|
|
||||||
/// `prefix/prefix_len,max_len,asn`
|
|
||||||
///
|
|
||||||
/// 例如:
|
|
||||||
/// `10.0.0.0/24,24,65001`
|
|
||||||
pub fn parse_vrp_line(line: &str) -> Result<ParsedVrp> {
|
|
||||||
let parts: Vec<_> = line.split(',').map(|s| s.trim()).collect();
|
|
||||||
if parts.len() != 3 {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"expected format: <prefix>/<prefix_len>,<max_len>,<asn>"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let prefix_part = parts[0];
|
|
||||||
let max_len =
|
|
||||||
u8::from_str(parts[1]).with_context(|| format!("invalid max_len: {}", parts[1]))?;
|
|
||||||
let asn = u32::from_str(parts[2]).with_context(|| format!("invalid asn: {}", parts[2]))?;
|
|
||||||
|
|
||||||
let (addr_str, prefix_len_str) = prefix_part
|
|
||||||
.split_once('/')
|
|
||||||
.ok_or_else(|| anyhow!("prefix must be in CIDR form, e.g. 10.0.0.0/24"))?;
|
|
||||||
|
|
||||||
let prefix_addr = IpAddr::from_str(addr_str.trim())
|
|
||||||
.with_context(|| format!("invalid IP address: {}", addr_str))?;
|
|
||||||
|
|
||||||
let prefix_len = u8::from_str(prefix_len_str.trim())
|
|
||||||
.with_context(|| format!("invalid prefix length: {}", prefix_len_str))?;
|
|
||||||
|
|
||||||
validate_vrp(prefix_addr, prefix_len, max_len)?;
|
|
||||||
|
|
||||||
Ok(ParsedVrp {
|
|
||||||
prefix_addr,
|
|
||||||
prefix_len,
|
|
||||||
max_len,
|
|
||||||
asn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_aspa_line(line: &str) -> Result<ParsedAspa> {
|
|
||||||
let parts: Vec<_> = line.split(',').map(|s| s.trim()).collect();
|
|
||||||
if parts.len() != 2 {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"expected format: <customer_asn>,<provider_asn> [provider_asn ...]"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let customer_asn =
|
|
||||||
u32::from_str(parts[0]).with_context(|| format!("invalid customer_asn: {}", parts[0]))?;
|
|
||||||
|
|
||||||
let provider_asns = parts[1]
|
|
||||||
.split_whitespace()
|
|
||||||
.map(|provider| {
|
|
||||||
u32::from_str(provider).with_context(|| format!("invalid provider_asn: {}", provider))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>>>()?;
|
|
||||||
|
|
||||||
validate_aspa(customer_asn, &provider_asns)?;
|
|
||||||
|
|
||||||
Ok(ParsedAspa {
|
|
||||||
customer_asn,
|
|
||||||
provider_asns,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_router_key_line(line: &str) -> Result<ParsedRouterKey> {
|
|
||||||
let parts: Vec<_> = line.split(',').map(|s| s.trim()).collect();
|
|
||||||
if parts.len() != 3 {
|
|
||||||
return Err(anyhow!("expected format: <ski_hex>,<asn>,<spki_hex>"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let ski_vec = decode_hex(parts[0]).with_context(|| format!("invalid SKI hex: {}", parts[0]))?;
|
|
||||||
if ski_vec.len() != 20 {
|
|
||||||
return Err(anyhow!("SKI must be exactly 20 bytes"));
|
|
||||||
}
|
|
||||||
let mut ski = [0u8; 20];
|
|
||||||
ski.copy_from_slice(&ski_vec);
|
|
||||||
|
|
||||||
let asn = u32::from_str(parts[1]).with_context(|| format!("invalid asn: {}", parts[1]))?;
|
|
||||||
let spki = decode_hex(parts[2]).with_context(|| format!("invalid SPKI hex: {}", parts[2]))?;
|
|
||||||
|
|
||||||
validate_router_key(asn, &spki)?;
|
|
||||||
|
|
||||||
Ok(ParsedRouterKey { ski, asn, spki })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_vrp(prefix_addr: IpAddr, prefix_len: u8, max_len: u8) -> Result<()> {
|
|
||||||
match prefix_addr {
|
|
||||||
IpAddr::V4(_) => {
|
|
||||||
if prefix_len > 32 {
|
|
||||||
return Err(anyhow!("IPv4 prefix length must be <= 32"));
|
|
||||||
}
|
|
||||||
if max_len > 32 {
|
|
||||||
return Err(anyhow!("IPv4 max_len must be <= 32"));
|
|
||||||
}
|
|
||||||
if max_len < prefix_len {
|
|
||||||
return Err(anyhow!("IPv4 max_len must be >= prefix length"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IpAddr::V6(_) => {
|
|
||||||
if prefix_len > 128 {
|
|
||||||
return Err(anyhow!("IPv6 prefix length must be <= 128"));
|
|
||||||
}
|
|
||||||
if max_len > 128 {
|
|
||||||
return Err(anyhow!("IPv6 max_len must be <= 128"));
|
|
||||||
}
|
|
||||||
if max_len < prefix_len {
|
|
||||||
return Err(anyhow!("IPv6 max_len must be >= prefix length"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_aspa(customer_asn: u32, provider_asns: &[u32]) -> Result<()> {
|
|
||||||
if customer_asn == 0 {
|
|
||||||
return Err(anyhow!("customer_asn must not be AS0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if provider_asns.is_empty() {
|
|
||||||
return Err(anyhow!("provider list must not be empty"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if provider_asns.iter().any(|asn| *asn == 0)
|
|
||||||
&& !(provider_asns.len() == 1 && provider_asns[0] == 0)
|
|
||||||
{
|
|
||||||
return Err(anyhow!(
|
|
||||||
"provider list containing AS0 must be exactly [0]"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_router_key(asn: u32, spki: &[u8]) -> Result<()> {
|
|
||||||
crate::rtr::payload::RouterKey::new(Ski::default(), Asn::from(asn), spki.to_vec())
|
|
||||||
.validate()
|
|
||||||
.map_err(|err| anyhow!(err.to_string()))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_route_origin(vrp: ParsedVrp) -> Result<RouteOrigin> {
|
|
||||||
let address = match vrp.prefix_addr {
|
|
||||||
IpAddr::V4(addr) => IPAddress::from_ipv4(addr),
|
|
||||||
IpAddr::V6(addr) => IPAddress::from_ipv6(addr),
|
|
||||||
};
|
|
||||||
|
|
||||||
let prefix = IPAddressPrefix::new(address, vrp.prefix_len);
|
|
||||||
let asn = Asn::from(vrp.asn);
|
|
||||||
|
|
||||||
Ok(RouteOrigin::new(prefix, vrp.max_len, asn))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_aspa(aspa: ParsedAspa) -> Result<Aspa> {
|
|
||||||
let customer_asn = Asn::from(aspa.customer_asn);
|
|
||||||
let provider_asns = aspa
|
|
||||||
.provider_asns
|
|
||||||
.into_iter()
|
|
||||||
.map(Asn::from)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let aspa = Aspa::new(customer_asn, provider_asns);
|
|
||||||
aspa.validate_announcement()?;
|
|
||||||
Ok(aspa)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_router_key(router_key: ParsedRouterKey) -> Result<RouterKey> {
|
|
||||||
let asn = Asn::from(router_key.asn);
|
|
||||||
let ski = Ski::from_bytes(router_key.ski);
|
|
||||||
let router_key = RouterKey::new(ski, asn, router_key.spki);
|
|
||||||
Ok(router_key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decode_hex(input: &str) -> Result<Vec<u8>> {
|
|
||||||
let trimmed = input.trim();
|
|
||||||
if trimmed.len() % 2 != 0 {
|
|
||||||
return Err(anyhow!("hex string must have even length"));
|
|
||||||
}
|
|
||||||
|
|
||||||
(0..trimmed.len())
|
|
||||||
.step_by(2)
|
|
||||||
.map(|idx| {
|
|
||||||
u8::from_str_radix(&trimmed[idx..idx + 2], 16)
|
|
||||||
.map_err(|err| anyhow!("invalid hex at byte {}: {}", idx / 2, err))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod error_type;
|
pub mod error_type;
|
||||||
pub mod loader;
|
|
||||||
pub mod payload;
|
pub mod payload;
|
||||||
pub mod pdu;
|
pub mod pdu;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|||||||
@ -6,12 +6,27 @@ use anyhow::{Context, Result, anyhow};
|
|||||||
use der_parser::ber::{BerObject, BerObjectContent};
|
use der_parser::ber::{BerObject, BerObjectContent};
|
||||||
use der_parser::der::parse_der;
|
use der_parser::der::parse_der;
|
||||||
|
|
||||||
use crate::rtr::loader::{ParsedAspa, ParsedVrp, build_aspa, build_route_origin};
|
use crate::data_model::resources::as_resources::Asn;
|
||||||
use crate::rtr::payload::Payload;
|
use crate::data_model::resources::ip_resources::{IPAddress, IPAddressPrefix};
|
||||||
|
use crate::rtr::payload::{Aspa, Payload, RouteOrigin};
|
||||||
|
|
||||||
const VRPS_INDEX: usize = 3;
|
const VRPS_INDEX: usize = 3;
|
||||||
const VAPS_INDEX: usize = 4;
|
const VAPS_INDEX: usize = 4;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ParsedVrp {
|
||||||
|
pub prefix_addr: IpAddr,
|
||||||
|
pub prefix_len: u8,
|
||||||
|
pub max_len: u8,
|
||||||
|
pub asn: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ParsedAspa {
|
||||||
|
pub customer_asn: u32,
|
||||||
|
pub provider_asns: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct ParsedCcrSnapshot {
|
pub struct ParsedCcrSnapshot {
|
||||||
pub content_type_oid: String,
|
pub content_type_oid: String,
|
||||||
@ -397,3 +412,27 @@ fn contains_ccr_file(dir: &Path) -> Result<bool> {
|
|||||||
|
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_route_origin(vrp: ParsedVrp) -> Result<RouteOrigin> {
|
||||||
|
let address = match vrp.prefix_addr {
|
||||||
|
IpAddr::V4(addr) => IPAddress::from_ipv4(addr),
|
||||||
|
IpAddr::V6(addr) => IPAddress::from_ipv6(addr),
|
||||||
|
};
|
||||||
|
|
||||||
|
let prefix = IPAddressPrefix::new(address, vrp.prefix_len);
|
||||||
|
let asn = Asn::from(vrp.asn);
|
||||||
|
|
||||||
|
Ok(RouteOrigin::new(prefix, vrp.max_len, asn))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_aspa(aspa: ParsedAspa) -> Result<Aspa> {
|
||||||
|
let customer_asn = Asn::from(aspa.customer_asn);
|
||||||
|
let provider_asns = aspa
|
||||||
|
.provider_asns
|
||||||
|
.into_iter()
|
||||||
|
.map(Asn::from)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let aspa = Aspa::new(customer_asn, provider_asns);
|
||||||
|
aspa.validate_announcement()?;
|
||||||
|
Ok(aspa)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use rpki::rtr::loader::{ParsedAspa, ParsedVrp};
|
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use rpki::source::ccr::{find_latest_ccr_file, load_ccr_snapshot_from_file,
|
use rpki::source::ccr::{
|
||||||
snapshot_to_payloads_with_options, ParsedCcrSnapshot};
|
ParsedAspa, ParsedCcrSnapshot, ParsedVrp, find_latest_ccr_file, load_ccr_snapshot_from_file,
|
||||||
|
snapshot_to_payloads_with_options,
|
||||||
|
};
|
||||||
|
|
||||||
fn fixture_path(name: &str) -> PathBuf {
|
fn fixture_path(name: &str) -> PathBuf {
|
||||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data").join(name)
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data").join(name)
|
||||||
|
|||||||
@ -1,123 +0,0 @@
|
|||||||
use std::net::IpAddr;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use rpki::rtr::loader::{
|
|
||||||
parse_aspa_line, parse_router_key_line, parse_vrp_line, ParsedAspa, ParsedVrp,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_ipv4_vrp_line() {
|
|
||||||
let got = parse_vrp_line("10.0.0.0/24,24,65001").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
got,
|
|
||||||
ParsedVrp {
|
|
||||||
prefix_addr: IpAddr::from_str("10.0.0.0").unwrap(),
|
|
||||||
prefix_len: 24,
|
|
||||||
max_len: 24,
|
|
||||||
asn: 65001,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_ipv6_vrp_line() {
|
|
||||||
let got = parse_vrp_line("2001:db8::/32,48,65003").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
got,
|
|
||||||
ParsedVrp {
|
|
||||||
prefix_addr: IpAddr::from_str("2001:db8::").unwrap(),
|
|
||||||
prefix_len: 32,
|
|
||||||
max_len: 48,
|
|
||||||
asn: 65003,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_rejects_invalid_max_len() {
|
|
||||||
let err = parse_vrp_line("10.0.0.0/24,16,65001").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("max_len"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_rejects_invalid_ip() {
|
|
||||||
let err = parse_vrp_line("10.0.0.999/24,24,65001").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("invalid IP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_rejects_invalid_format() {
|
|
||||||
let err = parse_vrp_line("10.0.0.0/24,24").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("expected format"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_aspa_line_ok() {
|
|
||||||
let got = parse_aspa_line("64496,64497 64498").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
got,
|
|
||||||
ParsedAspa {
|
|
||||||
customer_asn: 64496,
|
|
||||||
provider_asns: vec![64497, 64498],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_aspa_rejects_empty_provider_list() {
|
|
||||||
let err = parse_aspa_line("64496,").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("provider list"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_aspa_rejects_as0() {
|
|
||||||
let err = parse_aspa_line("0,64497").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("AS0"));
|
|
||||||
|
|
||||||
let err = parse_aspa_line("64496,0").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("AS0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_router_key_line_ok() {
|
|
||||||
let got = parse_router_key_line(
|
|
||||||
"00112233445566778899aabbccddeeff00112233,64496,3013300d06092a864886f70d010101050003020000",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(got.asn, 64496);
|
|
||||||
assert_eq!(
|
|
||||||
got.ski,
|
|
||||||
[
|
|
||||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
|
|
||||||
0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
got.spki,
|
|
||||||
vec![
|
|
||||||
0x30, 0x13, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
|
||||||
0x01, 0x01, 0x05, 0x00, 0x03, 0x02, 0x00, 0x00,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_router_key_rejects_invalid_ski_length() {
|
|
||||||
let err = parse_router_key_line("0011,64496,deadbeef").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("SKI"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_router_key_rejects_empty_spki() {
|
|
||||||
let err =
|
|
||||||
parse_router_key_line("00112233445566778899aabbccddeeff00112233,64496,").unwrap_err();
|
|
||||||
assert!(err.to_string().contains("SPKI"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_router_key_rejects_invalid_spki_der() {
|
|
||||||
let err =
|
|
||||||
parse_router_key_line("00112233445566778899aabbccddeeff00112233,64496,deadbeef")
|
|
||||||
.unwrap_err();
|
|
||||||
assert!(err.to_string().contains("valid DER"));
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user