Fixed crash when no internet conneciton

This commit is contained in:
Rémi BERTHO 2021-10-27 23:13:34 +02:00
parent aa2ce3e0f4
commit 7ac7b97341
Signed by: dalan
GPG key ID: EE3B917931C07B64
2 changed files with 48 additions and 8 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "check_ip"
version = "2.0.0"
version = "2.1.0"
edition = "2018"
[dependencies]
@ -15,4 +15,5 @@ simplelog = "^0.10.0"
clokwerk = "0.3"
trust-dns-resolver = {version = "0.20", features = ["serde-config"] }
query_external_ip = "0.1"
tokio = "1"
tokio = "1"
systemstat = "0.1"

View file

@ -6,17 +6,18 @@ extern crate log;
extern crate native_tls;
extern crate serde;
extern crate simplelog;
extern crate systemstat;
extern crate tokio;
extern crate toml;
extern crate trust_dns_resolver;
use self::native_tls::{Protocol, TlsConnector};
use anyhow::{bail, Result};
use anyhow::{anyhow, bail, Result};
use clokwerk::{Scheduler, TimeUnits};
use lettre::smtp::authentication::Credentials;
use lettre::{ClientSecurity, ClientTlsParameters, SmtpClient, Transport};
use lettre_email::EmailBuilder;
use log::{error, info};
use log::{error, info, warn};
use query_external_ip::Consensus;
use serde::Deserialize;
use simplelog::{ConfigBuilder, LevelFilter, WriteLogger};
@ -24,6 +25,7 @@ use std::fs::{self, OpenOptions};
use std::net::{Ipv4Addr, Ipv6Addr};
use std::string::String;
use std::{thread, time::Duration};
use systemstat::{Platform, System};
use tokio::runtime::{Builder, Runtime};
use trust_dns_resolver::{config::*, Name, Resolver};
@ -54,12 +56,19 @@ fn main() -> Result<()> {
Ok(tester) => tester,
};
// Test Ethernet
if let Err(e) = wait_eth_connection() {
error!("Error {}", e);
return Err(e);
}
// Initial check
if let Err(e) = tester.check() {
error!("Error {}", e);
bail!("Cannot get initial IP");
}
// Lauch scheduler
if let Some(false) = tester.config.test {
// Init scheduler
info!("Init scheduler");
@ -80,6 +89,31 @@ fn main() -> Result<()> {
Ok(())
}
fn wait_eth_connection() -> Result<()> {
let mut wait_s = 0;
loop {
let sys = System::new();
for netif in sys.networks()?.values() {
if netif.addrs.len() > 0 {
for addr in netif.addrs.iter() {
if let systemstat::IpAddr::V4(ipv4_addr) = addr.addr {
if ipv4_addr != Ipv4Addr::LOCALHOST {
return Ok(());
}
}
}
}
}
if wait_s >= 60 {
break;
}
warn!("Cannot get ethernet connection, wait 5s and retry");
wait_s += 5;
std::thread::sleep(std::time::Duration::from_secs(5));
}
bail!("Cannot get ethernet connection")
}
struct Tester {
config: Config,
dns_resolver: Resolver,
@ -117,8 +151,12 @@ impl Tester {
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();
let ipv4 = cons
.v4()
.ok_or(anyhow!("Cannot get current IPv4 address"))?;
let ipv6 = cons
.v6()
.ok_or(anyhow!("Cannot get current IPv6 address"))?;
info!("Current IPv4 is {} and IPv6 {}", ipv4, ipv6);
Ok((ipv4, ipv6))
@ -136,12 +174,13 @@ impl Tester {
let mut full_msg = String::new();
for domain in self.config.server.domains.iter() {
info!("Test domain {}", domain);
if let Ok(dns_ipv4_lookup) = self.dns_resolver.ipv4_lookup(domain.clone()) {
let dns_ipv4 = dns_ipv4_lookup.iter().next().unwrap();
if *dns_ipv4 != ipv4 {
msg!(
full_msg,
"Wrong IPV4 for {} (DNS: {}, current: {})",
"Wrong IPv4 for {} (DNS: {}, current: {})",
domain,
dns_ipv4,
ipv4
@ -155,7 +194,7 @@ impl Tester {
if *dns_ipv6 != ipv6 {
msg!(
full_msg,
"Wrong IPV6 for {} (DNS: {}, current: {})",
"Wrong IPv6 for {} (DNS: {}, current: {})",
domain,
dns_ipv6,
ipv6