use defguard_wireguard_rs::host::Peer;
use std::time::Duration;
const DEFAULT_PEER_MAX_FLUSHING_RATE: Duration = Duration::from_secs(60 * 60 * 24); const DEFAULT_PEER_MAX_DELTA_FLUSHING_AMOUNT: u64 = 512 * 1024 * 1024;
#[derive(Debug, Clone, Copy)]
pub struct PeerFlushingBehaviourConfig {
pub peer_max_flushing_rate: Duration,
pub peer_max_delta_flushing_amount: u64,
}
impl Default for PeerFlushingBehaviourConfig {
fn default() -> Self {
Self {
peer_max_flushing_rate: DEFAULT_PEER_MAX_FLUSHING_RATE,
peer_max_delta_flushing_amount: DEFAULT_PEER_MAX_DELTA_FLUSHING_AMOUNT,
}
}
}
pub struct CachedPeerManager {
pub(crate) peer_information: Option<PeerInformation>,
}
impl CachedPeerManager {
pub(crate) fn new(peer: &Peer) -> Self {
Self {
peer_information: Some(peer.into()),
}
}
pub(crate) fn get_peer(&self) -> Option<PeerInformation> {
self.peer_information
}
pub(crate) fn remove_peer(&mut self) {
self.peer_information = None;
}
pub(crate) fn update(&mut self, kernel_peer: PeerInformation) {
if let Some(peer_information) = self.peer_information.as_mut() {
peer_information.update_tx_rx_bytes(kernel_peer);
}
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct PeerInformation {
pub(crate) tx_bytes: u64,
pub(crate) rx_bytes: u64,
}
impl From<&Peer> for PeerInformation {
fn from(value: &Peer) -> Self {
Self {
tx_bytes: value.tx_bytes,
rx_bytes: value.rx_bytes,
}
}
}
impl PeerInformation {
pub(crate) fn update_tx_rx_bytes(&mut self, peer: PeerInformation) {
self.tx_bytes = peer.tx_bytes;
self.rx_bytes = peer.rx_bytes;
}
fn rx_tx_total(&self, typ: &'static str) -> Option<u64> {
self.rx_bytes.checked_add(self.tx_bytes).or_else(|| {
tracing::error!(
"overflow on {typ} adding bytes: {} + {}",
self.rx_bytes,
self.tx_bytes
);
None
})
}
pub(crate) fn consumed_bandwidth(kernel: &Self, previous_cached: &Self) -> Option<u64> {
let kernel_total = kernel.rx_tx_total("kernel")?;
let cached_total = previous_cached.rx_tx_total("cached")?;
kernel_total.checked_sub(cached_total).or_else(|| {
tracing::error!("Overflow on spent bandwidth subtraction: kernel - cached = {kernel_total} - {cached_total}");
None
})
}
pub(crate) fn consumed_kernel_bandwidth(&self, previous_cached: &Self) -> i64 {
let Some(consumed) = Self::consumed_bandwidth(self, previous_cached) else {
return 0;
};
consumed
.try_into()
.inspect_err(|err| tracing::error!("Could not convert from u64 to i64: {err:?}"))
.unwrap_or(i64::MAX)
}
}