mirror of https://github.com/dswd/vpncloud.git
Compare commits
No commits in common. "5eeb125d747ee979d4a21fbdac68a57887ae92ae" and "16d5d47f01240e4f64896f64fa3f38115d4cc3d3" have entirely different histories.
5eeb125d74
...
16d5d47f01
|
@ -11,7 +11,7 @@ RUN chown vscode: -R /usr/local/rustup /usr/local/cargo
|
||||||
|
|
||||||
USER vscode
|
USER vscode
|
||||||
|
|
||||||
RUN rustup default 1.73.0 \
|
RUN rustup default 1.57.0 \
|
||||||
&& rustup component add clippy rust-src rustfmt
|
&& rustup component add clippy rust-src rustfmt
|
||||||
|
|
||||||
RUN cargo install cargo-outdated cargo-cache cargo-criterion \
|
RUN cargo install cargo-outdated cargo-cache cargo-criterion \
|
||||||
|
|
|
@ -8,16 +8,14 @@
|
||||||
"--security-opt",
|
"--security-opt",
|
||||||
"seccomp=unconfined"
|
"seccomp=unconfined"
|
||||||
],
|
],
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
// Set *default* container specific settings.json values on container create.
|
||||||
"customizations": {
|
"settings": {
|
||||||
"vscode": {
|
|
||||||
"terminal.integrated.shell.linux": "/bin/bash",
|
"terminal.integrated.shell.linux": "/bin/bash",
|
||||||
"lldb.executable": "/usr/bin/lldb",
|
"lldb.executable": "/usr/bin/lldb",
|
||||||
// VS Code don't watch files under ./target
|
// VS Code don't watch files under ./target
|
||||||
"files.watcherExclude": {
|
"files.watcherExclude": {
|
||||||
"**/target/**": true
|
"**/target/**": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
@ -29,9 +27,7 @@
|
||||||
"matklad.rust-analyzer",
|
"matklad.rust-analyzer",
|
||||||
"asciidoctor.asciidoctor-vscode",
|
"asciidoctor.asciidoctor-vscode",
|
||||||
"ms-vscode.test-adapter-converter"
|
"ms-vscode.test-adapter-converter"
|
||||||
]
|
],
|
||||||
}
|
|
||||||
},
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
// "forwardPorts": [],
|
// "forwardPorts": [],
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
|
|
@ -21,7 +21,7 @@ rustup target add armv5te-unknown-linux-musleabi
|
||||||
rustup target add armv7-unknown-linux-musleabihf
|
rustup target add armv7-unknown-linux-musleabihf
|
||||||
rustup target add aarch64-unknown-linux-musl
|
rustup target add aarch64-unknown-linux-musl
|
||||||
|
|
||||||
curl https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-amd64_linux.tar.xz -Lf | tar -xJ --strip-components=1 -C /usr/bin
|
curl https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-amd64_linux.tar.xz -Lf | tar -xJ --strip-components=1 -C /opt/rust/cargo/bin
|
||||||
|
|
||||||
mkdir dist
|
mkdir dist
|
||||||
|
|
||||||
|
|
|
@ -30,3 +30,23 @@ jobs:
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
|
coverage:
|
||||||
|
name: Coverage
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Install stable toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
- name: Run cargo-tarpaulin
|
||||||
|
uses: actions-rs/tarpaulin@v0.1
|
||||||
|
with:
|
||||||
|
args: '-o Html -- --test-threads=1'
|
||||||
|
- name: Archive code coverage results
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: code-coverage-report
|
||||||
|
path: tarpaulin-report.html
|
||||||
|
|
|
@ -2,12 +2,6 @@
|
||||||
|
|
||||||
This project follows [semantic versioning](http://semver.org).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
### UNRELEASED
|
|
||||||
|
|
||||||
- [changed] Changed Rust version to 1.73.0
|
|
||||||
- [changed] Updated dependencies
|
|
||||||
- [fixed] Fix error when IPv6 is not available
|
|
||||||
|
|
||||||
### v2.3.0 (2021-12-23)
|
### v2.3.0 (2021-12-23)
|
||||||
|
|
||||||
- [added] Added build for armv5te (thanks to xek)
|
- [added] Added build for armv5te (thanks to xek)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
15
Cargo.toml
|
@ -12,36 +12,35 @@ readme = "README.md"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
toolchain = "1.73.0"
|
toolchain = "1.57.0"
|
||||||
upx_version = "3.96"
|
upx_version = "3.96"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { version = "0.4", features = ["std", "clock"], default_features = false}
|
chrono = { version = "0.4", features = ["std", "clock"], default_features = false}
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.8"
|
||||||
log = { version = "0.4", features = ["std"] }
|
log = { version = "0.4", features = ["std"] }
|
||||||
signal = "0.7"
|
signal = "0.7"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
fnv = "1"
|
fnv = "1"
|
||||||
yaml-rust = "0.4"
|
yaml-rust = "0.4"
|
||||||
daemonize = "0.5"
|
daemonize = "0.4"
|
||||||
#ring = "0.17"
|
ring = "0.16"
|
||||||
ring = { git = "https://github.com/briansmith/ring", rev = "2afc921" } # https://github.com/briansmith/ring/issues/1707
|
|
||||||
privdrop = "0.5"
|
privdrop = "0.5"
|
||||||
byteorder = "1.4"
|
byteorder = "1.4"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
smallvec = "1.7"
|
smallvec = "1.7"
|
||||||
dialoguer = { version = "0.11", optional = true }
|
dialoguer = { version = "0.9", optional = true }
|
||||||
tungstenite = { version = "0.20", optional = true }
|
tungstenite = { version = "0.16", optional = true, default-features = false }
|
||||||
url = { version = "2.2", optional = true }
|
url = { version = "2.2", optional = true }
|
||||||
igd = { version = "0.12", optional = true }
|
igd = { version = "0.12", optional = true }
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
criterion = { version = "0.5", features = ["html_reports"] }
|
criterion = { version = "0.3", features = ["html_reports"] }
|
||||||
iai = "0.1"
|
iai = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -15,7 +15,7 @@ include!(".code.rs");
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
use util::{MockTimeSource, MsgBuffer};
|
use util::{MockTimeSource, MsgBuffer};
|
||||||
use types::{Address, Range};
|
use types::{Address, Range};
|
||||||
use table::ClaimTable;
|
use table::{ClaimTable};
|
||||||
use device::Type;
|
use device::Type;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use payload::{Packet, Frame, Protocol};
|
use payload::{Packet, Frame, Protocol};
|
||||||
|
@ -29,7 +29,7 @@ fn udp_send(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("udp_send");
|
let mut g = c.benchmark_group("udp_send");
|
||||||
g.throughput(Throughput::Bytes(1400));
|
g.throughput(Throughput::Bytes(1400));
|
||||||
g.bench_function("udp_send", |b| {
|
g.bench_function("udp_send", |b| {
|
||||||
b.iter(|| sock.send_to(&data, addr).unwrap());
|
b.iter(|| sock.send_to(&data, &addr).unwrap());
|
||||||
});
|
});
|
||||||
g.finish();
|
g.finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use util::{MockTimeSource, MsgBuffer};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use types::{Address, Range};
|
use types::{Address, Range};
|
||||||
use device::Type;
|
use device::Type;
|
||||||
use table::ClaimTable;
|
use table::{ClaimTable};
|
||||||
use payload::{Packet, Frame, Protocol};
|
use payload::{Packet, Frame, Protocol};
|
||||||
use crypto::core::{create_dummy_pair, EXTRA_LEN};
|
use crypto::core::{create_dummy_pair, EXTRA_LEN};
|
||||||
use tests::common::{TunSimulator, TapSimulator};
|
use tests::common::{TunSimulator, TapSimulator};
|
||||||
|
@ -26,7 +26,7 @@ fn udp_send() {
|
||||||
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||||
let data = [0; 1400];
|
let data = [0; 1400];
|
||||||
let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1);
|
let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1);
|
||||||
sock.send_to(&data, black_box(addr)).unwrap();
|
sock.send_to(&data, &black_box(addr)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_ipv4() {
|
fn decode_ipv4() {
|
||||||
|
|
6
build.rs
6
build.rs
|
@ -12,12 +12,12 @@ fn main() {
|
||||||
fs::create_dir_all(&out_dir).unwrap();
|
fs::create_dir_all(&out_dir).unwrap();
|
||||||
fs::copy("vpncloud.adoc", Path::new(&out_dir).join("vpncloud.adoc")).unwrap();
|
fs::copy("vpncloud.adoc", Path::new(&out_dir).join("vpncloud.adoc")).unwrap();
|
||||||
match Command::new("asciidoctor")
|
match Command::new("asciidoctor")
|
||||||
.args(["-b", "manpage", "vpncloud.adoc"])
|
.args(&["-b", "manpage", "vpncloud.adoc"])
|
||||||
.current_dir(Path::new(&out_dir))
|
.current_dir(&Path::new(&out_dir))
|
||||||
.status()
|
.status()
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
Command::new("gzip").args(["vpncloud.1"]).current_dir(Path::new(&out_dir)).status().unwrap();
|
Command::new("gzip").args(&["vpncloud.1"]).current_dir(&Path::new(&out_dir)).status().unwrap();
|
||||||
fs::copy(Path::new(&out_dir).join("vpncloud.1.gz"), "target/vpncloud.1.gz").unwrap();
|
fs::copy(Path::new(&out_dir).join("vpncloud.1.gz"), "target/vpncloud.1.gz").unwrap();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
|
@ -228,7 +228,7 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
||||||
let beacon = format!("{}{}{}", begin, data, end);
|
let beacon = format!("{}{}{}", begin, data, end);
|
||||||
debug!("Calling beacon command: {}", cmd);
|
debug!("Calling beacon command: {}", cmd);
|
||||||
let process = Command::new("sh")
|
let process = Command::new("sh")
|
||||||
.args(["-c", cmd])
|
.args(&["-c", cmd])
|
||||||
.env("begin", begin)
|
.env("begin", begin)
|
||||||
.env("data", data)
|
.env("data", data)
|
||||||
.env("end", end)
|
.env("end", end)
|
||||||
|
@ -281,7 +281,7 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
||||||
let end = self.end();
|
let end = self.end();
|
||||||
debug!("Calling beacon command: {}", cmd);
|
debug!("Calling beacon command: {}", cmd);
|
||||||
let process = Command::new("sh")
|
let process = Command::new("sh")
|
||||||
.args(["-c", cmd])
|
.args(&["-c", cmd])
|
||||||
.env("begin", begin)
|
.env("begin", begin)
|
||||||
.env("end", end)
|
.env("end", end)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
|
|
@ -450,7 +450,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
self.broadcast_msg(MESSAGE_TYPE_NODE_INFO, &mut buffer)?;
|
self.broadcast_msg(MESSAGE_TYPE_NODE_INFO, &mut buffer)?;
|
||||||
// Reschedule for next update
|
// Reschedule for next update
|
||||||
let min_peer_timeout = self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(DEFAULT_PEER_TIMEOUT);
|
let min_peer_timeout = self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(DEFAULT_PEER_TIMEOUT);
|
||||||
let interval = min(self.update_freq, max(min_peer_timeout / 2 - 60, 1));
|
let interval = min(self.update_freq as u16, max(min_peer_timeout / 2 - 60, 1));
|
||||||
self.next_peers = now + Time::from(interval);
|
self.next_peers = now + Time::from(interval);
|
||||||
}
|
}
|
||||||
self.reconnect_to_peers()?;
|
self.reconnect_to_peers()?;
|
||||||
|
@ -491,7 +491,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
.map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?;
|
.map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?;
|
||||||
} else {
|
} else {
|
||||||
self.beacon_serializer
|
self.beacon_serializer
|
||||||
.write_to_file(&peers, path)
|
.write_to_file(&peers, &path)
|
||||||
.map_err(|e| Error::BeaconIo("Failed to write beacon to file", e))?;
|
.map_err(|e| Error::BeaconIo("Failed to write beacon to file", e))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
} else {
|
} else {
|
||||||
peers = self
|
peers = self
|
||||||
.beacon_serializer
|
.beacon_serializer
|
||||||
.read_from_file(path, Some(50))
|
.read_from_file(&path, Some(50))
|
||||||
.map_err(|e| Error::BeaconIo("Failed to read beacon from file", e))?;
|
.map_err(|e| Error::BeaconIo("Failed to read beacon from file", e))?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -459,8 +459,8 @@ impl<P: Payload> InitState<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_master_key(&self, algo: &'static Algorithm, privk: EcdhPrivateKey, pubk: &EcdhPublicKey) -> LessSafeKey {
|
fn derive_master_key(&self, algo: &'static Algorithm, privk: EcdhPrivateKey, pubk: &EcdhPublicKey) -> LessSafeKey {
|
||||||
agree_ephemeral(privk, pubk, |k| {
|
agree_ephemeral(privk, pubk, (), |k| {
|
||||||
UnboundKey::new(algo, &k[..algo.key_len()]).map(LessSafeKey::new).unwrap()
|
UnboundKey::new(algo, &k[..algo.key_len()]).map(LessSafeKey::new).map_err(|_| ())
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,10 +137,10 @@ impl RotationState {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_key(private_key: EcdhPrivateKey, public_key: EcdhPublicKey) -> Key {
|
fn derive_key(private_key: EcdhPrivateKey, public_key: EcdhPublicKey) -> Key {
|
||||||
agree_ephemeral(private_key, &public_key, |k| {
|
agree_ephemeral(private_key, &public_key, (), |k| {
|
||||||
let mut vec = Key::new();
|
let mut vec = Key::new();
|
||||||
vec.extend_from_slice(k);
|
vec.extend_from_slice(k);
|
||||||
vec
|
Ok(vec)
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ use std::{
|
||||||
process,
|
process,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -113,7 +114,7 @@ impl log::Log for DualLogger {
|
||||||
|
|
||||||
fn run_script(script: &str, ifname: &str) {
|
fn run_script(script: &str, ifname: &str) {
|
||||||
let mut cmd = process::Command::new("sh");
|
let mut cmd = process::Command::new("sh");
|
||||||
cmd.arg("-c").arg(script).env("IFNAME", ifname);
|
cmd.arg("-c").arg(&script).env("IFNAME", ifname);
|
||||||
debug!("Running script: {:?}", cmd);
|
debug!("Running script: {:?}", cmd);
|
||||||
match cmd.status() {
|
match cmd.status() {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
|
@ -211,6 +212,8 @@ fn run<P: Protocol, S: Socket>(config: Config, socket: S) {
|
||||||
}
|
}
|
||||||
if let Some(pid_file) = config.pid_file {
|
if let Some(pid_file) = config.pid_file {
|
||||||
daemonize = daemonize.pid_file(pid_file).chown_pid_file(true);
|
daemonize = daemonize.pid_file(pid_file).chown_pid_file(true);
|
||||||
|
// Give child process some time to write PID file
|
||||||
|
daemonize = daemonize.exit_action(|| thread::sleep(std::time::Duration::from_millis(10)));
|
||||||
}
|
}
|
||||||
try_fail!(daemonize.start(), "Failed to daemonize: {}");
|
try_fail!(daemonize.start(), "Failed to daemonize: {}");
|
||||||
} else if config.user.is_some() || config.group.is_some() {
|
} else if config.user.is_some() || config.group.is_some() {
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ip() -> IpAddr {
|
pub fn get_ip() -> IpAddr {
|
||||||
let s = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let s = UdpSocket::bind("[::]:0").unwrap();
|
||||||
s.connect("8.8.8.8:0").unwrap();
|
s.connect("8.8.8.8:0").unwrap();
|
||||||
s.local_addr().unwrap().ip()
|
s.local_addr().unwrap().ip()
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ pub fn from_base62(data: &str) -> Result<Vec<u8>, char> {
|
||||||
let mut buf = Vec::with_capacity(data.len() / 2 + data.len() / 4);
|
let mut buf = Vec::with_capacity(data.len() / 2 + data.len() / 4);
|
||||||
for c in data.chars() {
|
for c in data.chars() {
|
||||||
let mut val = match c {
|
let mut val = match c {
|
||||||
'0'..='9' => (c as usize) % ('0' as usize),
|
'0'..='9' => ((c as usize) % ('0' as usize)),
|
||||||
'A'..='Z' => ((c as usize) % ('A' as usize)) + 10,
|
'A'..='Z' => ((c as usize) % ('A' as usize)) + 10,
|
||||||
'a'..='z' => ((c as usize) % ('a' as usize)) + 36,
|
'a'..='z' => ((c as usize) % ('a' as usize)) + 36,
|
||||||
_ => return Err(c),
|
_ => return Err(c),
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn str_opt(s: String) -> Option<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode >= MODE_ADVANCED {
|
if mode >= MODE_ADVANCED {
|
||||||
config.listen =
|
config.listen =
|
||||||
Input::with_theme(theme).with_prompt("Listen address").default(config.listen.clone()).interact_text()?;
|
Input::with_theme(theme).with_prompt("Listen address").default(config.listen.clone()).interact_text()?;
|
||||||
|
@ -60,7 +60,7 @@ fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulThem
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if (config.crypto.password.is_some() || config.crypto.private_key.is_some())
|
if (config.crypto.password.is_some() || config.crypto.private_key.is_some())
|
||||||
&& !Confirm::with_theme(theme).with_prompt("Create new crypto config?").default(false).interact()?
|
&& !Confirm::with_theme(theme).with_prompt("Create new crypto config?").default(false).interact()?
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode >= MODE_ADVANCED {
|
if mode >= MODE_ADVANCED {
|
||||||
config.device_type = match Select::with_theme(theme)
|
config.device_type = match Select::with_theme(theme)
|
||||||
.with_prompt("Device type")
|
.with_prompt("Device type")
|
||||||
|
@ -204,7 +204,7 @@ fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
config.ip = str_opt(
|
config.ip = str_opt(
|
||||||
Input::with_theme(theme)
|
Input::with_theme(theme)
|
||||||
.with_prompt("Virtual IP address (e.g. 10.0.0.1, leave empty for none)")
|
.with_prompt("Virtual IP address (e.g. 10.0.0.1, leave empty for none)")
|
||||||
|
@ -250,7 +250,7 @@ fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme)
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode == MODE_EXPERT
|
if mode == MODE_EXPERT
|
||||||
&& Confirm::with_theme(theme)
|
&& Confirm::with_theme(theme)
|
||||||
.with_prompt("Configure beacons?")
|
.with_prompt("Configure beacons?")
|
||||||
|
@ -332,7 +332,7 @@ fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode >= MODE_ADVANCED {
|
if mode >= MODE_ADVANCED {
|
||||||
config.stats_file = str_opt(
|
config.stats_file = str_opt(
|
||||||
Input::with_theme(theme)
|
Input::with_theme(theme)
|
||||||
|
@ -369,7 +369,7 @@ fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> R
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode == MODE_EXPERT {
|
if mode == MODE_EXPERT {
|
||||||
config.user = str_opt(
|
config.user = str_opt(
|
||||||
Input::with_theme(theme)
|
Input::with_theme(theme)
|
||||||
|
@ -396,7 +396,7 @@ fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||||
if mode == MODE_EXPERT {
|
if mode == MODE_EXPERT {
|
||||||
if Confirm::with_theme(theme)
|
if Confirm::with_theme(theme)
|
||||||
.with_prompt("Set hooks to react on events?")
|
.with_prompt("Set hooks to react on events?")
|
||||||
|
@ -439,7 +439,7 @@ fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> R
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure(name: Option<String>) -> Result<(), dialoguer::Error> {
|
pub fn configure(name: Option<String>) -> Result<(), io::Error> {
|
||||||
let theme = ColorfulTheme::default();
|
let theme = ColorfulTheme::default();
|
||||||
|
|
||||||
let name = if let Some(name) = name {
|
let name = if let Some(name) = name {
|
||||||
|
@ -467,7 +467,7 @@ pub fn configure(name: Option<String>) -> Result<(), dialoguer::Error> {
|
||||||
config.merge_file(config_file);
|
config.merge_file(config_file);
|
||||||
}
|
}
|
||||||
if file.parent().unwrap().metadata()?.permissions().readonly() {
|
if file.parent().unwrap().metadata()?.permissions().readonly() {
|
||||||
return Err(io::Error::new(io::ErrorKind::PermissionDenied, "Config file not writable").into());
|
return Err(io::Error::new(io::ErrorKind::PermissionDenied, "Config file not writable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -58,14 +58,14 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
|
||||||
info!("Listening on {} for peer {}", addr, peer);
|
info!("Listening on {} for peer {}", addr, peer);
|
||||||
addr.set_ip(get_ip());
|
addr.set_ip(get_ip());
|
||||||
write_addr(addr, &mut msg)?;
|
write_addr(addr, &mut msg)?;
|
||||||
io_error!(websocket.send(Message::Binary(msg)), "Failed to write to ws connection: {}")?;
|
io_error!(websocket.write_message(Message::Binary(msg)), "Failed to write to ws connection: {}")?;
|
||||||
let websocketfd = websocket.get_ref().as_raw_fd();
|
let websocketfd = websocket.get_ref().as_raw_fd();
|
||||||
let poll = WaitImpl::new(websocketfd, udpsocket.as_raw_fd(), 60 * 1000)?;
|
let poll = WaitImpl::new(websocketfd, udpsocket.as_raw_fd(), 60 * 1000)?;
|
||||||
let mut buffer = [0; 65535];
|
let mut buffer = [0; 65535];
|
||||||
for evt in poll {
|
for evt in poll {
|
||||||
match evt {
|
match evt {
|
||||||
WaitResult::Socket => {
|
WaitResult::Socket => {
|
||||||
let msg = io_error!(websocket.read(), "Failed to read message on websocket {}: {}", peer)?;
|
let msg = io_error!(websocket.read_message(), "Failed to read message on websocket {}: {}", peer)?;
|
||||||
match msg {
|
match msg {
|
||||||
Message::Binary(data) => {
|
Message::Binary(data) => {
|
||||||
let dst = read_addr(Cursor::new(&data))?;
|
let dst = read_addr(Cursor::new(&data))?;
|
||||||
|
@ -80,10 +80,10 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
|
||||||
let mut data = Vec::with_capacity(18 + size);
|
let mut data = Vec::with_capacity(18 + size);
|
||||||
write_addr(addr, &mut data)?;
|
write_addr(addr, &mut data)?;
|
||||||
data.write_all(&buffer[..size])?;
|
data.write_all(&buffer[..size])?;
|
||||||
io_error!(websocket.send(Message::Binary(data)), "Failed to write to {}: {}", peer)?;
|
io_error!(websocket.write_message(Message::Binary(data)), "Failed to write to {}: {}", peer)?;
|
||||||
}
|
}
|
||||||
WaitResult::Timeout => {
|
WaitResult::Timeout => {
|
||||||
io_error!(websocket.send(Message::Ping(vec![])), "Failed to send ping: {}")?;
|
io_error!(websocket.write_message(Message::Ping(vec![])), "Failed to send ping: {}")?;
|
||||||
}
|
}
|
||||||
WaitResult::Error(err) => return Err(err),
|
WaitResult::Error(err) => return Err(err),
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ pub struct ProxyConnection {
|
||||||
impl ProxyConnection {
|
impl ProxyConnection {
|
||||||
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
|
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
|
||||||
loop {
|
loop {
|
||||||
if let Message::Binary(data) = io_error!(self.socket.read(), "Failed to read from ws proxy: {}")? {
|
if let Message::Binary(data) = io_error!(self.socket.read_message(), "Failed to read from ws proxy: {}")? {
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ impl Socket for ProxyConnection {
|
||||||
let mut msg = Vec::with_capacity(data.len() + 18);
|
let mut msg = Vec::with_capacity(data.len() + 18);
|
||||||
write_addr(addr, &mut msg)?;
|
write_addr(addr, &mut msg)?;
|
||||||
msg.write_all(data)?;
|
msg.write_all(data)?;
|
||||||
io_error!(self.socket.send(Message::Binary(msg)), "Failed to write to ws proxy: {}")?;
|
io_error!(self.socket.write_message(Message::Binary(msg)), "Failed to write to ws proxy: {}")?;
|
||||||
Ok(data.len())
|
Ok(data.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue