#![allow(clippy::integer_arithmetic)] pub mod nonblocking; pub mod udp_client; use { crate::{ nonblocking::udp_client::UdpClientConnection as NonblockingUdpConnection, udp_client::UdpClientConnection as BlockingUdpConnection, }, solana_connection_cache::{ client_connection::ClientConnection as BlockingClientConnection, connection_cache::{ BaseClientConnection, ClientError, ConnectionManager, ConnectionPool, ConnectionPoolError, NewConnectionConfig, ProtocolType, }, connection_cache_stats::ConnectionCacheStats, nonblocking::client_connection::ClientConnection as NonblockingClientConnection, }, std::{ any::Any, net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}, sync::Arc, }, }; pub struct UdpPool { connections: Vec>, } impl ConnectionPool for UdpPool { fn add_connection(&mut self, config: &dyn NewConnectionConfig, addr: &SocketAddr) { let connection = self.create_pool_entry(config, addr); self.connections.push(connection); } fn num_connections(&self) -> usize { self.connections.len() } fn get(&self, index: usize) -> Result, ConnectionPoolError> { self.connections .get(index) .cloned() .ok_or(ConnectionPoolError::IndexOutOfRange) } fn create_pool_entry( &self, config: &dyn NewConnectionConfig, _addr: &SocketAddr, ) -> Arc { let config: &UdpConfig = match config.as_any().downcast_ref::() { Some(b) => b, None => panic!("Expecting a UdpConfig!"), }; Arc::new(Udp(config.udp_socket.clone())) } } pub struct UdpConfig { udp_socket: Arc, } impl NewConnectionConfig for UdpConfig { fn new() -> Result { let socket = solana_net_utils::bind_with_any_port(IpAddr::V4(Ipv4Addr::UNSPECIFIED)) .map_err(Into::::into)?; Ok(Self { udp_socket: Arc::new(socket), }) } fn as_any(&self) -> &dyn Any { self } fn as_mut_any(&mut self) -> &mut dyn Any { self } } pub struct Udp(Arc); impl BaseClientConnection for Udp { fn new_blocking_connection( &self, addr: SocketAddr, _stats: Arc, ) -> Arc { Arc::new(BlockingUdpConnection::new_from_addr(self.0.clone(), addr)) } fn new_nonblocking_connection( &self, addr: SocketAddr, _stats: Arc, ) -> Arc { Arc::new(NonblockingUdpConnection::new_from_addr( self.0.try_clone().unwrap(), addr, )) } } #[derive(Default)] pub struct UdpConnectionManager {} impl ConnectionManager for UdpConnectionManager { fn new_connection_pool(&self) -> Box { Box::new(UdpPool { connections: Vec::default(), }) } fn new_connection_config(&self) -> Box { Box::new(UdpConfig::new().unwrap()) } fn get_port_offset(&self) -> u16 { 0 } fn get_protocol_type(&self) -> ProtocolType { ProtocolType::UDP } }