mirror of https://github.com/dswd/vpncloud.git
Support for port forwarding (closes #6)
This commit is contained in:
parent
ed9f464dbf
commit
0243859d5a
|
@ -4,12 +4,13 @@ This project follows [semantic versioning](http://semver.org).
|
|||
|
||||
### UNRELEASED
|
||||
|
||||
- [added] Support for automatic port forwarding via UPnP
|
||||
- [added] Added `-s` shorthand for `--subnet`
|
||||
- [added] Added support for YAML config file via `--config`
|
||||
- [added] Support for YAML config file via `--config`
|
||||
- [changed] Configurable magic header is now used instead of Network-ID (**incompatible**)
|
||||
- [changed] Clarified documentation on TUN netmasks
|
||||
- [fixed] Fixed documentation of listen parameter
|
||||
- [fixed] Fixed problem with multiple
|
||||
- [fixed] Fixed problem with multiple subnets
|
||||
- [fixed] Fixed problem with interrupted poll after suspend to ram
|
||||
|
||||
### v0.7.0 (2016-08-05)
|
||||
|
|
|
@ -7,6 +7,7 @@ dependencies = [
|
|||
"docopt 0.6.82 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -52,6 +53,15 @@ name = "cfg-if"
|
|||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.6.82"
|
||||
|
@ -73,6 +83,61 @@ name = "gcc"
|
|||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hpack"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "igd"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
|
@ -82,6 +147,11 @@ dependencies = [
|
|||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "language-tags"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.1"
|
||||
|
@ -97,6 +167,11 @@ name = "log"
|
|||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
|
@ -105,6 +180,14 @@ dependencies = [
|
|||
"libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.26"
|
||||
|
@ -130,6 +213,14 @@ dependencies = [
|
|||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.8"
|
||||
|
@ -187,6 +278,15 @@ dependencies = [
|
|||
"nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solicit"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.3.0"
|
||||
|
@ -219,6 +319,46 @@ dependencies = [
|
|||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "typeable"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
|
@ -248,6 +388,22 @@ dependencies = [
|
|||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmltree"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.3.3"
|
||||
|
@ -259,16 +415,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
|
||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||
"checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626"
|
||||
"checksum docopt 0.6.82 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20016093b4e545dccf6ad4a01099de0b695f9bc99b08210e68f6425db2d37d"
|
||||
"checksum fnv 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d3d4285d5aa1cf04504b7d8c2d1fdccf4586b56739499a04cc58663b2543cd30"
|
||||
"checksum gcc 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb000abd6df9df4c637f75190297ebe56c1d7e66b56bbf3b4aa7aece15f61a2"
|
||||
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
||||
"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae"
|
||||
"checksum hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "eb27e8a3e8f17ac43ffa41bbda9cf5ad3f9f13ef66fa4873409d4902310275f7"
|
||||
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
|
||||
"checksum igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c8c12b1795b8b168f577c45fa10379b3814dcb11b7ab702406001f0d63f40484"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||
"checksum libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "23e3757828fa702a20072c37ff47938e9dd331b92fac6e223d26d4b7a55f7ee2"
|
||||
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
|
||||
"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e"
|
||||
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||
"checksum mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c93a4bd787ddc6e7833c519b73a50883deb5863d76d9b71eb8216fb7f94e66"
|
||||
"checksum net2 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "5edf9cb6be97212423aed9413dd4729d62b370b5e1c571750e882cebbbc1e3e2"
|
||||
"checksum nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7bb1da2be7da3cbffda73fc681d509ffd9e665af478d2bee1907cee0bc64b2"
|
||||
"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
|
||||
"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa"
|
||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||
"checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
|
||||
|
@ -277,13 +443,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||
"checksum signal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "beb615e58999635b6063277cf520f2d88824955c1056cf4f166b0f55b218512d"
|
||||
"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2"
|
||||
"checksum strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e4d73a2c36a4d095ed1a6df5cbeac159863173447f7a82b3f4757426844ab825"
|
||||
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||
"checksum thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "55dd963dbaeadc08aa7266bf7f91c3154a7805e32bb94b820b769d2ef3b4744d"
|
||||
"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
|
||||
"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616"
|
||||
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
||||
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
|
||||
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
|
||||
"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119"
|
||||
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef"
|
||||
"checksum xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "472a9d37c7c53ab2391161df5b89b1f3bf76dab6ab150d7941ecbdd832282082"
|
||||
"checksum yaml-rust 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ebfe12f475ad59be6178ebf004d51e682022496535994f8d23fd7ed31084598c"
|
||||
|
|
|
@ -24,6 +24,7 @@ fnv = "1"
|
|||
net2 = "0.2"
|
||||
bitflags = "0.7"
|
||||
yaml-rust = "0.3"
|
||||
igd = "0.5"
|
||||
|
||||
[build-dependencies]
|
||||
gcc = "0.3"
|
||||
|
|
|
@ -35,6 +35,7 @@ somewhat stable state. VpnCloud features the following functionality:
|
|||
* High throughput and low additional latency (see [performance page](https://github.com/dswd/vpncloud.rs/wiki/Performance-Measurements))
|
||||
* Support for tunneled VLans (TAP device)
|
||||
* Option to hide protocol header
|
||||
* Automatic port forwarding via UPnP
|
||||
|
||||
|
||||
### Installing
|
||||
|
|
|
@ -152,7 +152,7 @@ fn epoll_wait(b: &mut Bencher) {
|
|||
fn handle_interface_data(b: &mut Bencher) {
|
||||
let mut node = GenericCloud::<Frame>::new(
|
||||
MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0,
|
||||
Box::new(SwitchTable::new(300)), 1800, true, true, vec![], Crypto::None
|
||||
Box::new(SwitchTable::new(300)), 1800, true, true, vec![], Crypto::None, None
|
||||
);
|
||||
let mut data = [0; 1500];
|
||||
data[105] = 45;
|
||||
|
@ -166,7 +166,7 @@ fn handle_interface_data(b: &mut Bencher) {
|
|||
fn handle_net_message(b: &mut Bencher) {
|
||||
let mut node = GenericCloud::<Frame>::new(
|
||||
MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0,
|
||||
Box::new(SwitchTable::new(300)), 1800, true, true, vec![], Crypto::None
|
||||
Box::new(SwitchTable::new(300)), 1800, true, true, vec![], Crypto::None, None
|
||||
);
|
||||
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1));
|
||||
let mut data = [0; 1500];
|
||||
|
|
|
@ -23,6 +23,7 @@ use super::types::{Table, Protocol, Range, Error, HeaderMagic, NodeId};
|
|||
use super::device::Device;
|
||||
use super::udpmessage::{encode, decode, Message};
|
||||
use super::crypto::Crypto;
|
||||
use super::port_forwarding::PortForwarding;
|
||||
use super::util::{now, Time, Duration, resolve};
|
||||
use super::poll::{self, Poll};
|
||||
|
||||
|
@ -170,6 +171,7 @@ pub struct GenericCloud<P: Protocol> {
|
|||
update_freq: Duration,
|
||||
buffer_out: [u8; 64*1024],
|
||||
next_housekeep: Time,
|
||||
port_forwarding: Option<PortForwarding>,
|
||||
_dummy_p: PhantomData<P>,
|
||||
}
|
||||
|
||||
|
@ -178,7 +180,7 @@ impl<P: Protocol> GenericCloud<P> {
|
|||
#[allow(too_many_arguments)]
|
||||
pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: Box<Table>,
|
||||
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
|
||||
crypto: Crypto) -> Self {
|
||||
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
|
||||
let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder")
|
||||
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("0.0.0.0", listen)) {
|
||||
Ok(socket) => socket,
|
||||
|
@ -208,6 +210,7 @@ impl<P: Protocol> GenericCloud<P> {
|
|||
update_freq: peer_timeout/2-60,
|
||||
buffer_out: [0; 64*1024],
|
||||
next_housekeep: now(),
|
||||
port_forwarding: port_forwarding,
|
||||
_dummy_p: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -347,6 +350,10 @@ impl<P: Protocol> GenericCloud<P> {
|
|||
self.table.remove_all(&peer);
|
||||
}
|
||||
self.table.housekeep();
|
||||
// Periodically extend the port-forwarding
|
||||
if let Some(ref mut pfw) = self.port_forwarding {
|
||||
pfw.check_extend();
|
||||
}
|
||||
// Periodically send peer list to peers
|
||||
let now = now();
|
||||
if self.next_peerlist <= now {
|
||||
|
|
|
@ -23,6 +23,7 @@ pub struct Config {
|
|||
pub mode: Mode,
|
||||
pub dst_timeout: Duration,
|
||||
pub subnets: Vec<String>,
|
||||
pub port_forwarding: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -34,7 +35,8 @@ impl Default for Config {
|
|||
magic: None,
|
||||
port: 3210, peers: vec![], peer_timeout: 1800,
|
||||
mode: Mode::Normal, dst_timeout: 300,
|
||||
subnets: vec![]
|
||||
subnets: vec![],
|
||||
port_forwarding: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +82,9 @@ impl Config {
|
|||
if let Some(mut val) = file.subnets {
|
||||
self.subnets.append(&mut val);
|
||||
}
|
||||
if let Some(val) = file.port_forwarding {
|
||||
self.port_forwarding = val;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn merge_args(&mut self, mut args: Args) {
|
||||
|
@ -122,6 +127,9 @@ impl Config {
|
|||
self.dst_timeout = val;
|
||||
}
|
||||
self.subnets.append(&mut args.flag_subnet);
|
||||
if args.flag_no_port_forwarding {
|
||||
self.port_forwarding = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_magic(&self) -> HeaderMagic {
|
||||
|
@ -160,4 +168,5 @@ pub struct ConfigFile {
|
|||
pub mode: Option<Mode>,
|
||||
pub dst_timeout: Option<Duration>,
|
||||
pub subnets: Option<Vec<String>>,
|
||||
pub port_forwarding: Option<bool>
|
||||
}
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -17,6 +17,7 @@ extern crate rand;
|
|||
extern crate fnv;
|
||||
extern crate net2;
|
||||
extern crate yaml_rust;
|
||||
extern crate igd;
|
||||
#[cfg(feature = "bench")] extern crate test;
|
||||
|
||||
#[macro_use] pub mod util;
|
||||
|
@ -30,6 +31,7 @@ pub mod device;
|
|||
pub mod poll;
|
||||
pub mod config;
|
||||
pub mod configfile;
|
||||
pub mod port_forwarding;
|
||||
#[cfg(test)] mod tests;
|
||||
#[cfg(feature = "bench")] mod benches;
|
||||
|
||||
|
@ -44,6 +46,7 @@ use ip::RoutingTable;
|
|||
use types::{Mode, Range, Table, Protocol, HeaderMagic};
|
||||
use cloud::GenericCloud;
|
||||
use crypto::{Crypto, CryptoMethod};
|
||||
use port_forwarding::PortForwarding;
|
||||
use util::Duration;
|
||||
use config::Config;
|
||||
|
||||
|
@ -72,7 +75,8 @@ pub struct Args {
|
|||
flag_quiet: bool,
|
||||
flag_ifup: Option<String>,
|
||||
flag_ifdown: Option<String>,
|
||||
flag_version: bool
|
||||
flag_version: bool,
|
||||
flag_no_port_forwarding: bool
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +135,12 @@ fn run<T: Protocol> (config: Config) {
|
|||
Some(key) => Crypto::from_shared_key(config.crypto, &key),
|
||||
None => Crypto::None
|
||||
};
|
||||
let mut cloud = GenericCloud::<T>::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto);
|
||||
let port_forwarding = if config.port_forwarding {
|
||||
PortForwarding::new(config.port)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut cloud = GenericCloud::<T>::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto, port_forwarding);
|
||||
if let Some(script) = config.ifup {
|
||||
run_script(script, cloud.ifname());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
use std::net::{SocketAddrV4, UdpSocket, SocketAddr};
|
||||
use std::io;
|
||||
|
||||
use igd::*;
|
||||
|
||||
use super::util::{Time, now};
|
||||
|
||||
const LEASE_TIME: u32 = 300;
|
||||
const DESCRIPTION: &'static str = "VpnCloud";
|
||||
|
||||
|
||||
pub struct PortForwarding {
|
||||
pub internal_addr: SocketAddrV4,
|
||||
pub external_addr: SocketAddrV4,
|
||||
pub gateway: Gateway,
|
||||
pub next_extension: Option<Time>,
|
||||
}
|
||||
|
||||
impl PortForwarding {
|
||||
pub fn new(port: u16) -> Option<Self> {
|
||||
// Get the gateway
|
||||
let gateway = match search_gateway() {
|
||||
Ok(gateway) => gateway,
|
||||
Err(err) => {
|
||||
if let SearchError::IoError(ref err) = err {
|
||||
if err.kind() == io::ErrorKind::WouldBlock { // Why this code?
|
||||
warn!("Port-forwarding: no router found");
|
||||
return None
|
||||
}
|
||||
}
|
||||
error!("Port-forwarding: failed to find router: {}", err);
|
||||
return None
|
||||
}
|
||||
};
|
||||
info!("Port-forwarding: found router at {}", gateway.addr);
|
||||
// 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(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
|
||||
let external_ip = match gateway.get_external_ip() {
|
||||
Ok(ip) => ip,
|
||||
Err(err) => {
|
||||
error!("Port-forwarding: failed to obtain external IP: {}", err);
|
||||
return None
|
||||
}
|
||||
};
|
||||
// Try to activate the port forwarding
|
||||
// - First with external port = internal port and timeout
|
||||
// - If the port is used, request any port
|
||||
// - If timeout is denied, try permanent forwarding
|
||||
info!("Port-forwarding: external IP is {}", external_ip);
|
||||
let (external_addr, timeout) = match gateway.add_port(PortMappingProtocol::UDP, internal_addr.port(), internal_addr, LEASE_TIME, DESCRIPTION) {
|
||||
Ok(()) => (SocketAddrV4::new(external_ip, internal_addr.port()), LEASE_TIME),
|
||||
Err(AddPortError::PortInUse) => match gateway.add_any_port(PortMappingProtocol::UDP, internal_addr, LEASE_TIME, DESCRIPTION) {
|
||||
Ok(port) => (SocketAddrV4::new(external_ip, port), LEASE_TIME),
|
||||
Err(AddAnyPortError::OnlyPermanentLeasesSupported) => match gateway.add_any_port(PortMappingProtocol::UDP, internal_addr, 0, DESCRIPTION) {
|
||||
Ok(port) => (SocketAddrV4::new(external_ip, port), 0),
|
||||
Err(err) => {
|
||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||
return None
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||
return None
|
||||
}
|
||||
},
|
||||
Err(AddPortError::OnlyPermanentLeasesSupported) => match gateway.add_port(PortMappingProtocol::UDP, internal_addr.port(), internal_addr, 0, DESCRIPTION) {
|
||||
Ok(()) => (SocketAddrV4::new(external_ip, internal_addr.port()), 0),
|
||||
Err(err) => {
|
||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||
return None
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||
return None
|
||||
}
|
||||
};
|
||||
info!("Port-forwarding: sucessfully activated port forward on {}, timeout: {}", external_addr, timeout);
|
||||
let next_extension = if timeout > 0 {
|
||||
Some(now() + timeout as Time - 60)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Some(PortForwarding {
|
||||
internal_addr: internal_addr,
|
||||
external_addr: external_addr,
|
||||
gateway: gateway,
|
||||
next_extension: next_extension
|
||||
})
|
||||
}
|
||||
|
||||
pub fn check_extend(&mut self) {
|
||||
if let Some(deadline) = self.next_extension {
|
||||
if deadline > now() {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
match self.gateway.add_port(PortMappingProtocol::UDP, self.external_addr.port(), self.internal_addr, LEASE_TIME, DESCRIPTION) {
|
||||
Ok(()) => debug!("Port-forwarding: extended port forwarding"),
|
||||
Err(err) => error!("Port-forwarding: failed to extend port forwarding: {}", err)
|
||||
};
|
||||
self.next_extension = Some(now() + LEASE_TIME as Time - 60);
|
||||
}
|
||||
|
||||
fn deactivate(&self) {
|
||||
match self.gateway.remove_port(PortMappingProtocol::UDP, self.external_addr.port()) {
|
||||
Ok(()) => info!("Port-forwarding: successfully deactivated port forwarding"),
|
||||
Err(err) => error!("Port-forwarding: failed to deactivate port forwarding: {}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PortForwarding {
|
||||
fn drop(&mut self) {
|
||||
self.deactivate()
|
||||
}
|
||||
}
|
|
@ -411,6 +411,7 @@ peer_timeout: 1800
|
|||
mode: normal
|
||||
subnets:
|
||||
- 10.0.1.0/24
|
||||
port_forwarding: true
|
||||
";
|
||||
assert_eq!(configfile::parse_str::<ConfigFile>(config_file).unwrap(), ConfigFile{
|
||||
device_type: Some(Type::Tun),
|
||||
|
@ -425,7 +426,8 @@ subnets:
|
|||
peer_timeout: Some(1800),
|
||||
mode: Some(Mode::Normal),
|
||||
dst_timeout: None,
|
||||
subnets: Some(vec!["10.0.1.0/24".to_string()])
|
||||
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
||||
port_forwarding: Some(true)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -445,7 +447,8 @@ fn config_merge() {
|
|||
peer_timeout: Some(1800),
|
||||
mode: Some(Mode::Normal),
|
||||
dst_timeout: None,
|
||||
subnets: Some(vec!["10.0.1.0/24".to_string()])
|
||||
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
||||
port_forwarding: None
|
||||
});
|
||||
assert_eq!(config, Config{
|
||||
device_type: Type::Tun,
|
||||
|
|
|
@ -23,6 +23,7 @@ Options:
|
|||
--ifup <command> A command to setup the network interface.
|
||||
--ifdown <command> A command to bring down the network
|
||||
interface.
|
||||
--no-port-forwarding Disable automatic port forward.
|
||||
-v, --verbose Print debug information.
|
||||
-q, --quiet Only print errors and warnings.
|
||||
-h, --help Display the help.
|
||||
|
|
|
@ -96,6 +96,11 @@ vpncloud(1) -- Peer-to-peer VPN
|
|||
The name of the allocated device will be available via the environment
|
||||
variable `IFNAME`.
|
||||
|
||||
* `--no-port-forwarding`:
|
||||
|
||||
Disable automatic port forward. If this option is not set, VpnCloud tries to
|
||||
detect a NAT router and automatically add a port forwarding to it.
|
||||
|
||||
* `-v`, `--verbose`:
|
||||
|
||||
Print debug information, including information for data being received and
|
||||
|
@ -239,6 +244,7 @@ detailed descriptions of the options.
|
|||
* `mode`: The mode of the VPN. Same as `--mode`
|
||||
* `dst_timeout`: Switch table entry timeout in seconds. Same as `--dst-timeout`
|
||||
* `subnets`: A list of local subnets to use. See `--subnet`
|
||||
* `port_forwarding`: Whether to activate port forwardig. See `--no-port-forwarding`
|
||||
|
||||
|
||||
### Example
|
||||
|
@ -256,6 +262,7 @@ peer_timeout: 1800
|
|||
mode: normal
|
||||
subnets:
|
||||
- 10.0.1.0/24
|
||||
port_forwarding: true
|
||||
|
||||
|
||||
## NETWORK PROTOCOL
|
||||
|
|
Loading…
Reference in New Issue