use riptun::{Queue, Tun};
use std::collections::HashMap;
use std::io::{self, ErrorKind};
use std::time::Duration;
use mio::{Events, Interest, Poll, Token};
const NUM_QUEUES: usize = 5;
fn main() -> io::Result<()> {
let mut sync = Tun::new("rip%d", NUM_QUEUES).map_err(|err| err.into_io())?;
println!("[INFO] => Created new virtual device: {}", sync.name());
let mut poll = Poll::new()?;
let mut queues: HashMap<Token, Queue> = HashMap::with_capacity(NUM_QUEUES);
for (idx, mut queue) in sync.drain(..).enumerate() {
queue.set_non_blocking(true).map_err(|err| err.into_io())?;
let token = Token(idx);
poll.registry()
.register(&mut queue, token, Interest::READABLE)?;
queues.insert(token, queue);
}
let mut events = Events::with_capacity(NUM_QUEUES);
let mut buffer: [u8; 1500] = [0x00; 1500];
loop {
poll.poll(&mut events, Some(Duration::from_millis(500)))?;
if events.is_empty() {
continue;
}
for event in events.iter() {
if event.is_readable() {
let queue = queues.get(&event.token()).unwrap();
let read = match queue.recv(&mut buffer) {
Ok(read) => read,
Err(err) if err.kind() == ErrorKind::WouldBlock => continue,
Err(err) => {
println!("[ERROR][Queue: {:?}] => {}", event.token(), err);
continue;
}
};
println!(
"[INFO][Queue: {:?}] => Packet data ({}B): {:?}",
event.token(),
read,
&buffer[..read]
);
}
}
}
}