break out network_change_listener
This commit is contained in:
		@@ -5,6 +5,7 @@ mod config;
 | 
			
		||||
mod exit_listener;
 | 
			
		||||
mod logging;
 | 
			
		||||
mod message_handler;
 | 
			
		||||
mod network_change_listener;
 | 
			
		||||
mod public_ip;
 | 
			
		||||
mod tests;
 | 
			
		||||
pub mod utils;
 | 
			
		||||
@@ -14,6 +15,7 @@ pub use config::{get_config_path, read_config, Config};
 | 
			
		||||
pub use exit_listener::ExitListener;
 | 
			
		||||
pub use logging::init_logger;
 | 
			
		||||
pub use message_handler::MessageHandler;
 | 
			
		||||
pub use network_change_listener::NetworkChangeListener;
 | 
			
		||||
pub use public_ip::get_current_public_ipv4;
 | 
			
		||||
 | 
			
		||||
pub const PROGRAM_NAME: &'static str = "dynip-cloudflare";
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,31 +1,14 @@
 | 
			
		||||
// SPDX: BSD-2-Clause
 | 
			
		||||
 | 
			
		||||
use futures::future::{self, Either};
 | 
			
		||||
use futures::stream::StreamExt;
 | 
			
		||||
use log::{error, info};
 | 
			
		||||
use netlink_sys::{AsyncSocket, SocketAddr};
 | 
			
		||||
use rtnetlink::new_connection;
 | 
			
		||||
 | 
			
		||||
use dynip_cloudflare::{
 | 
			
		||||
    utils::{self, duration_to_string},
 | 
			
		||||
    CloudflareClient, ExitListener, MessageHandler, MAX_ERORS_IN_ROW_DEFAULT,
 | 
			
		||||
};
 | 
			
		||||
use scopeguard::defer;
 | 
			
		||||
use tokio::time;
 | 
			
		||||
 | 
			
		||||
const RTNLGRP_LINK: u32 = 1;
 | 
			
		||||
const RTNLGRP_IPV4_IFADDR: u32 = 5;
 | 
			
		||||
 | 
			
		||||
const fn nl_mgrp(group: u32) -> u32 {
 | 
			
		||||
    if group > 31 {
 | 
			
		||||
        panic!("use netlink_sys::Socket::add_membership() for this group");
 | 
			
		||||
    }
 | 
			
		||||
    if group == 0 {
 | 
			
		||||
        0
 | 
			
		||||
    } else {
 | 
			
		||||
        1 << (group - 1)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
use dynip_cloudflare::{
 | 
			
		||||
    utils, CloudflareClient, ExitListener, MessageHandler, NetworkChangeListener,
 | 
			
		||||
    MAX_ERORS_IN_ROW_DEFAULT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() {
 | 
			
		||||
@@ -50,18 +33,16 @@ async fn main() {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    let (mut conn, mut _handle, mut messages) = new_connection().unwrap();
 | 
			
		||||
    let groups = nl_mgrp(RTNLGRP_LINK) | nl_mgrp(RTNLGRP_IPV4_IFADDR);
 | 
			
		||||
 | 
			
		||||
    let addr = SocketAddr::new(0, groups);
 | 
			
		||||
 | 
			
		||||
    if let Err(e) = conn.socket_mut().socket_mut().bind(&addr) {
 | 
			
		||||
        error!("Failed to bind to socket: {:?}", &e);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tokio::spawn(conn);
 | 
			
		||||
    info!("Listening for IPv4 address changes and interface connect/disconnect events...");
 | 
			
		||||
    let mut network_change_listener = match NetworkChangeListener::new() {
 | 
			
		||||
        Some(aux) => {
 | 
			
		||||
            info!("Listening for IPv4 address changes and interface connect/disconnect events...");
 | 
			
		||||
            aux
 | 
			
		||||
        }
 | 
			
		||||
        None => {
 | 
			
		||||
            error!("Failed to initialize networkchangelistener");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let mut message_handler = MessageHandler::new(
 | 
			
		||||
        &mut cloudflare,
 | 
			
		||||
@@ -84,12 +65,12 @@ async fn main() {
 | 
			
		||||
            _ = exit_listener.notified() => break,
 | 
			
		||||
            _ = tick_future => {
 | 
			
		||||
                if let Some(duration) = config.max_duration.as_ref() {
 | 
			
		||||
                    let duration_string = duration_to_string(duration);
 | 
			
		||||
                    let duration_string = utils::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() => {
 | 
			
		||||
            message = network_change_listener.next_message() => {
 | 
			
		||||
                if let Some((message, _)) = message {
 | 
			
		||||
                    if let Some(interval) = interval.as_mut() {
 | 
			
		||||
                        interval.reset();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								src/network_change_listener.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/network_change_listener.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
use futures::{
 | 
			
		||||
    channel::mpsc::UnboundedReceiver,
 | 
			
		||||
    stream::{Next, StreamExt},
 | 
			
		||||
};
 | 
			
		||||
use log::error;
 | 
			
		||||
use netlink_packet_core::NetlinkMessage;
 | 
			
		||||
use netlink_packet_route::RouteNetlinkMessage;
 | 
			
		||||
use netlink_sys::{AsyncSocket, SocketAddr};
 | 
			
		||||
use rtnetlink::new_connection;
 | 
			
		||||
use tokio::task::JoinHandle;
 | 
			
		||||
 | 
			
		||||
const RTNLGRP_LINK: u32 = 1;
 | 
			
		||||
const RTNLGRP_IPV4_IFADDR: u32 = 5;
 | 
			
		||||
 | 
			
		||||
const fn nl_mgrp(group: u32) -> u32 {
 | 
			
		||||
    if group > 31 {
 | 
			
		||||
        panic!("use netlink_sys::Socket::add_membership() for this group");
 | 
			
		||||
    }
 | 
			
		||||
    if group == 0 {
 | 
			
		||||
        0
 | 
			
		||||
    } else {
 | 
			
		||||
        1 << (group - 1)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Messages = UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>;
 | 
			
		||||
pub struct NetworkChangeListener {
 | 
			
		||||
    messages: Messages,
 | 
			
		||||
    thread_handle: JoinHandle<()>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl NetworkChangeListener {
 | 
			
		||||
    pub fn new() -> Option<Self> {
 | 
			
		||||
        let (mut conn, mut _handle, messages) = new_connection().ok()?;
 | 
			
		||||
        let groups = nl_mgrp(RTNLGRP_LINK) | nl_mgrp(RTNLGRP_IPV4_IFADDR);
 | 
			
		||||
 | 
			
		||||
        let addr = SocketAddr::new(0, groups);
 | 
			
		||||
 | 
			
		||||
        if let Err(e) = conn.socket_mut().socket_mut().bind(&addr) {
 | 
			
		||||
            error!("Failed to bind to socket: {:?}", &e);
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let thread_handle = tokio::spawn(conn);
 | 
			
		||||
        Some(Self {
 | 
			
		||||
            messages,
 | 
			
		||||
            thread_handle,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn next_message(&mut self) -> Next<'_, Messages> {
 | 
			
		||||
        self.messages.next()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Drop for NetworkChangeListener {
 | 
			
		||||
    fn drop(&mut self) {
 | 
			
		||||
        self.thread_handle.abort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user