summaryrefslogtreecommitdiffstats
path: root/src/timers.rs
blob: 0d69c3f868fa0532cde5f0166febb077eb1685c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;

use hjul::{Runner, Timer};

use crate::router::Callbacks;

const ZERO_DURATION: Duration = Duration::from_micros(0);

pub struct TimersInner {
    handshake_pending: AtomicBool,
    handshake_attempts: AtomicUsize,

    retransmit_handshake: Timer,
    send_keepalive: Timer,
    zero_key_material: Timer,
    new_handshake: Timer,

    // stats
    rx_bytes: AtomicU64,
    tx_bytes: AtomicU64,
}

impl TimersInner {
    pub fn new(runner: &Runner) -> Timers {
        Arc::new(TimersInner {
            handshake_pending: AtomicBool::new(false),
            handshake_attempts: AtomicUsize::new(0),
            retransmit_handshake: runner.timer(|| {}),
            new_handshake: runner.timer(|| {}),
            send_keepalive: runner.timer(|| {}),
            zero_key_material: runner.timer(|| {}),
            rx_bytes: AtomicU64::new(0),
            tx_bytes: AtomicU64::new(0),
        })
    }

    pub fn handshake_sent(&self) {
        self.send_keepalive.stop();
    }
}

pub type Timers = Arc<TimersInner>;

pub struct Events();

impl Callbacks for Events {
    type Opaque = Timers;

    fn send(t: &Timers, size: usize, data: bool, sent: bool) {
        t.tx_bytes.fetch_add(size as u64, Ordering::Relaxed);
    }

    fn recv(t: &Timers, size: usize, data: bool, sent: bool) {
        t.rx_bytes.fetch_add(size as u64, Ordering::Relaxed);
    }

    fn need_key(t: &Timers) {
        if !t.handshake_pending.swap(true, Ordering::SeqCst) {
            t.handshake_attempts.store(0, Ordering::SeqCst);
            t.new_handshake.reset(ZERO_DURATION);
        }
    }
}