--- /dev/null
+use std::io::{ Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
+use std::io::net::tcp::{ TcpAcceptor, TcpListener };
+use packet;
+use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
+
+pub struct Server {
+ acceptor: TcpAcceptor
+}
+
+pub struct Client {
+ end_point: EndPoint,
+}
+
+struct EndPoint {
+ socket: TcpStream,
+ current_timestamp: u64
+}
+
+impl Server {
+ pub fn new(port: u16) -> IoResult<Server> {
+ let mut acceptor = try!(TcpListener::bind("127.0.0.1", port).listen());
+
+ let server = Server {
+ acceptor: acceptor.clone()
+ };
+
+ spawn(proc() {
+ loop {
+ for stream in acceptor.incoming() {
+ match stream {
+ Err(_) => return,
+ Ok(stream) => spawn(proc() {
+ Server::handle_client(EndPoint { socket: stream, current_timestamp: 0 });
+ })
+ }
+ }
+ }
+ });
+
+ Ok(server)
+ }
+
+ pub fn close(&mut self) -> IoResult<()> {
+ self.acceptor.close_accept()
+ }
+
+ fn handle_client(mut end_point: EndPoint) {
+ loop {
+ match end_point.read() {
+ Ok(packet@Packet { t: Command(..), .. }) => {
+ println!("[Server] Valid command received: {}", packet);
+ let answer = Answer(Packet::random_packet_data());
+ match end_point.send(answer.clone()) {
+ Ok(_) =>
+ println!("[Server] Answer sent: {}", answer),
+ Err(e) =>
+ println!("[Server] Can't send the answer. Error: {}", e)
+ }
+ },
+ // Socket has been closed.
+ Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => {
+ println!("[Server] Connection closed: EOF");
+ return
+ },
+ other =>
+ println!("[Server] Error or invalid packet: {}", other)
+ }
+ }
+ }
+}
+
+impl Client {
+ pub fn new(address: &str, port: u16) -> IoResult<Client> {
+ Ok(Client { end_point: EndPoint {
+ socket: try!(TcpStream::connect(address, port)),
+ current_timestamp: 0
+ }})
+ }
+
+ pub fn close(&mut self) -> IoResult<()> {
+ self.end_point.close()
+ }
+
+ pub fn send(&mut self, packet: PacketType) {
+ match packet {
+ Command(_) => {
+ println!("[Client] Sending: {}", packet);
+ match self.end_point.send_with_result(packet) {
+ Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
+ println!("[Client] Command transmitted correctly, answer: {}", packet),
+ Ok(Ok(packet)) =>
+ println!("[Client] Command transmitted correctly, wrong answer: {}", packet),
+ Ok(Err(e)) =>
+ println!("[Client] Answer error: {}", e),
+ Err(e) =>
+ println!("[Client] Can't send the packet. Error: {}", e)
+ }
+ },
+ other =>
+ println!("[Client] Cannot send this type of packet: {}", other)
+ }
+ }
+}
+
+impl EndPoint {
+ fn close(&mut self) -> IoResult<()> {
+ try!(self.socket.close_read());
+ try!(self.socket.close_write());
+ Ok(())
+ }
+
+ /**
+ * Send a packet and wait synchronously an answer.
+ */
+ fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
+ match self.send(p) {
+ Err(e) => Err(e),
+ _ => Ok(self.read())
+ }
+ }
+
+ fn send(&mut self, p: PacketType) -> IoResult<()> {
+ self.current_timestamp += 1;
+ match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
+ Ok(_) => Ok(()),
+ Err(packet::WriteIOError(e)) => Err(e)
+ }
+ }
+
+ 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(_) => ()
+ };
+ };
+
+ match Packet::read(&mut self.socket) {
+ Ok(packet) => {
+ if packet.timestamp <= self.current_timestamp {
+ println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
+ Err(packet::InvalidTimestamp)
+ } else {
+ self.current_timestamp = packet.timestamp + 1;
+ Ok(packet)
+ }
+ },
+ e @ Err(packet::PaddingError) => {
+ send_error(self, packet::CryptError);
+ e
+ },
+ e @ Err(packet::MACMismatchError) => {
+ send_error(self, packet::AuthError);
+ e
+ },
+ other =>
+ other
+ }
+ }
+}
\ No newline at end of file