mirror of https://github.com/dswd/vpncloud.git
Compare commits
No commits in common. "a9b960b04ea71dccadb5d52f912f64e208977408" and "7d86892f6ffc30e2d9594d85a49d5f2e519ea371" have entirely different histories.
a9b960b04e
...
7d86892f6f
|
@ -11,7 +11,7 @@ RUN chown vscode: -R /usr/local/rustup /usr/local/cargo
|
||||||
|
|
||||||
USER vscode
|
USER vscode
|
||||||
|
|
||||||
RUN rustup default 1.64.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 \
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
"serayuzgur.crates",
|
"serayuzgur.crates",
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"swellaby.vscode-rust-test-adapter",
|
"swellaby.vscode-rust-test-adapter",
|
||||||
|
"matklad.rust-analyzer",
|
||||||
"asciidoctor.asciidoctor-vscode",
|
"asciidoctor.asciidoctor-vscode",
|
||||||
"ms-vscode.test-adapter-converter",
|
"ms-vscode.test-adapter-converter"
|
||||||
"rust-lang.rust-analyzer"
|
|
||||||
],
|
],
|
||||||
// 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": [],
|
||||||
|
|
|
@ -6,8 +6,6 @@ RUN yum install -y libstdc++-*.i686 \
|
||||||
&& yum install -y glibc-*.i686 \
|
&& yum install -y glibc-*.i686 \
|
||||||
&& yum install -y libgcc.i686
|
&& yum install -y libgcc.i686
|
||||||
|
|
||||||
RUN ln -s /usr/bin/gcc /usr/bin/i686-linux-gnu-gcc
|
|
||||||
|
|
||||||
ADD entrypoint.sh /entrypoint.sh
|
ADD entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
ENTRYPOINT /entrypoint.sh
|
ENTRYPOINT /entrypoint.sh
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ jobs:
|
||||||
audit:
|
audit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v1
|
||||||
- uses: actions-rs/audit-check@v1
|
- uses: actions-rs/audit-check@v1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
|
@ -4,18 +4,12 @@ This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
### UNRELEASED
|
### UNRELEASED
|
||||||
|
|
||||||
- [changed] Changed Rust version to 1.64.0
|
|
||||||
- [changed] Updated dependencies
|
|
||||||
|
|
||||||
### v2.3.0 (2021-12-23)
|
|
||||||
|
|
||||||
- [added] Added build for armv5te (thanks to xek)
|
- [added] Added build for armv5te (thanks to xek)
|
||||||
- [added] Option to specify advertised addresses
|
- [added] Option to specify advertised addresses
|
||||||
- [added] Peers now learn their own address from peers
|
- [added] Peers now learn their own address from peers
|
||||||
- [changed] Changed Rust version to 1.57.0
|
- [changed] Changed Rust version to 1.57.0
|
||||||
- [changed] Updated dependencies
|
- [changed] Updated dependencies
|
||||||
- [fixed] Fixed problem with IPv4 addresses in listen option
|
- [fixed] Fixed problem with IPv4 addresses in listen option
|
||||||
- [fixed] Fixed periodic broadcast messages in switch mode
|
|
||||||
|
|
||||||
### v2.2.0 (2021-04-06)
|
### v2.2.0 (2021-04-06)
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "vpncloud"
|
name = "vpncloud"
|
||||||
version = "2.4.0"
|
version = "2.2.0"
|
||||||
authors = ["Dennis Schwerdel <schwerdel@googlemail.com>"]
|
authors = ["Dennis Schwerdel <schwerdel@googlemail.com>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
@ -12,14 +12,14 @@ readme = "README.md"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
toolchain = "1.64.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"] }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
@ -30,10 +30,10 @@ ring = "0.16"
|
||||||
privdrop = "0.5"
|
privdrop = "0.5"
|
||||||
byteorder = "1.4"
|
byteorder = "1.4"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
parking_lot = "0.12"
|
parking_lot = "^0.11.2"
|
||||||
smallvec = "1.7"
|
smallvec = "1.7"
|
||||||
dialoguer = { version = "0.10", optional = true }
|
dialoguer = { version = "0.9", optional = true }
|
||||||
tungstenite = { version = "0.17", optional = true, default-features = false }
|
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 }
|
||||||
timeout_io = "0.6"
|
timeout_io = "0.6"
|
||||||
|
@ -41,7 +41,7 @@ signal = "0.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
criterion = { version = "0.4", features = ["html_reports"] }
|
criterion = { version = "0.3", features = ["html_reports"] }
|
||||||
iai = "0.1"
|
iai = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
20
ROADMAP.md
20
ROADMAP.md
|
@ -7,25 +7,7 @@
|
||||||
- [x] Check how async affects performance
|
- [x] Check how async affects performance
|
||||||
- [x] Sync traffic stats
|
- [x] Sync traffic stats
|
||||||
- [x] Sync forwarding table
|
- [x] Sync forwarding table
|
||||||
- [x] Fix WS Proxy code
|
- [ ] Fix WS Proxy code
|
||||||
- [x] Fix Ctrl-C
|
|
||||||
- [x] Fix auto-claim IP
|
|
||||||
|
|
||||||
## More threads
|
|
||||||
|
|
||||||
- [ ] abstract socket + peers + traffic + table into one class + shared part
|
|
||||||
- [ ] management thread
|
|
||||||
- [ ] Send peer list
|
|
||||||
- [ ] Statsd
|
|
||||||
- [ ] Write out stats
|
|
||||||
- [ ] Port forwarding
|
|
||||||
|
|
||||||
## VIA Feature
|
|
||||||
|
|
||||||
- [ ] Implement message type VIA for relaying messages
|
|
||||||
- [ ] Advertize VIA addresses (optional) as claims from own peers
|
|
||||||
- [ ] Use VIA if no peer found
|
|
||||||
- [ ] Make sure VIA does not recurse
|
|
||||||
- [ ] Allow enabling VIA in config
|
|
||||||
|
|
||||||
## REST API
|
## REST API
|
|
@ -1,15 +1,3 @@
|
||||||
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
|
vpncloud (2.2.0) stable; urgency=medium
|
||||||
|
|
||||||
* [added] Service target file (thanks to mnhauke)
|
* [added] Service target file (thanks to mnhauke)
|
||||||
|
|
|
@ -82,11 +82,11 @@ fn decode_ethernet_with_vlan(c: &mut Criterion) {
|
||||||
fn lookup_warm(c: &mut Criterion) {
|
fn lookup_warm(c: &mut Criterion) {
|
||||||
let mut table = ClaimTable::<MockTimeSource>::new(60, 60);
|
let mut table = ClaimTable::<MockTimeSource>::new(60, 60);
|
||||||
let addr = Address::from_str("1.2.3.4").unwrap();
|
let addr = Address::from_str("1.2.3.4").unwrap();
|
||||||
table.cache(addr.clone(), SocketAddr::from_str("1.2.3.4:3210").unwrap());
|
table.cache(addr, SocketAddr::from_str("1.2.3.4:3210").unwrap());
|
||||||
let mut g = c.benchmark_group("table");
|
let mut g = c.benchmark_group("table");
|
||||||
g.throughput(Throughput::Bytes(1400));
|
g.throughput(Throughput::Bytes(1400));
|
||||||
g.bench_function("lookup_warm", |b| {
|
g.bench_function("lookup_warm", |b| {
|
||||||
b.iter(|| table.lookup(&addr));
|
b.iter(|| table.lookup(addr));
|
||||||
});
|
});
|
||||||
g.finish();
|
g.finish();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ fn lookup_cold(c: &mut Criterion) {
|
||||||
g.bench_function("lookup_cold", |b| {
|
g.bench_function("lookup_cold", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
table.clear_cache();
|
table.clear_cache();
|
||||||
table.lookup(&addr)
|
table.lookup(addr)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
g.finish();
|
g.finish();
|
||||||
|
|
|
@ -57,9 +57,9 @@ fn decode_ethernet_with_vlan() {
|
||||||
fn lookup_warm() {
|
fn lookup_warm() {
|
||||||
let mut table = ClaimTable::<MockTimeSource>::new(60, 60);
|
let mut table = ClaimTable::<MockTimeSource>::new(60, 60);
|
||||||
let addr = Address::from_str("1.2.3.4").unwrap();
|
let addr = Address::from_str("1.2.3.4").unwrap();
|
||||||
table.cache(addr.clone(), SocketAddr::from_str("1.2.3.4:3210").unwrap());
|
table.cache(addr, SocketAddr::from_str("1.2.3.4:3210").unwrap());
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
table.lookup(black_box(&addr));
|
table.lookup(black_box(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ fn lookup_cold() {
|
||||||
table.set_claims(SocketAddr::from_str("1.2.3.4:3210").unwrap(), smallvec![Range::from_str("1.2.3.4/32").unwrap()]);
|
table.set_claims(SocketAddr::from_str("1.2.3.4:3210").unwrap(), smallvec![Range::from_str("1.2.3.4/32").unwrap()]);
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
table.clear_cache();
|
table.clear_cache();
|
||||||
table.lookup(black_box(&addr));
|
table.lookup(black_box(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,85 +121,13 @@ fn full_communication_tun_router() {
|
||||||
|
|
||||||
let mut payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2];
|
let mut payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2];
|
||||||
payload.append(&mut vec![0; 1400]);
|
payload.append(&mut vec![0; 1400]);
|
||||||
for _ in 0..10000 {
|
for _ in 0..1000 {
|
||||||
sim.put_payload(node1, payload.clone());
|
sim.put_payload(node1, payload.clone());
|
||||||
sim.simulate_all_messages();
|
sim.simulate_all_messages();
|
||||||
assert_eq!(Some(&payload), black_box(sim.pop_payload(node2).as_ref()));
|
assert_eq!(Some(&payload), black_box(sim.pop_payload(node2).as_ref()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tun_router_send() {
|
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
|
||||||
let config1 = Config {
|
|
||||||
device_type: Type::Tun,
|
|
||||||
auto_claim: false,
|
|
||||||
claims: vec!["1.1.1.1/32".to_string()],
|
|
||||||
..Config::default()
|
|
||||||
};
|
|
||||||
let config2 = Config {
|
|
||||||
device_type: Type::Tun,
|
|
||||||
auto_claim: false,
|
|
||||||
claims: vec!["2.2.2.2/32".to_string()],
|
|
||||||
..Config::default()
|
|
||||||
};
|
|
||||||
let mut sim = TunSimulator::new();
|
|
||||||
let node1 = sim.add_node(false, &config1);
|
|
||||||
let node2 = sim.add_node(false, &config2);
|
|
||||||
|
|
||||||
sim.connect(node1, node2);
|
|
||||||
sim.simulate_all_messages();
|
|
||||||
assert!(sim.is_connected(node1, node2));
|
|
||||||
assert!(sim.is_connected(node2, node1));
|
|
||||||
sim.trigger_housekeep();
|
|
||||||
|
|
||||||
let mut payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2];
|
|
||||||
payload.append(&mut vec![0; 1400]);
|
|
||||||
let node = sim.get_node(node1);
|
|
||||||
for _ in 0..10000 {
|
|
||||||
node.device().put_inbound(black_box(payload.clone()));
|
|
||||||
node.trigger_device_event();
|
|
||||||
assert!(node.socket().pop_outbound().is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tun_router_receive() {
|
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
|
||||||
let config1 = Config {
|
|
||||||
device_type: Type::Tun,
|
|
||||||
auto_claim: false,
|
|
||||||
claims: vec!["1.1.1.1/32".to_string()],
|
|
||||||
..Config::default()
|
|
||||||
};
|
|
||||||
let config2 = Config {
|
|
||||||
device_type: Type::Tun,
|
|
||||||
auto_claim: false,
|
|
||||||
claims: vec!["2.2.2.2/32".to_string()],
|
|
||||||
..Config::default()
|
|
||||||
};
|
|
||||||
let mut sim = TunSimulator::new();
|
|
||||||
let node1 = sim.add_node(false, &config1);
|
|
||||||
let node2 = sim.add_node(false, &config2);
|
|
||||||
|
|
||||||
sim.connect(node1, node2);
|
|
||||||
sim.simulate_all_messages();
|
|
||||||
assert!(sim.is_connected(node1, node2));
|
|
||||||
assert!(sim.is_connected(node2, node1));
|
|
||||||
sim.trigger_housekeep();
|
|
||||||
|
|
||||||
let mut payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2];
|
|
||||||
payload.append(&mut vec![0; 1400]);
|
|
||||||
let node = sim.get_node(node1);
|
|
||||||
node.device().put_inbound(payload.clone());
|
|
||||||
node.trigger_device_event();
|
|
||||||
let msg = node.socket().pop_outbound().unwrap().1;
|
|
||||||
let node = sim.get_node(node2);
|
|
||||||
for _ in 0..10000 {
|
|
||||||
node.socket().put_inbound(node1, black_box(msg.clone()));
|
|
||||||
node.trigger_socket_event();
|
|
||||||
assert!(node.device().pop_outbound().is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn full_communication_tap_switch() {
|
fn full_communication_tap_switch() {
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
log::set_max_level(log::LevelFilter::Error);
|
||||||
let config = Config { device_type: Type::Tap, ..Config::default() };
|
let config = Config { device_type: Type::Tap, ..Config::default() };
|
||||||
|
@ -216,65 +144,13 @@ fn full_communication_tap_switch() {
|
||||||
|
|
||||||
let mut payload = vec![2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5];
|
let mut payload = vec![2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5];
|
||||||
payload.append(&mut vec![0; 1400]);
|
payload.append(&mut vec![0; 1400]);
|
||||||
for _ in 0..10000 {
|
for _ in 0..1000 {
|
||||||
sim.put_payload(node1, payload.clone());
|
sim.put_payload(node1, payload.clone());
|
||||||
sim.simulate_all_messages();
|
sim.simulate_all_messages();
|
||||||
assert_eq!(Some(&payload), black_box(sim.pop_payload(node2).as_ref()));
|
assert_eq!(Some(&payload), black_box(sim.pop_payload(node2).as_ref()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tap_switch_send() {
|
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
|
||||||
let config = Config { device_type: Type::Tap, ..Config::default() };
|
|
||||||
let mut sim = TapSimulator::new();
|
|
||||||
|
|
||||||
let node1 = sim.add_node(false, &config);
|
|
||||||
let node2 = sim.add_node(false, &config);
|
|
||||||
|
|
||||||
sim.connect(node1, node2);
|
|
||||||
sim.simulate_all_messages();
|
|
||||||
assert!(sim.is_connected(node1, node2));
|
|
||||||
assert!(sim.is_connected(node2, node1));
|
|
||||||
sim.trigger_housekeep();
|
|
||||||
|
|
||||||
let mut payload = vec![2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5];
|
|
||||||
payload.append(&mut vec![0; 1400]);
|
|
||||||
let node = sim.get_node(node1);
|
|
||||||
for _ in 0..10000 {
|
|
||||||
node.device().put_inbound(black_box(payload.clone()));
|
|
||||||
node.trigger_device_event();
|
|
||||||
assert!(node.socket().pop_outbound().is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tap_switch_receive() {
|
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
|
||||||
let config = Config { device_type: Type::Tap, ..Config::default() };
|
|
||||||
let mut sim = TapSimulator::new();
|
|
||||||
|
|
||||||
let node1 = sim.add_node(false, &config);
|
|
||||||
let node2 = sim.add_node(false, &config);
|
|
||||||
|
|
||||||
sim.connect(node1, node2);
|
|
||||||
sim.simulate_all_messages();
|
|
||||||
assert!(sim.is_connected(node1, node2));
|
|
||||||
assert!(sim.is_connected(node2, node1));
|
|
||||||
sim.trigger_housekeep();
|
|
||||||
|
|
||||||
let mut payload = vec![2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5];
|
|
||||||
payload.append(&mut vec![0; 1400]);
|
|
||||||
let node = sim.get_node(node1);
|
|
||||||
node.device().put_inbound(payload.clone());
|
|
||||||
node.trigger_device_event();
|
|
||||||
let msg = node.socket().pop_outbound().unwrap().1;
|
|
||||||
let node = sim.get_node(node2);
|
|
||||||
for _ in 0..10000 {
|
|
||||||
node.socket().put_inbound(node1, black_box(msg.clone()));
|
|
||||||
node.trigger_socket_event();
|
|
||||||
assert!(node.device().pop_outbound().is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iai::main!(
|
iai::main!(
|
||||||
udp_send,
|
udp_send,
|
||||||
decode_ipv4,
|
decode_ipv4,
|
||||||
|
@ -286,10 +162,6 @@ iai::main!(
|
||||||
crypto_chacha20,
|
crypto_chacha20,
|
||||||
crypto_aes128,
|
crypto_aes128,
|
||||||
crypto_aes256,
|
crypto_aes256,
|
||||||
tun_router_send,
|
|
||||||
tun_router_receive,
|
|
||||||
full_communication_tun_router,
|
full_communication_tun_router,
|
||||||
tap_switch_send,
|
|
||||||
tap_switch_receive,
|
|
||||||
full_communication_tap_switch
|
full_communication_tap_switch
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,8 +20,6 @@ RUN yum install -y libstdc++-*.i686 \
|
||||||
&& yum install -y glibc-*.i686 \
|
&& yum install -y glibc-*.i686 \
|
||||||
&& yum install -y libgcc.i686
|
&& yum install -y libgcc.i686
|
||||||
|
|
||||||
RUN ln -s /usr/bin/gcc /usr/bin/i686-linux-gnu-gcc
|
|
||||||
|
|
||||||
RUN useradd -ms /bin/bash user
|
RUN useradd -ms /bin/bash user
|
||||||
USER user
|
USER user
|
||||||
WORKDIR /home/user
|
WORKDIR /home/user
|
||||||
|
|
|
@ -293,7 +293,7 @@ runcmd:
|
||||||
MinCount=self.node_count,
|
MinCount=self.node_count,
|
||||||
NetworkInterfaces=[
|
NetworkInterfaces=[
|
||||||
{
|
{
|
||||||
'SubnetId': self.subnet,
|
'SubnetId': self.subnet.id,
|
||||||
'DeviceIndex': 0,
|
'DeviceIndex': 0,
|
||||||
'AssociatePublicIpAddress': True,
|
'AssociatePublicIpAddress': True,
|
||||||
'Groups': [sg.group_id]
|
'Groups': [sg.group_id]
|
||||||
|
@ -301,7 +301,7 @@ runcmd:
|
||||||
],
|
],
|
||||||
Placement=placement,
|
Placement=placement,
|
||||||
UserData=userdata,
|
UserData=userdata,
|
||||||
KeyName=key_pair.name
|
KeyName='vpncloud-perf-test-keypair'
|
||||||
)
|
)
|
||||||
for instance in self.instances:
|
for instance in self.instances:
|
||||||
self.track_resource(instance)
|
self.track_resource(instance)
|
||||||
|
@ -361,7 +361,6 @@ runcmd:
|
||||||
self.connections = []
|
self.connections = []
|
||||||
eprint("Terminating instances...")
|
eprint("Terminating instances...")
|
||||||
for instance in self.instances:
|
for instance in self.instances:
|
||||||
if instance:
|
|
||||||
instance.terminate()
|
instance.terminate()
|
||||||
for instance in self.instances:
|
for instance in self.instances:
|
||||||
eprint("\t{}".format(instance.id))
|
eprint("\t{}".format(instance.id))
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,14 +8,14 @@ from datetime import date
|
||||||
# Note: this script will run for ~8 minutes and incur costs of about $ 0.02
|
# Note: this script will run for ~8 minutes and incur costs of about $ 0.02
|
||||||
|
|
||||||
FILE = "../../target/release/vpncloud"
|
FILE = "../../target/release/vpncloud"
|
||||||
VERSION = "2.3.0"
|
VERSION = "2.2.0"
|
||||||
REGION = "eu-central-1"
|
REGION = "eu-central-1"
|
||||||
|
|
||||||
env = EC2Environment(
|
env = EC2Environment(
|
||||||
region = REGION,
|
region = REGION,
|
||||||
node_count = 2,
|
node_count = 2,
|
||||||
instance_type = "m5.large",
|
instance_type = "m5.large",
|
||||||
use_spot = False,
|
use_spot = True,
|
||||||
max_price = "0.08", # USD per hour per VM
|
max_price = "0.08", # USD per hour per VM
|
||||||
vpncloud_version = VERSION,
|
vpncloud_version = VERSION,
|
||||||
vpncloud_file = FILE,
|
vpncloud_file = FILE,
|
||||||
|
@ -70,7 +70,7 @@ class PerfTest:
|
||||||
eprint("\tSetting up vpncloud on receiver")
|
eprint("\tSetting up vpncloud on receiver")
|
||||||
self.receiver.start_vpncloud(crypto=crypto, ip=f"{self.receiver_ip_vpncloud}/24")
|
self.receiver.start_vpncloud(crypto=crypto, ip=f"{self.receiver_ip_vpncloud}/24")
|
||||||
eprint("\tSetting up vpncloud on sender")
|
eprint("\tSetting up vpncloud on sender")
|
||||||
self.sender.start_vpncloud(crypto=crypto, peers=[f"{self.receiver.private_ip}:3210"], ip=f"{self.sender_ip_vpncloud}/24")
|
self.sender.start_vpncloud(crypto=crypto, peers=[f"{self.receiver_ip_vpncloud}:3210"], ip=f"{self.sender_ip_vpncloud}/24")
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
def stop_vpncloud(self):
|
def stop_vpncloud(self):
|
||||||
|
|
|
@ -12,7 +12,7 @@ env = EC2Environment(
|
||||||
region = REGION,
|
region = REGION,
|
||||||
node_count = 2,
|
node_count = 2,
|
||||||
instance_type = "m5.large",
|
instance_type = "m5.large",
|
||||||
use_spot = False,
|
use_spot = True,
|
||||||
max_price = "0.08", # USD per hour per VM
|
max_price = "0.08", # USD per hour per VM
|
||||||
vpncloud_version = VERSION,
|
vpncloud_version = VERSION,
|
||||||
vpncloud_file = FILE,
|
vpncloud_file = FILE,
|
||||||
|
@ -45,11 +45,11 @@ class PerfTest:
|
||||||
self.receiver.stop_iperf_server()
|
self.receiver.stop_iperf_server()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def start_vpncloud(self, crypto=None):
|
def start_vpncloud(self):
|
||||||
eprint("\tSetting up vpncloud on receiver")
|
eprint("\tSetting up vpncloud on receiver")
|
||||||
self.receiver.start_vpncloud(crypto=crypto, ip=f"{self.receiver_ip_vpncloud}/24")
|
self.receiver.start_vpncloud(ip=f"{self.receiver_ip_vpncloud}/24")
|
||||||
eprint("\tSetting up vpncloud on sender")
|
eprint("\tSetting up vpncloud on sender")
|
||||||
self.sender.start_vpncloud(crypto=crypto, peers=[f"{self.receiver.private_ip}:3210"], ip=f"{self.sender_ip_vpncloud}/24")
|
self.sender.start_vpncloud(peers=[f"{self.receiver.private_ip}:3210"], ip=f"{self.sender_ip_vpncloud}/24")
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
def stop_vpncloud(self):
|
def stop_vpncloud(self):
|
||||||
|
@ -58,7 +58,7 @@ class PerfTest:
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
print()
|
print()
|
||||||
self.start_vpncloud(crypto="plain")
|
self.start_vpncloud()
|
||||||
throughput = self.run_iperf(self.receiver_ip_vpncloud)["throughput"]
|
throughput = self.run_iperf(self.receiver_ip_vpncloud)["throughput"]
|
||||||
print(f"Throughput: {throughput / 1_000_000.0} MBit/s")
|
print(f"Throughput: {throughput / 1_000_000.0} MBit/s")
|
||||||
native_ping_100 = self.run_ping(self.receiver.private_ip, 100)["rtt_avg"]
|
native_ping_100 = self.run_ping(self.receiver.private_ip, 100)["rtt_avg"]
|
||||||
|
|
|
@ -11,7 +11,7 @@ use structopt::{clap::Shell, StructOpt};
|
||||||
pub const DEFAULT_PEER_TIMEOUT: u16 = 300;
|
pub const DEFAULT_PEER_TIMEOUT: u16 = 300;
|
||||||
pub const DEFAULT_PORT: u16 = 3210;
|
pub const DEFAULT_PORT: u16 = 3210;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Deserialize, Debug, PartialEq, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub device_type: Type,
|
pub device_type: Type,
|
||||||
pub device_name: String,
|
pub device_name: String,
|
||||||
|
@ -622,7 +622,7 @@ pub enum Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
||||||
pub struct ConfigFileDevice {
|
pub struct ConfigFileDevice {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -633,7 +633,7 @@ pub struct ConfigFileDevice {
|
||||||
pub fix_rp_filter: Option<bool>,
|
pub fix_rp_filter: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
||||||
pub struct ConfigFileBeacon {
|
pub struct ConfigFileBeacon {
|
||||||
pub store: Option<String>,
|
pub store: Option<String>,
|
||||||
|
@ -642,14 +642,14 @@ pub struct ConfigFileBeacon {
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
||||||
pub struct ConfigFileStatsd {
|
pub struct ConfigFileStatsd {
|
||||||
pub server: Option<String>,
|
pub server: Option<String>,
|
||||||
pub prefix: Option<String>,
|
pub prefix: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
||||||
pub struct ConfigFile {
|
pub struct ConfigFile {
|
||||||
pub device: Option<ConfigFileDevice>,
|
pub device: Option<ConfigFileDevice>,
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub struct Algorithms {
|
||||||
pub allow_unencrypted: bool,
|
pub allow_unencrypted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
#[serde(rename_all = "kebab-case", deny_unknown_fields, default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
|
@ -201,14 +201,13 @@ impl Crypto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum MessageResult {
|
pub enum MessageResult {
|
||||||
Message(u8),
|
Message(u8),
|
||||||
Reply,
|
Reply,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
pub enum PeerCrypto {
|
pub enum PeerCrypto {
|
||||||
Encrypted {
|
Encrypted {
|
||||||
last_init_message: Vec<u8>,
|
last_init_message: Vec<u8>,
|
||||||
|
|
|
@ -384,7 +384,7 @@ impl InitMsg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum InitResult<P: Payload> {
|
pub enum InitResult<P: Payload> {
|
||||||
Continue,
|
Continue,
|
||||||
Success { peer_payload: P, is_initiator: bool },
|
Success { peer_payload: P, is_initiator: bool },
|
||||||
|
|
|
@ -3,38 +3,18 @@
|
||||||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{cmp, collections::VecDeque, convert::TryInto, fmt, fs::{self, File}, io::{self, Cursor, Read, Write, Error as IoError, BufReader, BufRead}, net::{Ipv4Addr, UdpSocket}, os::unix::io::AsRawFd, str, str::FromStr, sync::Arc, time::Duration};
|
||||||
cmp,
|
|
||||||
collections::VecDeque,
|
|
||||||
convert::TryInto,
|
|
||||||
fmt,
|
|
||||||
fs::{self, File},
|
|
||||||
io::{self, BufRead, BufReader, Cursor, Error as IoError, Read, Write},
|
|
||||||
net::{Ipv4Addr, UdpSocket},
|
|
||||||
os::unix::io::AsRawFd,
|
|
||||||
str,
|
|
||||||
str::FromStr,
|
|
||||||
sync::Arc,
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
use timeout_io::Reader;
|
use timeout_io::Reader;
|
||||||
|
|
||||||
use crate::{crypto, error::Error, util::MsgBuffer};
|
use crate::{crypto, error::Error, util::MsgBuffer};
|
||||||
|
|
||||||
static TUNSETIFF: libc::c_ulong = 1074025674;
|
static TUNSETIFF: libc::c_ulong = 1074025674;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
struct IfReqDataAddr {
|
|
||||||
af: libc::c_int,
|
|
||||||
addr: Ipv4Addr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
union IfReqData {
|
union IfReqData {
|
||||||
flags: libc::c_short,
|
flags: libc::c_short,
|
||||||
value: libc::c_int,
|
value: libc::c_int,
|
||||||
addr: IfReqDataAddr,
|
addr: (libc::c_short, Ipv4Addr),
|
||||||
_dummy: [u8; 24],
|
_dummy: [u8; 24],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +34,7 @@ impl IfReq {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of a tun/tap device
|
/// The type of a tun/tap device
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
/// Tun interface: This interface transports IP packets.
|
/// Tun interface: This interface transports IP packets.
|
||||||
#[serde(rename = "tun")]
|
#[serde(rename = "tun")]
|
||||||
|
@ -402,11 +382,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) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFADDR.try_into().unwrap(), &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
let af = unsafe { ifreq.data.addr.af };
|
let af = unsafe { ifreq.data.addr.0 };
|
||||||
if af as libc::c_int != libc::AF_INET {
|
if af as libc::c_int != libc::AF_INET {
|
||||||
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
||||||
}
|
}
|
||||||
let ip = unsafe { ifreq.data.addr.addr };
|
let ip = unsafe { ifreq.data.addr.1 };
|
||||||
Ok(ip)
|
Ok(ip)
|
||||||
}
|
}
|
||||||
_ => Err(IoError::last_os_error()),
|
_ => Err(IoError::last_os_error()),
|
||||||
|
@ -417,8 +397,7 @@ fn get_device_addr(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
fn set_device_addr(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.addr.af = libc::AF_INET as libc::c_int;
|
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||||
ifreq.data.addr.addr = addr;
|
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFADDR.try_into().unwrap(), &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
|
@ -434,11 +413,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) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCGIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
let af = unsafe { ifreq.data.addr.af };
|
let af = unsafe { ifreq.data.addr.0 };
|
||||||
if af as libc::c_int != libc::AF_INET {
|
if af as libc::c_int != libc::AF_INET {
|
||||||
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
return Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Invalid address family".to_owned()));
|
||||||
}
|
}
|
||||||
let ip = unsafe { ifreq.data.addr.addr };
|
let ip = unsafe { ifreq.data.addr.1 };
|
||||||
Ok(ip)
|
Ok(ip)
|
||||||
}
|
}
|
||||||
_ => Err(IoError::last_os_error()),
|
_ => Err(IoError::last_os_error()),
|
||||||
|
@ -449,8 +428,7 @@ fn get_device_netmask(ifname: &str) -> io::Result<Ipv4Addr> {
|
||||||
fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
fn set_device_netmask(ifname: &str, addr: Ipv4Addr) -> io::Result<()> {
|
||||||
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
let sock = UdpSocket::bind("0.0.0.0:0")?;
|
||||||
let mut ifreq = IfReq::new(ifname);
|
let mut ifreq = IfReq::new(ifname);
|
||||||
ifreq.data.addr.af = libc::AF_INET as libc::c_int;
|
ifreq.data.addr = (libc::AF_INET as libc::c_short, addr);
|
||||||
ifreq.data.addr.addr = addr;
|
|
||||||
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
let res = unsafe { libc::ioctl(sock.as_raw_fd(), libc::SIOCSIFNETMASK.try_into().unwrap(), &mut ifreq) };
|
||||||
match res {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
let device_thread = DeviceThread::<S, D, P, TS>::new(
|
let device_thread = DeviceThread::<S, D, P, TS>::new(
|
||||||
config.clone(),
|
config.clone(),
|
||||||
device.duplicate()?,
|
device.duplicate()?,
|
||||||
socket.try_clone().map_err(|e| Error::SocketIo("Failed to clone socket", e))?,
|
socket.clone(),
|
||||||
traffic.clone(),
|
traffic.clone(),
|
||||||
peer_crypto.clone(),
|
peer_crypto.clone(),
|
||||||
table.clone(),
|
table.clone(),
|
||||||
|
@ -132,11 +132,11 @@ impl<P: Protocol> GenericCloud<MockDevice, P, MockSocket, MockTimeSource> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trigger_socket_event(&mut self) {
|
pub fn trigger_socket_event(&mut self) {
|
||||||
self.socket_thread.iteration();
|
self.socket_thread.iteration()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trigger_device_event(&mut self) {
|
pub fn trigger_device_event(&mut self) {
|
||||||
self.device_thread.iteration();
|
self.device_thread.iteration()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trigger_housekeep(&mut self) {
|
pub fn trigger_housekeep(&mut self) {
|
||||||
|
|
|
@ -102,14 +102,13 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> DeviceThread<S, D, P, TS
|
||||||
fn forward_packet(&mut self) -> Result<(), Error> {
|
fn forward_packet(&mut self) -> Result<(), Error> {
|
||||||
let (src, dst) = P::parse(self.buffer.message())?;
|
let (src, dst) = P::parse(self.buffer.message())?;
|
||||||
debug!("Read data from interface: src: {}, dst: {}, {} bytes", src, dst, self.buffer.len());
|
debug!("Read data from interface: src: {}, dst: {}, {} bytes", src, dst, self.buffer.len());
|
||||||
self.traffic.count_out_payload(dst.clone(), src, self.buffer.len());
|
self.traffic.count_out_payload(dst, src, self.buffer.len());
|
||||||
match self.table.lookup(&dst) {
|
match self.table.lookup(dst) {
|
||||||
Some(addr) => {
|
Some(addr) => {
|
||||||
// Peer found for destination
|
// Peer found for destination
|
||||||
debug!("Found destination for {} => {}", dst, addr);
|
debug!("Found destination for {} => {}", dst, addr);
|
||||||
self.send_msg(addr, MESSAGE_TYPE_DATA)?;
|
self.send_msg(addr, MESSAGE_TYPE_DATA)?;
|
||||||
}
|
}
|
||||||
//TODO: VIA: find relay peer and relay message
|
|
||||||
None => {
|
None => {
|
||||||
if self.broadcast {
|
if self.broadcast {
|
||||||
debug!("No destination for {} found, broadcasting", dst);
|
debug!("No destination for {} found, broadcasting", dst);
|
||||||
|
@ -130,7 +129,7 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> DeviceThread<S, D, P, TS
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iteration(&mut self) -> bool {
|
pub fn iteration(&mut self) {
|
||||||
if self.device.read(&mut self.buffer).is_ok() {
|
if self.device.read(&mut self.buffer).is_ok() {
|
||||||
//try_fail!(result, "Failed to read from device: {}");
|
//try_fail!(result, "Failed to read from device: {}");
|
||||||
if let Err(e) = self.forward_packet() {
|
if let Err(e) = self.forward_packet() {
|
||||||
|
@ -142,16 +141,17 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> DeviceThread<S, D, P, TS
|
||||||
if let Err(e) = self.housekeep() {
|
if let Err(e) = self.housekeep() {
|
||||||
error!("{}", e)
|
error!("{}", e)
|
||||||
}
|
}
|
||||||
self.next_housekeep = now + 1;
|
self.next_housekeep = now + 1
|
||||||
if !self.running.load(Ordering::SeqCst) {
|
|
||||||
debug!("Device: end");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(mut self) {
|
pub fn run(mut self) {
|
||||||
while self.iteration() {}
|
loop {
|
||||||
|
self.iteration();
|
||||||
|
if !self.running.load(Ordering::SeqCst) {
|
||||||
|
debug!("Device: end");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ use std::{
|
||||||
use super::common::PeerData;
|
use super::common::PeerData;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub struct SharedPeerCrypto {
|
pub struct SharedPeerCrypto {
|
||||||
peers: Arc<Mutex<HashMap<SocketAddr, Option<Arc<CryptoCore>>, Hash>>>,
|
peers: Arc<Mutex<HashMap<SocketAddr, Option<Arc<CryptoCore>>, Hash>>>,
|
||||||
cache: HashMap<SocketAddr, Option<Arc<CryptoCore>>, Hash>, //TODO: local hashmap as cache
|
cache: HashMap<SocketAddr, Option<Arc<CryptoCore>>, Hash>, //TODO: local hashmap as cache
|
||||||
|
@ -154,13 +153,13 @@ impl<TS: TimeSource> SharedTable<TS> {
|
||||||
self.cache.clear();
|
self.cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup(&mut self, addr: &Address) -> Option<SocketAddr> {
|
pub fn lookup(&mut self, addr: Address) -> Option<SocketAddr> {
|
||||||
if let Some(val) = self.cache.get(addr) {
|
if let Some(val) = self.cache.get(&addr) {
|
||||||
return *val;
|
return *val;
|
||||||
}
|
}
|
||||||
// if not found, use shared table and put into cache
|
// if not found, use shared table and put into cache
|
||||||
let val = self.table.lock().lookup(addr);
|
let val = self.table.lock().lookup(addr);
|
||||||
self.cache.insert(addr.clone(), val);
|
self.cache.insert(addr, val);
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,10 +173,10 @@ impl<TS: TimeSource> SharedTable<TS> {
|
||||||
self.cache.clear();
|
self.cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache(&mut self, addr: &Address, peer: SocketAddr) {
|
pub fn cache(&mut self, addr: Address, peer: SocketAddr) {
|
||||||
if self.cache.get(addr) != Some(&Some(peer)) {
|
if self.cache.get(&addr) != Some(&Some(peer)) {
|
||||||
self.table.lock().cache(addr.clone(), peer);
|
self.table.lock().cache(addr, peer);
|
||||||
self.cache.insert(addr.clone(), Some(peer));
|
self.cache.insert(addr, Some(peer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,6 @@ pub struct SocketThread<S: Socket, D: Device, P: Protocol, TS: TimeSource> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS> {
|
impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: Config, device: D, socket: S, traffic: SharedTraffic, peer_crypto: SharedPeerCrypto,
|
config: Config, device: D, socket: S, traffic: SharedTraffic, peer_crypto: SharedPeerCrypto,
|
||||||
table: SharedTable<TS>, port_forwarding: Option<PortForwarding>, stats_file: Option<File>,
|
table: SharedTable<TS>, port_forwarding: Option<PortForwarding>, stats_file: Option<File>,
|
||||||
|
@ -332,7 +331,7 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
let (src, dst) = P::parse(self.buffer.message())?;
|
let (src, dst) = P::parse(self.buffer.message())?;
|
||||||
let len = self.buffer.len();
|
let len = self.buffer.len();
|
||||||
debug!("Writing data to device: {} bytes", len);
|
debug!("Writing data to device: {} bytes", len);
|
||||||
self.traffic.count_in_payload(src.clone(), dst, len);
|
self.traffic.count_in_payload(src, dst, len);
|
||||||
if let Err(e) = self.device.write(&mut self.buffer) {
|
if let Err(e) = self.device.write(&mut self.buffer) {
|
||||||
error!("Failed to send via device: {}", e);
|
error!("Failed to send via device: {}", e);
|
||||||
return Err(e);
|
return Err(e);
|
||||||
|
@ -340,7 +339,7 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
self.buffer.clear();
|
self.buffer.clear();
|
||||||
if self.learning {
|
if self.learning {
|
||||||
// Learn single address
|
// Learn single address
|
||||||
self.table.cache(&src, peer);
|
self.table.cache(src, peer);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -349,7 +348,6 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
match msg_result {
|
match msg_result {
|
||||||
MessageResult::Message(type_) => match type_ {
|
MessageResult::Message(type_) => match type_ {
|
||||||
MESSAGE_TYPE_DATA => self.handle_payload_from(src)?,
|
MESSAGE_TYPE_DATA => self.handle_payload_from(src)?,
|
||||||
//TODO: VIA: relay message
|
|
||||||
MESSAGE_TYPE_NODE_INFO => {
|
MESSAGE_TYPE_NODE_INFO => {
|
||||||
let info = match NodeInfo::decode(Cursor::new(self.buffer.message())) {
|
let info = match NodeInfo::decode(Cursor::new(self.buffer.message())) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
|
@ -446,7 +444,6 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
self.table.housekeep();
|
self.table.housekeep();
|
||||||
self.crypto_housekeep()?;
|
self.crypto_housekeep()?;
|
||||||
// Periodically extend the port-forwarding
|
// Periodically extend the port-forwarding
|
||||||
//TODO: extra thread
|
|
||||||
if let Some(ref mut pfw) = self.port_forwarding {
|
if let Some(ref mut pfw) = self.port_forwarding {
|
||||||
pfw.check_extend();
|
pfw.check_extend();
|
||||||
}
|
}
|
||||||
|
@ -465,9 +462,7 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
self.reconnect_to_peers()?;
|
self.reconnect_to_peers()?;
|
||||||
if self.next_stats_out < now {
|
if self.next_stats_out < now {
|
||||||
// Write out the statistics
|
// Write out the statistics
|
||||||
//TODO: extra thread
|
|
||||||
self.write_out_stats().map_err(|err| Error::FileIo("Failed to write stats file", err))?;
|
self.write_out_stats().map_err(|err| Error::FileIo("Failed to write stats file", err))?;
|
||||||
//TODO: extra thread
|
|
||||||
self.send_stats_to_statsd()?;
|
self.send_stats_to_statsd()?;
|
||||||
self.next_stats_out = now + STATS_INTERVAL;
|
self.next_stats_out = now + STATS_INTERVAL;
|
||||||
self.traffic.period(Some(5));
|
self.traffic.period(Some(5));
|
||||||
|
@ -721,7 +716,7 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iteration(&mut self) -> bool {
|
pub fn iteration(&mut self) {
|
||||||
if let Ok(src) = self.socket.receive(&mut self.buffer)
|
if let Ok(src) = self.socket.receive(&mut self.buffer)
|
||||||
{
|
{
|
||||||
match self.handle_message(src) {
|
match self.handle_message(src) {
|
||||||
|
@ -749,17 +744,18 @@ impl<S: Socket, D: Device, P: Protocol, TS: TimeSource> SocketThread<S, D, P, TS
|
||||||
if let Err(e) = self.housekeep() {
|
if let Err(e) = self.housekeep() {
|
||||||
error!("{}", e)
|
error!("{}", e)
|
||||||
}
|
}
|
||||||
self.next_housekeep = now + 1;
|
self.next_housekeep = now + 1
|
||||||
if !self.running.load(Ordering::SeqCst) {
|
|
||||||
debug!("Socket: end");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug_assert!(self.buffer.is_empty());
|
debug_assert!(self.buffer.is_empty());
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(mut self) {
|
pub fn run(mut self) {
|
||||||
while self.iteration() {}
|
loop {
|
||||||
|
self.iteration();
|
||||||
|
if !self.running.load(Ordering::SeqCst) {
|
||||||
|
debug!("Socket: end");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,20 +23,19 @@ pub const MESSAGE_TYPE_CLOSE: u8 = 0xff;
|
||||||
pub type AddrList = SmallVec<[SocketAddr; 4]>;
|
pub type AddrList = SmallVec<[SocketAddr; 4]>;
|
||||||
pub type PeerList = SmallVec<[PeerInfo; 16]>;
|
pub type PeerList = SmallVec<[PeerInfo; 16]>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct PeerInfo {
|
pub struct PeerInfo {
|
||||||
pub node_id: Option<NodeId>,
|
pub node_id: Option<NodeId>,
|
||||||
pub addrs: AddrList,
|
pub addrs: AddrList,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct NodeInfo {
|
pub struct NodeInfo {
|
||||||
pub node_id: NodeId,
|
pub node_id: NodeId,
|
||||||
pub peers: PeerList,
|
pub peers: PeerList,
|
||||||
pub claims: RangeList,
|
pub claims: RangeList,
|
||||||
pub peer_timeout: Option<u16>,
|
pub peer_timeout: Option<u16>,
|
||||||
pub addrs: AddrList,
|
pub addrs: AddrList,
|
||||||
//TODO: VIA: Add via ranges
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeInfo {
|
impl NodeInfo {
|
||||||
|
|
17
src/net.rs
17
src/net.rs
|
@ -31,12 +31,11 @@ pub fn get_ip() -> IpAddr {
|
||||||
s.local_addr().unwrap().ip()
|
s.local_addr().unwrap().ip()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Socket: Sized + Send + Sync + 'static {
|
pub trait Socket: Sized + Clone + Send + Sync + 'static {
|
||||||
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error>;
|
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error>;
|
||||||
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>;
|
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>;
|
||||||
fn address(&self) -> Result<SocketAddr, io::Error>;
|
fn address(&self) -> Result<SocketAddr, io::Error>;
|
||||||
fn create_port_forwarding(&self) -> Option<PortForwarding>;
|
fn create_port_forwarding(&self) -> Option<PortForwarding>;
|
||||||
fn try_clone(&self) -> Result<Self, io::Error>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr {
|
pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr {
|
||||||
|
@ -64,6 +63,12 @@ impl NetSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for NetSocket {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Socket for NetSocket {
|
impl Socket for NetSocket {
|
||||||
fn create_port_forwarding(&self) -> Option<PortForwarding> {
|
fn create_port_forwarding(&self) -> Option<PortForwarding> {
|
||||||
PortForwarding::new(self.0.local_addr().unwrap().port())
|
PortForwarding::new(self.0.local_addr().unwrap().port())
|
||||||
|
@ -85,10 +90,6 @@ impl Socket for NetSocket {
|
||||||
addr.set_ip(get_ip());
|
addr.set_ip(get_ip());
|
||||||
Ok(addr)
|
Ok(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_clone(&self) -> Result<Self, io::Error> {
|
|
||||||
Ok(Self(self.0.clone()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
@ -172,10 +173,6 @@ impl Socket for MockSocket {
|
||||||
fn create_port_forwarding(&self) -> Option<PortForwarding> {
|
fn create_port_forwarding(&self) -> Option<PortForwarding> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_clone(&self) -> Result<Self, io::Error> {
|
|
||||||
Ok(self.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bench")]
|
#[cfg(feature = "bench")]
|
||||||
|
|
|
@ -6,7 +6,7 @@ use super::{device::Type, types::Mode, util::Duration};
|
||||||
use crate::config::{ConfigFile, ConfigFileBeacon, ConfigFileDevice, ConfigFileStatsd, CryptoConfig};
|
use crate::config::{ConfigFile, ConfigFileBeacon, ConfigFileDevice, ConfigFileStatsd, CryptoConfig};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
|
||||||
pub enum OldCryptoMethod {
|
pub enum OldCryptoMethod {
|
||||||
#[serde(rename = "chacha20")]
|
#[serde(rename = "chacha20")]
|
||||||
ChaCha20,
|
ChaCha20,
|
||||||
|
@ -16,7 +16,7 @@ pub enum OldCryptoMethod {
|
||||||
AES128,
|
AES128,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Default)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||||
pub struct OldConfigFile {
|
pub struct OldConfigFile {
|
||||||
#[serde(alias = "device-type")]
|
#[serde(alias = "device-type")]
|
||||||
pub device_type: Option<Type>,
|
pub device_type: Option<Type>,
|
||||||
|
|
12
src/table.rs
12
src/table.rs
|
@ -48,7 +48,6 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_claims(&mut self, peer: SocketAddr, mut claims: RangeList) {
|
pub fn set_claims(&mut self, peer: SocketAddr, mut claims: RangeList) {
|
||||||
let mut removed_claim = false;
|
|
||||||
for entry in &mut self.claims {
|
for entry in &mut self.claims {
|
||||||
if entry.peer == peer {
|
if entry.peer == peer {
|
||||||
let pos = claims.iter().position(|r| r == &entry.claim);
|
let pos = claims.iter().position(|r| r == &entry.claim);
|
||||||
|
@ -59,21 +58,18 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entry.timeout = 0;
|
entry.timeout = 0
|
||||||
removed_claim = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for claim in claims {
|
for claim in claims {
|
||||||
self.claims.push(ClaimEntry { peer, claim, timeout: TS::now() + self.claim_timeout as Time })
|
self.claims.push(ClaimEntry { peer, claim, timeout: TS::now() + self.claim_timeout as Time })
|
||||||
}
|
}
|
||||||
if removed_claim {
|
|
||||||
for entry in self.cache.values_mut() {
|
for entry in self.cache.values_mut() {
|
||||||
if entry.peer == peer {
|
if entry.peer == peer {
|
||||||
entry.timeout = 0
|
entry.timeout = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
self.housekeep()
|
self.housekeep()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +87,9 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
self.housekeep()
|
self.housekeep()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup(&mut self, addr: &Address) -> Option<SocketAddr> {
|
pub fn lookup(&mut self, addr: Address) -> Option<SocketAddr> {
|
||||||
// HOT PATH
|
// HOT PATH
|
||||||
if let Some(entry) = self.cache.get(addr) {
|
if let Some(entry) = self.cache.get(&addr) {
|
||||||
return Some(entry.peer);
|
return Some(entry.peer);
|
||||||
}
|
}
|
||||||
// COLD PATH
|
// COLD PATH
|
||||||
|
@ -107,7 +103,7 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
}
|
}
|
||||||
if let Some(entry) = found {
|
if let Some(entry) = found {
|
||||||
self.cache.insert(
|
self.cache.insert(
|
||||||
addr.clone(),
|
addr,
|
||||||
CacheValue { peer: entry.peer, timeout: min(TS::now() + self.cache_timeout as Time, entry.timeout) },
|
CacheValue { peer: entry.peer, timeout: min(TS::now() + self.cache_timeout as Time, entry.timeout) },
|
||||||
);
|
);
|
||||||
return Some(entry.peer);
|
return Some(entry.peer);
|
||||||
|
|
|
@ -228,7 +228,7 @@ impl TrafficStats {
|
||||||
if let Some(entry) = self.payload.get_mut(key) {
|
if let Some(entry) = self.payload.get_mut(key) {
|
||||||
*entry += data
|
*entry += data
|
||||||
} else {
|
} else {
|
||||||
self.payload.insert(key.clone(), data.clone());
|
self.payload.insert(*key, data.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.dropped += &other.dropped
|
self.dropped += &other.dropped
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub const NODE_ID_BYTES: usize = 16;
|
||||||
|
|
||||||
pub type NodeId = [u8; NODE_ID_BYTES];
|
pub type NodeId = [u8; NODE_ID_BYTES];
|
||||||
|
|
||||||
#[derive(Eq, Clone)]
|
#[derive(Eq, Clone, Copy)]
|
||||||
pub struct Address {
|
pub struct Address {
|
||||||
pub data: [u8; 16],
|
pub data: [u8; 16],
|
||||||
pub len: u8,
|
pub len: u8,
|
||||||
|
@ -126,7 +126,7 @@ impl FromStr for Address {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone)]
|
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub base: Address,
|
pub base: Address,
|
||||||
pub prefix_len: u8,
|
pub prefix_len: u8,
|
||||||
|
@ -135,7 +135,7 @@ pub struct Range {
|
||||||
pub type RangeList = SmallVec<[Range; 4]>;
|
pub type RangeList = SmallVec<[Range; 4]>;
|
||||||
|
|
||||||
impl Range {
|
impl Range {
|
||||||
pub fn matches(&self, addr: &Address) -> bool {
|
pub fn matches(&self, addr: Address) -> bool {
|
||||||
if self.base.len != addr.len {
|
if self.base.len != addr.len {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ impl fmt::Debug for Range {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
#[serde(rename = "normal")]
|
#[serde(rename = "normal")]
|
||||||
Normal,
|
Normal,
|
||||||
|
|
|
@ -379,7 +379,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),
|
||||||
|
|
|
@ -13,14 +13,9 @@ use std::{
|
||||||
io::{self, Cursor, Read, Write},
|
io::{self, Cursor, Read, Write},
|
||||||
net::{Ipv6Addr, SocketAddr, SocketAddrV6, TcpListener, TcpStream, UdpSocket},
|
net::{Ipv6Addr, SocketAddr, SocketAddrV6, TcpListener, TcpStream, UdpSocket},
|
||||||
os::unix::io::{AsRawFd, RawFd},
|
os::unix::io::{AsRawFd, RawFd},
|
||||||
thread, time::Duration,
|
thread, sync::Arc,
|
||||||
};
|
|
||||||
use tungstenite::{
|
|
||||||
accept, connect,
|
|
||||||
protocol::WebSocket,
|
|
||||||
stream::{MaybeTlsStream, NoDelay},
|
|
||||||
Message,
|
|
||||||
};
|
};
|
||||||
|
use tungstenite::{connect, protocol::WebSocket, Message, accept, stream::{MaybeTlsStream, NoDelay}};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
macro_rules! io_error {
|
macro_rules! io_error {
|
||||||
|
@ -112,9 +107,10 @@ pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ProxyConnection {
|
pub struct ProxyConnection {
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
socket: WebSocket<MaybeTlsStream<TcpStream>>,
|
socket: Arc<WebSocket<MaybeTlsStream<TcpStream>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProxyConnection {
|
impl ProxyConnection {
|
||||||
|
@ -122,14 +118,8 @@ impl ProxyConnection {
|
||||||
let parsed_url = io_error!(Url::parse(url), "Invalid URL {}: {}", url)?;
|
let parsed_url = io_error!(Url::parse(url), "Invalid URL {}: {}", url)?;
|
||||||
let (mut socket, _) = io_error!(connect(parsed_url), "Failed to connect to URL {}: {}", url)?;
|
let (mut socket, _) = io_error!(connect(parsed_url), "Failed to connect to URL {}: {}", url)?;
|
||||||
socket.get_mut().set_nodelay(true)?;
|
socket.get_mut().set_nodelay(true)?;
|
||||||
match socket.get_mut() {
|
|
||||||
&mut MaybeTlsStream::Plain(ref mut stream) => {
|
|
||||||
io_error!(stream.set_read_timeout(Some(Duration::from_secs(1))), "Failed to set read timeout: {}")?
|
|
||||||
},
|
|
||||||
_ => unimplemented!()
|
|
||||||
}
|
|
||||||
let addr = "0.0.0.0:0".parse::<SocketAddr>().unwrap();
|
let addr = "0.0.0.0:0".parse::<SocketAddr>().unwrap();
|
||||||
let mut con = ProxyConnection { addr, socket };
|
let mut con = ProxyConnection { addr, socket: Arc::new(socket) };
|
||||||
let addr_data = con.read_message()?;
|
let addr_data = con.read_message()?;
|
||||||
con.addr = read_addr(Cursor::new(&addr_data))?;
|
con.addr = read_addr(Cursor::new(&addr_data))?;
|
||||||
Ok(con)
|
Ok(con)
|
||||||
|
@ -137,9 +127,12 @@ impl ProxyConnection {
|
||||||
|
|
||||||
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
|
fn read_message(&mut self) -> Result<Vec<u8>, io::Error> {
|
||||||
loop {
|
loop {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
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_message(), "Failed to read from ws proxy: {}")? {
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +141,7 @@ impl AsRawFd for ProxyConnection {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
match self.socket.get_ref() {
|
match self.socket.get_ref() {
|
||||||
MaybeTlsStream::Plain(stream) => stream.as_raw_fd(),
|
MaybeTlsStream::Plain(stream) => stream.as_raw_fd(),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,23 +163,14 @@ 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)?;
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
io_error!(self.socket.write_message(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())
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address(&self) -> Result<SocketAddr, io::Error> {
|
fn address(&self) -> Result<SocketAddr, io::Error> {
|
||||||
Ok(self.addr)
|
Ok(self.addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_clone(&self) -> Result<Self, io::Error> {
|
|
||||||
let socket = match self.socket.get_ref() {
|
|
||||||
MaybeTlsStream::Plain(stream) => WebSocket::from_raw_socket(
|
|
||||||
MaybeTlsStream::Plain(stream.try_clone()?),
|
|
||||||
tungstenite::protocol::Role::Client,
|
|
||||||
Some(*self.socket.get_config()),
|
|
||||||
),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
|
||||||
Ok(Self { addr: self.addr, socket })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue