dynip-cloudflare/src/message_handler.rs
2024-07-14 16:10:13 +02:00

81 lines
2.5 KiB
Rust

use std::fmt;
use log::{debug, error, info, log_enabled, Level};
use netlink_packet_core::{NetlinkMessage, NetlinkPayload};
use netlink_packet_route::RouteNetlinkMessage as RtnlMessage;
use crate::CloudflareClient;
pub struct MessageHandler<'a> {
cloudflare: &'a mut CloudflareClient,
errs_counter: usize,
errs_max: usize,
}
impl<'a> MessageHandler<'a> {
pub fn new(cloudflare: &'a mut CloudflareClient, errs_max: usize) -> Self {
Self {
cloudflare,
errs_counter: 0,
errs_max,
}
}
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
}
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)
.await
}
NetlinkPayload::InnerMessage(RtnlMessage::DelLink(link)) => {
self.log_info("Deleted link (interface disconnected)", &link)
.await
}
_ => {
if log_enabled!(Level::Debug) {
debug!("Unhandled message payload: {:?}", message.payload);
}
Some(())
}
}
}
async fn log_and_check<D, M>(&mut self, log_msg: &D, msg: &M) -> Option<()>
where
D: fmt::Display + ?Sized,
M: fmt::Debug,
{
if log_enabled!(Level::Debug) {
debug!("{}: {:?}", log_msg, msg);
} else {
info!("{}", log_msg);
if let Err(e) = self.cloudflare.check().await {
self.errs_counter += 1;
error!(
"Failed to check cloudflare ({}/{}): {:?}",
self.errs_counter, self.errs_max, &e
);
if self.errs_counter >= self.errs_max {
return None;
}
}
}
Some(())
}
async fn log_info<M: fmt::Debug>(&self, log_msg: &str, msg: &M) -> Option<()> {
if log_enabled!(Level::Debug) {
debug!("{:?} message: {:?}", log_msg, msg);
} else {
info!("{}", log_msg);
}
Some(())
}
}