Clean some warnings.
[crypto_lab1.git] / src / end_point.rs
1 use std::io;
2 use std::io::{ MemWriter, Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
3 use std::io::net::tcp::{ TcpAcceptor, TcpListener };
4 use packet;
5 use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
6
7 static DEFAULT_TIMEOUT: Option<u64> = Some(500); // [ms].
8
9 pub struct Server {
10 acceptor: TcpAcceptor
11 }
12
13 pub struct Client {
14 end_point: EndPoint,
15 }
16
17 struct EndPoint {
18 socket: TcpStream,
19 current_timestamp: u64
20 }
21
22 impl Server {
23 pub fn new(interface: &str, port: u16) -> IoResult<Server> {
24 let mut acceptor = try!(TcpListener::bind(interface, port).listen());
25
26 let server = Server {
27 acceptor: acceptor.clone()
28 };
29
30 spawn(proc() {
31 loop {
32 for stream in acceptor.incoming() {
33 match stream {
34 Err(_) => return,
35 Ok(stream) => spawn(proc() {
36 Server::handle_client(EndPoint { socket: stream, current_timestamp: 0 });
37 })
38 }
39 }
40 }
41 });
42
43 Ok(server)
44 }
45
46 pub fn close(&mut self) -> IoResult<()> {
47 self.acceptor.close_accept()
48 }
49
50 fn handle_client(mut end_point: EndPoint) {
51 loop {
52 match end_point.read() {
53 Ok(packet@Packet { t: Command(..), .. }) => {
54 println!("[Server] Valid command received: {}", packet);
55 let answer = Answer(Packet::random_packet_data([]));
56 match end_point.send(answer.clone()) {
57 Ok(_) =>
58 println!("[Server] Answer sent: {}", answer),
59 Err(e) =>
60 println!("[Server] Can't send the answer. Error: {}", e)
61 }
62 },
63 // Socket has been closed.
64 Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => {
65 println!("[Server] Connection closed: EOF");
66 return
67 },
68 other =>
69 println!("[Server] Error or invalid packet: {}", other)
70 }
71 }
72 }
73 }
74
75 impl Client {
76 pub fn new(address: &str, port: u16) -> IoResult<Client> {
77 Ok(Client { end_point: EndPoint {
78 socket: try!(TcpStream::connect(address, port)),
79 current_timestamp: 0
80 }})
81 }
82
83 pub fn close(&mut self) -> IoResult<()> {
84 self.end_point.close()
85 }
86
87 pub fn send(&mut self, packet: PacketType) {
88 match packet {
89 Command(_) => {
90 println!("[Client] Sending: {}", packet);
91 match self.end_point.send_with_result(packet) {
92 Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
93 println!("[Client] Command transmitted correctly, answer: {}", packet),
94 Ok(Ok(packet)) =>
95 println!("[Client] Command transmitted correctly, wrong answer: {}", packet),
96 Ok(Err(e)) =>
97 println!("[Client] Answer error: {}", e),
98 Err(e) =>
99 println!("[Client] Can't send the packet. Error: {}", e)
100 }
101 },
102 other =>
103 println!("[Client] Cannot send this type of packet: {}", other)
104 }
105 }
106
107 /// Send some valid and not-valid packets to the server and check the result.
108 pub fn start_tests(address: &str, port: u16) {
109 let execute = |f: &mut |&mut Client| -> bool| -> bool {
110 match Client::new(address, port) {
111 Ok(ref mut client) => (*f)(client),
112 Err(e) => {
113 println!("Unable to create a client. Error: {}", e);
114 false
115 }
116 }
117 };
118
119 fn raw_packet(timestamp: u64) -> Vec<u8> {
120 let mut m = MemWriter::new();
121 match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: timestamp }).write(&mut m) {
122 Err(_) => vec!(),
123 _ => m.unwrap()
124 }
125 }
126
127 let mut tests = vec!(
128 |client: &mut Client| -> bool {
129 println!("Send a valid packet...");
130 match client.end_point.send_with_result(Command(Packet::random_packet_data([42]))) {
131 Ok(Ok(Packet { t: Answer(..), .. })) => true,
132 other => {
133 println!("Error: {}", other);
134 false
135 }
136 }
137 },
138
139 |client: &mut Client| -> bool {
140 println!("Send a packet with an unknown type...");
141 client.end_point.current_timestamp += 1;
142 let mut raw_packet = raw_packet(client.end_point.current_timestamp);
143 raw_packet[2] = 0xEE; // Alter the type.
144 match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
145 Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
146 other => {
147 println!("Error: {}", other);
148 false
149 }
150 }
151 },
152
153 |client: &mut Client| -> bool {
154 println!("Send a packet with an old timestamp...");
155 client.end_point.current_timestamp += 1;
156 let raw_packet = raw_packet(0);
157 match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
158 Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
159 other => {
160 println!("Error: {}", other);
161 false
162 }
163 }
164 },
165
166 |client: &mut Client| -> bool {
167 println!("Send a packet with altered crypted data...");
168 client.end_point.current_timestamp += 1;
169 let mut raw_packet = raw_packet(client.end_point.current_timestamp);
170 raw_packet[11] = 0xDE;
171 raw_packet[12] = 0xAD;
172 raw_packet[13] = 0xBE;
173 raw_packet[14] = 0xEF;
174 match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
175 Ok(Ok(Packet { t: Error(packet::AuthError), .. })) => true,
176 other => {
177 println!("Error: {}", other);
178 false
179 }
180 }
181 },
182
183 |client: &mut Client| -> bool {
184 println!("Send a packet with too small data...");
185 let command = Command(Packet::new_packet_data(0, Vec::from_elem(6, 0x00)));
186 match client.end_point.send_with_result(command) {
187 Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
188 other => {
189 println!("Error: {}", other);
190 false
191 }
192 }
193 },
194
195 |client: &mut Client| -> bool {
196 println!("Send a packet with too large data...");
197 let command = Command(Packet::new_packet_data(0, Vec::from_elem(40, 0x00)));
198 match client.end_point.send_with_result(command) {
199 Ok(Err(packet::IOReadError( IoError { kind: io::TimedOut, .. }))) => true, // OK: the server should not send any packet.
200 other => {
201 println!("Error: {}", other);
202 false
203 }
204 }
205 },
206
207 |client: &mut Client| -> bool {
208 println!("Send a packet with wrong padding...");
209 client.end_point.current_timestamp += 1;
210 let mut m = MemWriter::new();
211 let raw_packet = match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write_with_padding_fun(&mut m, |_, _| -> u8 { 0 }) {
212 Err(_) => vec!(),
213 _ => m.unwrap()
214 };
215
216 match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
217 Ok(Ok(Packet { t: Error(packet::CryptError), .. })) => true,
218 other => {
219 println!("Error: {}", other);
220 false
221 }
222 }
223 },
224 );
225
226 let mut nb_test_passed = 0;
227 for (i, test) in range(1, tests.len()+1).zip(tests.iter_mut()) {
228 println!("===== Test case #{}:", i)
229 if execute(test) {
230 nb_test_passed += 1;
231 println!("===== Test passed");
232 } else {
233 println!("===== Test failed");
234 }
235 }
236
237 if nb_test_passed == tests.len() {
238 println!("All tests passed");
239 } else {
240 println!("#{} test(s) failed", tests.len() - nb_test_passed);
241 }
242 }
243 }
244
245 impl EndPoint {
246 fn close(&mut self) -> IoResult<()> {
247 try!(self.socket.close_read());
248 try!(self.socket.close_write());
249 Ok(())
250 }
251
252 /// Send a packet and wait for an answer synchronously.
253 fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
254 match self.send(p) {
255 Err(e) => Err(e),
256 _ => Ok(self.read())
257 }
258 }
259
260 /// Send arbitrary data and wait for an answer synchronously.
261 /// Do not increment the current timestamp.
262 fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult<ReadingResult> {
263 self.socket.set_timeout(DEFAULT_TIMEOUT);
264 match self.socket.write(p) {
265 Err(e) => Err(e),
266 _ => Ok(self.read())
267 }
268 }
269
270 fn send(&mut self, p: PacketType) -> IoResult<()> {
271 self.socket.set_timeout(DEFAULT_TIMEOUT);
272 self.current_timestamp += 1;
273 match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
274 Err(packet::WriteIOError(e)) => Err(e),
275 _ => Ok(())
276 }
277 }
278
279 fn read(&mut self) -> ReadingResult {
280 fn send_error(ep: &mut EndPoint, error_type: packet::ErrorType) {
281 match ep.send(Error(error_type)) {
282 Err(e) => println!("Unable to send error packet: {}", e),
283 Ok(_) => ()
284 };
285 };
286
287 self.socket.set_timeout(DEFAULT_TIMEOUT);
288 match Packet::read(&mut self.socket) {
289 Ok(packet) => {
290 if packet.timestamp <= self.current_timestamp {
291 println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
292 Err(packet::InvalidTimestampError)
293 } else {
294 self.current_timestamp = packet.timestamp + 1;
295 Ok(packet)
296 }
297 },
298 e @ Err(packet::PaddingError) => {
299 self.current_timestamp += 1;
300 send_error(self, packet::CryptError);
301 e
302 },
303 e @ Err(packet::MACMismatchError) => {
304 self.current_timestamp += 1;
305 send_error(self, packet::AuthError);
306 e
307 },
308 other =>
309 other
310 }
311 }
312 }