2017-07-22 14:49:53 +00:00
|
|
|
// VpnCloud - Peer-to-Peer VPN
|
2019-02-19 21:04:21 +00:00
|
|
|
// Copyright (C) 2015-2019 Dennis Schwerdel
|
2017-07-22 14:49:53 +00:00
|
|
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
|
|
|
|
2016-06-30 08:05:37 +00:00
|
|
|
use libc;
|
|
|
|
|
|
|
|
use std::os::unix::io::RawFd;
|
|
|
|
use std::io;
|
2019-02-21 21:41:36 +00:00
|
|
|
use device::Device;
|
|
|
|
|
|
|
|
use super::WaitResult;
|
|
|
|
use ::device::Type;
|
|
|
|
use net::Socket;
|
|
|
|
|
|
|
|
pub struct EpollWait {
|
|
|
|
poll_fd: RawFd,
|
|
|
|
event: libc::epoll_event,
|
|
|
|
socketv4: RawFd,
|
|
|
|
socketv6: RawFd,
|
|
|
|
device: RawFd,
|
|
|
|
timeout: u32,
|
2016-06-30 08:05:37 +00:00
|
|
|
}
|
|
|
|
|
2019-02-21 21:41:36 +00:00
|
|
|
impl EpollWait {
|
|
|
|
pub fn new<S: Socket>(socketv4: &S, socketv6: &S, device: &Device, timeout: u32) -> io::Result<Self> {
|
|
|
|
let mut event = libc::epoll_event{u64: 0, events: 0};
|
|
|
|
let poll_fd = unsafe { libc::epoll_create(3) };
|
|
|
|
if poll_fd == -1 {
|
2016-06-30 08:05:37 +00:00
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
2019-02-21 21:41:36 +00:00
|
|
|
let raw_fds = if device.get_type() != Type::Dummy {
|
|
|
|
vec![socketv4.as_raw_fd(), socketv6.as_raw_fd(), device.as_raw_fd()]
|
|
|
|
} else {
|
|
|
|
vec![socketv4.as_raw_fd(), socketv6.as_raw_fd()]
|
|
|
|
};
|
|
|
|
for fd in raw_fds {
|
|
|
|
event.u64 = fd as u64;
|
|
|
|
event.events = libc::EPOLLIN as u32;
|
|
|
|
let res = unsafe { libc::epoll_ctl(poll_fd, libc::EPOLL_CTL_ADD, fd, &mut event) };
|
|
|
|
if res == -1 {
|
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
2016-06-30 08:05:37 +00:00
|
|
|
}
|
2019-02-21 21:41:36 +00:00
|
|
|
Ok(Self {
|
|
|
|
poll_fd,
|
|
|
|
event,
|
|
|
|
socketv4: socketv4.as_raw_fd(),
|
|
|
|
socketv6: socketv6.as_raw_fd(),
|
|
|
|
device: device.as_raw_fd(),
|
|
|
|
timeout
|
|
|
|
})
|
2016-06-30 08:05:37 +00:00
|
|
|
}
|
2019-02-21 21:41:36 +00:00
|
|
|
}
|
2016-06-30 08:05:37 +00:00
|
|
|
|
2019-02-21 21:41:36 +00:00
|
|
|
impl Drop for EpollWait {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe { libc::close(self.poll_fd) };
|
2016-06-30 08:05:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-21 21:41:36 +00:00
|
|
|
impl Iterator for EpollWait {
|
|
|
|
type Item = WaitResult;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
Some(match unsafe { libc::epoll_wait(self.poll_fd, &mut self.event, 1, self.timeout as i32) } {
|
|
|
|
-1 => WaitResult::Error(io::Error::last_os_error()),
|
|
|
|
0 => WaitResult::Timeout,
|
|
|
|
1 => if self.event.u64 == self.socketv4 as u64 {
|
|
|
|
WaitResult::SocketV4
|
|
|
|
} else if self.event.u64 == self.socketv6 as u64 {
|
|
|
|
WaitResult::SocketV6
|
|
|
|
} else if self.event.u64 == self.device as u64 {
|
|
|
|
WaitResult::Device
|
|
|
|
} else {
|
|
|
|
unreachable!()
|
|
|
|
},
|
|
|
|
_ => unreachable!()
|
|
|
|
})
|
2016-06-30 08:05:37 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-21 21:41:36 +00:00
|
|
|
|