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] [package]
name = "check_ip" name = "check_ip"
version = "2.0.0" version = "2.1.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
@ -16,3 +16,4 @@ clokwerk = "0.3"
trust-dns-resolver = {version = "0.20", features = ["serde-config"] } trust-dns-resolver = {version = "0.20", features = ["serde-config"] }
query_external_ip = "0.1" 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 native_tls;
extern crate serde; extern crate serde;
extern crate simplelog; extern crate simplelog;
extern crate systemstat;
extern crate tokio; extern crate tokio;
extern crate toml; extern crate toml;
extern crate trust_dns_resolver; extern crate trust_dns_resolver;
use self::native_tls::{Protocol, TlsConnector}; use self::native_tls::{Protocol, TlsConnector};
use anyhow::{bail, Result}; use anyhow::{anyhow, bail, Result};
use clokwerk::{Scheduler, TimeUnits}; use clokwerk::{Scheduler, TimeUnits};
use lettre::smtp::authentication::Credentials; use lettre::smtp::authentication::Credentials;
use lettre::{ClientSecurity, ClientTlsParameters, SmtpClient, Transport}; use lettre::{ClientSecurity, ClientTlsParameters, SmtpClient, Transport};
use lettre_email::EmailBuilder; use lettre_email::EmailBuilder;
use log::{error, info}; use log::{error, info, warn};
use query_external_ip::Consensus; use query_external_ip::Consensus;
use serde::Deserialize; use serde::Deserialize;
use simplelog::{ConfigBuilder, LevelFilter, WriteLogger}; use simplelog::{ConfigBuilder, LevelFilter, WriteLogger};
@ -24,6 +25,7 @@ use std::fs::{self, OpenOptions};
use std::net::{Ipv4Addr, Ipv6Addr}; use std::net::{Ipv4Addr, Ipv6Addr};
use std::string::String; use std::string::String;
use std::{thread, time::Duration}; use std::{thread, time::Duration};
use systemstat::{Platform, System};
use tokio::runtime::{Builder, Runtime}; use tokio::runtime::{Builder, Runtime};
use trust_dns_resolver::{config::*, Name, Resolver}; use trust_dns_resolver::{config::*, Name, Resolver};
@ -54,12 +56,19 @@ fn main() -> Result<()> {
Ok(tester) => tester, Ok(tester) => tester,
}; };
// Test Ethernet
if let Err(e) = wait_eth_connection() {
error!("Error {}", e);
return Err(e);
}
// Initial check // Initial check
if let Err(e) = tester.check() { if let Err(e) = tester.check() {
error!("Error {}", e); error!("Error {}", e);
bail!("Cannot get initial IP"); bail!("Cannot get initial IP");
} }
// Lauch scheduler
if let Some(false) = tester.config.test { if let Some(false) = tester.config.test {
// Init scheduler // Init scheduler
info!("Init scheduler"); info!("Init scheduler");
@ -80,6 +89,31 @@ fn main() -> Result<()> {
Ok(()) 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 { struct Tester {
config: Config, config: Config,
dns_resolver: Resolver, dns_resolver: Resolver,
@ -117,8 +151,12 @@ impl Tester {
fn get_ip(&self) -> Result<(Ipv4Addr, Ipv6Addr)> { fn get_ip(&self) -> Result<(Ipv4Addr, Ipv6Addr)> {
let cons = self.async_runtime.block_on(Consensus::get())?; let cons = self.async_runtime.block_on(Consensus::get())?;
let ipv4 = cons.v4().unwrap(); let ipv4 = cons
let ipv6 = cons.v6().unwrap(); .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); info!("Current IPv4 is {} and IPv6 {}", ipv4, ipv6);
Ok((ipv4, ipv6)) Ok((ipv4, ipv6))
@ -136,12 +174,13 @@ impl Tester {
let mut full_msg = String::new(); let mut full_msg = String::new();
for domain in self.config.server.domains.iter() { 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()) { if let Ok(dns_ipv4_lookup) = self.dns_resolver.ipv4_lookup(domain.clone()) {
let dns_ipv4 = dns_ipv4_lookup.iter().next().unwrap(); let dns_ipv4 = dns_ipv4_lookup.iter().next().unwrap();
if *dns_ipv4 != ipv4 { if *dns_ipv4 != ipv4 {
msg!( msg!(
full_msg, full_msg,
"Wrong IPV4 for {} (DNS: {}, current: {})", "Wrong IPv4 for {} (DNS: {}, current: {})",
domain, domain,
dns_ipv4, dns_ipv4,
ipv4 ipv4
@ -155,7 +194,7 @@ impl Tester {
if *dns_ipv6 != ipv6 { if *dns_ipv6 != ipv6 {
msg!( msg!(
full_msg, full_msg,
"Wrong IPV6 for {} (DNS: {}, current: {})", "Wrong IPv6 for {} (DNS: {}, current: {})",
domain, domain,
dns_ipv6, dns_ipv6,
ipv6 ipv6