summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2021-05-06 10:46:04 +0100
committerEmīls <emils@mullvad.net>2021-05-12 13:57:35 +0100
commitd53c2926fdab33637f8f290acb07983cfe71e87c (patch)
treef512d9eebc944514e018b327d14acc47210c9375
parent057e5966e24104be2f033abebe66729ab21f251d (diff)
downloadmullvadvpn-d53c2926fdab33637f8f290acb07983cfe71e87c.tar.xz
mullvadvpn-d53c2926fdab33637f8f290acb07983cfe71e87c.zip
Use ICMP socket on Linux
-rw-r--r--CHANGELOG.md2
-rw-r--r--Cargo.lock252
-rw-r--r--talpid-core/Cargo.toml5
-rw-r--r--talpid-core/src/lib.rs2
-rw-r--r--talpid-core/src/ping_monitor/icmp.rs239
-rw-r--r--talpid-core/src/ping_monitor/mod.rs8
-rw-r--r--talpid-core/src/ping_monitor/win.rs120
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)
- }
-}