diff --git a/Cargo.toml b/Cargo.toml index ce94546..6f21132 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,6 @@ edition = "2018" [dependencies] anyhow = "1.0" -my_internet_ip = "0.1.1" lettre = "0.9" lettre_email = "0.9" native-tls = "0.2" @@ -15,3 +14,5 @@ log = "0.4" simplelog = "^0.10.0" clokwerk = "0.3" trust-dns-resolver = {version = "0.20", features = ["serde-config"] } +query_external_ip = "0.1" +tokio = "1" \ No newline at end of file diff --git a/TODO.md b/TODO.md index 18157ea..bde4e85 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,4 @@ # TODO * [ ] Examples de fichiers de config (config + systemd) * [ ] N’envoyer qu’un seul mail par test =>_test_domains renvoie Option - * [ ] Test de l’IPv6 (https://crates.io/crates/query_external_ip) * [ ] Rustfmt \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2aa00ee..f4da6bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,12 @@ extern crate clokwerk; extern crate lettre; extern crate lettre_email; extern crate log; -extern crate my_internet_ip; extern crate native_tls; extern crate serde; extern crate simplelog; extern crate toml; extern crate trust_dns_resolver; +extern crate tokio; use self::native_tls::{Protocol, TlsConnector}; use anyhow::{bail, Result}; @@ -20,9 +20,11 @@ use log::{error, info}; use serde::Deserialize; use simplelog::{ConfigBuilder, LevelFilter, WriteLogger}; use std::fs::{self, OpenOptions}; -use std::net::IpAddr; +use std::net::{Ipv4Addr, Ipv6Addr}; use std::{thread, time::Duration}; use trust_dns_resolver::{config::*, Name, Resolver}; +use query_external_ip::Consensus; +use tokio::runtime::{Builder, Runtime}; fn main() -> Result<()> { // Init log @@ -80,6 +82,7 @@ fn main() -> Result<()> { struct Tester { config: Config, dns_resolver: Resolver, + async_runtime: Runtime } impl Tester { @@ -89,14 +92,18 @@ impl Tester { Ok(Tester { config: toml::from_str(&fs::read_to_string("config.toml")?)?, dns_resolver: Resolver::new(ResolverConfig::default(), resolver_opt)?, + async_runtime: Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() }) } fn check(&self) -> Result<()> { info!("Check"); match self.get_ip() { - Ok(ipv4) => { - self.test_domains(ipv4)?; + Ok((ipv4, ipv6)) => { + self.test_domains(ipv4, ipv6)?; } Err(err) => { let msg = format!("Cannot get IP ({})", err); @@ -107,18 +114,16 @@ impl Tester { Ok(()) } - fn get_ip(&self) -> Result { - // Get new IP - let new_ip = match my_internet_ip::get() { - Ok(ip) => ip, - Err(e) => bail!("Could not get IP: {:?}", e), - }; - info!("Current IP is {}", new_ip); + fn get_ip(&self) -> Result<(Ipv4Addr, Ipv6Addr)> { + let cons = self.async_runtime.block_on(Consensus::get())?; + let ipv4 = cons.v4().unwrap(); + let ipv6 = cons.v6().unwrap(); + info!("Current IPv4 is {} and IPv6 {}", ipv4, ipv6); - Ok(new_ip) + Ok((ipv4, ipv6)) } - fn test_domains(&self, ipv4: IpAddr) -> Result<()> { + fn test_domains(&self, ipv4: Ipv4Addr, ipv6: Ipv6Addr) -> Result<()> { for domain in self.config.server.domains.iter() { let address = self.dns_resolver.lookup_ip(domain.clone())?; for dns_ip in address.iter() { @@ -132,6 +137,16 @@ impl Tester { self.send_mail("Wrong IP".to_owned(), msg)?; } } + if dns_ip.is_ipv6() { + if dns_ip != ipv6 { + let msg = format!( + "Wrong IPV6 for {} (DNS: {}, current: {})", + domain, dns_ip, ipv6 + ); + info!("{}", msg); + self.send_mail("Wrong IP".to_owned(), msg)?; + } + } } } Ok(())