use std::{ sync::Arc, }; use tokio::{ io::{ AsyncReadExt, AsyncWriteExt, }, net::{ UdpSocket, tcp, } }; pub async fn rx ( udp_sock: Arc , mut tcp_read: tcp::OwnedReadHalf, ) -> anyhow::Result <()> { loop { let mut tag = [0u8, 0, 0, 0]; let bytes_read = tcp_read.read (&mut tag).await?; if bytes_read != 4 { anyhow::anyhow! ("loops::rx: Couldn't read 4 bytes for tag"); } if tag != [1, 0, 0, 0] { anyhow::anyhow! ("loops::rx: unexpected tag in framing"); } let mut length = [0u8, 0, 0, 0]; let bytes_read = tcp_read.read (&mut length).await?; if bytes_read != 4 { anyhow::anyhow! ("loops::rx: Couldn't read 4 bytes for tag"); } let length = usize::try_from (u32::from_le_bytes (length))?; if length >= 8_192 { anyhow::anyhow! ("loops::rx: Length too big for UDP packets"); } let mut buf = vec! [0u8; length]; let bytes_read = tcp_read.read_exact (&mut buf).await?; if length != bytes_read { anyhow::anyhow! ("loops::rx: read_exact failed"); } buf.truncate (bytes_read); udp_sock.send (&buf).await?; } } pub async fn tx ( udp_sock: Arc , mut tcp_write: tcp::OwnedWriteHalf, ) -> anyhow::Result <()> { loop { let mut buf = vec! [0u8; 8_192]; let bytes_read = udp_sock.recv (&mut buf).await?; buf.truncate (bytes_read); let tag = [1u8, 0, 0, 0]; let length = u32::try_from (bytes_read)?.to_le_bytes (); tcp_write.write_all (&tag).await?; tcp_write.write_all (&length).await?; tcp_write.write_all (&buf).await?; } }