77af33d5014f67964ab172e44e691ca4739dfe79
[crypto_lab1.git] / src / end_point.rs
1 use std::io::{ MemWriter, 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 static DEFAULT_TIMEOUT: Option<u64> = Some(500); // [ms].
7
8 pub struct Server {
9 acceptor: TcpAcceptor
10 }
11
12 pub struct Client {
13 end_point: EndPoint,
14 }
15
16 struct EndPoint {
17 socket: TcpStream,
18 current_timestamp: u64
19 }
20
21 impl Server {
22 pub fn new(interface: &str, port: u16) -> IoResult<Server> {
23 let mut acceptor = try!(TcpListener::bind(interface, port).listen());
24
25 let server = Server {
26 acceptor: acceptor.clone()
27 };
28
29 spawn(proc() {
30 loop {
31 for stream in acceptor.incoming() {
32 match stream {
33 Err(_) => return,
34 Ok(stream) => spawn(proc() {
35 Server::handle_client(EndPoint { socket: stream, current_timestamp: 0 });
36 })
37 }
38 }
39 }
40 });
41
42 Ok(server)
43 }
44
45 pub fn close(&mut self) -> IoResult<()> {
46 self.acceptor.close_accept()
47 }
48
49 fn handle_client(mut end_point: EndPoint) {
50 loop {
51 match end_point.read() {
52 Ok(packet@Packet { t: Command(..), .. }) => {
53 println!("[Server] Valid command received: {}", packet);
54 let answer = Answer(Packet::random_packet_data([]));
55 match end_point.send(answer.clone()) {
56 Ok(_) =>
57 println!("[Server] Answer sent: {}", answer),
58 Err(e) =>
59 println!("[Server] Can't send the answer. Error: {}", e)
60 }
61 },
62 // Socket has been closed.
63 Err(packet::IOReadError(IoError { kind: EndOfFile, .. })) => {
64 println!("[Server] Connection closed: EOF");
65 return
66 },
67 other =>
68 println!("[Server] Error or invalid packet: {}", other)
69 }
70 }
71 }
72 }
73
74 impl Client {
75 pub fn new(address: &str, port: u16) -> IoResult<Client> {
76 Ok(Client { end_point: EndPoint {
77 socket: try!(TcpStream::connect(address, port)),
78 current_timestamp: 0
79 }})
80 }
81
82 pub fn close(&mut self) -> IoResult<()> {
83 self.end_point.close()
84 }
85
86 pub fn send(&mut self, packet: PacketType) {
87 match packet {
88 Command(_) => {
89 println!("[Client] Sending: {}", packet);
90 match self.end_point.send_with_result(packet) {
91 Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
92 println!("[Client] Command transmitted correctly, answer: {}", packet),
93 Ok(Ok(packet)) =>
94 println!("[Client] Command transmitted correctly, wrong answer: {}", packet),
95 Ok(Err(e)) =>
96 println!("[Client] Answer error: {}", e),
97 Err(e) =>
98 println!("[Client] Can't send the packet. Error: {}", e)
99 }
100 },
101 other =>
102 println!("[Client] Cannot send this type of packet: {}", other)
103 }
104 }
105
106 /// Send some valid and not-valid packets to the server and check the result.
107 pub fn start_tests(address: &str, port: u16) {
108 let execute = |f: &mut |&mut Client| -> bool| -> bool {
109 match Client::new(address, port) {
110 Ok(ref mut client) => (*f)(client),
111 Err(e) => {
112 println!("Unable to create a client. Error: {}", e);
113 false
114 }
115 }
116 };
117
118 let mut tests = vec!(
119 |client: &mut Client| -> bool {
120 println!("Send a valid packet...");
121 match client.end_point.send_with_result(Command(Packet::random_packet_data([42]))) {
122 Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
123 true,
124 other => {
125 println!("Error: {}", other);
126 false
127 }
128 }
129 },
130
131 |client: &mut Client| -> bool {
132 println!("Send a packet with an unknown type...");
133 client.end_point.current_timestamp += 1;
134 let mut m = MemWriter::new();
135 match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write(&mut m) {
136 Err(e) => {
137 println!("Error: {}", e)
138 false
139 },
140 _ => {
141 let mut raw_packet = m.unwrap();
142 raw_packet[2] = 0xEE; // Alter the type.
143
144 match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
145 Ok(Err(packet::IOReadError( IoError { kind: TimedOut, .. }))) => true, // The server should not send a packet.
146 other => {
147 println!("Error: {}", other);
148 false
149 }
150 }
151 }
152 }
153 }
154 );
155
156 for (i, test) in range(0, tests.len()).zip(tests.iter_mut()) {
157 println!("===== Test case #{}:", i)
158 if execute(test) {
159 println!("===== Test passed");
160 } else {
161 println!("===== Test failed");
162 break;
163 }
164 }
165
166 // Send a packet with a wrong timestamp.
167 // Send a packet with a maximum timestamp.
168 // Send a packet with altered encrypted data.
169 }
170 }
171
172 impl EndPoint {
173 fn close(&mut self) -> IoResult<()> {
174 try!(self.socket.close_read());
175 try!(self.socket.close_write());
176 Ok(())
177 }
178
179 /// Send a packet and wait for an answer synchronously.
180 fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
181 match self.send(p) {
182 Err(e) => Err(e),
183 _ => Ok(self.read())
184 }
185 }
186
187 /// Send arbitrary data and wait for an answer synchronously.
188 /// Do not increment the current timestamp.
189 fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult<ReadingResult> {
190 self.socket.set_timeout(DEFAULT_TIMEOUT);
191 match self.socket.write(p) {
192 Err(e) => Err(e),
193 _ => Ok(self.read())
194 }
195 }
196
197 fn send(&mut self, p: PacketType) -> IoResult<()> {
198 self.socket.set_timeout(DEFAULT_TIMEOUT);
199 self.current_timestamp += 1;
200 match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
201 Err(packet::WriteIOError(e)) => Err(e),
202 _ => Ok(())
203 }
204 }
205
206 fn read(&mut self) -> ReadingResult {
207 fn send_error(ep: &mut EndPoint, error_type: packet::ErrorType) {
208 match ep.send(Error(error_type)) {
209 Err(e) => println!("Unable to send error packet: {}", e),
210 Ok(_) => ()
211 };
212 };
213
214 self.socket.set_timeout(DEFAULT_TIMEOUT);
215 match Packet::read(&mut self.socket) {
216 Ok(packet) => {
217 if packet.timestamp <= self.current_timestamp {
218 println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
219 Err(packet::InvalidTimestampError)
220 } else {
221 self.current_timestamp = packet.timestamp + 1;
222 Ok(packet)
223 }
224 },
225 e @ Err(packet::PaddingError) => {
226 send_error(self, packet::CryptError);
227 e
228 },
229 e @ Err(packet::MACMismatchError) => {
230 send_error(self, packet::AuthError);
231 e
232 },
233 other =>
234 other
235 }
236 }
237 }