From 4503eed6ce400ec1cde8f5d755e58861a7563277 Mon Sep 17 00:00:00 2001 From: Techmore Date: Thu, 29 Oct 2026 10:24:07 -0400 Subject: [PATCH] Tailscale app: honest VPN status, timers, conflict warning, Remote Into a Mac - A VPN is Connected only when its tunnel interface is up (found by the VPN's own address), else Connecting, Dropped or Failed with a reason from NetworkManager/pppd/IPsec logs, plus Reconnect. Shows which interface really carries internet traffic (ip route get). - Session timer and bytes down/up for each connected VPN and Tailscale, kept across app restarts, reset on reconnect. - Banner when another tunnel (WiFiman's utun etc.) is up next to a VPN or knocked it off. - Remote Into a Mac: the BFS Mac mini and online Macs with Screen Sharing (Remmina vnc://) and Copy ssh; Turn On Tailscale when it is off. Co-Authored-By: Claude Opus 5.5 --- rust/mseries-tailscale/README.md | 14 + .../docs/vpn-conflict-light.png | Bin 0 -> 91211 bytes .../docs/vpn-status-light.png | Bin 0 -> 84843 bytes rust/mseries-tailscale/fixtures/active.txt | 1 + rust/mseries-tailscale/fixtures/ip4.txt | 1 + rust/mseries-tailscale/fixtures/net.json | 45 ++ rust/mseries-tailscale/fixtures/nmcli.txt | 1 + .../fixtures/split-tunnel.txt | 1 - .../fixtures/unsaved-passwords.txt | 1 - rust/mseries-tailscale/src/cli.rs | 13 + rust/mseries-tailscale/src/lib.rs | 1 + rust/mseries-tailscale/src/model.rs | 63 ++ rust/mseries-tailscale/src/net.rs | 183 +++++ rust/mseries-tailscale/src/ui/window.rs | 700 +++++++++++++++--- 14 files changed, 937 insertions(+), 87 deletions(-) create mode 100644 rust/mseries-tailscale/docs/vpn-conflict-light.png create mode 100644 rust/mseries-tailscale/docs/vpn-status-light.png create mode 100644 rust/mseries-tailscale/fixtures/active.txt create mode 100644 rust/mseries-tailscale/fixtures/ip4.txt create mode 100644 rust/mseries-tailscale/fixtures/net.json create mode 100644 rust/mseries-tailscale/src/net.rs diff --git a/rust/mseries-tailscale/README.md b/rust/mseries-tailscale/README.md index 542242c..18cdbae 100644 --- a/rust/mseries-tailscale/README.md +++ b/rust/mseries-tailscale/README.md @@ -35,6 +35,20 @@ A native Pantheon window for Tailscale. It replaces the old launcher that opened - **Devices:** every device on the tailnet, online first, with IP, OS and when it was last seen. Search with Ctrl+F. Click a row or the copy button to copy its IP; the terminal button copies `ssh ` (the MagicDNS name, e.g. `ssh sdolbec-ser8`). +- **Honest VPN status:** a VPN counts as Connected only when its tunnel interface (ppp0, utun, …) is up; the + app finds it by the VPN's own address instead of trusting NetworkManager's "activated". Otherwise it says + Connecting…, "Dropped: on, but not carrying any traffic", or "Failed: " (from NetworkManager, pppd and + IPsec logs), with Reconnect. "Internet traffic now goes through …" names the interface the kernel really uses + (`ip route get`, policy routing included). +- **Timer and traffic:** each connected VPN, and Tailscale, shows how long it has been up (kept across app + restarts, reset on reconnect) and bytes down/up. +- **Two VPNs at once:** a banner when another tunnel (WiFiman's `utun`, any WireGuard/tun/PPP device) is up next + to a VPN, or knocked it off. +- **Remote Into a Mac:** the tailnet's Mac mini at BFS plus any online Mac, with Screen Sharing (Remmina, + `vnc://`) and Copy ssh. Offers Turn On Tailscale when it is off, and the Remmina install command + when Remmina is missing. + + ![Status](docs/vpn-status-light.png) ![Conflict](docs/vpn-conflict-light.png) - **Settings:** Tailscale DNS, subnet routes, incoming connections (shields up), and the Tailscale SSH server, each a `tailscale set` flag. - **Logged out:** "Log In…" starts `tailscale login` and opens the sign-in page. diff --git a/rust/mseries-tailscale/docs/vpn-conflict-light.png b/rust/mseries-tailscale/docs/vpn-conflict-light.png new file mode 100644 index 0000000000000000000000000000000000000000..d65367a500869415711211d4d1e38e3ceab16cf0 GIT binary patch literal 91211 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%0DRgP=DDR4BB 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

!TjAm1e*6kF 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�+NkB}VESuioyJC?nA%Vs z7}t}I$8D(l9Uqk0zm5J8uK9L0Lot-Nr|S=eB7SY=&}$ zc7A!3WAh{5k!Q(KWy~Te4yY^1sr>`K zU-tU)OQqW^FTkag7~;ii@td3^O6b zV*6xuu$*bzRryhB%hRV$J%BgpzA25go~)CSuB?HkQ&!Y-5@o8%GDZfwW?p@zl8}Yp zj09v|1#>7F&uN~7wv-<#bqYfYVE`%^S~Ihg>m)J`!UkqGzvjO2dl-QE18xf20|Wbl zv;T=BowlltRkPsc)xYNfDYBW|n0X{~HQG5YUxfK4o($?CC0OhPiQ*xpoWutYA6^2m zWb7^R4zfsmQCHsyNV~Q$OlCuO4{BaU4N-B%!Q&SO`PV}he?VB{!QTqD#y$>EK4*YJ zM%lhqsLJG&0%Yyozh7DWuK4U@`{_X&!+T~bg(x*u=$SLO!)wWik8+;WD`;Iz=g*%4 zv5Z9~(xZ(VXH55!f0hRK!sIt@k28Bt9}}xLtxrIj6Ajtz z+bb(OS?$Ypj$iHUe5S?5)YSB#;@YT@)g>uLgp(_8lD#_*2XKr~TU)n0 zHK;IW$?x>dWy?n^ol07g>&Mx?#0$t|gqhhf zjB+T6+p8!UuM$Xz0P%oyBFD@;t)lqYtP^)+&J3=tmb{rtP|kC2ot=4QH3k~@+lg)3 zSf4pR#dUwz934?1GWCA~0S>-jbpsZDv#zFl zpGgfw$vz4yI$rxIo(BUwW%TpJX@;4tIm9bg`sBKI2O0y1Rb{OgIc6x^`qPXJNoX@NCY`R31}?Q(-)5 zqPM3FMA1@|zYxs9<&y)7sct_p-`y+5{P0gm&6E$qdEg>#aKB3lY}1Y^HE5>U7r(Vq zpZ)n{xt_zF(?d2w#Jbbx-|AQYPTC%6LEJ8;o)c%zys^nL&v8E_!}a7dU3D?&2pa~+ zJF##|jd%{a_e`8MpUY3YB9<@H4U{d69QJT14y5Qu+jAY)SttK=!Z>ZxtmlI*r4jGF zX>Hu1KfO{i)GlO>o0~LgPaUn_&&z%>uwPKs3_D|ep)z=g*I4)Jd4c<>vvkH@_C_>FA#H+n!c6);YC~&+FyM{25&-I9)8|@=0M?tfE+~4^MSseLEHXh)rArs-_R0RzdmjZ_kAKhdvo=k8^ACFRz? z2Kj@^d_I4jKi~)Xv!297QCD2?4!XAc_SLSN7@k%z4rSiJV7|yf{4(%7CGM(lKoWL8 zBB~8xfy?Sw6%{!WN*K1|B~Gr1>0k5u_IMB<$mQ#rtr+Y>$Hd~CfsuJlEhPy)a>6H^ zJNGlHL#}~d+WU!sj07qasn(8hck3Sv%Ot!!n0FqtFvduetgHf3Yqt)r1?V>jFHP2a zQu1H`?+1fZ6#LDpW3tx}{SUtSX|ijRQhbqyZs0y3fb^Sl6)L$3tLHr z=kxnLuy%;M`@tl1iC*)OdS#Wq-oe%rDw`d~)D72vwYlu|QP<*dX1dby^X@lp+^{!Z z^JLhF5zDyt)Lv05@SJ~6y%cfC? z%ldwHx!ul+dMHXi`uq2$%)!0AtM$A-I-Gj4V>ZnI41ueid0^-0>WYZ8e-;4VCK?o?A$uK3Ptht1Cl&9i$l;y~X zt)Y<6r0{{M2zP^RIiC=1Vk(ptbCQ@0jXgXP*BRN{?$f#jSk}Bqzz@prYGtePvP0M2 zkUB(11vV={mTVf1C<~TpqNQbJquuIg?qZBFAPwrelP#eih=uG%d#F*{T}Ay6ARINl z(d!58n+OmLg)`Ncohy`W^hjI2H#?-!bmtz)I4?E(=1ud4!nvNL54lSjZhQ#p87|qA zMmsxj6*Ms6dVxxE1FxW;e zTvm_gcT48>|H!A5b?;D7!mo~2aCmkL?_>3~Yu84jR)U=@cpkvA=H1Ik*Y?2T!o;%L zXr_X&Cn`06|4e+g@+DxA$Be10h@{$3NH+vw05#3ut1X}M zunL1uhO-J%_LIh#`0(*R_cu(P@kW96<4xAOE$wwW^xc;Wn^6P$IbSaHYNCBf9m(*? z-l4(Hp6?;&JLZ_|OPHswnJ|Oqidc?kshU`#)`!j9UtUrXogFvD<(BGmwzMlYb(~bEa2!f z9^D30LYb#UWA@RD9KTbMkxOZZOYm;vj0tqzrlUmLVDO}>9!DrxCFeAx!&BBl%qpUo@PMl#CN>+b&lM)92|8el5n( z%THwttIWQ{L$0J|G@e%R_6wElKOCYgq8wd177+GMrS->Ai^25qt~b0~H`zb)Ug5lU z>?S8q$#*F!r|);Mo^>KdZBY%ke{FH1itkn22iLypbeQXiq0sl6OLF>~YUW#(*9QeA zRpc1mUw#A28EiGSw$|+_4fb$|F$%cZKuH;NV?3+4dJP@>sw#I{sSork)7mC6>gAcO z4mRU{&%Y3J{Ox&XETH1eODR2~HaQMA%rtqfSL*gTyKx7TVw?}A)<7vvo#uZcDU1b1 z(AEKy@|MAmD_Q=_rG|upH`N5pVDZWo((6)0CITa|T*@<7ee94c+a=F97VC30bU}b6RemJ*V4yy{Gt<{4yNnD6%WXKE=O@5EG2;{@8 zw)UHHu=T5ug)mz-A3C5F*uu@=WWxCPF^-U3V98zqU{Kciw9*@=S=psbOM9wPPRYA+ z_0|EPddPn~@}K{hmkD)a0XdnYF+fM>5M>K|v=WV47}~i@)u?C0)4;|(e?9~NnfMUp z?pM3>lnRpMw|loT9UTvCl+x^3RqT7zN_#f?LsOj3>C5Byp`aWk3RDOb!XVx9?&UQ4 zE7+IIalw*?R19|^wBUsn-RzbSo>5dyFnIvh(wA!DLQ4q{!9{U311yIzf0f>eokt-{ zo^C?GDro7kW5;xx6uM6SAt3`~SOd%^>!Ts=*4~J_j04w3LSf!3Gt^dM5d+Lj^u-`_ zy0`bcO`k;#JwqMC#v#1Io|bWfH7QoBcbgwMg?lQ>hjwj#AA);u%d z%PB%5u1@-%J`KwuD3Ihrd{8GrKLz@N#dvG@0hgZ}j?Xn%i0HGI(U&Y3=E&MGiSs=0)F z|Kz>BCJ}=PYdn+S(LqJOyS#lxZF&7IX0!Xb3lcM+8$n?qY|4ZQLO6lUr0LF4&^IyV z;9hdgv`NKH_m1T3*cH5;=07(1QJ1EaYb$&|?qTGyLmM8Jog@@R*s(|hME^`b8qjz# z{;r+lX)pVuf2R@GWa+Q_789Oi@lFFjqlS^)$;3LYG^0)z@EzEmfJv4$4@zpr+)cLS z$(_a;FVY6*&*c4u%cEwi_U~Vp*G=>A<>jMC(b!UbLq()EQHIx`fN+OWEQ+c95v^f%cQ`a>*E-oT0j9tSM!PK$ny!p*68E=;E5SL0^`Sf>y>S`Rk z{&iI<+9_TWod;@Hje|3`_m+8;BIJ%eFG-;brdM~iry67t!ALrF3d_H7sBM{}PI$h9 z*kB=$A5-P7qlDfkCdPfC{{fkpYZ=oi6ct&05ng`I68;5+RUh3p?NJm#v6pXn%|ELg z|4}3bqG}(rA8NvFIZ9dQq<9LU~!RZFfJ^JUYti-C>GYy?={-iW%-7Yn*jXf x*4m9!pJ2G}>e7MO>*Ab-pI||L;ltMUQ~h?VJY-+>Lcu>XrkMN?J8ALu{{WwLEW`i+ literal 0 HcmV?d00001 diff --git a/rust/mseries-tailscale/fixtures/active.txt b/rust/mseries-tailscale/fixtures/active.txt new file mode 100644 index 0000000..bc296fb --- /dev/null +++ b/rust/mseries-tailscale/fixtures/active.txt @@ -0,0 +1 @@ +4a1d6d4d-c5e4:activated:enx605b:vpn diff --git a/rust/mseries-tailscale/fixtures/ip4.txt b/rust/mseries-tailscale/fixtures/ip4.txt new file mode 100644 index 0000000..0e50a79 --- /dev/null +++ b/rust/mseries-tailscale/fixtures/ip4.txt @@ -0,0 +1 @@ +4a1d6d4d-c5e4 192.168.200.20/32 diff --git a/rust/mseries-tailscale/fixtures/net.json b/rust/mseries-tailscale/fixtures/net.json new file mode 100644 index 0000000..620f4d8 --- /dev/null +++ b/rust/mseries-tailscale/fixtures/net.json @@ -0,0 +1,45 @@ +{ + "internet_iface": "ppp0", + "ifaces": [ + { + "name": "lo", + "index": 1, + "up": true, + "rx_bytes": 0, + "tx_bytes": 0, + "ipv4": [ + "127.0.0.1" + ] + }, + { + "name": "wld0", + "index": 3, + "up": true, + "rx_bytes": 0, + "tx_bytes": 0, + "ipv4": [ + "10.20.0.120" + ] + }, + { + "name": "tailscale0", + "index": 9, + "up": true, + "rx_bytes": 0, + "tx_bytes": 0, + "ipv4": [ + "100.115.140.33" + ] + }, + { + "name": "ppp0", + "index": 41, + "up": true, + "rx_bytes": 48300000, + "tx_bytes": 6100000, + "ipv4": [ + "192.168.200.20" + ] + } + ] +} \ No newline at end of file diff --git a/rust/mseries-tailscale/fixtures/nmcli.txt b/rust/mseries-tailscale/fixtures/nmcli.txt index 97adeb4..dac5382 100644 --- a/rust/mseries-tailscale/fixtures/nmcli.txt +++ b/rust/mseries-tailscale/fixtures/nmcli.txt @@ -1,2 +1,3 @@ Home Wi-Fi:11111111-aaaa:802-11-wireless:yes BFS:4a1d6d4d-c5e4:vpn:yes +utun:2e861348-utun:wireguard:no diff --git a/rust/mseries-tailscale/fixtures/split-tunnel.txt b/rust/mseries-tailscale/fixtures/split-tunnel.txt index c051887..e69de29 100644 --- a/rust/mseries-tailscale/fixtures/split-tunnel.txt +++ b/rust/mseries-tailscale/fixtures/split-tunnel.txt @@ -1 +0,0 @@ -4a1d6d4d-c5e4 diff --git a/rust/mseries-tailscale/fixtures/unsaved-passwords.txt b/rust/mseries-tailscale/fixtures/unsaved-passwords.txt index c051887..e69de29 100644 --- a/rust/mseries-tailscale/fixtures/unsaved-passwords.txt +++ b/rust/mseries-tailscale/fixtures/unsaved-passwords.txt @@ -1 +0,0 @@ -4a1d6d4d-c5e4 diff --git a/rust/mseries-tailscale/src/cli.rs b/rust/mseries-tailscale/src/cli.rs index 3c2f9ac..3c286fb 100644 --- a/rust/mseries-tailscale/src/cli.rs +++ b/rust/mseries-tailscale/src/cli.rs @@ -96,8 +96,21 @@ pub async fn run_program(argv: &[&str], limit_secs: u64) -> Result<(bool, String // Fixture VPNs: `nmcli.txt` is the connection list; every VPN sends all traffic unless listed in // `split-tunnel.txt`; changes are refused like Tailscale's. let list = std::fs::read_to_string(dir.join("nmcli.txt")).unwrap_or_default(); + let read = |f: &str| std::fs::read_to_string(dir.join(f)).unwrap_or_default(); return match argv.get(1..4) { + Some(["-t", "-f", fields]) if fields.starts_with("UUID,STATE") => { + Ok((true, read("active.txt"), String::new())) + } Some(["-t", "-f", _]) => Ok((true, list, String::new())), + // `ip4.txt` lines: "uuid address". + Some(["-g", "IP4.ADDRESS", _]) => { + let uuid = argv.last().copied().unwrap_or_default(); + let addr = read("ip4.txt") + .lines() + .find_map(|l| l.strip_prefix(uuid).map(|a| a.trim().to_string())) + .unwrap_or_default(); + Ok((true, addr, String::new())) + } Some(["-g", "ipv4.never-default", _]) => { let split = std::fs::read_to_string(dir.join("split-tunnel.txt")).unwrap_or_default(); let uuid = argv.last().copied().unwrap_or_default(); diff --git a/rust/mseries-tailscale/src/lib.rs b/rust/mseries-tailscale/src/lib.rs index de38713..36f9796 100644 --- a/rust/mseries-tailscale/src/lib.rs +++ b/rust/mseries-tailscale/src/lib.rs @@ -3,6 +3,7 @@ pub mod cli; pub mod model; +pub mod net; pub mod nm; pub mod strings; pub mod ui; diff --git a/rust/mseries-tailscale/src/model.rs b/rust/mseries-tailscale/src/model.rs index 5f3cedb..d3dc166 100644 --- a/rust/mseries-tailscale/src/model.rs +++ b/rust/mseries-tailscale/src/model.rs @@ -319,6 +319,55 @@ pub struct Vpn { pub all_traffic: bool, /// False when a secret is "always ask" (flag 2) and so is never stored. pub secrets_saved: bool, + /// "vpn" (NetworkManager VPN plugin) or "wireguard". + pub kind: String, +} + +impl Vpn { + /// Only plugin VPNs get the "Send all traffic" switch; WireGuard routes by its allowed IPs. + pub fn kind_has_routing(&self) -> bool { + self.kind == "vpn" + } +} + +/// A friendlier name for connections other apps create. +pub fn display_name(name: &str) -> String { + match name { + "utun" => "WiFiman (utun)".into(), + other => other.into(), + } +} + +/// `nmcli -t -f UUID,STATE,DEVICE,TYPE connection show --active` → uuid → (state, device, type). +pub fn parse_active(text: &str) -> std::collections::HashMap { + text.lines() + .map(nmcli_fields) + .filter(|f| f.len() >= 4) + .map(|f| (f[0].clone(), (f[1].clone(), f[2].clone(), f[3].clone()))) + .collect() +} + +/// Why a VPN dropped, from recent NetworkManager / pppd / IPsec log lines, in plain words. +/// `others` are tunnels from other apps that are up now. +pub fn classify_vpn_failure(log: &str, others: &[String]) -> String { + if let Some(other) = others.first() { + return format!("{other} took over the connection"); + } + let l = log.to_lowercase(); + let has = |words: &[&str]| words.iter().any(|w| l.contains(w)); + if has(&["authentication failed", "auth failed"]) { + "the server rejected the username or password".into() + } else if has(&["no agents were available", "secrets were required"]) { + "passwords aren't saved".into() + } else if has(&["modem hangup", "hung up", "lcp terminated", "peer closed"]) { + "the server hung up".into() + } else if has(&["timed out", "timeout"]) { + "the server didn't answer".into() + } else if has(&["ipsec"]) && has(&["shut", "terminat", "deleting ike", "closing"]) { + "the IPsec tunnel closed".into() + } else { + "the connection stopped".into() + } } /// Reads the `*-flags` entries from `nmcli -g vpn.data` (flags only; secrets are not in vpn.data). @@ -365,6 +414,7 @@ pub fn parse_vpn_list(text: &str) -> Vec { active: f[3] == "yes", all_traffic: false, secrets_saved: true, + kind: f[2].clone(), }) .collect() } @@ -397,6 +447,19 @@ mod vpn_tests { let d = parse_vpn_data("gateway = vpn.example.com, ipsec-enabled = yes, password-flags = 0, user = a@b.org\n"); assert_eq!(d.get("gateway").map(String::as_str), Some("vpn.example.com")); assert_eq!(d.get("user").map(String::as_str), Some("a@b.org")); + let a = parse_active("4a1d:activated:enx60:vpn\nutun-1:activated:utun:wireguard\n"); + assert_eq!(a.get("4a1d").map(|t| t.0.as_str()), Some("activated")); + assert_eq!(a.get("utun-1").map(|t| t.1.as_str()), Some("utun")); + assert_eq!(display_name("utun"), "WiFiman (utun)"); + assert_eq!( + classify_vpn_failure("", &["WiFiman (Ubiquiti Teleport)".into()]), + "WiFiman (Ubiquiti Teleport) took over the connection" + ); + assert_eq!(classify_vpn_failure("pppd: Modem hangup", &[]), "the server hung up"); + assert_eq!( + classify_vpn_failure("PAP authentication failed", &[]), + "the server rejected the username or password" + ); assert!(needs_secrets("Error: Connection activation failed: Secrets were required, but not provided")); } } diff --git a/rust/mseries-tailscale/src/net.rs b/rust/mseries-tailscale/src/net.rs new file mode 100644 index 0000000..19ff57b --- /dev/null +++ b/rust/mseries-tailscale/src/net.rs @@ -0,0 +1,183 @@ +//! What the kernel says about tunnels: which interface carries internet traffic, which interface owns an +//! address, and per-interface counters. NetworkManager's "activated" is not trusted on its own. +//! +//! `MSERIES_TAILSCALE_FIXTURES=DIR` reads `net.json` (a serialized `Snapshot`) instead. + +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct Iface { + pub name: String, + pub index: u32, + pub up: bool, + pub rx_bytes: u64, + pub tx_bytes: u64, + pub ipv4: Vec, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct Snapshot { + /// Interface the kernel would use to reach the internet (`ip route get 1.1.1.1`, policy routing included). + pub internet_iface: Option, + pub ifaces: Vec, +} + +impl Snapshot { + pub fn iface(&self, name: &str) -> Option<&Iface> { + self.ifaces.iter().find(|i| i.name == name) + } + + /// The interface that holds `address` (a VPN's own IP, as NetworkManager reports it). + pub fn iface_with_address(&self, address: &str) -> Option<&Iface> { + let address = address.split('/').next().unwrap_or(address); + self.ifaces.iter().find(|i| i.ipv4.iter().any(|a| a == address)) + } + + /// Tunnel-like interfaces (tun, WireGuard, PPP) other than Tailscale's. + pub fn tunnels(&self) -> impl Iterator { + self.ifaces.iter().filter(|i| { + let n = i.name.as_str(); + n != "tailscale0" + && (n.starts_with("ppp") || n.starts_with("tun") || n.starts_with("utun") || n.starts_with("wg")) + }) + } +} + +fn read_u64(path: &str) -> u64 { + std::fs::read_to_string(path).ok().and_then(|s| s.trim().parse().ok()).unwrap_or(0) +} + +#[derive(Deserialize)] +struct IpAddr { + ifname: String, + #[serde(default)] + addr_info: Vec, +} + +#[derive(Deserialize)] +struct IpAddrInfo { + #[serde(default)] + local: String, +} + +#[derive(Deserialize)] +struct IpRoute { + #[serde(default)] + dev: String, +} + +/// Reads the snapshot. Cheap: two `ip` calls and a few small sysfs files. +pub async fn probe() -> Snapshot { + if let Some(dir) = std::env::var_os("MSERIES_TAILSCALE_FIXTURES") { + let path = std::path::Path::new(&dir).join("net.json"); + return std::fs::read_to_string(path).ok().and_then(|t| serde_json::from_str(&t).ok()).unwrap_or_default(); + } + let route = crate::cli::run_program(&["ip", "-j", "route", "get", "1.1.1.1"], 5).await; + let internet_iface = route + .ok() + .and_then(|(ok, out, _)| ok.then_some(out)) + .and_then(|out| serde_json::from_str::>(&out).ok()) + .and_then(|r| r.into_iter().next()) + .map(|r| r.dev) + .filter(|d| !d.is_empty()); + let mut addrs: HashMap> = HashMap::new(); + if let Ok((true, out, _)) = crate::cli::run_program(&["ip", "-j", "-4", "addr"], 5).await { + for entry in serde_json::from_str::>(&out).unwrap_or_default() { + addrs.entry(entry.ifname).or_default().extend(entry.addr_info.into_iter().map(|a| a.local)); + } + } + let mut ifaces = Vec::new(); + if let Ok(dir) = std::fs::read_dir("/sys/class/net") { + for entry in dir.flatten() { + let name = entry.file_name().to_string_lossy().to_string(); + let base = format!("/sys/class/net/{name}"); + let oper = std::fs::read_to_string(format!("{base}/operstate")).unwrap_or_default(); + ifaces.push(Iface { + index: read_u64(&format!("{base}/ifindex")) as u32, + up: oper.trim() != "down", + rx_bytes: read_u64(&format!("{base}/statistics/rx_bytes")), + tx_bytes: read_u64(&format!("{base}/statistics/tx_bytes")), + ipv4: addrs.remove(&name).unwrap_or_default(), + name, + }); + } + } + Snapshot { internet_iface, ifaces } +} + +/// Counters for one interface, read fresh (for the one-second timer). +pub fn counters(name: &str) -> Option<(u64, u64)> { + if std::env::var_os("MSERIES_TAILSCALE_FIXTURES").is_some() { + return Some((48_300_000, 6_100_000)); + } + let base = format!("/sys/class/net/{name}/statistics"); + std::path::Path::new(&base) + .exists() + .then(|| (read_u64(&format!("{base}/rx_bytes")), read_u64(&format!("{base}/tx_bytes")))) +} + +/// "1.2 GB", "340 KB". +pub fn bytes_text(n: u64) -> String { + const UNITS: [&str; 5] = ["B", "KB", "MB", "GB", "TB"]; + let mut v = n as f64; + let mut u = 0; + while v >= 1000.0 && u < UNITS.len() - 1 { + v /= 1000.0; + u += 1; + } + if u == 0 { + format!("{n} B") + } else if v < 10.0 { + format!("{v:.1} {}", UNITS[u]) + } else { + format!("{v:.0} {}", UNITS[u]) + } +} + +/// "0:04:09", "12:30:00". +pub fn duration_text(secs: i64) -> String { + let s = secs.max(0); + format!("{}:{:02}:{:02}", s / 3600, (s / 60) % 60, s % 60) +} + +/// A friendly name for a tunnel interface that is not one of the listed VPNs. +pub fn tunnel_owner(iface: &str) -> String { + match iface { + "utun" => "WiFiman (Ubiquiti Teleport)".into(), + n if n.starts_with("ppp") => format!("A PPP/L2TP VPN ({n})"), + n if n.starts_with("wg") => format!("A WireGuard VPN ({n})"), + n => format!("Another VPN ({n})"), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn texts() { + assert_eq!(bytes_text(999), "999 B"); + assert_eq!(bytes_text(4_307_842), "4.3 MB"); + assert_eq!(bytes_text(48_300_000), "48 MB"); + assert_eq!(duration_text(249), "0:04:09"); + assert_eq!(duration_text(45_000), "12:30:00"); + assert_eq!(tunnel_owner("utun"), "WiFiman (Ubiquiti Teleport)"); + } + + #[test] + fn maps_addresses_to_tunnels() { + let snap = Snapshot { + internet_iface: Some("utun".into()), + ifaces: vec![ + Iface { name: "ppp0".into(), ipv4: vec!["192.168.200.20".into()], up: true, ..Default::default() }, + Iface { name: "utun".into(), ipv4: vec!["192.168.2.3".into()], up: true, ..Default::default() }, + Iface { name: "tailscale0".into(), up: true, ..Default::default() }, + Iface { name: "wld0".into(), up: true, ..Default::default() }, + ], + }; + assert_eq!(snap.iface_with_address("192.168.200.20/32").map(|i| i.name.as_str()), Some("ppp0")); + let tunnels: Vec<_> = snap.tunnels().map(|i| i.name.as_str()).collect(); + assert_eq!(tunnels, ["ppp0", "utun"]); + } +} diff --git a/rust/mseries-tailscale/src/ui/window.rs b/rust/mseries-tailscale/src/ui/window.rs index 2ce6dda..3bcb90e 100644 --- a/rust/mseries-tailscale/src/ui/window.rs +++ b/rust/mseries-tailscale/src/ui/window.rs @@ -6,11 +6,13 @@ use crate::cli::{self, CliError}; use crate::model::{self, Backend, Device, Prefs, Status}; +use crate::net; use crate::strings::tr; use granite::prelude::{HeaderLabelExt, PlaceholderExt}; use gtk::{gio, glib, prelude::*}; use mseries_pantheon_kit::{appearance, chrome, set_accessible_label}; use std::cell::{Cell, RefCell}; +use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Duration; @@ -47,6 +49,19 @@ pub struct AppWindow { vpn_list: gtk::Box, vpn_key: RefCell, vpn_pending: RefCell>, + vpn_live: RefCell>, + vpn_failures: RefCell>, + vpn_connecting: RefCell>, + vpn_stopping: RefCell>, + vpn_ticks: RefCell>, + vpn_banner: gtk::Box, + vpn_banner_text: gtk::Label, + route_now: gtk::Label, + sessions: Sessions, + ts_timer: gtk::Label, + remote_list: gtk::Box, + remote_key: RefCell, + ticker: RefCell>, // Devices devices_header: granite::HeaderLabel, search: gtk::SearchEntry, @@ -101,6 +116,10 @@ impl AppWindow { let route_line = gtk::Label::builder().xalign(0.0).wrap(true).visible(false).build(); route_line.add_css_class(granite::CssClassACCENT); titles.append(&route_line); + let ts_timer = gtk::Label::builder().xalign(0.0).visible(false).build(); + ts_timer.add_css_class(granite::CssClassNUMERIC); + ts_timer.add_css_class(granite::CssClassDIM); + titles.append(&ts_timer); let connect = gtk::Switch::builder().valign(gtk::Align::Center).build(); set_accessible_label(&connect, &tr("Connected")); let top = gtk::Box::builder().spacing(12).build(); @@ -208,7 +227,19 @@ impl AppWindow { let window = b.root().and_downcast::(); gtk::UriLauncher::new("settings://network").launch(window.as_ref(), gio::Cancellable::NONE, |_| {}); }); + let vpn_banner_text = gtk::Label::builder().xalign(0.0).wrap(true).hexpand(true).build(); + let vpn_banner = card_box(); + vpn_banner.add_css_class("mseries-tailscale-setup"); + let banner_line = gtk::Box::builder().spacing(12).build(); + banner_line.append(>k::Image::from_icon_name("dialog-warning-symbolic")); + banner_line.append(&vpn_banner_text); + vpn_banner.append(&banner_line); + vpn_banner.set_visible(false); + let route_now = gtk::Label::builder().xalign(0.0).wrap(true).visible(false).build(); + route_now.add_css_class("heading"); let vpn_body = gtk::Box::builder().orientation(gtk::Orientation::Vertical).spacing(9).build(); + vpn_body.append(&vpn_banner); + vpn_body.append(&route_now); vpn_body.append(&vpn_list); vpn_body.append(&add_vpn); let vpn_section = section(&vpn_header, &vpn_body); @@ -262,11 +293,16 @@ impl AppWindow { .margin_end(18) .build(); column.append(&card); + let remote_header = granite::HeaderLabel::new(&tr("Remote Into a Mac")); + remote_header.set_secondary_text(Some(&tr("Screen Sharing over Tailscale, from anywhere"))); + let remote_list = gtk::Box::builder().orientation(gtk::Orientation::Vertical).spacing(9).build(); + let remote_section = section(&remote_header, &remote_list); column.append(&setup); column.append(&health); + column.append(&remote_section); + column.append(&vpn_section); column.append(&exit_section); column.append(&devices_section); - column.append(&vpn_section); column.append(&settings_section); column.append(&footer); let scroller = gtk::ScrolledWindow::builder().hscrollbar_policy(gtk::PolicyType::Never).child(&column).build(); @@ -320,6 +356,19 @@ impl AppWindow { vpn_list, vpn_key: RefCell::new(String::new()), vpn_pending: RefCell::new(Default::default()), + vpn_live: RefCell::new(HashMap::new()), + vpn_failures: RefCell::new(HashMap::new()), + vpn_connecting: RefCell::new(HashSet::new()), + vpn_stopping: RefCell::new(HashSet::new()), + vpn_ticks: RefCell::new(Vec::new()), + vpn_banner, + vpn_banner_text, + route_now, + sessions: Sessions::load(), + ts_timer, + remote_list, + remote_key: RefCell::new(String::new()), + ticker: RefCell::new(None), devices_header, search, device_list, @@ -350,6 +399,14 @@ impl AppWindow { }); poll.bind_to_widget_mapped(&this.window); *this.poll.borrow_mut() = Some(poll); + let weak = Rc::downgrade(&this); + let ticker = mseries_pantheon_kit::Polling::new(Duration::from_secs(1), move || { + if let Some(this) = weak.upgrade() { + this.tick(); + } + }); + ticker.bind_to_widget_mapped(&this.window); + *this.ticker.borrow_mut() = Some(ticker); // Wi-Fi changes make tailscaled reconnect; show it at once instead of waiting for the next poll. let weak = Rc::downgrade(&this); let id = gio::NetworkMonitor::default().connect_network_changed(move |_, _| { @@ -708,8 +765,16 @@ impl AppWindow { status.peers.len(), tr("total") ))); + if connected { + self.sessions.start("tailscale", 1, now_unix()); + } else { + self.sessions.stop("tailscale"); + } + self.sessions.save(); *self.status.borrow_mut() = Some(status); self.show_devices(); + self.show_remote(); + self.tick(); } fn show_devices(self: &Rc) { @@ -850,6 +915,18 @@ impl AppWindow { Ok((true, out, _)) => model::parse_vpn_list(&out), _ => Vec::new(), }; + let active = match cli::run_program( + &["nmcli", "-t", "-f", "UUID,STATE,DEVICE,TYPE", "connection", "show", "--active"], + 8, + ) + .await + { + Ok((true, out, _)) => model::parse_active(&out), + _ => Default::default(), + }; + let snap = net::probe().await; + let now = now_unix(); + let mut lives = Vec::new(); for vpn in &mut vpns { if let Ok((true, out, _)) = cli::run_program(&["nmcli", "-g", "ipv4.never-default", "connection", "show", &vpn.uuid], 8).await @@ -861,9 +938,66 @@ impl AppWindow { { vpn.secrets_saved = model::secrets_saved(&out); } + // Never trust NetworkManager's "activated" alone: find the tunnel and check it is up. + let (nm_state, device, kind) = active.get(&vpn.uuid).cloned().unwrap_or_default(); + let mut iface = None; + if nm_state == "activated" { + if kind == "wireguard" { + iface = snap.iface(&device).filter(|i| i.up && !i.ipv4.is_empty()).map(|i| i.name.clone()); + } else if let Ok((true, out, _)) = + cli::run_program(&["nmcli", "-g", "IP4.ADDRESS", "connection", "show", &vpn.uuid], 8).await + { + let addr = out.lines().next().unwrap_or_default().trim().to_string(); + iface = (!addr.is_empty()) + .then(|| snap.iface_with_address(&addr)) + .flatten() + .filter(|i| i.up) + .map(|i| i.name.clone()); + } + } + let connecting = self.vpn_connecting.borrow().contains(&vpn.uuid) || nm_state == "activating"; + let previous = self.vpn_live.borrow().get(&vpn.uuid).cloned(); + let live = if let Some(iface) = iface.clone() { + self.vpn_failures.borrow_mut().remove(&vpn.uuid); + Live::Connected(iface) + } else if connecting { + Live::Connecting + } else if nm_state == "activated" { + Live::Dropped + } else if let Some(reason) = self.vpn_failures.borrow().get(&vpn.uuid).cloned() { + Live::Failed(reason) + } else { + Live::Off + }; + // It was up and went away without us turning it off: record why. + let live = match (&previous, &live) { + (Some(Live::Connected(_)) | Some(Live::Connecting) | Some(Live::Dropped), Live::Off) + if !self.vpn_stopping.borrow().contains(&vpn.uuid) => + { + let reason = failure_reason(&vpn.name, &snap, iface.as_deref()).await; + self.vpn_failures.borrow_mut().insert(vpn.uuid.clone(), reason.clone()); + Live::Failed(reason) + } + _ => live, + }; + if matches!(live, Live::Off) { + self.vpn_stopping.borrow_mut().remove(&vpn.uuid); + } + // Session timer: keep the start while the same tunnel interface stays up. + if let Live::Connected(name) = &live { + let index = snap.iface(name).map(|i| i.index).unwrap_or(0); + self.sessions.start(&vpn.uuid, index, now); + } else { + self.sessions.stop(&vpn.uuid); + } + self.vpn_live.borrow_mut().insert(vpn.uuid.clone(), live.clone()); + lives.push(live); } + self.sessions.save(); + self.show_vpn_overview(&vpns, &lives, &snap); + let pending = self.vpn_pending.borrow().clone(); - let key = format!("{vpns:?}|{pending:?}"); + let key = format!("{vpns:?}|{lives:?}|{pending:?}"); if *self.vpn_key.borrow() == key { return; } @@ -871,60 +1005,185 @@ impl AppWindow { while let Some(child) = self.vpn_list.first_child() { self.vpn_list.remove(&child); } + self.vpn_ticks.borrow_mut().clear(); if vpns.is_empty() { let none = gtk::Label::builder().label(tr("No other VPNs set up")).xalign(0.0).build(); none.add_css_class(granite::CssClassDIM); self.vpn_list.append(&none); } - for vpn in vpns { - let needs_reconnect = pending.contains(&vpn.uuid) && vpn.active; - self.vpn_list.append(&self.vpn_card(&vpn, needs_reconnect)); + for (vpn, live) in vpns.iter().zip(lives) { + let needs_reconnect = pending.contains(&vpn.uuid) && matches!(live, Live::Connected(_)); + self.vpn_list.append(&self.vpn_card(vpn, &live, needs_reconnect)); } + self.tick(); } - fn vpn_card(self: &Rc, vpn: &model::Vpn, needs_reconnect: bool) -> gtk::Box { + /// Where internet traffic goes now, and a warning when two VPNs fight. + fn show_vpn_overview(&self, vpns: &[model::Vpn], lives: &[Live], snap: &net::Snapshot) { + let ours: Vec<(&model::Vpn, &Live)> = vpns.iter().zip(lives).collect(); + let iface_name = |iface: &str| -> String { + if let Some((vpn, _)) = ours.iter().find(|(_, l)| matches!(l, Live::Connected(i) if i == iface)) { + return model::display_name(&vpn.name); + } + if let Some((vpn, _)) = ours.iter().find(|(v, _)| v.name == iface) { + return model::display_name(&vpn.name); + } + match iface { + "tailscale0" => tr("Tailscale exit node"), + i if snap.tunnels().any(|t| t.name == i) => net::tunnel_owner(i), + _ => tr("this computer's own connection (no VPN)"), + } + }; + match &snap.internet_iface { + Some(iface) => { + self.route_now.set_label(&format!("{} {}", tr("Internet traffic now goes through"), iface_name(iface))); + self.route_now.set_visible(true); + } + None => self.route_now.set_visible(false), + } + + // Tunnels up right now: our connected VPNs plus tunnels nobody listed (another app's VPN). + let mut up: Vec = ours + .iter() + .filter(|(_, l)| matches!(l, Live::Connected(_))) + .map(|(v, _)| model::display_name(&v.name)) + .collect(); + for t in snap.tunnels() { + let ours_iface = + ours.iter().any(|(v, l)| matches!(l, Live::Connected(i) if *i == t.name) || v.name == t.name); + if !ours_iface && t.up { + up.push(net::tunnel_owner(&t.name)); + } + } + let knocked = ours.iter().find(|(_, l)| matches!(l, Live::Dropped | Live::Failed(_))); + let message = match (knocked, up.as_slice()) { + (Some((victim, _)), [other, ..]) => Some(format!( + "{other} {} {} {}", + tr("started its own VPN; it knocked"), + model::display_name(&victim.name), + tr("off. Use one VPN at a time.") + )), + (None, [a, b, ..]) => Some(format!( + "{a} {} {b} {}", + tr("and"), + tr("are both on. Two VPNs at once fight over your traffic; use one at a time.") + )), + _ => None, + }; + self.vpn_banner.set_visible(message.is_some()); + if let Some(m) = message { + self.vpn_banner_text.set_label(&m); + } + } + + fn vpn_card(self: &Rc, vpn: &model::Vpn, live: &Live, needs_reconnect: bool) -> gtk::Box { let card = card_box(); - let on = gtk::Switch::builder().valign(gtk::Align::Center).active(vpn.active).state(vpn.active).build(); - let gear = icon_button("emblem-system-symbolic", &format!("{} {}", vpn.name, tr("Settings"))); + let name = model::display_name(&vpn.name); + let on_now = !matches!(live, Live::Off | Live::Failed(_)); + let on = gtk::Switch::builder().valign(gtk::Align::Center).active(on_now).state(on_now).build(); + let gear = icon_button("emblem-system-symbolic", &format!("{name} {}", tr("Settings"))); let controls = gtk::Box::builder().spacing(6).valign(gtk::Align::Center).build(); + if matches!(live, Live::Connecting) { + let spinner = gtk::Spinner::builder().spinning(true).valign(gtk::Align::Center).build(); + controls.append(&spinner); + } controls.append(&gear); controls.append(&on); - set_accessible_label(&on, &format!("{} {}", tr("Connect"), vpn.name)); - card.append(&setting_row( - &vpn.name, - Some(&if vpn.active { tr("Connected") } else { tr("Not connected") }), - &controls, - )); + set_accessible_label(&on, &format!("{} {name}", tr("Connect"))); + let (status_text, status_class) = match live { + Live::Connected(iface) => (format!("{} · {iface}", tr("Connected")), Some(granite::CssClassSUCCESS)), + Live::Connecting => (tr("Connecting…"), None), + Live::Dropped => (tr("Dropped: on, but not carrying any traffic"), Some(granite::CssClassERROR)), + Live::Failed(reason) => (format!("{}: {reason}", tr("Failed")), Some(granite::CssClassERROR)), + Live::Off => (tr("Not connected"), None), + }; + let row = setting_row(&name, Some(&status_text), &controls); + if let Some(class) = status_class { + // The description label is the second child of the text box. + if let Some(desc) = row.first_child().and_then(|t| t.last_child()) { + desc.remove_css_class(granite::CssClassDIM); + desc.add_css_class(class); + } + } + card.append(&row); + + if let Live::Connected(iface) = live { + let timer = gtk::Label::builder().xalign(0.0).hexpand(true).build(); + timer.add_css_class(granite::CssClassNUMERIC); + timer.add_css_class("title-4"); + let bytes = gtk::Label::builder().xalign(1.0).build(); + bytes.add_css_class(granite::CssClassNUMERIC); + bytes.add_css_class(granite::CssClassDIM); + let line = gtk::Box::builder().spacing(12).build(); + line.append(&timer); + line.append(&bytes); + card.append(&line); + self.vpn_ticks.borrow_mut().push(Tick { key: vpn.uuid.clone(), iface: iface.clone(), timer, bytes }); + } + let (weak, edit_vpn) = (Rc::downgrade(self), vpn.clone()); gear.connect_clicked(move |_| { if let Some(this) = weak.upgrade() { - this.open_vpn_sheet(&edit_vpn); + // The sheet covers plugin VPNs (L2TP and friends); WireGuard opens the system editor. + if edit_vpn.kind_has_routing() { + this.open_vpn_sheet(&edit_vpn); + } else { + this.edit_vpn(&edit_vpn.uuid); + } } }); - card.append(>k::Separator::new(gtk::Orientation::Horizontal)); - let all = - gtk::Switch::builder().valign(gtk::Align::Center).active(vpn.all_traffic).state(vpn.all_traffic).build(); - let mode = if vpn.all_traffic { - format!("{} {}", tr("All internet traffic goes through"), vpn.name) - } else { - format!("{} {}", tr("Off: only its own networks go through"), vpn.name) - }; - card.append(&setting_row(&tr("Send all traffic over VPN connection"), Some(&mode), &all)); - if !vpn.secrets_saved { - let line = gtk::Box::builder().spacing(12).build(); - let note = gtk::Label::builder() - .label(tr("Passwords aren't saved, so connecting from here can't work. Save them once.")) - .xalign(0.0) - .hexpand(true) - .wrap(true) + if vpn.kind_has_routing() { + card.append(>k::Separator::new(gtk::Orientation::Horizontal)); + let all = gtk::Switch::builder() + .valign(gtk::Align::Center) + .active(vpn.all_traffic) + .state(vpn.all_traffic) .build(); - note.add_css_class(granite::CssClassWARNING); - let save = gtk::Button::with_label(&tr("Save Passwords…")); - save.set_valign(gtk::Align::Center); - line.append(¬e); - line.append(&save); + let mode = if vpn.all_traffic { + format!("{} {name}", tr("On: all internet traffic goes through")) + } else { + format!("{} {name}", tr("Off: only its own networks go through")) + }; + card.append(&setting_row(&tr("Send all traffic over VPN connection"), Some(&mode), &all)); + let (weak, uuid, connected) = (Rc::downgrade(self), vpn.uuid.clone(), matches!(live, Live::Connected(_))); + all.connect_state_set(move |_, everything| { + if let Some(this) = weak.upgrade() { + let never_default = if everything { "no" } else { "yes" }; + let done = if everything { + tr("All traffic will go over the VPN") + } else { + tr("Only the VPN's own networks will use it") + }; + if connected { + this.vpn_pending.borrow_mut().insert(uuid.clone()); + } + this.vpn_command( + &uuid, + vec![ + "nmcli", + "connection", + "modify", + "uuid", + &uuid, + "ipv4.never-default", + never_default, + "ipv6.never-default", + never_default, + ], + done, + false, + ); + } + glib::Propagation::Stop + }); + } + if !vpn.secrets_saved { card.append(>k::Separator::new(gtk::Orientation::Horizontal)); - card.append(&line); + let save = gtk::Button::with_label(&tr("Save Passwords…")); + card.append(¬e_line( + &tr("Passwords aren't saved, so connecting from here can't work. Save them once."), + &save, + )); let (weak, edit_vpn) = (Rc::downgrade(self), vpn.clone()); save.connect_clicked(move |_| { if let Some(this) = weak.upgrade() { @@ -932,79 +1191,224 @@ impl AppWindow { } }); } - if needs_reconnect { - let line = gtk::Box::builder().spacing(12).build(); - let note = gtk::Label::builder() - .label(tr("Reconnect to use the new setting.")) - .xalign(0.0) - .hexpand(true) - .wrap(true) - .build(); - note.add_css_class(granite::CssClassWARNING); + let broken = matches!(live, Live::Dropped | Live::Failed(_)); + if needs_reconnect || broken { let reconnect = gtk::Button::with_label(&tr("Reconnect")); reconnect.add_css_class(granite::CssClassSUGGESTED); - line.append(¬e); - line.append(&reconnect); - card.append(&line); - let (weak, uuid, name) = (Rc::downgrade(self), vpn.uuid.clone(), vpn.name.clone()); + let text = if broken { tr("Reconnect to bring it back.") } else { tr("Reconnect to use the new setting.") }; + card.append(¬e_line(&text, &reconnect)); + let (weak, uuid, label) = (Rc::downgrade(self), vpn.uuid.clone(), name.clone()); reconnect.connect_clicked(move |_| { if let Some(this) = weak.upgrade() { + this.vpn_failures.borrow_mut().remove(&uuid); + this.vpn_connecting.borrow_mut().insert(uuid.clone()); this.vpn_command( &uuid, - vec!["sh", "-c", "nmcli connection down uuid \"$0\" && nmcli connection up uuid \"$0\"", &uuid], - format!("{} {name}", tr("Reconnected")), + vec![ + "sh", + "-c", + "nmcli connection down uuid \"$0\" >/dev/null 2>&1; nmcli connection up uuid \"$0\"", + &uuid, + ], + format!("{} {label}", tr("Reconnected")), true, ); } }); } - let (weak, uuid, name) = (Rc::downgrade(self), vpn.uuid.clone(), vpn.name.clone()); + let (weak, uuid) = (Rc::downgrade(self), vpn.uuid.clone()); on.connect_state_set(move |_, active| { if let Some(this) = weak.upgrade() { let verb = if active { "up" } else { "down" }; let done = if active { tr("Connected to") } else { tr("Disconnected from") }; + this.vpn_failures.borrow_mut().remove(&uuid); + if active { + this.vpn_connecting.borrow_mut().insert(uuid.clone()); + } else { + this.vpn_stopping.borrow_mut().insert(uuid.clone()); + } + this.vpn_key.borrow_mut().clear(); this.vpn_command( &uuid, vec!["nmcli", "connection", verb, "uuid", &uuid], format!("{done} {name}"), false, ); + // Show "Connecting…" right away instead of waiting for nmcli. + let this2 = this.clone(); + glib::spawn_future_local(async move { this2.refresh_vpns().await }); } glib::Propagation::Stop }); - let (weak, uuid, active) = (Rc::downgrade(self), vpn.uuid.clone(), vpn.active); - all.connect_state_set(move |_, everything| { - if let Some(this) = weak.upgrade() { - let never_default = if everything { "no" } else { "yes" }; - let done = if everything { - tr("All traffic will go over the VPN") - } else { - tr("Only the VPN's own networks will use it") - }; - if active { - this.vpn_pending.borrow_mut().insert(uuid.clone()); + card + } + + /// One-second update of session timers and traffic counters (no rebuilds). + fn tick(&self) { + let now = now_unix(); + for t in self.vpn_ticks.borrow().iter() { + if let Some(start) = self.sessions.started(&t.key) { + t.timer.set_label(&net::duration_text(now - start)); + } + if let Some((rx, tx)) = net::counters(&t.iface) { + t.bytes.set_label(&format!("↓ {} ↑ {}", net::bytes_text(rx), net::bytes_text(tx))); + } + } + match self.sessions.started("tailscale") { + Some(start) if self.status_is_running() => { + self.ts_timer.set_label(&format!("{} {}", tr("Connected for"), net::duration_text(now - start))); + self.ts_timer.set_visible(true); + } + _ => self.ts_timer.set_visible(false), + } + } + + fn status_is_running(&self) -> bool { + self.status.borrow().as_ref().is_some_and(|s| s.backend == Backend::Running) + } + + /// "Remote Into a Mac": the tailnet's Macs with Screen Sharing (VNC over Tailscale). + fn show_remote(self: &Rc) { + let status = self.status.borrow(); + let running = status.as_ref().is_some_and(|s| s.backend == Backend::Running); + let macs: Vec = status + .as_ref() + .map(|s| { + // The Mac mini at BFS always; other Macs only while online (the full list is under Devices). + let mut m: Vec = s + .peers + .iter() + .filter(|d| d.os == "macOS" && (d.online || d.ssh_host == "csp-bfs-mini")) + .cloned() + .collect(); + // The Mac mini at BFS first, then online ones. + m.sort_by_key(|d| (d.ssh_host != "csp-bfs-mini", !d.online, d.name.to_lowercase())); + m + }) + .unwrap_or_default(); + drop(status); + let have_viewer = glib::find_program_in_path("remmina").is_some(); + let key = format!( + "{running}|{have_viewer}|{}", + macs.iter().map(|d| format!("{}:{}", d.id, d.online)).collect::>().join(",") + ); + if *self.remote_key.borrow() == key { + return; + } + *self.remote_key.borrow_mut() = key; + while let Some(child) = self.remote_list.first_child() { + self.remote_list.remove(&child); + } + if !running { + let turn_on = gtk::Button::with_label(&tr("Turn On Tailscale")); + turn_on.add_css_class(granite::CssClassSUGGESTED); + let card = card_box(); + card.append(¬e_line(&tr("Tailscale is off. Turn it on to reach your Macs from anywhere."), &turn_on)); + self.remote_list.append(&card); + let weak = Rc::downgrade(self); + turn_on.connect_clicked(move |_| { + if let Some(this) = weak.upgrade() { + this.change(vec!["up"], tr("Connected")); } - this.vpn_command( - &uuid, - vec![ - "nmcli", - "connection", - "modify", - "uuid", - &uuid, - "ipv4.never-default", - never_default, - "ipv6.never-default", - never_default, - ], - done, - false, - ); + }); + } + if !have_viewer { + let copy = gtk::Button::with_label(&tr("Copy Command")); + let card = card_box(); + card.append(¬e_line( + &tr("Screen Sharing needs the Remmina app. Install it once: sudo apt install remmina remmina-plugin-vnc"), + ©, + )); + self.remote_list.append(&card); + let weak = Rc::downgrade(self); + copy.connect_clicked(move |_| { + if let Some(this) = weak.upgrade() { + this.copy( + "sudo apt install remmina remmina-plugin-vnc", + &tr("Copied. Paste it in Terminal, then come back."), + ); + } + }); + } + if macs.is_empty() { + return; + } + let list = gtk::ListBox::builder().selection_mode(gtk::SelectionMode::None).build(); + list.add_css_class("boxed-list"); + list.add_css_class(granite::CssClassCARD); + list.add_css_class("mseries-tailscale-devices"); + let now = now_unix(); + for mac in macs { + let dot = gtk::Label::new(Some("●")); + dot.add_css_class("mseries-tailscale-dot"); + dot.add_css_class(if mac.online && running { granite::CssClassSUCCESS } else { granite::CssClassDIM }); + let name = + gtk::Label::builder().label(&mac.name).xalign(0.0).ellipsize(gtk::pango::EllipsizeMode::End).build(); + name.add_css_class("heading"); + let seen = + mac.last_seen.as_deref().and_then(|s| glib::DateTime::from_iso8601(s, None).ok()).map(|t| t.to_unix()); + let detail = gtk::Label::builder() + .label(format!( + "{} · {}", + mac.ip(), + if running { tr(&model::presence_text(mac.online, seen, now)) } else { tr("Tailscale is off") } + )) + .xalign(0.0) + .ellipsize(gtk::pango::EllipsizeMode::End) + .build(); + detail.add_css_class(granite::CssClassDIM); + detail.add_css_class(granite::CssClassSMALL); + let text = gtk::Box::builder().orientation(gtk::Orientation::Vertical).spacing(2).hexpand(true).build(); + text.append(&name); + text.append(&detail); + let share = gtk::Button::with_label(&tr("Screen Sharing")); + share.set_valign(gtk::Align::Center); + if mac.online && running { + share.add_css_class(granite::CssClassSUGGESTED); } - glib::Propagation::Stop - }); - card + share.set_tooltip_text(Some(&format!("vnc://{}", mac.ip()))); + let ssh = icon_button("utilities-terminal-symbolic", &format!("{} “{}”", tr("Copy"), mac.ssh_command())); + let line = + gtk::Box::builder().spacing(12).margin_top(9).margin_bottom(9).margin_start(12).margin_end(6).build(); + line.append(&dot); + line.append(&text); + line.append(&share); + line.append(&ssh); + list.append(>k::ListBoxRow::builder().child(&line).activatable(false).build()); + let (weak, ip, label) = (Rc::downgrade(self), mac.ip().to_string(), mac.name.clone()); + share.connect_clicked(move |_| { + if let Some(this) = weak.upgrade() { + this.screen_share(&ip, &label); + } + }); + let (weak, cmd) = (Rc::downgrade(self), mac.ssh_command()); + ssh.connect_clicked(move |_| { + if let Some(this) = weak.upgrade() { + this.copy(&cmd, &format!("{} “{cmd}”", tr("Copied"))); + } + }); + } + self.remote_list.append(&list); + } + + fn screen_share(&self, ip: &str, name: &str) { + if !self.status_is_running() { + chrome::show_toast(&self.toast, &tr("Turn on Tailscale first.")); + return; + } + if glib::find_program_in_path("remmina").is_none() { + self.copy( + "sudo apt install remmina remmina-plugin-vnc", + &tr("Remmina isn't installed. Copied the install command."), + ); + return; + } + let uri = format!("vnc://{ip}"); + match gio::Subprocess::newv(&["remmina".as_ref(), "-c".as_ref(), uri.as_ref()], gio::SubprocessFlags::NONE) { + Ok(_) => chrome::show_toast(&self.toast, &format!("{} {name}…", tr("Opening Screen Sharing on"))), + Err(e) => chrome::show_toast(&self.toast, e.message()), + } } pub fn open_vpn_sheet(self: &Rc, vpn: &model::Vpn) { @@ -1058,7 +1462,9 @@ impl AppWindow { glib::spawn_future_local(async move { let refs: Vec<&str> = argv.iter().map(String::as_str).collect(); // Connecting an L2TP/IPsec VPN takes a while; a polkit prompt waits for the user. - match cli::run_program(&refs, 90).await { + let result = cli::run_program(&refs, 90).await; + this.vpn_connecting.borrow_mut().remove(&uuid); + match result { Ok((true, _, _)) => { if clears_pending { this.vpn_pending.borrow_mut().remove(&uuid); @@ -1074,7 +1480,19 @@ impl AppWindow { } Ok((false, _, err)) => { let first = err.lines().map(str::trim).find(|l| !l.is_empty()).unwrap_or("The VPN change failed."); - chrome::show_toast(&this.toast, first.trim_start_matches("Error: ")); + let first = first.trim_start_matches("Error: ").to_string(); + if refs.iter().any(|a| *a == "up" || a.contains("connection up")) { + let snap = net::probe().await; + let others: Vec = snap + .tunnels() + .filter(|t| t.up && !t.name.starts_with("ppp")) + .map(|t| net::tunnel_owner(&t.name)) + .collect(); + let reason = + if others.is_empty() { first.clone() } else { model::classify_vpn_failure("", &others) }; + this.vpn_failures.borrow_mut().insert(uuid.clone(), reason); + } + chrome::show_toast(&this.toast, &first); } Err(e) => chrome::show_toast(&this.toast, &e.message()), } @@ -1150,3 +1568,115 @@ fn icon_button(icon: &str, label: &str) -> gtk::Button { set_accessible_label(&b, label); b } + +/// What a VPN is really doing, from the kernel's point of view. +#[derive(Debug, Clone, PartialEq)] +enum Live { + /// Its tunnel interface is up. + Connected(String), + Connecting, + /// NetworkManager says on, but no tunnel carries traffic. + Dropped, + Failed(String), + Off, +} + +/// Labels the one-second timer updates. +struct Tick { + key: String, + iface: String, + timer: gtk::Label, + bytes: gtk::Label, +} + +/// Session start times, kept across app restarts (keyed by connection and tunnel interface index, so a +/// reconnect starts a new session). +struct Sessions { + path: std::path::PathBuf, + map: RefCell>, + dirty: Cell, +} + +impl Sessions { + fn load() -> Self { + let path = mseries_pantheon_kit::settings::app_config_dir(APP_ID).join("sessions.json"); + let map = if std::env::var_os("MSERIES_TAILSCALE_FIXTURES").is_some() { + // Fixture screenshots show a session that has been up for a while. + HashMap::new() + } else { + mseries_pantheon_kit::settings::load_json(&path) + }; + Self { path, map: RefCell::new(map), dirty: Cell::new(false) } + } + + fn start(&self, key: &str, index: u32, now: i64) { + let mut map = self.map.borrow_mut(); + if map.get(key).is_some_and(|(i, _)| *i == index) { + return; + } + let start = if std::env::var_os("MSERIES_TAILSCALE_FIXTURES").is_some() { now - 4 * 3600 - 249 } else { now }; + map.insert(key.into(), (index, start)); + self.dirty.set(true); + } + + fn stop(&self, key: &str) { + if self.map.borrow_mut().remove(key).is_some() { + self.dirty.set(true); + } + } + + fn started(&self, key: &str) -> Option { + self.map.borrow().get(key).map(|(_, s)| *s) + } + + fn save(&self) { + if self.dirty.replace(false) && std::env::var_os("MSERIES_TAILSCALE_FIXTURES").is_none() { + let _ = mseries_pantheon_kit::settings::save_json(&self.path, &*self.map.borrow()); + } + } +} + +fn now_unix() -> i64 { + glib::DateTime::now_utc().map(|t| t.to_unix()).unwrap_or(0) +} + +/// Reason for a VPN that dropped on its own, from the last few minutes of logs. +async fn failure_reason(_name: &str, snap: &net::Snapshot, _iface: Option<&str>) -> String { + let others: Vec = + snap.tunnels().filter(|t| t.up && !t.name.starts_with("ppp")).map(|t| net::tunnel_owner(&t.name)).collect(); + let log = cli::run_program( + &[ + "journalctl", + "--since", + "-3min", + "--no-pager", + "-o", + "cat", + "-t", + "NetworkManager", + "-t", + "pppd", + "-t", + "nm-l2tp-service", + "-t", + "charon", + "-t", + "ipsec", + ], + 5, + ) + .await + .map(|(_, out, _)| out) + .unwrap_or_default(); + model::classify_vpn_failure(&log, &others) +} + +/// A wrapped note with a button at the end. +fn note_line(text: &str, button: >k::Button) -> gtk::Box { + let note = gtk::Label::builder().label(text).xalign(0.0).hexpand(true).wrap(true).build(); + button.set_valign(gtk::Align::Center); + let line = gtk::Box::builder().spacing(12).build(); + line.append(¬e); + line.append(button); + line +}