Skip to content

Instantly share code, notes, and snippets.

@povilasb
Created November 8, 2018 15:47
Show Gist options
  • Save povilasb/d4c51405eea2494d8a50c0d4b8fb6a45 to your computer and use it in GitHub Desktop.
Save povilasb/d4c51405eea2494d8a50c0d4b8fb6a45 to your computer and use it in GitHub Desktop.
#[cfg(target_os = "linux")]
#[test]
fn keep_alive() {
let mut evloop = Core::new().unwrap();
let network = Network::new(&evloop.handle());
let network_handle = network.handle();
let (server_addr_tx, server_addr_rx) = oneshot::channel();
let (plug_client, mut plug_server) = IpPlug::new_pair();
let plug_client = plug_client.map(move |packet| {
println!("[client] rx: {:?}", packet);
packet
}).into_ip_plug(&network_handle);
let mut syn_received = false;
let mut ack_received = false;
let plug_server = plug_server.filter(move |packet| {
println!("[server] rx: {:?}", packet);
// Drop all incoming packets to server after TCP connection was established. So keepalive
// packets comming from client will be dropped and client won't receive further ACKs
let allow_packet = !(syn_received && ack_received);
syn_received |= packet.to_ipv4_packet().and_then(|p| p.to_tcp_packet())
.and_then(|p| Some(p.is_syn())).unwrap_or(false);
ack_received |= packet.to_ipv4_packet().and_then(|p| p.to_tcp_packet())
.and_then(|p| Some(p.is_ack())).unwrap_or(false);
allow_packet
}).into_ip_plug(&network_handle);
let server_ip = Ipv4Addr::random_global();
let spawn_server = netsim::device::MachineBuilder::new()
.add_ip_iface(
netsim::iface::IpIfaceBuilder::new()
.ipv4_addr(server_ip, 0)
.ipv4_route(Ipv4Route::new(Ipv4Range::global(), None)),
plug_server,
).spawn(&network_handle, move || {
println!("[server] ip = {}", server_ip);
let bind_addr = SocketAddr::V4(SocketAddrV4::new(server_ip, 0));
let listener = unwrap!(TcpListener::bind(bind_addr));
let server_addr = unwrap!(listener.local_addr());
let _ = server_addr_tx.send(server_addr);
let (mut client_sock, _client_addr) = unwrap!(listener.accept());
println!("[server] new client: {}", _client_addr);
let mut buf = [0; 4096];
let res = client_sock.read(&mut buf);
assert!(res.is_err());
});
let spawn_client = netsim::device::MachineBuilder::new()
.add_ip_iface(
netsim::iface::IpIfaceBuilder::new()
.ipv4_addr(Ipv4Addr::random_global(), 0)
.ipv4_route(Ipv4Route::new(Ipv4Range::global(), None)),
plug_client,
).spawn(&network_handle, move || {
const SOCKET1_TOKEN: Token = Token(0);
let evloop = unwrap!(Poll::new());
let server_addr = unwrap!(server_addr_rx.wait());
let mut sock1 = unwrap!(TcpSock::connect(&server_addr));
unwrap!(evloop.register(&sock1, SOCKET1_TOKEN, Ready::writable() | Ready::readable(), PollOpt::edge(),));
let mut events = Events::with_capacity(16);
'event_loop: loop {
unwrap!(evloop.poll(&mut events, None));
for ev in events.iter() {
use std::time::Duration;
match ev.token() {
SOCKET1_TOKEN => {
let res: Result<Option<Vec<u8>>, SocketError> = sock1.read();
println!("[client] bytes read {:?}", unwrap!(res));
}
_ => panic!("Unexpected event"),
}
}
}
});
unwrap!(evloop.run(spawn_server.join(spawn_client)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment