Skip to content

Commit

Permalink
Update dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
madeye committed Dec 30, 2024
1 parent fc63e6f commit a426850
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 74 deletions.
19 changes: 11 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[package]
name = "qtun"
version = "0.2.0"
version = "0.3.0"
authors = ["Max Lv <[email protected]>"]
repository = "https://github.com/madeye/qtun"
repository = "https://github.com/shadowsocks/qtun"
license = "MIT"
edition = "2021"
edition = "2024"

[[bin]]
name = "qtun-client"
Expand All @@ -20,14 +20,17 @@ path = "src/server.rs"
tokio = { version = "1", features = ["full"] }
bytes = "1.2.1"
futures = "0.3"
rustls = "0.21.8"
rustls-pemfile = "1.0.2"
rustls-native-certs = "0.6.1"
webpki-roots = "0.25.2"
quinn = "0.10.2"
rustls = { version = "0.23.5", default-features = false, features = ["std"] }
rustls-pemfile = "2"
rustls-platform-verifier = "0.5"
rustls-pki-types = "1.7"
webpki-roots = "0.26.7"
quinn = "0.11.6"
quinn-proto = "0.11.9"
structopt = "0.3"
anyhow = "1.0"
tracing = "0.1"
log = "0.4"
env_logger = "0.10.0"
dirs = "5.0.1"
rustls-native-certs = "0.8.1"
23 changes: 10 additions & 13 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::net::SocketAddr;
use std::sync::Arc;

use quinn::crypto::rustls::QuicClientConfig;
use tokio::net::{TcpListener, TcpStream};

use anyhow::{anyhow, Result};
Expand Down Expand Up @@ -58,22 +59,15 @@ async fn main() -> Result<()> {
}
}

let mut roots = rustls::RootCertStore::empty();
let mut roots = rustls::RootCertStore {
roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
};

for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs") {
roots.add(&rustls::Certificate(cert.0)).unwrap();
for certs in rustls_native_certs::load_native_certs().expect("could not load platform certs") {
roots.add(certs).unwrap();
}

roots.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}));

let mut client_crypto = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(roots)
.with_no_client_auth();

Expand All @@ -85,7 +79,10 @@ async fn main() -> Result<()> {
} else {
Endpoint::client("[::]:0".parse().unwrap())
}?;
endpoint.set_default_client_config(quinn::ClientConfig::new(Arc::new(client_crypto)));
let client_config =
quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(client_crypto)?));

endpoint.set_default_client_config(client_config);

let remote = Arc::<SocketAddr>::from(relay_addr);
let host = Arc::<String>::from(host);
Expand Down
96 changes: 43 additions & 53 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use env_logger::Builder;
use futures::future::try_join;
use futures::TryFutureExt;
use log::LevelFilter;
use log::{debug, error, info};
use rustls_pemfile::Item;
use log::{error, info};
use quinn_proto::crypto::rustls::QuicServerConfig;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use structopt::{self, StructOpt};
use tokio::net::TcpStream;

Expand Down Expand Up @@ -50,6 +51,12 @@ struct Opt {
/// Specify the host to load TLS certificates from ~/.acme.sh/host
#[structopt(long = "acme-host")]
acme_host: Option<String>,
/// Client address to block
#[structopt(long = "block")]
block: Option<SocketAddr>,
/// Maximum number of concurrent connections to allow
#[structopt(long = "connection-limit")]
connection_limit: Option<usize>,
}

#[tokio::main]
Expand Down Expand Up @@ -99,82 +106,65 @@ async fn main() -> Result<()> {
info!("loading key: {:?}", key_path);

let key = fs::read(key_path.clone()).context("failed to read private key")?;
let key = if key_path.extension().map_or(false, |x| x == "der") {
debug!("private key with DER format");
rustls::PrivateKey(key)
let key = if key_path.extension().is_some_and(|x| x == "der") {
PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(key))
} else {
match rustls_pemfile::read_one(&mut &*key) {
Ok(x) => match x.unwrap() {
Item::RSAKey(key) => {
debug!("private key with PKCS #1 format");
rustls::PrivateKey(key)
}
Item::PKCS8Key(key) => {
debug!("private key with PKCS #8 format");
rustls::PrivateKey(key)
}
Item::ECKey(key) => {
debug!("private key with SEC1 format");
rustls::PrivateKey(key)
}
Item::X509Certificate(_) => {
anyhow::bail!("you should provide a key file instead of cert");
}
_ => {
anyhow::bail!("no private keys found");
}
},
Err(_) => {
anyhow::bail!("malformed private key");
}
}
rustls_pemfile::private_key(&mut &*key)
.context("malformed PKCS #1 private key")?
.ok_or_else(|| anyhow::Error::msg("no private keys found"))?
};

let certs = fs::read(cert_path.clone()).context("failed to read certificate chain")?;
let certs = if cert_path.extension().map_or(false, |x| x == "der") {
vec![rustls::Certificate(certs)]
let certs = if cert_path.extension().is_some_and(|x| x == "der") {
vec![CertificateDer::from(certs)]
} else {
rustls_pemfile::certs(&mut &*certs)
.collect::<Result<_, _>>()
.context("invalid PEM-encoded certificate")?
.into_iter()
.map(rustls::Certificate)
.collect()
};

let mut server_crypto = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, key)?;
server_crypto.alpn_protocols = common::ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect();

let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(server_crypto));
Arc::get_mut(&mut server_config.transport)
.unwrap()
.max_concurrent_uni_streams(0_u8.into())
.congestion_controller_factory(Arc::new(quinn::congestion::BbrConfig::default()));

if options.stateless_retry {
server_config.use_retry(true);
}
let mut server_config =
quinn::ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(server_crypto)?));
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
transport_config.max_concurrent_uni_streams(0_u8.into());

let remote = Arc::<SocketAddr>::from(relay_addr);

let endpoint = quinn::Endpoint::server(server_config, listen_addr)?;
eprintln!("listening on {}", endpoint.local_addr()?);

while let Some(conn) = endpoint.accept().await {
info!("connection incoming");
tokio::spawn(
handle_connection(remote.clone(), conn).unwrap_or_else(move |e| {
error!("connection failed: {reason}", reason = e.to_string())
}),
);
if options
.connection_limit
.is_some_and(|n| endpoint.open_connections() >= n)
{
info!("refusing due to open connection limit");
conn.refuse();
} else if Some(conn.remote_address()) == options.block {
info!("refusing blocked client IP address");
conn.refuse();
} else if options.stateless_retry && !conn.remote_address_validated() {
info!("requiring connection to validate its address");
conn.retry().unwrap();
} else {
info!("accepting connection");
let fut = handle_connection(remote.clone(), conn);
tokio::spawn(async move {
if let Err(e) = fut.await {
error!("connection failed: {reason}", reason = e.to_string())
}
});
}
}

Ok(())
}

async fn handle_connection(remote: Arc<SocketAddr>, conn: quinn::Connecting) -> Result<()> {
async fn handle_connection(remote: Arc<SocketAddr>, conn: quinn::Incoming) -> Result<()> {
let bi_streams = conn.await?;

async {
Expand Down

0 comments on commit a426850

Please sign in to comment.