From 149595048401270b6053b2ab4cabb9e30fdf3c1b Mon Sep 17 00:00:00 2001 From: William Desportes Date: Thu, 10 Oct 2024 15:06:23 +0200 Subject: [PATCH] Re-work crate management --- snow-scanner/Cargo.toml | 21 +++- snow-scanner/src/event_bus.rs | 7 +- snow-scanner/src/main.rs | 139 +++--------------------- snow-scanner/src/server.rs | 6 +- snow-scanner/src/worker/Cargo.toml | 26 +++-- snow-scanner/src/worker/detection.rs | 26 ++--- snow-scanner/src/worker/mod.rs | 2 + snow-scanner/src/worker/scanners.rs | 133 +++++++++++++++++++++++ snow-scanner/src/worker/utils.rs | 35 +++++++ snow-scanner/src/worker/worker.rs | 151 ++++++++++++++++++++------- 10 files changed, 348 insertions(+), 198 deletions(-) create mode 100644 snow-scanner/src/worker/scanners.rs create mode 100644 snow-scanner/src/worker/utils.rs diff --git a/snow-scanner/Cargo.toml b/snow-scanner/Cargo.toml index b3a750f..3171e01 100644 --- a/snow-scanner/Cargo.toml +++ b/snow-scanner/Cargo.toml @@ -44,20 +44,35 @@ members = [ unstable = [] [dependencies] -rocket = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d"} -rocket_ws = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d"} rocket_db_pools = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d", default-features = false, features = ["diesel_mysql"] } +snow-scanner-worker = {path = "./src/worker"} +diesel.workspace = true +dns-ptr-resolver.workspace = true +hickory-resolver.workspace = true +uuid.workspace = true +rocket.workspace = true +rocket_ws.workspace = true +ws.workspace = true +chrono.workspace = true +serde.workspace = true +serde_json.workspace = true +cidr.workspace = true +weighted-rs.workspace = true +[workspace.dependencies] # mariadb-dev on Alpine # "mysqlclient-src" "mysql_backend" diesel = { version = "^2", default-features = false, features = ["mysql", "chrono", "uuid"] } - ws = { package = "rocket_ws", version = "0.1.1" } dns-ptr-resolver = {git = "https://github.com/wdes/dns-ptr-resolver.git"} hickory-resolver = { version = "0.24.1", default-features = false, features = ["tokio-runtime", "dns-over-h3", "dns-over-https", "dns-over-quic"]} + +rocket = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d"} +rocket_ws = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d"} chrono = "0.4.38" uuid = { version = "1.10.0", default-features = false, features = ["v7", "serde", "std"] } cidr = "0.3.0" serde = { version = "1.0.210", features = ["derive"] } serde_json = "1.0.128" +weighted-rs = "0.1.3" diff --git a/snow-scanner/src/event_bus.rs b/snow-scanner/src/event_bus.rs index 3f06474..f90bc1c 100644 --- a/snow-scanner/src/event_bus.rs +++ b/snow-scanner/src/event_bus.rs @@ -1,13 +1,12 @@ use std::{net::IpAddr, str::FromStr}; -use crate::{ - worker::detection::{detect_scanner_from_name, validate_ip}, - DbConnection, SnowDb, -}; +use crate::{DbConnection, SnowDb}; + use hickory_resolver::Name; use rocket::futures::channel::mpsc as rocket_mpsc; use rocket::futures::StreamExt; use rocket::tokio; +use snow_scanner_worker::detection::{detect_scanner_from_name, validate_ip}; use crate::Scanner; diff --git a/snow-scanner/src/main.rs b/snow-scanner/src/main.rs index bf44feb..e17a662 100644 --- a/snow-scanner/src/main.rs +++ b/snow-scanner/src/main.rs @@ -27,29 +27,30 @@ use rocket_db_pools::{ Connection, Pool, }; -use crate::worker::modules::{Network, WorkerMessages}; - -use rocket_db_pools::diesel::mysql::{Mysql, MysqlValue}; -use rocket_db_pools::diesel::serialize::IsNull; -use rocket_db_pools::diesel::sql_types::Text; use rocket_db_pools::diesel::MysqlPool; -use rocket_db_pools::diesel::{deserialize, serialize}; use rocket_db_pools::Database; - use rocket_ws::WebSocket; use server::Server; -use worker::detection::{detect_scanner, get_dns_client, validate_ip, Scanners}; +use weighted_rs::Weight; +use snow_scanner_worker::detection::{ + detect_scanner, get_dns_client, get_dns_server_config, validate_ip, +}; +use snow_scanner_worker::modules::{Network, WorkerMessages}; +use snow_scanner_worker::scanners::IsStatic; +use snow_scanner_worker::scanners::Scanners; +use snow_scanner_worker::utils::get_dns_rr; + +use std::net::SocketAddr; use std::{ - env, fmt, + env, net::IpAddr, ops::{Deref, DerefMut}, }; -use std::{io::Write, net::SocketAddr}; use std::{path::PathBuf, str::FromStr}; use uuid::Uuid; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{Deserialize, Serialize}; use dns_ptr_resolver::{get_ptr, ResolvedResult}; @@ -57,7 +58,6 @@ pub mod event_bus; pub mod models; pub mod schema; pub mod server; -pub mod worker; use crate::models::*; @@ -99,20 +99,6 @@ impl DerefMut for DbConnection { } } -trait IsStatic { - fn is_static(self: &Self) -> bool; -} - -impl IsStatic for Scanners { - fn is_static(self: &Self) -> bool { - match self { - Scanners::Censys => true, - Scanners::InternetMeasurement => true, - _ => false, - } - } -} - #[derive(serde::Deserialize, Clone)] struct SafeIpAddr { pub addr: IpAddr, @@ -137,109 +123,12 @@ impl FromFormField<'_> for SafeIpAddr { } } -impl FromParam<'_> for Scanners { - type Error = String; - - fn from_param(param: &'_ str) -> Result { - match param { - "stretchoid" => Ok(Scanners::Stretchoid), - "binaryedge" => Ok(Scanners::Binaryedge), - "shadowserver" => Ok(Scanners::Shadowserver), - "stretchoid.txt" => Ok(Scanners::Stretchoid), - "binaryedge.txt" => Ok(Scanners::Binaryedge), - "shadowserver.txt" => Ok(Scanners::Shadowserver), - "censys.txt" => Ok(Scanners::Censys), - "internet-measurement.com.txt" => Ok(Scanners::InternetMeasurement), - v => Err(format!("Unknown value: {v}")), - } - } -} - -impl<'de> Deserialize<'de> for Scanners { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = >::deserialize(deserializer)?; - let k: &str = s[0].as_str(); - match k { - "stretchoid" => Ok(Scanners::Stretchoid), - "binaryedge" => Ok(Scanners::Binaryedge), - "shadowserver" => Ok(Scanners::Shadowserver), - "stretchoid.txt" => Ok(Scanners::Stretchoid), - "binaryedge.txt" => Ok(Scanners::Binaryedge), - "shadowserver.txt" => Ok(Scanners::Shadowserver), - "censys.txt" => Ok(Scanners::Censys), - "internet-measurement.com.txt" => Ok(Scanners::InternetMeasurement), - v => Err(serde::de::Error::custom(format!( - "Unknown value: {}", - v.to_string() - ))), - } - } -} - -impl fmt::Display for Scanners { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{}", - match self { - Self::Stretchoid => "stretchoid", - Self::Binaryedge => "binaryedge", - Self::Censys => "censys", - Self::InternetMeasurement => "internet-measurement.com", - Self::Shadowserver => "shadowserver", - } - ) - } -} - -impl serialize::ToSql for Scanners { - fn to_sql(&self, out: &mut serialize::Output) -> serialize::Result { - match *self { - Self::Stretchoid => out.write_all(b"stretchoid")?, - Self::Binaryedge => out.write_all(b"binaryedge")?, - Self::Censys => out.write_all(b"censys")?, - Self::InternetMeasurement => out.write_all(b"internet-measurement.com")?, - Self::Shadowserver => out.write_all(b"shadowserver")?, - }; - - Ok(IsNull::No) - } -} - -impl deserialize::FromSql for Scanners { - fn from_sql(bytes: MysqlValue) -> deserialize::Result { - let value = >::from_sql(bytes)?; - let value = &value as &str; - let value: Result = value.try_into(); - match value { - Ok(d) => Ok(d), - Err(err) => Err(err.into()), - } - } -} - -impl TryInto for &str { - type Error = String; - - fn try_into(self) -> Result { - match self { - "stretchoid" => Ok(Scanners::Stretchoid), - "binaryedge" => Ok(Scanners::Binaryedge), - "internet-measurement.com" => Ok(Scanners::InternetMeasurement), - "shadowserver" => Ok(Scanners::Shadowserver), - value => Err(format!("Invalid value: {value}")), - } - } -} - async fn handle_ip( query_address: IpAddr, ) -> Result<(IpAddr, Option, ResolvedResult), ()> { let ptr_result: Result = std::thread::spawn(move || { - let client = get_dns_client(); + let mut rr_dns_servers = get_dns_rr(); + let client = get_dns_client(&get_dns_server_config(&rr_dns_servers.next().unwrap())); let ptr_result: ResolvedResult = if let Ok(res) = get_ptr(query_address, client) { res } else { diff --git a/snow-scanner/src/server.rs b/snow-scanner/src/server.rs index 216f48b..0e32780 100644 --- a/snow-scanner/src/server.rs +++ b/snow-scanner/src/server.rs @@ -2,11 +2,9 @@ use rocket::futures::{stream::Next, SinkExt, StreamExt}; use rocket_ws::{frame::CloseFrame, Message}; use std::pin::Pin; -use crate::{ - event_bus::{EventBusEvent, EventBusWriter, EventBusWriterEvent}, - worker::modules::WorkerMessages, -}; +use crate::event_bus::{EventBusEvent, EventBusWriter, EventBusWriterEvent}; use rocket::futures::channel::mpsc as rocket_mpsc; +use snow_scanner_worker::modules::WorkerMessages; pub struct Server {} diff --git a/snow-scanner/src/worker/Cargo.toml b/snow-scanner/src/worker/Cargo.toml index 3a274aa..3891e62 100644 --- a/snow-scanner/src/worker/Cargo.toml +++ b/snow-scanner/src/worker/Cargo.toml @@ -10,17 +10,25 @@ description = "The CLI to run a snow-scanner worker" name = "snow-scanner-worker" path = "worker.rs" +[lib] +name = "snow_scanner_worker" +path = "mod.rs" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] tungstenite = { version = "0.24.0", default-features = true, features = ["native-tls"] } -rocket_ws = { git = "https://github.com/rwf2/Rocket/", rev = "3bf9ef02d6e803fe9f753777f5a829dda6d2453d", default-features = true} +rocket.workspace = true +rocket_ws.workspace = true log2 = "0.1.11" -diesel = { version = "2", default-features = false, features = [] } -dns-ptr-resolver = {git = "https://github.com/wdes/dns-ptr-resolver.git"} -hickory-resolver = { version = "0.24.1", default-features = false, features = ["tokio-runtime", "dns-over-h3", "dns-over-https", "dns-over-quic"]} -chrono = "0.4.38" -uuid = { version = "1.10.0", default-features = false, features = ["v7", "serde", "std"] } -cidr = "0.2.2" -serde = "1.0.210" -serde_json = "1.0.128" +diesel.workspace = true +dns-ptr-resolver.workspace = true +hickory-resolver.workspace = true +chrono.workspace = true +uuid.workspace = true +cidr.workspace = true +serde.workspace = true +serde_json.workspace = true +weighted-rs.workspace = true +rayon = "1.10.0" +rand = "0.8.5" diff --git a/snow-scanner/src/worker/detection.rs b/snow-scanner/src/worker/detection.rs index 2d66e5c..25ff1b7 100644 --- a/snow-scanner/src/worker/detection.rs +++ b/snow-scanner/src/worker/detection.rs @@ -2,7 +2,7 @@ use std::net::IpAddr; use std::str::FromStr; use std::time::Duration; -use diesel::deserialize::FromSqlRow; +use crate::scanners::Scanners; use dns_ptr_resolver::ResolvedResult; use hickory_resolver::config::{NameServerConfigGroup, ResolverConfig, ResolverOpts}; @@ -10,25 +10,15 @@ use hickory_resolver::{Name, Resolver}; use crate::ip_addr::is_global_hardcoded; -#[derive(Debug, Clone, Copy, FromSqlRow, PartialEq)] -pub enum Scanners { - Stretchoid, - Binaryedge, - Shadowserver, - Censys, - InternetMeasurement, +pub fn get_dns_server_config(server_ips: &Vec) -> NameServerConfigGroup { + NameServerConfigGroup::from_ips_clear( + server_ips, 53, // Port 53 + true, + ) } -pub fn get_dns_client() -> Resolver { - let server_ip = "1.1.1.1"; - - let server = NameServerConfigGroup::from_ips_clear( - &[IpAddr::from_str(server_ip).unwrap()], - 53, // Port 53 - true, - ); - - let config = ResolverConfig::from_parts(None, vec![], server); +pub fn get_dns_client(server: &NameServerConfigGroup) -> Resolver { + let config = ResolverConfig::from_parts(None, vec![], server.clone()); let mut options = ResolverOpts::default(); options.timeout = Duration::from_secs(5); options.attempts = 1; // One try diff --git a/snow-scanner/src/worker/mod.rs b/snow-scanner/src/worker/mod.rs index addc8a7..6638ca8 100644 --- a/snow-scanner/src/worker/mod.rs +++ b/snow-scanner/src/worker/mod.rs @@ -1,3 +1,5 @@ pub mod detection; pub mod ip_addr; pub mod modules; +pub mod scanners; +pub mod utils; diff --git a/snow-scanner/src/worker/scanners.rs b/snow-scanner/src/worker/scanners.rs new file mode 100644 index 0000000..8a56ff0 --- /dev/null +++ b/snow-scanner/src/worker/scanners.rs @@ -0,0 +1,133 @@ +use diesel::deserialize; +use diesel::deserialize::FromSqlRow; +use diesel::mysql::Mysql; +use diesel::mysql::MysqlValue; +use diesel::serialize; +use diesel::serialize::IsNull; +use diesel::sql_types::Text; +use rocket::request::FromParam; + +use serde::{Deserialize, Deserializer}; +use std::fmt; +use std::io::Write; + +#[derive(Debug, Clone, Copy, FromSqlRow, PartialEq)] +pub enum Scanners { + Stretchoid, + Binaryedge, + Shadowserver, + Censys, + InternetMeasurement, +} + +pub trait IsStatic { + fn is_static(self: &Self) -> bool; +} + +impl IsStatic for Scanners { + fn is_static(self: &Self) -> bool { + match self { + Scanners::Censys => true, + Scanners::InternetMeasurement => true, + _ => false, + } + } +} + +impl FromParam<'_> for Scanners { + type Error = String; + + fn from_param(param: &'_ str) -> Result { + match param { + "stretchoid" => Ok(Scanners::Stretchoid), + "binaryedge" => Ok(Scanners::Binaryedge), + "shadowserver" => Ok(Scanners::Shadowserver), + "stretchoid.txt" => Ok(Scanners::Stretchoid), + "binaryedge.txt" => Ok(Scanners::Binaryedge), + "shadowserver.txt" => Ok(Scanners::Shadowserver), + "censys.txt" => Ok(Scanners::Censys), + "internet-measurement.com.txt" => Ok(Scanners::InternetMeasurement), + v => Err(format!("Unknown value: {v}")), + } + } +} + +impl<'de> Deserialize<'de> for Scanners { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = >::deserialize(deserializer)?; + let k: &str = s[0].as_str(); + match k { + "stretchoid" => Ok(Scanners::Stretchoid), + "binaryedge" => Ok(Scanners::Binaryedge), + "shadowserver" => Ok(Scanners::Shadowserver), + "stretchoid.txt" => Ok(Scanners::Stretchoid), + "binaryedge.txt" => Ok(Scanners::Binaryedge), + "shadowserver.txt" => Ok(Scanners::Shadowserver), + "censys.txt" => Ok(Scanners::Censys), + "internet-measurement.com.txt" => Ok(Scanners::InternetMeasurement), + v => Err(serde::de::Error::custom(format!( + "Unknown value: {}", + v.to_string() + ))), + } + } +} + +impl fmt::Display for Scanners { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::Stretchoid => "stretchoid", + Self::Binaryedge => "binaryedge", + Self::Censys => "censys", + Self::InternetMeasurement => "internet-measurement.com", + Self::Shadowserver => "shadowserver", + } + ) + } +} + +impl serialize::ToSql for Scanners { + fn to_sql(&self, out: &mut serialize::Output) -> serialize::Result { + match *self { + Self::Stretchoid => out.write_all(b"stretchoid")?, + Self::Binaryedge => out.write_all(b"binaryedge")?, + Self::Censys => out.write_all(b"censys")?, + Self::InternetMeasurement => out.write_all(b"internet-measurement.com")?, + Self::Shadowserver => out.write_all(b"shadowserver")?, + }; + + Ok(IsNull::No) + } +} + +impl deserialize::FromSql for Scanners { + fn from_sql(bytes: MysqlValue) -> deserialize::Result { + let value = >::from_sql(bytes)?; + let value = &value as &str; + let value: Result = value.try_into(); + match value { + Ok(d) => Ok(d), + Err(err) => Err(err.into()), + } + } +} + +impl TryInto for &str { + type Error = String; + + fn try_into(self) -> Result { + match self { + "stretchoid" => Ok(Scanners::Stretchoid), + "binaryedge" => Ok(Scanners::Binaryedge), + "internet-measurement.com" => Ok(Scanners::InternetMeasurement), + "shadowserver" => Ok(Scanners::Shadowserver), + value => Err(format!("Invalid value: {value}")), + } + } +} diff --git a/snow-scanner/src/worker/utils.rs b/snow-scanner/src/worker/utils.rs new file mode 100644 index 0000000..4ab15aa --- /dev/null +++ b/snow-scanner/src/worker/utils.rs @@ -0,0 +1,35 @@ +use rand::seq::SliceRandom; +use rand::thread_rng; +use std::net::IpAddr; +use weighted_rs::{RoundrobinWeight, Weight}; + +pub fn get_dns_rr() -> RoundrobinWeight> { + use std::str::FromStr; + + // https://gist.github.com/mutin-sa/5dcbd35ee436eb629db7872581093bc5 + let dns_servers: Vec = vec![ + IpAddr::from_str("1.1.1.1").unwrap(), + IpAddr::from_str("1.0.0.1").unwrap(), + IpAddr::from_str("8.8.8.8").unwrap(), + IpAddr::from_str("8.8.4.4").unwrap(), + IpAddr::from_str("9.9.9.9").unwrap(), + IpAddr::from_str("9.9.9.10").unwrap(), + IpAddr::from_str("208.67.222.222").unwrap(), // OpenDNS Cisco + IpAddr::from_str("208.67.220.220").unwrap(), // OpenDNS Cisco + IpAddr::from_str("208.67.222.220").unwrap(), // OpenDNS Cisco + IpAddr::from_str("208.67.220.222").unwrap(), // OpenDNS Cisco + IpAddr::from_str("193.110.81.0").unwrap(), // dns0.eu AS50902 + IpAddr::from_str("185.253.5.0").unwrap(), // dns0.eu AS50902 + IpAddr::from_str("74.82.42.42").unwrap(), // Hurricane Electric [AS6939] + ]; + + let mut rr: RoundrobinWeight> = RoundrobinWeight::new(); + // For each entry in the list we create a lot of two DNS servers to use + for _ in &dns_servers { + let mut client_servers = dns_servers.clone(); + client_servers.shuffle(&mut thread_rng()); + client_servers.truncate(2); + rr.add(client_servers, 1); + } + rr +} diff --git a/snow-scanner/src/worker/worker.rs b/snow-scanner/src/worker/worker.rs index 28f950a..5ccc4d4 100644 --- a/snow-scanner/src/worker/worker.rs +++ b/snow-scanner/src/worker/worker.rs @@ -1,18 +1,24 @@ use std::{env, net::IpAddr}; use chrono::{Duration, NaiveDateTime, Utc}; +use cidr::IpCidr; use detection::detect_scanner; -use dns_ptr_resolver::get_ptr; +use dns_ptr_resolver::{get_ptr, ResolvedResult}; use log2::*; +use scanners::Scanners; use tungstenite::stream::MaybeTlsStream; use tungstenite::{connect, Error, Message, WebSocket}; +use weighted_rs::Weight; pub mod detection; pub mod ip_addr; pub mod modules; +pub mod scanners; +pub mod utils; -use crate::detection::get_dns_client; +use crate::detection::{get_dns_client, get_dns_server_config}; use crate::modules::WorkerMessages; +use crate::utils::get_dns_rr; #[derive(Debug, Clone)] pub struct IpToResolve { @@ -143,44 +149,57 @@ impl Worker { self } + fn work_on_cidr(&mut self, cidr: IpCidr) { + info!("Picking up: {cidr}"); + info!("Range, from {} to {}", cidr.first(), cidr.last()); + let addresses = cidr.iter().addresses(); + let count = addresses.count(); + let mut current = 0; + let mut rr_dns_servers = get_dns_rr(); + + for addr in addresses { + let client = get_dns_client(&get_dns_server_config(&rr_dns_servers.next().unwrap())); + match get_ptr(addr, client) { + Ok(result) => match detect_scanner(&result) { + Ok(Some(scanner_name)) => { + self.report_detection(scanner_name, addr, result); + } + Ok(None) => {} + + Err(err) => error!("Error detecting for {addr}: {:?}", err), + }, + Err(_) => { + //debug!("Error processing {addr}: {err}") + } + }; + + current += 1; + if current % 10 == 0 { + info!("Progress: {count}/{current}"); + } + } + } + + fn report_detection(&mut self, scanner_name: Scanners, addr: IpAddr, result: ResolvedResult) { + info!("Detected {:?} for {addr}", scanner_name); + let request = WorkerMessages::ScannerFoundResponse { + name: result.result.unwrap().to_string(), + address: addr, + }; + let msg_string: String = request.to_string(); + match self.ws.send(Message::Text(msg_string)) { + Ok(_) => {} + Err(err) => error!("Unable to send scanner result: {err}"), + } + } + pub fn receive_request(&mut self, server_request: WorkerMessages) -> &Worker { match server_request { WorkerMessages::DoWorkRequest { neworks } => { - info!("Should work on: {:?}", neworks); + info!("Work request received for neworks: {:?}", neworks); for cidr in neworks { let cidr = cidr.0; - info!("Picking up: {cidr}"); - info!("Range, from {} to {}", cidr.first(), cidr.last()); - let addresses = cidr.iter().addresses(); - let count = addresses.count(); - let mut current = 0; - for addr in addresses { - let client = get_dns_client(); - match get_ptr(addr, client) { - Ok(result) => match detect_scanner(&result) { - Ok(Some(scanner_name)) => { - info!("Detected {:?} for {addr}", scanner_name); - let request = WorkerMessages::ScannerFoundResponse { - name: result.result.unwrap().to_string(), - address: addr, - }; - let msg_string: String = request.to_string(); - match self.ws.send(Message::Text(msg_string)) { - Ok(_) => {} - Err(err) => error!("Unable to send scanner result: {err}"), - } - } - Ok(None) => {} - - Err(err) => error!("Error detecting for {addr}: {:?}", err), - }, - Err(_) => { - //debug!("Error processing {addr}: {err}") - } - }; - - current += 1; - } + self.work_on_cidr(cidr); } } WorkerMessages::AuthenticateRequest { .. } @@ -194,6 +213,68 @@ impl Worker { } } +/*fn resolve_file(addresses: InetAddressIterator, dns_servers: Vec<&str>) { + + + let mut ips = vec![]; + for address in addresses { + match IpAddr::from_str(address) { + Ok(addr) => ips.push(IpToResolve { + address: addr, + server: rr.next().unwrap(), + }), + Err(err) => { + eprintln!( + "Something went wrong while parsing the IP ({}): {}", + address, err + ); + process::exit(1); + } + } + } + + match rayon::ThreadPoolBuilder::new() + .num_threads(30) + .build_global() + { + Ok(r) => r, + Err(err) => { + eprintln!( + "Something went wrong while building the thread pool: {}", + err + ); + process::exit(1); + } + } + + ips.into_par_iter() + .enumerate() + .for_each(|(_i, to_resolve)| { + let server = NameServerConfigGroup::from_ips_clear( + &[to_resolve.server.ip()], + to_resolve.server.port(), + true, + ); + + let ptr_result = get_ptr(to_resolve.address, resolver); + match ptr_result { + Ok(ptr) => match ptr.result { + Some(res) => println!("{} # {}", to_resolve.address, res), + None => println!("{}", to_resolve.address), + }, + Err(err) => { + let two_hundred_millis = Duration::from_millis(400); + thread::sleep(two_hundred_millis); + + eprintln!( + "[{}] Error for {} -> {}", + to_resolve.server, to_resolve.address, err.message + ) + } + } + }); +}*/ + fn main() -> () { let _log2 = log2::stdout() .module(true)