prototype (failed) to multiplex quic streams
This commit is contained in:
parent
9d4cf08fba
commit
4b42e6eec1
3 changed files with 123 additions and 178 deletions
|
|
@ -4,6 +4,7 @@ use crate::{constants::CERTS_WATCH_DELAY_SECS, error::*, log::*};
|
|||
use futures::StreamExt;
|
||||
use futures::{future::FutureExt, join, select};
|
||||
use hyper::{client::connect::Connect, server::conn::Http};
|
||||
use rustls::ServerConfig;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
|
|
@ -58,25 +59,13 @@ where
|
|||
info!("No SNI in ClientHello");
|
||||
continue;
|
||||
};
|
||||
let backend_serve = if let Some(backend_serve) = self.backends.apps.get(svn){
|
||||
backend_serve
|
||||
} else {
|
||||
info!("No configuration for the server name {} given in client_hello", svn);
|
||||
continue;
|
||||
};
|
||||
|
||||
if backend_serve.tls_cert_path.is_none() { // at least cert does exit
|
||||
debug!("SNI indicates a site that doesn't support TLS.");
|
||||
continue;
|
||||
}
|
||||
let server_config = if let Some(p) = backend_serve.get_tls_server_config(){
|
||||
let server_crypto = if let Some(p) = self.fetch_server_crypto(svn) {
|
||||
p
|
||||
} else {
|
||||
error!("Failed to load server config");
|
||||
continue;
|
||||
};
|
||||
// Finally serve the TLS connection
|
||||
if let Ok(stream) = start.into_stream(Arc::new(server_config)).await {
|
||||
if let Ok(stream) = start.into_stream(Arc::new(server_crypto)).await {
|
||||
self.clone().client_serve(stream, server.clone(), _client_addr).await
|
||||
}
|
||||
}
|
||||
|
|
@ -86,11 +75,23 @@ where
|
|||
Ok(()) as Result<()>
|
||||
};
|
||||
|
||||
/////////////////////// TODO:!!!!!
|
||||
///////////////////////
|
||||
#[cfg(feature = "h3")]
|
||||
let listener_service_h3 = async {
|
||||
// TODO: とりあえずデフォルトのserver_cryptoが必要になりそう
|
||||
let backend_serve = self.backends.apps.get("localhost").unwrap();
|
||||
// TODO: Work around to initially serve incoming connection
|
||||
let tls_app_names: Vec<String> = self
|
||||
.backends
|
||||
.apps
|
||||
.iter()
|
||||
.filter(|&(_, backend)| {
|
||||
backend.tls_cert_key_path.is_some() && backend.tls_cert_path.is_some()
|
||||
})
|
||||
.map(|(name, _)| name.to_string())
|
||||
.collect();
|
||||
ensure!(!tls_app_names.is_empty(), "No TLS supported app");
|
||||
let initial_app_name = tls_app_names.get(0).unwrap().as_str();
|
||||
info!("Initial app_name: {}", initial_app_name);
|
||||
let backend_serve = self.backends.apps.get(initial_app_name).unwrap();
|
||||
let server_crypto = backend_serve.get_tls_server_config().unwrap();
|
||||
let server_config_h3 = quinn::ServerConfig::with_crypto(Arc::new(server_crypto));
|
||||
|
||||
|
|
@ -98,23 +99,39 @@ where
|
|||
quinn::Endpoint::server(server_config_h3, self.listening_on).unwrap();
|
||||
debug!("HTTP/3 UDP listening on {}", endpoint.local_addr().unwrap());
|
||||
|
||||
// let peekable_incoming = incoming.peekable();
|
||||
|
||||
while let Some(mut conn) = incoming.next().await {
|
||||
debug!("HTTP/3 connection incoming");
|
||||
let hsd = conn.handshake_data().await;
|
||||
let hsd_downcast = hsd
|
||||
.unwrap()
|
||||
let hsd_downcast = hsd?
|
||||
.downcast::<quinn::crypto::rustls::HandshakeData>()
|
||||
.unwrap();
|
||||
debug!("HTTP/3 SNI: {:?}", hsd_downcast.server_name);
|
||||
// TODO: ServerConfig::set_server_configでSNIに応じて再セット
|
||||
let svn = if let Some(sni) = hsd_downcast.server_name {
|
||||
info!("HTTP/3 connection incoming (SNI {:?})", sni);
|
||||
sni
|
||||
} else {
|
||||
debug!("HTTP/3 no SNI is given");
|
||||
continue;
|
||||
};
|
||||
|
||||
let new_server_crypto = if let Some(p) = self.fetch_server_crypto(&svn) {
|
||||
p
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
// Set ServerConfig::set_server_config for given SNI
|
||||
let new_server_config_h3 = quinn::ServerConfig::with_crypto(Arc::new(new_server_crypto));
|
||||
endpoint.set_server_config(Some(new_server_config_h3));
|
||||
|
||||
let fut = self.clone().client_serve_h3(conn);
|
||||
self.globals.runtime_handle.spawn(async {
|
||||
if let Err(e) = fut.await {
|
||||
error!("connection failed: {reason}", reason = e.to_string())
|
||||
warn!("QUIC or HTTP/3 connection failed: {}", e)
|
||||
}
|
||||
});
|
||||
}
|
||||
endpoint.wait_idle().await;
|
||||
Ok(()) as Result<()>
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "h3"))]
|
||||
|
|
@ -126,4 +143,28 @@ where
|
|||
join!(listener_service, cert_service, listener_service_h3).0
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_server_crypto(&self, server_name: &str) -> Option<ServerConfig> {
|
||||
let backend_serve = if let Some(backend_serve) = self.backends.apps.get(server_name) {
|
||||
backend_serve
|
||||
} else {
|
||||
warn!(
|
||||
"No configuration for the server name {} given in client_hello",
|
||||
server_name
|
||||
);
|
||||
return None;
|
||||
};
|
||||
|
||||
if backend_serve.tls_cert_path.is_none() {
|
||||
// at least cert does exit
|
||||
warn!("SNI indicates a site that doesn't support TLS.");
|
||||
return None;
|
||||
}
|
||||
if let Some(p) = backend_serve.get_tls_server_config() {
|
||||
Some(p)
|
||||
} else {
|
||||
error!("Failed to load server config");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue