From b708c70485e7d3178166875e77c35af2cd8e0268 Mon Sep 17 00:00:00 2001 From: PsypherPunk Date: Wed, 18 Sep 2024 17:41:52 +0100 Subject: [PATCH] fix: avoid duplicate IP addresses avoid scanning duplicated IPs for overlapping CIDRs. fixes #651 --- src/address.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/address.rs b/src/address.rs index 762f86541..4829fabf9 100644 --- a/src/address.rs +++ b/src/address.rs @@ -1,4 +1,5 @@ //! Provides functions to parse input IP addresses, CIDRs or files. +use std::collections::BTreeSet; use std::fs::{self, File}; use std::io::{prelude::*, BufReader}; use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; @@ -27,6 +28,8 @@ use crate::warning; /// /// let ips = parse_addresses(&opts); /// ``` +/// +/// Finally, any duplicates are removed to avoid excessive scans. pub fn parse_addresses(input: &Opts) -> Vec { let mut ips: Vec = Vec::new(); let mut unresolved_addresses: Vec<&str> = Vec::new(); @@ -66,7 +69,10 @@ pub fn parse_addresses(input: &Opts) -> Vec { } } - ips + ips.into_iter() + .collect::>() + .into_iter() + .collect() } /// Given a string, parse it as a host, IP address, or CIDR. @@ -256,6 +262,16 @@ mod tests { assert_eq!(ips.len(), 0); } + #[test] + fn parse_duplicate_cidrs() { + let mut opts = Opts::default(); + opts.addresses = vec!["79.98.104.0/21".to_owned(), "79.98.104.0/24".to_owned()]; + + let ips = parse_addresses(&opts); + + assert_eq!(ips.len(), 2_048); + } + #[test] fn resolver_default_cloudflare() { let opts = Opts::default();