mirror of https://github.com/dswd/vpncloud.git
Compare commits
91 Commits
Author | SHA1 | Date |
---|---|---|
Dennis Schwerdel | bef99162fe | |
Dennis Schwerdel | 24c48e2ef2 | |
Dennis Schwerdel | 7e55ec5df6 | |
Dennis Schwerdel | 18e4a22210 | |
Dennis Schwerdel | 06f3d3c761 | |
Dennis Schwerdel | 5eeb125d74 | |
Dennis Schwerdel | ca220ded0c | |
Dennis Schwerdel | 2505679021 | |
Dennis Schwerdel | 358183ef12 | |
Dennis Schwerdel | 28b1c76d70 | |
Dennis Schwerdel | 5c361d08ab | |
Dennis Schwerdel | 16d5d47f01 | |
Dennis Schwerdel | 50a6c01e93 | |
Dennis Schwerdel | 2dc774196e | |
Dennis Schwerdel | 79916104ba | |
Dennis Schwerdel | 798964030f | |
Dennis Schwerdel | c7c1ebc11b | |
Dennis Schwerdel | 4896a964ea | |
dswd | 59920ff627 | |
dswd | 665b4d505f | |
dswd | 6c5065c267 | |
dswd | 8d6c2b955e | |
Grzegorz Grasza | c61abbdb34 | |
dependabot[bot] | cd5c58239b | |
dependabot[bot] | e52c28794e | |
dependabot[bot] | e70a0412f9 | |
dswd | 0d19bb04e8 | |
dswd | bb97bfd2c5 | |
dependabot[bot] | 87446af0b2 | |
dswd | 85fc272ad4 | |
dswd | 1368ee50e5 | |
dependabot[bot] | 45216f7ef2 | |
dependabot[bot] | d71225b88d | |
dependabot[bot] | bd50eaec77 | |
dswd | 95dabab017 | |
dswd | e4956d209b | |
dswd | 46f083ed68 | |
dswd | 88d34e2fcd | |
dependabot[bot] | 4cbbc21a76 | |
dependabot[bot] | 4c9df625df | |
dependabot[bot] | 7cbbababce | |
dependabot[bot] | 1ddb18d63b | |
dswd | b584eb7163 | |
dswd | 115e42b553 | |
dswd | dd529f15ff | |
dswd | 062868dfd0 | |
dependabot[bot] | 2810eebca2 | |
dependabot[bot] | a69b6e94cf | |
dependabot[bot] | d70ff828bc | |
dependabot[bot] | 96cf585ca6 | |
dswd | ba0a903774 | |
dswd | 7213cc055d | |
dswd | 8bd1479904 | |
Kirill Isakov | 2adbc07cc3 | |
dependabot[bot] | 4868e8064c | |
dependabot[bot] | 671454f59c | |
dswd | 6e5f71b116 | |
dswd | 5e5522d6bd | |
dependabot[bot] | 883fae862f | |
dependabot[bot] | 9601aeffee | |
dswd | 7209e311c9 | |
dependabot[bot] | 1e9eb41ea6 | |
dswd | 06d29c8e3c | |
dependabot[bot] | 1ac20db0b3 | |
dswd | ba15bcfabf | |
dependabot[bot] | 129d0e5e93 | |
Dennis Schwerdel | 10ee616d89 | |
Dennis Schwerdel | ad75704f7b | |
dswd | 4d8286c54c | |
dswd | 00bf732be9 | |
dependabot[bot] | 817d060441 | |
dependabot[bot] | cc105daac6 | |
dswd | 36195cb582 | |
dependabot[bot] | f77ac6d6f4 | |
dswd | 8fe0815acd | |
dependabot[bot] | 0119820495 | |
dswd | e77cb6ef0f | |
dependabot[bot] | 213faa5649 | |
dswd | 396351b61c | |
dswd | 41bcb46579 | |
dswd | b0d73c44ed | |
dswd | ea53a4aad5 | |
dswd | 25e2f327e9 | |
Dennis Schwerdel | 37aebf64c3 | |
Dennis Schwerdel | 8d81a0117f | |
Dennis Schwerdel | 8c55e6c076 | |
Dennis Schwerdel | 7427be31c8 | |
Dennis Schwerdel | 5609a61ddb | |
Jeffrey Schiller | 0f9a0d8f91 | |
dswd | 7a55529cb9 | |
dependabot[bot] | eef6e528e2 |
|
@ -1,29 +0,0 @@
|
|||
[target.armv7-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
|
||||
strip = { path = "arm-linux-gnueabihf-strip" }
|
||||
|
||||
[target.armv7-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
|
||||
strip = { path = "arm-linux-gnueabihf-strip" }
|
||||
|
||||
[target.arm-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
|
||||
strip = { path = "arm-linux-gnueabihf-strip" }
|
||||
|
||||
[target.arm-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
objcopy = { path = "arm-linux-gnueabihf-objcopy" }
|
||||
strip = { path = "arm-linux-gnueabihf-strip" }
|
||||
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
objcopy = { path = "aarch64-linux-gnu-objcopy" }
|
||||
strip = { path = "aarch64-linux-gnu-strip" }
|
||||
|
||||
[target.aarch64-unknown-linux-musl]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
objcopy = { path = "aarch64-linux-gnu-objcopy" }
|
||||
strip = { path = "aarch64-linux-gnu-strip" }
|
|
@ -1,18 +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:1
|
||||
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends asciidoctor
|
||||
|
||||
RUN rm /etc/localtime && ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
|
||||
|
||||
RUN chown vscode: -R /usr/local/rustup /usr/local/cargo
|
||||
|
||||
USER vscode
|
||||
|
||||
RUN rustup default 1.51.0 \
|
||||
&& rustup component add clippy rust-src rustfmt
|
||||
|
||||
RUN cargo install cargo-outdated cargo-cache \
|
||||
&& cargo cache -a
|
|
@ -1,36 +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": [
|
||||
"bungcip.better-toml",
|
||||
"vadimcn.vscode-lldb",
|
||||
"serayuzgur.crates",
|
||||
"editorconfig.editorconfig",
|
||||
"swellaby.vscode-rust-test-adapter",
|
||||
"matklad.rust-analyzer",
|
||||
"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"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Report a bug
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Describe the bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
### Details of your setup
|
||||
|
||||
**VpnCloud version:**
|
||||
|
||||
**Description of your VPN setup**
|
||||
- How many nodes?
|
||||
- Any NAT involved?
|
||||
- Any custom routing?
|
||||
|
||||
**Config file contents**
|
||||
normally in `/etc/vpncloud/MYNET.net`
|
||||
:bangbang: make sure to mask (`***`) passwords and public IPs/hostnames :bangbang:
|
||||
|
||||
**Log entries**
|
||||
normally in `/var/log/vpncloud.MYNET.log`
|
|
@ -0,0 +1,8 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: VpnCloud Documentation
|
||||
url: https://vpncloud.ddswd.de/docs
|
||||
about: Please check the documentation before asking how things work.
|
||||
- name: Discussion Group on GitHub
|
||||
url: https://github.com/dswd/vpncloud/discussions
|
||||
about: Please discuss or ask anything there that is not an issue.
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
** Describe the high-level goal you want to achieve **
|
||||
|
||||
I would like to...
|
||||
|
||||
** Describe the proposed solution **
|
||||
|
||||
I propose to...
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
name: Other issue
|
||||
about: Any other issue
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Describe your issue
|
||||
|
||||
👉 Please use the [Discussion group](https://github.com/dswd/vpncloud/discussions) if you...
|
||||
* just want to ask a question
|
||||
* want to discuss a new feature
|
|
@ -6,8 +6,10 @@ RUN apt-get update \
|
|||
curl \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
gcc-arm-linux-gnueabi \
|
||||
libc6-dev-arm64-cross \
|
||||
libc6-dev-armhf-cross \
|
||||
libc6-dev-armel-cross \
|
||||
libc6-dev-i386 \
|
||||
gcc-5-multilib \
|
||||
asciidoctor \
|
||||
|
|
|
@ -13,6 +13,7 @@ curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${TOOLCHAIN}
|
|||
source $HOME/.cargo/env
|
||||
|
||||
rustup target add i686-unknown-linux-gnu
|
||||
rustup target add armv5te-unknown-linux-gnueabi
|
||||
rustup target add armv7-unknown-linux-gnueabihf
|
||||
rustup target add aarch64-unknown-linux-gnu
|
||||
|
||||
|
@ -32,4 +33,5 @@ cp target/debian/vpncloud_${DEB_VERSION}_amd64.deb dist/vpncloud_${DEB_VERSION}_
|
|||
|
||||
build_deb i386 i686-unknown-linux-gnu
|
||||
build_deb armhf armv7-unknown-linux-gnueabihf
|
||||
build_deb armel armv5te-unknown-linux-gnueabi
|
||||
build_deb arm64 aarch64-unknown-linux-gnu
|
|
@ -6,6 +6,8 @@ RUN yum install -y libstdc++-*.i686 \
|
|||
&& yum install -y glibc-*.i686 \
|
||||
&& yum install -y libgcc.i686
|
||||
|
||||
RUN ln -s /usr/bin/gcc /usr/bin/i686-linux-gnu-gcc
|
||||
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
|
||||
ENTRYPOINT /entrypoint.sh
|
||||
|
|
|
@ -6,8 +6,10 @@ RUN apt-get update \
|
|||
curl \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
gcc-arm-linux-gnueabi \
|
||||
libc6-dev-arm64-cross \
|
||||
libc6-dev-armhf-cross \
|
||||
libc6-dev-armel-cross \
|
||||
libc6-dev-i386 \
|
||||
gcc-5-multilib \
|
||||
asciidoctor \
|
||||
|
|
|
@ -17,10 +17,11 @@ source $HOME/.cargo/env
|
|||
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
rustup target add i686-unknown-linux-musl
|
||||
rustup target add armv5te-unknown-linux-musleabi
|
||||
rustup target add armv7-unknown-linux-musleabihf
|
||||
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 /opt/rust/cargo/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 /usr/bin
|
||||
|
||||
mkdir dist
|
||||
|
||||
|
@ -34,4 +35,5 @@ build_static() {
|
|||
build_static amd64 x86_64-unknown-linux-musl
|
||||
#build_static i386 i686-unknown-linux-musl
|
||||
build_static armhf armv7-unknown-linux-musleabihf
|
||||
build_static armel armv5te-unknown-linux-musleabi
|
||||
build_static arm64 aarch64-unknown-linux-musl
|
|
@ -6,7 +6,7 @@ jobs:
|
|||
audit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/audit-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -29,24 +29,4 @@ jobs:
|
|||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
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
|
||||
command: test
|
|
@ -1,59 +0,0 @@
|
|||
on:
|
||||
release:
|
||||
types: [created]
|
||||
name: Build packages
|
||||
jobs:
|
||||
deb:
|
||||
name: "Build deb packages"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run builder
|
||||
uses: ./.github/actions/build-deb
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: packages
|
||||
path: dist
|
||||
- name: Upload artifacts
|
||||
uses: skx/github-action-publish-binaries@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
args: 'dist/*.deb'
|
||||
rpm:
|
||||
name: "Build rpm packages"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run builder
|
||||
uses: ./.github/actions/build-rpm
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: packages
|
||||
path: dist
|
||||
- name: Upload artifacts
|
||||
uses: skx/github-action-publish-binaries@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
args: 'dist/*.rpm'
|
||||
static:
|
||||
name: "Build static binaries"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run builder
|
||||
uses: ./.github/actions/build-static
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: packages
|
||||
path: dist
|
||||
- name: Upload artifacts
|
||||
uses: skx/github-action-publish-binaries@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
args: 'dist/*'
|
|
@ -1,49 +0,0 @@
|
|||
%define __spec_install_post %{nil}
|
||||
%define __os_install_post %{_dbpath}/brp-compress
|
||||
%define debug_package %{nil}
|
||||
|
||||
Name: vpncloud
|
||||
Summary: Peer-to-peer VPN
|
||||
Version: @@VERSION@@
|
||||
Release: @@RELEASE@@
|
||||
License: GPL-3.0
|
||||
Group: Applications/System
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
URL: https://vpncloud.ddswd.de
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
|
||||
%description
|
||||
%{summary}
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
mkdir -p %{buildroot}
|
||||
mkdir -p %{buildroot}/etc/vpncloud
|
||||
chmod 700 %{buildroot}/etc/vpncloud
|
||||
mkdir -p %{buildroot}/lib/systemd/system
|
||||
mkdir -p %{buildroot}/usr/share/man/man1
|
||||
cp %{buildroot}/../../../../../assets/example.net.disabled %{buildroot}/etc/vpncloud/example.net.disabled
|
||||
cp %{buildroot}/../../../../../assets/vpncloud@.service %{buildroot}/lib/systemd/system/vpncloud@.service
|
||||
cp %{buildroot}/../../../../../assets/vpncloud.target %{buildroot}/lib/systemd/system/vpncloud.target
|
||||
cp %{buildroot}/../../../../../assets/vpncloud-wsproxy.service %{buildroot}/lib/systemd/system/vpncloud-wsproxy.service
|
||||
cp %{buildroot}/../../../../../target/vpncloud.1.gz %{buildroot}/usr/share/man/man1/vpncloud.1.gz
|
||||
cp -a * %{buildroot}
|
||||
|
||||
%clean
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%files
|
||||
/etc/vpncloud
|
||||
/etc/vpncloud/example.net.disabled
|
||||
/usr/bin/vpncloud
|
||||
/lib/systemd/system/vpncloud@.service
|
||||
/lib/systemd/system/vpncloud.target
|
||||
/lib/systemd/system/vpncloud-wsproxy.service
|
||||
/usr/share/man/man1/vpncloud.1.gz
|
||||
|
||||
%defattr(-,root,root,-)
|
||||
%{_bindir}/*
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
|||
|
||||
This project follows [semantic versioning](http://semver.org).
|
||||
|
||||
### UNRELEASED
|
||||
|
||||
- [changed] Changed Rust version to 1.75.0
|
||||
- [changed] Updated dependencies
|
||||
- [fixed] Fix error when IPv6 is not available
|
||||
|
||||
### v2.3.0 (2021-12-23)
|
||||
|
||||
- [added] Added build for armv5te (thanks to xek)
|
||||
- [added] Option to specify advertised addresses
|
||||
- [added] Peers now learn their own address from peers
|
||||
- [changed] Changed Rust version to 1.57.0
|
||||
- [changed] Updated dependencies
|
||||
- [fixed] Fixed problem with IPv4 addresses in listen option
|
||||
- [fixed] Fixed periodic broadcast messages in switch mode
|
||||
|
||||
### v2.2.0 (2021-04-06)
|
||||
|
||||
- [added] Service target file (thanks to mnhauke)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
42
Cargo.toml
42
Cargo.toml
|
@ -1,45 +1,45 @@
|
|||
[package]
|
||||
name = "vpncloud"
|
||||
version = "2.2.0"
|
||||
version = "2.4.0"
|
||||
authors = ["Dennis Schwerdel <schwerdel@googlemail.com>"]
|
||||
build = "build.rs"
|
||||
license = "GPL-3.0"
|
||||
description = "Peer-to-peer VPN"
|
||||
homepage = "https://vpncloud.ddswd.de"
|
||||
repository = "https://github.com/dswd/vpncloud"
|
||||
keywords = ["vpn", "p2p", "tun", "tap", "network"]
|
||||
readme = "README.md"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
toolchain = "1.51.0"
|
||||
upx_version = "3.96"
|
||||
toolchain = "1.75.0"
|
||||
upx_version = "4.2.2"
|
||||
|
||||
[dependencies]
|
||||
time = "=0.2.22"
|
||||
chrono = { version = "0.4", features = ["std", "clock"], default_features = false}
|
||||
structopt = "0.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_yaml = "0.8"
|
||||
serde_yaml = "0.9"
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
signal = "0.7"
|
||||
libc = "0.2"
|
||||
rand = "0.8"
|
||||
fnv = "1"
|
||||
yaml-rust = "0.4"
|
||||
daemonize = "0.4"
|
||||
ring = "0.16"
|
||||
daemonize = "0.5"
|
||||
ring = "0.17"
|
||||
privdrop = "0.5"
|
||||
byteorder = "1.4"
|
||||
thiserror = "1.0"
|
||||
smallvec = "1.6"
|
||||
dialoguer = { version = "0.8", optional = true }
|
||||
tungstenite = { version = "0.13", optional = true, default-features = false }
|
||||
smallvec = "1.7"
|
||||
dialoguer = { version = "0.11", optional = true }
|
||||
tungstenite = { version = "0.21", optional = true }
|
||||
url = { version = "2.2", optional = true }
|
||||
igd = { version = "0.12", optional = true }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
criterion = { version = "0.3", features = ["html_reports"] }
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
iai = "0.1"
|
||||
|
||||
[features]
|
||||
|
@ -59,6 +59,7 @@ harness = false
|
|||
|
||||
[profile.release]
|
||||
lto = true
|
||||
strip = true
|
||||
|
||||
[profile.dev]
|
||||
lto = false
|
||||
|
@ -88,8 +89,13 @@ assets = [
|
|||
["target/vpncloud.1.gz", "/usr/share/man/man1/vpncloud.1.gz", "644"]
|
||||
]
|
||||
|
||||
[package.metadata.rpm.cargo]
|
||||
buildflags = ["--release"]
|
||||
|
||||
[package.metadata.rpm.targets]
|
||||
vpncloud = { path = "/usr/bin/vpncloud" }
|
||||
[package.metadata.generate-rpm]
|
||||
assets = [
|
||||
{ source = "target/release/vpncloud", dest = "/usr/bin/vpncloud", mode = "755" },
|
||||
{ source = "assets/example.net.disabled", dest = "/etc/vpncloud/example.net.disabled", mode = "600" },
|
||||
{ source = "assets/vpncloud@.service", dest = "/lib/systemd/system/vpncloud@.service", mode = "644" },
|
||||
{ source = "assets/vpncloud.target", dest = "/lib/systemd/system/vpncloud.target", mode = "644" },
|
||||
{ source = "assets/vpncloud-wsproxy.service", dest = "/lib/systemd/system/vpncloud-wsproxy.service", mode = "644" },
|
||||
{ source = "target/vpncloud.1.gz", dest = "/usr/share/man/man1/vpncloud.1.gz", mode = "644" }
|
||||
]
|
||||
auto-req = "no"
|
|
@ -1,3 +1,15 @@
|
|||
vpncloud (2.3.0) stable; urgency=medium
|
||||
|
||||
* [added] Added build for armv5te (thanks to xek)
|
||||
* [added] Option to specify advertised addresses
|
||||
* [added] Peers now learn their own address from peers
|
||||
* [changed] Changed Rust version to 1.57.0
|
||||
* [changed] Updated dependencies
|
||||
* [fixed] Fixed problem with IPv4 addresses in listen option
|
||||
* [fixed] Fixed periodic broadcast messages in switch mode
|
||||
|
||||
-- Dennis Schwerdel <schwerdel+vpncloud@googlemail.com> Thu, 23 Dec 2021 20:41:00 +0100
|
||||
|
||||
vpncloud (2.2.0) stable; urgency=medium
|
||||
|
||||
* [added] Service target file (thanks to mnhauke)
|
||||
|
|
|
@ -15,7 +15,7 @@ include!(".code.rs");
|
|||
pub use error::Error;
|
||||
use util::{MockTimeSource, MsgBuffer};
|
||||
use types::{Address, Range};
|
||||
use table::{ClaimTable};
|
||||
use table::ClaimTable;
|
||||
use device::Type;
|
||||
use config::Config;
|
||||
use payload::{Packet, Frame, Protocol};
|
||||
|
@ -29,7 +29,7 @@ fn udp_send(c: &mut Criterion) {
|
|||
let mut g = c.benchmark_group("udp_send");
|
||||
g.throughput(Throughput::Bytes(1400));
|
||||
g.bench_function("udp_send", |b| {
|
||||
b.iter(|| sock.send_to(&data, &addr).unwrap());
|
||||
b.iter(|| sock.send_to(&data, addr).unwrap());
|
||||
});
|
||||
g.finish();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use util::{MockTimeSource, MsgBuffer};
|
|||
use config::Config;
|
||||
use types::{Address, Range};
|
||||
use device::Type;
|
||||
use table::{ClaimTable};
|
||||
use table::ClaimTable;
|
||||
use payload::{Packet, Frame, Protocol};
|
||||
use crypto::core::{create_dummy_pair, EXTRA_LEN};
|
||||
use tests::common::{TunSimulator, TapSimulator};
|
||||
|
@ -26,7 +26,7 @@ fn udp_send() {
|
|||
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||
let data = [0; 1400];
|
||||
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() {
|
||||
|
|
28
build.rs
28
build.rs
|
@ -1,28 +0,0 @@
|
|||
// VpnCloud - Peer-to-Peer VPN
|
||||
// Copyright (C) 2015-2021 Dennis Schwerdel
|
||||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||
|
||||
use std::{env, fs, path::Path, process::Command};
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
|
||||
// Process manpage using asciidoctor command
|
||||
println!("cargo:rerun-if-changed=vpncloud.adoc");
|
||||
fs::create_dir_all(&out_dir).unwrap();
|
||||
fs::copy("vpncloud.adoc", Path::new(&out_dir).join("vpncloud.adoc")).unwrap();
|
||||
match Command::new("asciidoctor")
|
||||
.args(&["-b", "manpage", "vpncloud.adoc"])
|
||||
.current_dir(&Path::new(&out_dir))
|
||||
.status()
|
||||
{
|
||||
Ok(_) => {
|
||||
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();
|
||||
}
|
||||
Err(err) => {
|
||||
println!("cargo:warning=Error building manpage: {}", err);
|
||||
println!("cargo:warning=The manpage will not be build. Do you have 'asciidoctor'?");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
cache
|
||||
build.sh
|
|
@ -1,42 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
ARG TOOLCHAIN=stable
|
||||
ARG UPX_VERSION=3.96
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
curl \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
libc6-dev-arm64-cross \
|
||||
libc6-dev-armhf-cross \
|
||||
libc6-dev-i386 \
|
||||
gcc-5-multilib \
|
||||
asciidoctor \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV RUSTUP_HOME=/opt/rust/rustup \
|
||||
PATH=/opt/rust/cargo/bin:/home/user/.cargo/bin:/usr/local/musl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | env CARGO_HOME=/opt/rust/cargo sh -s -- -y --default-toolchain ${TOOLCHAIN} --profile minimal --no-modify-path
|
||||
|
||||
RUN env CARGO_HOME=/opt/rust/cargo rustup target add i686-unknown-linux-gnu \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add armv7-unknown-linux-gnueabihf \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add aarch64-unknown-linux-gnu
|
||||
|
||||
RUN env CARGO_HOME=/opt/rust/cargo cargo install cargo-deb \
|
||||
&& rm -rf /opt/rust/cargo/{git,tmp,registry}
|
||||
|
||||
RUN ln -s asm-generic/ /usr/include/asm
|
||||
|
||||
RUN useradd -ms /bin/bash user
|
||||
USER user
|
||||
WORKDIR /home/user
|
||||
|
||||
RUN mkdir -p /home/user/.cargo \
|
||||
&& ln -s /opt/rust/cargo/config /home/user/.cargo/config
|
||||
|
||||
VOLUME /home/user/.cargo/tmp
|
||||
VOLUME /home/user/.cargo/git
|
||||
VOLUME /home/user/.cargo/registry
|
|
@ -1,46 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
ARG TOOLCHAIN=stable
|
||||
ARG UPX_VERSION=3.96
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||
build-essential \
|
||||
curl \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
libc6-dev-arm64-cross \
|
||||
libc6-dev-armhf-cross \
|
||||
libc6-dev-i386 \
|
||||
gcc-5-multilib \
|
||||
asciidoctor \
|
||||
musl musl-dev musl-tools \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV RUSTUP_HOME=/opt/rust/rustup \
|
||||
PATH=/opt/rust/cargo/bin:/home/user/.cargo/bin:/usr/local/musl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | env CARGO_HOME=/opt/rust/cargo sh -s -- -y --default-toolchain ${TOOLCHAIN} --profile minimal --no-modify-path
|
||||
|
||||
RUN env CARGO_HOME=/opt/rust/cargo rustup target add x86_64-unknown-linux-musl \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add i686-unknown-linux-musl \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add armv7-unknown-linux-musleabihf \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add aarch64-unknown-linux-musl
|
||||
|
||||
RUN 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
|
||||
|
||||
RUN ln -s asm-generic/ /usr/include/asm \
|
||||
&& ln -s /usr/bin/g++ /usr/bin/musl-g++ \
|
||||
&& ln -s /usr/bin/aarch64-linux-gnu-gcc /usr/bin/aarch64-linux-musl-gcc \
|
||||
&& ln -s /usr/bin/arm-linux-gnueabihf-gcc /usr/bin/arm-linux-musleabihf-gcc
|
||||
|
||||
RUN useradd -ms /bin/bash user
|
||||
USER user
|
||||
WORKDIR /home/user
|
||||
|
||||
RUN mkdir -p /home/user/.cargo \
|
||||
&& ln -s /opt/rust/cargo/config /home/user/.cargo/config
|
||||
|
||||
VOLUME /home/user/.cargo/tmp
|
||||
VOLUME /home/user/.cargo/git
|
||||
VOLUME /home/user/.cargo/registry
|
|
@ -1,32 +0,0 @@
|
|||
FROM centos:7
|
||||
|
||||
ARG TOOLCHAIN=stable
|
||||
|
||||
RUN yum groupinstall -y 'Development Tools'
|
||||
RUN yum install -y ruby && gem install asciidoctor -v 2.0.10
|
||||
|
||||
ENV RUSTUP_HOME=/opt/rust/rustup \
|
||||
PATH=/opt/rust/cargo/bin:/home/user/.cargo/bin:/usr/local/musl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | env CARGO_HOME=/opt/rust/cargo sh -s -- -y --default-toolchain ${TOOLCHAIN} --profile minimal --no-modify-path
|
||||
|
||||
RUN env CARGO_HOME=/opt/rust/cargo rustup target add i686-unknown-linux-gnu \
|
||||
&& env CARGO_HOME=/opt/rust/cargo rustup target add armv7-unknown-linux-gnueabihf
|
||||
|
||||
RUN env CARGO_HOME=/opt/rust/cargo cargo install cargo-rpm \
|
||||
&& rm -rf /opt/rust/cargo/{git,tmp,registry}
|
||||
|
||||
RUN yum install -y libstdc++-*.i686 \
|
||||
&& yum install -y glibc-*.i686 \
|
||||
&& yum install -y libgcc.i686
|
||||
|
||||
RUN useradd -ms /bin/bash user
|
||||
USER user
|
||||
WORKDIR /home/user
|
||||
|
||||
RUN mkdir -p /home/user/.cargo \
|
||||
&& ln -s /opt/rust/cargo/config /home/user/.cargo/config
|
||||
|
||||
VOLUME /home/user/.cargo/tmp
|
||||
VOLUME /home/user/.cargo/git
|
||||
VOLUME /home/user/.cargo/registry
|
|
@ -1,96 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
function docker_cmd() {
|
||||
DIST=$1
|
||||
CMD=$2
|
||||
mkdir -p $CACHE/$DIST/{target,registry,git,tmp}
|
||||
docker run -it --rm -v $(pwd)/..:/home/user/code \
|
||||
-v $CACHE/$DIST/target:/home/user/code/target \
|
||||
-v $CACHE/$DIST/registry:/home/user/.cargo/registry \
|
||||
-v $CACHE/$DIST/git:/home/user/.cargo/git \
|
||||
-v $CACHE/$DIST/tmp:/home/user/.cargo/tmp \
|
||||
vpncloud-builder-$DIST bash -c "$CMD"
|
||||
}
|
||||
|
||||
# docker run -it --rm -v $(pwd)/..:/home/user/code -v $(pwd)/cache/rpm/target:/home/user/code/target -v $(pwd)/cache/rpm/registry:/home/user/code/registry -v $(pwd)/cache/rpm/git:/home/user/code/git -v $(pwd)/cache/rpm/tmp:/home/user/code/tmp vpncloud-builder-rpm
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
TOOLCHAIN=$(grep -e '^toolchain =' ../Cargo.toml | sed -e 's/toolchain = "\(.*\)"/\1/')
|
||||
UPX_VERSION=$(grep -e '^upx_version =' ../Cargo.toml | sed -e 's/upx_version = "\(.*\)"/\1/')
|
||||
|
||||
VERSION=$(grep -e '^version =' ../Cargo.toml | sed -e 's/version = "\(.*\)"/\1/')
|
||||
DEB_VERSION=$(echo "$VERSION" | sed -e 's/-/~/g')
|
||||
if echo "$VERSION" | fgrep -q "-"; then
|
||||
RPM_VERSION=$(echo "$VERSION" | sed -e 's/-/-0./g')
|
||||
else
|
||||
RPM_VERSION="$VERSION-1"
|
||||
fi
|
||||
|
||||
mkdir -p cache/{rpm,deb,musl}
|
||||
CACHE=$(pwd)/cache
|
||||
|
||||
mkdir -p ../dist
|
||||
|
||||
docker build --rm -f=Dockerfile-deb --build-arg TOOLCHAIN=$TOOLCHAIN --build-arg UPX_VERSION=$UPX_VERSION -t vpncloud-builder-deb .
|
||||
|
||||
# x86_64 deb
|
||||
if ! [ -f ../dist/vpncloud_${DEB_VERSION}_amd64.deb ]; then
|
||||
docker_cmd deb 'cd code && cargo deb'
|
||||
cp $CACHE/deb/target/debian/vpncloud_${DEB_VERSION}_amd64.deb ../dist/vpncloud_${DEB_VERSION}_amd64.deb
|
||||
fi
|
||||
|
||||
build_deb() {
|
||||
ARCH=$1
|
||||
TARGET=$2
|
||||
if ! [ -f ../dist/vpncloud_${DEB_VERSION}_${ARCH}.deb ]; then
|
||||
docker_cmd deb "cd code && cargo deb --target ${TARGET}"
|
||||
cp $CACHE/deb/target/${TARGET}/debian/vpncloud_${DEB_VERSION}_${ARCH}.deb ../dist/vpncloud_${DEB_VERSION}_${ARCH}.deb
|
||||
fi
|
||||
}
|
||||
|
||||
build_deb i386 i686-unknown-linux-gnu
|
||||
build_deb armhf armv7-unknown-linux-gnueabihf
|
||||
build_deb arm64 aarch64-unknown-linux-gnu
|
||||
|
||||
|
||||
docker build --rm -f=Dockerfile-musl -t vpncloud-builder-musl .
|
||||
|
||||
build_static() {
|
||||
ARCH=$1
|
||||
TARGET=$2
|
||||
if ! [ -f ../dist/vpncloud_${VERSION}_static_${ARCH} ]; then
|
||||
docker_cmd musl "cd code && cargo build --release --features installer --target ${TARGET} && upx --lzma target/${TARGET}/release/vpncloud"
|
||||
cp $CACHE/musl/target/${TARGET}/release/vpncloud ../dist/vpncloud_${VERSION}_static_${ARCH}
|
||||
fi
|
||||
}
|
||||
|
||||
build_static amd64 x86_64-unknown-linux-musl
|
||||
#build_static i386 i686-unknown-linux-musl
|
||||
build_static armhf armv7-unknown-linux-musleabihf
|
||||
build_static arm64 aarch64-unknown-linux-musl
|
||||
|
||||
|
||||
docker build --rm -f=Dockerfile-rpm -t vpncloud-builder-rpm .
|
||||
|
||||
if ! [ -f ../dist/vpncloud_${RPM_VERSION}.x86_64.rpm ]; then
|
||||
# x86_64 rpm
|
||||
docker_cmd rpm 'cd code && cargo rpm build'
|
||||
cp $CACHE/rpm/target/release/rpmbuild/RPMS/x86_64/vpncloud-${RPM_VERSION}.x86_64.rpm ../dist/vpncloud_${RPM_VERSION}.x86_64.rpm
|
||||
fi
|
||||
|
||||
build_rpm() {
|
||||
ARCH=$1
|
||||
TARGET=$2
|
||||
if ! [ -f ../dist/vpncloud_${RPM_VERSION}.${ARCH}.rpm ]; then
|
||||
mkdir -p $CACHE/rpm/target
|
||||
[ -L $CACHE/rpm/target/assets ] || ln -s ../assets $CACHE/rpm/target/assets
|
||||
[ -L $CACHE/rpm/target/target ] || ln -s ../target $CACHE/rpm/target/target
|
||||
docker_cmd rpm "cd code && cargo rpm build --target ${TARGET}"
|
||||
cp $CACHE/rpm/target/${TARGET}/release/rpmbuild/RPMS/${ARCH}/vpncloud-${RPM_VERSION}.${ARCH}.rpm ../dist/vpncloud_${RPM_VERSION}.${ARCH}.rpm
|
||||
fi
|
||||
}
|
||||
|
||||
build_rpm i686 i686-unknown-linux-gnu
|
|
@ -120,7 +120,7 @@ def find_ami(region, owner, name_pattern, arch='x86_64'):
|
|||
|
||||
|
||||
class EC2Environment:
|
||||
def __init__(self, vpncloud_version, region, node_count, instance_type, vpncloud_file=None, use_spot=True, max_price=0.1, ami=('amazon', 'amzn2-ami-hvm-*'), username="ec2-user", subnet=CREATE, keyname=CREATE, privatekey=CREATE, tag="vpncloud", cluster_nodes=False):
|
||||
def __init__(self, vpncloud_version, region, node_count, instance_type, vpncloud_file=None, use_spot=True, max_price=0.1, ami=('amazon', 'al2023-ami-*-hvm-*'), username="ec2-user", subnet=CREATE, keyname=CREATE, privatekey=CREATE, tag="vpncloud", cluster_nodes=False):
|
||||
self.region = region
|
||||
self.node_count = node_count
|
||||
self.instance_type = instance_type
|
||||
|
@ -249,7 +249,6 @@ runcmd:
|
|||
"Ebs": {
|
||||
"DeleteOnTermination": True,
|
||||
"VolumeType": "gp2",
|
||||
"VolumeSize": 8,
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -292,7 +291,7 @@ runcmd:
|
|||
MinCount=self.node_count,
|
||||
NetworkInterfaces=[
|
||||
{
|
||||
'SubnetId': self.subnet.id,
|
||||
'SubnetId': self.subnet,
|
||||
'DeviceIndex': 0,
|
||||
'AssociatePublicIpAddress': True,
|
||||
'Groups': [sg.group_id]
|
||||
|
@ -300,7 +299,7 @@ runcmd:
|
|||
],
|
||||
Placement=placement,
|
||||
UserData=userdata,
|
||||
KeyName='vpncloud-perf-test-keypair'
|
||||
KeyName=key_pair.name
|
||||
)
|
||||
for instance in self.instances:
|
||||
self.track_resource(instance)
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
{
|
||||
"meta": {
|
||||
"region": "eu-central-1",
|
||||
"instance_type": "m5.large",
|
||||
"ami": "ami-0db9040eb3ab74509",
|
||||
"version": "2.2.0",
|
||||
"duration": 623.0307722091675
|
||||
},
|
||||
"native": {
|
||||
"iperf": {
|
||||
"throughput": 9680235000.0,
|
||||
"cpu_sender": 12.015535,
|
||||
"cpu_receiver": 71.982452
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.049,
|
||||
"rtt_max": 0.219,
|
||||
"rtt_avg": 0.058,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.053,
|
||||
"rtt_max": 0.247,
|
||||
"rtt_avg": 0.059,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.053,
|
||||
"rtt_max": 0.189,
|
||||
"rtt_avg": 0.06,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"plain": {
|
||||
"iperf": {
|
||||
"throughput": 5790600000.0,
|
||||
"cpu_sender": 14.109763,
|
||||
"cpu_receiver": 69.727033
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.079,
|
||||
"rtt_max": 0.291,
|
||||
"rtt_avg": 0.094,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.079,
|
||||
"rtt_max": 0.304,
|
||||
"rtt_avg": 0.096,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.082,
|
||||
"rtt_max": 0.367,
|
||||
"rtt_avg": 0.097,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"aes256": {
|
||||
"iperf": {
|
||||
"throughput": 3917767000.0,
|
||||
"cpu_sender": 6.439156,
|
||||
"cpu_receiver": 64.267206
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.081,
|
||||
"rtt_max": 0.206,
|
||||
"rtt_avg": 0.097,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.088,
|
||||
"rtt_max": 0.206,
|
||||
"rtt_avg": 0.1,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.089,
|
||||
"rtt_max": 0.319,
|
||||
"rtt_avg": 0.103,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"aes128": {
|
||||
"iperf": {
|
||||
"throughput": 3697142000.0,
|
||||
"cpu_sender": 7.417808,
|
||||
"cpu_receiver": 59.433831
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.083,
|
||||
"rtt_max": 0.265,
|
||||
"rtt_avg": 0.097,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.081,
|
||||
"rtt_max": 0.369,
|
||||
"rtt_avg": 0.102,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.086,
|
||||
"rtt_max": 0.448,
|
||||
"rtt_avg": 0.102,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"chacha20": {
|
||||
"iperf": {
|
||||
"throughput": 3194412000.0,
|
||||
"cpu_sender": 6.12856,
|
||||
"cpu_receiver": 61.223349
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.081,
|
||||
"rtt_max": 0.28,
|
||||
"rtt_avg": 0.098,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.088,
|
||||
"rtt_max": 0.264,
|
||||
"rtt_avg": 0.103,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.092,
|
||||
"rtt_max": 0.204,
|
||||
"rtt_avg": 0.106,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"throughput_mbits": {
|
||||
"native": 9680.235,
|
||||
"plain": 5790.6,
|
||||
"aes256": 3917.767,
|
||||
"aes128": 3697.142,
|
||||
"chacha20": 3194.412
|
||||
},
|
||||
"latency_us": {
|
||||
"plain": {
|
||||
"100": 18.0,
|
||||
"500": 18.500000000000004,
|
||||
"1000": 18.500000000000004
|
||||
},
|
||||
"aes256": {
|
||||
"100": 19.5,
|
||||
"500": 20.500000000000004,
|
||||
"1000": 21.5
|
||||
},
|
||||
"aes128": {
|
||||
"100": 19.5,
|
||||
"500": 21.5,
|
||||
"1000": 20.999999999999996
|
||||
},
|
||||
"chacha20": {
|
||||
"100": 20.0,
|
||||
"500": 22.0,
|
||||
"1000": 23.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
{
|
||||
"meta": {
|
||||
"region": "eu-central-1",
|
||||
"instance_type": "m5.large",
|
||||
"ami": "ami-099ccc441b2ef41ec",
|
||||
"version": "2.3.0",
|
||||
"duration": 622.5463161468506
|
||||
},
|
||||
"native": {
|
||||
"iperf": {
|
||||
"throughput": 9529265000.0,
|
||||
"cpu_sender": 11.32918,
|
||||
"cpu_receiver": 61.870429
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.046,
|
||||
"rtt_max": 0.225,
|
||||
"rtt_avg": 0.053,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.047,
|
||||
"rtt_max": 10.98,
|
||||
"rtt_avg": 0.054,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.048,
|
||||
"rtt_max": 0.175,
|
||||
"rtt_avg": 0.056,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"plain": {
|
||||
"iperf": {
|
||||
"throughput": 6388312000.0,
|
||||
"cpu_sender": 16.955082,
|
||||
"cpu_receiver": 72.705695
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.076,
|
||||
"rtt_max": 11.973,
|
||||
"rtt_avg": 0.09,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.08,
|
||||
"rtt_max": 10.95,
|
||||
"rtt_avg": 0.094,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.081,
|
||||
"rtt_max": 1.638,
|
||||
"rtt_avg": 0.095,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"aes256": {
|
||||
"iperf": {
|
||||
"throughput": 3801851000.0,
|
||||
"cpu_sender": 5.826756,
|
||||
"cpu_receiver": 61.612033
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.075,
|
||||
"rtt_max": 0.9,
|
||||
"rtt_avg": 0.093,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.079,
|
||||
"rtt_max": 0.275,
|
||||
"rtt_avg": 0.091,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.08,
|
||||
"rtt_max": 1.015,
|
||||
"rtt_avg": 0.093,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"aes128": {
|
||||
"iperf": {
|
||||
"throughput": 3880325000.0,
|
||||
"cpu_sender": 6.219277,
|
||||
"cpu_receiver": 62.125445
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.077,
|
||||
"rtt_max": 11.656,
|
||||
"rtt_avg": 0.09,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.08,
|
||||
"rtt_max": 0.211,
|
||||
"rtt_avg": 0.095,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.082,
|
||||
"rtt_max": 1.398,
|
||||
"rtt_avg": 0.095,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"chacha20": {
|
||||
"iperf": {
|
||||
"throughput": 3126447000.0,
|
||||
"cpu_sender": 5.113819,
|
||||
"cpu_receiver": 58.58095
|
||||
},
|
||||
"ping_100": {
|
||||
"rtt_min": 0.079,
|
||||
"rtt_max": 0.271,
|
||||
"rtt_avg": 0.091,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_500": {
|
||||
"rtt_min": 0.083,
|
||||
"rtt_max": 0.272,
|
||||
"rtt_avg": 0.098,
|
||||
"pkt_loss": 0.0
|
||||
},
|
||||
"ping_1000": {
|
||||
"rtt_min": 0.087,
|
||||
"rtt_max": 1.615,
|
||||
"rtt_avg": 0.101,
|
||||
"pkt_loss": 0.0
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"throughput_mbits": {
|
||||
"native": 9529.265,
|
||||
"plain": 6388.312,
|
||||
"aes256": 3801.851,
|
||||
"aes128": 3880.325,
|
||||
"chacha20": 3126.447
|
||||
},
|
||||
"latency_us": {
|
||||
"plain": {
|
||||
"100": 18.5,
|
||||
"500": 20.0,
|
||||
"1000": 19.5
|
||||
},
|
||||
"aes256": {
|
||||
"100": 20.0,
|
||||
"500": 18.5,
|
||||
"1000": 18.5
|
||||
},
|
||||
"aes128": {
|
||||
"100": 18.5,
|
||||
"500": 20.5,
|
||||
"1000": 19.5
|
||||
},
|
||||
"chacha20": {
|
||||
"100": 19.0,
|
||||
"500": 22.000000000000004,
|
||||
"1000": 22.500000000000004
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,15 +7,15 @@ from datetime import date
|
|||
|
||||
# Note: this script will run for ~8 minutes and incur costs of about $ 0.02
|
||||
|
||||
FILE = "../target/release/vpncloud"
|
||||
VERSION = "2.1.0"
|
||||
FILE = "../../target/release/vpncloud"
|
||||
VERSION = "2.4.0"
|
||||
REGION = "eu-central-1"
|
||||
|
||||
env = EC2Environment(
|
||||
region = REGION,
|
||||
node_count = 2,
|
||||
instance_type = "m5.large",
|
||||
use_spot = True,
|
||||
use_spot = False,
|
||||
max_price = "0.08", # USD per hour per VM
|
||||
vpncloud_version = VERSION,
|
||||
vpncloud_file = FILE,
|
||||
|
@ -113,4 +113,4 @@ name = "measurements/{date}_{version}_perf.json".format(date=date.today().strfti
|
|||
eprint('Storing results in {}'.format(name))
|
||||
with open(name, 'w') as fp:
|
||||
json.dump(results, fp, indent=2)
|
||||
eprint("done.")
|
||||
eprint("done.")
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
# Commands
|
||||
|
||||
Needs [mask](https://github.com/jacobdeichert/mask) to run.
|
||||
|
||||
|
||||
## install-tools
|
||||
|
||||
> Install tools.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
apt-get install -y asciidoctor
|
||||
cargo install cargo-binstall
|
||||
cargo binstall cross cargo-deb cargo-generate-rpm
|
||||
UPX_VERSION=$(grep -e '^upx_version =' Cargo.toml | sed -e 's/upx_version = "\(.*\)"/\1/')
|
||||
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/local/bin
|
||||
```
|
||||
|
||||
## manpage
|
||||
|
||||
> Generate manpage.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
echo >&2 "Generating manpage"
|
||||
if [ ! -f target/vpncloud.1.gz -o vpncloud.adoc -nt target/vpncloud.1.gz ]; then
|
||||
asciidoctor -b manpage -o target/vpncloud.1 vpncloud.adoc
|
||||
gzip -f target/vpncloud.1
|
||||
fi
|
||||
```
|
||||
|
||||
## build-packages-cross (target) (target_name) (target_name_rpm)
|
||||
|
||||
> Build the project packages for a given target.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
VERSION=$(grep -e '^version =' Cargo.toml | sed -e 's/version = "\(.*\)"/\1/')
|
||||
TARGET=$target
|
||||
TARGET_DIR=target/$target_name
|
||||
|
||||
# compile
|
||||
echo >&2 "Compiling for $target_name"
|
||||
cross build --release --target $TARGET --target-dir $TARGET_DIR
|
||||
mkdir -p target/$TARGET/release
|
||||
cp $TARGET_DIR/$TARGET/release/vpncloud target/$TARGET/release/
|
||||
|
||||
# build deb
|
||||
echo >&2 "Building deb package"
|
||||
cargo deb --no-build --no-strip --target $TARGET
|
||||
mv target/$TARGET/debian/vpncloud_${VERSION}-1_$target_name.deb dist/vpncloud_${VERSION}_$target_name.deb
|
||||
|
||||
# build rpm
|
||||
if [ -n "$target_name_rpm" ]; then
|
||||
echo >&2 "Building rpm package"
|
||||
cargo generate-rpm --target $TARGET --target-dir $TARGET_DIR
|
||||
mv $TARGET_DIR/$TARGET/generate-rpm/vpncloud-${VERSION}-1.$target_name_rpm.rpm dist/vpncloud_${VERSION}-1.$target_name_rpm.rpm
|
||||
fi
|
||||
```
|
||||
|
||||
## build-amd64-packages
|
||||
|
||||
```sh
|
||||
$MASK build-packages-cross x86_64-unknown-linux-gnu amd64 x86_64
|
||||
```
|
||||
|
||||
## build-i386-packages
|
||||
|
||||
```sh
|
||||
$MASK build-packages-cross i686-unknown-linux-gnu i386 i686
|
||||
```
|
||||
|
||||
## build-arm64-packages
|
||||
|
||||
```sh
|
||||
$MASK build-packages-cross aarch64-unknown-linux-gnu arm64 aarch64
|
||||
```
|
||||
|
||||
## build-armhf-packages
|
||||
|
||||
```sh
|
||||
$MASK build-packages-cross armv7-unknown-linux-gnueabihf armhf ""
|
||||
```
|
||||
|
||||
## build-armel-packages
|
||||
|
||||
```sh
|
||||
$MASK build-packages-cross armv5te-unknown-linux-gnueabi armel ""
|
||||
```
|
||||
|
||||
|
||||
|
||||
## build-static-cross (target) (target_name)
|
||||
|
||||
> Build the project statically for a given target.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
VERSION=$(grep -e '^version =' Cargo.toml | sed -e 's/version = "\(.*\)"/\1/')
|
||||
TARGET=$target
|
||||
TARGET_DIR=target/$target_name-musl
|
||||
BIN=$TARGET_DIR/$TARGET/release/vpncloud
|
||||
|
||||
echo >&2 "Compiling for $target_name musl"
|
||||
cross build --release --features installer --target $TARGET --target-dir $TARGET_DIR
|
||||
upx --lzma $BIN
|
||||
cp $BIN dist/vpncloud_${VERSION}_static_$target_name
|
||||
```
|
||||
|
||||
## build-amd64-static
|
||||
|
||||
```sh
|
||||
$MASK build-static-cross x86_64-unknown-linux-musl amd64
|
||||
```
|
||||
|
||||
|
||||
## build-i386-static
|
||||
|
||||
```sh
|
||||
$MASK build-static-cross i686-unknown-linux-musl i386
|
||||
```
|
||||
|
||||
|
||||
## build-arm64-static
|
||||
|
||||
```sh
|
||||
$MASK build-static-cross aarch64-unknown-linux-musl arm64
|
||||
```
|
||||
|
||||
## build-armhf-static
|
||||
|
||||
```sh
|
||||
$MASK build-static-cross armv7-unknown-linux-musleabihf armhf
|
||||
```
|
||||
|
||||
## build-armel-static
|
||||
|
||||
```sh
|
||||
$MASK build-static-cross armv5te-unknown-linux-musleabi armel
|
||||
```
|
||||
|
||||
|
||||
## build
|
||||
|
||||
> Build the project for all architectures.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
$MASK manpage
|
||||
$MASK build-amd64-packages
|
||||
$MASK build-amd64-static
|
||||
$MASK build-i386-packages
|
||||
$MASK build-i386-static
|
||||
$MASK build-arm64-packages
|
||||
$MASK build-arm64-static
|
||||
$MASK build-armhf-packages
|
||||
$MASK build-armhf-static
|
||||
$MASK build-armel-packages
|
||||
$MASK build-armel-static
|
||||
```
|
||||
|
||||
## sign
|
||||
|
||||
> Sign the packages.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
VERSION=$(grep -e '^version =' Cargo.toml | sed -e 's/version = "\(.*\)"/\1/')
|
||||
cd dist
|
||||
sha256sum vpncloud_${VERSION}_static_* vpncloud_${VERSION}*.rpm vpncloud_${VERSION}*.deb > vpncloud_${VERSION}_SHA256SUMS.txt
|
||||
gpg --armor --output vpncloud_${VERSION}_SHA256SUMS.txt.asc --detach-sig vpncloud_${VERSION}_SHA256SUMS.txt
|
||||
```
|
||||
|
||||
## test
|
||||
|
||||
> Test the project.
|
||||
|
||||
```sh
|
||||
cargo test --all-features
|
||||
```
|
||||
|
||||
## release
|
||||
|
||||
> Release the project.
|
||||
|
||||
```sh
|
||||
set -e
|
||||
|
||||
$MASK test
|
||||
nano Cargo.toml
|
||||
VERSION=$(grep -e '^version =' Cargo.toml | sed -e 's/version = "\(.*\)"/\1/')
|
||||
nano CHANGELOG.md
|
||||
nano assets/changelog.txt
|
||||
$MASK build
|
||||
$MASK sign
|
||||
git commit -a
|
||||
cargo publish
|
||||
git tag v$VERSION
|
||||
git push --tags
|
||||
```
|
||||
|
||||
|
||||
## count
|
||||
|
||||
> Count the lines of code.
|
||||
|
||||
```sh
|
||||
tokei
|
||||
```
|
|
@ -228,7 +228,7 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
|||
let beacon = format!("{}{}{}", begin, data, end);
|
||||
debug!("Calling beacon command: {}", cmd);
|
||||
let process = Command::new("sh")
|
||||
.args(&["-c", cmd])
|
||||
.args(["-c", cmd])
|
||||
.env("begin", begin)
|
||||
.env("data", data)
|
||||
.env("end", end)
|
||||
|
@ -281,7 +281,7 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
|||
let end = self.end();
|
||||
debug!("Calling beacon command: {}", cmd);
|
||||
let process = Command::new("sh")
|
||||
.args(&["-c", cmd])
|
||||
.args(["-c", cmd])
|
||||
.env("begin", begin)
|
||||
.env("end", end)
|
||||
.stdout(Stdio::piped())
|
||||
|
|
49
src/cloud.rs
49
src/cloud.rs
|
@ -29,7 +29,7 @@ use crate::{
|
|||
AddrList, NodeInfo, PeerInfo, MESSAGE_TYPE_CLOSE, MESSAGE_TYPE_DATA, MESSAGE_TYPE_KEEPALIVE,
|
||||
MESSAGE_TYPE_NODE_INFO,
|
||||
},
|
||||
net::{mapped_addr, Socket},
|
||||
net::{mapped_addr, parse_listen, Socket},
|
||||
payload::Protocol,
|
||||
poll::{WaitImpl, WaitResult},
|
||||
port_forwarding::PortForwarding,
|
||||
|
@ -222,7 +222,14 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
|
||||
pub fn reset_own_addresses(&mut self) -> io::Result<()> {
|
||||
self.own_addresses.clear();
|
||||
self.own_addresses.push(self.socket.address().map(mapped_addr)?);
|
||||
let socket_addr = self.socket.address().map(mapped_addr)?;
|
||||
// 1) Specified advertise addresses
|
||||
for addr in &self.config.advertise_addresses {
|
||||
self.own_addresses.push(parse_listen(addr, socket_addr.port()));
|
||||
}
|
||||
// 2) Address of UDP socket
|
||||
self.own_addresses.push(socket_addr);
|
||||
// 3) Addresses from port forwarding
|
||||
if let Some(ref pfw) = self.port_forwarding {
|
||||
self.own_addresses.push(pfw.get_internal_ip().into());
|
||||
self.own_addresses.push(pfw.get_external_ip().into());
|
||||
|
@ -372,7 +379,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
for entry in &mut self.reconnect_peers {
|
||||
// Schedule for next second if node is connected
|
||||
for addr in &entry.resolved {
|
||||
if self.peers.contains_key(&addr) {
|
||||
if self.peers.contains_key(addr) {
|
||||
entry.tries = 0;
|
||||
entry.timeout = 1;
|
||||
entry.next = now + 1;
|
||||
|
@ -417,7 +424,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
let now = TS::now();
|
||||
let mut buffer = MsgBuffer::new(SPACE_BEFORE);
|
||||
let mut del: SmallVec<[SocketAddr; 3]> = SmallVec::new();
|
||||
for (&addr, ref data) in &self.peers {
|
||||
for (&addr, data) in &self.peers {
|
||||
if data.timeout < now {
|
||||
del.push(addr);
|
||||
}
|
||||
|
@ -435,11 +442,6 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
pfw.check_extend();
|
||||
}
|
||||
let now = TS::now();
|
||||
// Periodically reset own peers
|
||||
if self.next_own_address_reset <= now {
|
||||
self.reset_own_addresses().map_err(|err| Error::SocketIo("Failed to get own addresses", err))?;
|
||||
self.next_own_address_reset = now + OWN_ADDRESS_RESET_INTERVAL;
|
||||
}
|
||||
// Periodically send peer list to peers
|
||||
if self.next_peers <= now {
|
||||
debug!("Send peer list to all peers");
|
||||
|
@ -448,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)?;
|
||||
// Reschedule for next update
|
||||
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 as u16, max(min_peer_timeout / 2 - 60, 1));
|
||||
let interval = min(self.update_freq, max(min_peer_timeout / 2 - 60, 1));
|
||||
self.next_peers = now + Time::from(interval);
|
||||
}
|
||||
self.reconnect_to_peers()?;
|
||||
|
@ -470,6 +472,11 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
self.load_beacon()?;
|
||||
self.next_beacon = now + Time::from(self.config.beacon_interval);
|
||||
}
|
||||
// Periodically reset own peers
|
||||
if self.next_own_address_reset <= now {
|
||||
self.reset_own_addresses().map_err(|err| Error::SocketIo("Failed to get own addresses", err))?;
|
||||
self.next_own_address_reset = now + OWN_ADDRESS_RESET_INTERVAL;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -484,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))?;
|
||||
} else {
|
||||
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))?;
|
||||
}
|
||||
}
|
||||
|
@ -503,7 +510,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
} else {
|
||||
peers = self
|
||||
.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))?;
|
||||
}
|
||||
} else {
|
||||
|
@ -691,6 +698,12 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
}
|
||||
if let Some(node_id) = peer.node_id {
|
||||
if self.node_id == node_id {
|
||||
// Check addresses and add addresses that we don't know to own addresses
|
||||
for addr in &peer.addrs {
|
||||
if !self.own_addresses.contains(addr) {
|
||||
self.own_addresses.push(*addr)
|
||||
}
|
||||
}
|
||||
continue 'outer;
|
||||
}
|
||||
for p in self.peers.values() {
|
||||
|
@ -707,7 +720,17 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
|||
fn update_peer_info(&mut self, addr: SocketAddr, info: Option<NodeInfo>) -> Result<(), Error> {
|
||||
if let Some(peer) = self.peers.get_mut(&addr) {
|
||||
peer.last_seen = TS::now();
|
||||
peer.timeout = TS::now() + self.config.peer_timeout as Time
|
||||
peer.timeout = TS::now() + self.config.peer_timeout as Time;
|
||||
if let Some(info) = &info {
|
||||
// Update peer addresses, always add seen address
|
||||
peer.addrs.clear();
|
||||
peer.addrs.push(addr);
|
||||
for addr in &info.addrs {
|
||||
if !peer.addrs.contains(addr) {
|
||||
peer.addrs.push(*addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("Received peer update from non peer {}", addr_nice(addr));
|
||||
return Ok(());
|
||||
|
|
|
@ -19,6 +19,7 @@ pub struct Config {
|
|||
pub fix_rp_filter: bool,
|
||||
|
||||
pub ip: Option<String>,
|
||||
pub advertise_addresses: Vec<String>,
|
||||
pub ifup: Option<String>,
|
||||
pub ifdown: Option<String>,
|
||||
|
||||
|
@ -56,6 +57,7 @@ impl Default for Config {
|
|||
device_path: None,
|
||||
fix_rp_filter: false,
|
||||
ip: None,
|
||||
advertise_addresses: vec![],
|
||||
ifup: None,
|
||||
ifdown: None,
|
||||
crypto: CryptoConfig::default(),
|
||||
|
@ -105,6 +107,9 @@ impl Config {
|
|||
if let Some(val) = file.ip {
|
||||
self.ip = Some(val);
|
||||
}
|
||||
if let Some(mut val) = file.advertise_addresses {
|
||||
self.advertise_addresses.append(&mut val);
|
||||
}
|
||||
if let Some(val) = file.ifup {
|
||||
self.ifup = Some(val);
|
||||
}
|
||||
|
@ -212,6 +217,7 @@ impl Config {
|
|||
if let Some(val) = args.ifup {
|
||||
self.ifup = Some(val);
|
||||
}
|
||||
self.advertise_addresses.append(&mut args.advertise_addresses);
|
||||
if let Some(val) = args.ifdown {
|
||||
self.ifdown = Some(val);
|
||||
}
|
||||
|
@ -318,6 +324,7 @@ impl Config {
|
|||
ifup: self.ifup,
|
||||
ifdown: self.ifdown,
|
||||
ip: self.ip,
|
||||
advertise_addresses: Some(self.advertise_addresses),
|
||||
keepalive: self.keepalive,
|
||||
listen: Some(self.listen),
|
||||
mode: Some(self.mode),
|
||||
|
@ -347,7 +354,7 @@ impl Config {
|
|||
if let Some(ref s) = self.hook {
|
||||
script = Some(s);
|
||||
}
|
||||
if let Some(ref s) = self.hooks.get(event) {
|
||||
if let Some(s) = self.hooks.get(event) {
|
||||
script = Some(s);
|
||||
}
|
||||
if script.is_none() {
|
||||
|
@ -467,6 +474,10 @@ pub struct Args {
|
|||
#[structopt(long)]
|
||||
pub ip: Option<String>,
|
||||
|
||||
/// A list of IP Addresses to advertise as our external address(s)
|
||||
#[structopt(long = "advertise_addresses", use_delimiter = true)]
|
||||
pub advertise_addresses: Vec<String>,
|
||||
|
||||
/// A command to setup the network interface
|
||||
#[structopt(long)]
|
||||
pub ifup: Option<String>,
|
||||
|
@ -606,6 +617,7 @@ pub struct ConfigFile {
|
|||
pub device: Option<ConfigFileDevice>,
|
||||
|
||||
pub ip: Option<String>,
|
||||
pub advertise_addresses: Option<Vec<String>>,
|
||||
pub ifup: Option<String>,
|
||||
pub ifdown: Option<String>,
|
||||
|
||||
|
@ -638,6 +650,9 @@ device:
|
|||
name: vpncloud%d
|
||||
path: /dev/net/tun
|
||||
ip: 10.0.1.1/16
|
||||
advertise-addresses:
|
||||
- 192.168.0.1
|
||||
- 192.168.1.1
|
||||
ifup: ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up
|
||||
ifdown: 'true'
|
||||
peers:
|
||||
|
@ -673,6 +688,7 @@ statsd:
|
|||
fix_rp_filter: None
|
||||
}),
|
||||
ip: Some("10.0.1.1/16".to_string()),
|
||||
advertise_addresses: Some(vec!["192.168.0.1".to_string(), "192.168.1.1".to_string()]),
|
||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||
ifdown: Some("true".to_string()),
|
||||
crypto: CryptoConfig::default(),
|
||||
|
@ -721,6 +737,7 @@ fn config_merge() {
|
|||
fix_rp_filter: None,
|
||||
}),
|
||||
ip: None,
|
||||
advertise_addresses: Some(vec![]),
|
||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||
ifdown: Some("true".to_string()),
|
||||
crypto: CryptoConfig::default(),
|
||||
|
@ -757,6 +774,7 @@ fn config_merge() {
|
|||
device_name: "vpncloud%d".to_string(),
|
||||
device_path: None,
|
||||
ip: None,
|
||||
advertise_addresses: vec![],
|
||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||
ifdown: Some("true".to_string()),
|
||||
listen: "3210".to_string(),
|
||||
|
@ -816,6 +834,8 @@ fn config_merge() {
|
|||
device_path: Some("/dev/null".to_string()),
|
||||
fix_rp_filter: false,
|
||||
ip: None,
|
||||
advertise_addresses: vec![],
|
||||
|
||||
ifup: Some("ifconfig $IFNAME 10.0.1.2/16 mtu 1400 up".to_string()),
|
||||
ifdown: Some("ifconfig $IFNAME down".to_string()),
|
||||
crypto: CryptoConfig { password: Some("anothersecret".to_string()), ..CryptoConfig::default() },
|
||||
|
|
|
@ -110,7 +110,7 @@ struct CryptoKey {
|
|||
|
||||
impl CryptoKey {
|
||||
fn new(rand: &SystemRandom, key: LessSafeKey, nonce_half: bool) -> Self {
|
||||
let mut send_nonce = Nonce::random(&rand);
|
||||
let mut send_nonce = Nonce::random(rand);
|
||||
send_nonce.set_msb(if nonce_half { 0x80 } else { 0x00 });
|
||||
CryptoKey {
|
||||
key,
|
||||
|
|
|
@ -235,7 +235,7 @@ impl InitMsg {
|
|||
|
||||
let signed_data = &r.into_inner()[0..pos];
|
||||
let public_key = signature::UnparsedPublicKey::new(&ED25519, &public_key_data);
|
||||
if public_key.verify(&signed_data, &signature).is_err() {
|
||||
if public_key.verify(signed_data, &signature).is_err() {
|
||||
return Err(Error::Crypto("invalid signature"));
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,7 @@ impl InitMsg {
|
|||
w.write_u8(Self::PART_ECDH_PUBLIC_KEY)?;
|
||||
let key_bytes = ecdh_public_key.bytes();
|
||||
w.write_u16::<NetworkEndian>(key_bytes.len() as u16)?;
|
||||
w.write_all(&key_bytes)?;
|
||||
w.write_all(key_bytes)?;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -459,8 +459,8 @@ impl<P: Payload> InitState<P> {
|
|||
}
|
||||
|
||||
fn derive_master_key(&self, algo: &'static Algorithm, privk: EcdhPrivateKey, pubk: &EcdhPublicKey) -> LessSafeKey {
|
||||
agree_ephemeral(privk, pubk, (), |k| {
|
||||
UnboundKey::new(algo, &k[..algo.key_len()]).map(LessSafeKey::new).map_err(|_| ())
|
||||
agree_ephemeral(privk, pubk, |k| {
|
||||
UnboundKey::new(algo, &k[..algo.key_len()]).map(LessSafeKey::new).unwrap()
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -522,8 +522,8 @@ impl<P: Payload> InitState<P> {
|
|||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let mut bytes = out.buffer();
|
||||
let len = msg.write_to(&mut bytes, &self.key_pair).expect("Buffer too small");
|
||||
let bytes = out.buffer();
|
||||
let len = msg.write_to(bytes, &self.key_pair).expect("Buffer too small");
|
||||
self.last_message = Some(bytes[0..len].to_vec());
|
||||
out.set_length(len);
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ mod tests {
|
|||
|
||||
impl Payload for Vec<u8> {
|
||||
fn write_to(&self, buffer: &mut MsgBuffer) {
|
||||
buffer.buffer().write_all(&self).expect("Buffer too small");
|
||||
buffer.buffer().write_all(self).expect("Buffer too small");
|
||||
buffer.set_length(self.len())
|
||||
}
|
||||
|
||||
|
|
|
@ -137,10 +137,10 @@ impl RotationState {
|
|||
}
|
||||
|
||||
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();
|
||||
vec.extend_from_slice(k);
|
||||
Ok(vec)
|
||||
vec
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ impl RotationState {
|
|||
if let Some(ref private_key) = self.proposed {
|
||||
// Still a proposed key that has not been confirmed, proposal must have been lost
|
||||
if self.timeout {
|
||||
let proposed_key = Self::compute_public_key(&private_key);
|
||||
let proposed_key = Self::compute_public_key(private_key);
|
||||
if let Some((ref confirmed_key, message_id)) = self.confirmed {
|
||||
// Reconfirm last confirmed key
|
||||
Self::send(
|
||||
|
@ -271,7 +271,7 @@ mod tests {
|
|||
assert!(key2.is_some());
|
||||
let key2 = key2.unwrap();
|
||||
assert_eq!(key2.id, 2);
|
||||
assert_eq!(key2.use_for_sending, false);
|
||||
assert!(!key2.use_for_sending);
|
||||
assert!(!out2.is_empty());
|
||||
let msg2 = out2.msg().unwrap();
|
||||
assert_eq!(msg2.message_id, 2);
|
||||
|
@ -281,14 +281,14 @@ mod tests {
|
|||
assert!(key.is_some());
|
||||
let key = key.unwrap();
|
||||
assert_eq!(key.id, 2);
|
||||
assert_eq!(key.use_for_sending, true);
|
||||
assert!(key.use_for_sending);
|
||||
// Cycle 2
|
||||
let key1 = node1.cycle(&mut out1);
|
||||
let key2 = node2.cycle(&mut out2);
|
||||
assert!(key1.is_some());
|
||||
let key1 = key1.unwrap();
|
||||
assert_eq!(key1.id, 3);
|
||||
assert_eq!(key1.use_for_sending, false);
|
||||
assert!(!key1.use_for_sending);
|
||||
assert!(!out1.is_empty());
|
||||
let msg1 = out1.msg().unwrap();
|
||||
assert_eq!(msg1.message_id, 3);
|
||||
|
@ -300,7 +300,7 @@ mod tests {
|
|||
assert!(key.is_some());
|
||||
let key = key.unwrap();
|
||||
assert_eq!(key.id, 3);
|
||||
assert_eq!(key.use_for_sending, true);
|
||||
assert!(key.use_for_sending);
|
||||
// Cycle 3
|
||||
let key1 = node1.cycle(&mut out1);
|
||||
let key2 = node2.cycle(&mut out2);
|
||||
|
@ -309,7 +309,7 @@ mod tests {
|
|||
assert!(key2.is_some());
|
||||
let key2 = key2.unwrap();
|
||||
assert_eq!(key2.id, 4);
|
||||
assert_eq!(key2.use_for_sending, false);
|
||||
assert!(!key2.use_for_sending);
|
||||
assert!(!out2.is_empty());
|
||||
let msg2 = out2.msg().unwrap();
|
||||
assert_eq!(msg2.message_id, 4);
|
||||
|
@ -319,7 +319,7 @@ mod tests {
|
|||
assert!(key.is_some());
|
||||
let key = key.unwrap();
|
||||
assert_eq!(key.id, 4);
|
||||
assert_eq!(key.use_for_sending, true);
|
||||
assert!(key.use_for_sending);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -10,20 +10,27 @@ use std::{
|
|||
fs::{self, File},
|
||||
io::{self, BufRead, BufReader, Cursor, Error as IoError, Read, Write},
|
||||
net::{Ipv4Addr, UdpSocket},
|
||||
os::unix::io::{AsRawFd, RawFd},
|
||||
os::{unix::io::AsRawFd, fd::RawFd},
|
||||
str,
|
||||
str::FromStr,
|
||||
str::FromStr
|
||||
};
|
||||
|
||||
use crate::{crypto, error::Error, util::MsgBuffer};
|
||||
|
||||
static TUNSETIFF: libc::c_ulong = 1074025674;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct IfReqDataAddr {
|
||||
af: libc::c_int,
|
||||
addr: Ipv4Addr
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
union IfReqData {
|
||||
flags: libc::c_short,
|
||||
value: libc::c_int,
|
||||
addr: (libc::c_short, Ipv4Addr),
|
||||
addr: IfReqDataAddr,
|
||||
_dummy: [u8; 24],
|
||||
}
|
||||
|
||||
|
@ -392,11 +399,11 @@ fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
|||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFADDR.try_into().unwrap(), &mut ifreq) };
|
||||
match res {
|
||||
0 => {
|
||||
let af = unsafe { ifreq.data.addr.0 };
|
||||
let af = unsafe { ifreq.data.addr.af };
|
||||
if af as libc::c_int != libc::AF_INET {
|
||||
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
||||
}
|
||||
let ip = unsafe { ifreq.data.addr.1 };
|
||||
let ip = unsafe { ifreq.data.addr.addr };
|
||||
Ok(ip)
|
||||
}
|
||||
_ => Err(IoError::last_os_error()),
|
||||
|
@ -407,7 +414,8 @@ fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
|||
fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||
let mut ifreq = IfReq::new(ifname);
|
||||
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||
ifreq.data.addr.af = libc::AF_INET as libc::c_int;
|
||||
ifreq.data.addr.addr = addr;
|
||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR.try_into().unwrap(), &mut ifreq) };
|
||||
match res {
|
||||
0 => Ok(()),
|
||||
|
@ -423,11 +431,11 @@ fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
|||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
||||
match res {
|
||||
0 => {
|
||||
let af = unsafe { ifreq.data.addr.0 };
|
||||
let af = unsafe { ifreq.data.addr.af };
|
||||
if af as libc::c_int != libc::AF_INET {
|
||||
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
||||
}
|
||||
let ip = unsafe { ifreq.data.addr.1 };
|
||||
let ip = unsafe { ifreq.data.addr.addr };
|
||||
Ok(ip)
|
||||
}
|
||||
_ => Err(IoError::last_os_error()),
|
||||
|
@ -438,7 +446,8 @@ fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
|||
fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||
let mut ifreq = IfReq::new(ifname);
|
||||
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||
ifreq.data.addr.af = libc::AF_INET as libc::c_int;
|
||||
ifreq.data.addr.addr = addr;
|
||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
||||
match res {
|
||||
0 => Ok(()),
|
||||
|
|
|
@ -48,7 +48,6 @@ use std::{
|
|||
process,
|
||||
str::FromStr,
|
||||
sync::Mutex,
|
||||
thread,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -96,7 +95,7 @@ impl log::Log for DualLogger {
|
|||
println!("{} - {}", record.level(), record.args());
|
||||
if let Some(ref file) = self.file {
|
||||
let mut file = file.lock().expect("Lock poisoned");
|
||||
let time = time::OffsetDateTime::now_local().format("%F %H:%M:%S");
|
||||
let time = chrono::Local::now().format("%F %H:%M:%S");
|
||||
writeln!(file, "{} - {} - {}", time, record.level(), record.args())
|
||||
.expect("Failed to write to logfile");
|
||||
}
|
||||
|
@ -114,7 +113,7 @@ impl log::Log for DualLogger {
|
|||
|
||||
fn run_script(script: &str, ifname: &str) {
|
||||
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);
|
||||
match cmd.status() {
|
||||
Ok(status) => {
|
||||
|
@ -212,8 +211,6 @@ fn run<P: Protocol, S: Socket>(config: Config, socket: S) {
|
|||
}
|
||||
if let Some(pid_file) = config.pid_file {
|
||||
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: {}");
|
||||
} else if config.user.is_some() || config.group.is_some() {
|
||||
|
|
16
src/net.rs
16
src/net.rs
|
@ -11,7 +11,7 @@ use std::{
|
|||
};
|
||||
|
||||
use super::util::{MockTimeSource, MsgBuffer, Time, TimeSource};
|
||||
use crate::port_forwarding::PortForwarding;
|
||||
use crate::{config::DEFAULT_PORT, port_forwarding::PortForwarding};
|
||||
|
||||
pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
|
||||
// HOT PATH
|
||||
|
@ -22,7 +22,7 @@ pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
|
|||
}
|
||||
|
||||
pub fn get_ip() -> IpAddr {
|
||||
let s = UdpSocket::bind("[::]:0").unwrap();
|
||||
let s = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||
s.connect("8.8.8.8:0").unwrap();
|
||||
s.local_addr().unwrap().ip()
|
||||
}
|
||||
|
@ -35,21 +35,23 @@ pub trait Socket: AsRawFd + Sized {
|
|||
fn create_port_forwarding(&self) -> Option<PortForwarding>;
|
||||
}
|
||||
|
||||
pub fn parse_listen(addr: &str) -> SocketAddr {
|
||||
pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr {
|
||||
if let Some(addr) = addr.strip_prefix("*:") {
|
||||
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
||||
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
||||
} else if addr.contains(':') {
|
||||
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
|
||||
} else {
|
||||
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
||||
} else if let Ok(port) = addr.parse::<u16>() {
|
||||
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
||||
} else {
|
||||
let ip = try_fail!(addr.parse::<IpAddr>(), "Invalid addr: {}");
|
||||
SocketAddr::new(ip, default_port)
|
||||
}
|
||||
}
|
||||
|
||||
impl Socket for UdpSocket {
|
||||
fn listen(addr: &str) -> Result<Self, io::Error> {
|
||||
let addr = parse_listen(addr);
|
||||
let addr = mapped_addr(parse_listen(addr, DEFAULT_PORT));
|
||||
UdpSocket::bind(addr)
|
||||
}
|
||||
|
||||
|
@ -134,7 +136,7 @@ impl AsRawFd for MockSocket {
|
|||
|
||||
impl Socket for MockSocket {
|
||||
fn listen(addr: &str) -> Result<Self, io::Error> {
|
||||
Ok(Self::new(parse_listen(addr)))
|
||||
Ok(Self::new(mapped_addr(parse_listen(addr, DEFAULT_PORT))))
|
||||
}
|
||||
|
||||
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
|
||||
|
|
|
@ -109,6 +109,7 @@ impl OldConfigFile {
|
|||
ifdown: self.ifdown,
|
||||
ifup: self.ifup,
|
||||
ip: None,
|
||||
advertise_addresses: None,
|
||||
keepalive: self.keepalive,
|
||||
listen: self.listen.or(self.port.map(|p| format!("{}", p))),
|
||||
mode: self.mode,
|
||||
|
|
12
src/table.rs
12
src/table.rs
|
@ -48,6 +48,7 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
|||
}
|
||||
|
||||
pub fn set_claims(&mut self, peer: SocketAddr, mut claims: RangeList) {
|
||||
let mut removed_claim = false;
|
||||
for entry in &mut self.claims {
|
||||
if entry.peer == peer {
|
||||
let pos = claims.iter().position(|r| r == &entry.claim);
|
||||
|
@ -58,16 +59,19 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
entry.timeout = 0
|
||||
entry.timeout = 0;
|
||||
removed_claim = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for claim in claims {
|
||||
self.claims.push(ClaimEntry { peer, claim, timeout: TS::now() + self.claim_timeout as Time })
|
||||
}
|
||||
for entry in self.cache.values_mut() {
|
||||
if entry.peer == peer {
|
||||
entry.timeout = 0
|
||||
if removed_claim {
|
||||
for entry in self.cache.values_mut() {
|
||||
if entry.peer == peer {
|
||||
entry.timeout = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
self.housekeep()
|
||||
|
|
|
@ -18,7 +18,6 @@ pub use crate::{
|
|||
device::{MockDevice, Type},
|
||||
net::MockSocket,
|
||||
payload::{Frame, Packet, Protocol},
|
||||
types::Range,
|
||||
util::{MockTimeSource, Time, TimeSource},
|
||||
};
|
||||
|
||||
|
|
|
@ -5,9 +5,4 @@
|
|||
mod common;
|
||||
mod nat;
|
||||
mod payload;
|
||||
mod peers;
|
||||
|
||||
#[test]
|
||||
fn test_time_format() {
|
||||
assert!(time::OffsetDateTime::try_now_local().is_ok());
|
||||
}
|
||||
mod peers;
|
|
@ -82,25 +82,25 @@ impl TrafficStats {
|
|||
#[inline]
|
||||
pub fn count_out_traffic(&mut self, peer: SocketAddr, bytes: usize) {
|
||||
// HOT PATH
|
||||
self.peers.entry(peer).or_insert_with(TrafficEntry::default).count_out(bytes);
|
||||
self.peers.entry(peer).or_default().count_out(bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn count_in_traffic(&mut self, peer: SocketAddr, bytes: usize) {
|
||||
// HOT PATH
|
||||
self.peers.entry(peer).or_insert_with(TrafficEntry::default).count_in(bytes);
|
||||
self.peers.entry(peer).or_default().count_in(bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn count_out_payload(&mut self, remote: Address, local: Address, bytes: usize) {
|
||||
// HOT PATH
|
||||
self.payload.entry((remote, local)).or_insert_with(TrafficEntry::default).count_out(bytes);
|
||||
self.payload.entry((remote, local)).or_default().count_out(bytes);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn count_in_payload(&mut self, remote: Address, local: Address, bytes: usize) {
|
||||
// HOT PATH
|
||||
self.payload.entry((remote, local)).or_insert_with(TrafficEntry::default).count_in(bytes);
|
||||
self.payload.entry((remote, local)).or_default().count_in(bytes);
|
||||
}
|
||||
|
||||
pub fn count_invalid_protocol(&mut self, bytes: usize) {
|
||||
|
|
|
@ -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);
|
||||
for c in data.chars() {
|
||||
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)) + 36,
|
||||
_ => 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<(), io::Error> {
|
||||
fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode >= MODE_ADVANCED {
|
||||
config.listen =
|
||||
Input::with_theme(theme).with_prompt("Listen address").default(config.listen.clone()).interact_text()?;
|
||||
|
@ -41,6 +41,12 @@ fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulThem
|
|||
.interact()?;
|
||||
}
|
||||
if mode == MODE_EXPERT {
|
||||
config.advertise_addresses = str_list(
|
||||
Input::with_theme(theme)
|
||||
.with_prompt("Advertise addresses (comma separated)")
|
||||
.default(config.advertise_addresses.join(","))
|
||||
.interact_text()?,
|
||||
);
|
||||
config.peer_timeout = Input::with_theme(theme)
|
||||
.with_prompt("Peer timeout (in seconds)")
|
||||
.default(config.peer_timeout)
|
||||
|
@ -54,7 +60,7 @@ fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulThem
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
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()?
|
||||
{
|
||||
|
@ -145,7 +151,7 @@ fn configure_crypto(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode >= MODE_ADVANCED {
|
||||
config.device_type = match Select::with_theme(theme)
|
||||
.with_prompt("Device type")
|
||||
|
@ -198,7 +204,7 @@ fn configure_device(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
config.ip = str_opt(
|
||||
Input::with_theme(theme)
|
||||
.with_prompt("Virtual IP address (e.g. 10.0.0.1, leave empty for none)")
|
||||
|
@ -244,7 +250,7 @@ fn configure_addresses(config: &mut Config, mode: usize, theme: &ColorfulTheme)
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode == MODE_EXPERT
|
||||
&& Confirm::with_theme(theme)
|
||||
.with_prompt("Configure beacons?")
|
||||
|
@ -326,7 +332,7 @@ fn configure_beacon(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode >= MODE_ADVANCED {
|
||||
config.stats_file = str_opt(
|
||||
Input::with_theme(theme)
|
||||
|
@ -363,7 +369,7 @@ fn configure_stats(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> R
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode == MODE_EXPERT {
|
||||
config.user = str_opt(
|
||||
Input::with_theme(theme)
|
||||
|
@ -390,7 +396,7 @@ fn configure_process(config: &mut Config, mode: usize, theme: &ColorfulTheme) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), io::Error> {
|
||||
fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> Result<(), dialoguer::Error> {
|
||||
if mode == MODE_EXPERT {
|
||||
if Confirm::with_theme(theme)
|
||||
.with_prompt("Set hooks to react on events?")
|
||||
|
@ -433,7 +439,7 @@ fn configure_hooks(config: &mut Config, mode: usize, theme: &ColorfulTheme) -> R
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn configure(name: Option<String>) -> Result<(), io::Error> {
|
||||
pub fn configure(name: Option<String>) -> Result<(), dialoguer::Error> {
|
||||
let theme = ColorfulTheme::default();
|
||||
|
||||
let name = if let Some(name) = name {
|
||||
|
@ -461,7 +467,7 @@ pub fn configure(name: Option<String>) -> Result<(), io::Error> {
|
|||
config.merge_file(config_file);
|
||||
}
|
||||
if file.parent().unwrap().metadata()?.permissions().readonly() {
|
||||
return Err(io::Error::new(io::ErrorKind::PermissionDenied, "Config file not writable"));
|
||||
return Err(io::Error::new(io::ErrorKind::PermissionDenied, "Config file not writable").into());
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -495,8 +501,8 @@ pub fn configure(name: Option<String>) -> Result<(), io::Error> {
|
|||
println!(" start the VPN: sudo service vpncloud@{0} start", name);
|
||||
println!(" stop the VPN: sudo service vpncloud@{0} stop", name);
|
||||
println!(" get the status: sudo service vpncloud@{0} status", name);
|
||||
println!(" add VPN to autostart: sudo sysctl enable vpncloud@{0}", name);
|
||||
println!(" remove VPN from autostart: sudo sysctl disable vpncloud@{0}", name);
|
||||
println!(" add VPN to autostart: sudo systemctl enable vpncloud@{0}", name);
|
||||
println!(" remove VPN from autostart: sudo systemctl disable vpncloud@{0}", name);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
|||
os::unix::io::{AsRawFd, RawFd},
|
||||
thread::spawn,
|
||||
};
|
||||
use tungstenite::{client::AutoStream, connect, protocol::WebSocket, server::accept, Message};
|
||||
use tungstenite::{connect, protocol::WebSocket, Message, accept, stream::{MaybeTlsStream, NoDelay}};
|
||||
use url::Url;
|
||||
|
||||
macro_rules! io_error {
|
||||
|
@ -58,14 +58,14 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
|
|||
info!("Listening on {} for peer {}", addr, peer);
|
||||
addr.set_ip(get_ip());
|
||||
write_addr(addr, &mut msg)?;
|
||||
io_error!(websocket.write_message(Message::Binary(msg)), "Failed to write to ws connection: {}")?;
|
||||
io_error!(websocket.send(Message::Binary(msg)), "Failed to write to ws connection: {}")?;
|
||||
let websocketfd = websocket.get_ref().as_raw_fd();
|
||||
let poll = WaitImpl::new(websocketfd, udpsocket.as_raw_fd(), 60 * 1000)?;
|
||||
let mut buffer = [0; 65535];
|
||||
for evt in poll {
|
||||
match evt {
|
||||
WaitResult::Socket => {
|
||||
let msg = io_error!(websocket.read_message(), "Failed to read message on websocket {}: {}", peer)?;
|
||||
let msg = io_error!(websocket.read(), "Failed to read message on websocket {}: {}", peer)?;
|
||||
match msg {
|
||||
Message::Binary(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);
|
||||
write_addr(addr, &mut data)?;
|
||||
data.write_all(&buffer[..size])?;
|
||||
io_error!(websocket.write_message(Message::Binary(data)), "Failed to write to {}: {}", peer)?;
|
||||
io_error!(websocket.send(Message::Binary(data)), "Failed to write to {}: {}", peer)?;
|
||||
}
|
||||
WaitResult::Timeout => {
|
||||
io_error!(websocket.write_message(Message::Ping(vec![])), "Failed to send ping: {}")?;
|
||||
io_error!(websocket.send(Message::Ping(vec![])), "Failed to send ping: {}")?;
|
||||
}
|
||||
WaitResult::Error(err) => return Err(err),
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
|
|||
}
|
||||
|
||||
pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
|
||||
let addr = parse_listen(listen);
|
||||
let addr = parse_listen(listen, 8080);
|
||||
let server = TcpListener::bind(addr)?;
|
||||
info!("Listening on ws://{}", server.local_addr()?);
|
||||
for stream in server.incoming() {
|
||||
|
@ -109,13 +109,13 @@ pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
|
|||
|
||||
pub struct ProxyConnection {
|
||||
addr: SocketAddr,
|
||||
socket: WebSocket<AutoStream>,
|
||||
socket: WebSocket<MaybeTlsStream<TcpStream>>,
|
||||
}
|
||||
|
||||
impl ProxyConnection {
|
||||
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
|
||||
loop {
|
||||
if let Message::Binary(data) = io_error!(self.socket.read_message(), "Failed to read from ws proxy: {}")? {
|
||||
if let Message::Binary(data) = io_error!(self.socket.read(), "Failed to read from ws proxy: {}")? {
|
||||
return Ok(data);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,10 @@ impl ProxyConnection {
|
|||
|
||||
impl AsRawFd for ProxyConnection {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.socket.get_ref().as_raw_fd()
|
||||
match self.socket.get_ref() {
|
||||
MaybeTlsStream::Plain(stream) => stream.as_raw_fd(),
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +155,7 @@ impl Socket for ProxyConnection {
|
|||
let mut msg = Vec::with_capacity(data.len() + 18);
|
||||
write_addr(addr, &mut msg)?;
|
||||
msg.write_all(data)?;
|
||||
io_error!(self.socket.write_message(Message::Binary(msg)), "Failed to write to ws proxy: {}")?;
|
||||
io_error!(self.socket.send(Message::Binary(msg)), "Failed to write to ws proxy: {}")?;
|
||||
Ok(data.len())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue