d2cedcb9ff2e511079eee11e6b6d021020e8ea0c
2 use std
::io
::{ MemWriter
, Acceptor
, Listener
, TcpStream
, IoResult
, IoError
, EndOfFile
};
3 use std
::io
::net
::tcp
::{ TcpAcceptor
, TcpListener
};
4 use std
::thread
::Thread
;
6 use packet
::{ Packet
, ReadingResult
, PacketType
};
7 use packet
::PacketType
::{ Command
, Answer
, Error
};
9 // Default timeout when waiting data on a stream (for instance: 'TcpStream::read').
10 static DEFAULT_TIMEOUT
: Option
<u64> = Some(500); // [ms].
13 acceptor
: TcpAcceptor
,
22 current_timestamp
: u64,
23 variant
: packet
::Variant
,
27 pub fn new(interface
: &str, port
: u16, variant
: packet
::Variant
) -> IoResult
<Server
> {
28 let mut acceptor
= try!(TcpListener
::bind((interface
, port
)).listen());
31 acceptor
: acceptor
.clone()
34 Thread
::spawn(move || {
36 for stream
in acceptor
.incoming() {
39 Thread
::spawn(move || {
40 Server
::handle_client(EndPoint
::new(stream
, variant
));
51 pub fn close(&mut self) -> IoResult
<()> {
52 self.acceptor
.close_accept()
55 fn handle_client(mut end_point
: EndPoint
) {
57 match end_point
.read() {
58 Ok(packet@Packet
{ t
: Command(..), .. }) => {
59 end_point
.print("Server", format!("Valid command received: {}", packet
));
60 let answer
= Answer(Packet
::random_packet_data(&[]));
61 match end_point
.send(answer
.clone()) {
63 end_point
.print("Server", format!("Answer sent: {}", answer
)),
65 end_point
.print("Server", format!("Can't send the answer. Error: {}", e
))
68 // Socket has been closed.
69 Err(packet
::ReadingError
::IO(IoError
{ kind
: EndOfFile
, .. })) => {
70 end_point
.print("Server", format!("Connection closed: EOF"));
74 end_point
.print("Server", format!("Error or invalid packet: {}", other
))
81 pub fn new(address
: &str, port
: u16, variant
: packet
::Variant
) -> IoResult
<Client
> {
82 Ok(Client
{ end_point
: EndPoint
{
83 socket
: try!(TcpStream
::connect((address
, port
))),
90 pub fn close(&mut self) -> IoResult
<()> {
91 self.end_point
.close()
94 pub fn send(&mut self, packet
: PacketType
) -> bool
{
97 self.end_point
.print("Client", format!("Sending: {}", packet
));
98 match self.end_point
.send_with_result(packet
) {
99 Ok(Ok(packet@Packet
{ t
: Answer(..), .. })) => {
100 self.end_point
.print("Client", format!("Command transmitted correctly, answer: {}", packet
));
104 self.end_point
.print("Client", format!("Command transmitted correctly, wrong answer: {}", packet
));
108 self.end_point
.print("Client", format!("Answer error: {}", e
));
112 self.end_point
.print("Client", format!("Can't send the packet. Error: {}", e
));
118 self.end_point
.print("Client", format!("Cannot send this type of packet: {}", other
));
124 /// Sends some valid and not-valid packets to the server and check the result.
125 /// For each test a new client is created.
126 pub fn start_tests(address
: &str, port
: u16, variant
: packet
::Variant
) {
127 let execute
= |f
: &mut |&mut Client
| -> bool
| -> bool
{
128 match Client
::new(address
, port
, variant
) {
129 Ok(ref mut client
) => (*f
)(client
),
131 println!("Unable to create a client. Error: {}", e
);
137 fn raw_packet(timestamp
: u64) -> Vec
<u8> {
138 let mut m
= MemWriter
::new();
139 match (Packet
{ t
: Command(Packet
::random_packet_data(&[42])), timestamp
: timestamp
}).write(&mut m
, packet
::Variant
::Weak
) {
145 let mut tests
= vec!(
147 |client
: &mut Client
| -> bool
{
148 println!("Sending a valid packet...");
149 client
.send(Command(Packet
::random_packet_data(&[42])))
152 |client
: &mut Client
| -> bool
{
153 println!("Sending a packet with an unknown type...");
154 client
.end_point
.current_timestamp
+= 1;
155 let mut raw_packet
= raw_packet(client
.end_point
.current_timestamp
);
156 raw_packet
[2] = 0xEE; // Alter the type.
157 match client
.end_point
.send_raw_with_result(raw_packet
.as_slice()) {
158 Ok(Err(packet
::ReadingError
::IO( IoError
{ kind
: io
::TimedOut
, .. }))) => true, // OK: the server should not send any packet.
160 println!("Error: {}", other
);
166 |client
: &mut Client
| -> bool
{
167 println!("Sending a packet with an old timestamp...");
168 client
.end_point
.current_timestamp
+= 1;
169 let raw_packet
= raw_packet(0);
170 match client
.end_point
.send_raw_with_result(raw_packet
.as_slice()) {
171 Ok(Err(packet
::ReadingError
::IO( IoError
{ kind
: io
::TimedOut
, .. }))) => true, // OK: the server should not send any packet.
173 println!("Error: {}", other
);
179 |client
: &mut Client
| -> bool
{
180 println!("Sending a packet with altered crypted data (do not alter the padding)...");
181 client
.end_point
.current_timestamp
+= 1;
182 let mut raw_packet
= raw_packet(client
.end_point
.current_timestamp
);
183 raw_packet
[11] = 0xDE;
184 raw_packet
[12] = 0xAD;
185 raw_packet
[13] = 0xBE;
186 raw_packet
[14] = 0xEF;
187 match client
.end_point
.send_raw_with_result(raw_packet
.as_slice()) {
188 Ok(Ok(Packet
{ t
: Error(packet
::ErrorType
::Auth
), .. })) => true,
190 println!("Error: {}", other
);
196 |client
: &mut Client
| -> bool
{
197 println!("Sending a packet with too small data...");
198 let command
= Command(Packet
::new_packet_data(0, Vec
::from_elem(6, 0x00)));
199 match client
.end_point
.send_with_result(command
) {
200 Ok(Err(packet
::ReadingError
::IO( IoError
{ kind
: io
::TimedOut
, .. }))) => true, // OK: the server should not send any packet.
202 println!("Error: {}", other
);
208 |client
: &mut Client
| -> bool
{
209 println!("Sending a packet with too large data...");
210 let command
= Command(Packet
::new_packet_data(0, Vec
::from_elem(40, 0x00)));
211 match client
.end_point
.send_with_result(command
) {
212 Ok(Err(packet
::ReadingError
::IO( IoError
{ kind
: io
::TimedOut
, .. }))) => true, // OK: the server should not send any packet.
214 println!("Error: {}", other
);
220 |client
: &mut Client
| -> bool
{
221 println!("Sending a packet with wrong padding (all 0)...");
222 client
.end_point
.current_timestamp
+= 1;
223 let mut m
= MemWriter
::new();
224 let raw_packet
= match (Packet
{ t
: Command(Packet
::random_packet_data(&[42])), timestamp
: client
.end_point
.current_timestamp
}).write_with_padding_fun(&mut m
, packet
::Variant
::Weak
, |_
, _
| -> u8 { 0 }) {
229 match client
.end_point
.send_raw_with_result(raw_packet
.as_slice()) {
230 Ok(Ok(Packet
{ t
: Error(packet
::ErrorType
::Crypt
), .. })) => true,
232 println!("Error: {}", other
);
239 let mut nb_test_passed
= 0;
240 for (i
, test
) in range(1, tests
.len()+1).zip(tests
.iter_mut()) {
241 println!("===== Test case #{}:", i
);
244 println!("===== Test passed");
246 println!("===== Test failed");
250 if nb_test_passed
== tests
.len() {
251 println!("All tests passed");
253 println!("#{} test(s) failed", tests
.len() - nb_test_passed
);
259 pub fn new(mut socket
: TcpStream
, variant
: packet
::Variant
) -> EndPoint
{
260 let _
= socket
.set_nodelay(true);
261 EndPoint
{ socket
: socket
, current_timestamp
: 0 , variant
: variant
}
265 fn close(&mut self) -> IoResult
<()> {
266 try!(self.socket
.close_read());
267 try!(self.socket
.close_write());
271 fn print(&self, prefix
: &str, s
: String
) {
272 println!("[{}] time: {}. {}", prefix
, self.current_timestamp
, s
);
275 /// Sends a packet and wait for an answer synchronously.
276 fn send_with_result(&mut self, p
: PacketType
) -> IoResult
<ReadingResult
> {
283 /// Sends arbitrary data and wait for an answer synchronously.
284 /// Doesn't increment the current timestamp.
285 pub fn send_raw_with_result(&mut self, p
: &[u8]) -> IoResult
<ReadingResult
> {
286 self.socket
.set_timeout(DEFAULT_TIMEOUT
);
287 match self.socket
.write(p
) {
293 fn send(&mut self, p
: PacketType
) -> IoResult
<()> {
294 self.socket
.set_timeout(DEFAULT_TIMEOUT
);
295 self.current_timestamp
+= 1;
296 match (Packet
{ t
: p
, timestamp
: self.current_timestamp
}).write(&mut self.socket
, self.variant
) {
297 Err(packet
::WritingError
::IO(e
)) => Err(e
),
302 fn read(&mut self) -> ReadingResult
{
303 fn send_error(ep
: &mut EndPoint
, error_type
: packet
::ErrorType
) {
304 if let Err(e
) = ep
.send(Error(error_type
)) {
305 println!("Unable to send error packet: {}", e
)
309 self.socket
.set_timeout(DEFAULT_TIMEOUT
);
310 match Packet
::read(&mut self.socket
, self.variant
) {
312 if packet
.timestamp
<= self.current_timestamp
{
313 println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp
, packet
);
314 Err(packet
::ReadingError
::InvalidTimestamp
)
316 self.current_timestamp
= packet
.timestamp
+ 1;
320 e @
Err(packet
::ReadingError
::Padding
) => {
321 self.current_timestamp
+= 1;
322 send_error(self, packet
::ErrorType
::Crypt
);
325 e @
Err(packet
::ReadingError
::MACMismatch
) => {
326 self.current_timestamp
+= 1;
327 send_error(self, packet
::ErrorType
::Auth
);