add check every so other
This commit is contained in:
		@@ -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<Option<Duration>, D::Error>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								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::time::Instant>()),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<RtnlMessage>) -> 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<D, M>(&mut self, log_msg: &D, msg: &M) -> Option<()>
 | 
			
		||||
    pub async fn log_and_check<D, M>(&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!(
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								src/utils.rs
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								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<Config> {
 | 
			
		||||
    }
 | 
			
		||||
    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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user