nncs/src/ipc.rs
BloxerHD a4dbe9c399
Some checks failed
Build and Test / rust-boss (push) Has been cancelled
Initial Commit
2026-07-16 21:25:41 +01:00

71 lines
2.3 KiB
Rust

use std::net::{Ipv4Addr, SocketAddrV4};
use std::sync::Arc;
use tokio::net::UdpSocket;
use crate::types::{Message, Sockets};
pub struct IpcFrame {
pub message: Message,
pub remote_addr: SocketAddrV4,
}
impl IpcFrame {
pub fn to_bytes(&self, socket: Arc<UdpSocket>) -> [u8; 22] {
let message_bytes = self.message.to_response_bytes(socket, self.remote_addr);
let mut buf = [0u8; 22];
buf[0..2].copy_from_slice(&self.remote_addr.port().to_be_bytes());
buf[2..6].copy_from_slice(&u32::from(*self.remote_addr.ip()).to_be_bytes());
buf[6..].copy_from_slice(&message_bytes.unwrap());
buf
}
pub fn from_bytes(slice: &[u8]) -> Result<Self, String> {
if slice.len() < 6 {
return Err("Frame too small to extract client metadata".into())
}
let remote_port = u16::from_be_bytes(slice[0..2].try_into().unwrap());
let remote_ip = Ipv4Addr::from(u32::from_be_bytes(slice[2..6].try_into().unwrap()));
let remote_addr = SocketAddrV4::new(remote_ip, remote_port);
let message = Message::from_bytes(&slice[6..])?;
Ok(IpcFrame{message, remote_addr})
}
}
pub async fn run(host: String, port: u16, sockets: Arc<Sockets>) -> Result<(), Box<dyn std::error::Error>> {
let ipc_socket = UdpSocket::bind(format!("{host}:{port}")).await?;
let mut buf = [0u8; 2048];
tokio::spawn(async move {
loop {
match ipc_socket.recv_from(&mut buf).await {
Ok((len, _sender_addr)) => {
match IpcFrame::from_bytes(&buf[..len]) {
Ok(ipc_frame) => {
let socket = &sockets.alt;
let _ = socket.send_to(
&ipc_frame.message.to_response_bytes(socket.clone(), ipc_frame.remote_addr).unwrap(),
format!("{}:{}", ipc_frame.remote_addr.ip(), ipc_frame.remote_addr.port()),
).await;
},
Err(e) => {
eprintln!("Failed to decode IPC Frame: {e}")
}
}
},
Err(e) => {
eprintln!("IPC Socket Error: {e}");
break;
}
}
}
});
Ok(())
}