1818
1919use super :: * ;
2020use async_trait:: async_trait;
21+ use lru:: LruCache ;
2122use std:: collections:: HashMap ;
2223use std:: net:: SocketAddr ;
24+ use std:: num:: NonZeroUsize ;
2325use std:: sync:: Arc ;
2426use tokio:: io:: { AsyncRead , AsyncWrite } ;
2527use tokio:: net:: { TcpListener , TcpStream } ;
2628use tokio:: sync:: RwLock ;
2729use tracing;
2830
31+ /// Maximum number of cached TCP connections to prevent memory exhaustion
32+ const MAX_TCP_CONNECTIONS : usize = 1_000 ;
33+
2934/// Transport protocol types
3035#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
3136pub enum TransportProtocol {
@@ -83,8 +88,8 @@ pub trait TransportConnection: AsyncRead + AsyncWrite + Send + Sync + Unpin {
8388
8489/// TCP transport implementation
8590pub struct TcpTransport {
86- /// Connection pool for reuse
87- connections : Arc < RwLock < HashMap < SocketAddr , Arc < RwLock < TcpStream > > > > > ,
91+ /// Connection pool for reuse (bounded LRU to prevent memory DoS)
92+ connections : Arc < RwLock < LruCache < SocketAddr , Arc < RwLock < TcpStream > > > > > ,
8893}
8994
9095impl Default for TcpTransport {
@@ -96,7 +101,9 @@ impl Default for TcpTransport {
96101impl TcpTransport {
97102 pub fn new ( ) -> Self {
98103 Self {
99- connections : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
104+ connections : Arc :: new ( RwLock :: new ( LruCache :: new (
105+ NonZeroUsize :: new ( MAX_TCP_CONNECTIONS ) . unwrap_or ( NonZeroUsize :: MIN ) ,
106+ ) ) ) ,
100107 }
101108 }
102109}
@@ -112,10 +119,10 @@ impl Transport for TcpTransport {
112119 }
113120
114121 async fn connect ( & self , addr : SocketAddr ) -> Result < Box < dyn TransportConnection > > {
115- // Check connection pool first
122+ // Check connection pool first (use peek to avoid mutating LRU order with read lock)
116123 {
117124 let connections = self . connections . read ( ) . await ;
118- if let Some ( _conn) = connections. get ( & addr) {
125+ if let Some ( _conn) = connections. peek ( & addr) {
119126 // TODO: Check if connection is still alive
120127 // For now, always create new connection
121128 }
@@ -390,7 +397,11 @@ impl TransportManager {
390397
391398 // For now, just try the first listener
392399 // TODO: Implement proper multiplexing
393- listeners[ 0 ] . accept ( ) . await
400+ listeners
401+ . first ( )
402+ . ok_or_else ( || AdaptiveNetworkError :: Other ( "No listeners available" . to_string ( ) ) ) ?
403+ . accept ( )
404+ . await
394405 }
395406}
396407
0 commit comments