+++ /dev/null
-use std::io::{ MemWriter, Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
-use std::io::net::tcp::{ TcpAcceptor, TcpListener };
-use packet;
-use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
-
-static DEFAULT_TIMEOUT: Option<u64> = Some(500); // [ms].
-
-pub struct Server {
- acceptor: TcpAcceptor
-}
-
-pub struct Client {
- end_point: EndPoint,
-}
-
-struct EndPoint {
- socket: TcpStream,
- current_timestamp: u64
-}
-
-impl Server {
- pub fn new(interface: &str, port: u16) -> IoResult<Server> {
- let mut acceptor = try!(TcpListener::bind(interface, 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)
- }
- }
-
- /// Send some valid and not-valid packets to the server and check the result.
- pub fn start_tests(address: &str, port: u16) {
- let execute = |f: &mut |&mut Client| -> bool| -> bool {
- match Client::new(address, port) {
- Ok(ref mut client) => (*f)(client),
- Err(e) => {
- println!("Unable to create a client. Error: {}", e);
- false
- }
- }
- };
-
- let mut tests = vec!(
- |client: &mut Client| -> bool {
- println!("Send a valid packet...");
- match client.end_point.send_with_result(Command(Packet::random_packet_data([42]))) {
- Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
- true,
- other => {
- println!("Error: {}", other);
- false
- }
- }
- },
-
- |client: &mut Client| -> bool {
- println!("Send a packet with an unknown type...");
- client.end_point.current_timestamp += 1;
- let mut m = MemWriter::new();
- match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write(&mut m) {
- Err(e) => {
- println!("Error: {}", e)
- false
- },
- _ => {
- let mut raw_packet = m.unwrap();
- 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: TimedOut, .. }))) => true, // The server should not send a packet.
- other => {
- println!("Error: {}", other);
- false
- }
- }
- }
- }
- }
- );
-
- for (i, test) in range(0, tests.len()).zip(tests.iter_mut()) {
- println!("===== Test case #{}:", i)
- if execute(test) {
- println!("===== Test passed");
- } else {
- println!("===== Test failed");
- break;
- }
- }
-
- // Send a packet with a wrong timestamp.
- // Send a packet with a maximum timestamp.
- // Send a packet with altered encrypted data.
- }
-}
-
-impl EndPoint {
- fn close(&mut self) -> IoResult<()> {
- try!(self.socket.close_read());
- try!(self.socket.close_write());
- Ok(())
- }
-
- /// Send 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),
- _ => Ok(self.read())
- }
- }
-
- /// Send arbitrary data and wait for an answer synchronously.
- /// Do not increment the current timestamp.
- fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult<ReadingResult> {
- self.socket.set_timeout(DEFAULT_TIMEOUT);
- match self.socket.write(p) {
- Err(e) => Err(e),
- _ => Ok(self.read())
- }
- }
-
- fn send(&mut self, p: PacketType) -> IoResult<()> {
- self.socket.set_timeout(DEFAULT_TIMEOUT);
- self.current_timestamp += 1;
- match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
- Err(packet::WriteIOError(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(_) => ()
- };
- };
-
- self.socket.set_timeout(DEFAULT_TIMEOUT);
- 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::InvalidTimestampError)
- } 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
- }
- }
-}