nncs/src/types.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

55 lines
1.8 KiB
Rust

use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::sync::Arc;
use tokio::net::UdpSocket;
pub struct Sockets {
pub primary: Arc<UdpSocket>,
pub secondary: Arc<UdpSocket>,
pub alt: Arc<UdpSocket>,
pub p33334: Arc<UdpSocket>,
pub p33335: Arc<UdpSocket>,
}
pub struct Message {
pub r#type: u32,
pub external_port: u32,
pub external_address: Ipv4Addr,
pub local_address: u32,
}
impl Message {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
if bytes.len() < 16 {
return Err(format!("Buffer too short, expected 16 bytes but found {} bytes", bytes.len()))
};
let r#type = u32::from_be_bytes(bytes[0..4].try_into().unwrap());
let external_port = u32::from_be_bytes(bytes[4..8].try_into().unwrap());
let external_address = Ipv4Addr::from(u32::from_be_bytes(bytes[8..12].try_into().unwrap()));
let local_address = u32::from_be_bytes(bytes[12..16].try_into().unwrap());
Ok(Message{
r#type,
external_port,
external_address,
local_address,
})
}
pub fn to_response_bytes(&self, socket: Arc<UdpSocket>, remote_addr: SocketAddrV4) -> Result<[u8; 16], String> {
let mut bytes = [0u8; 16];
bytes[0..4].copy_from_slice(&self.r#type.to_be_bytes());
bytes[4..8].copy_from_slice(&remote_addr.port().to_be_bytes());
bytes[8..12].copy_from_slice(&u32::from(*remote_addr.ip()).to_be_bytes());
let local_ip = match socket.local_addr().unwrap() {
SocketAddr::V4(addr) => *addr.ip(),
SocketAddr::V6(_) => {
return Err("Ipv6 not supported".into());
},
};
bytes[12..16].copy_from_slice(&u32::from(local_ip).to_be_bytes());
Ok(bytes)
}
}