1#![allow(clippy::arithmetic_side_effects)]
2
3pub mod nonblocking;
4pub mod udp_client;
5
6use {
7 crate::{
8 nonblocking::udp_client::UdpClientConnection as NonblockingUdpConnection,
9 udp_client::UdpClientConnection as BlockingUdpConnection,
10 },
11 solana_connection_cache::{
12 connection_cache::{
13 BaseClientConnection, ClientError, ConnectionManager, ConnectionPool,
14 ConnectionPoolError, NewConnectionConfig, Protocol,
15 },
16 connection_cache_stats::ConnectionCacheStats,
17 },
18 solana_keypair::Keypair,
19 solana_net_utils::sockets::{self, SocketConfiguration},
20 std::{
21 net::{SocketAddr, UdpSocket},
22 sync::Arc,
23 },
24};
25
26pub struct UdpPool {
27 connections: Vec<Arc<Udp>>,
28}
29impl ConnectionPool for UdpPool {
30 type BaseClientConnection = Udp;
31 type NewConnectionConfig = UdpConfig;
32
33 fn add_connection(&mut self, config: &Self::NewConnectionConfig, addr: &SocketAddr) -> usize {
34 let connection = self.create_pool_entry(config, addr);
35 let idx = self.connections.len();
36 self.connections.push(connection);
37 idx
38 }
39
40 fn num_connections(&self) -> usize {
41 self.connections.len()
42 }
43
44 fn get(&self, index: usize) -> Result<Arc<Self::BaseClientConnection>, ConnectionPoolError> {
45 self.connections
46 .get(index)
47 .cloned()
48 .ok_or(ConnectionPoolError::IndexOutOfRange)
49 }
50
51 fn create_pool_entry(
52 &self,
53 config: &Self::NewConnectionConfig,
54 _addr: &SocketAddr,
55 ) -> Arc<Self::BaseClientConnection> {
56 Arc::new(Udp(config.udp_socket.clone()))
57 }
58}
59
60pub struct UdpConfig {
61 udp_socket: Arc<UdpSocket>,
62}
63
64impl NewConnectionConfig for UdpConfig {
65 fn new() -> Result<Self, ClientError> {
66 let socket = sockets::bind_in_range_with_config(
69 std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST),
70 solana_net_utils::VALIDATOR_PORT_RANGE,
71 SocketConfiguration::default(),
72 )
73 .map_err(Into::<ClientError>::into)?;
74 Ok(Self {
75 udp_socket: Arc::new(socket.1),
76 })
77 }
78}
79
80pub struct Udp(Arc<UdpSocket>);
81impl BaseClientConnection for Udp {
82 type BlockingClientConnection = BlockingUdpConnection;
83 type NonblockingClientConnection = NonblockingUdpConnection;
84
85 fn new_blocking_connection(
86 &self,
87 addr: SocketAddr,
88 _stats: Arc<ConnectionCacheStats>,
89 ) -> Arc<Self::BlockingClientConnection> {
90 Arc::new(BlockingUdpConnection::new_from_addr(self.0.clone(), addr))
91 }
92
93 fn new_nonblocking_connection(
94 &self,
95 addr: SocketAddr,
96 _stats: Arc<ConnectionCacheStats>,
97 ) -> Arc<Self::NonblockingClientConnection> {
98 Arc::new(NonblockingUdpConnection::new_from_addr(
99 self.0.try_clone().unwrap(),
100 addr,
101 ))
102 }
103}
104
105#[derive(Default)]
106pub struct UdpConnectionManager {}
107
108impl ConnectionManager for UdpConnectionManager {
109 type ConnectionPool = UdpPool;
110 type NewConnectionConfig = UdpConfig;
111
112 const PROTOCOL: Protocol = Protocol::UDP;
113
114 fn new_connection_pool(&self) -> Self::ConnectionPool {
115 UdpPool {
116 connections: Vec::default(),
117 }
118 }
119
120 fn new_connection_config(&self) -> Self::NewConnectionConfig {
121 UdpConfig::new().unwrap()
122 }
123
124 fn update_key(&self, _key: &Keypair) -> Result<(), Box<dyn std::error::Error>> {
125 Ok(())
126 }
127}