This commit is contained in:
2025-11-14 13:49:16 -05:00
parent d72a070a73
commit d384154310
7 changed files with 925 additions and 121 deletions

View File

@@ -1,3 +1,122 @@
pub fn run_server() {
println!("hello world!")
use quinn::{
Endpoint,
crypto::rustls::QuicServerConfig,
rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer},
};
use std::{fs, net::SocketAddr, path::Path, str::FromStr, sync::Arc};
use tracing::Instrument;
use crate::net::ClientMsg;
#[tokio::main]
pub async fn run_server() {
quinn::rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.unwrap();
let dirs = directories_next::ProjectDirs::from("", "", "openworm").unwrap();
let path = dirs.data_local_dir();
let endpoint = listen(path);
println!("listening on {}", endpoint.local_addr().unwrap());
while let Some(conn) = endpoint.accept().await {
let fut = handle_connection(conn);
tokio::spawn(async move {
if let Err(e) = fut.await {
eprintln!("connection failed: {reason}", reason = e)
}
});
}
println!("hello world!");
}
pub fn listen(data_path: &Path) -> Endpoint {
let cert_path = data_path.join("cert.der");
let key_path = data_path.join("key.der");
let (cert, key) = match fs::read(&cert_path).and_then(|x| Ok((x, fs::read(&key_path)?))) {
Ok((cert, key)) => (
CertificateDer::from(cert),
PrivateKeyDer::try_from(key).unwrap(),
),
Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
let key = PrivatePkcs8KeyDer::from(cert.signing_key.serialize_der());
let cert = cert.cert.into();
fs::create_dir_all(data_path).expect("failed to create certificate directory");
fs::write(&cert_path, &cert).expect("failed to write certificate");
fs::write(&key_path, key.secret_pkcs8_der()).expect("failed to write private key");
(cert, key.into())
}
Err(e) => {
panic!("failed to read certificate: {}", e);
}
};
let server_crypto = quinn::rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(vec![cert], key)
.unwrap();
let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(
QuicServerConfig::try_from(server_crypto).unwrap(),
));
let transport_config = Arc::get_mut(&mut server_config.transport).unwrap();
transport_config.max_concurrent_uni_streams(0_u8.into());
quinn::Endpoint::server(server_config, SocketAddr::from_str("[::1]:4433").unwrap()).unwrap()
}
async fn handle_connection(conn: quinn::Incoming) -> std::io::Result<()> {
let connection = conn.await?;
let span = tracing::info_span!(
"connection",
remote = %connection.remote_address(),
protocol = %connection
.handshake_data()
.unwrap()
.downcast::<quinn::crypto::rustls::HandshakeData>().unwrap()
.protocol
.map_or_else(|| "<none>".into(), |x| String::from_utf8_lossy(&x).into_owned())
);
async {
// Each stream initiated by the client constitutes a new request.
loop {
let stream = connection.accept_bi().await;
// let time = Instant::now();
let stream = match stream {
Err(quinn::ConnectionError::ApplicationClosed { .. }) => {
println!("connection closed");
return Ok(());
}
Err(e) => {
return Err(e);
}
Ok(s) => s,
};
tokio::spawn(
async move {
if let Err(e) = handle_stream(stream).await {
eprintln!("failed: {reason}", reason = e);
}
}
.instrument(tracing::info_span!("request")),
);
}
}
.instrument(span)
.await?;
Ok(())
}
async fn handle_stream(
(send, mut recv): (quinn::SendStream, quinn::RecvStream),
) -> Result<(), String> {
drop(send);
let msg = recv
.read_to_end(std::mem::size_of::<ClientMsg>())
.await
.map_err(|e| format!("failed reading request: {}", e))?;
println!("received message");
println!("{:?}", msg);
Ok(())
}