use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tokio::net::UdpSocket;
use tokio::sync::Mutex;
use tracing::{debug, error};
use crate::api::client::security::ClientSecurityContext;
use crate::api::common::error::SecurityError;
use crate::api::server::security::SocketHandle;
use crate::dtls::transport::udp::UdpTransport;
use crate::dtls::DtlsConnection;
pub async fn setup_transport(
socket: &SocketHandle,
connection: &Arc<Mutex<Option<DtlsConnection>>>,
) -> Result<(), SecurityError> {
let mut conn_guard = connection.lock().await;
if let Some(conn) = conn_guard.as_mut() {
let transport = Arc::new(Mutex::new(
match create_udp_transport(socket.socket.clone(), 1500).await {
Ok(t) => t,
Err(e) => {
return Err(SecurityError::Configuration(format!(
"Failed to create DTLS transport: {}",
e
)))
}
},
));
match transport.lock().await.start().await {
Ok(_) => debug!("DTLS transport started successfully"),
Err(e) => {
return Err(SecurityError::Configuration(format!(
"Failed to start DTLS transport: {}",
e
)))
}
}
conn.set_transport(transport);
debug!("DTLS transport set up successfully");
Ok(())
} else {
debug!("No DTLS connection to set up transport for");
Ok(())
}
}
pub async fn start_packet_handler(
socket: &SocketHandle,
remote_addr: SocketAddr,
context: Arc<dyn ClientSecurityContext>,
) -> Result<(), SecurityError> {
debug!(
"Client: Starting DTLS packet handler for server {}",
remote_addr
);
let socket_clone = socket.socket.clone();
tokio::spawn(async move {
debug!(
"Client packet handler task started for server {}",
remote_addr
);
let mut buffer = vec![0u8; 2048];
loop {
match socket_clone.recv_from(&mut buffer).await {
Ok((size, addr)) => {
if addr == remote_addr {
debug!("Client received {} bytes from server {}", size, addr);
if let Err(e) = context.process_packet(&buffer[..size]).await {
error!("Error processing server DTLS packet: {:?}", e);
}
} else {
debug!("Ignoring packet from unknown sender {}", addr);
}
}
Err(e) => {
debug!("Client receive error: {}", e);
tokio::time::sleep(Duration::from_millis(10)).await;
}
}
}
});
Ok(())
}
pub async fn create_udp_transport(
socket: Arc<UdpSocket>,
mtu: usize,
) -> Result<UdpTransport, SecurityError> {
match UdpTransport::new(socket, mtu).await {
Ok(transport) => Ok(transport),
Err(e) => Err(SecurityError::Configuration(format!(
"Failed to create UDP transport: {}",
e
))),
}
}