-
Notifications
You must be signed in to change notification settings - Fork 923
Description
When running InitialQuicConnection<UdpSocket, M>.start(driver) the handshake and resume is completed within. However, in my testing where mTLS fails due to incorrect host names (doesn't match Common Name in TLS Cert), the .start(driver) silently fails and what happens is my app assumes the quic handshake succeeded but it actually failed so it initializes the app logic and runs the tasks in them since there is no way to know if the handshake failed or not (to my knowledge).
To fix the issue, I implemented this in my app
async fn start_connection<M>
(
initial_quic_connection: InitialQuicConnection<UdpSocket, M>,
driver: MyDriver
) -> io::Result<QuicConnection>
where
M: Metrics
{
let (q_conn, handshake) = initial_quic_connection.handshake(driver).await?;
metrics::tokio_task::spawn_with_killswitch(
"quic_handshake_worker",
DefaultMetrics, //can be cloned if used within the crate
async move {
InitialQuicConnection::<UdpSocket, M>::resume(handshake)
}
);
Ok(q_conn)
}which is taken from
pub fn start<A: ApplicationOverQuic>(self, app: A) -> QuicConnection {
let task_metrics = self.params.metrics.clone();
let (conn, handshake_fut) = Self::handshake_fut(self, app);
let fut = async move {
match handshake_fut.await {
Ok(running) => Self::resume(running),
Err(e) => {
log::error!("QUIC handshake failed in IQC::start"; "error" => e)
},
}
};
crate::metrics::tokio_task::spawn_with_killswitch(
"quic_handshake_worker",
task_metrics,
fut,
);
conn
}Why don't we create a new start function to support returning the result?
pub async fn start_with_result<A: ApplicationOverQuic>(self, app: A) -> io::Result<QuicConnection> {
let task_metrics = self.params.metrics.clone();
let result = self.handshake(app).await;
match result {
Ok((q_conn, handshake)) => {
crate::metrics::tokio_task::spawn_with_killswitch(
"quic_handshake_worker",
task_metrics,
async move {
Self::resume(handshake)
}
);
Ok(q_conn)
},
Err(err) => {
log::error!("QUIC handshake failed in IQC::start_with_result"; "error" => &err);
Err(err) // Pass it upward
}
}
}This would propagate errors upward which can be handled by the user instead being silently logged while also maintaining the same logging behavior as start().