use quinn::Connection;
use crate::common::connection::quic::QuicReader;
use crate::common::{
connection::{Reader, Writer},
message::{ClientMessage, ServerMessage, PROTOCOL_VERSION},
result::DynResult,
};
#[allow(unused)]
pub async fn initialize_connection(
connection: Connection,
domain: &str,
port: u16,
) -> DynResult<(Connection, impl Writer, impl Reader)> {
initialize_connection_private(connection, domain, port, false).await
}
#[inline]
pub async fn finalize_connection(
connection: Connection,
) -> DynResult<(Connection, impl Writer, impl Reader)> {
let (writer, reader) = connection.accept_bi().await?;
Ok((connection, writer, QuicReader::from(reader)))
}
#[inline]
pub(crate) async fn initialize_connection_private(
connection: Connection,
domain: &str,
port: u16,
print_to_stdout: bool,
) -> DynResult<(Connection, impl Writer, impl Reader)> {
if print_to_stdout {
println!("Connecting to {domain}:{port}");
}
log::info!("Connecting to {domain}:{port}");
let (connection, mut writer, mut reader) = finalize_connection(connection).await?;
let (server_version, hash) = match reader.get_next_message::<ServerMessage>().await? {
Some(ServerMessage::Hello(vprot, vcrate, hash)) => {
if vprot == PROTOCOL_VERSION {
(vcrate, hash)
} else {
Err(format!(
"Server ({vcrate}) using unsupported protocol {vprot}"
))?
}
}
Some(other) => Err(format!("Got unexpected first message: {other:?}"))?,
None => Err("Got no message.")?,
};
let random_num = rand::random();
writer
.write_message(ClientMessage::Ping { c: random_num })
.await?;
match reader.get_next_message::<ServerMessage>().await? {
Some(ServerMessage::Pong { c }) if c == random_num => {
if let Some(hash) = hash {
if print_to_stdout {
println!(
"Connected to Server at {:?} ({server_version}, {hash})",
connection.remote_address(),
);
}
log::info!(
"Connected to Server at {:?} ({server_version}, {hash})",
connection.remote_address()
);
} else {
if print_to_stdout {
println!(
"Connected to Server at {:?} ({server_version})",
connection.remote_address(),
);
}
log::info!(
"Connected to Server at {:?} ({server_version})",
connection.remote_address()
);
}
Ok((connection, writer, reader))
}
Some(other) => Err(format!("Got unexpected second message: {other:?}"))?,
None => Err("Got no message.")?,
}
}