fix: validate topology probe IP prefixes

This commit is contained in:
Herbert Wolverson committed 2026-06-23 09:22:21 -05:00
1 parent b14d07df52
commit 4df5b2017e
3 files changed
+31 -19

No files matched your search

+29 -6
View File
@@ -1796,11 +1796,23 @@ pub fn publish_topology_runtime_error_status(
}
fn parse_probe_ip(raw: &str) -> Option<IpAddr> {
raw.trim()
.split('/')
.next()
.filter(|value| !value.is_empty())
.and_then(|value| value.parse::<IpAddr>().ok())
let raw = raw.trim();
if raw.is_empty() {
return None;
}
let Some((addr, prefix)) = raw.split_once('/') else {
return raw.parse::<IpAddr>().ok();
};
if addr.is_empty() || prefix.is_empty() || prefix.contains('/') {
return None;
}
let ip = addr.parse::<IpAddr>().ok()?;
let prefix = prefix.parse::<u8>().ok()?;
match ip {
IpAddr::V4(_) if prefix <= 32 => Some(ip),
IpAddr::V6(_) if prefix <= 128 => Some(ip),
_ => None,
}
}
/// Returns the runtime stale cutoff in seconds for topology attachment health.
@@ -4597,7 +4609,7 @@ mod tests {
apply_health_to_option, auto_attachment_option, build_effective_topology_artifacts,
build_effective_topology_artifacts_from_canonical, build_shaping_inputs,
collect_direct_circuit_node_ids, collect_direct_circuit_node_names,
compute_effective_state, publish_effective_topology_artifacts,
compute_effective_state, parse_probe_ip, publish_effective_topology_artifacts,
publish_topology_runtime_error_status, ranked_auto_attachment_id,
validate_effective_topology_network,
};
@@ -4629,6 +4641,17 @@ mod tests {
path
}
#[test]
fn parse_probe_ip_rejects_invalid_cidr_suffixes() {
assert!(parse_probe_ip("192.0.2.1").is_some());
assert!(parse_probe_ip("192.0.2.1/32").is_some());
assert!(parse_probe_ip("2001:db8::1/128").is_some());
assert!(parse_probe_ip("192.0.2.1/not-a-prefix").is_none());
assert!(parse_probe_ip("192.0.2.1/33").is_none());
assert!(parse_probe_ip("2001:db8::1/129").is_none());
assert!(parse_probe_ip("192.0.2.1/24/extra").is_none());
}
fn apply_effective_topology_to_network_json(
config: &Config,
canonical_network: &Value,
+1 -3
View File
@@ -7,9 +7,7 @@ use std::collections::HashMap;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use crate::{AttachmentProbeSpec, is_health_state_fresh};
use super::probe::parse_probe_ip;
use crate::{AttachmentProbeSpec, is_health_state_fresh, parse_probe_ip};
pub(super) fn now_unix() -> Option<u64> {
lqos_utils::unix_time::unix_now().ok()
+1 -10
View File
@@ -2,12 +2,11 @@ use anyhow::Result;
use lqos_bus::{BusReply, BusRequest, BusResponse};
use lqos_probe::{ProbeClass, ProbeObservation, ProbeRequest};
use std::collections::HashMap;
use std::net::IpAddr;
use std::time::{Duration, Instant};
use tokio::sync::mpsc::error::TrySendError;
use tokio::sync::oneshot::error::TryRecvError;
use crate::AttachmentProbeSpec;
use crate::{AttachmentProbeSpec, parse_probe_ip};
use super::TopologyBusSender;
@@ -94,14 +93,6 @@ fn bus_call(
}
}
pub(super) fn parse_probe_ip(raw: &str) -> Option<IpAddr> {
raw.trim()
.split('/')
.next()
.filter(|value| !value.is_empty())
.and_then(|value| value.parse::<IpAddr>().ok())
}
pub(super) fn probe_specs(
bus_tx: TopologyBusSender,
specs: &[AttachmentProbeSpec],