Skip to content

Commit

Permalink
Use cool down period if TCP accept fails
Browse files Browse the repository at this point in the history
  • Loading branch information
mvd-ows committed Oct 3, 2023
1 parent 5d7c1fe commit 0f241b9
Showing 1 changed file with 36 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/tcp2udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
//! to UDP.
use crate::logging::Redact;
use core::cmp::min;
use err_context::{BoxedErrorExt as _, ErrorExt as _, ResultExt as _};
use std::convert::Infallible;
use std::fmt;
use std::io;
use std::net::{IpAddr, SocketAddr};
use std::time::Duration;
use tokio::net::{TcpListener, TcpSocket, TcpStream, UdpSocket};
use tokio::time::sleep;

const OS_ERROR_TOO_MANY_OPEN_FILES: i32 = 24;

#[derive(Debug)]
#[cfg_attr(feature = "clap", derive(clap::Parser))]
Expand Down Expand Up @@ -142,16 +146,42 @@ fn create_listening_socket(
Ok(tcp_listener)
}

struct Cooldown<const N: usize> {
index: usize,
delays: [u64; N],
}

impl<const N: usize> Cooldown<N> {
pub fn new(start: u64) -> Cooldown<N> {
Cooldown::<N> {
index: 0,
delays: core::array::from_fn(|i| start * (1 << i)),
}
}

pub fn rewind(&mut self) {
self.index = 0
}

pub fn step(&mut self) -> u64 {
let delay = self.delays[self.index];
self.index = min(self.index + 1, self.delays.len() - 1);
delay
}
}

async fn process_tcp_listener(
tcp_listener: TcpListener,
udp_bind_ip: IpAddr,
udp_forward_addr: SocketAddr,
tcp_recv_timeout: Option<Duration>,
tcp_nodelay: bool,
) -> ! {
let mut cooldown = Cooldown::<5>::new(100);
loop {
match tcp_listener.accept().await {
Ok((tcp_stream, tcp_peer_addr)) => {
cooldown.rewind();
log::debug!("Incoming connection from {}/TCP", Redact(tcp_peer_addr));
if let Err(error) = crate::tcp_options::set_nodelay(&tcp_stream, tcp_nodelay) {
log::error!("Error: {}", error.display("\nCaused by: "));
Expand All @@ -170,7 +200,12 @@ async fn process_tcp_listener(
}
});
}
Err(error) => log::error!("Error when accepting incoming TCP connection: {}", error),
Err(error) => {
log::error!("Error when accepting incoming TCP connection: {}", error);
if error.raw_os_error().map_or(false, |err|err == OS_ERROR_TOO_MANY_OPEN_FILES) {
sleep(Duration::from_millis(cooldown.step())).await;
}
}
}
}
}
Expand Down

0 comments on commit 0f241b9

Please sign in to comment.