9488d132c5191d2e6899a1c547859bdc1eb5bf91
[crypto_lab1.git] / src / end_point.rs
1 use std::io::{ Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
2 use std::io::net::tcp::{ TcpAcceptor, TcpListener };
3 use packet;
4 use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
5
6 pub struct Server {
7 acceptor: TcpAcceptor
8 }
9
10 pub struct Client {
11 end_point: EndPoint,
12 }
13
14 struct EndPoint {
15 socket: TcpStream,
16 current_timestamp: u64
17 }
18
19 impl Server {
20 pub fn new(port: u16) -> IoResult<Server> {
21 let mut acceptor = try!(TcpListener::bind("127.0.0.1", port).listen());
22
23 let server = Server {
24 acceptor: acceptor.clone()
25 };
26
27 spawn(proc() {
28 loop {
29 for stream in acceptor.incoming() {
30 match stream {
31 Err(_) => return,
32 Ok(stream) => spawn(proc() {
33 Server::handle_client(EndPoint { socket: stream, current_timestamp: 0 });
34 })
35 }
36 }
37 }
38 });
39
40 Ok(server)
41 }
42
43 pub fn close(&mut self) -> IoResult<()> {
44 self.acceptor.close_accept()
45 }
46
47 fn handle_client(mut end_point: EndPoint) {
48 loop {
49 match end_point.read() {
50 Ok(packet@Packet { t: Command(..), .. }) => {
51 println!("[Server] Valid command received: {}", packet);
52 let answer = Answer(Packet::random_packet_data());
53 match end_point.send(answer.clone()) {
54 Ok(_) =>
55 println!("[Server] Answer sent: {}", answer),
56 Err(e) =>
57 println!("[Server] Can't send the answer. Error: {}", e)
58 }
59 },
60 // Socket has been closed.
61 Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => {
62 println!("[Server] Connection closed: EOF");
63 return
64 },
65 other =>
66 println!("[Server] Error or invalid packet: {}", other)
67 }
68 }
69 }
70 }
71
72 impl Client {
73 pub fn new(address: &str, port: u16) -> IoResult<Client> {
74 Ok(Client { end_point: EndPoint {
75 socket: try!(TcpStream::connect(address, port)),
76 current_timestamp: 0
77 }})
78 }
79
80 pub fn close(&mut self) -> IoResult<()> {
81 self.end_point.close()
82 }
83
84 pub fn send(&mut self, packet: PacketType) {
85 match packet {
86 Command(_) => {
87 println!("[Client] Sending: {}", packet);
88 match self.end_point.send_with_result(packet) {
89 Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
90 println!("[Client] Command transmitted correctly, answer: {}", packet),
91 Ok(Ok(packet)) =>
92 println!("[Client] Command transmitted correctly, wrong answer: {}", packet),
93 Ok(Err(e)) =>
94 println!("[Client] Answer error: {}", e),
95 Err(e) =>
96 println!("[Client] Can't send the packet. Error: {}", e)
97 }
98 },
99 other =>
100 println!("[Client] Cannot send this type of packet: {}", other)
101 }
102 }
103 }
104
105 impl EndPoint {
106 fn close(&mut self) -> IoResult<()> {
107 try!(self.socket.close_read());
108 try!(self.socket.close_write());
109 Ok(())
110 }
111
112 /**
113 * Send a packet and wait synchronously an answer.
114 */
115 fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
116 match self.send(p) {
117 Err(e) => Err(e),
118 _ => Ok(self.read())
119 }
120 }
121
122 fn send(&mut self, p: PacketType) -> IoResult<()> {
123 self.current_timestamp += 1;
124 match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
125 Ok(_) => Ok(()),
126 Err(packet::WriteIOError(e)) => Err(e)
127 }
128 }
129
130 fn read(&mut self) -> ReadingResult {
131 fn send_error(ep: &mut EndPoint, error_type: packet::ErrorType) {
132 match ep.send(Error(error_type)) {
133 Err(e) => println!("Unable to send error packet: {}", e),
134 Ok(_) => ()
135 };
136 };
137
138 match Packet::read(&mut self.socket) {
139 Ok(packet) => {
140 if packet.timestamp <= self.current_timestamp {
141 println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
142 Err(packet::InvalidTimestamp)
143 } else {
144 self.current_timestamp = packet.timestamp + 1;
145 Ok(packet)
146 }
147 },
148 e @ Err(packet::PaddingError) => {
149 send_error(self, packet::CryptError);
150 e
151 },
152 e @ Err(packet::MACMismatchError) => {
153 send_error(self, packet::AuthError);
154 e
155 },
156 other =>
157 other
158 }
159 }
160 }