feat(connection): rebrand to snownet (#3435)

`firezone-connection` was a working title that I never really quite
liked. Here is a proposal to rebrand it to `snownet`. That is a lot more
concise and derived from the fact that we are established a network of
connections using ICE.
This commit is contained in:
Thomas Eizinger
2024-01-30 16:54:00 -08:00
committed by GitHub
parent b2d7b95091
commit 6a33516460
25 changed files with 114 additions and 116 deletions

View File

@@ -25,9 +25,9 @@ jobs:
- runs-on: ubuntu-22.04
packages: # Intentionally blank as a package catch-all linter
- runs-on: macos-13
packages: -p connlib-client-apple -p firezone-connection
packages: -p connlib-client-apple -p snownet
- runs-on: windows-2022
packages: -p connlib-client-shared -p firezone-windows-client -p firezone-connection
packages: -p connlib-client-shared -p firezone-windows-client -p snownet
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
@@ -47,17 +47,17 @@ jobs:
# TODO: https://github.com/rust-lang/cargo/issues/5220
include:
- runs-on: ubuntu-20.04
packages: -p firezone-linux-client -p firezone-gateway -p connlib-client-android -p firezone-connection
packages: -p firezone-linux-client -p firezone-gateway -p connlib-client-android -p snownet
- runs-on: ubuntu-22.04
packages: -p firezone-linux-client -p firezone-gateway -p connlib-client-android -p firezone-connection
packages: -p firezone-linux-client -p firezone-gateway -p connlib-client-android -p snownet
- runs-on: macos-12
packages: -p connlib-client-apple -p firezone-connection
packages: -p connlib-client-apple -p snownet
- runs-on: macos-13
packages: -p connlib-client-apple -p firezone-connection
packages: -p connlib-client-apple -p snownet
- runs-on: windows-2019
packages: -p firezone-windows-client -p connlib-client-shared -p firezone-connection
packages: -p firezone-windows-client -p connlib-client-shared -p snownet
- runs-on: windows-2022
packages: -p firezone-windows-client -p connlib-client-shared -p firezone-connection
packages: -p firezone-windows-client -p connlib-client-shared -p snownet
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4

View File

@@ -63,11 +63,11 @@ jobs:
context: rust
build-args: |
PACKAGE=firezone-linux-client
- image_name: connection-tests
- image_name: snownet-tests
target: debug
context: rust
build-args: |
PACKAGE=firezone-connection-tests
PACKAGE=snownet-tests
- image_name: elixir
target: compiler
context: elixir
@@ -139,7 +139,7 @@ jobs:
target: ${{ matrix.target }}
tags: ${{ steps.build_docker_tags.outputs.tags }}
connection-integration-tests:
snownet-integration-tests:
needs: build-images
runs-on: ubuntu-22.04
permissions:
@@ -165,7 +165,7 @@ jobs:
- name: Run ${{ matrix.file }} test
run: |
sudo sysctl -w vm.overcommit_memory=1
timeout 600 docker compose -f rust/connection-tests/${{ matrix.file }} up --exit-code-from dialer --abort-on-container-exit
timeout 600 docker compose -f rust/snownet-tests/${{ matrix.file }} up --exit-code-from dialer --abort-on-container-exit
integration-tests:
needs: build-images

84
rust/Cargo.lock generated
View File

@@ -1971,48 +1971,6 @@ dependencies = [
"url",
]
[[package]]
name = "firezone-connection"
version = "1.0.0"
dependencies = [
"anyhow",
"boringtun",
"bytecodec",
"bytes",
"firezone-relay",
"once_cell",
"pnet_packet",
"rand 0.8.5",
"secrecy",
"str0m",
"stun_codec",
"thiserror",
"tracing",
]
[[package]]
name = "firezone-connection-tests"
version = "1.0.0"
dependencies = [
"anyhow",
"boringtun",
"firezone-connection",
"futures",
"hex",
"pnet_packet",
"rand 0.8.5",
"redis 0.24.0",
"redis-macros",
"secrecy",
"serde",
"serde-hex",
"serde_json",
"system-info",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "firezone-gateway"
version = "1.0.0"
@@ -5981,6 +5939,48 @@ dependencies = [
"serde",
]
[[package]]
name = "snownet"
version = "1.0.0"
dependencies = [
"anyhow",
"boringtun",
"bytecodec",
"bytes",
"firezone-relay",
"once_cell",
"pnet_packet",
"rand 0.8.5",
"secrecy",
"str0m",
"stun_codec",
"thiserror",
"tracing",
]
[[package]]
name = "snownet-tests"
version = "1.0.0"
dependencies = [
"anyhow",
"boringtun",
"futures",
"hex",
"pnet_packet",
"rand 0.8.5",
"redis 0.24.0",
"redis-macros",
"secrecy",
"serde",
"serde-hex",
"serde_json",
"snownet",
"system-info",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "socket2"
version = "0.4.10"

View File

@@ -5,11 +5,11 @@ members = [
"connlib/clients/shared",
"connlib/shared",
"connlib/tunnel",
"connlib/connection",
"connlib/snownet",
"gateway",
"linux-client",
"firezone-cli-utils",
"connection-tests",
"snownet-tests",
"phoenix-channel",
"relay",
"windows-client/src-tauri",
@@ -40,7 +40,7 @@ firezone-gateway = { path = "gateway"}
firezone-linux-client = { path = "linux-client"}
firezone-windows-client = { path = "windows-client/src-tauri"}
firezone-cli-utils = { path = "firezone-cli-utils"}
firezone-connection = { path = "connlib/connection"}
snownet = { path = "connlib/snownet"}
firezone-relay = { path = "relay"}
connlib-shared = { path = "connlib/shared"}
firezone-tunnel = { path = "connlib/tunnel"}

View File

@@ -1,14 +0,0 @@
mod allocation;
mod channel_data;
mod index;
mod info;
mod ip_packet;
mod pool;
mod stun_binding;
pub use info::ConnectionInfo;
pub use ip_packet::IpPacket;
pub use pool::{
Answer, ClientConnectionPool, ConnectionPool, Credentials, Error, Event, Offer,
ServerConnectionPool, Transmit,
};

View File

@@ -1,5 +1,5 @@
[package]
name = "firezone-connection"
name = "snownet"
# mark:automatic-version
version = "1.0.0"
edition = "2021"

View File

@@ -0,0 +1,4 @@
# snownet
`snownet` is a SANS-IO connectivity library built on top of ICE (brr cold) and wireguard.
In case direct connectivity cannot be established, TURN servers are used as a fallback.

View File

@@ -1,4 +1,4 @@
use crate::pool::Transmit;
use crate::node::Transmit;
use bytecodec::{DecodeExt as _, EncodeExt as _};
use rand::random;
use std::{

View File

@@ -1,4 +1,4 @@
use crate::pool::WIREGUARD_KEEP_ALIVE;
use crate::node::WIREGUARD_KEEP_ALIVE;
use std::time::Instant;
#[derive(Debug)]

View File

@@ -0,0 +1,11 @@
mod allocation;
mod channel_data;
mod index;
mod info;
mod ip_packet;
mod node;
mod stun_binding;
pub use info::ConnectionInfo;
pub use ip_packet::IpPacket;
pub use node::{Answer, ClientNode, Credentials, Error, Event, Node, Offer, ServerNode, Transmit};

View File

@@ -37,14 +37,15 @@ pub(crate) const WIREGUARD_KEEP_ALIVE: u16 = 5;
const MAX_UDP_SIZE: usize = (1 << 16) - 1;
/// Manages a set of wireguard connections for a server.
pub type ServerConnectionPool<TId> = ConnectionPool<Server, TId>;
pub type ServerNode<TId> = Node<Server, TId>;
/// Manages a set of wireguard connections for a client.
pub type ClientConnectionPool<TId> = ConnectionPool<Client, TId>;
pub type ClientNode<TId> = Node<Client, TId>;
pub enum Server {}
pub enum Client {}
pub struct ConnectionPool<T, TId> {
/// A node within a `snownet` network maintains connections to several other nodes.
pub struct Node<T, TId> {
private_key: StaticSecret,
index: IndexLfsr,
rate_limiter: Arc<RateLimiter>,
@@ -81,7 +82,7 @@ pub enum Error {
NotConnected,
}
impl<T, TId> ConnectionPool<T, TId>
impl<T, TId> Node<T, TId>
where
TId: Eq + Hash + Copy + fmt::Display,
{
@@ -412,7 +413,7 @@ where
self.pending_events.pop_front()
}
/// Returns, when [`ConnectionPool::handle_timeout`] should be called next.
/// Returns, when [`Node::handle_timeout`] should be called next.
///
/// This function only takes `&mut self` because it caches certain computations internally.
/// The returned timestamp will **not** change unless other state is modified.
@@ -429,7 +430,7 @@ where
earliest(connection_timeout, self.next_rate_limiter_reset)
}
/// Advances time within the [`ConnectionPool`].
/// Advances time within the [`Node`].
///
/// This advances time within the ICE agent, updates timers within all wireguard connections as well as resets wireguard's rate limiter (if necessary).
pub fn handle_timeout(&mut self, now: Instant) {
@@ -547,7 +548,7 @@ where
}
}
impl<TId> ConnectionPool<Client, TId>
impl<TId> Node<Client, TId>
where
TId: Eq + Hash + Copy + fmt::Display,
{
@@ -605,7 +606,7 @@ where
params
}
/// Accept an [`Answer`] from the remote for a connection previously created via [`ConnectionPool::new_connection`].
/// Accept an [`Answer`] from the remote for a connection previously created via [`Node::new_connection`].
pub fn accept_answer(&mut self, id: TId, remote: PublicKey, answer: Answer) {
let Some(initial) = self.initial_connections.remove(&id) else {
return; // TODO: Better error handling
@@ -629,7 +630,7 @@ where
}
}
impl<TId> ConnectionPool<Server, TId>
impl<TId> Node<Server, TId>
where
TId: Eq + Hash + Copy + fmt::Display,
{
@@ -690,7 +691,7 @@ where
}
}
impl<T, TId> ConnectionPool<T, TId>
impl<T, TId> Node<T, TId>
where
TId: Eq + Hash + Copy + fmt::Display,
{

View File

@@ -1,4 +1,4 @@
use crate::pool::Transmit;
use crate::node::Transmit;
use bytecodec::{DecodeExt, EncodeExt};
use std::{
collections::VecDeque,

View File

@@ -1,5 +1,5 @@
use boringtun::x25519::StaticSecret;
use firezone_connection::{ClientConnectionPool, Event};
use snownet::{ClientNode, Event};
use std::{
collections::HashSet,
time::{Duration, Instant},
@@ -10,7 +10,7 @@ fn connection_times_out_after_10_seconds() {
let start = Instant::now();
let mut alice =
ClientConnectionPool::<u64>::new(StaticSecret::random_from_rng(rand::thread_rng()), start);
ClientNode::<u64>::new(StaticSecret::random_from_rng(rand::thread_rng()), start);
let _ = alice.new_connection(1, HashSet::new(), HashSet::new());
alice.handle_timeout(start + Duration::from_secs(10));

View File

@@ -1,5 +1,5 @@
[package]
name = "firezone-connection-tests"
name = "snownet-tests"
# mark:automatic-version
version = "1.0.0"
edition = "2021"
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
anyhow = "1"
boringtun = { workspace = true }
firezone-connection = { workspace = true }
snownet = { workspace = true }
futures = "0.3"
hex = "0.4"
pnet_packet = { version = "0.34" }

View File

@@ -1,6 +1,6 @@
# firezone-connection integration tests
# snownet integration tests
This directory contains Docker-based integration tests for the `firezone-connection` crate.
This directory contains Docker-based integration tests for the `snownet` crate.
Each integration test setup is a dedicated docker-compose file.
## Running

View File

@@ -7,7 +7,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -24,7 +24,7 @@ services:
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/lan-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."lan-integration-test_app".IPAddress')
firezone-connection-tests
snownet-tests
depends_on:
- redis
networks:
@@ -37,7 +37,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -54,7 +54,7 @@ services:
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/lan-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."lan-integration-test_app".IPAddress')
firezone-connection-tests
snownet-tests
depends_on:
- redis
networks:

View File

@@ -10,7 +10,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -32,7 +32,7 @@ services:
export STUN_SERVER=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-hp-integration-test-relay-1/json | jq -r '.NetworkSettings.Networks."wan-hp-integration-test_wan".IPAddress')
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-hp-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."wan-hp-integration-test_wan".IPAddress')
firezone-connection-tests
snownet-tests
depends_on:
- dialer_router
- redis
@@ -56,7 +56,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -77,7 +77,7 @@ services:
export STUN_SERVER=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-hp-integration-test-relay-1/json | jq -r '.NetworkSettings.Networks."wan-hp-integration-test_wan".IPAddress')
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-hp-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."wan-hp-integration-test_wan".IPAddress')
firezone-connection-tests
snownet-tests
cap_add:
- NET_ADMIN
depends_on:

View File

@@ -10,7 +10,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -32,7 +32,7 @@ services:
export TURN_SERVER=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-relay-integration-test-relay-1/json | jq -r '.NetworkSettings.Networks."wan-relay-integration-test_wan".IPAddress')
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-relay-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."wan-relay-integration-test_wan".IPAddress')
firezone-connection-tests
snownet-tests
depends_on:
- dialer_router
- redis
@@ -58,7 +58,7 @@ services:
target: debug
context: ..
args:
PACKAGE: firezone-connection-tests
PACKAGE: snownet-tests
cache_from:
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/connection-tests:main
image: us-east1-docker.pkg.dev/firezone-staging/firezone/connection-tests:${VERSION:-main}
@@ -79,7 +79,7 @@ services:
export TURN_SERVER=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-relay-integration-test-relay-1/json | jq -r '.NetworkSettings.Networks."wan-relay-integration-test_wan".IPAddress')
export REDIS_HOST=$$(curl --fail --silent --unix-socket /var/run/docker.sock http://localhost/containers/wan-relay-integration-test-redis-1/json | jq -r '.NetworkSettings.Networks."wan-relay-integration-test_wan".IPAddress')
firezone-connection-tests
snownet-tests
cap_add:
- NET_ADMIN
depends_on:

View File

@@ -8,14 +8,11 @@ use std::{
use anyhow::{bail, Context as _, Result};
use boringtun::x25519::{PublicKey, StaticSecret};
use firezone_connection::{
Answer, ClientConnectionPool, ConnectionPool, Credentials, IpPacket, Offer,
ServerConnectionPool,
};
use futures::{channel::mpsc, future::BoxFuture, FutureExt, SinkExt, StreamExt};
use pnet_packet::{ip::IpNextHeaderProtocols, ipv4::Ipv4Packet};
use redis::{aio::MultiplexedConnection, AsyncCommands};
use secrecy::{ExposeSecret as _, Secret};
use snownet::{Answer, ClientNode, Credentials, IpPacket, Node, Offer, ServerNode};
use tokio::{io::ReadBuf, net::UdpSocket};
use tracing_subscriber::EnvFilter;
@@ -25,8 +22,7 @@ const MAX_UDP_SIZE: usize = (1 << 16) - 1;
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::builder()
.parse("info,boringtun=debug,str0m=debug,firezone_connection=debug")?,
EnvFilter::builder().parse("info,boringtun=debug,str0m=debug,snownet=debug")?,
)
.init();
@@ -80,7 +76,7 @@ async fn main() -> Result<()> {
match role {
Role::Dialer => {
let mut pool = ClientConnectionPool::<u64>::new(private_key, Instant::now());
let mut pool = ClientNode::<u64>::new(private_key, Instant::now());
pool.add_local_interface(socket_addr);
let offer = pool.new_connection(
@@ -163,7 +159,7 @@ async fn main() -> Result<()> {
}
}
Role::Listener => {
let mut pool = ServerConnectionPool::<u64>::new(private_key, Instant::now());
let mut pool = ServerNode::<u64>::new(private_key, Instant::now());
pool.add_local_interface(socket_addr);
let offer = redis_connection
@@ -336,7 +332,7 @@ impl FromStr for Role {
struct Eventloop<T> {
socket: UdpSocket,
pool: ConnectionPool<T, u64>,
pool: Node<T, u64>,
timeout: BoxFuture<'static, Instant>,
candidate_rx: mpsc::Receiver<wire::Candidate>,
read_buffer: Box<[u8; MAX_UDP_SIZE]>,
@@ -346,7 +342,7 @@ struct Eventloop<T> {
impl<T> Eventloop<T> {
fn new(
socket: UdpSocket,
pool: ConnectionPool<T, u64>,
pool: Node<T, u64>,
candidate_rx: mpsc::Receiver<wire::Candidate>,
) -> Self {
Self {
@@ -379,7 +375,7 @@ impl<T> Eventloop<T> {
}
match self.pool.poll_event() {
Some(firezone_connection::Event::SignalIceCandidate {
Some(snownet::Event::SignalIceCandidate {
connection,
candidate,
}) => {
@@ -388,10 +384,10 @@ impl<T> Eventloop<T> {
candidate,
}))
}
Some(firezone_connection::Event::ConnectionEstablished(conn)) => {
Some(snownet::Event::ConnectionEstablished(conn)) => {
return Poll::Ready(Ok(Event::ConnectionEstablished { conn }))
}
Some(firezone_connection::Event::ConnectionFailed(conn)) => {
Some(snownet::Event::ConnectionFailed(conn)) => {
return Poll::Ready(Ok(Event::ConnectionFailed { conn }))
}
None => {}