Skip to content

Commit c2311a3

Browse files
committedDec 24, 2016
Add tests for TCP state machine.
1 parent 34741f2 commit c2311a3

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed
 

‎src/socket/tcp.rs

+118
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,122 @@ mod test {
334334
assert_eq!(buffer.dequeue(8), b"zho"); // ........
335335
buffer.enqueue(8).copy_from_slice(b"gefug"); // ...gefug
336336
}
337+
338+
const LOCAL_IP: IpAddress = IpAddress::v4(10, 0, 0, 1);
339+
const REMOTE_IP: IpAddress = IpAddress::v4(10, 0, 0, 2);
340+
const LOCAL_PORT: u16 = 80;
341+
const REMOTE_PORT: u16 = 49500;
342+
const LOCAL_END: IpEndpoint = IpEndpoint::new(LOCAL_IP, LOCAL_PORT);
343+
const REMOTE_END: IpEndpoint = IpEndpoint::new(REMOTE_IP, REMOTE_PORT);
344+
const LOCAL_SEQ: i32 = 100;
345+
const REMOTE_SEQ: i32 = !100;
346+
347+
const SEND_TEMPL: TcpRepr<'static> = TcpRepr {
348+
src_port: REMOTE_PORT, dst_port: LOCAL_PORT,
349+
control: TcpControl::None,
350+
seq_number: 0, ack_number: Some(0),
351+
window_len: 256, payload: &[]
352+
};
353+
const RECV_TEMPL: TcpRepr<'static> = TcpRepr {
354+
src_port: LOCAL_PORT, dst_port: REMOTE_PORT,
355+
control: TcpControl::None,
356+
seq_number: 0, ack_number: Some(0),
357+
window_len: 128, payload: &[]
358+
};
359+
360+
macro_rules! send {
361+
($socket:ident, $repr:expr) => ({
362+
let repr = $repr;
363+
let mut buffer = vec![0; repr.buffer_len()];
364+
let mut packet = TcpPacket::new(&mut buffer).unwrap();
365+
repr.emit(&mut packet, &REMOTE_IP, &LOCAL_IP);
366+
let result = $socket.collect(&REMOTE_IP, &LOCAL_IP, IpProtocol::Tcp,
367+
&packet.into_inner()[..]);
368+
result.expect("send error")
369+
})
370+
}
371+
372+
macro_rules! recv {
373+
($socket:ident, $expected:expr) => ({
374+
let result = $socket.dispatch(&mut |src_addr, dst_addr, protocol, payload| {
375+
assert_eq!(protocol, IpProtocol::Tcp);
376+
assert_eq!(src_addr, &LOCAL_IP);
377+
assert_eq!(dst_addr, &REMOTE_IP);
378+
379+
let mut buffer = vec![0; payload.buffer_len()];
380+
payload.emit(src_addr, dst_addr, &mut buffer);
381+
let packet = TcpPacket::new(&buffer[..]).unwrap();
382+
let repr = TcpRepr::parse(&packet, src_addr, dst_addr).unwrap();
383+
assert_eq!(repr, $expected);
384+
Ok(())
385+
});
386+
assert_eq!(result, Ok(()));
387+
let result = $socket.dispatch(&mut |_src_addr, _dst_addr, _protocol, _payload| {
388+
Ok(())
389+
});
390+
assert_eq!(result, Err(Error::Exhausted));
391+
})
392+
}
393+
394+
fn init_logger() {
395+
extern crate log;
396+
use std::boxed::Box;
397+
398+
struct Logger(());
399+
400+
impl log::Log for Logger {
401+
fn enabled(&self, _metadata: &log::LogMetadata) -> bool {
402+
true
403+
}
404+
405+
fn log(&self, record: &log::LogRecord) {
406+
println!("{}", record.args());
407+
}
408+
}
409+
410+
let _ = log::set_logger(|max_level| {
411+
max_level.set(log::LogLevelFilter::Trace);
412+
Box::new(Logger(()))
413+
});
414+
415+
println!("");
416+
}
417+
418+
fn socket() -> TcpSocket<'static> {
419+
init_logger();
420+
421+
let rx_buffer = SocketBuffer::new(vec![0; 128]);
422+
let tx_buffer = SocketBuffer::new(vec![0; 128]);
423+
match TcpSocket::new(rx_buffer, tx_buffer) {
424+
Socket::Tcp(socket) => socket,
425+
_ => unreachable!()
426+
}
427+
}
428+
429+
#[test]
430+
fn test_handshake() {
431+
let mut s = socket();
432+
s.listen(IpEndpoint::new(IpAddress::default(), LOCAL_PORT));
433+
assert_eq!(s.state(), State::Listen);
434+
435+
send!(s, TcpRepr {
436+
control: TcpControl::Syn,
437+
seq_number: LOCAL_SEQ, ack_number: None,
438+
..SEND_TEMPL
439+
});
440+
assert_eq!(s.state(), State::SynReceived);
441+
assert_eq!(s.local_endpoint(), LOCAL_END);
442+
assert_eq!(s.remote_endpoint(), REMOTE_END);
443+
recv!(s, TcpRepr {
444+
control: TcpControl::Syn,
445+
seq_number: REMOTE_SEQ, ack_number: Some(LOCAL_SEQ + 1),
446+
..RECV_TEMPL
447+
});
448+
send!(s, TcpRepr {
449+
control: TcpControl::None,
450+
seq_number: LOCAL_SEQ + 1, ack_number: Some(REMOTE_SEQ + 1),
451+
..SEND_TEMPL
452+
});
453+
assert_eq!(s.state(), State::Established);
454+
}
337455
}

‎src/wire/ip.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl Endpoint {
8787
pub const UNSPECIFIED: Endpoint = Endpoint { addr: Address::Unspecified, port: 0 };
8888

8989
/// Create an endpoint address from given address and port.
90-
pub fn new(addr: Address, port: u16) -> Endpoint {
90+
pub const fn new(addr: Address, port: u16) -> Endpoint {
9191
Endpoint { addr: addr, port: port }
9292
}
9393
}

0 commit comments

Comments
 (0)
Please sign in to comment.