do smarter IP deserialization

This commit is contained in:
Joe Ardent 2025-08-08 13:38:16 -07:00
parent 940e7984e3
commit cb071f4a7c
2 changed files with 21 additions and 15 deletions

View file

@ -147,7 +147,7 @@ impl Widget for &mut App {
buf, buf,
); );
network_info( network_info(
&self.service.config.local_ip_addr.unwrap_or([0u8; 4].into()), &self.service.config.local_ip_addr,
footer_left.inner(footer_margin), footer_left.inner(footer_margin),
buf, buf,
); );

View file

@ -9,7 +9,7 @@ use figment::{
providers::{Format, Serialized, Toml}, providers::{Format, Serialized, Toml},
}; };
use local_ip_address::local_ip; use local_ip_address::local_ip;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use crate::{ use crate::{
DEFAULT_PORT, MULTICAST_IP, DEFAULT_PORT, MULTICAST_IP,
@ -22,8 +22,8 @@ pub struct Config {
pub multicast_addr: SocketAddrV4, pub multicast_addr: SocketAddrV4,
pub download_dir: PathBuf, pub download_dir: PathBuf,
pub data_dir: PathBuf, pub data_dir: PathBuf,
#[serde(skip_serializing)] #[serde(deserialize_with = "deserialize_local_addr")]
pub local_ip_addr: Option<Ipv4Addr>, pub local_ip_addr: Ipv4Addr,
pub device: Device, pub device: Device,
} }
@ -33,7 +33,7 @@ impl Default for Config {
multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT), multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT),
download_dir: Default::default(), download_dir: Default::default(),
data_dir: Default::default(), data_dir: Default::default(),
local_ip_addr: None, local_ip_addr: Ipv4Addr::from_bits(0),
device: Default::default(), device: Default::default(),
} }
} }
@ -47,10 +47,6 @@ impl Config {
let config_file = dirs.config_dir().join("jocalsend.toml"); let config_file = dirs.config_dir().join("jocalsend.toml");
let data_dir = dirs.data_local_dir().join("jocalsend"); let data_dir = dirs.data_local_dir().join("jocalsend");
let IpAddr::V4(local_ip_addr) = local_ip()? else {
return Err(LocalSendError::IPv6Unsupported);
};
let key = data_dir.join("key.pem"); let key = data_dir.join("key.pem");
let cert = data_dir.join("cert.pem"); let cert = data_dir.join("cert.pem");
let fingerprint = if data_dir.exists() { let fingerprint = if data_dir.exists() {
@ -67,8 +63,8 @@ impl Config {
let config = Self { let config = Self {
multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT), multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT),
local_ip_addr: get_local_ip_addr(),
download_dir, download_dir,
local_ip_addr: Some(local_ip_addr),
data_dir, data_dir,
device: Device { device: Device {
alias: rustix::system::uname() alias: rustix::system::uname()
@ -80,7 +76,7 @@ impl Config {
}, },
}; };
let mut config = if !config_file.exists() { let config = if !config_file.exists() {
log::info!("creating config file at {config_file:?}"); log::info!("creating config file at {config_file:?}");
std::fs::write(&config_file, toml::to_string(&config)?)?; std::fs::write(&config_file, toml::to_string(&config)?)?;
config config
@ -92,10 +88,6 @@ impl Config {
.map_err(Box::new)? // boxed because the error size from figment is large .map_err(Box::new)? // boxed because the error size from figment is large
}; };
if config.local_ip_addr.is_none() {
config.local_ip_addr = Some(local_ip_addr);
}
log::info!("using config: {config:?}"); log::info!("using config: {config:?}");
Ok(config) Ok(config)
@ -118,3 +110,17 @@ fn gen_ssl(key: &Path, cert: &Path) -> Result<String> {
std::fs::write(cert, cert_text)?; std::fs::write(cert, cert_text)?;
Ok(sha256::digest(key_text)) Ok(sha256::digest(key_text))
} }
fn deserialize_local_addr<'de, D>(_: D) -> std::result::Result<Ipv4Addr, D::Error>
where
D: Deserializer<'de>,
{
Ok(get_local_ip_addr())
}
fn get_local_ip_addr() -> Ipv4Addr {
let IpAddr::V4(local_ip_addr) = local_ip().unwrap_or(IpAddr::V4(Ipv4Addr::from_bits(0))) else {
panic!("IPv6 is unsupported");
};
local_ip_addr
}