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