diff --git a/.gitignore b/.gitignore index ea8c4bf..d81f12e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/.idea diff --git a/Cargo.toml b/Cargo.toml index 3f86205..4ecc087 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +threadpool = "1.0" +json = "0.12.4" +openssl = {version = "0.10", features = ["vendored"]} diff --git a/src/http.rs b/src/http.rs new file mode 100644 index 0000000..b94cbb2 --- /dev/null +++ b/src/http.rs @@ -0,0 +1,17 @@ +use std::net::TcpStream; +use openssl::ssl::SslStream; + +pub enum Stream { + Tcp(TcpStream), + Ssl(SslStream), +} + +impl Stream {} + +pub fn connection_handler(client: Stream) { + +} + +fn request_handler(client: Stream) { + +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..1c129da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,64 @@ +mod http; +mod udp; + +use std::thread; +use threadpool::ThreadPool; +use std::net::{TcpListener, UdpSocket}; +use openssl::ssl::{SslMethod, SslAcceptor, SslStream, SslFiletype}; +use std::sync::Arc; +use std::sync::Mutex; + fn main() { - println!("Hello, world!"); + let mut threads = Vec::new(); + + let pool = ThreadPool::new(256); + let pool_mutex = Arc::new(Mutex::new(pool)); + + let pool_mutex_ref = pool_mutex.clone(); + threads.push(thread::spawn(move || { + let mut tcp_socket = TcpListener::bind("[::]:8080").unwrap(); + + for stream in tcp_socket.incoming() { + pool_mutex_ref.lock().unwrap().execute(|| { + let stream = stream.unwrap(); + http::connection_handler(http::Stream::Tcp(stream)); + }); + } + })); + + let pool_mutex_ref = pool_mutex.clone(); + threads.push(thread::spawn(move || { + let mut ssl_socket = TcpListener::bind("[::]:8443").unwrap(); + + let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + acceptor.set_certificate_chain_file("/home/lorenz/Certificates/chakotay.pem").unwrap(); + acceptor.set_private_key_file("/home/lorenz/Certificates/priv/chakotay.key", SslFiletype::PEM).unwrap(); + acceptor.check_private_key().unwrap(); + let acceptor = Arc::new(acceptor.build()); + + for stream in ssl_socket.incoming() { + let acceptor = acceptor.clone(); + pool_mutex_ref.lock().unwrap().execute(move || { + let stream = stream.unwrap(); + let stream = acceptor.accept(stream).unwrap(); + http::connection_handler(http::Stream::Ssl(stream)); + }); + } + })); + + let pool_mutex_ref = pool_mutex.clone(); + threads.push(thread::spawn(move || { + let mut udp_socket = UdpSocket::bind("[::]:12345").unwrap(); + let mut buf = [0; 65_536]; + + loop { + let (size, addr) = udp_socket.recv_from(&mut buf).unwrap(); + let req = udp::Request::new(&udp_socket, addr, size, &buf); + pool_mutex_ref.lock().unwrap().execute(|| udp::handler(req)); + } + })); + + for thread in threads { + thread.join(); + } } diff --git a/src/udp.rs b/src/udp.rs new file mode 100644 index 0000000..9d29a6e --- /dev/null +++ b/src/udp.rs @@ -0,0 +1,23 @@ +use std::net::{UdpSocket, SocketAddr}; + +pub struct Request { + socket: UdpSocket, + address: SocketAddr, + size: usize, + buf: [u8; 65_536], +} + +impl Request { + pub fn new(socket: &UdpSocket, address: SocketAddr, size: usize, buf: &[u8; 65_536]) -> Request { + Request { + socket: socket.try_clone().unwrap(), + address, + size, + buf: buf.clone(), + } + } +} + +pub fn handler(request: Request) { + // TODO handle UDP requests +}