mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
wip: tls refactor
This commit is contained in:
@@ -5,15 +5,62 @@ use async_stream::try_stream;
|
||||
use color_eyre::eyre::eyre;
|
||||
use futures::stream::BoxStream;
|
||||
use futures::{StreamExt, TryStreamExt};
|
||||
use imbl::OrdMap;
|
||||
use imbl_value::InternedString;
|
||||
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
||||
use models::GatewayId;
|
||||
use nix::net::if_::if_nametoindex;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::db::model::public::{NetworkInterfaceInfo, NetworkInterfaceType};
|
||||
use crate::prelude::*;
|
||||
use crate::util::collections::OrdMapIterMut;
|
||||
use crate::util::Invoke;
|
||||
|
||||
pub async fn load_network_interface_info() -> Result<OrdMap<GatewayId, NetworkInterfaceInfo>, Error>
|
||||
{
|
||||
let output = String::from_utf8(
|
||||
Command::new("ip")
|
||||
.arg("-o")
|
||||
.arg("addr")
|
||||
.arg("show")
|
||||
.invoke(crate::ErrorKind::Network)
|
||||
.await?,
|
||||
)?;
|
||||
|
||||
let err_fn = || {
|
||||
Error::new(
|
||||
eyre!("malformed output from `ip`"),
|
||||
crate::ErrorKind::Network,
|
||||
)
|
||||
};
|
||||
|
||||
let mut res = OrdMap::<GatewayId, NetworkInterfaceInfo>::new();
|
||||
|
||||
for line in output.lines() {
|
||||
let split = line.split_ascii_whitespace().collect::<Vec<_>>();
|
||||
let iface = GatewayId::from(InternedString::from(*split.get(1).ok_or_else(&err_fn)?));
|
||||
let subnet: IpNet = split.get(3).ok_or_else(&err_fn)?.parse()?;
|
||||
let info = res.entry(iface).or_default();
|
||||
let ip_info = info.ip_info.get_or_insert_default();
|
||||
ip_info.scope_id = split
|
||||
.get(0)
|
||||
.ok_or_else(&err_fn)?
|
||||
.strip_suffix(":")
|
||||
.ok_or_else(&err_fn)?
|
||||
.parse()?;
|
||||
ip_info.subnets.insert(subnet);
|
||||
}
|
||||
|
||||
for (id, info) in OrdMapIterMut::from(&mut res) {
|
||||
let ip_info = info.ip_info.get_or_insert_default();
|
||||
ip_info.device_type = probe_iface_type(id.as_str()).await;
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn ipv6_is_link_local(addr: Ipv6Addr) -> bool {
|
||||
(addr.segments()[0] & 0xffc0) == 0xfe80
|
||||
}
|
||||
@@ -75,6 +122,22 @@ pub async fn get_iface_ipv6_addr(iface: &str) -> Result<Option<(Ipv6Addr, Ipv6Ne
|
||||
.transpose()?)
|
||||
}
|
||||
|
||||
pub async fn probe_iface_type(iface: &str) -> Option<NetworkInterfaceType> {
|
||||
match tokio::fs::read_to_string(Path::new("/sys/class/net").join(iface).join("uevent"))
|
||||
.await
|
||||
.ok()?
|
||||
.lines()
|
||||
.find_map(|l| l.strip_prefix("DEVTYPE="))
|
||||
{
|
||||
Some("wlan") => Some(NetworkInterfaceType::Wireless),
|
||||
Some("bridge") => Some(NetworkInterfaceType::Bridge),
|
||||
Some("wireguard") => Some(NetworkInterfaceType::Wireguard),
|
||||
None if iface_is_physical(iface).await => Some(NetworkInterfaceType::Ethernet),
|
||||
None if iface_is_loopback(iface).await => Some(NetworkInterfaceType::Loopback),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn iface_is_physical(iface: &str) -> bool {
|
||||
tokio::fs::metadata(Path::new("/sys/class/net").join(iface).join("device"))
|
||||
.await
|
||||
@@ -87,6 +150,19 @@ pub async fn iface_is_wireless(iface: &str) -> bool {
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn iface_is_bridge(iface: &str) -> bool {
|
||||
tokio::fs::metadata(Path::new("/sys/class/net").join(iface).join("bridge"))
|
||||
.await
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn iface_is_loopback(iface: &str) -> bool {
|
||||
tokio::fs::read_to_string(Path::new("/sys/class/net").join(iface).join("type"))
|
||||
.await
|
||||
.ok()
|
||||
.map_or(false, |x| x.trim() == "772")
|
||||
}
|
||||
|
||||
pub fn list_interfaces() -> BoxStream<'static, Result<String, Error>> {
|
||||
try_stream! {
|
||||
let mut ifaces = tokio::fs::read_dir("/sys/class/net").await?;
|
||||
|
||||
Reference in New Issue
Block a user