Skip to content

Commit

Permalink
docs(connlib): add more inline docs to connlib's state (#5105)
Browse files Browse the repository at this point in the history
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 <thomas@eizinger.io>
Co-authored-by: Reactor Scram <ReactorScram@users.noreply.github.com>
  • Loading branch information
thomaseizinger and ReactorScram committed May 24, 2024
1 parent 994b25b commit bb8cc86
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 21 deletions.
1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
58 changes: 41 additions & 17 deletions rust/connlib/tunnel/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/// Manages wireguard tunnels to gateways.
node: ClientNode<GatewayId, RelayId>,
/// All gateways we are connected to and the associated, connection-specific state.
peers: PeerStore<GatewayId, GatewayOnClient>,
/// Which Resources we are trying to connect to.
awaiting_connection: HashMap<ResourceId, AwaitingConnectionDetails>,

/// Tracks which gateway to use for a particular Resource.
resources_gateways: HashMap<ResourceId, GatewayId>,
/// The site a gateway belongs to.
gateways_site: HashMap<GatewayId, SiteId>,
/// The online/offline status of a site.
sites_status: HashMap<SiteId, Status>,

pub dns_resources_internal_ips: HashMap<DnsResource, HashSet<IpAddr>>,
/// All DNS resources we know about, indexed by their domain (could be wildcard domain like `*.mycompany.com`).
dns_resources: HashMap<String, ResourceDescriptionDns>,
/// All CIDR resources we know about, indexed by the IP range they cover (like `1.1.0.0/8`).
cidr_resources: IpNetworkTable<ResourceDescriptionCidr>,
pub resource_ids: HashMap<ResourceId, ResourceDescription>,
pub deferred_dns_queries: HashMap<(DnsResource, Rtype), IpPacket<'static>>,

peers: PeerStore<GatewayId, GatewayOnClient>,
/// All resources indexed by their ID.
resource_ids: HashMap<ResourceId, ResourceDescription>,

node: ClientNode<GatewayId, RelayId>,

pub ip_provider: IpProvider,

dns_mapping: BiMap<IpAddr, DnsServer>,

buffered_events: VecDeque<ClientEvent>,
interface_config: Option<InterfaceConfig>,
buffered_packets: VecDeque<IpPacket<'static>>,
/// The DNS resolvers configured on the system outside of connlib.
system_resolvers: Vec<IpAddr>,

/// DNS queries that we need to forward to the system resolver.
buffered_dns_queries: VecDeque<DnsQuery<'static>>,

/// 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<DnsResource, HashSet<IpAddr>>,
/// 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<IpAddr, DnsServer>,
/// 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<Instant>,

system_resolvers: Vec<IpAddr>,
/// Configuration of the TUN device, when it is up.
interface_config: Option<InterfaceConfig>,

gateways_site: HashMap<GatewayId, SiteId>,
sites_status: HashMap<SiteId, Status>,
buffered_events: VecDeque<ClientEvent>,
buffered_packets: VecDeque<IpPacket<'static>>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down
12 changes: 11 additions & 1 deletion rust/connlib/tunnel/src/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ClientId, ClientOnGateway>,
/// The [`snownet::ClientNode`].
///
/// Manages wireguard tunnels to clients.
node: ServerNode<ClientId, RelayId>,
/// All clients we are connected to and the associated, connection-specific state.
peers: PeerStore<ClientId, ClientOnGateway>,

/// When to next check whether a resource-access policy has expired.
next_expiry_resources_check: Option<Instant>,

buffered_events: VecDeque<GatewayEvent>,
}

Expand Down
7 changes: 6 additions & 1 deletion rust/connlib/tunnel/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Pin<Box<tokio::time::Sleep>>>,
/// The UDP sockets used to send & receive packets from the network.
sockets: Sockets,
timeout: Option<Pin<Box<tokio::time::Sleep>>>,

upstream_dns_servers: HashMap<IpAddr, TokioAsyncResolver>,
forwarded_dns_queries: FuturesTupleSet<
Expand Down
10 changes: 8 additions & 2 deletions rust/connlib/tunnel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ const FIREZONE_MARK: u32 = 0xfd002021;
pub type GatewayTunnel<CB> = Tunnel<CB, GatewayState>;
pub type ClientTunnel<CB> = Tunnel<CB, ClientState>;

/// 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<CB: Callbacks, TRoleState> {
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]>,
Expand Down

0 comments on commit bb8cc86

Please sign in to comment.