solana_udp_client/
lib.rs

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}