#![forbid(unsafe_code)]
mod chunks;
mod error;
mod frame;
pub(crate) mod connection;
mod tagged_stream;
pub use crate::connection::{Connection, Mode, Packet, Stream};
pub use crate::error::ConnectionError;
pub use crate::frame::{
header::{HeaderDecodeError, StreamId},
FrameDecodeError,
};
const KIB: usize = 1024;
const MIB: usize = KIB * 1024;
const GIB: usize = MIB * 1024;
pub const DEFAULT_CREDIT: u32 = 256 * KIB as u32;
pub type Result<T> = std::result::Result<T, ConnectionError>;
const MAX_ACK_BACKLOG: usize = 256;
const DEFAULT_SPLIT_SEND_SIZE: usize = 16 * KIB;
#[derive(Debug, Clone)]
pub struct Config {
max_connection_receive_window: Option<usize>,
max_num_streams: usize,
read_after_close: bool,
split_send_size: usize,
}
impl Default for Config {
fn default() -> Self {
Config {
max_connection_receive_window: Some(GIB),
max_num_streams: 512,
read_after_close: true,
split_send_size: DEFAULT_SPLIT_SEND_SIZE,
}
}
}
impl Config {
pub fn set_max_connection_receive_window(&mut self, n: Option<usize>) -> &mut Self {
self.max_connection_receive_window = n;
assert!(
self.max_connection_receive_window.unwrap_or(usize::MAX)
>= self.max_num_streams * DEFAULT_CREDIT as usize,
"`max_connection_receive_window` must be `>= 256 KiB * max_num_streams` to allow each
stream at least the Yamux default window size"
);
self
}
pub fn set_max_num_streams(&mut self, n: usize) -> &mut Self {
self.max_num_streams = n;
assert!(
self.max_connection_receive_window.unwrap_or(usize::MAX)
>= self.max_num_streams * DEFAULT_CREDIT as usize,
"`max_connection_receive_window` must be `>= 256 KiB * max_num_streams` to allow each
stream at least the Yamux default window size"
);
self
}
pub fn set_read_after_close(&mut self, b: bool) -> &mut Self {
self.read_after_close = b;
self
}
pub fn set_split_send_size(&mut self, n: usize) -> &mut Self {
self.split_send_size = n;
self
}
}
static_assertions::const_assert! {
std::mem::size_of::<usize>() <= std::mem::size_of::<u64>()
}
static_assertions::const_assert! {
std::mem::size_of::<u32>() <= std::mem::size_of::<usize>()
}
#[cfg(test)]
impl quickcheck::Arbitrary for Config {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
use quickcheck::GenRange;
let max_num_streams = g.gen_range(0..u16::MAX as usize);
Config {
max_connection_receive_window: if bool::arbitrary(g) {
Some(g.gen_range((DEFAULT_CREDIT as usize * max_num_streams)..usize::MAX))
} else {
None
},
max_num_streams,
read_after_close: bool::arbitrary(g),
split_send_size: g.gen_range(DEFAULT_SPLIT_SEND_SIZE..usize::MAX),
}
}
}