Fix to the new nightly.
[crypto_lab1.git] / lab1_rust / src / end_point.rs
index 9492d95..d2cedcb 100644 (file)
@@ -1,14 +1,16 @@
 use std::io;
 use std::io::{ MemWriter, Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
 use std::io::net::tcp::{ TcpAcceptor, TcpListener };
+use std::thread::Thread;
 use packet;
-use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
+use packet::{ Packet, ReadingResult, PacketType };
+use packet::PacketType::{ Command, Answer, Error };
 
 // Default timeout when waiting data on a stream (for instance: 'TcpStream::read').
 static DEFAULT_TIMEOUT: Option<u64> = Some(500); // [ms].
 
 pub struct Server {
-   acceptor: TcpAcceptor
+   acceptor: TcpAcceptor,
 }
 
 pub struct Client {
@@ -23,24 +25,25 @@ pub struct EndPoint {
 
 impl Server {
    pub fn new(interface: &str, port: u16, variant: packet::Variant) -> IoResult<Server> {
-      let mut acceptor = try!(TcpListener::bind(interface, port).listen());
+      let mut acceptor = try!(TcpListener::bind((interface, port)).listen());
 
       let server = Server {
          acceptor: acceptor.clone()
       };
 
-      spawn(proc() {
+      Thread::spawn(move || {
          loop {
             for stream in acceptor.incoming() {
                match stream {
-                  Ok(stream) => spawn(proc() {
-                     Server::handle_client(EndPoint::new(stream, variant));
-                  }),
+                  Ok(stream) =>
+                     Thread::spawn(move || {
+                        Server::handle_client(EndPoint::new(stream, variant));
+                     }).detach(),
                   _ => return
                }
             }
          }
-      });
+      }).detach();
 
       Ok(server)
    }
@@ -54,7 +57,7 @@ impl Server {
          match end_point.read() {
             Ok(packet@Packet { t: Command(..), .. }) => {
                end_point.print("Server",  format!("Valid command received: {}", packet));
-               let answer = Answer(Packet::random_packet_data([]));
+               let answer = Answer(Packet::random_packet_data(&[]));
                match end_point.send(answer.clone()) {
                   Ok(_) =>
                      end_point.print("Server", format!("Answer sent: {}", answer)),
@@ -63,7 +66,7 @@ impl Server {
                }
             },
             // Socket has been closed.
-            Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => {
+            Err(packet::ReadingError::IO(IoError { kind: EndOfFile, .. })) => {
                end_point.print("Server", format!("Connection closed: EOF"));
                return
             },
@@ -77,7 +80,7 @@ impl Server {
 impl Client {
    pub fn new(address: &str, port: u16, variant: packet::Variant) -> IoResult<Client> {
       Ok(Client { end_point: EndPoint {
-         socket: try!(TcpStream::connect(address, port)),
+         socket: try!(TcpStream::connect((address, port))),
          current_timestamp: 0,
          variant: variant,
       }})
@@ -118,7 +121,7 @@ impl Client {
       }
    }
 
-   /// Send some valid and not-valid packets to the server and check the result.
+   /// Sends some valid and not-valid packets to the server and check the result.
    /// For each test a new client is created.
    pub fn start_tests(address: &str, port: u16, variant: packet::Variant) {
       let execute = |f: &mut |&mut Client| -> bool| -> bool {
@@ -133,9 +136,9 @@ impl Client {
 
       fn raw_packet(timestamp: u64) -> Vec<u8> {
          let mut m = MemWriter::new();
-         match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: timestamp }).write(&mut m, packet::Weak) {
+         match (Packet { t: Command(Packet::random_packet_data(&[42])), timestamp: timestamp }).write(&mut m, packet::Variant::Weak) {
             Err(_) => vec!(),
-            _ => m.unwrap()
+            _ => m.into_inner()
          }
       }
 
@@ -143,7 +146,7 @@ impl Client {
          // 1)
          |client: &mut Client| -> bool {
             println!("Sending a valid packet...");
-            client.send(Command(Packet::random_packet_data([42])))
+            client.send(Command(Packet::random_packet_data(&[42])))
          },
          // 2)
          |client: &mut Client| -> bool {
@@ -152,7 +155,7 @@ impl Client {
             let mut raw_packet = raw_packet(client.end_point.current_timestamp);
             raw_packet[2] = 0xEE; // Alter the type.
             match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
-               Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
+               Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
                other => {
                   println!("Error: {}", other);
                   false
@@ -165,7 +168,7 @@ impl Client {
             client.end_point.current_timestamp += 1;
             let raw_packet = raw_packet(0);
             match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
-               Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
+               Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
                other => {
                   println!("Error: {}", other);
                   false
@@ -182,7 +185,7 @@ impl Client {
             raw_packet[13] = 0xBE;
             raw_packet[14] = 0xEF;
             match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
-               Ok(Ok(Packet { t: Error(packet::AuthError), .. })) => true,
+               Ok(Ok(Packet { t: Error(packet::ErrorType::Auth), .. })) => true,
                other => {
                   println!("Error: {}", other);
                   false
@@ -194,7 +197,7 @@ impl Client {
             println!("Sending a packet with too small data...");
             let command = Command(Packet::new_packet_data(0, Vec::from_elem(6, 0x00)));
             match client.end_point.send_with_result(command) {
-               Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
+               Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
                other => {
                   println!("Error: {}", other);
                   false
@@ -206,7 +209,7 @@ impl Client {
             println!("Sending a packet with too large data...");
             let command = Command(Packet::new_packet_data(0, Vec::from_elem(40, 0x00)));
             match client.end_point.send_with_result(command) {
-               Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
+               Ok(Err(packet::ReadingError::IO( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
                other => {
                   println!("Error: {}", other);
                   false
@@ -218,13 +221,13 @@ impl Client {
             println!("Sending a packet with wrong padding (all 0)...");
             client.end_point.current_timestamp += 1;
             let mut m = MemWriter::new();
-            let raw_packet = match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write_with_padding_fun(&mut m, packet::Weak, |_, _| -> u8 { 0 }) {
+            let raw_packet = match (Packet { t: Command(Packet::random_packet_data(&[42])), timestamp: client.end_point.current_timestamp }).write_with_padding_fun(&mut m, packet::Variant::Weak, |_, _| -> u8 { 0 }) {
                Err(_) => vec!(),
-               _ => m.unwrap()
+               _ => m.into_inner()
             };
 
             match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
-               Ok(Ok(Packet { t: Error(packet::CryptError), .. })) => true,
+               Ok(Ok(Packet { t: Error(packet::ErrorType::Crypt), .. })) => true,
                other => {
                   println!("Error: {}", other);
                   false
@@ -235,7 +238,7 @@ impl Client {
 
       let mut nb_test_passed = 0;
       for (i, test) in range(1, tests.len()+1).zip(tests.iter_mut()) {
-         println!("===== Test case #{}:", i)
+         println!("===== Test case #{}:", i);
          if execute(test) {
             nb_test_passed += 1;
             println!("===== Test passed");
@@ -269,7 +272,7 @@ impl EndPoint {
       println!("[{}] time: {}. {}", prefix, self.current_timestamp, s);
    }
 
-   /// Send a packet and wait for an answer synchronously.
+   /// Sends a packet and wait for an answer synchronously.
    fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
       match self.send(p) {
          Err(e) => Err(e),
@@ -277,8 +280,8 @@ impl EndPoint {
       }
    }
 
-   /// Send arbitrary data and wait for an answer synchronously.
-   /// Do not increment the current timestamp.
+   /// Sends arbitrary data and wait for an answer synchronously.
+   /// Doesn't increment the current timestamp.
    pub fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult<ReadingResult> {
       self.socket.set_timeout(DEFAULT_TIMEOUT);
       match self.socket.write(p) {
@@ -291,17 +294,16 @@ impl EndPoint {
       self.socket.set_timeout(DEFAULT_TIMEOUT);
       self.current_timestamp += 1;
       match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket, self.variant) {
-         Err(packet::WriteIOError(e)) => Err(e),
+         Err(packet::WritingError::IO(e)) => Err(e),
          _ => Ok(())
       }
    }
 
    fn read(&mut self) -> ReadingResult {
       fn send_error(ep: &mut EndPoint, error_type: packet::ErrorType) {
-         match ep.send(Error(error_type)) {
-            Err(e) => println!("Unable to send error packet: {}", e),
-            Ok(_) => ()
-         };
+         if let Err(e) = ep.send(Error(error_type)) {
+            println!("Unable to send error packet: {}", e)
+         }
       };
 
       self.socket.set_timeout(DEFAULT_TIMEOUT);
@@ -309,20 +311,20 @@ impl EndPoint {
          Ok(packet) => {
             if packet.timestamp <= self.current_timestamp {
                println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
-               Err(packet::InvalidTimestampError)
+               Err(packet::ReadingError::InvalidTimestamp)
             } else {
                self.current_timestamp = packet.timestamp + 1;
                Ok(packet)
             }
          },
-         e @ Err(packet::PaddingError) => {
+         e @ Err(packet::ReadingError::Padding) => {
             self.current_timestamp += 1;
-            send_error(self, packet::CryptError);
+            send_error(self, packet::ErrorType::Crypt);
             e
          },
-         e @ Err(packet::MACMismatchError) => {
+         e @ Err(packet::ReadingError::MACMismatch) => {
             self.current_timestamp += 1;
-            send_error(self, packet::AuthError);
+            send_error(self, packet::ErrorType::Auth);
             e
          },
          other =>