Skip to content

Commit

Permalink
Update qtun to 0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
madeye committed Dec 11, 2021
1 parent 3b8636e commit 492af31
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 43 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "qtun"
version = "0.1.0"
version = "0.2.0"
authors = ["Max Lv <max.c.lv@gmail.com>"]
repository = "https://github.com/madeye/qtun"
license = "MIT"
Expand All @@ -17,10 +17,13 @@ path = "src/server.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = { version = "^0.2.7", features = ["full"] }
tokio = { version = "1", features = ["full"] }
bytes = "0.5"
futures = "0.3"
quinn = "0.6"
rustls = "0.20"
rustls-pemfile = "0.2.1"
rustls-native-certs = "0.6.1"
quinn = "0.8"
structopt = "0.3"
anyhow = "1.0"
tracing = "0.1"
Expand Down
29 changes: 19 additions & 10 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::net::SocketAddr;
use std::sync::Arc;

use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;

use anyhow::{anyhow, Result};
use futures::future::try_join;
Expand All @@ -13,7 +12,8 @@ use structopt::{self, StructOpt};
use env_logger::Builder;
use log::LevelFilter;

use qtun::args;
mod args;
mod common;

#[derive(StructOpt, Debug)]
#[structopt(name = "qtun-client")]
Expand Down Expand Up @@ -55,19 +55,28 @@ async fn main() -> Result<()> {
}
}

let mut endpoint = quinn::Endpoint::builder();
let client_config = quinn::ClientConfigBuilder::default();
endpoint.default_client_config(client_config.build());
let mut roots = rustls::RootCertStore::empty();
for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs") {
roots.add(&rustls::Certificate(cert.0)).unwrap();
}

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

client_crypto.alpn_protocols = common::ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect();

let (endpoint, _) = endpoint.bind(&"[::]:0".parse().unwrap())?;
let mut endpoint = quinn::Endpoint::client("[::]:0".parse().unwrap())?;
endpoint.set_default_client_config(quinn::ClientConfig::new(Arc::new(client_crypto)));

let remote = Arc::<SocketAddr>::from(relay_addr);
let host = Arc::<String>::from(host);
let endpoint = Arc::<Endpoint>::from(endpoint);

info!("listening on {}", listen_addr);

let mut listener = TcpListener::bind(listen_addr).await?;
let listener = TcpListener::bind(listen_addr).await?;

while let Ok((inbound, _)) = listener.accept().await {
info!("connection incoming");
Expand All @@ -90,7 +99,7 @@ async fn transfer(
mut inbound: TcpStream,
) -> Result<()> {
let new_conn = endpoint
.connect(&remote, &host)?
.connect(*remote, &host)?
.await
.map_err(|e| anyhow!("failed to connect: {}", e))?;

Expand All @@ -104,8 +113,8 @@ async fn transfer(
.await
.map_err(|e| anyhow!("failed to open stream: {}", e))?;

let client_to_server = io::copy(&mut ri, &mut wo);
let server_to_client = io::copy(&mut ro, &mut wi);
let client_to_server = tokio::io::copy(&mut ri, &mut wo);
let server_to_client = tokio::io::copy(&mut ro, &mut wi);

try_join(client_to_server, server_to_client).await?;

Expand Down
2 changes: 2 additions & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#[allow(unused)]
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod args;
pub mod common;
74 changes: 44 additions & 30 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use log::LevelFilter;
use log::{error, info};
use structopt::{self, StructOpt};
use tokio::net::TcpStream;
use tokio::prelude::*;

use qtun::args;
mod args;
mod common;

#[derive(StructOpt, Debug)]
#[structopt(name = "qtun-server")]
Expand Down Expand Up @@ -60,16 +60,6 @@ async fn main() -> Result<()> {

let options = Opt::from_args();

let mut transport_config = quinn::TransportConfig::default();
transport_config.stream_window_uni(0);
let mut server_config = quinn::ServerConfig::default();
server_config.transport = Arc::new(transport_config);
let mut server_config = quinn::ServerConfigBuilder::new(server_config);

if options.stateless_retry {
server_config.use_stateless_retry(true);
}

// init all parameters
let mut cert_path = options.cert;
let mut key_path = options.key;
Expand Down Expand Up @@ -106,31 +96,55 @@ async fn main() -> Result<()> {
info!("loading cert: {:?}", cert_path);
info!("loading key: {:?}", key_path);

// load certificates
let key = fs::read(&key_path).context("failed to read private key")?;
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") {
quinn::PrivateKey::from_der(&key)?
rustls::PrivateKey(key)
} else {
quinn::PrivateKey::from_pem(&key)?
let pkcs8 = rustls_pemfile::pkcs8_private_keys(&mut &*key)
.context("malformed PKCS #8 private key")?;
match pkcs8.into_iter().next() {
Some(x) => rustls::PrivateKey(x),
None => {
let rsa = rustls_pemfile::rsa_private_keys(&mut &*key)
.context("malformed PKCS #1 private key")?;
match rsa.into_iter().next() {
Some(x) => rustls::PrivateKey(x),
None => {
anyhow::bail!("no private keys found");
}
}
}
}
};
let cert_chain = fs::read(&cert_path).context("failed to read certificate chain")?;
let cert_chain = if cert_path.extension().map_or(false, |x| x == "der") {
quinn::CertificateChain::from_certs(quinn::Certificate::from_der(&cert_chain))
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)]
} else {
quinn::CertificateChain::from_pem(&cert_chain)?
rustls_pemfile::certs(&mut &*certs)
.context("invalid PEM-encoded certificate")?
.into_iter()
.map(rustls::Certificate)
.collect()
};
server_config.certificate(cert_chain, key)?;

let mut endpoint = quinn::Endpoint::builder();
endpoint.listen(server_config.build());
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());
if options.stateless_retry {
server_config.use_retry(true);
}

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

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

while let Some(conn) = incoming.next().await {
info!("connection incoming");
Expand Down Expand Up @@ -183,8 +197,8 @@ async fn transfer(
let (mut wi, mut ri) = inbound;
let (mut ro, mut wo) = outbound.split();

let client_to_server = io::copy(&mut ri, &mut wo);
let server_to_client = io::copy(&mut ro, &mut wi);
let client_to_server = tokio::io::copy(&mut ri, &mut wo);
let server_to_client = tokio::io::copy(&mut ro, &mut wi);

try_join(client_to_server, server_to_client).await?;

Expand Down

0 comments on commit 492af31

Please sign in to comment.