feat(measurement): integrate IRTT with full configuration and per-stream tracking
Build binaries / Build (aarch64-musl) (push) Successful in 1m37s
Build binaries / Build (arm-musleabi) (push) Successful in 1m37s
Build binaries / Build (arm-musleabihf) (push) Successful in 1m34s
Build binaries / Build (armv7-musleabi) (push) Successful in 1m37s
Build binaries / Build (armv7-musleabihf) (push) Successful in 1m45s
Build binaries / Build (i686-musl) (push) Successful in 2m1s
Build binaries / Build (mips-musl) (push) Successful in 2m13s
Build binaries / Build (mips64-muslabi64) (push) Successful in 2m16s
Build binaries / Build (mips64el-muslabi64) (push) Successful in 2m4s
Build binaries / Build (mipsel-musl) (push) Successful in 2m1s
Build binaries / Build (riscv64gc-musl) (push) Successful in 1m51s
Build binaries / Build (x86_64-musl) (push) Successful in 1m43s
Build binaries / Build (aarch64-musl) (push) Successful in 1m37s
Build binaries / Build (arm-musleabi) (push) Successful in 1m37s
Build binaries / Build (arm-musleabihf) (push) Successful in 1m34s
Build binaries / Build (armv7-musleabi) (push) Successful in 1m37s
Build binaries / Build (armv7-musleabihf) (push) Successful in 1m45s
Build binaries / Build (i686-musl) (push) Successful in 2m1s
Build binaries / Build (mips-musl) (push) Successful in 2m13s
Build binaries / Build (mips64-muslabi64) (push) Successful in 2m16s
Build binaries / Build (mips64el-muslabi64) (push) Successful in 2m4s
Build binaries / Build (mipsel-musl) (push) Successful in 2m1s
Build binaries / Build (riscv64gc-musl) (push) Successful in 1m51s
Build binaries / Build (x86_64-musl) (push) Successful in 1m43s
Extend reflector configuration to support IRTT-specific parameters (ports, HMAC) and track per-stream measurement state, enabling dynamic selection and authentication for IRTT probes.
This commit is contained in:
7 files changed
+366
-117
No files matched your search
+101
-25
@@ -23,16 +23,17 @@ use crate::baseliner::Baseliner;
|
||||
use crate::controller::Controller;
|
||||
use crate::measurement::icmp::IcmpEngine;
|
||||
use crate::measurement::irtt::IrttEngine;
|
||||
use crate::measurement::model::{MeasurementSource, MeasurementStream};
|
||||
use crate::metrics::{Metric, Metrics, MetricsSender};
|
||||
use crate::platform::{TrafficControlBackend, traffic_control_backend, warn_platform_limitations};
|
||||
use crate::ratecontroller::Ratecontroller;
|
||||
use crate::reflector_selector::ReflectorSelector;
|
||||
use crate::settings::Settings;
|
||||
use crate::settings::{ReflectorDefinition, ReflectorProtocol, Settings};
|
||||
use crate::util::RwLockExt;
|
||||
use ::log::{info, warn};
|
||||
use flume::RecvTimeoutError;
|
||||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use std::collections::HashMap;
|
||||
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::thread;
|
||||
@@ -40,8 +41,11 @@ use std::thread::{JoinHandle, sleep};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
struct ReflectorSetup {
|
||||
peers: Arc<RwLock<Vec<IpAddr>>>,
|
||||
pool: Vec<IpAddr>,
|
||||
peers: Arc<RwLock<Vec<SocketAddr>>>,
|
||||
active_streams: Arc<RwLock<Vec<MeasurementStream>>>,
|
||||
endpoint_streams: Arc<RwLock<HashMap<SocketAddr, MeasurementStream>>>,
|
||||
pool: Vec<SocketAddr>,
|
||||
reflectors: HashMap<SocketAddr, ReflectorDefinition>,
|
||||
reselection_enabled: bool,
|
||||
}
|
||||
pub static SHUTDOWN: AtomicBool = AtomicBool::new(false);
|
||||
@@ -135,29 +139,84 @@ fn restore_shaper<T: TrafficControlBackend>(
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_reflectors(
|
||||
definitions: &[ReflectorDefinition],
|
||||
protocol: ReflectorProtocol,
|
||||
countries: &[String],
|
||||
filter_country: bool,
|
||||
) -> anyhow::Result<HashMap<SocketAddr, ReflectorDefinition>> {
|
||||
let mut resolved = HashMap::new();
|
||||
for definition in definitions {
|
||||
if !definition.protocols.contains(&protocol) {
|
||||
continue;
|
||||
}
|
||||
if protocol != ReflectorProtocol::Irtt
|
||||
&& definition
|
||||
.host
|
||||
.parse::<IpAddr>()
|
||||
.is_ok_and(|ip| ip.is_ipv6())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if filter_country
|
||||
&& !countries.is_empty()
|
||||
&& !definition.country.as_ref().is_some_and(|country| {
|
||||
countries
|
||||
.iter()
|
||||
.any(|allowed| allowed.eq_ignore_ascii_case(country))
|
||||
})
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let port = if protocol == ReflectorProtocol::Irtt {
|
||||
definition.irtt_port.unwrap_or(2112)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
for endpoint in (definition.host.as_str(), port).to_socket_addrs()? {
|
||||
if protocol != ReflectorProtocol::Irtt && endpoint.is_ipv6() {
|
||||
continue;
|
||||
}
|
||||
resolved.insert(endpoint, definition.clone());
|
||||
}
|
||||
}
|
||||
Ok(resolved)
|
||||
}
|
||||
|
||||
fn setup_reflectors(settings: &Settings) -> anyhow::Result<ReflectorSetup> {
|
||||
let configured = settings.load_reflectors()?;
|
||||
let configured_count = configured.len();
|
||||
|
||||
let default_reflectors = [
|
||||
IpAddr::from_str("9.9.9.9")?,
|
||||
IpAddr::from_str("8.238.120.14")?,
|
||||
IpAddr::from_str("74.82.42.42")?,
|
||||
IpAddr::from_str("194.242.2.2")?,
|
||||
IpAddr::from_str("208.67.222.222")?,
|
||||
IpAddr::from_str("94.140.14.14")?,
|
||||
];
|
||||
|
||||
let reselection_enabled = configured_count > settings.reflectors.num_reflectors as usize;
|
||||
let pool = if reselection_enabled {
|
||||
let protocol = settings.advanced_settings.measurement_type;
|
||||
let configured = resolve_reflectors(
|
||||
&settings.reflectors.entries,
|
||||
protocol,
|
||||
&settings.reflectors.countries,
|
||||
true,
|
||||
)?;
|
||||
let bootstrap = resolve_reflectors(&settings.reflectors.bootstrap, protocol, &[], false)?;
|
||||
let mut reflectors = bootstrap.clone();
|
||||
reflectors.extend(
|
||||
configured
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
.iter()
|
||||
.map(|(endpoint, definition)| (*endpoint, definition.clone())),
|
||||
);
|
||||
let mut pool = configured.keys().copied().collect::<Vec<_>>();
|
||||
pool.sort();
|
||||
let mut initial = bootstrap.keys().copied().collect::<Vec<_>>();
|
||||
initial.sort();
|
||||
if initial.is_empty() {
|
||||
initial = pool
|
||||
.iter()
|
||||
.take(settings.reflectors.num_reflectors as usize)
|
||||
.copied()
|
||||
.collect();
|
||||
}
|
||||
let reselection_enabled = pool.len() > settings.reflectors.num_reflectors as usize;
|
||||
|
||||
Ok(ReflectorSetup {
|
||||
peers: Arc::new(RwLock::new(default_reflectors.to_vec())),
|
||||
peers: Arc::new(RwLock::new(initial)),
|
||||
active_streams: Arc::new(RwLock::new(Vec::new())),
|
||||
endpoint_streams: Arc::new(RwLock::new(HashMap::new())),
|
||||
pool,
|
||||
reflectors,
|
||||
reselection_enabled,
|
||||
})
|
||||
}
|
||||
@@ -230,7 +289,10 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
|
||||
|
||||
let ReflectorSetup {
|
||||
peers: reflector_peers,
|
||||
active_streams,
|
||||
endpoint_streams,
|
||||
pool: reflector_pool,
|
||||
reflectors,
|
||||
reselection_enabled,
|
||||
} = setup_reflectors(settings)?;
|
||||
|
||||
@@ -248,7 +310,20 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let controller = Controller::new(reflector_rx, icmp_binding_tx);
|
||||
let source = match settings.advanced_settings.measurement_type {
|
||||
ReflectorProtocol::IcmpEcho => MeasurementSource::IcmpEcho,
|
||||
ReflectorProtocol::IcmpTimestamps => MeasurementSource::IcmpTimestamp,
|
||||
ReflectorProtocol::Irtt => MeasurementSource::Irtt,
|
||||
};
|
||||
let controller = Controller::new(
|
||||
reflector_rx,
|
||||
icmp_binding_tx,
|
||||
irtt_binding_tx,
|
||||
reflectors,
|
||||
Arc::clone(&active_streams),
|
||||
Arc::clone(&endpoint_streams),
|
||||
source,
|
||||
);
|
||||
let icmp_engine = {
|
||||
let _guard = rt.enter();
|
||||
IcmpEngine::new(
|
||||
@@ -336,6 +411,7 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
|
||||
.expect("reselection snapshot receiver must exist when reselection is enabled"),
|
||||
reflector_peers_lock: Arc::clone(&reflector_peers),
|
||||
reflector_pool,
|
||||
endpoint_streams,
|
||||
trigger_channel: reselect_rx,
|
||||
metrics: event_metrics,
|
||||
reflector_tx,
|
||||
@@ -349,7 +425,7 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
|
||||
let mut ratecontroller = Ratecontroller::new(
|
||||
settings.clone(),
|
||||
control_snapshot_rx,
|
||||
reflector_peers,
|
||||
active_streams,
|
||||
reselect_tx,
|
||||
rate_metrics,
|
||||
)?;
|
||||
|
||||
Reference in new issue
Block a user