#![allow(clippy::assertions_on_constants)]
use slither::constants::*;
use std::time::Duration;
#[test]
fn version() {
assert_eq!(VERSION, 0x01);
}
#[test]
fn pkt_handshake_init() {
assert_eq!(PKT_HANDSHAKE_INIT, 0x01);
}
#[test]
fn pkt_handshake_resp() {
assert_eq!(PKT_HANDSHAKE_RESP, 0x02);
}
#[test]
fn pkt_data() {
assert_eq!(PKT_DATA, 0x03);
}
#[test]
fn pkt_reserved_unused() {
assert_eq!(PKT_RESERVED_UNUSED, 0x04);
}
#[test]
fn pkt_reserved_cookie() {
assert_eq!(PKT_RESERVED_COOKIE, 0x05);
}
#[test]
fn init_header_len() {
assert_eq!(INIT_HEADER_LEN, 6);
}
#[test]
fn resp_header_len() {
assert_eq!(RESP_HEADER_LEN, 10);
}
#[test]
fn data_header_len() {
assert_eq!(DATA_HEADER_LEN, 14);
}
#[test]
fn max_datagram() {
assert_eq!(MAX_DATAGRAM, 1200);
}
#[test]
fn max_plaintext() {
assert_eq!(MAX_PLAINTEXT, 1170);
}
#[test]
fn static_public_len() {
assert_eq!(STATIC_PUBLIC_LEN, 65);
}
#[test]
fn aead_tag_len() {
assert_eq!(AEAD_TAG_LEN, 16);
}
#[test]
fn msg1_payload_len() {
assert_eq!(MSG1_PAYLOAD_LEN, 12);
}
#[test]
fn ik_msg1_len() {
assert_eq!(IK_MSG1_LEN, 174);
}
#[test]
fn ik_msg2_len() {
assert_eq!(IK_MSG2_LEN, 81);
}
#[test]
fn init_packet_len() {
assert_eq!(INIT_PACKET_LEN, 196);
}
#[test]
fn resp_packet_len() {
assert_eq!(RESP_PACKET_LEN, 107);
}
#[test]
fn prologue() {
assert_eq!(PROLOGUE, b"slither\x01");
}
#[test]
fn timestamp_len() {
assert_eq!(TIMESTAMP_LEN, 12);
}
#[test]
fn mac1_label() {
assert_eq!(MAC1_LABEL, b"slither mac1");
}
#[test]
fn mac1_len() {
assert_eq!(MAC1_LEN, 16);
}
#[test]
fn retransmit_base() {
assert_eq!(RETRANSMIT_BASE, Duration::from_secs(5));
}
#[test]
fn retransmit_jitter_max() {
assert_eq!(RETRANSMIT_JITTER_MAX, Duration::from_millis(333));
}
#[test]
fn handshake_giveup() {
assert_eq!(HANDSHAKE_GIVEUP, Duration::from_secs(90));
}
#[test]
fn intro_queue_cap() {
assert_eq!(INTRO_QUEUE_CAP, 1024);
}
#[test]
fn intro_max_per_source() {
assert_eq!(INTRO_MAX_PER_SOURCE, 4);
}
#[test]
fn intro_ttl() {
assert_eq!(INTRO_TTL, Duration::from_secs(15));
}
#[test]
fn replay_window() {
assert_eq!(REPLAY_WINDOW, 2048);
}
#[test]
fn amplification_factor() {
assert_eq!(AMPLIFICATION_FACTOR, 3);
}
#[test]
fn keepalive_timeout() {
assert_eq!(KEEPALIVE_TIMEOUT, Duration::from_secs(10));
}
#[test]
fn dead_timeout() {
assert_eq!(DEAD_TIMEOUT, Duration::from_secs(25));
}
#[test]
fn persistent_keepalive_default() {
assert_eq!(PERSISTENT_KEEPALIVE_DEFAULT, Duration::from_secs(10));
}
#[test]
fn persistent_keepalive_min() {
assert_eq!(PERSISTENT_KEEPALIVE_MIN, Duration::from_secs(1));
}
#[test]
fn rekey_epoch_msgs() {
assert_eq!(REKEY_EPOCH_MSGS, 65_536);
}
#[test]
fn max_epoch_jump() {
assert_eq!(MAX_EPOCH_JUMP, 2);
}
#[test]
fn frame_padding() {
assert_eq!(FRAME_PADDING, 0x00);
}
#[test]
fn frame_ping() {
assert_eq!(FRAME_PING, 0x01);
}
#[test]
fn frame_ack() {
assert_eq!(FRAME_ACK, 0x02);
}
#[test]
fn frame_reset_stream() {
assert_eq!(FRAME_RESET_STREAM, 0x04);
}
#[test]
fn frame_stop_sending_reserved() {
assert_eq!(FRAME_STOP_SENDING_RESERVED, 0x05);
}
#[test]
fn frame_stream_base() {
assert_eq!(FRAME_STREAM_BASE, 0x08);
}
#[test]
fn frame_stream_max() {
assert_eq!(FRAME_STREAM_MAX, 0x0f);
}
#[test]
fn frame_max_data() {
assert_eq!(FRAME_MAX_DATA, 0x10);
}
#[test]
fn frame_max_stream_data() {
assert_eq!(FRAME_MAX_STREAM_DATA, 0x11);
}
#[test]
fn frame_max_streams_bidi() {
assert_eq!(FRAME_MAX_STREAMS_BIDI, 0x12);
}
#[test]
fn frame_max_streams_uni() {
assert_eq!(FRAME_MAX_STREAMS_UNI, 0x13);
}
#[test]
fn frame_close() {
assert_eq!(FRAME_CLOSE, 0x1c);
}
#[test]
fn frame_datagram() {
assert_eq!(FRAME_DATAGRAM, 0x30);
}
#[test]
fn frame_datagram_len() {
assert_eq!(FRAME_DATAGRAM_LEN, 0x31);
}
#[test]
fn stream_off() {
assert_eq!(STREAM_OFF, 0x04);
}
#[test]
fn stream_len() {
assert_eq!(STREAM_LEN, 0x02);
}
#[test]
fn stream_fin() {
assert_eq!(STREAM_FIN, 0x01);
}
#[test]
fn stream_flag_mask() {
assert_eq!(STREAM_FLAG_MASK, 0x07);
}
#[test]
fn close_reason_max() {
assert_eq!(CLOSE_REASON_MAX, 256);
}
#[test]
fn message_recv_max() {
assert_eq!(MESSAGE_RECV_MAX, 262_144);
}
#[test]
fn initial_max_data() {
assert_eq!(INITIAL_MAX_DATA, 1_048_576);
}
#[test]
fn initial_max_stream_data() {
assert_eq!(INITIAL_MAX_STREAM_DATA, 262_144);
}
#[test]
fn initial_max_streams_bidi() {
assert_eq!(INITIAL_MAX_STREAMS_BIDI, 32);
}
#[test]
fn initial_max_streams_uni() {
assert_eq!(INITIAL_MAX_STREAMS_UNI, 128);
}
#[test]
fn streams_credit_batch() {
assert_eq!(STREAMS_CREDIT_BATCH, 8);
}
#[test]
fn credit_regrant_divisor() {
assert_eq!(CREDIT_REGRANT_DIVISOR, 2);
}
#[test]
fn reassembly_chunks_max() {
assert_eq!(REASSEMBLY_CHUNKS_MAX, 1024);
}
#[test]
fn max_datagram_payload() {
assert_eq!(MAX_DATAGRAM_PAYLOAD, 1169);
}
#[test]
fn datagram_send_queue() {
assert_eq!(DATAGRAM_SEND_QUEUE, 64);
}
#[test]
fn datagram_recv_queue() {
assert_eq!(DATAGRAM_RECV_QUEUE, 64);
}
#[test]
fn max_ack_ranges() {
assert_eq!(MAX_ACK_RANGES, 64);
}
#[test]
fn ack_eliciting_per_ack() {
assert_eq!(ACK_ELICITING_PER_ACK, 2);
}
#[test]
fn max_ack_delay() {
assert_eq!(MAX_ACK_DELAY, Duration::from_millis(25));
}
#[test]
fn k_packet_threshold() {
assert_eq!(K_PACKET_THRESHOLD, 3);
}
#[test]
fn k_time_threshold_num() {
assert_eq!(K_TIME_THRESHOLD_NUM, 9);
}
#[test]
fn k_time_threshold_den() {
assert_eq!(K_TIME_THRESHOLD_DEN, 8);
}
#[test]
fn k_granularity() {
assert_eq!(K_GRANULARITY, Duration::from_millis(1));
}
#[test]
fn k_initial_rtt() {
assert_eq!(K_INITIAL_RTT, Duration::from_millis(333));
}
#[test]
fn pto_backoff_cap() {
assert_eq!(PTO_BACKOFF_CAP, 8);
}
#[test]
fn initial_window() {
assert_eq!(INITIAL_WINDOW, 12_000);
}
#[test]
fn minimum_window() {
assert_eq!(MINIMUM_WINDOW, 2_400);
}
#[test]
fn loss_reduction_factor() {
assert_eq!(LOSS_REDUCTION_FACTOR, 0.5);
}
#[test]
fn persistent_congestion_threshold() {
assert_eq!(PERSISTENT_CONGESTION_THRESHOLD, 3);
}
#[test]
fn close_linger() {
assert_eq!(CLOSE_LINGER, Duration::from_secs(5));
}
#[test]
fn close_reply_min_interval() {
assert_eq!(CLOSE_REPLY_MIN_INTERVAL, Duration::from_secs(1));
}
#[test]
fn no_error() {
assert_eq!(NO_ERROR, 0x00);
}
#[test]
fn protocol_violation() {
assert_eq!(PROTOCOL_VIOLATION, 0x01);
}
#[test]
fn flow_control_error() {
assert_eq!(FLOW_CONTROL_ERROR, 0x02);
}
#[test]
fn stream_limit_error() {
assert_eq!(STREAM_LIMIT_ERROR, 0x03);
}
#[test]
fn stream_state_error() {
assert_eq!(STREAM_STATE_ERROR, 0x04);
}
#[test]
fn final_size_error() {
assert_eq!(FINAL_SIZE_ERROR, 0x05);
}
#[test]
fn message_overflow() {
assert_eq!(MESSAGE_OVERFLOW, 0x06);
}
#[test]
fn application_error_base() {
assert_eq!(APPLICATION_ERROR_BASE, 0x10);
}
#[test]
fn shell_lateness_bound() {
assert_eq!(SHELL_LATENESS_BOUND, Duration::from_millis(250));
}
#[test]
fn ts_guard_orphan_cap() {
assert_eq!(TS_GUARD_ORPHAN_CAP, 1024);
}
#[test]
fn max_plaintext_is_datagram_minus_header_minus_tag() {
assert_eq!(MAX_PLAINTEXT, MAX_DATAGRAM - DATA_HEADER_LEN - AEAD_TAG_LEN);
}
#[test]
fn max_datagram_payload_is_max_plaintext_minus_one() {
assert_eq!(MAX_DATAGRAM_PAYLOAD, MAX_PLAINTEXT - 1);
}
#[test]
fn init_packet_len_is_header_plus_msg1_plus_mac1() {
assert_eq!(INIT_PACKET_LEN, INIT_HEADER_LEN + IK_MSG1_LEN + MAC1_LEN);
}
#[test]
fn resp_packet_len_is_header_plus_msg2_plus_mac1() {
assert_eq!(RESP_PACKET_LEN, RESP_HEADER_LEN + IK_MSG2_LEN + MAC1_LEN);
}
#[test]
fn ik_msg1_len_is_two_statics_two_tags_plus_payload() {
assert_eq!(
IK_MSG1_LEN,
2 * STATIC_PUBLIC_LEN + 2 * AEAD_TAG_LEN + MSG1_PAYLOAD_LEN
);
}
#[test]
fn ik_msg2_len_is_one_static_plus_tag() {
assert_eq!(IK_MSG2_LEN, STATIC_PUBLIC_LEN + AEAD_TAG_LEN);
}
#[test]
fn dead_timeout_is_twice_keepalive_plus_five_seconds() {
assert_eq!(DEAD_TIMEOUT, 2 * KEEPALIVE_TIMEOUT + Duration::from_secs(5));
}
#[test]
fn message_recv_max_equals_initial_max_stream_data() {
assert_eq!(MESSAGE_RECV_MAX, INITIAL_MAX_STREAM_DATA);
}
#[test]
fn stream_flag_mask_is_union_of_flags() {
assert_eq!(STREAM_FLAG_MASK, STREAM_OFF | STREAM_LEN | STREAM_FIN);
}
#[test]
fn frame_stream_max_is_base_or_flag_mask() {
assert_eq!(FRAME_STREAM_MAX, FRAME_STREAM_BASE | STREAM_FLAG_MASK);
}
#[test]
fn persistent_keepalive_default_is_within_admissible_range() {
assert!(PERSISTENT_KEEPALIVE_DEFAULT >= PERSISTENT_KEEPALIVE_MIN);
assert!(PERSISTENT_KEEPALIVE_DEFAULT < DEAD_TIMEOUT);
}
#[test]
fn wire_error_codes_are_all_below_application_base() {
assert!(NO_ERROR < APPLICATION_ERROR_BASE);
assert!(PROTOCOL_VIOLATION < APPLICATION_ERROR_BASE);
assert!(FLOW_CONTROL_ERROR < APPLICATION_ERROR_BASE);
assert!(STREAM_LIMIT_ERROR < APPLICATION_ERROR_BASE);
assert!(STREAM_STATE_ERROR < APPLICATION_ERROR_BASE);
assert!(FINAL_SIZE_ERROR < APPLICATION_ERROR_BASE);
assert!(MESSAGE_OVERFLOW < APPLICATION_ERROR_BASE);
}
#[test]
fn frame_path_challenge() {
assert_eq!(FRAME_PATH_CHALLENGE, 0x1a);
}
#[test]
fn frame_path_response() {
assert_eq!(FRAME_PATH_RESPONSE, 0x1b);
}
#[test]
fn path_frames_are_distinct_and_ordered() {
assert_ne!(FRAME_PATH_CHALLENGE, FRAME_PATH_RESPONSE);
assert!(FRAME_PATH_CHALLENGE < FRAME_PATH_RESPONSE);
assert_eq!(FRAME_PATH_RESPONSE, FRAME_PATH_CHALLENGE + 1);
}
#[test]
fn path_frame_codes_collide_with_no_existing_frame_type() {
let existing: [u64; 14] = [
FRAME_PADDING,
FRAME_PING,
FRAME_ACK,
FRAME_RESET_STREAM,
FRAME_STOP_SENDING_RESERVED,
FRAME_STREAM_BASE,
FRAME_STREAM_MAX,
FRAME_MAX_DATA,
FRAME_MAX_STREAM_DATA,
FRAME_MAX_STREAMS_BIDI,
FRAME_MAX_STREAMS_UNI,
FRAME_CLOSE,
FRAME_DATAGRAM,
FRAME_DATAGRAM_LEN,
];
for code in existing {
assert_ne!(
code, FRAME_PATH_CHALLENGE,
"PATH_CHALLENGE (0x1a) collides with an existing §8.3 frame code",
);
assert_ne!(
code, FRAME_PATH_RESPONSE,
"PATH_RESPONSE (0x1b) collides with an existing §8.3 frame code",
);
}
for code in [FRAME_PATH_CHALLENGE, FRAME_PATH_RESPONSE] {
assert!(
!(FRAME_STREAM_BASE..=FRAME_STREAM_MAX).contains(&code),
"a path frame code fell inside §8.3's 0x08-0x0f STREAM range",
);
}
}
#[test]
fn no_existing_frame_code_moved_for_ruling_208() {
assert_eq!(FRAME_PADDING, 0x00);
assert_eq!(FRAME_PING, 0x01);
assert_eq!(FRAME_ACK, 0x02);
assert_eq!(FRAME_RESET_STREAM, 0x04);
assert_eq!(FRAME_STOP_SENDING_RESERVED, 0x05);
assert_eq!(FRAME_STREAM_BASE, 0x08);
assert_eq!(FRAME_STREAM_MAX, 0x0f);
assert_eq!(FRAME_MAX_DATA, 0x10);
assert_eq!(FRAME_MAX_STREAM_DATA, 0x11);
assert_eq!(FRAME_MAX_STREAMS_BIDI, 0x12);
assert_eq!(FRAME_MAX_STREAMS_UNI, 0x13);
assert_eq!(FRAME_CLOSE, 0x1c);
assert_eq!(FRAME_DATAGRAM, 0x30);
assert_eq!(FRAME_DATAGRAM_LEN, 0x31);
}
#[test]
fn path_frame_codes_encode_as_a_one_byte_varint() {
assert!(FRAME_PATH_CHALLENGE < 64);
assert!(FRAME_PATH_RESPONSE < 64);
}
#[test]
fn a_path_challenge_datagram_fits_the_smallest_budget_its_arming_creates() {
let smallest_arming_credit = DATA_HEADER_LEN + AEAD_TAG_LEN;
let budget = AMPLIFICATION_FACTOR as usize * smallest_arming_credit;
let challenge_datagram = DATA_HEADER_LEN + 1 + 8 + AEAD_TAG_LEN;
assert_eq!(smallest_arming_credit, 30);
assert_eq!(budget, 90);
assert_eq!(challenge_datagram, 39);
assert!(budget >= challenge_datagram);
assert_eq!(budget - challenge_datagram, 51);
}
#[test]
fn a_challenge_and_a_contested_probe_fit_one_arming_together() {
let ping = 1;
let challenge_frame = 1 + 8;
let both = DATA_HEADER_LEN + ping + challenge_frame + AEAD_TAG_LEN;
assert_eq!(both, 40);
let budget = AMPLIFICATION_FACTOR as usize * (DATA_HEADER_LEN + AEAD_TAG_LEN);
assert!(both <= budget);
assert_eq!(budget, 90);
}
#[test]
fn the_msg1_anchor_budget_still_admits_a_challenge_after_the_msg2_charge() {
let anchor_credit = INIT_PACKET_LEN;
let budget = AMPLIFICATION_FACTOR as usize * anchor_credit;
assert_eq!(budget, 588);
let after_msg2 = budget - RESP_PACKET_LEN;
assert_eq!(after_msg2, 481);
let challenge_datagram = DATA_HEADER_LEN + 1 + 8 + AEAD_TAG_LEN;
assert!(after_msg2 >= challenge_datagram);
assert_eq!(budget - after_msg2, RESP_PACKET_LEN);
}