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_sdk::signature::Keypair,
19 std::{
20 net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket},
21 sync::Arc,
22 },
23};
24
25pub struct UdpPool {
26 connections: Vec<Arc<Udp>>,
27}
28impl ConnectionPool for UdpPool {
29 type BaseClientConnection = Udp;
30 type NewConnectionConfig = UdpConfig;
31
32 fn add_connection(&mut self, config: &Self::NewConnectionConfig, addr: &SocketAddr) -> usize {
33 let connection = self.create_pool_entry(config, addr);
34 let idx = self.connections.len();
35 self.connections.push(connection);
36 idx
37 }
38
39 fn num_connections(&self) -> usize {
40 self.connections.len()
41 }
42
43 fn get(&self, index: usize) -> Result<Arc<Self::BaseClientConnection>, ConnectionPoolError> {
44 self.connections
45 .get(index)
46 .cloned()
47 .ok_or(ConnectionPoolError::IndexOutOfRange)
48 }
49
50 fn create_pool_entry(
51 &self,
52 config: &Self::NewConnectionConfig,
53 _addr: &SocketAddr,
54 ) -> Arc<Self::BaseClientConnection> {
55 Arc::new(Udp(config.udp_socket.clone()))
56 }
57}
58
59pub struct UdpConfig {
60 udp_socket: Arc<UdpSocket>,
61}
62
63impl NewConnectionConfig for UdpConfig {
64 fn new() -> Result<Self, ClientError> {
65 let socket = solana_net_utils::bind_with_any_port(IpAddr::V4(Ipv4Addr::UNSPECIFIED))
66 .map_err(Into::<ClientError>::into)?;
67 Ok(Self {
68 udp_socket: Arc::new(socket),
69 })
70 }
71}
72
73pub struct Udp(Arc<UdpSocket>);
74impl BaseClientConnection for Udp {
75 type BlockingClientConnection = BlockingUdpConnection;
76 type NonblockingClientConnection = NonblockingUdpConnection;
77
78 fn new_blocking_connection(
79 &self,
80 addr: SocketAddr,
81 _stats: Arc<ConnectionCacheStats>,
82 ) -> Arc<Self::BlockingClientConnection> {
83 Arc::new(BlockingUdpConnection::new_from_addr(self.0.clone(), addr))
84 }
85
86 fn new_nonblocking_connection(
87 &self,
88 addr: SocketAddr,
89 _stats: Arc<ConnectionCacheStats>,
90 ) -> Arc<Self::NonblockingClientConnection> {
91 Arc::new(NonblockingUdpConnection::new_from_addr(
92 self.0.try_clone().unwrap(),
93 addr,
94 ))
95 }
96}
97
98#[derive(Default)]
99pub struct UdpConnectionManager {}
100
101impl ConnectionManager for UdpConnectionManager {
102 type ConnectionPool = UdpPool;
103 type NewConnectionConfig = UdpConfig;
104
105 const PROTOCOL: Protocol = Protocol::UDP;
106
107 fn new_connection_pool(&self) -> Self::ConnectionPool {
108 UdpPool {
109 connections: Vec::default(),
110 }
111 }
112
113 fn new_connection_config(&self) -> Self::NewConnectionConfig {
114 UdpConfig::new().unwrap()
115 }
116
117 fn update_key(&self, _key: &Keypair) -> Result<(), Box<dyn std::error::Error>> {
118 Ok(())
119 }
120}