pub mod simulator;
use simulator::*;
use std::{
cmp::min,
time::{Duration, Instant},
};
use log::trace;
use srt_protocol::{
connection::{Connection, ConnectionSettings, DuplexConnection, Input},
options::{PacketCount, PacketSize},
packet::*,
protocol::handshake::Handshake,
};
#[test]
fn timestamp_rollover() {
let _ = pretty_env_logger::try_init();
let s1_sockid = SocketId(1234);
let s2_sockid = SocketId(5678);
let s1_addr = ([127, 0, 0, 1], 2223).into();
let s2_addr = ([127, 0, 0, 1], 2222).into();
let init_seqnum = SeqNumber::new_truncate(91234);
let start = Instant::now() + Duration::from_micros(u32::MAX as u64);
let s1 = ConnectionSettings {
remote: s2_addr,
remote_sockid: s2_sockid,
local_sockid: s1_sockid,
socket_start_time: start,
rtt: Duration::default(),
init_seq_num: init_seqnum,
max_packet_size: PacketSize(1316),
max_flow_size: PacketCount(8192),
send_tsbpd_latency: Duration::from_millis(20),
recv_tsbpd_latency: Duration::from_millis(20),
cipher: None,
stream_id: None,
bandwidth: Default::default(),
recv_buffer_size: PacketCount(8192),
send_buffer_size: PacketCount(8192),
statistics_interval: Duration::from_secs(1),
peer_idle_timeout: Duration::from_secs(5),
too_late_packet_drop: true,
};
let s2 = ConnectionSettings {
remote: s1_addr,
remote_sockid: s1_sockid,
local_sockid: s2_sockid,
socket_start_time: start,
rtt: Duration::default(),
init_seq_num: init_seqnum,
max_packet_size: PacketSize(1316),
max_flow_size: PacketCount(8192),
send_tsbpd_latency: Duration::from_millis(20),
recv_tsbpd_latency: Duration::from_millis(20),
cipher: None,
stream_id: None,
bandwidth: Default::default(),
recv_buffer_size: PacketCount(8192),
send_buffer_size: PacketCount(8192),
statistics_interval: Duration::from_secs(1),
peer_idle_timeout: Duration::from_secs(5),
too_late_packet_drop: true,
};
const PACKET_RATE: u32 = 10; const STREAM_DURATION: u32 = 2 * 60 * 60;
let packs_to_send = STREAM_DURATION * PACKET_RATE;
let latency = Duration::from_millis(10);
let mut network = NetworkSimulator::new(s1_addr, s2_addr);
let mut sender = DuplexConnection::new(Connection {
settings: s1,
handshake: Handshake::Connector,
});
let mut receiver = DuplexConnection::new(Connection {
settings: s2,
handshake: Handshake::Connector,
});
input_data_simulation(
start,
packs_to_send as usize,
Duration::from_secs(1) / PACKET_RATE,
&mut network.sender,
);
let mut now = start;
let mut received = vec![];
let mut dropped = vec![];
let mut next_data = 1;
loop {
let sender_next_time = if sender.is_open() {
assert_eq!(sender.next_data(now), None);
while let Some(packet) = sender.next_packet(now) {
network.send(now + latency, packet);
}
let next_timer = sender.check_timers(now);
let (next_time, input) = network.sender.select_next_input(now, next_timer);
match input {
Input::Data(data) => sender.handle_data_input(next_time, data),
Input::Packet(packet) => sender.handle_packet_input(next_time, packet),
_ => {}
};
Some(next_time)
} else {
None
};
let receiver_next_time = if receiver.is_open() {
while let Some((_, payload)) = receiver.next_data(now) {
let actual: i32 = std::str::from_utf8(&payload[..]).unwrap().parse().unwrap();
received.push(actual);
dropped.extend(next_data..actual);
next_data = actual + 1;
}
while let Some(packet) = receiver.next_packet(now) {
network.send(now + latency, packet);
}
let next_timer = receiver.check_timers(now);
let (next_time, input) = network.receiver.select_next_input(now, next_timer);
match input {
Input::Data(data) => receiver.handle_data_input(now, data),
Input::Packet(packet) => receiver.handle_packet_input(now, packet),
_ => {}
};
Some(next_time)
} else {
None
};
let next_time = match (sender_next_time, receiver_next_time) {
(Some(s), Some(r)) => min(s, r),
(Some(s), None) => s,
(None, Some(r)) => r,
_ => break,
};
let delta = next_time - now;
trace!("Delta = {:?}", delta);
now = next_time;
}
assert_eq!(dropped, Vec::new());
assert_eq!(packs_to_send as usize, received.len());
}