Skip to main content

netcore/
traits.rs

1//! Layer 4 — capability traits.
2//!
3//! Backends implement the subset they can. The CLI holds them as trait
4//! objects (`Box<dyn Trait>`) so NetworkManager, netlink, or shell-out
5//! backends can be selected at runtime based on what's available.
6//!
7//! All traits are object-safe: no generics on methods, no `Self` returns,
8//! no async (we stay sync for a sub-100ms CLI).
9
10use std::net::{IpAddr, SocketAddr};
11use std::time::Duration;
12
13use url::Url;
14
15use crate::Result;
16use crate::connection::{Connection, ConnectionId};
17use crate::diag::{
18    CheckScope, FirewallBackend, FirewallVerdict, Health, PingOpts, ProbeCapabilities, TraceOpts,
19};
20use crate::dns::DnsResolution;
21use crate::link::{Addr, L4Proto, Link, Neighbor, Route, Socket};
22use crate::path::{
23    Egress, Hop, HttpProbeResult, Path, PingResult, Target, TcpProbeResult, TlsProbeResult,
24};
25use crate::service::{Flow, Service};
26
27/// Raw kernel-primitive inventory. Backends implementing this expose
28/// unfiltered data for `jip raw *`.
29pub trait InventoryRaw: Send + Sync {
30    /// Return all kernel-visible network interfaces.
31    fn links(&self) -> Result<Vec<Link>>;
32    /// Return all addresses, each paired with the ifindex they belong to.
33    fn addrs(&self) -> Result<Vec<(u32, Addr)>>;
34    /// Return all routing table entries.
35    fn routes(&self) -> Result<Vec<Route>>;
36    /// Return all ARP/ND neighbor table entries.
37    fn neighbors(&self) -> Result<Vec<Neighbor>>;
38    /// Return all open sockets (TCP + UDP, IPv4 + IPv6).
39    fn sockets(&self) -> Result<Vec<Socket>>;
40}
41
42/// Domain-level inventory. Composes primitives into [`Connection`] etc.,
43/// applies smart filtering (IPv6 collapse, APIPA, metadata IPs).
44pub trait Inventory: Send + Sync {
45    /// Return all user-facing network connections.
46    fn connections(&self) -> Result<Vec<Connection>>;
47    /// Return all listening services.
48    fn services(&self) -> Result<Vec<Service>>;
49    /// Return all established flows.
50    fn flows(&self) -> Result<Vec<Flow>>;
51    /// Which [`Egress`] would carry traffic to `dst` — wraps `ip route get`.
52    fn egress_for(&self, dst: IpAddr) -> Result<Egress>;
53}
54
55/// DNS resolution, per-link resolver discovery.
56pub trait Resolver: Send + Sync {
57    /// Resolve a hostname or IP string, returning the full resolution record.
58    fn resolve(&self, name: &str) -> Result<DnsResolution>;
59    /// Per-link resolvers (as reported by `resolvectl`). Falls back to the
60    /// stub list when per-link info is unavailable.
61    fn servers_for(&self, conn: &ConnectionId) -> Result<Vec<IpAddr>>;
62    /// The local stub resolver, typically `127.0.0.53` on systemd-resolved hosts.
63    fn stub_server(&self) -> Result<Option<IpAddr>>;
64}
65
66/// Active probes: ICMP, TCP connect, TLS handshake, HTTP HEAD, traceroute.
67pub trait Reachability: Send + Sync {
68    /// Send ICMP echo requests to `ip` according to `opts`.
69    fn ping(&self, ip: IpAddr, opts: PingOpts) -> Result<PingResult>;
70    /// Attempt a TCP three-way handshake to `sa` within `timeout`.
71    fn tcp_connect(&self, sa: SocketAddr, timeout: Duration) -> Result<TcpProbeResult>;
72    /// Perform a TLS handshake to `sa` with the given SNI within `timeout`.
73    fn tls_handshake(&self, sa: SocketAddr, sni: &str, timeout: Duration)
74    -> Result<TlsProbeResult>;
75    /// Issue an HTTP HEAD request to `url` within `timeout`.
76    fn http_head(&self, url: &Url, timeout: Duration) -> Result<HttpProbeResult>;
77    /// Run a traceroute to `ip` using `opts`.
78    fn trace(&self, ip: IpAddr, opts: TraceOpts) -> Result<Vec<Hop>>;
79    /// What this backend can actually do on this system.
80    fn capabilities(&self) -> ProbeCapabilities;
81}
82
83/// Firewall posture.
84pub trait Firewall: Send + Sync {
85    /// Determine the inbound firewall verdict for a given (port, proto) pair.
86    fn verdict_for_inbound(&self, port: u16, proto: L4Proto) -> Result<FirewallVerdict>;
87    /// Return which firewall tool this backend read from.
88    fn backend(&self) -> FirewallBackend;
89}
90
91/// Write operations on connections (requires NetworkManager or similar).
92pub trait Actions: Send + Sync {
93    /// Activate the connection identified by `id`.
94    fn prefer(&self, id: &ConnectionId) -> Result<()>;
95    /// Delete the connection profile identified by `id`.
96    fn forget(&self, id: &ConnectionId) -> Result<()>;
97    /// Deactivate and then reactivate the connection identified by `id`.
98    fn reconnect(&self, id: &ConnectionId) -> Result<()>;
99    /// Enable or disable autoconnect for the connection identified by `id`.
100    fn set_autoconnect(&self, id: &ConnectionId, on: bool) -> Result<()>;
101}
102
103/// Orchestrates the others into end-to-end health checks and path probes.
104pub trait Diagnostician: Send + Sync {
105    /// Run a layered health check at the given scope. Returns an overall
106    /// [`Health`] value with any [`Finding`](crate::diag::Finding)s.
107    fn check(&self, scope: CheckScope) -> Result<Health>;
108    /// Resolve the target, select egress, run probes, and return the full
109    /// [`Path`].
110    fn trace_path(&self, target: Target) -> Result<Path>;
111}