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::SocketConfig,
20 std::{
21 net::{IpAddr, Ipv4Addr, 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 = solana_net_utils::bind_with_any_port_with_config(
67 IpAddr::V4(Ipv4Addr::UNSPECIFIED),
68 SocketConfig::default(),
69 )
70 .map_err(Into::<ClientError>::into)?;
71 Ok(Self {
72 udp_socket: Arc::new(socket),
73 })
74 }
75}
76
77pub struct Udp(Arc<UdpSocket>);
78impl BaseClientConnection for Udp {
79 type BlockingClientConnection = BlockingUdpConnection;
80 type NonblockingClientConnection = NonblockingUdpConnection;
81
82 fn new_blocking_connection(
83 &self,
84 addr: SocketAddr,
85 _stats: Arc<ConnectionCacheStats>,
86 ) -> Arc<Self::BlockingClientConnection> {
87 Arc::new(BlockingUdpConnection::new_from_addr(self.0.clone(), addr))
88 }
89
90 fn new_nonblocking_connection(
91 &self,
92 addr: SocketAddr,
93 _stats: Arc<ConnectionCacheStats>,
94 ) -> Arc<Self::NonblockingClientConnection> {
95 Arc::new(NonblockingUdpConnection::new_from_addr(
96 self.0.try_clone().unwrap(),
97 addr,
98 ))
99 }
100}
101
102#[derive(Default)]
103pub struct UdpConnectionManager {}
104
105impl ConnectionManager for UdpConnectionManager {
106 type ConnectionPool = UdpPool;
107 type NewConnectionConfig = UdpConfig;
108
109 const PROTOCOL: Protocol = Protocol::UDP;
110
111 fn new_connection_pool(&self) -> Self::ConnectionPool {
112 UdpPool {
113 connections: Vec::default(),
114 }
115 }
116
117 fn new_connection_config(&self) -> Self::NewConnectionConfig {
118 UdpConfig::new().unwrap()
119 }
120
121 fn update_key(&self, _key: &Keypair) -> Result<(), Box<dyn std::error::Error>> {
122 Ok(())
123 }
124}