From 7878548dc8adcd83df1967cf9130d28f889cff73 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 30 Jan 2021 19:24:33 -0500 Subject: [PATCH] Use the icmp-socket module instead of ekko --- Cargo.lock | 246 +++++++++++++++++++++++--------------------------- Cargo.toml | 3 +- src/icmp.rs | 254 ++++++++++++++++++++++++++++++++++++++++------------ src/main.rs | 2 +- src/util.rs | 6 +- 5 files changed, 311 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4cbb75..f0f5a8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,15 @@ # It is not intended for manual editing. [[package]] name = "anyhow" -version = "1.0.32" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" [[package]] name = "argv" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87b48bbc752e97f1b6d7f237c0fd50056f19417e30b10121d4065d1459270e1d" +checksum = "df1654988efdfaea9f6bb94b445b5239fa9f997c6b375f26b7caa193cc9d585b" [[package]] name = "ascii" @@ -31,15 +31,21 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "byteorder" -version = "1.3.4" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" [[package]] name = "cfg-if" @@ -55,26 +61,28 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.12" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0fee792e164f78f5fe0c296cc2eb3688a2ca2b70cdff33040922d298203f0c4" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ + "libc", "num-integer", "num-traits", "time", + "winapi", ] [[package]] name = "chunked_transfer" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d29eb15132782371f71da8f947dba48b3717bdb6fa771b9b434d645e40a7193" +checksum = "7477065d45a8fe57167bf3cf8bcd3729b54cfcb81cca49bda2d038ea89ae82ca" [[package]] name = "ctor" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39858aa5bac06462d4dd4b9164848eb81ffc4aa5c479746393598fd193afa227" +checksum = "10bcb9d7dcbf7002aaffbb53eac22906b64cdcc127971dcc387d8eb7c95d5560" dependencies = [ "quote", "syn", @@ -85,55 +93,44 @@ name = "durnitisp" version = "0.1.0" dependencies = [ "anyhow", - "ekko", "gflags", - "log 0.4.8", + "icmp-socket", + "log 0.4.14", "nursery", "prometheus", "resolve", + "socket2", "stderrlog", "tiny_http", ] -[[package]] -name = "ekko" -version = "0.2.0" -source = "git+https://github.com/dev-bio/Ekko?branch=ipv-hops#a59f2598c5e678dbba4420fbbbfd3b2a9c65d4d7" -dependencies = [ - "byteorder", - "rand 0.8.1", - "socket2", - "thiserror", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +dependencies = [ + "matches", + "percent-encoding", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "getrandom" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi", -] - [[package]] name = "gflags" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85e4af201231c9fbcea144cc9ab6d37a0c7f9fce512a9af4edb4d4cd2aaf320" +checksum = "59beffbf6fd7a747b9ccc0c30177c50b030b8d55824393107d95397ab28b8714" dependencies = [ "argv", "gflags-impl", @@ -143,9 +140,9 @@ dependencies = [ [[package]] name = "gflags-impl" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a85290f4bbfa1888d19a9c2621188c10b893500a45e516446f88f404a73" +checksum = "07ab1d33648a58677c98ee6ed81ce592e108d4e9847ce62a15302da7e5bfd437" dependencies = [ "proc-macro2", "quote", @@ -163,6 +160,15 @@ dependencies = [ "syn", ] +[[package]] +name = "icmp-socket" +version = "0.1.0" +source = "git+https://github.com/zaphar/icmp-socket.git?branch=master#37f3651995fc608cfe40bde9e89649ac5ea72df6" +dependencies = [ + "byteorder", + "socket2", +] + [[package]] name = "idna" version = "0.1.5" @@ -187,9 +193,9 @@ dependencies = [ [[package]] name = "inventory" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621b50c176968fd3b0bd71f821a28a0ea98db2b5aea966b2fbb8bd1b7d310328" +checksum = "0f0f7efb804ec95e33db9ad49e4252f049e37e8b0a4652e3cd61f7999f2eff7f" dependencies = [ "ctor", "ghost", @@ -198,9 +204,9 @@ dependencies = [ [[package]] name = "inventory-impl" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99a4111304bade76468d05beab3487c226e4fe4c4de1c4e8f006e815762db73" +checksum = "75c094e94816723ab936484666968f5b58060492e880f3c8d00489a1e244fa51" dependencies = [ "proc-macro2", "quote", @@ -221,9 +227,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.71" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" +checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" [[package]] name = "log" @@ -231,16 +237,16 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" dependencies = [ - "log 0.4.8", + "log 0.4.14", ] [[package]] name = "log" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] @@ -251,9 +257,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "num-integer" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", "num-traits", @@ -261,9 +267,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ "autocfg", ] @@ -286,17 +292,11 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro2" -version = "1.0.18" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] @@ -317,15 +317,15 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.15.1" +version = "2.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4951a8253c06334be9fe320bbcf73f14949fde62a0c8128d697eec1ff0fa8cd" +checksum = "86473d5f16580f10b131a0bf0afb68f8e029d1835d33a00f37281b05694e5312" [[package]] name = "quote" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ "proc-macro2", ] @@ -353,28 +353,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rand" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c24fcd450d3fa2b592732565aa4f17a27a61c65ece4726353e000939b0edee34" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.1", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.1", -] - [[package]] name = "rand_core" version = "0.3.1" @@ -390,24 +368,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -[[package]] -name = "rand_core" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core 0.6.1", -] - [[package]] name = "rdrand" version = "0.4.0" @@ -419,33 +379,36 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +dependencies = [ + "bitflags", +] [[package]] name = "redox_termios" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" dependencies = [ "redox_syscall", ] [[package]] name = "ref-cast" -version = "1.0.2" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.2" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" dependencies = [ "proc-macro2", "quote", @@ -489,16 +452,16 @@ checksum = "32e5ee9b90a5452c570a0b0ac1c99ae9498db7e56e33d74366de7f2a7add7f25" dependencies = [ "atty", "chrono", - "log 0.4.8", + "log 0.4.14", "termcolor", "thread_local", ] [[package]] name = "syn" -version = "1.0.33" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", @@ -507,18 +470,18 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "termion" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" +checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" dependencies = [ "libc", "numtoa", @@ -528,18 +491,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" +checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" dependencies = [ "proc-macro2", "quote", @@ -558,11 +521,12 @@ dependencies = [ [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi", "winapi", ] @@ -575,15 +539,24 @@ dependencies = [ "ascii", "chrono", "chunked_transfer", - "log 0.4.8", + "log 0.4.14", "url", ] [[package]] name = "tinyvec" -version = "0.3.3" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "unicode-bidi" @@ -596,9 +569,9 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" dependencies = [ "tinyvec", ] @@ -620,10 +593,11 @@ dependencies = [ [[package]] name = "url" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" dependencies = [ + "form_urlencoded", "idna 0.2.0", "matches", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index f32ab72..6e7bd80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,6 @@ nursery = "^0.0.1" prometheus = "^0.9.0" stderrlog = "0.4" tiny_http = "^0.7.0" -ekko = { git = "https://github.com/dev-bio/Ekko", branch = "ipv-hops"} +socket2 = "0.3.19" +icmp-socket = { git = "https://github.com/zaphar/icmp-socket.git" } resolve = "^0.2.0" \ No newline at end of file diff --git a/src/icmp.rs b/src/icmp.rs index 3400f55..8658dec 100644 --- a/src/icmp.rs +++ b/src/icmp.rs @@ -11,28 +11,31 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::{Arc, RwLock}; -use std::time::Duration; +use std::time::{Duration, Instant}; +use std::{convert::TryFrom, ops::Sub}; +use std::{ + net::{IpAddr, Ipv4Addr, Ipv6Addr}, + sync::{Arc, RwLock}, +}; use crate::util; -use ekko::{Ekko, EkkoResponse}; use gflags; +use icmp_socket::{ + packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest}, + IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet, +}; use log::{error, info}; use prometheus::{CounterVec, IntGaugeVec}; +use socket2::{self, SockAddr}; gflags::define! { - /// The size in bytes of the ping requests. + /// The payload to use for the ping requests. --pingPayload = "durnitisp" } gflags::define! { - /// The size in bytes of the ping requests. - --pingTTL: u32 = 113 -} - -gflags::define! { - /// The size in bytes of the ping requests. + /// The timeout for ping requests. --pingTimeout: u64 = 2048 } @@ -42,7 +45,58 @@ gflags::define! { } fn resolve_host_address(host: &str) -> String { - format!("{}", util::resolve_hosts(&vec![host]).unwrap().first().unwrap().unwrap()) + format!( + "{}", + util::resolve_hosts(&vec![host]) + .unwrap() + .first() + .unwrap() + .unwrap() + ) +} + +fn loop_impl( + mut socket: Sock, + dest: Sock::AddrType, + packet_handler: PH, + err_handler: EH, + stop_signal: Arc>, +) where + PH: Fn(Sock::PacketType, socket2::SockAddr, Instant) -> (), + EH: Fn(std::io::Error) -> (), + Sock: IcmpSocket, + Sock::AddrType: std::fmt::Display + Copy, + Sock::PacketType: WithEchoRequest, +{ + loop { + { + // Limit the scope of this lock + if *stop_signal.read().unwrap() { + info!("Stopping ping thread for {}", dest); + return; + } + } + let sequence = 0; + let packet = Sock::PacketType::with_echo_request( + 42, + sequence, + PINGPAYLOAD.flag.as_bytes().to_owned(), + ) + .unwrap(); + let send_time = Instant::now(); + if let Err(e) = socket.send_to(dest, packet) { + err_handler(e); + } + match socket.rcv_from() { + Err(e) => { + err_handler(e); + } + Ok((resp, sock_addr)) => { + packet_handler(resp, sock_addr, send_time); + } + } + std::thread::sleep(Duration::from_secs(3)); + } } pub fn start_echo_loop( @@ -52,25 +106,77 @@ pub fn start_echo_loop( ping_counter: CounterVec, ) { let resolved = resolve_host_address(domain_name); - info!("Attempting to ping domain {} at address: {}", domain_name, resolved); - let mut sender = Ekko::with_target(&resolved).unwrap(); - loop { - { - // Limit the scope of this lock - if *stop_signal.read().unwrap() { - info!("Stopping ping thread for {}", domain_name); - return; - } - } - match sender - .send_with_timeout(MAXHOPS.flag, Some(Duration::from_millis(PINGTIMEOUT.flag))) { - Ok(r) => match r { - EkkoResponse::DestinationResponse(r) => { - let elapsed = r.elapsed.as_millis(); + info!( + "Attempting to ping domain {} at address: {}", + domain_name, resolved + ); + let dest = resolved + .parse::() + .expect(&format!("Invalid IP Address {}", resolved)); + + let err_handler = |e: std::io::Error| { + ping_counter + .with(&prometheus::labels! {"result" => "err", "domain" => domain_name}) + .inc(); + error!( + "Ping send to domain: {} and address: {} failed: {:?}, Trying again later", + domain_name, &dest, e + ); + }; + match dest { + IpAddr::V4(dest) => { + let mut socket = IcmpSocket4::try_from(Ipv4Addr::new(0, 0, 0, 0)).unwrap(); + socket.set_max_hops(MAXHOPS.flag as u32); + let packet_handler = |p: Icmpv4Packet, s: SockAddr, send_time: Instant| { + // We only want to handle replies for the address we are pinging. + if let Some(addr) = s.as_inet() { + if &dest != addr.ip() { + return; + } + } else { + return; + }; + match p.message { + Icmpv4Message::ParameterProblem { + pointer: _, + padding: _, + header: _, + } => { + ping_counter + .with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name}) + .inc(); + } + Icmpv4Message::Unreachable { + padding: _, + header: _, + } => { + // // If we got unreachable we need to set up a new sender. + // error!("{:?}", r); + // info!("Restarting our sender"); + ping_counter + .with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name}) + .inc(); + // let resolved = resolve_host_address(domain_name); + // let mut new_sender = Ekko::with_target(&resolved).unwrap(); + // std::mem::swap(&mut sender, &mut new_sender); + } + Icmpv4Message::TimeExceeded { + padding: _, + header: _, + } => { + ping_counter + .with(&prometheus::labels! {"result" => "timeout", "domain" => domain_name}) + .inc(); + } + Icmpv4Message::EchoReply { + identifier: _, + sequence, + payload: _, + } => { + let elapsed = Instant::now().sub(send_time.clone()).as_millis(); info!( - "ICMP: Reply from {}: time={}ms", - r.address.unwrap(), - elapsed, + "ICMP: Reply from {}: time={}ms, seq={}", + dest, elapsed, sequence, ); ping_counter .with(&prometheus::labels! {"result" => "ok", "domain" => domain_name}) @@ -78,40 +184,70 @@ pub fn start_echo_loop( if elapsed != 0 { ping_latency_guage .with(&prometheus::labels! {"domain" => domain_name}) - .set(r.elapsed.as_millis() as i64); + .set(elapsed as i64); } } - EkkoResponse::UnreachableResponse((_, ref _code)) => { - // If we got unreachable we need to set up a new sender. - error!("{:?}", r); - info!("Restarting our sender"); - ping_counter - .with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name}) - .inc(); - let resolved = resolve_host_address(domain_name); - let mut new_sender = Ekko::with_target(&resolved).unwrap(); - std::mem::swap(&mut sender, &mut new_sender); - - } - EkkoResponse::ExceededResponse(_) => { - ping_counter - .with(&prometheus::labels! {"result" => "timeout", "domain" => domain_name}) - .inc(); - } _ => { - ping_counter - .with(&prometheus::labels! {"result" => "err", "domain" => domain_name}) - .inc(); - error!("{:?}", r); + // We ignore the rest. } - }, - Err(e) => { - ping_counter - .with(&prometheus::labels! {"result" => "err", "domain" => domain_name}) - .inc(); - error!("Ping send to domain: {} address: {} failed: {:?}, Trying again later", domain_name, &resolved, e); } }; - std::thread::sleep(Duration::from_secs(3)); - } + loop_impl(socket, dest, packet_handler, err_handler, stop_signal); + } + IpAddr::V6(dest) => { + let mut socket = IcmpSocket6::try_from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).unwrap(); + socket.set_max_hops(MAXHOPS.flag as u32); + let packet_handler = |p: Icmpv6Packet, s: SockAddr, send_time: Instant| { + // We only want to handle replies for the addres we are pinging. + if let Some(addr) = s.as_inet6() { + if &dest != addr.ip() { + return; + } + } else { + return; + }; + match p.message { + Icmpv6Message::Unreachable { + _unused, + invoking_packet: _, + } => { + ping_counter + .with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name}) + .inc(); + } + Icmpv6Message::ParameterProblem { + pointer: _, + invoking_packet: _, + } => { + ping_counter + .with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name}) + .inc(); + } + Icmpv6Message::EchoReply { + identifier: _, + sequence, + payload: _, + } => { + let elapsed = Instant::now().sub(send_time.clone()).as_millis(); + info!( + "ICMP: Reply from {}: time={}ms, seq={}", + dest, elapsed, sequence, + ); + ping_counter + .with(&prometheus::labels! {"result" => "ok", "domain" => domain_name}) + .inc(); + if elapsed != 0 { + ping_latency_guage + .with(&prometheus::labels! {"domain" => domain_name}) + .set(elapsed as i64); + } + } + _ => { + // We ignore the rest. + } + } + }; + loop_impl(socket, dest, packet_handler, err_handler, stop_signal); + } + }; } diff --git a/src/main.rs b/src/main.rs index a5fecc3..3c3baf4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::convert::Into; use std::sync::Arc; use std::sync::RwLock; -use std::convert::Into; use gflags; use log::{debug, error, info}; diff --git a/src/util.rs b/src/util.rs index 5bdfd53..d042da0 100644 --- a/src/util.rs +++ b/src/util.rs @@ -16,10 +16,10 @@ use std::io; use std::net::IpAddr; use std::net::{SocketAddr, ToSocketAddrs}; +use gflags; use log::info; use resolve::config::DnsConfig; -use resolve::resolver::{DnsResolver}; -use gflags; +use resolve::resolver::DnsResolver; gflags::define! { /// Allow IPv6 addresses for domain name lookups. @@ -52,4 +52,4 @@ pub fn resolve_socket_addrs<'a>(servers: &'a Vec<&str>) -> io::Result