Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

Commit

Permalink
add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
conectado committed May 24, 2023
1 parent 767b887 commit f1cf88f
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 10 deletions.
1 change: 1 addition & 0 deletions clients/apple/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl From<TunnelAddresses> for ffi::TunnelAddresses {
}
}

/// This is used by the apple client to interact with our code.
pub struct WrappedSession {
session: Session<CallbackHandler>,
}
Expand Down
1 change: 1 addition & 0 deletions libs/client/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl ControlSignal for ControlSignaler {
}
}

/// Implementation of [ControlSession] for clients.
pub struct ControlPlane<C: Callbacks> {
tunnel: Arc<Tunnel<ControlSignaler, C>>,
control_signaler: ControlSignaler,
Expand Down
8 changes: 6 additions & 2 deletions libs/client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
//! Main connlib library for clients.
use control::ControlPlane;
use messages::EgressMessages;
use messages::IngressMessages;

mod control;
mod messages;

// IPv6 Min MTU = 1280
const VIRTUAL_IFACE_MTU: u16 = 1280;
const VIRTUAL_IFACE_MTU: u16 = 1420;

/// Session type for clients.
///
/// For more information see libs_common docs on [Session][libs_common::Session].
pub type Session<C> = libs_common::Session<ControlPlane<C>, IngressMessages, EgressMessages>;

pub use libs_common::{
error::SwiftConnlibError,
error_type::{ErrorType, SwiftErrorType},
Expand Down
15 changes: 14 additions & 1 deletion libs/common/src/control.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Control protocol related module
//! Control protocol related module.
//!
//! This modules contains the logic for handling in and out messages through the control plane.
//! Handling of the message itself can be found in the other lib crates.
Expand Down Expand Up @@ -186,11 +186,21 @@ impl<T> PhoenixMessage<T> {
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
struct Empty {}

/// You can use this sender to send messages through a `PhoenixChannel`.
///
/// Messages won't be sent unless [PhoenixChannel::start] is running, internally
/// this sends messages through a future channel that are forwrarded then in [PhoenixChannel] event loop
pub struct PhoenixSender {
sender: Sender<Message>,
}

impl PhoenixSender {
/// Sends a message upstream to a connected [PhoenixChannel].
///
/// # Parameters
/// - topic: Phoenix topic
/// - event: Phoenix event
/// - payload: Message's payload
pub async fn send(
&mut self,
topic: impl Into<String>,
Expand All @@ -202,10 +212,13 @@ impl PhoenixSender {
Ok(())
}

/// Join a phoenix topic, meaning that after this method is invoked [PhoenixChannel] will
/// recieve messages from that topic, given that upstream accepts you into the given topic.
pub async fn join_topic(&mut self, topic: impl Into<String>) -> Result<()> {
self.send(topic, "phx_join", Empty {}).await
}

/// Closes the [PhoenixChannel]
pub async fn close(&mut self) -> Result<()> {
self.sender.send(Message::Close(None)).await?;
self.sender.close().await?;
Expand Down
1 change: 1 addition & 0 deletions libs/common/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Error module.
use base64::{DecodeError, DecodeSliceError};
use boringtun::noise::errors::WireGuardError;
use macros::SwiftEnum;
Expand Down
1 change: 1 addition & 0 deletions libs/common/src/error_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Module that contains the Error-Type that hints how to handle an error to upper layers.
use macros::SwiftEnum;
/// This indicates whether the produced error is something recoverable or fatal.
/// Fata/Recoverable only indicates how to handle the error for the client.
Expand Down
2 changes: 0 additions & 2 deletions libs/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
//! This includes types provided by external crates, i.e. [boringtun] to make sure that
//! we are using the same version across our own crates.
/// Erorrs module.
pub mod error;
/// Error types that hints how to handle an error for upper-layer libraries.
pub mod error_type;

mod session;
Expand Down
35 changes: 33 additions & 2 deletions libs/common/src/messages.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Message types that are used by both the gateway and client.
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

use serde::{Deserialize, Serialize};
Expand All @@ -8,37 +9,67 @@ mod key;

pub use key::Key;

// Sending Public key + Token in the query parameters when opening websocket

/// General type for handling portal's id (UUID v4)
pub type Id = Uuid;

/// Represents a wireguard peer.
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
pub struct Peer {
/// Keepalive: How often to send a keep alive message.
pub persistent_keepalive: Option<u16>,
/// Peer's public key.
pub public_key: Key,
/// Peer's Ipv4 (only 1 ipv4 per peer for now and mandatory).
pub ipv4: Ipv4Addr,
/// Peer's Ipv6 (only 1 ipv6 per peer for now and mandatory).
pub ipv6: Ipv6Addr,
/// Preshared key for the given peer.
pub preshared_key: Key,
}

/// Represent a connection request from a client to a given resource.
///
/// While this is a client-only message it's hosted in common since the tunnel
/// make use of this message type.
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct RequestConnection {
/// Resource id the request is for.
pub resource_id: Id,
/// The preshared key the client generated for the connection that it is trying to establish.
pub client_preshared_key: Key,
/// Client's local RTC Session Description that the client will use for this connection.
pub client_rtc_sdp: RTCSessionDescription,
}

/// Description of a resource from a client's perspective.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct ResourceDescription {
/// Resource's id.
pub id: Id,
/// Internal resource's domain name if any.
pub dns_name: Option<String>,
/// Resource's ipv4 mapping.
///
/// Note that this is not the actual ipv4 for the resource not even wireguard's ipv4 for the resource.
/// This is just the mapping we use internally between a resource and its ip for intercepting packets.
pub ipv4: Ipv4Addr,
/// Resource's ipv6 mapping.
///
/// Note that this is not the actual ipv6 for the resource not even wireguard's ipv6 for the resource.
/// This is just the mapping we use internally between a resource and its ip for intercepting packets.
pub ipv6: Ipv6Addr,
}

/// Represents a wireguard interface configuration.
///
/// Note that the ips are /32 for ipv4 and /128 for ipv6.
/// This is done to minimize collisions and we update the routing table manually.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct Interface {
/// Interface's Ipv4.
pub ipv4: Ipv4Addr,
/// Interface's Ipv6.
pub ipv6: Ipv6Addr,
/// DNS that will be used to query for DNS that aren't within our resource list.
pub upstream_dns: Vec<IpAddr>,
}
37 changes: 37 additions & 0 deletions libs/common/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,53 @@ use url::Url;

use crate::{control::PhoenixChannel, error_type::ErrorType, Error, Result};

// TODO: Not the most tidy trait for a control-plane.
/// Trait that represents a control-plane.
#[async_trait]
pub trait ControlSession<T, U> {
/// Start control-plane with the given private-key in the background.
async fn start(private_key: StaticSecret) -> Result<(Sender<T>, Receiver<U>)>;

/// Either "gateway" or "client" used to ge the control-plane URL.
fn mode() -> &'static str;
}

// TODO: Currently I'm using Session for both gateway and clients
// however, gateway could use the runtime directly and could make things easier
// so revisit this.
/// A session is the entry-point for connlib, mantains the runtime and the tunnel.
///
/// A session is created using [Session::connect], then to stop a session we use [Session::disconnect].
pub struct Session<T, U, V> {
runtime: Option<Runtime>,
_phantom: PhantomData<(T, U, V)>,
}

/// Resource list that will be displayed to the users.
pub struct ResourceList {
pub resources: Vec<String>,
}

/// Tunnel addresses to be surfaced to the client apps.
pub struct TunnelAddresses {
/// IPv4 Address.
pub address4: Ipv4Addr,
/// IPv6 Address.
pub address6: Ipv6Addr,
}

// Evaluate doing this not static
/// Traits that will be used by connlib to callback the client upper layers.
pub trait Callbacks {
/// Called when there's a change in the resource list.
fn on_update_resources(resource_list: ResourceList);
/// Called when the tunnel address is set.
fn on_set_tunnel_adresses(tunnel_addresses: TunnelAddresses);
/// Called when there's an error.
///
/// # Parameters
/// - `error`: The actual error that happened.
/// - `error_type`: Wether the error should terminate the session or not.
fn on_error(error: &Error, error_type: ErrorType);
}

Expand All @@ -63,6 +82,8 @@ where
U: for<'de> serde::Deserialize<'de> + std::fmt::Debug + Send + 'static,
V: serde::Serialize + Send + 'static,
{
/// Block on waiting for ctrl+c to terminate the runtime.
/// (Used for the gateways).
pub fn wait_for_ctrl_c(&mut self) -> Result<()> {
self.runtime
.as_ref()
Expand All @@ -73,6 +94,16 @@ where
})
}

/// Starts a session in the background.
///
/// This will:
/// 1. Create and start a tokio runtime
/// 2. Connect to the control plane to the portal
/// 3. Start the tunnel in the background and forward control plane messages to it.
///
/// The generic parameter `C` should implement all the handlers and that's how errors will be surfaced.
///
/// On a fatal error you should call `[Session::disconnect]` and start a new one.
pub fn connect<C: Callbacks>(portal_url: impl TryInto<Url>, token: String) -> Result<Self> {
// TODO: We could use tokio::runtime::current() to get the current runtime
// which could work with swif-rust that already runs a runtime. But IDK if that will work
Expand Down Expand Up @@ -145,6 +176,10 @@ where
})
}

/// Cleanup a [Session].
///
/// For now this just drops the runtime, which should drop all pending tasks.
/// Further cleanup should be done here. (Otherwise we can just drop [Session]).
pub fn disconnect(&mut self) -> bool {
// 1. Close the websocket connection
// 2. Free the device handle (UNIX)
Expand All @@ -161,10 +196,12 @@ where
true
}

/// TODO
pub fn bump_sockets(&self) -> bool {
true
}

/// TODO
pub fn disable_some_roaming_for_broken_mobile_semantics(&self) -> bool {
true
}
Expand Down
8 changes: 6 additions & 2 deletions libs/gateway/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
//! Main connlib library for gateway.
use control::ControlPlane;
use messages::EgressMessages;
use messages::IngressMessages;

mod control;
mod messages;

// IPv6 Min MTU = 1280
const VIRTUAL_IFACE_MTU: u16 = 1280;
const VIRTUAL_IFACE_MTU: u16 = 1420;

/// Session type for gateway.
///
/// For more information see libs_common docs on [Session][libs_common::Session].
pub type Session<C> = libs_common::Session<ControlPlane<C>, IngressMessages, EgressMessages>;

pub use libs_common::{error_type::ErrorType, Callbacks, Error, ResourceList, TunnelAddresses};
41 changes: 41 additions & 0 deletions libs/tunnel/src/control_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ where
));
}

/// Initiate an ice connection request.
///
/// Given a resource id and a list of relay creates a [RequestConnection]
/// and prepares the tunnel to handle the connection once initiated.
///
/// # Note
/// This function blocks until all ICE candidates are gathered so it might block for a long time.
///
/// # Parameters
/// - `resource_id`: Id of the resource we are going to request the connection to.
/// - `relays`: The list of relays used for that connection.
///
/// # Returns
/// A [RequestConnection] that should be sent to the gateway through the control-plane.
#[tracing::instrument(level = "trace", skip(self))]
pub async fn request_connection(
self: &Arc<Self>,
Expand Down Expand Up @@ -180,6 +194,14 @@ where
})
}

/// Called when a response to [Tunnel::request_connection] is ready.
///
/// Once this is called if everything goes fine a new tunnel should be started between the 2 peers.
///
/// # Parameters
/// - `resource_id`: Id of the resource that responded.
/// - `rtc_sdp`: Remote SDP.
/// - `gateway_public_key`: Public key of the gateway that is handling that resource for this connection.
#[tracing::instrument(level = "trace", skip(self))]
pub async fn recieved_offer_response(
self: &Arc<Self>,
Expand All @@ -200,6 +222,24 @@ where
Ok(())
}

/// Accept a connection request from a client.
///
/// Sets a connection to a remote SDP, creates the local SDP
/// and returns it.
///
/// # Note
///
/// This function blocks until it gathers all the ICE candidates
/// so it might block for a long time.
///
/// # Parameters
/// - `sdp_session`: Remote session description.
/// - `peer`: Configuration for the remote peer.
/// - `relays`: List of relays to use with this connection.
/// - `client_id`: UUID of the remote client.
///
/// # Returns
/// An [RTCSessionDescription] of the local sdp, with candidates gathered.
pub async fn set_peer_connection_request(
self: &Arc<Self>,
sdp_session: RTCSessionDescription,
Expand Down Expand Up @@ -254,6 +294,7 @@ where
Ok(local_desc)
}

/// Clean up a connection to a resource.
pub fn cleanup_connection(&self, resource_id: Id) {
self.awaiting_connection.lock().remove(&resource_id);
self.peer_connections.lock().remove(&resource_id);
Expand Down
Loading

0 comments on commit f1cf88f

Please sign in to comment.