55 lines
1.8 KiB
Rust
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)
|
||
|
|
}
|
||
|
|
}
|