diff options
| author | Emīls <emils@mullvad.net> | 2021-05-06 10:46:04 +0100 |
|---|---|---|
| committer | Emīls <emils@mullvad.net> | 2021-05-12 13:57:35 +0100 |
| commit | d53c2926fdab33637f8f290acb07983cfe71e87c (patch) | |
| tree | f512d9eebc944514e018b327d14acc47210c9375 | |
| parent | 057e5966e24104be2f033abebe66729ab21f251d (diff) | |
| download | mullvadvpn-d53c2926fdab33637f8f290acb07983cfe71e87c.tar.xz mullvadvpn-d53c2926fdab33637f8f290acb07983cfe71e87c.zip | |
Use ICMP socket on Linux
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | Cargo.lock | 252 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 5 | ||||
| -rw-r--r-- | talpid-core/src/lib.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/ping_monitor/icmp.rs | 239 | ||||
| -rw-r--r-- | talpid-core/src/ping_monitor/mod.rs | 8 | ||||
| -rw-r--r-- | talpid-core/src/ping_monitor/win.rs | 120 |
7 files changed, 316 insertions, 312 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 32eec0f408..8595a44f6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ Line wrap the file at 100 chars. Th #### Linux - Only allow packets with the mark set to `0x6d6f6c65` to communicate with the relay server. Previously, bridges were expected to run as root instead. +- Use an ICMP socket instead of relying on a `ping` binary in `$PATH` to establish if a tunnel is + working. #### Android - Improve stability by running the UI and the tunnel management logic in separate processes. diff --git a/Cargo.lock b/Cargo.lock index 9d3b2f2c53..57d8b725ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ "android_log-sys", "env_logger 0.7.1", "lazy_static", - "log 0.4.14", + "log", ] [[package]] @@ -142,12 +142,6 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" - -[[package]] -name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" @@ -231,7 +225,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags 1.2.1", + "bitflags", "strsim 0.8.0", "textwrap", "unicode-width", @@ -447,7 +441,7 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", "humantime 1.3.0", - "log 0.4.14", + "log", "regex", "termcolor", ] @@ -460,7 +454,7 @@ checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" dependencies = [ "atty", "humantime 2.1.0", - "log 0.4.14", + "log", "regex", "termcolor", ] @@ -559,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065" dependencies = [ "colored", - "log 0.4.14", + "log", ] [[package]] @@ -592,7 +586,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" dependencies = [ - "bitflags 1.2.1", + "bitflags", "fsevent-sys", ] @@ -611,7 +605,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.2.1", + "bitflags", "fuchsia-zircon-sys", ] @@ -761,12 +755,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" [[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - -[[package]] name = "h2" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -908,7 +896,7 @@ dependencies = [ "ct-logs", "futures-util", "hyper", - "log 0.4.14", + "log", "rustls", "rustls-native-certs", "tokio", @@ -938,7 +926,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" dependencies = [ - "bitflags 1.2.1", + "bitflags", "inotify-sys", "libc", ] @@ -962,6 +950,15 @@ dependencies = [ ] [[package]] +name = "internet-checksum" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb330f277f0a5e05436ac5cc8188eea73a492532c8d7f58f3e335c0b6f28c7b" +dependencies = [ + "byteorder", +] + +[[package]] name = "ioctl-sys" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1019,7 +1016,7 @@ dependencies = [ "combine", "error-chain", "jni-sys", - "log 0.4.14", + "log", "walkdir", ] @@ -1110,15 +1107,6 @@ dependencies = [ [[package]] name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.14", -] - -[[package]] -name = "log" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" @@ -1132,7 +1120,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae0136257df209261daa18d6c16394757c63e032e27aafd8b07788b051082bef" dependencies = [ - "log 0.4.14", + "log", ] [[package]] @@ -1163,7 +1151,7 @@ dependencies = [ "iovec", "kernel32-sys", "libc", - "log 0.4.14", + "log", "miow 0.2.2", "net2", "slab", @@ -1177,7 +1165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ "lazycell", - "log 0.4.14", + "log", "mio", "slab", ] @@ -1188,7 +1176,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ - "log 0.4.14", + "log", "mio", "miow 0.3.6", "winapi 0.3.9", @@ -1234,7 +1222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6efb50a48dbacd112e7e847b9847fa530ec4a473ba6322a2f82c42ef333e226" dependencies = [ "libc", - "log 0.4.14", + "log", "mnl-sys", ] @@ -1287,7 +1275,7 @@ dependencies = [ "ipnetwork", "lazy_static", "libc", - "log 0.4.14", + "log", "log-panics", "mullvad-management-interface", "mullvad-paths", @@ -1329,7 +1317,7 @@ dependencies = [ "ipnetwork", "jnix", "lazy_static", - "log 0.4.14", + "log", "log-panics", "mullvad-daemon", "mullvad-paths", @@ -1370,7 +1358,7 @@ version = "0.1.0" dependencies = [ "dirs-next", "err-derive 0.3.0", - "log 0.4.14", + "log", ] [[package]] @@ -1407,7 +1395,7 @@ dependencies = [ "hyper", "hyper-rustls", "ipnetwork", - "log 0.4.14", + "log", "mullvad-types", "rand 0.7.3", "regex", @@ -1452,7 +1440,7 @@ dependencies = [ "ipnetwork", "jnix", "lazy_static", - "log 0.4.14", + "log", "regex", "serde", "serde_json", @@ -1501,7 +1489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2253105e60b35a3fb6cf342b56a45ee1c76ef4b1e68c59b08f813f24c3b7b469" dependencies = [ "anyhow", - "bitflags 1.2.1", + "bitflags", "byteorder", "libc", "netlink-packet-core", @@ -1528,7 +1516,7 @@ checksum = "31dfd4f1653ba8e1e2410b3def2313f3399d9b9f7ec3a8a6a8f2f670c3e58d71" dependencies = [ "bytes 0.5.6", "futures", - "log 0.4.14", + "log", "netlink-packet-core", "netlink-sys 0.5.0", "tokio", @@ -1542,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc9e9df13fd91bdd4b92bea93d5d2848c8035677c60fc3fee5dabddc02c3012e" dependencies = [ "libc", - "log 0.4.14", + "log", ] [[package]] @@ -1553,7 +1541,7 @@ checksum = "bf10c3ab67b9c09b42abb5a53ecb8ffdad160d6485b140a6f21f53ba5362042d" dependencies = [ "futures", "libc", - "log 0.4.14", + "log", "mio", "tokio", ] @@ -1564,9 +1552,9 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2453197ab3fcf147bf0ebd193557eeffa3998e6c84670eb8c9d86393bd09011f" dependencies = [ - "bitflags 1.2.1", + "bitflags", "err-derive 0.3.0", - "log 0.4.14", + "log", "nftnl-sys", ] @@ -1587,7 +1575,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" dependencies = [ - "bitflags 1.2.1", + "bitflags", "cc", "cfg-if 0.1.10", "libc", @@ -1599,7 +1587,7 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" dependencies = [ - "bitflags 1.2.1", + "bitflags", "cc", "cfg-if 1.0.0", "libc", @@ -1611,7 +1599,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ - "bitflags 1.2.1", + "bitflags", "cc", "cfg-if 1.0.0", "libc", @@ -1623,7 +1611,7 @@ version = "4.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" dependencies = [ - "bitflags 1.2.1", + "bitflags", "filetime", "fsevent", "fsevent-sys", @@ -1689,7 +1677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45d63bb4b48a4dc331d31e86aeac7e51b70e3d8d5a1626fe7642538cf4e126c3" dependencies = [ "derive-try-from-primitive", - "log 0.4.14", + "log", "serde", ] @@ -1711,7 +1699,7 @@ checksum = "fd7f6c69d7687501b2205fe51ade1d7b8797bb3aa141fe5bf13dd78c0483bc89" dependencies = [ "futures", "libc", - "log 0.4.14", + "log", "mio-named-pipes", "miow 0.3.6", "rand 0.7.3", @@ -1889,45 +1877,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] -name = "pnet_base" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cd5f7e15220afa66b0a9a62841ea10089f39dcaa1c29752c0b22dfc03111b5" - -[[package]] -name = "pnet_macros" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbd5c52c6e04aa720400f9c71cd0e8bcb38cd13421d5caabd9035e9efa47de9" -dependencies = [ - "regex", - "syntex", - "syntex_syntax", -] - -[[package]] -name = "pnet_macros_support" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf9c5c0c36766d0a4da9ab268c0700771b8ec367b9463fd678109fa28463c5b" -dependencies = [ - "pnet_base", -] - -[[package]] -name = "pnet_packet" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e26a864d71d0ac51a549cf40283c44ed1b8f98168545638a4730ef9f560283" -dependencies = [ - "glob", - "pnet_base", - "pnet_macros", - "pnet_macros_support", - "syntex", -] - -[[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1975,7 +1924,7 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ - "unicode-xid 0.2.1", + "unicode-xid", ] [[package]] @@ -1997,7 +1946,7 @@ dependencies = [ "bytes 0.5.6", "heck", "itertools 0.8.2", - "log 0.4.14", + "log", "multimap", "petgraph", "prost", @@ -2042,7 +1991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger 0.8.2", - "log 0.4.14", + "log", "rand 0.8.3", ] @@ -2169,7 +2118,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" dependencies = [ - "bitflags 1.2.1", + "bitflags", ] [[package]] @@ -2247,7 +2196,7 @@ checksum = "0c942df3c7725a0500971d857a080d6dc537e257e19ccb352f80b2c726ef7007" dependencies = [ "byteordered", "futures", - "log 0.4.14", + "log", "netlink-packet-route", "netlink-proto", "thiserror", @@ -2260,19 +2209,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" [[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" - -[[package]] name = "rustls" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" dependencies = [ "base64 0.12.3", - "log 0.4.14", + "log", "ring", "sct", "webpki", @@ -2343,7 +2286,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad502866817f0575705bd7be36e2b2535cc33262d493aa733a2ec862baa2bc2b" dependencies = [ - "bitflags 1.2.1", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2375,7 +2318,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0bf1ba0696ccf0872866277143ff1fd14d22eec235d2b23702f95e6660f7dfa" dependencies = [ - "log 0.4.14", + "log", "serde", "thiserror", "xml-rs", @@ -2523,7 +2466,7 @@ checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", - "unicode-xid 0.2.1", + "unicode-xid", ] [[package]] @@ -2535,56 +2478,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "unicode-xid 0.2.1", -] - -[[package]] -name = "syntex" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a30b08a6b383a22e5f6edc127d169670d48f905bb00ca79a00ea3e442ebe317" -dependencies = [ - "syntex_errors", - "syntex_syntax", -] - -[[package]] -name = "syntex_errors" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c48f32867b6114449155b2a82114b86d4b09e1bddb21c47ff104ab9172b646" -dependencies = [ - "libc", - "log 0.3.9", - "rustc-serialize", - "syntex_pos", - "term", - "unicode-xid 0.0.3", -] - -[[package]] -name = "syntex_pos" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd49988e52451813c61fecbe9abb5cfd4e1b7bb6cdbb980a6fbcbab859171a6" -dependencies = [ - "rustc-serialize", -] - -[[package]] -name = "syntex_syntax" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7628a0506e8f9666fdabb5f265d0059b059edac9a3f810bda077abb5d826bd8d" -dependencies = [ - "bitflags 0.5.0", - "libc", - "log 0.3.9", - "rustc-serialize", - "syntex_errors", - "syntex_pos", - "term", - "unicode-xid 0.0.3", + "unicode-xid", ] [[package]] @@ -2593,7 +2487,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd4bc0637a2b8c0b1a5145cca3e21b707865edc7e32285771536af1ade129468" dependencies = [ - "bitflags 1.2.1", + "bitflags", "core-foundation", "system-configuration-sys", ] @@ -2621,11 +2515,12 @@ dependencies = [ "failure", "futures", "hex", + "internet-checksum", "ipnetwork", "jnix", "lazy_static", "libc", - "log 0.4.14", + "log", "mnl", "netlink-packet-core", "netlink-packet-route", @@ -2640,7 +2535,6 @@ dependencies = [ "parity-tokio-ipc", "parking_lot", "pfctl", - "pnet_packet", "prost", "quickcheck", "quickcheck_macros", @@ -2677,7 +2571,7 @@ dependencies = [ "err-derive 0.3.0", "lazy_static", "libc", - "log 0.4.14", + "log", "talpid-types", ] @@ -2687,7 +2581,7 @@ version = "2021.3.0" dependencies = [ "env_logger 0.8.2", "err-derive 0.3.0", - "log 0.4.14", + "log", "openvpn-plugin", "parity-tokio-ipc", "prost", @@ -2737,16 +2631,6 @@ dependencies = [ ] [[package]] -name = "term" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" -dependencies = [ - "kernel32-sys", - "winapi 0.2.8", -] - -[[package]] name = "termcolor" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2859,7 +2743,7 @@ dependencies = [ "bytes 0.5.6", "futures-core", "futures-sink", - "log 0.4.14", + "log", "pin-project-lite 0.1.12", "tokio", ] @@ -2873,7 +2757,7 @@ dependencies = [ "bytes 0.5.6", "futures-core", "futures-sink", - "log 0.4.14", + "log", "pin-project-lite 0.1.12", "tokio", ] @@ -3021,7 +2905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cc79fc3afd07492b7966d7efa7c6c50f8ed58d768a6075dd7ae6591c5d2017b" dependencies = [ "futures-core", - "log 0.4.14", + "log", "pin-project 0.4.27", "tokio", "tower-discover", @@ -3059,7 +2943,7 @@ dependencies = [ "futures-core", "futures-util", "indexmap", - "log 0.4.14", + "log", "tokio", "tower-service", ] @@ -3114,7 +2998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" dependencies = [ "cfg-if 1.0.0", - "log 0.4.14", + "log", "pin-project-lite 0.2.6", "tracing-attributes", "tracing-core", @@ -3198,7 +3082,7 @@ dependencies = [ "env_logger 0.7.1", "err-context", "futures", - "log 0.4.14", + "log", "nix 0.20.0", "structopt", "tokio", @@ -3218,12 +3102,6 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" - -[[package]] -name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" @@ -3293,7 +3171,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.14", + "log", "try-lock", ] @@ -3327,7 +3205,7 @@ checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.14", + "log", "proc-macro2", "quote", "syn", @@ -3457,7 +3335,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdfb0437cd780b66551aa81b466470f1159b1878ed45438b738de8bc6e5012b6" dependencies = [ - "bitflags 1.2.1", + "bitflags", "err-derive 0.2.4", "widestring", "winapi 0.3.9", diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 5413634702..6f0c60c08d 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -62,6 +62,8 @@ mnl = { version = "0.2.0", features = ["mnl-1-0-4"] } which = { version = "4.0", default-features = false } tun = "0.5.1" talpid-dbus = { path = "../talpid-dbus" } +socket2 = "0.3" +internet-checksum = "0.2" [target.'cfg(target_os = "macos")'.dependencies] @@ -71,11 +73,12 @@ tun = "0.5.1" [target.'cfg(windows)'.dependencies] +byteorder = "1" +internet-checksum = "0.2" widestring = "0.4" winreg = { version = "0.7", features = ["transactions"] } winapi = { version = "0.3.6", features = ["combaseapi", "handleapi", "ifdef", "libloaderapi", "netioapi", "stringapiset", "synchapi", "winbase", "winerror", "winuser"] } socket2 = "0.3" -pnet_packet = "0.26" talpid-platform-metadata = { path = "../talpid-platform-metadata" } [build-dependencies] diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs index fbf06c8815..e4ac42857b 100644 --- a/talpid-core/src/lib.rs +++ b/talpid-core/src/lib.rs @@ -60,4 +60,4 @@ mod mktemp; mod linux; /// A pair of functions to monitor and establish connectivity with ICMP -mod ping_monitor; +pub mod ping_monitor; diff --git a/talpid-core/src/ping_monitor/icmp.rs b/talpid-core/src/ping_monitor/icmp.rs new file mode 100644 index 0000000000..2965231219 --- /dev/null +++ b/talpid-core/src/ping_monitor/icmp.rs @@ -0,0 +1,239 @@ +use byteorder::{NetworkEndian, WriteBytesExt}; +use rand::Rng; +use socket2::{Domain, Protocol, Socket, Type}; +#[cfg(target_os = "linux")] +use std::ffi::CString; +use std::{ + io::{self, Write}, + net::{Ipv4Addr, SocketAddr}, + thread, + time::Duration, +}; + +const SEND_RETRY_ATTEMPTS: u32 = 10; + +/// Pinger errors +#[derive(err_derive::Error, Debug)] +#[error(no_from)] +pub enum Error { + /// Failed to open raw socket + #[error(display = "Failed to open ICMP socket")] + OpenError(#[error(source)] io::Error), + + /// Failed to read from raw socket + #[error(display = "Failed to read ICMP socket")] + ReadError(#[error(source)] io::Error), + + /// Failed to set socket options + #[error(display = "Failed to set socket options")] + SocketOptError(#[error(source)] io::Error), + + /// Failed to write to raw socket + #[error(display = "Failed to write to socket")] + WriteError(#[error(source)] io::Error), + + /// ICMP buffer too small + #[error(display = "ICMP message buffer too small")] + BufferTooSmall, + + /// Interface name contains null bytes + #[error(display = "Interface name contains a null byte")] + InterfaceNameContainsNull, +} + +type Result<T> = std::result::Result<T, Error>; + +pub struct Pinger { + sock: Socket, + addr: SocketAddr, + id: u16, + seq: u16, +} + +impl Pinger { + #[cfg(target_os = "windows")] + pub fn new(addr: Ipv4Addr, _interface_name: String) -> Result<Self> { + let addr = SocketAddr::new(addr.into(), 0); + let sock = Socket::new(Domain::ipv4(), Type::raw(), Some(Protocol::icmpv4())) + .map_err(Error::OpenError)?; + sock.set_nonblocking(true).map_err(Error::OpenError)?; + + Ok(Self { + sock, + id: rand::random(), + addr, + seq: 0, + }) + } + + #[cfg(target_os = "linux")] + pub fn new(addr: Ipv4Addr, interface_name: String) -> Result<Self> { + let addr = SocketAddr::new(addr.into(), 0); + let sock = Socket::new(Domain::ipv4(), Type::raw(), Some(Protocol::icmpv4())) + .map_err(Error::OpenError)?; + sock.set_nonblocking(true).map_err(Error::OpenError)?; + + let cname = CString::new(interface_name.as_bytes().to_vec()) + .map_err(|_| Error::InterfaceNameContainsNull)?; + sock.bind_device(Some(&cname)) + .map_err(Error::SocketOptError)?; + + Ok(Self { + addr, + sock, + seq: 0, + id: rand::random(), + }) + } + + fn send_ping_request(&mut self, message: &[u8], destination: SocketAddr) -> Result<()> { + let mut tries = 0; + let mut result = Ok(()); + while tries < SEND_RETRY_ATTEMPTS { + match self.sock.send_to(message, &destination.into()) { + Ok(_) => { + return Ok(()); + } + Err(err) => { + if Some(10065) != err.raw_os_error() { + return Err(Error::WriteError(err)); + } + result = Err(Error::WriteError(err)); + } + } + thread::sleep(Duration::from_secs(1)); + tries += 1; + } + result + } + + fn construct_icmpv4_packet(&mut self, buffer: &mut [u8]) -> Result<()> { + if !construct_icmpv4_packet_inner(buffer, self) { + return Err(Error::BufferTooSmall); + } + Ok(()) + } +} + +impl super::Pinger for Pinger { + fn send_icmp(&mut self) -> Result<()> { + let mut message = [0u8; 50]; + self.construct_icmpv4_packet(&mut message)?; + self.send_ping_request(&message, self.addr) + } +} + +trait PayloadWriter { + fn packet_id(&mut self) -> u16; + fn sequence_num(&mut self) -> u16; + fn write_payload(&mut self, buffer: &mut [u8]); +} + +impl PayloadWriter for Pinger { + fn packet_id(&mut self) -> u16 { + self.id + } + + fn sequence_num(&mut self) -> u16 { + let seq = self.seq; + self.seq += 1; + seq + } + + fn write_payload(&mut self, buffer: &mut [u8]) { + rand::thread_rng().fill(buffer); + } +} + +fn construct_icmpv4_packet_inner( + buffer: &mut [u8], + packet_writer: &mut impl PayloadWriter, +) -> bool { + const ICMP_CHECKSUM_OFFSET: usize = 2; + if buffer.len() < 14 { + return false; + } + + let mut writer = &mut buffer[..]; + // ICMP type - Echo (ping) request + writer.write_u8(0x08).unwrap(); + // Code - 0 + writer.write_u8(0x00).unwrap(); + // Checksum -filled in later + writer.write_u16::<NetworkEndian>(0x000).unwrap(); + // packet ID + writer + .write_u16::<NetworkEndian>(packet_writer.packet_id()) + .unwrap(); + // packet sequence number + writer + .write_u16::<NetworkEndian>(packet_writer.sequence_num()) + .unwrap(); + // payload + packet_writer.write_payload(writer); + + let checksum = internet_checksum::checksum(buffer); + (&mut buffer[ICMP_CHECKSUM_OFFSET..]) + .write(&checksum) + .unwrap(); + + true +} + +#[cfg(test)] +mod test { + use super::*; + + struct TestPayload {} + + impl PayloadWriter for TestPayload { + fn packet_id(&mut self) -> u16 { + 0x1dcd + } + + fn sequence_num(&mut self) -> u16 { + 0x0001 + } + + fn write_payload(&mut self, mut buffer: &mut [u8]) { + let _ = buffer.write(&[ + 0xb6, 0xe0, 0x87, 0x60, 0x00, 0x00, 0x00, 0x00, 0x97, 0xad, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + ]); + } + } + + #[test] + fn test_icmpv4_packet() { + // captured from a plain `ping -4 127.1` + let expected_packet = [ + // ICMP type - echo request + 0x08, // Code 0 + 0x00, // checksum + 0x3c, 0x70, // packet ID + 0x1d, 0xcd, // sequence number + 0x00, 0x01, // payload + 0xb6, 0xe0, 0x87, 0x60, 0x00, 0x00, 0x00, 0x00, 0x97, 0xad, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + ]; + + let mut buffer = [0u8; 64]; + assert!(construct_icmpv4_packet_inner( + &mut buffer[..], + &mut TestPayload {} + )); + assert_eq!(buffer, expected_packet); + } + + #[test] + fn test_icmpv4_packet_too_short() { + assert!(!construct_icmpv4_packet_inner( + &mut [0u8; 13], + &mut TestPayload {} + )); + } +} diff --git a/talpid-core/src/ping_monitor/mod.rs b/talpid-core/src/ping_monitor/mod.rs index c5e2a256e5..2a6f5afbee 100644 --- a/talpid-core/src/ping_monitor/mod.rs +++ b/talpid-core/src/ping_monitor/mod.rs @@ -1,14 +1,15 @@ -#[cfg(any(target_os = "android", target_os = "macos", target_os = "linux"))] +#[cfg(any(target_os = "android", target_os = "macos"))] #[path = "unix.rs"] mod imp; -#[cfg(target_os = "windows")] -#[path = "win.rs"] +#[cfg(any(target_os = "windows", target_os = "linux"))] +#[path = "icmp.rs"] mod imp; pub use imp::Error; +/// Trait for sending ICMP requests to get some traffic from a remote server pub trait Pinger: Send { /// Sends an ICMP packet fn send_icmp(&mut self) -> Result<(), Error>; @@ -16,6 +17,7 @@ pub trait Pinger: Send { fn reset(&mut self) {} } +/// Create a new pinger pub fn new_pinger( addr: std::net::Ipv4Addr, interface_name: String, diff --git a/talpid-core/src/ping_monitor/win.rs b/talpid-core/src/ping_monitor/win.rs deleted file mode 100644 index e2564b3943..0000000000 --- a/talpid-core/src/ping_monitor/win.rs +++ /dev/null @@ -1,120 +0,0 @@ -use pnet_packet::{ - icmp::{ - self, - echo_request::{EchoRequestPacket, MutableEchoRequestPacket}, - IcmpCode, IcmpPacket, IcmpType, - }, - Packet, -}; -use socket2::{Domain, Protocol, Socket, Type}; -use std::{ - io, - net::{IpAddr, Ipv4Addr, SocketAddr}, - thread, - time::Duration, -}; - -const SEND_RETRY_ATTEMPTS: u32 = 10; - -#[derive(err_derive::Error, Debug)] -#[error(no_from)] -pub enum Error { - /// Failed to open raw socket - #[error(display = "Failed to open raw socket")] - OpenError(#[error(source)] io::Error), - - /// Failed to read from raw socket - #[error(display = "Failed to read from socket")] - ReadError(#[error(source)] io::Error), - - /// Failed to write to raw socket - #[error(display = "Failed to write to socket")] - WriteError(#[error(source)] io::Error), - - #[error(display = "Timed out")] - TimeoutError, -} - -type Result<T> = std::result::Result<T, Error>; - -pub struct Pinger { - sock: Socket, - addr: Ipv4Addr, - id: u16, - seq: u16, -} - - -impl Pinger { - pub fn new(addr: Ipv4Addr, _interface_name: String) -> Result<Self> { - let sock = Socket::new(Domain::ipv4(), Type::raw(), Some(Protocol::icmpv4())) - .map_err(Error::OpenError)?; - sock.set_nonblocking(true).map_err(Error::OpenError)?; - - - Ok(Self { - sock, - id: rand::random(), - addr, - seq: 0, - }) - } - - fn send_ping_request( - &mut self, - request: &EchoRequestPacket<'static>, - destination: SocketAddr, - ) -> Result<()> { - let mut tries = 0; - let mut result = Ok(()); - while tries < SEND_RETRY_ATTEMPTS { - match self.sock.send_to(request.packet(), &destination.into()) { - Ok(_) => { - return Ok(()); - } - Err(err) => { - if Some(10065) != err.raw_os_error() { - return Err(Error::WriteError(err)); - } - result = Err(Error::WriteError(err)); - } - } - thread::sleep(Duration::from_secs(1)); - tries += 1; - } - result - } - - /// returns the next ping packet - fn next_ping_request(&mut self) -> EchoRequestPacket<'static> { - use rand::Rng; - const ICMP_HEADER_LENGTH: usize = 8; - const ICMP_PAYLOAD_LENGTH: usize = 150; - const ICMP_PACKET_LENGTH: usize = ICMP_HEADER_LENGTH + ICMP_PAYLOAD_LENGTH; - let mut payload = [0u8; ICMP_PAYLOAD_LENGTH]; - rand::thread_rng().fill(&mut payload[..]); - let mut packet = MutableEchoRequestPacket::owned(vec![0u8; ICMP_PACKET_LENGTH]) - .expect("Failed to construct an empty packet"); - packet.set_icmp_type(IcmpType::new(8)); - packet.set_icmp_code(IcmpCode::new(0)); - packet.set_sequence_number(self.next_seq()); - packet.set_identifier(self.id); - packet.set_payload(&payload); - packet.set_checksum(icmp::checksum(&IcmpPacket::new(&packet.packet()).unwrap())); - packet.consume_to_immutable() - } - - fn next_seq(&mut self) -> u16 { - let seq = self.seq; - self.seq += 1; - seq - } -} - -impl super::Pinger for Pinger { - fn send_icmp(&mut self) -> Result<()> { - let dest = SocketAddr::new(IpAddr::from(self.addr), 0); - let request = self.next_ping_request(); - self.send_ping_request(&request, dest) - } -} |
