84 lines
1.7 KiB
Rust
84 lines
1.7 KiB
Rust
use std::{
|
|
sync::Arc,
|
|
};
|
|
|
|
use tokio::{
|
|
io::{
|
|
AsyncReadExt,
|
|
AsyncWriteExt,
|
|
},
|
|
net::{
|
|
UdpSocket,
|
|
tcp,
|
|
}
|
|
};
|
|
|
|
pub async fn rx (
|
|
udp_sock: Arc <UdpSocket>,
|
|
mut tcp_read: tcp::OwnedReadHalf,
|
|
) -> anyhow::Result <()> {
|
|
for i in 0u64.. {
|
|
// Optimizes down to a bitwise AND
|
|
if i % 8_192 == 0 {
|
|
tracing::trace! ("rx 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?;
|
|
}
|
|
|
|
Ok (())
|
|
}
|
|
|
|
pub async fn tx (
|
|
udp_sock: Arc <UdpSocket>,
|
|
mut tcp_write: tcp::OwnedWriteHalf,
|
|
) -> anyhow::Result <()>
|
|
{
|
|
for i in 0u64.. {
|
|
// Optimizes down to a bitwise AND
|
|
if i % 8_192 == 0 {
|
|
tracing::trace! ("tx 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?;
|
|
}
|
|
|
|
Ok (())
|
|
}
|