MCPcopy Create free account
hub / github.com/DNSCrypt/encrypted-dns-server / tcp_acceptor

Function tcp_acceptor

src/main.rs:298–415  ·  view source on GitHub ↗
(globals: Arc<Globals>, tcp_listener: TcpListener)

Source from the content-addressed store, hash-verified

296}
297
298async fn tcp_acceptor(globals: Arc<Globals>, tcp_listener: TcpListener) -> Result<(), Error> {
299 let runtime_handle = globals.runtime_handle.clone();
300 let timeout = globals.tcp_timeout;
301 let concurrent_connections = globals.tcp_concurrent_connections.clone();
302 let active_connections = globals.tcp_active_connections.clone();
303 loop {
304 let (mut client_connection, client_addr) = match tcp_listener.accept().await {
305 Ok(x) => x,
306 Err(e) => {
307 if e.kind() == std::io::ErrorKind::WouldBlock {
308 continue;
309 }
310 error!("TCP accept error: {}", e);
311
312 // Rate limit repeated errors to avoid spinning
313 let is_resource_error = matches!(
314 e.kind(),
315 std::io::ErrorKind::ConnectionRefused
316 | std::io::ErrorKind::ConnectionReset
317 | std::io::ErrorKind::ConnectionAborted
318 | std::io::ErrorKind::AddrInUse
319 | std::io::ErrorKind::AddrNotAvailable
320 );
321
322 if is_resource_error {
323 // For resource-related errors, try to free up connections
324 let mut connections = active_connections.lock();
325 let freed = connections.len().min(5);
326 for _ in 0..freed {
327 if let Some(tx_oldest) = connections.pop_back() {
328 let _ = tx_oldest.send(());
329 }
330 }
331 info!("Freed {} connections to recover from resource error", freed);
332 }
333
334 // Add delay to prevent CPU spinning on persistent errors
335 tokio::time::sleep(Duration::from_secs(1)).await;
336 continue;
337 }
338 };
339
340 if let Some(ref rate_limiter) = globals.rate_limiter {
341 if !rate_limiter.is_allowed(client_addr.ip()) {
342 debug!("Rate limit exceeded for {}", client_addr.ip());
343 #[cfg(feature = "metrics")]
344 globals.varz.client_queries_rate_limited.inc();
345 continue;
346 }
347 }
348
349 let (tx, rx) = oneshot::channel::<()>();
350 let tx_channel_index = {
351 let mut active_connections = active_connections.lock();
352 if active_connections.is_full() {
353 let tx_oldest = active_connections.pop_back().unwrap();
354 let _ = tx_oldest.send(());
355 }

Callers 1

startFunction · 0.85

Calls 4

tls_proxyFunction · 0.85
handle_client_queryFunction · 0.85
lockMethod · 0.80
is_allowedMethod · 0.80

Tested by

no test coverage detected