rtr client 开发
This commit is contained in:
@@ -292,7 +292,7 @@ impl Timing {
|
||||
impl Default for Timing {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
refresh: 3600,
|
||||
refresh: 60,
|
||||
retry: 600,
|
||||
expire: 7200,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ use tokio::io::AsyncWrite;
|
||||
use anyhow::bail;
|
||||
use serde::Serialize;
|
||||
use std::slice;
|
||||
use std::sync::Once;
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt};
|
||||
use tracing::debug;
|
||||
|
||||
pub const HEADER_LEN: usize = 8;
|
||||
pub const MAX_PDU_LEN: u32 = 65535;
|
||||
@@ -22,6 +24,9 @@ pub const END_OF_DATA_V1_LEN: u32 = 24;
|
||||
pub const ZERO_16: u16 = 0;
|
||||
pub const ZERO_8: u8 = 0;
|
||||
|
||||
static ROUTER_KEY_RESERVED_ZERO_NONZERO_LOG_ONCE: Once = Once::new();
|
||||
static ASPA_RESERVED_ZERO_NONZERO_LOG_ONCE: Once = Once::new();
|
||||
|
||||
macro_rules! common {
|
||||
( $type:ident ) => {
|
||||
#[allow(dead_code)]
|
||||
@@ -1003,6 +1008,15 @@ impl RouterKey {
|
||||
let asn = Asn::from(u32::from_be_bytes(body[20..24].try_into().unwrap()));
|
||||
let subject_public_key_info = Arc::<[u8]>::from(body[24..].to_vec());
|
||||
|
||||
if header.zero() != 0 {
|
||||
ROUTER_KEY_RESERVED_ZERO_NONZERO_LOG_ONCE.call_once(|| {
|
||||
debug!(
|
||||
"received RouterKey PDU with non-zero reserved field (zero={}); ignoring per protocol compatibility",
|
||||
header.zero()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
let res = Self {
|
||||
header,
|
||||
flags: header.flags(),
|
||||
@@ -1015,10 +1029,25 @@ impl RouterKey {
|
||||
}
|
||||
|
||||
pub async fn write<A: AsyncWrite + Unpin>(&self, w: &mut A) -> Result<(), io::Error> {
|
||||
self.validate()?;
|
||||
let length = Self::BASE_LEN + self.subject_public_key_info.len();
|
||||
let length_u32 = u32::try_from(length).map_err(|_| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"RouterKey PDU length exceeds u32",
|
||||
)
|
||||
})?;
|
||||
if length_u32 > MAX_PDU_LEN {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!(
|
||||
"RouterKey PDU too large: {} octets exceeds max {}",
|
||||
length_u32, MAX_PDU_LEN
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
let header =
|
||||
HeaderWithFlags::new(self.header.version(), Self::PDU, self.flags, length as u32);
|
||||
let header = HeaderWithFlags::new(self.header.version(), Self::PDU, self.flags, length_u32);
|
||||
|
||||
w.write_all(&[
|
||||
header.version(),
|
||||
@@ -1028,7 +1057,7 @@ impl RouterKey {
|
||||
])
|
||||
.await?;
|
||||
|
||||
w.write_all(&(length as u32).to_be_bytes()).await?;
|
||||
w.write_all(&length_u32.to_be_bytes()).await?;
|
||||
w.write_all(self.ski.as_ref()).await?;
|
||||
w.write_all(&self.asn.into_u32().to_be_bytes()).await?;
|
||||
w.write_all(&self.subject_public_key_info).await?;
|
||||
@@ -1043,9 +1072,10 @@ impl RouterKey {
|
||||
subject_public_key_info: Arc<[u8]>,
|
||||
) -> Self {
|
||||
let length = Self::BASE_LEN + subject_public_key_info.len();
|
||||
let wire_length = u32::try_from(length).unwrap_or(u32::MAX);
|
||||
|
||||
Self {
|
||||
header: HeaderWithFlags::new(version, Self::PDU, flags, length as u32),
|
||||
header: HeaderWithFlags::new(version, Self::PDU, flags, wire_length),
|
||||
flags,
|
||||
ski,
|
||||
asn,
|
||||
@@ -1072,16 +1102,17 @@ impl RouterKey {
|
||||
"unexpected PDU type for RouterKey",
|
||||
));
|
||||
}
|
||||
if usize::try_from(self.header.length()).unwrap_or(0) < Self::BASE_LEN {
|
||||
let total_len = usize::try_from(self.header.length()).unwrap_or(0);
|
||||
if total_len < Self::BASE_LEN {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"RouterKey PDU shorter than fixed wire size",
|
||||
));
|
||||
}
|
||||
if self.header.zero() != 0 {
|
||||
if self.header.length() > MAX_PDU_LEN {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"RouterKey reserved zero octet must be zero",
|
||||
"RouterKey PDU length exceeds MAX_PDU_LEN",
|
||||
));
|
||||
}
|
||||
if self.header.flags().into_u8() & !0x01 != 0 {
|
||||
@@ -1165,6 +1196,15 @@ impl Aspa {
|
||||
provider_asns.push(u32::from_be_bytes(chunk.try_into().unwrap()));
|
||||
}
|
||||
|
||||
if header.zero() != 0 {
|
||||
ASPA_RESERVED_ZERO_NONZERO_LOG_ONCE.call_once(|| {
|
||||
debug!(
|
||||
"received ASPA PDU with non-zero reserved field (zero={}); ignoring per protocol compatibility",
|
||||
header.zero()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
let res = Self {
|
||||
header,
|
||||
customer_asn,
|
||||
@@ -1175,13 +1215,26 @@ impl Aspa {
|
||||
}
|
||||
|
||||
pub async fn write<A: AsyncWrite + Unpin>(&self, w: &mut A) -> Result<(), io::Error> {
|
||||
self.validate()?;
|
||||
let length = Self::BASE_LEN + (self.provider_asns.len() * 4);
|
||||
let length_u32 = u32::try_from(length).map_err(|_| {
|
||||
io::Error::new(io::ErrorKind::InvalidData, "ASPA PDU length exceeds u32")
|
||||
})?;
|
||||
if length_u32 > MAX_PDU_LEN {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!(
|
||||
"ASPA PDU too large: {} octets exceeds max {}",
|
||||
length_u32, MAX_PDU_LEN
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
let header = HeaderWithFlags::new(
|
||||
self.header.version(),
|
||||
Self::PDU,
|
||||
self.header.flags(),
|
||||
length as u32,
|
||||
length_u32,
|
||||
);
|
||||
|
||||
w.write_all(&[
|
||||
@@ -1192,7 +1245,7 @@ impl Aspa {
|
||||
])
|
||||
.await?;
|
||||
|
||||
w.write_all(&(length as u32).to_be_bytes()).await?;
|
||||
w.write_all(&length_u32.to_be_bytes()).await?;
|
||||
w.write_all(&self.customer_asn.to_be_bytes()).await?;
|
||||
|
||||
for asn in &self.provider_asns {
|
||||
@@ -1203,9 +1256,10 @@ impl Aspa {
|
||||
}
|
||||
pub fn new(version: u8, flags: Flags, customer_asn: u32, provider_asns: Vec<u32>) -> Self {
|
||||
let length = Self::BASE_LEN + (provider_asns.len() * 4);
|
||||
let wire_length = u32::try_from(length).unwrap_or(u32::MAX);
|
||||
|
||||
Self {
|
||||
header: HeaderWithFlags::new(version, Self::PDU, flags, length as u32),
|
||||
header: HeaderWithFlags::new(version, Self::PDU, flags, wire_length),
|
||||
customer_asn,
|
||||
provider_asns,
|
||||
}
|
||||
@@ -1225,18 +1279,18 @@ impl Aspa {
|
||||
"ASPA PDU shorter than fixed wire size",
|
||||
));
|
||||
}
|
||||
if self.header.length() > MAX_PDU_LEN {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"ASPA PDU length exceeds MAX_PDU_LEN",
|
||||
));
|
||||
}
|
||||
if (total_len - Self::BASE_LEN) % 4 != 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"ASPA provider list length must be a multiple of four octets",
|
||||
));
|
||||
}
|
||||
if self.header.zero() != 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"ASPA reserved zero octet must be zero",
|
||||
));
|
||||
}
|
||||
if self.header.flags().into_u8() & !0x01 != 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
|
||||
Reference in New Issue
Block a user