use crate::{
path::secret,
stream::{
application::Stream,
endpoint,
environment::tokio::{self as env, Environment},
socket::Protocol,
},
};
use std::{io, net::SocketAddr};
use tokio::net::TcpStream;
#[inline]
pub async fn connect_udp<H>(
handshake_addr: SocketAddr,
handshake: H,
acceptor_addr: SocketAddr,
env: &Environment,
map: &secret::Map,
) -> io::Result<Stream>
where
H: core::future::Future<Output = io::Result<secret::HandshakeKind>>,
{
handshake.await?;
let stream = endpoint::open_stream(
env,
handshake_addr.into(),
env::UdpUnbound(acceptor_addr.into()),
map,
None,
)?;
let mut stream = stream.build()?;
debug_assert_eq!(stream.protocol(), Protocol::Udp);
write_prelude(&mut stream).await?;
Ok(stream)
}
#[inline]
pub async fn connect_tcp<H>(
handshake_addr: SocketAddr,
handshake: H,
acceptor_addr: SocketAddr,
env: &Environment,
map: &secret::Map,
) -> io::Result<Stream>
where
H: core::future::Future<Output = io::Result<secret::HandshakeKind>>,
{
let (socket, _) = tokio::try_join!(TcpStream::connect(acceptor_addr), handshake,)?;
let stream = endpoint::open_stream(
env,
handshake_addr.into(),
env::TcpRegistered(socket),
map,
None,
)?;
let mut stream = stream.build()?;
debug_assert_eq!(stream.protocol(), Protocol::Tcp);
write_prelude(&mut stream).await?;
Ok(stream)
}
#[inline]
pub async fn connect_tcp_with(
handshake_addr: SocketAddr,
stream: TcpStream,
env: &Environment,
map: &secret::Map,
) -> io::Result<Stream> {
let stream = endpoint::open_stream(
env,
handshake_addr.into(),
env::TcpRegistered(stream),
map,
None,
)?;
let mut stream = stream.build()?;
debug_assert_eq!(stream.protocol(), Protocol::Tcp);
write_prelude(&mut stream).await?;
Ok(stream)
}
#[inline]
async fn write_prelude(stream: &mut Stream) -> io::Result<()> {
stream
.write_from(&mut s2n_quic_core::buffer::reader::storage::Empty)
.await
.map(|_| ())
}