|
| 1 | +use std::thread; |
| 2 | +use std::io::{Error as IoError, ErrorKind as IoErrorKind, Write}; |
| 3 | +use std::net::{Shutdown, TcpListener, TcpStream}; |
| 4 | +use fortanix_vme_abi::{self, Error, Response, Request}; |
| 5 | + |
| 6 | +pub struct Server { |
| 7 | + port: u16, |
| 8 | +} |
| 9 | + |
| 10 | +impl Server { |
| 11 | + pub fn new() -> Self { |
| 12 | + Server { |
| 13 | + port: fortanix_vme_abi::SERVER_PORT, |
| 14 | + } |
| 15 | + } |
| 16 | + |
| 17 | + fn read_request(stream: &mut TcpStream) -> Result<Request, Error> { |
| 18 | + // Blocks until a full `Request` object is received |
| 19 | + let mut deser = serde_cbor::Deserializer::from_reader(stream).into_iter::<Request>(); |
| 20 | + let req = deser |
| 21 | + .next() |
| 22 | + .ok_or(Error::ReadFailed)? |
| 23 | + .map_err(|e| Error::DeserializationError(e))?; |
| 24 | + Ok(req) |
| 25 | + } |
| 26 | + |
| 27 | + fn handle_client(stream: &mut TcpStream) -> Result<(), IoError> { |
| 28 | + let request = Self::read_request(stream).map_err(|_e| IoError::new(IoErrorKind::InvalidInput, "Failed to read request"))?; |
| 29 | + let response = match request { |
| 30 | + Request::Connect{ addr } => { |
| 31 | + println!("Received connect request to : {:?}", addr); |
| 32 | + Response::Connected { |
| 33 | + port: 42, |
| 34 | + local_addr: "local".to_string(), |
| 35 | + peer_addr: "peer".to_string() |
| 36 | + } |
| 37 | + }, |
| 38 | + }; |
| 39 | + stream.write(&response.serialize().unwrap())?; |
| 40 | + Ok(()) |
| 41 | + } |
| 42 | + |
| 43 | + pub fn run(&self) -> std::io::Result<()> { |
| 44 | + let listener = TcpListener::bind(format!("127.0.0.1:{}", self.port))?; |
| 45 | + |
| 46 | + for stream in listener.incoming() { |
| 47 | + let result = stream |
| 48 | + .map_err(|e| format!("Failed to connect to client: {}", e)) |
| 49 | + .map(|mut stream| thread::Builder::new() |
| 50 | + .spawn(move || { |
| 51 | + if let Err(e) = Self::handle_client(&mut stream) { |
| 52 | + eprintln!("Error handling connection: {}, shutting connection down", e); |
| 53 | + let _ = stream.shutdown(Shutdown::Both); |
| 54 | + } |
| 55 | + }).map_err(|_| "Launch failed")); |
| 56 | + |
| 57 | + if let Err(e) = result { |
| 58 | + eprintln!("Error: {}", e); |
| 59 | + } |
| 60 | + } |
| 61 | + Ok(()) |
| 62 | + } |
| 63 | +} |
| 64 | + |
0 commit comments