1 Commits

+53 -2
View File
@@ -13,6 +13,39 @@ pub const CF_IPV6_URL: &str = "https://www.cloudflare.com/ips-v6";
const USER_AGENT: &str = "cfopt/0.1";
/// Cloudflare's published IPv4 ranges, baked in as a fallback for when the
/// live fetch from CF_IPV4_URL is unreachable (offline, censored, etc.).
/// Source: https://www.cloudflare.com/ips-v4
const CF_IPV4_DEFAULTS: &str = "\
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
";
/// Cloudflare's published IPv6 ranges, baked in as a fallback.
/// Source: https://www.cloudflare.com/ips-v6
const CF_IPV6_DEFAULTS: &str = "\
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32
";
/// Which address families to fetch.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(dead_code)] // V4 / V6 reserved for a future --family CLI flag.
@@ -51,11 +84,23 @@ pub async fn fetch_ranges(family: Family) -> Result<CfRanges> {
let mut ranges = CfRanges::default();
if matches!(family, Family::V4 | Family::Both) {
let text = fetch_text(&client, CF_IPV4_URL).await?;
let text = match fetch_text(&client, CF_IPV4_URL).await {
Ok(text) => text,
Err(e) => {
eprintln!("warning: fetch {CF_IPV4_URL} failed ({e:#}); using built-in defaults");
CF_IPV4_DEFAULTS.to_string()
}
};
ranges.v4 = parse_v4_lines(&text);
}
if matches!(family, Family::V6 | Family::Both) {
let text = fetch_text(&client, CF_IPV6_URL).await?;
let text = match fetch_text(&client, CF_IPV6_URL).await {
Ok(text) => text,
Err(e) => {
eprintln!("warning: fetch {CF_IPV6_URL} failed ({e:#}); using built-in defaults");
CF_IPV6_DEFAULTS.to_string()
}
};
ranges.v6 = parse_v6_lines(&text);
}
Ok(ranges)
@@ -115,4 +160,10 @@ mod tests {
assert_eq!(parse_v6_lines(text).len(), 1);
assert_eq!(parse_v4_lines(text)[0].to_string(), "173.245.48.0/20");
}
#[test]
fn builtin_defaults_parse() {
assert_eq!(parse_v4_lines(CF_IPV4_DEFAULTS).len(), 15);
assert_eq!(parse_v6_lines(CF_IPV6_DEFAULTS).len(), 7);
}
}