From 361aa9a5d76e08aa6b369e1d072fe20a9fd468e1 Mon Sep 17 00:00:00 2001 From: Jan Wolff Date: Tue, 26 May 2020 07:36:53 +0200 Subject: [PATCH] correctly spawn multiple tcp listeners for each address --- doc/sheldond.conf | 2 +- src/server/handler.rs | 4 +-- src/server/mod.rs | 60 +++++++++++++++++++++++++++++++----------- src/server/response.rs | 5 ---- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/doc/sheldond.conf b/doc/sheldond.conf index 1c04c87..cbcdc59 100644 --- a/doc/sheldond.conf +++ b/doc/sheldond.conf @@ -6,7 +6,7 @@ gem_root = ./doc # you can define as many of these as you like listen = 0.0.0.0:1965 -listen = [::]:1965 +listen = [::1]:1965 # privilege level for the server to drop to after initializing user = nobody diff --git a/src/server/handler.rs b/src/server/handler.rs index db45073..0522f50 100644 --- a/src/server/handler.rs +++ b/src/server/handler.rs @@ -20,10 +20,10 @@ fn send_header(stream: &mut SslStream, header: &response::Header) { } pub fn handle_request(config: &ServerConfig, mut stream: SslStream) { - let mut buffer = [0; 1024]; + let mut buffer = [0; 1025]; match stream.ssl_read(&mut buffer) { Ok(s) => { - if s == 0 || s > 1025 { + if s == 0 || s > 1024 { send_header(&mut stream, &response::bad_request()); return; } diff --git a/src/server/mod.rs b/src/server/mod.rs index a38e194..54a936c 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -114,12 +114,19 @@ impl Server { println!("serving..."); let acceptor = Server::build_acceptor(&self.config); + let mut listeners = Vec::new(); for addr in &self.config.addrs { + let listener = match TcpListener::bind(addr) { + Ok(listener) => listener, + Err(_) => { + println!("failed listening on: {}", addr); + return; + } + }; + listeners.push(listener); println!("listening on: {}", addr); } - let listener = TcpListener::bind(&self.config.addrs[..]).unwrap(); - if self.config.user.is_root() { panic!("refusing to run as root"); } @@ -140,21 +147,42 @@ impl Server { } }; - for stream in listener.incoming() { - println!("new connection"); - match stream { - Ok(stream) => { - let acceptor = acceptor.clone(); - let config = self.config.clone(); - thread::spawn(move || { - let stream = acceptor.accept(stream).unwrap(); - handler::handle_request(&config, stream); - println!("closing connection"); - }); - } + let mut threads = Vec::new(); + for listener in listeners { + let config = self.config.clone(); + let acceptor = acceptor.clone(); + let t = thread::spawn(move || listener_loop(config, listener, acceptor)); + threads.push(t); + } + + for t in threads { + match t.join() { + Ok(_) => { + println!("failure! one listening thread exited"); + }, Err(_) => { - println!("connection failed"); - } + println!("failure! one listening thread exited"); + }, + }; + } + } +} + +fn listener_loop(config: ServerConfig, listener: TcpListener, acceptor: std::sync::Arc) { + for stream in listener.incoming() { + println!("new connection"); + match stream { + Ok(stream) => { + let acceptor = acceptor.clone(); + let config = config.clone(); + thread::spawn(move || { + let stream = acceptor.accept(stream).unwrap(); + handler::handle_request(&config, stream); + println!("closing connection"); + }); + } + Err(_) => { + println!("connection failed"); } } } diff --git a/src/server/response.rs b/src/server/response.rs index 263b2e3..7e2e542 100644 --- a/src/server/response.rs +++ b/src/server/response.rs @@ -4,7 +4,6 @@ use std::vec::Vec; pub enum Status { Success = 20, RedirectPermanent = 31, - PermanentFailure = 50, NotFound = 51, ProxyRequestRefused = 53, BadRequest = 59, @@ -36,10 +35,6 @@ pub fn redirect_permanent(meta: &str) -> Header { Header::new(Status::RedirectPermanent, meta) } -pub fn permanent_failure() -> Header { - Header::new(Status::PermanentFailure, "permanent failure") -} - pub fn not_found() -> Header { Header::new(Status::NotFound, "not found") }