pub mod connect;
pub mod enroll;
pub mod serve;
pub mod tenant_serve;
use std::io;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
pub(crate) const MAX_TOKEN_LEN: usize = 4096;
const MAX_NAME_LEN: usize = 256;
pub(crate) async fn write_frame<W: AsyncWrite + Unpin>(w: &mut W, data: &[u8]) -> io::Result<()> {
let len: u16 = data
.len()
.try_into()
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "frame too large"))?;
w.write_all(&len.to_be_bytes()).await?;
w.write_all(data).await?;
w.flush().await
}
pub(crate) async fn read_frame<R: AsyncRead + Unpin>(
r: &mut R,
max_len: usize,
) -> io::Result<Vec<u8>> {
let mut len_buf = [0u8; 2];
r.read_exact(&mut len_buf).await?;
let len = u16::from_be_bytes(len_buf) as usize;
if len > max_len {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"frame too large",
));
}
let mut buf = vec![0u8; len];
r.read_exact(&mut buf).await?;
Ok(buf)
}
pub(crate) fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
if a.len() != b.len() {
return false;
}
let mut diff = 0u8;
for (x, y) in a.iter().zip(b.iter()) {
diff |= x ^ y;
}
diff == 0
}