This commit is contained in:
2026-03-26 21:23:22 +04:00
commit 41f4fa65b5
25 changed files with 5009 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
use color_eyre::Result;
use tokio::io::{AsyncRead, AsyncWrite, copy_bidirectional};
/// Bidirectional relay between two async streams.
/// Returns when either direction hits EOF or an error.
pub async fn relay<A, B>(mut a: A, mut b: B) -> Result<()>
where
A: AsyncRead + AsyncWrite + Unpin,
B: AsyncRead + AsyncWrite + Unpin,
{
copy_bidirectional(&mut a, &mut b).await?;
Ok(())
}
/// Wrapper to combine a QUIC send+recv into a single AsyncRead+AsyncWrite.
pub struct QuicBiStream {
pub send: quinn::SendStream,
pub recv: quinn::RecvStream,
}
impl tokio::io::AsyncRead for QuicBiStream {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>,
) -> std::task::Poll<std::io::Result<()>> {
std::pin::Pin::new(&mut self.recv).poll_read(cx, buf)
}
}
impl tokio::io::AsyncWrite for QuicBiStream {
fn poll_write(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &[u8],
) -> std::task::Poll<std::io::Result<usize>> {
std::pin::Pin::new(&mut self.send)
.poll_write(cx, buf)
.map(|r| r.map_err(std::io::Error::other))
}
fn poll_flush(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
std::pin::Pin::new(&mut self.send).poll_flush(cx)
}
fn poll_shutdown(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
std::pin::Pin::new(&mut self.send).poll_shutdown(cx)
}
}