mirror of https://github.com/dswd/vpncloud.git
Compare commits
5 Commits
04d934491c
...
50058e60d0
Author | SHA1 | Date |
---|---|---|
Dennis Schwerdel | 50058e60d0 | |
Dennis Schwerdel | 229db241de | |
Dennis Schwerdel | 63dc1e3ce1 | |
Dennis Schwerdel | 9cd7e53880 | |
Dennis Schwerdel | ee8542307f |
|
@ -2,10 +2,15 @@
|
||||||
|
|
||||||
This project follows [semantic versioning](http://semver.org).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
### Unreleased
|
### v1.1.0 (2019-12-04)
|
||||||
|
|
||||||
- [changed] Rust version 1.41.0
|
- [added] Exchange peer timeout and adapt keepalive accordingly
|
||||||
|
- [added] Reducing published peer timeout to 5 min when NAT is detected
|
||||||
|
- [added] Added more tests
|
||||||
|
- [changed] Rust version 1.39.0
|
||||||
- [changed] Updated dependencies
|
- [changed] Updated dependencies
|
||||||
|
- [fixed] Fixed potential startup dependency issue
|
||||||
|
- [fixed] Fixed wrong base62 encoding
|
||||||
|
|
||||||
### v1.0.0 (2019-03-21)
|
### v1.0.0 (2019-03-21)
|
||||||
|
|
||||||
|
|
|
@ -23,42 +23,6 @@ dependencies = [
|
||||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace"
|
|
||||||
version = "0.3.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace-sys"
|
|
||||||
version = "0.1.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base-62"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -131,26 +95,6 @@ name = "dtoa"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "failure"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "failure_derive"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
|
@ -295,33 +239,6 @@ dependencies = [
|
||||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-bigint"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.41"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -466,11 +383,6 @@ dependencies = [
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-demangle"
|
|
||||||
version = "0.1.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
|
@ -544,17 +456,6 @@ dependencies = [
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "synstructure"
|
|
||||||
version = "0.12.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
|
@ -639,9 +540,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vpncloud"
|
name = "vpncloud"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base-62 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -799,10 +699,6 @@ dependencies = [
|
||||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||||
"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
|
"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
|
||||||
"checksum attohttpc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4da2f0d9a8eb4e0aabc162278968eaf753999aa4aed173b753f9fa8da4cb86"
|
"checksum attohttpc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4da2f0d9a8eb4e0aabc162278968eaf753999aa4aed173b753f9fa8da4cb86"
|
||||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
|
||||||
"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
|
|
||||||
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
|
|
||||||
"checksum base-62 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f28ebd71b3e708e895b83ec2d35c6e2ef96e34945706bf4d73826354e84f89b2"
|
|
||||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
"checksum boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
|
"checksum boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
|
||||||
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
||||||
|
@ -814,8 +710,6 @@ dependencies = [
|
||||||
"checksum daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815"
|
"checksum daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815"
|
||||||
"checksum docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
|
"checksum docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
|
||||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
||||||
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
|
|
||||||
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
|
|
||||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||||
|
@ -835,9 +729,6 @@ dependencies = [
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
|
|
||||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
|
||||||
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
|
|
||||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||||
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||||
|
@ -856,7 +747,6 @@ dependencies = [
|
||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||||
"checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac"
|
"checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac"
|
||||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
|
||||||
"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
|
"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
|
||||||
"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
|
"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
|
||||||
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
||||||
|
@ -867,7 +757,6 @@ dependencies = [
|
||||||
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
"checksum strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "032c03039aae92b350aad2e3779c352e104d919cb192ba2fabbd7b831ce4f0f6"
|
"checksum strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "032c03039aae92b350aad2e3779c352e104d919cb192ba2fabbd7b831ce4f0f6"
|
||||||
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
||||||
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
|
||||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "vpncloud"
|
name = "vpncloud"
|
||||||
version = "1.0.0"
|
version = "1.1.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"
|
||||||
|
@ -28,7 +28,6 @@ igd = "0.9"
|
||||||
siphasher = "0.3"
|
siphasher = "0.3"
|
||||||
daemonize = "0.4"
|
daemonize = "0.4"
|
||||||
ring = "0.16"
|
ring = "0.16"
|
||||||
base-62 = "0.1"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "^1"
|
cc = "^1"
|
||||||
|
|
|
@ -102,6 +102,4 @@ contributions are very welcome:
|
||||||
|
|
||||||
|
|
||||||
### Semantic Versioning
|
### Semantic Versioning
|
||||||
This project uses [semantic versioning](http://semver.org). Currently that means
|
This project uses [semantic versioning](http://semver.org).
|
||||||
that everything can change between versions before 1.0 is finally released.
|
|
||||||
However I am considering to release 1.0 soon.
|
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
vpncloud (1.1.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* [added] Exchange peer timeout and adapt keepalive accordingly
|
||||||
|
* [added] Reducing published peer timeout to 5 min when NAT is detected
|
||||||
|
* [added] Added more tests
|
||||||
|
* [changed] Rust version 1.41.0
|
||||||
|
* [changed] Updated dependencies
|
||||||
|
* [fixed] Fixed potential startup dependency issue
|
||||||
|
* [fixed] Fixed wrong base62 encoding
|
||||||
|
|
||||||
|
-- Dennis Schwerdel <schwerdel@googlemail.com> Thu, 04 Dec 2019 19:01:34 +0100
|
||||||
|
|
||||||
vpncloud (1.0.0) stable; urgency=medium
|
vpncloud (1.0.0) stable; urgency=medium
|
||||||
|
|
||||||
* [added] Added ability to publish small beacons for rendezvous
|
* [added] Added ability to publish small beacons for rendezvous
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=VpnCloud network '%I'
|
Description=VpnCloud network '%I'
|
||||||
Before=network-online.target
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
|
|
|
@ -9,7 +9,7 @@ RUN useradd -ms /bin/bash user
|
||||||
USER user
|
USER user
|
||||||
WORKDIR /home/user
|
WORKDIR /home/user
|
||||||
|
|
||||||
ENV RUST=1.33.0
|
ENV RUST=1.39.0
|
||||||
|
|
||||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ RUN useradd -ms /bin/bash user
|
||||||
USER user
|
USER user
|
||||||
WORKDIR /home/user
|
WORKDIR /home/user
|
||||||
|
|
||||||
ENV RUST=1.33.0
|
ENV RUST=1.39.0
|
||||||
|
|
||||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain ${RUST}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Copyright (C) 2019-2019 Dennis Schwerdel
|
// Copyright (C) 2019-2019 Dennis Schwerdel
|
||||||
// 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 base_62;
|
|
||||||
use ring::digest;
|
use ring::digest;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -21,7 +20,7 @@ use std::{
|
||||||
thread
|
thread
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::util::{Encoder, TimeSource};
|
use super::util::{from_base62, to_base62, Encoder, TimeSource};
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,11 +89,11 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin(&self) -> String {
|
fn begin(&self) -> String {
|
||||||
base_62::encode(&self.get_keystream(TYPE_BEGIN, 0, 0))[0..5].to_string()
|
to_base62(&self.get_keystream(TYPE_BEGIN, 0, 0))[0..5].to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(&self) -> String {
|
fn end(&self) -> String {
|
||||||
base_62::encode(&self.get_keystream(TYPE_END, 0, 0))[0..5].to_string()
|
to_base62(&self.get_keystream(TYPE_END, 0, 0))[0..5].to_string()
|
||||||
}
|
}
|
||||||
fn encrypt_data(&self, data: &mut Vec<u8>) {
|
fn encrypt_data(&self, data: &mut Vec<u8>) {
|
||||||
// Note: the 1 byte seed is only meant to protect from random changes,
|
// Note: the 1 byte seed is only meant to protect from random changes,
|
||||||
|
@ -152,11 +151,11 @@ impl<TS: TimeSource> BeaconSerializer<TS> {
|
||||||
data.extend_from_slice(&dat);
|
data.extend_from_slice(&dat);
|
||||||
}
|
}
|
||||||
self.encrypt_data(&mut data);
|
self.encrypt_data(&mut data);
|
||||||
base_62::encode(&data)
|
to_base62(&data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peerlist_decode(&self, data: &str, ttl_hours: Option<u16>) -> Vec<SocketAddr> {
|
fn peerlist_decode(&self, data: &str, ttl_hours: Option<u16>) -> Vec<SocketAddr> {
|
||||||
let mut data = base_62::decode(data).expect("Invalid input");
|
let mut data = from_base62(data).expect("Invalid input");
|
||||||
let mut peers = Vec::new();
|
let mut peers = Vec::new();
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
if data.len() < 4 {
|
if data.len() < 4 {
|
||||||
|
@ -327,13 +326,13 @@ fn encode() {
|
||||||
let mut peers = Vec::new();
|
let mut peers = Vec::new();
|
||||||
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
assert_eq!("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", ser.encode(&peers));
|
assert_eq!("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", ser.encode(&peers));
|
||||||
peers.push(SocketAddr::from_str("[::1]:5678").unwrap());
|
peers.push(SocketAddr::from_str("[::1]:5678").unwrap());
|
||||||
assert_eq!("juWwKjF5qZG7PE5imnpi5XARaXnP3UsMsGBLxM4FNFDzvjlKt1SO55LN", ser.encode(&peers));
|
assert_eq!("3hRD8BKvg7jotek0FGLeYtIc1zj7jzPRyQscQAe9tCqnFJ0vyVfIxYMB", ser.encode(&peers));
|
||||||
let mut peers = Vec::new();
|
let mut peers = Vec::new();
|
||||||
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:54").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:54").unwrap());
|
||||||
assert_eq!("juWwKIgSqTammVFRNoIVzLPO0BEO55LN", ser.encode(&peers));
|
assert_eq!("3hRD86NwMC5dPp8bh5idzhMal4AIxYMB", ser.encode(&peers));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -343,11 +342,11 @@ fn decode() {
|
||||||
let mut peers = Vec::new();
|
let mut peers = Vec::new();
|
||||||
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
assert_eq!(format!("{:?}", peers), format!("{:?}", ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None)));
|
assert_eq!(format!("{:?}", peers), format!("{:?}", ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", None)));
|
||||||
peers.push(SocketAddr::from_str("[::1]:5678").unwrap());
|
peers.push(SocketAddr::from_str("[::1]:5678").unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", peers),
|
format!("{:?}", peers),
|
||||||
format!("{:?}", ser.decode("juWwKjF5qZG7PE5imnpi5XARaXnP3UsMsGBLxM4FNFDzvjlKt1SO55LN", None))
|
format!("{:?}", ser.decode("3hRD8BKvg7jotek0FGLeYtIc1zj7jzPRyQscQAe9tCqnFJ0vyVfIxYMB", None))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,11 +359,11 @@ fn decode_split() {
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", peers),
|
format!("{:?}", peers),
|
||||||
format!("{:?}", ser.decode("juWwK-hj.VT:Yj bw\tJj\ntY(AZ)lM[fE]j7üIDäO55LN", None))
|
format!("{:?}", ser.decode("3hRD8-5V.3h:1P 0g\t5U\nn9(ZW)no[qR]Doü7ZäIxYMB", None))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", peers),
|
format!("{:?}", peers),
|
||||||
format!("{:?}", ser.decode("j -, \nuW--wKhjVTYjbwJjtYAZlMfEj7IDO(5}5ÖÄÜ\nLN", None))
|
format!("{:?}", ser.decode("3 -, \nhR--D85V3h1P0g5Un9ZWnoqRDo7ZI(x}YÖÄÜ\nMB", None))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +376,7 @@ fn decode_offset() {
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", peers),
|
format!("{:?}", peers),
|
||||||
format!("{:?}", ser.decode("Hello World: juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN! End of the World", None))
|
format!("{:?}", ser.decode("Hello World: 3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB! End of the World", None))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +389,7 @@ fn decode_multiple() {
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", peers),
|
format!("{:?}", peers),
|
||||||
format!("{:?}", ser.decode("juWwKkBEVBp9SsDiN3BO55LN juWwKtGGPQz1gXIBd68O55LN", None))
|
format!("{:?}", ser.decode("3hRD850fTOmqFffvcJEIxYMB 3hRD823uwTS47pupeONIxYMB", None))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,23 +401,23 @@ fn decode_ttl() {
|
||||||
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
peers.push(SocketAddr::from_str("1.2.3.4:5678").unwrap());
|
||||||
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
peers.push(SocketAddr::from_str("6.6.6.6:53").unwrap());
|
||||||
MockTimeSource::set_time(2000 * 3600);
|
MockTimeSource::set_time(2000 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", None).len());
|
||||||
MockTimeSource::set_time(2100 * 3600);
|
MockTimeSource::set_time(2100 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", None).len());
|
||||||
MockTimeSource::set_time(2005 * 3600);
|
MockTimeSource::set_time(2005 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", None).len());
|
||||||
MockTimeSource::set_time(1995 * 3600);
|
MockTimeSource::set_time(1995 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", None).len());
|
||||||
MockTimeSource::set_time(2000 * 3600);
|
MockTimeSource::set_time(2000 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", Some(24)).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", Some(24)).len());
|
||||||
MockTimeSource::set_time(1995 * 3600);
|
MockTimeSource::set_time(1995 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", Some(24)).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", Some(24)).len());
|
||||||
MockTimeSource::set_time(2005 * 3600);
|
MockTimeSource::set_time(2005 * 3600);
|
||||||
assert_eq!(2, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", Some(24)).len());
|
assert_eq!(2, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", Some(24)).len());
|
||||||
MockTimeSource::set_time(2100 * 3600);
|
MockTimeSource::set_time(2100 * 3600);
|
||||||
assert_eq!(0, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", Some(24)).len());
|
assert_eq!(0, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", Some(24)).len());
|
||||||
MockTimeSource::set_time(1900 * 3600);
|
MockTimeSource::set_time(1900 * 3600);
|
||||||
assert_eq!(0, ser.decode("juWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", Some(24)).len());
|
assert_eq!(0, ser.decode("3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB", Some(24)).len());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -426,12 +425,12 @@ fn decode_invalid() {
|
||||||
MockTimeSource::set_time(2000 * 3600);
|
MockTimeSource::set_time(2000 * 3600);
|
||||||
let ser = BeaconSerializer::<MockTimeSource>::new(b"vpnc", b"mysecretkey");
|
let ser = BeaconSerializer::<MockTimeSource>::new(b"vpnc", b"mysecretkey");
|
||||||
assert_eq!(0, ser.decode("", None).len());
|
assert_eq!(0, ser.decode("", None).len());
|
||||||
assert_eq!(0, ser.decode("juWwKO55LN", None).len());
|
assert_eq!(0, ser.decode("3hRD8IxYMB", None).len());
|
||||||
assert_eq!(0, ser.decode("juWwK--", None).len());
|
assert_eq!(0, ser.decode("3hRD8--", None).len());
|
||||||
assert_eq!(0, ser.decode("--O55LN", None).len());
|
assert_eq!(0, ser.decode("--IxYMB", None).len());
|
||||||
assert_eq!(0, ser.decode("juWwKhjVTYjbwJjtYAZXMfEj7IDO55LN", None).len());
|
assert_eq!(0, ser.decode("3hRD85V3h1P0g5Un8ZWnoqRDo7ZIxYMB", None).len());
|
||||||
assert_eq!(2, ser.decode("SGrivjuWwKhjVTYjbwJjtYAZlMfEj7IDO55LNjuWwK", None).len());
|
assert_eq!(2, ser.decode("IxYMB3hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMB3hRD8", None).len());
|
||||||
assert_eq!(2, ser.decode("juWwKjuWwKhjVTYjbwJjtYAZlMfEj7IDO55LN", None).len());
|
assert_eq!(2, ser.decode("3hRD83hRD85V3h1P0g5Un9ZWnoqRDo7ZIxYMBIxYMB", None).len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
36
src/cloud.rs
36
src/cloud.rs
|
@ -40,6 +40,7 @@ pub const STATS_INTERVAL: Time = 60;
|
||||||
|
|
||||||
struct PeerData {
|
struct PeerData {
|
||||||
timeout: Time,
|
timeout: Time,
|
||||||
|
peer_timeout: u16,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
alt_addrs: Vec<SocketAddr>
|
alt_addrs: Vec<SocketAddr>
|
||||||
}
|
}
|
||||||
|
@ -84,6 +85,10 @@ impl<TS: TimeSource> PeerList<TS> {
|
||||||
del
|
del
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn min_peer_timeout(&self) -> u16 {
|
||||||
|
self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(1800)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains_addr(&self, addr: &SocketAddr) -> bool {
|
pub fn contains_addr(&self, addr: &SocketAddr) -> bool {
|
||||||
self.addresses.contains_key(addr)
|
self.addresses.contains_key(addr)
|
||||||
|
@ -106,13 +111,14 @@ impl<TS: TimeSource> PeerList<TS> {
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&mut self, node_id: NodeId, addr: SocketAddr) {
|
fn add(&mut self, node_id: NodeId, addr: SocketAddr, peer_timeout: u16) {
|
||||||
if self.nodes.insert(node_id, addr).is_none() {
|
if self.nodes.insert(node_id, addr).is_none() {
|
||||||
info!("New peer: {}", addr);
|
info!("New peer: {}", addr);
|
||||||
self.peers.insert(addr, PeerData {
|
self.peers.insert(addr, PeerData {
|
||||||
timeout: TS::now() + Time::from(self.timeout),
|
timeout: TS::now() + Time::from(self.timeout),
|
||||||
node_id,
|
node_id,
|
||||||
alt_addrs: vec![]
|
alt_addrs: vec![],
|
||||||
|
peer_timeout
|
||||||
});
|
});
|
||||||
self.addresses.insert(addr, node_id);
|
self.addresses.insert(addr, node_id);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +227,8 @@ pub struct GenericCloud<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSou
|
||||||
device: D,
|
device: D,
|
||||||
crypto: Crypto,
|
crypto: Crypto,
|
||||||
next_peerlist: Time,
|
next_peerlist: Time,
|
||||||
update_freq: Duration,
|
peer_timeout_publish: u16,
|
||||||
|
update_freq: u16,
|
||||||
buffer_out: [u8; 64 * 1024],
|
buffer_out: [u8; 64 * 1024],
|
||||||
next_housekeep: Time,
|
next_housekeep: Time,
|
||||||
next_stats_out: Time,
|
next_stats_out: Time,
|
||||||
|
@ -249,6 +256,12 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err)
|
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err)
|
||||||
};
|
};
|
||||||
let now = TS::now();
|
let now = TS::now();
|
||||||
|
let peer_timeout_publish = if socket4.detect_nat() {
|
||||||
|
info!("Private IP detected, setting published peer timeout to 300s");
|
||||||
|
300
|
||||||
|
} else {
|
||||||
|
config.peer_timeout as u16
|
||||||
|
};
|
||||||
let mut res = GenericCloud {
|
let mut res = GenericCloud {
|
||||||
magic: config.get_magic(),
|
magic: config.get_magic(),
|
||||||
node_id: random(),
|
node_id: random(),
|
||||||
|
@ -258,12 +271,13 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
broadcast,
|
broadcast,
|
||||||
reconnect_peers: Vec::new(),
|
reconnect_peers: Vec::new(),
|
||||||
own_addresses: Vec::new(),
|
own_addresses: Vec::new(),
|
||||||
|
peer_timeout_publish,
|
||||||
table,
|
table,
|
||||||
socket4,
|
socket4,
|
||||||
socket6,
|
socket6,
|
||||||
device,
|
device,
|
||||||
next_peerlist: now,
|
next_peerlist: now,
|
||||||
update_freq: config.get_keepalive(),
|
update_freq: config.get_keepalive() as u16,
|
||||||
buffer_out: [0; 64 * 1024],
|
buffer_out: [0; 64 * 1024],
|
||||||
next_housekeep: now,
|
next_housekeep: now,
|
||||||
next_stats_out: now + STATS_INTERVAL,
|
next_stats_out: now + STATS_INTERVAL,
|
||||||
|
@ -408,7 +422,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
// Send a message to each resolved address
|
// Send a message to each resolved address
|
||||||
for a in resolve(&addr)? {
|
for a in resolve(&addr)? {
|
||||||
// Ignore error this time
|
// Ignore error this time
|
||||||
let mut msg = Message::Init(0, node_id, subnets.clone());
|
let mut msg = Message::Init(0, node_id, subnets.clone(), self.peer_timeout_publish);
|
||||||
self.send_msg(a, &mut msg).ok();
|
self.send_msg(a, &mut msg).ok();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -429,7 +443,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
debug!("Connecting to {:?}", addr);
|
debug!("Connecting to {:?}", addr);
|
||||||
let subnets = self.addresses.clone();
|
let subnets = self.addresses.clone();
|
||||||
let node_id = self.node_id;
|
let node_id = self.node_id;
|
||||||
let mut msg = Message::Init(0, node_id, subnets.clone());
|
let mut msg = Message::Init(0, node_id, subnets.clone(), self.peer_timeout_publish);
|
||||||
self.send_msg(addr, &mut msg)
|
self.send_msg(addr, &mut msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +480,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
let mut msg = Message::Peers(peers);
|
let mut msg = Message::Peers(peers);
|
||||||
self.broadcast_msg(&mut msg)?;
|
self.broadcast_msg(&mut msg)?;
|
||||||
// Reschedule for next update
|
// Reschedule for next update
|
||||||
|
self.update_freq = min(self.config.get_keepalive() as u16, self.peers.min_peer_timeout());
|
||||||
self.next_peerlist = now + Time::from(self.update_freq);
|
self.next_peerlist = now + Time::from(self.update_freq);
|
||||||
}
|
}
|
||||||
// Connect to those reconnect_peers that are due
|
// Connect to those reconnect_peers that are due
|
||||||
|
@ -697,7 +712,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
// Refresh peer
|
// Refresh peer
|
||||||
self.peers.refresh(&peer);
|
self.peers.refresh(&peer);
|
||||||
}
|
}
|
||||||
Message::Init(stage, node_id, ranges) => {
|
Message::Init(stage, node_id, ranges, peer_timeout) => {
|
||||||
// Avoid connecting to self
|
// Avoid connecting to self
|
||||||
if node_id == self.node_id {
|
if node_id == self.node_id {
|
||||||
self.own_addresses.push(peer);
|
self.own_addresses.push(peer);
|
||||||
|
@ -707,7 +722,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
if self.peers.contains_node(&node_id) {
|
if self.peers.contains_node(&node_id) {
|
||||||
self.peers.make_primary(node_id, peer);
|
self.peers.make_primary(node_id, peer);
|
||||||
} else {
|
} else {
|
||||||
self.peers.add(node_id, peer);
|
self.peers.add(node_id, peer, peer_timeout);
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
self.table.learn(range.base, Some(range.prefix_len), peer);
|
self.table.learn(range.base, Some(range.prefix_len), peer);
|
||||||
}
|
}
|
||||||
|
@ -716,7 +731,10 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
||||||
if stage == 0 {
|
if stage == 0 {
|
||||||
let own_addrs = self.addresses.clone();
|
let own_addrs = self.addresses.clone();
|
||||||
let own_node_id = self.node_id;
|
let own_node_id = self.node_id;
|
||||||
self.send_msg(peer, &mut Message::Init(stage + 1, own_node_id, own_addrs))?;
|
self.send_msg(
|
||||||
|
peer,
|
||||||
|
&mut Message::Init(stage + 1, own_node_id, own_addrs, self.peer_timeout_publish)
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
// Send peers in any case
|
// Send peers in any case
|
||||||
let peers = self.peers.as_vec();
|
let peers = self.peers.as_vec();
|
||||||
|
|
55
src/net.rs
55
src/net.rs
|
@ -1,10 +1,13 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::{HashMap, VecDeque},
|
||||||
io::{self, ErrorKind},
|
io::{self, ErrorKind},
|
||||||
net::{SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket},
|
net::{SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket},
|
||||||
os::unix::io::{AsRawFd, RawFd}
|
os::unix::io::{AsRawFd, RawFd},
|
||||||
|
sync::atomic::{AtomicBool, Ordering}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::util::{get_internal_ip, MockTimeSource, Time, TimeSource};
|
||||||
|
|
||||||
use net2::UdpBuilder;
|
use net2::UdpBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +17,7 @@ pub trait Socket: AsRawFd + Sized {
|
||||||
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error>;
|
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, 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 detect_nat(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket for UdpSocket {
|
impl Socket for UdpSocket {
|
||||||
|
@ -42,10 +46,18 @@ impl Socket for UdpSocket {
|
||||||
fn address(&self) -> Result<SocketAddr, io::Error> {
|
fn address(&self) -> Result<SocketAddr, io::Error> {
|
||||||
self.local_addr()
|
self.local_addr()
|
||||||
}
|
}
|
||||||
|
fn detect_nat(&self) -> bool {
|
||||||
|
get_internal_ip().is_private()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static MOCK_SOCKET_NAT: AtomicBool = AtomicBool::new(false);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MockSocket {
|
pub struct MockSocket {
|
||||||
|
nat: bool,
|
||||||
|
nat_peers: HashMap<SocketAddr, Time>,
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
outbound: VecDeque<(SocketAddr, Vec<u8>)>,
|
outbound: VecDeque<(SocketAddr, Vec<u8>)>,
|
||||||
inbound: VecDeque<(SocketAddr, Vec<u8>)>
|
inbound: VecDeque<(SocketAddr, Vec<u8>)>
|
||||||
|
@ -53,11 +65,36 @@ pub struct MockSocket {
|
||||||
|
|
||||||
impl MockSocket {
|
impl MockSocket {
|
||||||
pub fn new(address: SocketAddr) -> Self {
|
pub fn new(address: SocketAddr) -> Self {
|
||||||
Self { address, outbound: VecDeque::new(), inbound: VecDeque::new() }
|
Self {
|
||||||
|
nat: Self::get_nat(),
|
||||||
|
nat_peers: HashMap::new(),
|
||||||
|
address,
|
||||||
|
outbound: VecDeque::new(),
|
||||||
|
inbound: VecDeque::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_inbound(&mut self, from: SocketAddr, data: Vec<u8>) {
|
pub fn set_nat(nat: bool) {
|
||||||
self.inbound.push_back((from, data))
|
MOCK_SOCKET_NAT.with(|t| t.store(nat, Ordering::SeqCst))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nat() -> bool {
|
||||||
|
MOCK_SOCKET_NAT.with(|t| t.load(Ordering::SeqCst))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put_inbound(&mut self, from: SocketAddr, data: Vec<u8>) -> bool {
|
||||||
|
if !self.nat {
|
||||||
|
self.inbound.push_back((from, data));
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if let Some(timeout) = self.nat_peers.get(&from) {
|
||||||
|
if *timeout >= MockTimeSource::now() {
|
||||||
|
self.inbound.push_back((from, data));
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warn!("Sender {:?} is filtered out by NAT", from);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_outbound(&mut self) -> Option<(SocketAddr, Vec<u8>)> {
|
pub fn pop_outbound(&mut self) -> Option<(SocketAddr, Vec<u8>)> {
|
||||||
|
@ -85,14 +122,20 @@ impl Socket for MockSocket {
|
||||||
buffer[0..data.len()].copy_from_slice(&data);
|
buffer[0..data.len()].copy_from_slice(&data);
|
||||||
Ok((data.len(), addr))
|
Ok((data.len(), addr))
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::from(ErrorKind::UnexpectedEof))
|
Err(io::Error::new(ErrorKind::Other, "nothing in queue"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
|
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error> {
|
||||||
self.outbound.push_back((addr, data.to_owned()));
|
self.outbound.push_back((addr, data.to_owned()));
|
||||||
|
if self.nat {
|
||||||
|
self.nat_peers.insert(addr, MockTimeSource::now() + 300);
|
||||||
|
}
|
||||||
Ok(data.len())
|
Ok(data.len())
|
||||||
}
|
}
|
||||||
fn address(&self) -> Result<SocketAddr, io::Error> {
|
fn address(&self) -> Result<SocketAddr, io::Error> {
|
||||||
Ok(self.address)
|
Ok(self.address)
|
||||||
}
|
}
|
||||||
|
fn detect_nat(&self) -> bool {
|
||||||
|
self.nat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,13 @@
|
||||||
// Copyright (C) 2015-2019 Dennis Schwerdel
|
// Copyright (C) 2015-2019 Dennis Schwerdel
|
||||||
// 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 std::{
|
use std::{io, net::SocketAddrV4};
|
||||||
io,
|
|
||||||
net::{SocketAddr, SocketAddrV4, UdpSocket}
|
|
||||||
};
|
|
||||||
|
|
||||||
use igd::*;
|
use igd::*;
|
||||||
|
|
||||||
use super::util::{SystemTimeSource, Time, TimeSource};
|
use super::util::{get_internal_ip, SystemTimeSource, Time, TimeSource};
|
||||||
|
|
||||||
const LEASE_TIME: u32 = 300;
|
const LEASE_TIME: u32 = 1800;
|
||||||
const DESCRIPTION: &str = "VpnCloud";
|
const DESCRIPTION: &str = "VpnCloud";
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,16 +37,7 @@ impl PortForwarding {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
info!("Port-forwarding: found router at {}", gateway.addr);
|
info!("Port-forwarding: found router at {}", gateway.addr);
|
||||||
// Get the internal address (this trick gets the address by opening a UDP connection which
|
let internal_addr = SocketAddrV4::new(get_internal_ip(), port);
|
||||||
// does not really open anything but returns the correct address)
|
|
||||||
let dummy_sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
|
|
||||||
dummy_sock.connect(gateway.addr).expect("Failed to connect");
|
|
||||||
let internal_addr;
|
|
||||||
if let SocketAddr::V4(addr) = dummy_sock.local_addr().expect("Failed to get local address") {
|
|
||||||
internal_addr = SocketAddrV4::new(*addr.ip(), port);
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
// Query the external address
|
// Query the external address
|
||||||
let external_ip = match gateway.get_external_ip() {
|
let external_ip = match gateway.get_external_ip() {
|
||||||
Ok(ip) => ip,
|
Ok(ip) => ip,
|
||||||
|
|
|
@ -39,6 +39,20 @@ macro_rules! simulate {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! simulate_time {
|
||||||
|
($time:expr, $($node: expr => $addr: expr),*) => {
|
||||||
|
for _ in 0..$time {
|
||||||
|
use crate::util::{MockTimeSource, TimeSource};
|
||||||
|
MockTimeSource::set_time(MockTimeSource::now()+1);
|
||||||
|
$(
|
||||||
|
$node.trigger_housekeep();
|
||||||
|
)*
|
||||||
|
simulate(&mut [$((&mut $node, $addr)),*]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! assert_connected {
|
macro_rules! assert_connected {
|
||||||
($($node:expr),*) => {
|
($($node:expr),*) => {
|
||||||
for node1 in [$(&$node),*].iter() {
|
for node1 in [$(&$node),*].iter() {
|
||||||
|
|
|
@ -4,11 +4,18 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod helper;
|
mod helper;
|
||||||
|
mod nat;
|
||||||
mod payload;
|
mod payload;
|
||||||
mod peers;
|
mod peers;
|
||||||
|
|
||||||
pub use std::net::SocketAddr;
|
pub use std::net::SocketAddr;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::{
|
||||||
|
io::Write,
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
Once
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub use super::{
|
pub use super::{
|
||||||
cloud::GenericCloud,
|
cloud::GenericCloud,
|
||||||
|
@ -24,6 +31,37 @@ pub use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static INIT_LOGGER: Once = Once::new();
|
||||||
|
|
||||||
|
pub fn init_debug_logger() {
|
||||||
|
INIT_LOGGER.call_once(|| {
|
||||||
|
log::set_boxed_logger(Box::new(DebugLogger)).unwrap();
|
||||||
|
log::set_max_level(log::LevelFilter::Debug);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DebugLogger;
|
||||||
|
|
||||||
|
impl log::Log for DebugLogger {
|
||||||
|
#[inline]
|
||||||
|
fn enabled(&self, _metadata: &log::Metadata) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn log(&self, record: &log::Record) {
|
||||||
|
if self.enabled(record.metadata()) {
|
||||||
|
eprintln!("{} - {}", record.level(), record.args());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn flush(&self) {
|
||||||
|
std::io::stderr().flush().expect("Failed to flush")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type TestNode<P, T> = GenericCloud<MockDevice, P, T, MockSocket, MockTimeSource>;
|
type TestNode<P, T> = GenericCloud<MockDevice, P, T, MockSocket, MockTimeSource>;
|
||||||
|
|
||||||
type TapTestNode = TestNode<ethernet::Frame, SwitchTable<MockTimeSource>>;
|
type TapTestNode = TestNode<ethernet::Frame, SwitchTable<MockTimeSource>>;
|
||||||
|
@ -35,17 +73,19 @@ thread_local! {
|
||||||
static NEXT_PORT: AtomicUsize = AtomicUsize::new(1);
|
static NEXT_PORT: AtomicUsize = AtomicUsize::new(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_tap_node() -> TapTestNode {
|
fn create_tap_node(nat: bool) -> TapTestNode {
|
||||||
create_tap_node_with_config(Config::default())
|
create_tap_node_with_config(nat, Config::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_tap_node_with_config(mut config: Config) -> TapTestNode {
|
fn create_tap_node_with_config(nat: bool, mut config: Config) -> TapTestNode {
|
||||||
|
MockSocket::set_nat(nat);
|
||||||
config.port = NEXT_PORT.with(|p| p.fetch_add(1, Ordering::Relaxed)) as u16;
|
config.port = NEXT_PORT.with(|p| p.fetch_add(1, Ordering::Relaxed)) as u16;
|
||||||
TestNode::new(&config, MockDevice::new(), SwitchTable::new(1800, 10), true, true, vec![], Crypto::None, None)
|
TestNode::new(&config, MockDevice::new(), SwitchTable::new(1800, 10), true, true, vec![], Crypto::None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn create_tun_node(addresses: Vec<Range>) -> TunTestNode {
|
fn create_tun_node(nat: bool, addresses: Vec<Range>) -> TunTestNode {
|
||||||
|
MockSocket::set_nat(nat);
|
||||||
TestNode::new(
|
TestNode::new(
|
||||||
&Config { port: NEXT_PORT.with(|p| p.fetch_add(1, Ordering::Relaxed)) as u16, ..Config::default() },
|
&Config { port: NEXT_PORT.with(|p| p.fetch_add(1, Ordering::Relaxed)) as u16, ..Config::default() },
|
||||||
MockDevice::new(),
|
MockDevice::new(),
|
||||||
|
@ -73,13 +113,15 @@ fn msg6_get<P: Protocol, T: Table>(node: &mut TestNode<P, T>) -> (SocketAddr, Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg4_put<P: Protocol, T: Table>(node: &mut TestNode<P, T>, from: SocketAddr, msg: Vec<u8>) {
|
fn msg4_put<P: Protocol, T: Table>(node: &mut TestNode<P, T>, from: SocketAddr, msg: Vec<u8>) {
|
||||||
node.socket4().put_inbound(from, msg);
|
if node.socket4().put_inbound(from, msg) {
|
||||||
node.trigger_socket_v4_event();
|
node.trigger_socket_v4_event();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg6_put<P: Protocol, T: Table>(node: &mut TestNode<P, T>, from: SocketAddr, msg: Vec<u8>) {
|
fn msg6_put<P: Protocol, T: Table>(node: &mut TestNode<P, T>, from: SocketAddr, msg: Vec<u8>) {
|
||||||
node.socket6().put_inbound(from, msg);
|
if node.socket6().put_inbound(from, msg) {
|
||||||
node.trigger_socket_v6_event();
|
node.trigger_socket_v6_event();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simulate<P: Protocol, T: Table>(nodes: &mut [(&mut TestNode<P, T>, SocketAddr)]) {
|
fn simulate<P: Protocol, T: Table>(nodes: &mut [(&mut TestNode<P, T>, SocketAddr)]) {
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
// VpnCloud - Peer-to-Peer VPN
|
||||||
|
// Copyright (C) 2015-2019 Dennis Schwerdel
|
||||||
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connect_nat_2_peers() {
|
||||||
|
init_debug_logger();
|
||||||
|
MockTimeSource::set_time(0);
|
||||||
|
let mut node1 = create_tap_node(true);
|
||||||
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
|
let mut node2 = create_tap_node(false);
|
||||||
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
|
|
||||||
|
node2.connect("1.2.3.4:5678").unwrap();
|
||||||
|
|
||||||
|
simulate!(node1 => node1_addr, node2 => node2_addr);
|
||||||
|
|
||||||
|
assert!(!node1.peers().contains_node(&node2.node_id()));
|
||||||
|
assert!(!node2.peers().contains_node(&node1.node_id()));
|
||||||
|
|
||||||
|
|
||||||
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
|
simulate!(node1 => node1_addr, node2 => node2_addr);
|
||||||
|
|
||||||
|
assert_connected!(node1, node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn connect_nat_3_peers() {
|
||||||
|
init_debug_logger();
|
||||||
|
MockTimeSource::set_time(0);
|
||||||
|
let mut node1 = create_tap_node(true);
|
||||||
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
|
let mut node2 = create_tap_node(false);
|
||||||
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
|
let mut node3 = create_tap_node(false);
|
||||||
|
let node3_addr = addr!("3.4.5.6:7890");
|
||||||
|
node2.connect("1.2.3.4:5678").unwrap();
|
||||||
|
node3.connect("1.2.3.4:5678").unwrap();
|
||||||
|
simulate!(node1 => node1_addr, node2 => node2_addr, node3 => node3_addr);
|
||||||
|
|
||||||
|
assert!(!node1.peers().contains_node(&node2.node_id()));
|
||||||
|
assert!(!node2.peers().contains_node(&node1.node_id()));
|
||||||
|
assert!(!node3.peers().contains_node(&node1.node_id()));
|
||||||
|
assert!(!node3.peers().contains_node(&node2.node_id()));
|
||||||
|
assert!(!node1.peers().contains_node(&node3.node_id()));
|
||||||
|
assert!(!node2.peers().contains_node(&node3.node_id()));
|
||||||
|
|
||||||
|
node1.connect("3.4.5.6:7890").unwrap();
|
||||||
|
node2.connect("3.4.5.6:7890").unwrap();
|
||||||
|
|
||||||
|
simulate_time!(1000, node1 => node1_addr, node2 => node2_addr, node3 => node3_addr);
|
||||||
|
|
||||||
|
assert_connected!(node1, node3);
|
||||||
|
assert_connected!(node2, node3);
|
||||||
|
assert_connected!(node1, node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nat_keepalive() {
|
||||||
|
init_debug_logger();
|
||||||
|
MockTimeSource::set_time(0);
|
||||||
|
let mut node1 = create_tap_node(true);
|
||||||
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
|
let mut node2 = create_tap_node(false);
|
||||||
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
|
let mut node3 = create_tap_node(false);
|
||||||
|
let node3_addr = addr!("3.4.5.6:7890");
|
||||||
|
node1.connect("3.4.5.6:7890").unwrap();
|
||||||
|
node2.connect("3.4.5.6:7890").unwrap();
|
||||||
|
|
||||||
|
simulate_time!(1000, node1 => node1_addr, node2 => node2_addr, node3 => node3_addr);
|
||||||
|
|
||||||
|
assert_connected!(node1, node3);
|
||||||
|
assert_connected!(node2, node3);
|
||||||
|
assert_connected!(node1, node2);
|
||||||
|
|
||||||
|
simulate_time!(10000, node1 => node1_addr, node2 => node2_addr, node3 => node3_addr);
|
||||||
|
|
||||||
|
assert_connected!(node1, node3);
|
||||||
|
assert_connected!(node2, node3);
|
||||||
|
assert_connected!(node1, node2);
|
||||||
|
}
|
|
@ -6,9 +6,9 @@ use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ethernet_delivers() {
|
fn ethernet_delivers() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.2.3.4:5678");
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
|
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
@ -28,11 +28,11 @@ fn ethernet_delivers() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn switch_learns() {
|
fn switch_learns() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.2.3.4:5678");
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
let mut node3 = create_tap_node();
|
let mut node3 = create_tap_node(false);
|
||||||
let node3_addr = addr!("3.4.5.6:7890");
|
let node3_addr = addr!("3.4.5.6:7890");
|
||||||
|
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
|
@ -6,9 +6,9 @@ use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connect_v4() {
|
fn connect_v4() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.2.3.4:5678");
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
assert_clean!(node1, node2);
|
assert_clean!(node1, node2);
|
||||||
assert!(!node1.peers().contains_node(&node2.node_id()));
|
assert!(!node1.peers().contains_node(&node2.node_id()));
|
||||||
|
@ -17,24 +17,24 @@ fn connect_v4() {
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
// Node 1 -> Node 2: Init 0
|
// Node 1 -> Node 2: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
assert!(node2.peers().contains_node(&node1.node_id()));
|
assert!(node2.peers().contains_node(&node1.node_id()));
|
||||||
|
|
||||||
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
||||||
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![]));
|
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![], 1800));
|
||||||
assert!(node1.peers().contains_node(&node2.node_id()));
|
assert!(node1.peers().contains_node(&node2.node_id()));
|
||||||
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr]));
|
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr]));
|
||||||
assert_clean!(node2);
|
assert_clean!(node2);
|
||||||
|
|
||||||
// Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0
|
// Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr]));
|
||||||
assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert!(node1.own_addresses().contains(&node1_addr));
|
assert!(node1.own_addresses().contains(&node1_addr));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
|
|
||||||
// Node 2 -> Node 2: Init 0
|
// Node 2 -> Node 2: Init 0
|
||||||
assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![]));
|
assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![], 1800));
|
||||||
assert_clean!(node2);
|
assert_clean!(node2);
|
||||||
assert!(node2.own_addresses().contains(&node2_addr));
|
assert!(node2.own_addresses().contains(&node2_addr));
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ fn connect_v4() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn connect_v6() {
|
fn connect_v6() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("[::1]:5678");
|
let node1_addr = addr!("[::1]:5678");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("[::2]:6789");
|
let node2_addr = addr!("[::2]:6789");
|
||||||
|
|
||||||
node1.connect("[::2]:6789").unwrap();
|
node1.connect("[::2]:6789").unwrap();
|
||||||
|
@ -57,13 +57,13 @@ fn connect_v6() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cross_connect() {
|
fn cross_connect() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.1.1.1:1111");
|
let node1_addr = addr!("1.1.1.1:1111");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.2.2.2:2222");
|
let node2_addr = addr!("2.2.2.2:2222");
|
||||||
let mut node3 = create_tap_node();
|
let mut node3 = create_tap_node(false);
|
||||||
let node3_addr = addr!("3.3.3.3:3333");
|
let node3_addr = addr!("3.3.3.3:3333");
|
||||||
let mut node4 = create_tap_node();
|
let mut node4 = create_tap_node(false);
|
||||||
let node4_addr = addr!("4.4.4.4:4444");
|
let node4_addr = addr!("4.4.4.4:4444");
|
||||||
|
|
||||||
node1.connect("2.2.2.2:2222").unwrap();
|
node1.connect("2.2.2.2:2222").unwrap();
|
||||||
|
@ -98,10 +98,10 @@ fn connect_via_beacons() {
|
||||||
MockTimeSource::set_time(0);
|
MockTimeSource::set_time(0);
|
||||||
let beacon_path = "target/.vpncloud_test";
|
let beacon_path = "target/.vpncloud_test";
|
||||||
let mut node1 =
|
let mut node1 =
|
||||||
create_tap_node_with_config(Config { beacon_store: Some(beacon_path.to_string()), ..Config::default() });
|
create_tap_node_with_config(false, Config { beacon_store: Some(beacon_path.to_string()), ..Config::default() });
|
||||||
let node1_addr = node1.address().unwrap().0;
|
let node1_addr = node1.address().unwrap().0;
|
||||||
let mut node2 =
|
let mut node2 =
|
||||||
create_tap_node_with_config(Config { beacon_load: Some(beacon_path.to_string()), ..Config::default() });
|
create_tap_node_with_config(false, Config { beacon_load: Some(beacon_path.to_string()), ..Config::default() });
|
||||||
let node2_addr = addr!("2.2.2.2:2222");
|
let node2_addr = addr!("2.2.2.2:2222");
|
||||||
|
|
||||||
assert!(!node1.peers().contains_node(&node2.node_id()));
|
assert!(!node1.peers().contains_node(&node2.node_id()));
|
||||||
|
@ -122,9 +122,9 @@ fn connect_via_beacons() {
|
||||||
#[test]
|
#[test]
|
||||||
fn reconnect_after_timeout() {
|
fn reconnect_after_timeout() {
|
||||||
MockTimeSource::set_time(0);
|
MockTimeSource::set_time(0);
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.1.1.1:1111");
|
let node1_addr = addr!("1.1.1.1:1111");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.2.2.2:2222");
|
let node2_addr = addr!("2.2.2.2:2222");
|
||||||
|
|
||||||
node1.add_reconnect_peer("2.2.2.2:2222".to_string());
|
node1.add_reconnect_peer("2.2.2.2:2222".to_string());
|
||||||
|
@ -148,15 +148,15 @@ fn reconnect_after_timeout() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lost_init1() {
|
fn lost_init1() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.2.3.4:5678");
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
let mut node2 = create_tap_node();
|
let mut node2 = create_tap_node(false);
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
|
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
// Node 1 -> Node 2: Init 0
|
// Node 1 -> Node 2: Init 0
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
assert_clean!(node1);
|
assert_clean!(node1);
|
||||||
|
|
||||||
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
|
||||||
|
@ -170,14 +170,14 @@ fn lost_init1() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn wrong_magic() {
|
fn wrong_magic() {
|
||||||
let mut node1 = create_tap_node();
|
let mut node1 = create_tap_node(false);
|
||||||
let node1_addr = addr!("1.2.3.4:5678");
|
let node1_addr = addr!("1.2.3.4:5678");
|
||||||
let mut node2 =
|
let mut node2 =
|
||||||
create_tap_node_with_config(Config { magic: Some("hash:different".to_string()), ..Config::default() });
|
create_tap_node_with_config(false, Config { magic: Some("hash:different".to_string()), ..Config::default() });
|
||||||
let node2_addr = addr!("2.3.4.5:6789");
|
let node2_addr = addr!("2.3.4.5:6789");
|
||||||
node1.connect("2.3.4.5:6789").unwrap();
|
node1.connect("2.3.4.5:6789").unwrap();
|
||||||
|
|
||||||
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![]));
|
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800));
|
||||||
|
|
||||||
assert_clean!(node1, node2);
|
assert_clean!(node1, node2);
|
||||||
|
|
||||||
|
@ -204,3 +204,8 @@ fn remove_dead_peers() {
|
||||||
fn update_primary_address() {
|
fn update_primary_address() {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn automatic_peer_timeout() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
|
@ -53,9 +53,9 @@ impl TopHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Message<'a> {
|
pub enum Message<'a> {
|
||||||
Data(&'a mut [u8], usize, usize), // data, start, end
|
Data(&'a mut [u8], usize, usize), // data, start, end
|
||||||
Peers(Vec<SocketAddr>), // peers
|
Peers(Vec<SocketAddr>), // peers
|
||||||
Init(u8, NodeId, Vec<Range>), // step, node_id, ranges
|
Init(u8, NodeId, Vec<Range>, u16), // step, node_id, ranges
|
||||||
Close
|
Close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl<'a> Message<'a> {
|
||||||
match self {
|
match self {
|
||||||
Message::Data(_, start, end) => Message::Data(&mut [], start, end),
|
Message::Data(_, start, end) => Message::Data(&mut [], start, end),
|
||||||
Message::Peers(peers) => Message::Peers(peers),
|
Message::Peers(peers) => Message::Peers(peers),
|
||||||
Message::Init(step, node_id, ranges) => Message::Init(step, node_id, ranges),
|
Message::Init(step, node_id, ranges, timeout) => Message::Init(step, node_id, ranges, timeout),
|
||||||
Message::Close => Message::Close
|
Message::Close => Message::Close
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,15 @@ impl<'a> fmt::Debug for Message<'a> {
|
||||||
}
|
}
|
||||||
write!(formatter, "]")
|
write!(formatter, "]")
|
||||||
}
|
}
|
||||||
Message::Init(stage, ref node_id, ref peers) => {
|
Message::Init(stage, ref node_id, ref peers, ref peer_timeout) => {
|
||||||
write!(formatter, "Init(stage={}, node_id={}, {:?})", stage, bytes_to_hex(node_id), peers)
|
write!(
|
||||||
|
formatter,
|
||||||
|
"Init(stage={}, node_id={}, peer_timeout={}, {:?})",
|
||||||
|
stage,
|
||||||
|
bytes_to_hex(node_id),
|
||||||
|
peer_timeout,
|
||||||
|
peers
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Message::Close => write!(formatter, "Close")
|
Message::Close => write!(formatter, "Close")
|
||||||
}
|
}
|
||||||
|
@ -183,7 +190,12 @@ pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &Crypto) -> Re
|
||||||
pos += read;
|
pos += read;
|
||||||
addrs.push(range);
|
addrs.push(range);
|
||||||
}
|
}
|
||||||
Message::Init(stage, node_id, addrs)
|
let mut peer_timeout = 1800;
|
||||||
|
if data.len() >= pos + 2 {
|
||||||
|
peer_timeout = Encoder::read_u16(&data[pos..]);
|
||||||
|
// pos += 2; never read
|
||||||
|
}
|
||||||
|
Message::Init(stage, node_id, addrs, peer_timeout)
|
||||||
}
|
}
|
||||||
3 => Message::Close,
|
3 => Message::Close,
|
||||||
_ => return Err(Error::Parse("Unknown message type"))
|
_ => return Err(Error::Parse("Unknown message type"))
|
||||||
|
@ -198,7 +210,7 @@ pub fn encode<'a>(
|
||||||
let header_type = match msg {
|
let header_type = match msg {
|
||||||
Message::Data(_, _, _) => 0,
|
Message::Data(_, _, _) => 0,
|
||||||
Message::Peers(_) => 1,
|
Message::Peers(_) => 1,
|
||||||
Message::Init(_, _, _) => 2,
|
Message::Init(_, _, _, _) => 2,
|
||||||
Message::Close => 3
|
Message::Close => 3
|
||||||
};
|
};
|
||||||
let mut start = 64;
|
let mut start = 64;
|
||||||
|
@ -244,7 +256,7 @@ pub fn encode<'a>(
|
||||||
}
|
}
|
||||||
end = pos;
|
end = pos;
|
||||||
}
|
}
|
||||||
Message::Init(stage, ref node_id, ref ranges) => {
|
Message::Init(stage, ref node_id, ref ranges, peer_timeout) => {
|
||||||
let mut pos = start;
|
let mut pos = start;
|
||||||
assert!(buf.len() >= pos + 2 + NODE_ID_BYTES);
|
assert!(buf.len() >= pos + 2 + NODE_ID_BYTES);
|
||||||
buf[pos] = stage;
|
buf[pos] = stage;
|
||||||
|
@ -257,6 +269,8 @@ pub fn encode<'a>(
|
||||||
for range in ranges {
|
for range in ranges {
|
||||||
pos += range.write_to(&mut buf[pos..]);
|
pos += range.write_to(&mut buf[pos..]);
|
||||||
}
|
}
|
||||||
|
Encoder::write_u16(peer_timeout, &mut buf[pos..]);
|
||||||
|
pos += 2;
|
||||||
end = pos;
|
end = pos;
|
||||||
}
|
}
|
||||||
Message::Close => {}
|
Message::Close => {}
|
||||||
|
@ -299,9 +313,9 @@ impl<'a> PartialEq for Message<'a> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Init(step1, node_id1, ref ranges1) => {
|
Message::Init(step1, node_id1, ref ranges1, peer_timeout1) => {
|
||||||
if let Message::Init(step2, node_id2, ref ranges2) = *other {
|
if let Message::Init(step2, node_id2, ref ranges2, peer_timeout2) = *other {
|
||||||
step1 == step2 && node_id1 == node_id2 && ranges1 == ranges2
|
step1 == step2 && node_id1 == node_id2 && ranges1 == ranges2 && peer_timeout1 == peer_timeout2
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -421,15 +435,15 @@ fn udpmessage_init() {
|
||||||
Range { base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }, prefix_len: 16 },
|
Range { base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }, prefix_len: 16 },
|
||||||
];
|
];
|
||||||
let node_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
let node_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||||
let mut msg = Message::Init(0, node_id, addrs);
|
let mut msg = Message::Init(0, node_id, addrs, 1800);
|
||||||
let mut should = [
|
let mut should = [
|
||||||
118, 112, 110, 1, 0, 0, 0, 2, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 0, 1, 2, 3, 24, 6,
|
118, 112, 110, 1, 0, 0, 0, 2, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 0, 1, 2, 3, 24, 6,
|
||||||
0, 1, 2, 3, 4, 5, 16
|
0, 1, 2, 3, 4, 5, 16, 7, 8
|
||||||
];
|
];
|
||||||
{
|
{
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 1024];
|
||||||
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
|
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
|
||||||
assert_eq!(res.len(), 40);
|
assert_eq!(res.len(), 42);
|
||||||
for i in 0..res.len() {
|
for i in 0..res.len() {
|
||||||
assert_eq!(res[i], should[i]);
|
assert_eq!(res[i], should[i]);
|
||||||
}
|
}
|
||||||
|
@ -502,9 +516,9 @@ fn message_fmt() {
|
||||||
base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 },
|
base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 },
|
||||||
prefix_len: 16
|
prefix_len: 16
|
||||||
}
|
}
|
||||||
])
|
], 1800)
|
||||||
),
|
),
|
||||||
"Init(stage=0, node_id=000102030405060708090a0b0c0d0e0f, [0.1.2.3/24, 00:01:02:03:04:05/16])"
|
"Init(stage=0, node_id=000102030405060708090a0b0c0d0e0f, peer_timeout=1800, [0.1.2.3/24, 00:01:02:03:04:05/16])"
|
||||||
);
|
);
|
||||||
assert_eq!(format!("{:?}", Message::Close), "Close");
|
assert_eq!(format!("{:?}", Message::Close), "Close");
|
||||||
}
|
}
|
||||||
|
|
92
src/util.rs
92
src/util.rs
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt,
|
||||||
net::{SocketAddr, ToSocketAddrs},
|
net::{Ipv4Addr, SocketAddr, ToSocketAddrs, UdpSocket},
|
||||||
sync::atomic::{AtomicIsize, Ordering}
|
sync::atomic::{AtomicIsize, Ordering}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,11 +91,13 @@ macro_rules! fail {
|
||||||
($format:expr) => ( {
|
($format:expr) => ( {
|
||||||
use std::process;
|
use std::process;
|
||||||
error!($format);
|
error!($format);
|
||||||
|
log::logger().flush();
|
||||||
process::exit(-1);
|
process::exit(-1);
|
||||||
} );
|
} );
|
||||||
($format:expr, $( $arg:expr ),+) => ( {
|
($format:expr, $( $arg:expr ),+) => ( {
|
||||||
use std::process;
|
use std::process;
|
||||||
error!($format, $( $arg ),+ );
|
error!($format, $( $arg ),+ );
|
||||||
|
log::logger().flush();
|
||||||
process::exit(-1);
|
process::exit(-1);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -115,6 +117,18 @@ macro_rules! try_fail {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_internal_ip() -> Ipv4Addr {
|
||||||
|
// Get the internal address (this trick gets the address by opening a UDP connection which
|
||||||
|
// does not really open anything but returns the correct address)
|
||||||
|
let dummy_sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
|
||||||
|
dummy_sock.connect("8.8.8.8:53").expect("Failed to connect");
|
||||||
|
if let SocketAddr::V4(addr) = dummy_sock.local_addr().expect("Failed to get local address") {
|
||||||
|
*addr.ip()
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(unknown_lints, clippy::needless_pass_by_value)]
|
#[allow(unknown_lints, clippy::needless_pass_by_value)]
|
||||||
pub fn resolve<Addr: ToSocketAddrs + fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> {
|
pub fn resolve<Addr: ToSocketAddrs + fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> {
|
||||||
|
@ -235,3 +249,79 @@ impl TimeSource for MockTimeSource {
|
||||||
MOCK_TIME.with(|t| t.load(Ordering::SeqCst) as Time)
|
MOCK_TIME.with(|t| t.load(Ordering::SeqCst) as Time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Helper function that multiplies the base62 data in buf[0..buflen] by 16 and adds m to it
|
||||||
|
fn base62_add_mult_16(buf: &mut [u8], mut buflen: usize, m: u8) -> usize {
|
||||||
|
let mut d: usize = m as usize;
|
||||||
|
for i in 0..buflen {
|
||||||
|
d += buf[i] as usize * 16;
|
||||||
|
buf[i] = (d % 62) as u8;
|
||||||
|
d /= 62;
|
||||||
|
}
|
||||||
|
assert!(d < 62);
|
||||||
|
if d > 0 {
|
||||||
|
buf[buflen] = d as u8;
|
||||||
|
buflen += 1;
|
||||||
|
}
|
||||||
|
buflen
|
||||||
|
}
|
||||||
|
|
||||||
|
const BASE62: [char; 62] = [
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||||
|
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
|
||||||
|
];
|
||||||
|
|
||||||
|
pub fn to_base62(data: &[u8]) -> String {
|
||||||
|
let l = data.len();
|
||||||
|
let mut buf = vec![0; l * 2];
|
||||||
|
let mut buflen = 0;
|
||||||
|
for b in data {
|
||||||
|
buflen = base62_add_mult_16(&mut buf, buflen, b / 16);
|
||||||
|
buflen = base62_add_mult_16(&mut buf, buflen, b % 16);
|
||||||
|
}
|
||||||
|
buf[0..buflen].reverse();
|
||||||
|
let mut result = String::with_capacity(buflen);
|
||||||
|
for b in &buf[0..buflen] {
|
||||||
|
result.push(BASE62[*b as usize]);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
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)),
|
||||||
|
'A'..='Z' => ((c as usize) % ('A' as usize)) + 10,
|
||||||
|
'a'..='z' => ((c as usize) % ('a' as usize)) + 36,
|
||||||
|
_ => return Err(c)
|
||||||
|
};
|
||||||
|
for i in 0..buf.len() {
|
||||||
|
val += buf[i] as usize * 62;
|
||||||
|
buf[i] = (val % 256) as u8;
|
||||||
|
val /= 256;
|
||||||
|
}
|
||||||
|
if val > 0 {
|
||||||
|
buf.push(val as u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.reverse();
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn base62() {
|
||||||
|
assert_eq!("", to_base62(&[0]));
|
||||||
|
assert_eq!("z", to_base62(&[61]));
|
||||||
|
assert_eq!("10", to_base62(&[62]));
|
||||||
|
assert_eq!("48", to_base62(&[1, 0]));
|
||||||
|
assert_eq!("1Xp7Ke", to_base62(b"Test"));
|
||||||
|
assert!(from_base62("").unwrap().is_empty());
|
||||||
|
assert_eq!(vec![61], from_base62("z").unwrap());
|
||||||
|
assert_eq!(vec![62], from_base62("10").unwrap());
|
||||||
|
assert_eq!(vec![1, 0], from_base62("48").unwrap());
|
||||||
|
assert_eq!(b"Test".to_vec(), from_base62("1Xp7Ke").unwrap());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue