mirror of https://github.com/dswd/vpncloud.git
Compare commits
No commits in common. "26689a3003f1ad0e5f4c787614c65925b53db7c2" and "d3402e1f50d0e4690737cfb4c03eeaddcee6b617" have entirely different histories.
26689a3003
...
d3402e1f50
|
@ -1,6 +0,0 @@
|
||||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/rust/.devcontainer/base.Dockerfile
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/vscode/devcontainers/rust:0-1
|
|
||||||
|
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
|
||||||
&& apt-get -y install --no-install-recommends asciidoctor
|
|
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Rust",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
|
|
||||||
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
|
||||||
"settings": {
|
|
||||||
"terminal.integrated.shell.linux": "/bin/bash",
|
|
||||||
"lldb.executable": "/usr/bin/lldb",
|
|
||||||
// VS Code don't watch files under ./target
|
|
||||||
"files.watcherExclude": {
|
|
||||||
"**/target/**": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
|
||||||
"extensions": [
|
|
||||||
"rust-lang.rust",
|
|
||||||
"bungcip.better-toml",
|
|
||||||
"vadimcn.vscode-lldb",
|
|
||||||
"mutantdino.resourcemonitor",
|
|
||||||
"asciidoctor.asciidoctor-vscode"
|
|
||||||
],
|
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
|
||||||
// "forwardPorts": [],
|
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
|
||||||
// "postCreateCommand": "rustc --version",
|
|
||||||
|
|
||||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
|
||||||
"remoteUser": "vscode"
|
|
||||||
}
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
This project follows [semantic versioning](http://semver.org).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
### UNRELEASED
|
|
||||||
|
|
||||||
- [removed] Removed dummy device type
|
|
||||||
|
|
||||||
### v2.0.1 (2020-11-07)
|
### v2.0.1 (2020-11-07)
|
||||||
|
|
||||||
- [changed] Changed documentation
|
- [changed] Changed documentation
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
Mode::Normal => {
|
Mode::Normal => {
|
||||||
match config.device_type {
|
match config.device_type {
|
||||||
Type::Tap => (true, true),
|
Type::Tap => (true, true),
|
||||||
Type::Tun => (false, false)
|
Type::Tun | Type::Dummy => (false, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mode::Router => (false, false),
|
Mode::Router => (false, false),
|
||||||
|
|
|
@ -589,7 +589,7 @@ statsd:
|
||||||
#[test]
|
#[test]
|
||||||
fn default_config_as_default() {
|
fn default_config_as_default() {
|
||||||
let mut default_config = Config {
|
let mut default_config = Config {
|
||||||
device_type: Type::Tun,
|
device_type: Type::Dummy,
|
||||||
device_name: "".to_string(),
|
device_name: "".to_string(),
|
||||||
device_path: None,
|
device_path: None,
|
||||||
fix_rp_filter: false,
|
fix_rp_filter: false,
|
||||||
|
|
|
@ -51,14 +51,18 @@ pub enum Type {
|
||||||
Tun,
|
Tun,
|
||||||
/// Tap interface: This interface transports Ethernet frames.
|
/// Tap interface: This interface transports Ethernet frames.
|
||||||
#[serde(rename = "tap")]
|
#[serde(rename = "tap")]
|
||||||
Tap
|
Tap,
|
||||||
|
/// Dummy interface: This interface does nothing.
|
||||||
|
#[serde(rename = "dummy")]
|
||||||
|
Dummy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
impl fmt::Display for Type {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
Type::Tun => write!(formatter, "tun"),
|
Type::Tun => write!(formatter, "tun"),
|
||||||
Type::Tap => write!(formatter, "tap")
|
Type::Tap => write!(formatter, "tap"),
|
||||||
|
Type::Dummy => write!(formatter, "dummy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +74,7 @@ impl FromStr for Type {
|
||||||
Ok(match &text.to_lowercase() as &str {
|
Ok(match &text.to_lowercase() as &str {
|
||||||
"tun" => Self::Tun,
|
"tun" => Self::Tun,
|
||||||
"tap" => Self::Tap,
|
"tap" => Self::Tap,
|
||||||
|
"dummy" => Self::Dummy,
|
||||||
_ => return Err("Unknown device type")
|
_ => return Err("Unknown device type")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -139,10 +144,14 @@ impl TunTapDevice {
|
||||||
#[allow(clippy::useless_conversion)]
|
#[allow(clippy::useless_conversion)]
|
||||||
pub fn new(ifname: &str, type_: Type, path: Option<&str>) -> io::Result<Self> {
|
pub fn new(ifname: &str, type_: Type, path: Option<&str>) -> io::Result<Self> {
|
||||||
let path = path.unwrap_or_else(|| Self::default_path(type_));
|
let path = path.unwrap_or_else(|| Self::default_path(type_));
|
||||||
|
if type_ == Type::Dummy {
|
||||||
|
return Self::dummy(ifname, path, type_)
|
||||||
|
}
|
||||||
let fd = fs::OpenOptions::new().read(true).write(true).open(path)?;
|
let fd = fs::OpenOptions::new().read(true).write(true).open(path)?;
|
||||||
let flags = match type_ {
|
let flags = match type_ {
|
||||||
Type::Tun => libc::IFF_TUN | libc::IFF_NO_PI,
|
Type::Tun => libc::IFF_TUN | libc::IFF_NO_PI,
|
||||||
Type::Tap => libc::IFF_TAP | libc::IFF_NO_PI
|
Type::Tap => libc::IFF_TAP | libc::IFF_NO_PI,
|
||||||
|
Type::Dummy => unreachable!()
|
||||||
};
|
};
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.flags = flags as libc::c_short;
|
ifreq.data.flags = flags as libc::c_short;
|
||||||
|
@ -163,10 +172,33 @@ impl TunTapDevice {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn default_path(type_: Type) -> &'static str {
|
pub fn default_path(type_: Type) -> &'static str {
|
||||||
match type_ {
|
match type_ {
|
||||||
Type::Tun | Type::Tap => "/dev/net/tun"
|
Type::Tun | Type::Tap => "/dev/net/tun",
|
||||||
|
Type::Dummy => "/dev/null"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a dummy device based on an existing file
|
||||||
|
///
|
||||||
|
/// This method opens a regular or special file and reads from it to receive packets and
|
||||||
|
/// writes to it to send packets. This method does not use a networking device and therefore
|
||||||
|
/// can be used for testing.
|
||||||
|
///
|
||||||
|
/// The parameter `path` is the file that should be used. Special files like `/dev/null`,
|
||||||
|
/// named pipes and unix sockets can be used with this method.
|
||||||
|
///
|
||||||
|
/// Both `ifname` and `type_` parameters have no effect.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// This method will return an error if the file can not be opened for reading and writing.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn dummy(ifname: &str, path: &str, type_: Type) -> io::Result<Self> {
|
||||||
|
Ok(TunTapDevice {
|
||||||
|
fd: fs::OpenOptions::new().create(true).read(true).write(true).open(path)?,
|
||||||
|
ifname: ifname.to_string(),
|
||||||
|
type_
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn correct_data_after_read(&mut self, _buffer: &mut MsgBuffer) {}
|
fn correct_data_after_read(&mut self, _buffer: &mut MsgBuffer) {}
|
||||||
|
@ -223,7 +255,7 @@ impl TunTapDevice {
|
||||||
+ 1 /* message type header */
|
+ 1 /* message type header */
|
||||||
+ match self.type_ {
|
+ match self.type_ {
|
||||||
Type::Tap => 14, /* inner ethernet header */
|
Type::Tap => 14, /* inner ethernet header */
|
||||||
Type::Tun => 0
|
Type::Tun | Type::Dummy => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +357,7 @@ impl MockDevice {
|
||||||
|
|
||||||
impl Device for MockDevice {
|
impl Device for MockDevice {
|
||||||
fn get_type(&self) -> Type {
|
fn get_type(&self) -> Type {
|
||||||
Type::Tun
|
Type::Dummy
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ifname(&self) -> &str {
|
fn ifname(&self) -> &str {
|
||||||
|
|
|
@ -286,6 +286,7 @@ fn main() {
|
||||||
debug!("Config: {:?}", config);
|
debug!("Config: {:?}", config);
|
||||||
match config.device_type {
|
match config.device_type {
|
||||||
Type::Tap => run::<payload::Frame>(config),
|
Type::Tap => run::<payload::Frame>(config),
|
||||||
Type::Tun => run::<payload::Packet>(config)
|
Type::Tun => run::<payload::Packet>(config),
|
||||||
|
Type::Dummy => run::<payload::Frame>(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::device::Device;
|
||||||
use std::{io, os::unix::io::RawFd};
|
use std::{io, os::unix::io::RawFd};
|
||||||
|
|
||||||
use super::WaitResult;
|
use super::WaitResult;
|
||||||
use crate::net::Socket;
|
use crate::{device::Type, net::Socket};
|
||||||
|
|
||||||
pub struct EpollWait {
|
pub struct EpollWait {
|
||||||
poll_fd: RawFd,
|
poll_fd: RawFd,
|
||||||
|
@ -31,10 +31,15 @@ impl EpollWait {
|
||||||
if poll_fd == -1 {
|
if poll_fd == -1 {
|
||||||
return Err(io::Error::last_os_error())
|
return Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
for fd in &[socket.as_raw_fd(), device.as_raw_fd()] {
|
let raw_fds = if device.get_type() != Type::Dummy {
|
||||||
event.u64 = *fd as u64;
|
vec![socket.as_raw_fd(), device.as_raw_fd()]
|
||||||
|
} else {
|
||||||
|
vec![socket.as_raw_fd()]
|
||||||
|
};
|
||||||
|
for fd in raw_fds {
|
||||||
|
event.u64 = fd as u64;
|
||||||
event.events = flags;
|
event.events = flags;
|
||||||
let res = unsafe { libc::epoll_ctl(poll_fd, libc::EPOLL_CTL_ADD, *fd, &mut event) };
|
let res = unsafe { libc::epoll_ctl(poll_fd, libc::EPOLL_CTL_ADD, fd, &mut event) };
|
||||||
if res == -1 {
|
if res == -1 {
|
||||||
return Err(io::Error::last_os_error())
|
return Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue