break out network_change_listener

This commit is contained in:
Love 2024-07-25 21:01:40 +02:00
parent f34c4609a5
commit 0cd2d364aa
3 changed files with 78 additions and 35 deletions

View File

@ -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";

View File

@ -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();

View 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();
}
}