Skip to content

Commit

Permalink
Establish an MSRV and add a CI test to ensure compatibility (#44)
Browse files Browse the repository at this point in the history
adding CI tests for msrv
  • Loading branch information
jmwample authored May 15, 2024
1 parent 02135f7 commit 51381b3
Show file tree
Hide file tree
Showing 15 changed files with 132 additions and 72 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,25 @@ jobs:
- uses: dtolnay/rust-toolchain@nightly
- run: cargo test --workspace --all-targets

msrv:
name: Check Crates against MSRV
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Re-resolve Cargo.lock with minimal versions
- uses: dtolnay/rust-toolchain@nightly
- run: cargo update -Z minimal-versions
# Now check that `cargo build` works with respect to the oldest possible
# deps and the stated MSRV. 1.70 should work for all
- uses: dtolnay/[email protected]
- run: cargo test --workspace --all-targets --all-features
# Also make sure the AVX2 build works
- run: cargo build --target x86_64-unknown-linux-gnu
# The PTRS crate has fewer dependencies and a lower msrv
- uses: dtolnay/[email protected]
- run: cargo test -p ptrs --all-targets --all-features
- run: cargo build -p ptrs --target x86_64-unknown-linux-gnu

build:
name: Build
needs: format
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

members = [
"crates/lyrebird",
"crates/o5",
# "crates/o5",
"crates/o7",
"crates/obfs4",
"crates/ptrs",
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,23 @@ This repository contains multiple related crates implementing the lyrebird (obfs
lyrebird binary, and Pluggable Transports in Rust (PTRS) library.


| Crate | Description | Crates.io | Docs |
-------------------------------------------|----------------|-----------|------|
| [`ptrs`](./crates/ptrs) | A library supporting implementation and integration of Pluggable Transport protocols. | [![](https://img.shields.io/crates/v/ptrs.svg)](https://crates.io/crates/ptrs) | [![](https://img.shields.io/docsrs/ptrs)](https://docs.rs/ptrs) |
| [`lyrebird`](./crates/lyrebird) | Implementation of the `Lyrebird` Tor bridge and a forward proxy compatible with `ptrs`. | [![](https://img.shields.io/crates/v/lyrebird.svg)](https://crates.io/crates/lyrebird) | [![](https://docs.rs/lyrebird/badge.svg)](https://docs.rs/lyrebird) |
| [`obfs4`](./crates/obfs4) | An implementation of obfs4 pluggable transport library in pure rust. | [![](https://img.shields.io/crates/v/obfs4.svg)](https://crates.io/crates/obfs4) | [![](https://docs.rs/obfs4/badge.svg)](https://docs.rs/obfs4) |
| Crate | Description | Crates.io | Docs | MSRV |
-------------------------------------------|----------------|-----------|------|------|
| [`ptrs`](./crates/ptrs) | A library supporting implementation and integration of Pluggable Transport protocols. | [![](https://img.shields.io/crates/v/ptrs.svg)](https://crates.io/crates/ptrs) | [![](https://img.shields.io/docsrs/ptrs)](https://docs.rs/ptrs) | 1.63 |
| [`lyrebird`](./crates/lyrebird) | Implementation of the `Lyrebird` Tor bridge and a forward proxy compatible with `ptrs`. | [![](https://img.shields.io/crates/v/lyrebird.svg)](https://crates.io/crates/lyrebird) | [![](https://docs.rs/lyrebird/badge.svg)](https://docs.rs/lyrebird) | 1.70 |
| [`obfs4`](./crates/obfs4) | An implementation of obfs4 pluggable transport library in pure rust. | [![](https://img.shields.io/crates/v/obfs4.svg)](https://crates.io/crates/obfs4) | [![](https://docs.rs/obfs4/badge.svg)](https://docs.rs/obfs4) | 1.70 |

## MSRV

The planned Minimum Supported Rust Version (MSRV) is 1.60, however there is no
current testing to ensure that this is working currently.
The Minimum Supported Rust Versions (MSRV) for the various crates are listed above.
These are ensured by test and build steps in the CI pipeline.

MSRV can be changed in the future, but it will be done with a minor version bump.
We will not increase MSRV on PATCH releases, though downstream dependencies might.

We won't increase MSRV just because we can: we'll only do so when we have a
reason. (We don't guarantee that you'll agree with our reasoning; only that
it will exist.)

## Related

Expand Down
4 changes: 2 additions & 2 deletions crates/lyrebird/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ obfs4 = { path="../obfs4", version="0.1.0" }

# fwd deps
anyhow = "1.0"
clap = { version = "4.4.7", features = ["derive"]}
clap = { version = "4.4", features = ["derive"]}
fast-socks5 = "0.9.1"
futures = "0.3.29"
safelog = "0.3.5"
thiserror = "1.0.56"
tokio = { version = "1.33", features = ["io-util", "net", "macros", "sync", "signal"] }
tokio = { version = "1.34", features = ["io-util", "net", "macros", "sync", "signal"] }
tokio-util = "0.7.10"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
Expand Down
33 changes: 24 additions & 9 deletions crates/lyrebird/src/fwd/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use tokio::net::TcpStream;

use std::net::SocketAddr;
use std::ops::Deref;
use std::pin::Pin;
use std::sync::Arc;

pub(crate) trait Backend {
Expand All @@ -15,7 +16,8 @@ pub(crate) trait Backend {
&self,
conn: In,
client_addr: SocketAddr,
) -> impl Future<Output = Result<()>> + Send + Sync
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + Sync + '_>>
// ) -> impl Future<Output = Result<()>> + Send + Sync
where
In: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static;
}
Expand Down Expand Up @@ -54,6 +56,21 @@ impl Backends {
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct BackendArc(Arc<Backends>);

impl BackendArc {
async fn handle_internal<In>(&self, conn: In, client_addr: SocketAddr) -> Result<()>
where
In: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
{
match self.0.as_ref() {
Backends::Echo => server_echo_connection(conn, client_addr).await?,
Backends::Fwd { dst } => server_fwd_connection(conn, dst.parse()?, client_addr).await?,
Backends::Socks { auth: _ } => todo!("not yet implemented"),
}

Ok(())
}
}

impl Deref for BackendArc {
type Target = Backends;
fn deref(&self) -> &Self::Target {
Expand All @@ -62,17 +79,15 @@ impl Deref for BackendArc {
}

impl Backend for BackendArc {
async fn handle<In>(&self, conn: In, client_addr: SocketAddr) -> Result<()>
fn handle<In>(
&self,
conn: In,
client_addr: SocketAddr,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + Sync + '_>>
where
In: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static,
{
match self.0.as_ref() {
Backends::Echo => server_echo_connection(conn, client_addr).await?,
Backends::Fwd { dst } => server_fwd_connection(conn, dst.parse()?, client_addr).await?,
Backends::Socks { auth: _ } => todo!("not yet implemented"),
}

Ok(())
Box::pin(self.handle_internal(conn, client_addr))
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/lyrebird/src/fwd/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ async fn client_accept_loop<C>(
) -> Result<()>
where
// the provided client builder should build the C ClientTransport.
C: ptrs::ClientTransport<TcpStream, std::io::Error> + 'static,
C: ptrs::ClientTransport<TcpStream, std::io::Error> + Send + 'static,
{
let pt_name = C::method_name();
let builder = builder.options(&params)?;
Expand Down
4 changes: 2 additions & 2 deletions crates/lyrebird/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ async fn client_accept_loop<C>(
) -> Result<()>
where
// the provided client builder should build the C ClientTransport.
C: ptrs::ClientTransport<TcpStream, std::io::Error> + 'static,
C: ptrs::ClientTransport<TcpStream, std::io::Error> + Send + 'static,
{
let pt_name = C::method_name();
loop {
Expand Down Expand Up @@ -351,7 +351,7 @@ where
// the provided T must be usable as a connection in an async context
In: AsyncRead + AsyncWrite + Send + Unpin,
// the provided client builder should build the C ClientTransport.
C: ptrs::ClientTransport<TcpStream, std::io::Error>,
C: ptrs::ClientTransport<TcpStream, std::io::Error> + Send,
{
let mut config: fast_socks5::server::Config<SimpleUserPassword> =
fast_socks5::server::Config::default();
Expand Down
2 changes: 1 addition & 1 deletion crates/o5/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rand = { version="0.8.5", features=["getrandom"]}
rand_core = "0.6.4"

subtle = "2.5.0"
x25519-dalek = { version = "2", features = ["static_secrets", "getrandom", "reusable_secrets", "elligator2"], git = "https://github.com/jmwample/curve25519-dalek.git", branch = "elligator2-ntor"}
x25519-dalek = { version = "2.0.1", features = ["static_secrets", "getrandom", "reusable_secrets", "elligator2"], git = "https://github.com/jmwample/curve25519-dalek.git", branch = "elligator2-ntor"}

# ntor_arti
zeroize = "1.7.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/o7/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ ptrs = { path="../ptrs", version="0.1.0" }

## Networking tools
tokio = { version = "1.33", features = ["io-util", "rt-multi-thread", "net", "rt", "macros", "sync", "signal", "time", "fs"] }
tokio-util = { version = "0.7.10", features = ["codec", "io", "net"]}
# tokio-util = { version = "0.7.10", features = ["codec", "io", "net"]}
19 changes: 10 additions & 9 deletions crates/obfs4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ hmac = { version="0.12.1", features=["reset"]}
hkdf = "0.12.3"
crypto_secretbox = { version="0.1.1", features=["salsa20"]}
subtle = "2.5.0"
x25519-dalek = { version = "2", features = ["static_secrets", "getrandom", "reusable_secrets", "elligator2"], git = "https://github.com/jmwample/curve25519-dalek.git", branch = "elligator2-ntor"}
x25519-dalek = { version = "2.0.1", features = ["static_secrets", "getrandom", "reusable_secrets", "elligator2"], git = "https://github.com/jmwample/curve25519-dalek.git", branch = "elligator2-ntor"}

## Utils
hex = "0.4.3"
Expand All @@ -49,7 +49,7 @@ serde = "1.0.197"
## Networking tools
pin-project = "1.1.3"
futures = "0.3.29"
tokio = { version = "1.33", features = ["io-util", "rt-multi-thread", "net", "rt", "macros", "sync", "signal", "time", "fs"] }
tokio = { version = "1.34", features = ["io-util", "rt-multi-thread", "net", "rt", "macros", "sync", "signal", "time", "fs"] }
tokio-util = { version = "0.7.10", features = ["codec", "io"]}
bytes = "1.5.0"

Expand All @@ -62,13 +62,13 @@ cipher = "0.4.4"
zeroize = "1.7.0"
thiserror = "1.0.56"

# fwd
fast-socks5 = "0.9.1"
url = "2.5.0"
anyhow = "1.0"
tracing-subscriber = "0.3.18"
clap = { version = "4.4.7", features = ["derive"]}
safelog = { version = "0.3.5" }
## transitive dependencies that break things when versions are too low
## i.e. any lower than the exact versions here.
curve25519-dalek = { version="4.1.2", optional=true}
anyhow = { version="1.0.20", optional=true}
async-trait = { version="0.1.9", optional=true}
num-bigint = { version="0.4.2", optional=true}
simple_asn1 = { version="0.6.1", optional=true}

## Maybe useful in future iterations
# tor-socksproto = { version = "0.10.0" }
Expand All @@ -83,3 +83,4 @@ tor-basic-utils = "0.18.0"
# o5 pqc test
# pqc_kyber = {version="0.7.1", features=["kyber1024", "std"]}
# ml-kem = "0.1.0"

4 changes: 2 additions & 2 deletions crates/obfs4/src/sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(crate) struct Established;
/// The session broke due to something like a timeout, reset, lost connection, etc.
trait Fault {}

pub enum Session {
pub(crate) enum Session {
Client(ClientSession<Established>),
Server(ServerSession<Established>),
}
Expand Down Expand Up @@ -140,7 +140,7 @@ impl<S: ClientSessionState> ClientSession<S> {
}
}

pub fn new_client_session(
pub(crate) fn new_client_session(
station_pubkey: Obfs4NtorPublicKey,
iat_mode: IAT,
) -> ClientSession<Initialized> {
Expand Down
51 changes: 26 additions & 25 deletions crates/obfs4/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,34 +254,35 @@ async fn transfer_512k_x1() -> Result<()> {
let (mut r, mut w) = tokio::io::split(o4c_stream);

tokio::spawn(async move {
let msg = [0_u8; 1024 * 512];
w.write_all(&msg)
.await
.unwrap_or_else(|_| panic!("failed on write"));
w.flush().await.unwrap();
});

let expected_total = 1024 * 512;
let mut buf = vec![0_u8; 1024 * 1024];
let mut received: usize = 0;
let mut i = 0;
while received < expected_total {
debug!("client read: {i} / {received}");
tokio::select! {
res = r.read(&mut buf) => {
received += res?;
}
_ = tokio::time::sleep(std::time::Duration::from_millis(2000)) => {
panic!("client failed to read after {i} iterations: timeout");
let expected_total = 1024 * 512;
let mut buf = vec![0_u8; 1024 * 513];
let mut received: usize = 0;
let mut i = 0;
while received < expected_total {
debug!("client read: {i} / {received}");
tokio::select! {
res = r.read(&mut buf) => {
received += res.unwrap();
}
_ = tokio::time::sleep(std::time::Duration::from_millis(2000)) => {
panic!("client failed to read after {i} iterations: timeout");
}
}
i += 1;
}
i += 1;
}

assert_eq!(
received, expected_total,
"incorrect amount received {received} != {expected_total}"
);
assert_eq!(
received, expected_total,
"incorrect amount received {received} != {expected_total}"
);
});

let msg = [0_u8; 1024 * 512];
w.write_all(&msg)
.await
.unwrap_or_else(|_| panic!("failed on write"));
w.flush().await?;

Ok(())
}

Expand Down
4 changes: 2 additions & 2 deletions crates/ptrs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "ptrs"
version = "0.1.0"
edition = "2021"
authors = ["Jack Wampler <[email protected]>"]
rust-version = "1.70"
rust-version = "1.63"
license = "MIT OR Apache-2.0"
description = "Interdaces and utilities supporting pluggable transport implementations"
keywords = ["tor", "censorship", "pluggable", "transports"]
Expand All @@ -24,7 +24,7 @@ futures = "0.3.30"
itertools = "0.12.1"
subtle = "2.5.0"
thiserror = "1"
tokio = { version = "1.33", features = ["full"] }
tokio = { version = "1.34", features = ["full"] }
tracing = "0.1.40"
url = "2.5.0"

Expand Down
Loading

0 comments on commit 51381b3

Please sign in to comment.