Update active networks without needing to poll every 5 seconds
This commit is contained in:
parent
9b60cc758b
commit
fc8e6e4d4d
1 changed files with 85 additions and 60 deletions
|
|
@ -1,10 +1,15 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
use cosmic_dbus_networkmanager::{
|
use cosmic_dbus_networkmanager::{
|
||||||
|
active_connection::ActiveConnection,
|
||||||
device::SpecificDevice,
|
device::SpecificDevice,
|
||||||
interface::enums::{ApFlags, ApSecurityFlags},
|
interface::{
|
||||||
|
active_connection::ActiveConnectionProxy,
|
||||||
|
enums::{ApFlags, ApSecurityFlags},
|
||||||
|
},
|
||||||
nm::NetworkManager,
|
nm::NetworkManager,
|
||||||
};
|
};
|
||||||
|
use futures_util::StreamExt;
|
||||||
use gtk4::{
|
use gtk4::{
|
||||||
glib::{self, clone, source::PRIORITY_DEFAULT, MainContext, Sender},
|
glib::{self, clone, source::PRIORITY_DEFAULT, MainContext, Sender},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
|
@ -127,72 +132,92 @@ fn render_vpn(name: String, ip_addresses: Vec<IpAddr>) -> gtk4::Box {
|
||||||
async fn handle_devices(tx: Sender<Vec<ActiveConnectionInfo>>) -> zbus::Result<()> {
|
async fn handle_devices(tx: Sender<Vec<ActiveConnectionInfo>>) -> zbus::Result<()> {
|
||||||
let conn = Connection::system().await?;
|
let conn = Connection::system().await?;
|
||||||
let network_manager = NetworkManager::new(&conn).await?;
|
let network_manager = NetworkManager::new(&conn).await?;
|
||||||
loop {
|
handle_active_connections(tx.clone(), network_manager.active_connections().await?).await?;
|
||||||
let active_connections = network_manager.active_connections().await?;
|
let mut active_connections_changed = network_manager.receive_active_connections_changed().await;
|
||||||
let mut info = Vec::<ActiveConnectionInfo>::with_capacity(active_connections.len());
|
while let Some(active_connection_objects) = active_connections_changed.next().await {
|
||||||
for connection in active_connections {
|
let active_connection_objects = active_connection_objects.get().await?;
|
||||||
if connection.vpn().await? {
|
let mut active_connections = Vec::with_capacity(active_connection_objects.len());
|
||||||
let mut ip_addresses = Vec::new();
|
for object in active_connection_objects {
|
||||||
for address_data in connection.ip4_config().await?.address_data().await? {
|
active_connections.push(
|
||||||
ip_addresses.push(IpAddr::V4(address_data.address));
|
ActiveConnectionProxy::builder(&conn)
|
||||||
}
|
.path(object)?
|
||||||
for address_data in connection.ip6_config().await?.address_data().await? {
|
.build()
|
||||||
ip_addresses.push(IpAddr::V6(address_data.address));
|
.await
|
||||||
}
|
.map(ActiveConnection::from)?,
|
||||||
info.push(ActiveConnectionInfo::Vpn {
|
);
|
||||||
name: connection.id().await?,
|
}
|
||||||
ip_addresses,
|
handle_active_connections(tx.clone(), active_connections).await?;
|
||||||
});
|
}
|
||||||
continue;
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_active_connections(
|
||||||
|
tx: Sender<Vec<ActiveConnectionInfo>>,
|
||||||
|
active_connections: Vec<ActiveConnection<'_>>,
|
||||||
|
) -> zbus::Result<()> {
|
||||||
|
let mut info = Vec::<ActiveConnectionInfo>::with_capacity(active_connections.len());
|
||||||
|
for connection in active_connections {
|
||||||
|
if connection.vpn().await? {
|
||||||
|
let mut ip_addresses = Vec::new();
|
||||||
|
for address_data in connection.ip4_config().await?.address_data().await? {
|
||||||
|
ip_addresses.push(IpAddr::V4(address_data.address));
|
||||||
}
|
}
|
||||||
for device in connection.devices().await? {
|
for address_data in connection.ip6_config().await?.address_data().await? {
|
||||||
match device.downcast_to_device().await? {
|
ip_addresses.push(IpAddr::V6(address_data.address));
|
||||||
Some(SpecificDevice::Wired(wired_device)) => {
|
}
|
||||||
let mut ip_addresses = Vec::new();
|
info.push(ActiveConnectionInfo::Vpn {
|
||||||
for address_data in device.ip4_config().await?.address_data().await? {
|
name: connection.id().await?,
|
||||||
ip_addresses.push(IpAddr::V4(address_data.address));
|
ip_addresses,
|
||||||
}
|
});
|
||||||
for address_data in device.ip6_config().await?.address_data().await? {
|
continue;
|
||||||
ip_addresses.push(IpAddr::V6(address_data.address));
|
}
|
||||||
}
|
for device in connection.devices().await? {
|
||||||
info.push(ActiveConnectionInfo::Wired {
|
match device.downcast_to_device().await? {
|
||||||
name: connection.id().await?,
|
Some(SpecificDevice::Wired(wired_device)) => {
|
||||||
hw_address: wired_device.hw_address().await?,
|
let mut ip_addresses = Vec::new();
|
||||||
speed: wired_device.speed().await?,
|
for address_data in device.ip4_config().await?.address_data().await? {
|
||||||
ip_addresses,
|
ip_addresses.push(IpAddr::V4(address_data.address));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Some(SpecificDevice::Wireless(wireless_device)) => {
|
for address_data in device.ip6_config().await?.address_data().await? {
|
||||||
let access_point = wireless_device.active_access_point().await?;
|
ip_addresses.push(IpAddr::V6(address_data.address));
|
||||||
info.push(ActiveConnectionInfo::WiFi {
|
|
||||||
name: String::from_utf8_lossy(&access_point.ssid().await?).into_owned(),
|
|
||||||
hw_address: wireless_device.hw_address().await?,
|
|
||||||
flags: access_point.flags().await?,
|
|
||||||
rsn_flags: access_point.rsn_flags().await?,
|
|
||||||
wpa_flags: access_point.wpa_flags().await?,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Some(SpecificDevice::WireGuard(_)) => {
|
info.push(ActiveConnectionInfo::Wired {
|
||||||
let mut ip_addresses = Vec::new();
|
name: connection.id().await?,
|
||||||
for address_data in connection.ip4_config().await?.address_data().await? {
|
hw_address: wired_device.hw_address().await?,
|
||||||
ip_addresses.push(IpAddr::V4(address_data.address));
|
speed: wired_device.speed().await?,
|
||||||
}
|
ip_addresses,
|
||||||
for address_data in connection.ip6_config().await?.address_data().await? {
|
});
|
||||||
ip_addresses.push(IpAddr::V6(address_data.address));
|
|
||||||
}
|
|
||||||
info.push(ActiveConnectionInfo::Vpn {
|
|
||||||
name: connection.id().await?,
|
|
||||||
ip_addresses,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
Some(SpecificDevice::Wireless(wireless_device)) => {
|
||||||
|
let access_point = wireless_device.active_access_point().await?;
|
||||||
|
info.push(ActiveConnectionInfo::WiFi {
|
||||||
|
name: String::from_utf8_lossy(&access_point.ssid().await?).into_owned(),
|
||||||
|
hw_address: wireless_device.hw_address().await?,
|
||||||
|
flags: access_point.flags().await?,
|
||||||
|
rsn_flags: access_point.rsn_flags().await?,
|
||||||
|
wpa_flags: access_point.wpa_flags().await?,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Some(SpecificDevice::WireGuard(_)) => {
|
||||||
|
let mut ip_addresses = Vec::new();
|
||||||
|
for address_data in connection.ip4_config().await?.address_data().await? {
|
||||||
|
ip_addresses.push(IpAddr::V4(address_data.address));
|
||||||
|
}
|
||||||
|
for address_data in connection.ip6_config().await?.address_data().await? {
|
||||||
|
ip_addresses.push(IpAddr::V6(address_data.address));
|
||||||
|
}
|
||||||
|
info.push(ActiveConnectionInfo::Vpn {
|
||||||
|
name: connection.id().await?,
|
||||||
|
ip_addresses,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx.send(info)
|
|
||||||
.expect("failed to send active connections back to main thread");
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
|
||||||
}
|
}
|
||||||
|
tx.send(info)
|
||||||
|
.expect("failed to send active connections back to main thread");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ActiveConnectionInfo {
|
enum ActiveConnectionInfo {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue