From bb8cc86b581d8b7f62e2d38e4e54f372034caf77 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 24 May 2024 13:52:06 +1000 Subject: [PATCH] docs(connlib): add more inline docs to connlib's state (#5105) This is a follow-up to #5035. I didn't end up renaming `Tunnel`, `GatewayState` or `ClientState` but I've added some comments with my understanding of what the state is we are tracking and tried to group the fields together in a logical way. --------- Signed-off-by: Thomas Eizinger Co-authored-by: Reactor Scram --- rust/Cargo.toml | 1 + rust/connlib/tunnel/src/client.rs | 62 +++++++++++++++++++++--------- rust/connlib/tunnel/src/gateway.rs | 12 +++++- rust/connlib/tunnel/src/io.rs | 7 +++- rust/connlib/tunnel/src/lib.rs | 10 ++++- 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 246ae4d8e..7f9723f5e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -60,6 +60,7 @@ clippy.unused_async = "warn" clippy.wildcard_enum_match_arm = "warn" # Ensures we match on all combinations of `Poll`, preventing erroneous suspensions. clippy.redundant_else = "warn" clippy.redundant_clone = "warn" +rustdoc.private-intra-doc-links = "allow" # We don't publish any of our docs but want to catch dead links. [patch.crates-io] boringtun = { git = "https://github.com/cloudflare/boringtun", branch = "master" } diff --git a/rust/connlib/tunnel/src/client.rs b/rust/connlib/tunnel/src/client.rs index 1aa262465..825cb8816 100644 --- a/rust/connlib/tunnel/src/client.rs +++ b/rust/connlib/tunnel/src/client.rs @@ -281,37 +281,61 @@ fn send_dns_answer( } } +/// A sans-IO implementation of a Client's functionality. +/// +/// Internally, this composes a [`snownet::ClientNode`] with firezone's policy engine around resources. +/// Clients differ from gateways in that they also implement a DNS resolver for DNS resources. +/// They also initiate connections to Gateways based on packets sent to Resources. Gateways only accept incoming connections. pub struct ClientState { - awaiting_connection: HashMap, - resources_gateways: HashMap, - - pub dns_resources_internal_ips: HashMap>, - dns_resources: HashMap, - cidr_resources: IpNetworkTable, - pub resource_ids: HashMap, - pub deferred_dns_queries: HashMap<(DnsResource, Rtype), IpPacket<'static>>, - - peers: PeerStore, - + /// Manages wireguard tunnels to gateways. node: ClientNode, + /// All gateways we are connected to and the associated, connection-specific state. + peers: PeerStore, + /// Which Resources we are trying to connect to. + awaiting_connection: HashMap, - pub ip_provider: IpProvider, + /// Tracks which gateway to use for a particular Resource. + resources_gateways: HashMap, + /// The site a gateway belongs to. + gateways_site: HashMap, + /// The online/offline status of a site. + sites_status: HashMap, - dns_mapping: BiMap, + /// All DNS resources we know about, indexed by their domain (could be wildcard domain like `*.mycompany.com`). + dns_resources: HashMap, + /// All CIDR resources we know about, indexed by the IP range they cover (like `1.1.0.0/8`). + cidr_resources: IpNetworkTable, + /// All resources indexed by their ID. + resource_ids: HashMap, - buffered_events: VecDeque, - interface_config: Option, - buffered_packets: VecDeque>, + /// The DNS resolvers configured on the system outside of connlib. + system_resolvers: Vec, /// DNS queries that we need to forward to the system resolver. buffered_dns_queries: VecDeque>, + /// The (internal) IPs we have assigned for a certain DNS resource. + /// + /// We assign one internal IP per externally resolved IP. + dns_resources_internal_ips: HashMap>, + /// DNS queries we can only answer once we have connected to the resource. + /// + /// See [`dns::ResolveStrategy`] for details. + deferred_dns_queries: HashMap<(DnsResource, Rtype), IpPacket<'static>>, + /// Hands out IPs for DNS resources. + ip_provider: IpProvider, + /// Maps from connlib-assigned IP of a DNS server back to the originally configured system DNS resolver. + dns_mapping: BiMap, + /// When to next refresh DNS resources. + /// + /// "Refreshing" DNS resources means triggering a new DNS lookup for this domain on the gateway. next_dns_refresh: Option, - system_resolvers: Vec, + /// Configuration of the TUN device, when it is up. + interface_config: Option, - gateways_site: HashMap, - sites_status: HashMap, + buffered_events: VecDeque, + buffered_packets: VecDeque>, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/rust/connlib/tunnel/src/gateway.rs b/rust/connlib/tunnel/src/gateway.rs index 396dd5696..cd262b3d8 100644 --- a/rust/connlib/tunnel/src/gateway.rs +++ b/rust/connlib/tunnel/src/gateway.rs @@ -125,10 +125,20 @@ where } } +/// A SANS-IO implementation of a gateway's functionality. +/// +/// Internally, this composes a [`snownet::ServerNode`] with firezone's policy engine around resources. pub struct GatewayState { - peers: PeerStore, + /// The [`snownet::ClientNode`]. + /// + /// Manages wireguard tunnels to clients. node: ServerNode, + /// All clients we are connected to and the associated, connection-specific state. + peers: PeerStore, + + /// When to next check whether a resource-access policy has expired. next_expiry_resources_check: Option, + buffered_events: VecDeque, } diff --git a/rust/connlib/tunnel/src/io.rs b/rust/connlib/tunnel/src/io.rs index 4f58c0347..3c15f3ac7 100644 --- a/rust/connlib/tunnel/src/io.rs +++ b/rust/connlib/tunnel/src/io.rs @@ -24,10 +24,15 @@ use std::{ const DNS_QUERIES_QUEUE_SIZE: usize = 100; +/// Bundles together all side-effects that connlib needs to have access to. pub struct Io { + /// The TUN device offered to the user. + /// + /// This is the `tun-firezone` network interface that users see when they e.g. type `ip addr` on Linux. device: Device, - timeout: Option>>, + /// The UDP sockets used to send & receive packets from the network. sockets: Sockets, + timeout: Option>>, upstream_dns_servers: HashMap, forwarded_dns_queries: FuturesTupleSet< diff --git a/rust/connlib/tunnel/src/lib.rs b/rust/connlib/tunnel/src/lib.rs index 8fdb3e8bb..43c8dd851 100644 --- a/rust/connlib/tunnel/src/lib.rs +++ b/rust/connlib/tunnel/src/lib.rs @@ -45,13 +45,19 @@ const FIREZONE_MARK: u32 = 0xfd002021; pub type GatewayTunnel = Tunnel; pub type ClientTunnel = Tunnel; -/// Tunnel is a wireguard state machine that uses webrtc's ICE channels instead of UDP sockets to communicate between peers. +/// [`Tunnel`] glues together connlib's [`Io`] component and the respective (pure) state of a client or gateway. +/// +/// Most of connlib's functionality is implemented as a pure state machine in [`ClientState`] and [`GatewayState`]. +/// The only job of [`Tunnel`] is to take input from the TUN [`Device`](crate::device_channel::Device), [`Sockets`] or time and pass it to the respective state. pub struct Tunnel { pub callbacks: CB, - /// State that differs per role, i.e. clients vs gateways. + /// (pure) state that differs per role, either [`ClientState`] or [`GatewayState`]. role_state: TRoleState, + /// The I/O component of connlib. + /// + /// Handles all side-effects. io: Io, write_buf: Box<[u8; MAX_UDP_SIZE]>,