tcp listener ctrl-c handler #51

Merged
JakeHillion merged 1 commits from tls-improvements into main 2022-05-24 21:10:36 +01:00
4 changed files with 59 additions and 22 deletions

1
Cargo.lock generated
View File

@ -132,6 +132,7 @@ dependencies = [
"exitcode",
"httparse",
"ipnetwork",
"lazy_static",
"libc",
"log",
"nix",

View File

@ -30,6 +30,7 @@ anyhow = "1"
httparse = "1"
rustls = "0.20"
rustls-pemfile = "1"
lazy_static = "1"
[[bench]]
name = "clone3"

55
examples/tls/listener.rs Normal file
View File

@ -0,0 +1,55 @@
use std::fs::File;
use std::io::ErrorKind;
use std::net::TcpListener;
use std::os::unix::io::AsRawFd;
use std::sync::atomic::{AtomicBool, Ordering};
use nix::poll::{poll, PollFd, PollFlags};
use nix::sys::signal::{signal, SigHandler, Signal};
use nix::Error as NixError;
use lazy_static::lazy_static;
lazy_static! {
static ref RUNNING: AtomicBool = AtomicBool::new(true);
}
pub(crate) fn handler(tls_handler_trigger: File, listener: TcpListener) -> i32 {
println!("connection_listener entered");
// SAFETY: only unsafe if you use the result
unsafe { signal(Signal::SIGINT, SigHandler::Handler(handle_sigint)) }.unwrap();
listener.set_nonblocking(true).unwrap();
let mut to_poll = [PollFd::new(listener.as_raw_fd(), PollFlags::POLLIN)];
while RUNNING.load(Ordering::Relaxed) {
if let Err(e) = poll(&mut to_poll, 1000) {
if e == NixError::EINTR {
continue; // timed out
}
Err(e).unwrap()
}
let stream = match listener.accept() {
Ok(s) => s,
Err(e) => {
if e.kind() != ErrorKind::WouldBlock {
Err(e).unwrap()
} else {
continue;
}
}
};
println!("received a new connection");
super::tls_handler(&tls_handler_trigger, stream.0);
}
exitcode::OK
}
extern "C" fn handle_sigint(signal: libc::c_int) {
let signal = Signal::try_from(signal).unwrap();
RUNNING.store(signal != Signal::SIGINT, Ordering::Relaxed);
}

View File

@ -1,4 +1,5 @@
mod http;
mod listener;
mod tls;
use std::fs::File;
@ -41,29 +42,8 @@ fn connection_listener_entrypoint() {
.expect("tcp listener should be a file descriptor");
let tcp_listener = unsafe { TcpListener::from_raw_fd(tcp_listener) };
// actual function body
fn connection_listener(tls_handler_trigger: File, tcp_listener: TcpListener) -> i32 {
println!("connection_listener entered");
// handle incoming connections
for stream in tcp_listener.incoming() {
let stream = match stream {
Ok(s) => s,
Err(e) => {
println!("connection listener: error: {}", e);
return 1;
}
};
println!("received a new connection");
tls_handler(&tls_handler_trigger, stream);
}
exitcode::OK
}
// run function
std::process::exit(connection_listener(tls_handler_trigger, tcp_listener));
std::process::exit(listener::handler(tls_handler_trigger, tcp_listener));
}
fn tls_handler(trigger_socket: &File, stream: TcpStream) {