add checking mechanism of consistency between sni and host/request line

This commit is contained in:
Jun Kurihara 2022-07-15 23:55:21 +09:00
commit d37ed57a1c
No known key found for this signature in database
GPG key ID: 48ADFD173ED22B03
11 changed files with 111 additions and 69 deletions

View file

@ -1,5 +1,5 @@
use super::Proxy;
use crate::{error::*, log::*};
use crate::{backend::ServerNameLC, error::*, log::*};
use bytes::{Buf, Bytes};
use h3::{quic::BidiStream, server::RequestStream};
use hyper::{client::connect::Connect, Body, HeaderMap, Request, Response};
@ -10,13 +10,15 @@ impl<T> Proxy<T>
where
T: Connect + Clone + Sync + Send + 'static,
{
pub async fn client_serve_h3(&self, conn: quinn::Connecting) {
pub async fn client_serve_h3(&self, conn: quinn::Connecting, tls_server_name: &[u8]) {
let clients_count = self.globals.clients_count.clone();
if clients_count.increment() > self.globals.max_clients {
clients_count.decrement();
return;
}
let fut = self.clone().handle_connection_h3(conn);
let fut = self
.clone()
.handle_connection_h3(conn, tls_server_name.to_vec());
self.globals.runtime_handle.spawn(async move {
// Timeout is based on underlying quic
if let Err(e) = fut.await {
@ -27,31 +29,22 @@ where
});
}
pub async fn handle_connection_h3(self, conn: quinn::Connecting) -> Result<()> {
pub async fn handle_connection_h3(
self,
conn: quinn::Connecting,
tls_server_name: ServerNameLC,
) -> Result<()> {
let client_addr = conn.remote_address();
match conn.await {
Ok(new_conn) => {
info!("QUIC connection established from {:?} {:?}", client_addr, {
let hsd = new_conn
.connection
.handshake_data()
.ok_or_else(|| anyhow!(""))?
.downcast::<quinn::crypto::rustls::HandshakeData>()
.map_err(|_| anyhow!(""))?;
(
hsd.protocol.map_or_else(
|| "<none>".into(),
|x| String::from_utf8_lossy(&x).into_owned(),
),
hsd.server_name.map_or_else(|| "<none>".into(), |x| x),
)
});
let mut h3_conn =
h3::server::Connection::<_, bytes::Bytes>::new(h3_quinn::Connection::new(new_conn))
.await?;
info!("HTTP/3 connection established");
info!(
"QUIC/HTTP3 connection established from {:?} {:?}",
client_addr, tls_server_name
);
// Does this work enough?
// while let Some((req, stream)) = h3_conn
@ -73,10 +66,11 @@ where
);
let self_inner = self.clone();
let tls_server_name_inner = tls_server_name.clone();
self.globals.runtime_handle.spawn(async move {
if let Err(e) = timeout(
self_inner.globals.proxy_timeout + Duration::from_secs(1), // timeout per stream are considered as same as one in http2
self_inner.handle_stream_h3(req, stream, client_addr),
self_inner.handle_stream_h3(req, stream, client_addr, tls_server_name_inner),
)
.await
{
@ -99,6 +93,7 @@ where
req: Request<()>,
mut stream: RequestStream<S, Bytes>,
client_addr: SocketAddr,
tls_server_name: ServerNameLC,
) -> Result<()>
where
S: BidiStream<Bytes>,
@ -128,7 +123,13 @@ where
let res = self
.msg_handler
.clone()
.handle_request(new_req, client_addr, self.listening_on, self.tls_enabled)
.handle_request(
new_req,
client_addr,
self.listening_on,
self.tls_enabled,
Some(tls_server_name),
)
.await?;
let (new_res_parts, new_body) = res.into_parts();