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_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}