From b6f447e39f9406cb5d18c114c57f496de3479be2 Mon Sep 17 00:00:00 2001 From: Love Billenius Date: Thu, 25 Jul 2024 20:32:52 +0200 Subject: [PATCH] add check every so other --- src/config.rs | 37 ++++--------------------------------- src/main.rs | 29 +++++++++++++++++++++++++++-- src/message_handler.rs | 20 ++++++++++++++------ src/utils.rs | 31 +++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 41 deletions(-) diff --git a/src/config.rs b/src/config.rs index 64d7b2a..8fb4503 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ // SPDX: BSD-2-Clause +use crate::utils::duration_to_string; use anyhow; use dirs; use log::warn; @@ -81,40 +82,10 @@ mod duration_format { where S: Serializer, { - let duration = if let Some(aux) = duration.as_ref() { - aux - } else { - return serializer.serialize_none(); - }; - - let mut secs = duration.as_secs(); - let nanos = duration.subsec_nanos(); - - let days = secs / 86400; - secs %= 86400; - let hours = secs / 3600; - secs %= 3600; - let minutes = secs / 60; - secs %= 60; - - let mut formatted = String::new(); - if days > 0 { - formatted.push_str(&format!("{}d ", days)); + match duration.as_ref() { + Some(duration) => serializer.serialize_str(duration_to_string(duration).trim()), + None => serializer.serialize_none(), } - if hours > 0 { - formatted.push_str(&format!("{}h ", hours)); - } - if minutes > 0 { - formatted.push_str(&format!("{}m ", minutes)); - } - if secs > 0 { - formatted.push_str(&format!("{}s ", secs)); - } - if nanos > 0 { - formatted.push_str(&format!("{}ns", nanos)); - } - - serializer.serialize_str(formatted.trim()) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> diff --git a/src/main.rs b/src/main.rs index d8863ea..3cb43f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ // SPDX: BSD-2-Clause +use futures::future::{self, Either}; use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -10,9 +11,12 @@ use log::{error, info}; use netlink_sys::{AsyncSocket, SocketAddr}; use rtnetlink::new_connection; -use dynip_cloudflare::{utils, CloudflareClient, MessageHandler, MAX_ERORS_IN_ROW_DEFAULT}; +use dynip_cloudflare::{ + utils::{self, duration_to_string}, + CloudflareClient, MessageHandler, MAX_ERORS_IN_ROW_DEFAULT, +}; use scopeguard::defer; -use tokio::{signal, sync::Notify}; +use tokio::{signal, sync::Notify, time}; const RTNLGRP_LINK: u32 = 1; const RTNLGRP_IPV4_IFADDR: u32 = 5; @@ -81,11 +85,32 @@ async fn main() { config.max_errors_in_row.unwrap_or(MAX_ERORS_IN_ROW_DEFAULT), ); + let mut interval = config.max_duration.map(|duration| { + let mut interval = time::interval(duration); + interval.set_missed_tick_behavior(time::MissedTickBehavior::Delay); + interval + }); + while !should_exit.load(Ordering::SeqCst) { + let tick_future = match interval.as_mut() { + Some(interval) => Either::Left(interval.tick()), + None => Either::Right(future::pending::()), + }; + tokio::select! { _ = notify.notified() => break, + _ = tick_future => { + if let Some(duration) = config.max_duration.as_ref() { + let duration_string = duration_to_string(duration); + let log_string = format!("{} has passed since last check, checking...", duration_string.trim()); + message_handler.log_and_check(Some(&log_string), Option::<&&str>::None).await; + } + } message = messages.next() => { if let Some((message, _)) = message { + if let Some(interval) = interval.as_mut() { + interval.reset(); + } message_handler.handle_message(message).await; } } diff --git a/src/message_handler.rs b/src/message_handler.rs index d51a017..1893c97 100644 --- a/src/message_handler.rs +++ b/src/message_handler.rs @@ -1,7 +1,6 @@ // SPDX: BSD-2-Clause use std::fmt; - use log::{debug, error, info}; use netlink_packet_core::{NetlinkMessage, NetlinkPayload}; use netlink_packet_route::RouteNetlinkMessage as RtnlMessage; @@ -34,13 +33,14 @@ where pub async fn handle_message(&mut self, message: NetlinkMessage) -> Option<()> { match message.payload { NetlinkPayload::InnerMessage(RtnlMessage::NewAddress(msg)) => { - self.log_and_check("New IPv4 address", &msg).await + self.log_and_check(Some("New IPv4 address"), Some(&msg)) + .await } NetlinkPayload::InnerMessage(RtnlMessage::DelAddress(msg)) => { self.log_info("Deleted IPv4 address", &msg).await } NetlinkPayload::InnerMessage(RtnlMessage::NewLink(link)) => { - self.log_and_check("New link (interface connected)", &link) + self.log_and_check(Some("New link (interface connected)"), Some(&link)) .await } NetlinkPayload::InnerMessage(RtnlMessage::DelLink(link)) => { @@ -54,13 +54,21 @@ where } } - async fn log_and_check(&mut self, log_msg: &D, msg: &M) -> Option<()> + pub async fn log_and_check(&mut self, log_msg: Option<&D>, msg: Option<&M>) -> Option<()> where D: fmt::Display + ?Sized, M: fmt::Debug, { - info!("{}", log_msg); - debug!("{}: {:?}", log_msg, msg); + if let Some(s) = log_msg { + info!("{}", s); + } + if let Some(m) = msg { + if let Some(lm) = log_msg { + debug!("{}: {:?}", lm, m); + } else { + debug!("{:?}", m); + } + } if let Err(e) = self.cloudflare.check().await { self.errs_counter += 1; error!( diff --git a/src/utils.rs b/src/utils.rs index 62fb185..a4e36ae 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,5 +1,7 @@ // SPDX: BSD-2-Clause +use std::time::Duration; + use crate::{get_config_path, read_config, Config}; use log::error; @@ -28,3 +30,32 @@ pub async fn get_config() -> Option { } read_result.ok() } +pub fn duration_to_string(duration: &Duration) -> String { + let mut secs = duration.as_secs(); + let nanos = duration.subsec_nanos(); + + let days = secs / 86400; + secs %= 86400; + let hours = secs / 3600; + secs %= 3600; + let minutes = secs / 60; + secs %= 60; + + let mut ret = String::new(); + if days > 0 { + ret.push_str(&format!("{}d ", days)); + } + if hours > 0 { + ret.push_str(&format!("{}h ", hours)); + } + if minutes > 0 { + ret.push_str(&format!("{}m ", minutes)); + } + if secs > 0 { + ret.push_str(&format!("{}s ", secs)); + } + if nanos > 0 { + ret.push_str(&format!("{}ns", nanos)); + } + ret +}