srt/protocol/
connection.rs

1use crate::connection::ConnectionSettings;
2use crate::protocol::Timer;
3
4use std::cmp::min;
5use std::time::{Duration, Instant};
6
7use log::info;
8
9/// Handing connection timeout, etc
10/// The only events that this entity cares about is when packets are recevied from the remote,
11/// and when packets are sent from the remote
12pub struct Connection {
13    exp_count: u32,
14    exp_timer: Timer,
15
16    // this isn't in the spec, but it's in the reference implementation
17    // https://github.com/Haivision/srt/blob/1d7b391905d7e344d80b86b39ac5c90fda8764a9/srtcore/core.cpp#L10610-L10614
18    keepalive_timer: Timer,
19}
20
21pub enum ConnectionAction {
22    ContinueUntil(Instant),
23    SendKeepAlive,
24    Close, // due to timeout
25}
26
27impl Connection {
28    pub fn new(conn: ConnectionSettings) -> Self {
29        Self {
30            exp_count: 1,
31            exp_timer: Timer::new(Duration::from_millis(500), conn.socket_start_time),
32            // 1s period https://github.com/Haivision/srt/blob/1d7b391905d7e344d80b86b39ac5c90fda8764a9/srtcore/core.h#L647
33            keepalive_timer: Timer::new(Duration::from_secs(1), conn.socket_start_time),
34        }
35    }
36    pub fn on_packet(&mut self, now: Instant) {
37        self.exp_count = 1;
38        self.exp_timer.reset(now);
39    }
40    pub fn on_send(&mut self, now: Instant) {
41        self.keepalive_timer.reset(now);
42    }
43    pub fn next_action(&mut self, now: Instant) -> ConnectionAction {
44        if let Some(exp) = self.exp_timer.check_expired(now) {
45            self.exp_count += 1;
46            info!("Exp event hit, exp count={}", self.exp_count);
47            if self.exp_count == 16 {
48                info!("16 exps, timeout!");
49            }
50            self.exp_timer.reset(exp)
51        }
52        if let Some(exp) = self.keepalive_timer.check_expired(now) {
53            self.keepalive_timer.reset(exp);
54            return ConnectionAction::SendKeepAlive;
55        }
56        if self.exp_count >= 16 {
57            ConnectionAction::Close
58        } else {
59            ConnectionAction::ContinueUntil(min(
60                self.exp_timer.next_instant(),
61                self.keepalive_timer.next_instant(),
62            ))
63        }
64    }
65}
66
67// 0.5s min, accordiding to page 9
68// self.exp.set_period(max(
69//     4 * rtt + rtt_var + self.syn.period(),
70//     Duration::from_millis(500),
71// ));