diff --git a/docs/man/ntp.toml.5.md b/docs/man/ntp.toml.5.md index e3e4e368b..04ce9ff5b 100644 --- a/docs/man/ntp.toml.5.md +++ b/docs/man/ntp.toml.5.md @@ -55,20 +55,20 @@ with any of these options: # CONFIGURATION ## `[source-defaults]` -Some values are shared between all sources in the daemon. You can configure -these in the `[source-defaults]` section. +Some of the behavior of a source is configurable. You can set defaults for those +settings in the `[source-defaults]` section. `poll-interval-limits` = { `min` = *min*, `max` = *max* } (**{ min = 4, max = 10}**) : Specifies the limit on how often a source is queried for a new time. For most instances the defaults will be adequate. The min and max are given as the log2 of the number of seconds (i.e. two to the power of the interval). - An interval of 4 equates to 32 seconds, 10 results in an interval of 1024 + An interval of 4 equates to 16 seconds, 10 results in an interval of 1024 seconds. If specified, both min and max must be specified. `initial-poll-interval` = *interval* (**4**) : Initial poll interval used on startup. The value is given as the log2 of the number of seconds (i.e. two to the power of the interval). The default - value of 4 results in an interval of 32 seconds. + value of 4 results in an interval of 16 seconds. ## `[[source]]` Each `[[source]]` is a set of one or more time sources for the daemon to @@ -111,6 +111,19 @@ sources. : `pool` mode only. Specifies a list of IP addresses of servers in the pool which should not be used. For example: `["127.0.0.1"]`. Empty by default. +`poll-interval-limits` = { `min` = *min*, `max` = *max* } (defaults from `[source-defaults]`) +: Specifies the limit on how often a source is queried for a new time. For + most instances the defaults will be adequate. The min and max are given as + the log2 of the number of seconds (i.e. two to the power of the interval). + An interval of 4 equates to 16 seconds, 10 results in an interval of 1024 + seconds. If only one of the two boundaries is specified, the other is + inherited from `[source-defaults]` + +`initial-poll-interval` = *interval* (defaults from `[source-defaults]`) +: Initial poll interval used on startup. The value is given as the log2 of + the number of seconds (i.e. two to the power of the interval). The default + value of 4 results in an interval of 16 seconds. + ## `[[server]]` The NTP daemon can be configured to distribute time via any number of `[[server]]` sections. If no such sections have been defined, the daemon runs in diff --git a/docs/precompiled/man/ntp.toml.5 b/docs/precompiled/man/ntp.toml.5 index e36b8c7f3..1b8335927 100644 --- a/docs/precompiled/man/ntp.toml.5 +++ b/docs/precompiled/man/ntp.toml.5 @@ -76,15 +76,16 @@ As these devices only provide periodic data, they do not count towards .SH CONFIGURATION .SS \f[V][source-defaults]\f[R] .PP -Some values are shared between all sources in the daemon. -You can configure these in the \f[V][source-defaults]\f[R] section. +Some of the behavior of a source is configurable. +You can set defaults for those settings in the +\f[V][source-defaults]\f[R] section. .TP \f[V]poll-interval-limits\f[R] = { \f[V]min\f[R] = \f[I]min\f[R], \f[V]max\f[R] = \f[I]max\f[R] } (\f[B]{ min = 4, max = 10}\f[R]) Specifies the limit on how often a source is queried for a new time. For most instances the defaults will be adequate. The min and max are given as the log2 of the number of seconds (i.e.\ two to the power of the interval). -An interval of 4 equates to 32 seconds, 10 results in an interval of +An interval of 4 equates to 16 seconds, 10 results in an interval of 1024 seconds. If specified, both min and max must be specified. .TP @@ -92,7 +93,7 @@ If specified, both min and max must be specified. Initial poll interval used on startup. The value is given as the log2 of the number of seconds (i.e.\ two to the power of the interval). -The default value of 4 results in an interval of 32 seconds. +The default value of 4 results in an interval of 16 seconds. .SS \f[V][[source]]\f[R] .PP Each \f[V][[source]]\f[R] is a set of one or more time sources for the @@ -144,6 +145,22 @@ Specifies a list of IP addresses of servers in the pool which should not be used. For example: \f[V][\[dq]127.0.0.1\[dq]]\f[R]. Empty by default. +.TP +\f[V]poll-interval-limits\f[R] = { \f[V]min\f[R] = \f[I]min\f[R], \f[V]max\f[R] = \f[I]max\f[R] } (defaults from \f[V][source-defaults]\f[R]) +Specifies the limit on how often a source is queried for a new time. +For most instances the defaults will be adequate. +The min and max are given as the log2 of the number of seconds +(i.e.\ two to the power of the interval). +An interval of 4 equates to 16 seconds, 10 results in an interval of +1024 seconds. +If only one of the two boundaries is specified, the other is inherited +from \f[V][source-defaults]\f[R] +.TP +\f[V]initial-poll-interval\f[R] = \f[I]interval\f[R] (defaults from \f[V][source-defaults]\f[R]) +Initial poll interval used on startup. +The value is given as the log2 of the number of seconds (i.e.\ two to +the power of the interval). +The default value of 4 results in an interval of 16 seconds. .SS \f[V][[server]]\f[R] .PP The NTP daemon can be configured to distribute time via any number of diff --git a/ntp-proto/src/algorithm/kalman/mod.rs b/ntp-proto/src/algorithm/kalman/mod.rs index 05e499c24..4dd168b6f 100644 --- a/ntp-proto/src/algorithm/kalman/mod.rs +++ b/ntp-proto/src/algorithm/kalman/mod.rs @@ -6,7 +6,7 @@ use tracing::{debug, error, info}; use crate::{ clock::NtpClock, - config::{SourceDefaultsConfig, SynchronizationConfig}, + config::{SourceConfig, SynchronizationConfig}, packet::NtpLeapIndicator, system::TimeSnapshot, time_types::{NtpDuration, NtpTimestamp}, @@ -89,7 +89,6 @@ pub struct KalmanClockController>, bool)>, clock: C, synchronization_config: SynchronizationConfig, - source_defaults_config: SourceDefaultsConfig, algo_config: AlgorithmConfig, freq_offset: f64, timedata: TimeSnapshot, @@ -362,7 +361,6 @@ impl TimeSyncC fn new( clock: C, synchronization_config: SynchronizationConfig, - source_defaults_config: SourceDefaultsConfig, algo_config: Self::AlgorithmConfig, ) -> Result { // Setup clock @@ -372,7 +370,6 @@ impl TimeSyncC sources: HashMap::new(), clock, synchronization_config, - source_defaults_config, algo_config, freq_offset, desired_freq: 0.0, @@ -387,13 +384,17 @@ impl TimeSyncC Ok(()) } - fn add_source(&mut self, id: SourceId) -> Self::NtpSourceController { + fn add_source( + &mut self, + id: SourceId, + source_config: SourceConfig, + ) -> Self::NtpSourceController { self.sources.insert(id, (None, false)); KalmanSourceController::new( id, self.algo_config, None, - self.source_defaults_config, + source_config, AveragingBuffer::default(), ) } @@ -401,6 +402,7 @@ impl TimeSyncC fn add_one_way_source( &mut self, id: SourceId, + source_config: SourceConfig, measurement_noise_estimate: f64, period: Option, ) -> Self::OneWaySourceController { @@ -409,7 +411,7 @@ impl TimeSyncC id, self.algo_config, period, - self.source_defaults_config, + source_config, measurement_noise_estimate, ) } @@ -508,14 +510,13 @@ mod tests { ..SynchronizationConfig::default() }; let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); + let source_config = SourceConfig::default(); let mut algo = KalmanClockController::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -524,7 +525,7 @@ mod tests { // ignore startup steer of frequency. *algo.clock.has_steered.borrow_mut() = false; - let mut source = algo.add_source(0); + let mut source = algo.add_source(0, source_config); algo.source_update(0, true); assert!(algo.in_startup); @@ -576,14 +577,12 @@ mod tests { step_threshold: 1800.0, ..Default::default() }; - let source_defaults_config = SourceDefaultsConfig::default(); let mut algo = KalmanClockController::<_, u32>::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -606,14 +605,12 @@ mod tests { ..SynchronizationConfig::default() }; let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); let mut algo = KalmanClockController::<_, u32>::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -627,14 +624,12 @@ mod tests { fn test_jumps_update_state() { let synchronization_config = SynchronizationConfig::default(); let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); let mut algo = KalmanClockController::<_, u32>::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -702,14 +697,12 @@ mod tests { fn test_freqsteer_update_state() { let synchronization_config = SynchronizationConfig::default(); let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); let mut algo = KalmanClockController::<_, u32>::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -748,14 +741,13 @@ mod tests { ..SynchronizationConfig::default() }; let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); + let source_config = SourceConfig::default(); let mut algo = KalmanClockController::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -764,7 +756,7 @@ mod tests { // ignore startup steer of frequency. *algo.clock.has_steered.borrow_mut() = false; - let mut source = algo.add_source(0); + let mut source = algo.add_source(0, source_config); algo.source_update(0, true); let mut noise = 1e-9; @@ -807,14 +799,13 @@ mod tests { ..SynchronizationConfig::default() }; let algo_config = AlgorithmConfig::default(); - let source_defaults_config = SourceDefaultsConfig::default(); + let source_config = SourceConfig::default(); let mut algo = KalmanClockController::new( TestClock { has_steered: RefCell::new(false), current_time: NtpTimestamp::from_fixed_int(0), }, synchronization_config, - source_defaults_config, algo_config, ) .unwrap(); @@ -823,7 +814,7 @@ mod tests { // ignore startup steer of frequency. *algo.clock.has_steered.borrow_mut() = false; - let mut source = algo.add_source(0); + let mut source = algo.add_source(0, source_config); algo.source_update(0, true); let mut noise = 1e-9; diff --git a/ntp-proto/src/algorithm/kalman/source.rs b/ntp-proto/src/algorithm/kalman/source.rs index 5ae751c07..fefbe5ee9 100644 --- a/ntp-proto/src/algorithm/kalman/source.rs +++ b/ntp-proto/src/algorithm/kalman/source.rs @@ -77,7 +77,7 @@ use tracing::{debug, trace}; use crate::{ algorithm::{KalmanControllerMessage, KalmanSourceMessage, SourceController}, - config::SourceDefaultsConfig, + config::SourceConfig, source::Measurement, time_types::{NtpDuration, NtpTimestamp, PollInterval, PollIntervalLimits}, ObservableSourceTimedata, @@ -533,7 +533,7 @@ impl /// not so much that each individual poll message gives us very little new information. fn update_desired_poll( &mut self, - source_defaults_config: &SourceDefaultsConfig, + source_config: &SourceConfig, algo_config: &AlgorithmConfig, p: f64, weight: f64, @@ -554,18 +554,18 @@ impl } trace!(poll_score = self.poll_score, ?weight, "Poll desire update"); if p <= algo_config.poll_interval_step_threshold { - self.desired_poll_interval = source_defaults_config.poll_interval_limits.min; + self.desired_poll_interval = source_config.poll_interval_limits.min; self.poll_score = 0; } else if self.poll_score <= -algo_config.poll_interval_hysteresis { self.desired_poll_interval = self .desired_poll_interval - .inc(source_defaults_config.poll_interval_limits); + .inc(source_config.poll_interval_limits); self.poll_score = 0; debug!(interval = ?self.desired_poll_interval, "Increased poll interval"); } else if self.poll_score >= algo_config.poll_interval_hysteresis { self.desired_poll_interval = self .desired_poll_interval - .dec(source_defaults_config.poll_interval_limits); + .dec(source_config.poll_interval_limits); self.poll_score = 0; debug!(interval = ?self.desired_poll_interval, "Decreased poll interval"); } @@ -611,7 +611,7 @@ impl /// Update our estimates based on a new measurement. fn update( &mut self, - source_defaults_config: &SourceDefaultsConfig, + source_config: &SourceConfig, algo_config: &AlgorithmConfig, measurement: Measurement, period: Option, @@ -648,13 +648,7 @@ impl let (p, weight, measurement_period) = self.absorb_measurement(measurement, period); self.update_wander_estimate(algo_config, p, weight); - self.update_desired_poll( - source_defaults_config, - algo_config, - p, - weight, - measurement_period, - ); + self.update_desired_poll(source_config, algo_config, p, weight, measurement_period); debug!( "source offset {}±{}ms, freq {}±{}ppm", @@ -719,7 +713,7 @@ impl // Returns whether the clock may need adjusting. pub fn update_self_using_measurement( &mut self, - source_defaults_config: &SourceDefaultsConfig, + source_config: &SourceConfig, algo_config: &AlgorithmConfig, mut measurement: Measurement, period: Option, @@ -731,17 +725,12 @@ impl }; measurement.delay = noise_estimator.preprocess(measurement.delay); - self.update_self_using_raw_measurement( - source_defaults_config, - algo_config, - measurement, - period, - ) + self.update_self_using_raw_measurement(source_config, algo_config, measurement, period) } fn update_self_using_raw_measurement( &mut self, - source_defaults_config: &SourceDefaultsConfig, + source_config: &SourceConfig, algo_config: &AlgorithmConfig, measurement: Measurement, period: Option, @@ -764,7 +753,7 @@ impl noise_estimator: filter.noise_estimator.clone(), precision_score: 0, poll_score: 0, - desired_poll_interval: source_defaults_config.initial_poll_interval, + desired_poll_interval: source_config.initial_poll_interval, last_measurement: measurement, prev_was_outlier: false, last_iter: measurement.localtime, @@ -799,7 +788,7 @@ impl false } else { - filter.update(source_defaults_config, algo_config, measurement, period) + filter.update(source_config, algo_config, measurement, period) } } } @@ -903,7 +892,7 @@ pub struct KalmanSourceController< state: SourceState, period: Option, algo_config: AlgorithmConfig, - source_defaults_config: SourceDefaultsConfig, + source_config: SourceConfig, } pub type TwoWayKalmanSourceController = @@ -921,7 +910,7 @@ impl< index: SourceId, algo_config: AlgorithmConfig, period: Option, - source_defaults_config: SourceDefaultsConfig, + source_config: SourceConfig, noise_estimator: N, ) -> Self { KalmanSourceController { @@ -929,7 +918,7 @@ impl< state: SourceState::new(noise_estimator), period, algo_config, - source_defaults_config, + source_config, } } } @@ -960,7 +949,7 @@ impl< measurement: Measurement, ) -> Option { if self.state.update_self_using_measurement( - &self.source_defaults_config, + &self.source_config, &self.algo_config, measurement, self.period, @@ -975,7 +964,7 @@ impl< fn desired_poll_interval(&self) -> PollInterval { self.state - .get_desired_poll(&self.source_defaults_config.poll_interval_limits) + .get_desired_poll(&self.source_config.poll_interval_limits) } fn observe(&self) -> super::super::ObservableSourceTimedata { @@ -1034,7 +1023,7 @@ mod tests { last_iter: base, })); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -1083,7 +1072,7 @@ mod tests { })); source.process_offset_steering(-1800.0, None); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -1132,7 +1121,7 @@ mod tests { })); source.process_offset_steering(1800.0, None); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -1237,7 +1226,7 @@ mod tests { ); source.update_self_using_raw_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1314,7 +1303,7 @@ mod tests { ); source.update_self_using_raw_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1469,7 +1458,7 @@ mod tests { })); source.update_self_using_raw_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1507,7 +1496,7 @@ mod tests { .snapshot(0_usize, &AlgorithmConfig::default(), None) .is_none()); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1532,7 +1521,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1557,7 +1546,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1582,7 +1571,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1607,7 +1596,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1632,7 +1621,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1657,7 +1646,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1682,7 +1671,7 @@ mod tests { < 0.5001 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::ZERO, @@ -1844,7 +1833,7 @@ mod tests { .snapshot(0_usize, &AlgorithmConfig::default(), None) .is_none()); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1869,7 +1858,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1894,7 +1883,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1919,7 +1908,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1944,7 +1933,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1969,7 +1958,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -1994,7 +1983,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -2019,7 +2008,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay, @@ -2081,7 +2070,7 @@ mod tests { .snapshot(0_usize, &AlgorithmConfig::default(), None) .is_none()); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2106,7 +2095,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2131,7 +2120,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2156,7 +2145,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2182,7 +2171,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2207,7 +2196,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2232,7 +2221,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2257,7 +2246,7 @@ mod tests { > 1.0 ); source.update_self_using_measurement( - &SourceDefaultsConfig::default(), + &SourceConfig::default(), &AlgorithmConfig::default(), Measurement { delay: NtpDuration::from_seconds(0.0), @@ -2296,7 +2285,7 @@ mod tests { #[test] fn test_poll_duration_variation() { - let config = SourceDefaultsConfig::default(); + let config = SourceConfig::default(); let algo_config = AlgorithmConfig { poll_interval_hysteresis: 2, ..Default::default() diff --git a/ntp-proto/src/algorithm/mod.rs b/ntp-proto/src/algorithm/mod.rs index 87578363b..be66971da 100644 --- a/ntp-proto/src/algorithm/mod.rs +++ b/ntp-proto/src/algorithm/mod.rs @@ -4,7 +4,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{ clock::NtpClock, - config::{SourceDefaultsConfig, SynchronizationConfig}, + config::{SourceConfig, SynchronizationConfig}, source::Measurement, system::TimeSnapshot, time_types::{NtpDuration, NtpTimestamp}, @@ -70,7 +70,6 @@ pub trait TimeSyncController: Sized + Send + 'static { fn new( clock: Self::Clock, synchronization_config: SynchronizationConfig, - source_defaults_config: SourceDefaultsConfig, algorithm_config: Self::AlgorithmConfig, ) -> Result::Error>; @@ -78,11 +77,16 @@ pub trait TimeSyncController: Sized + Send + 'static { fn take_control(&mut self) -> Result<(), ::Error>; /// Create a new source with given identity - fn add_source(&mut self, id: Self::SourceId) -> Self::NtpSourceController; + fn add_source( + &mut self, + id: Self::SourceId, + source_config: SourceConfig, + ) -> Self::NtpSourceController; /// Create a new one way source with given identity (used e.g. with GPS sock sources) fn add_one_way_source( &mut self, id: Self::SourceId, + source_config: SourceConfig, measurement_noise_estimate: f64, period: Option, ) -> Self::OneWaySourceController; diff --git a/ntp-proto/src/config.rs b/ntp-proto/src/config.rs index 0004f2b6e..6d6aa5ee5 100644 --- a/ntp-proto/src/config.rs +++ b/ntp-proto/src/config.rs @@ -197,7 +197,7 @@ impl<'de> Deserialize<'de> for StepThreshold { #[derive(Deserialize, Debug, Clone, Copy)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] -pub struct SourceDefaultsConfig { +pub struct SourceConfig { /// Minima and maxima for the poll interval of clients #[serde(default)] pub poll_interval_limits: PollIntervalLimits, @@ -207,7 +207,7 @@ pub struct SourceDefaultsConfig { pub initial_poll_interval: PollInterval, } -impl Default for SourceDefaultsConfig { +impl Default for SourceConfig { fn default() -> Self { Self { poll_interval_limits: Default::default(), diff --git a/ntp-proto/src/lib.rs b/ntp-proto/src/lib.rs index fab02f281..20bf067a3 100644 --- a/ntp-proto/src/lib.rs +++ b/ntp-proto/src/lib.rs @@ -42,7 +42,7 @@ mod exports { TimeSyncController, TwoWayKalmanSourceController, }; pub use super::clock::NtpClock; - pub use super::config::{SourceDefaultsConfig, StepThreshold, SynchronizationConfig}; + pub use super::config::{SourceConfig, StepThreshold, SynchronizationConfig}; pub use super::identifiers::ReferenceId; #[cfg(feature = "__internal-fuzz")] pub use super::ipfilter::fuzz::fuzz_ipfilter; diff --git a/ntp-proto/src/source.rs b/ntp-proto/src/source.rs index 6cb4539d2..3df87ef60 100644 --- a/ntp-proto/src/source.rs +++ b/ntp-proto/src/source.rs @@ -5,7 +5,7 @@ use crate::packet::{ }; use crate::{ algorithm::{ObservableSourceTimedata, SourceController}, - config::SourceDefaultsConfig, + config::SourceConfig, cookiestash::CookieStash, identifiers::ReferenceId, packet::{Cipher, NtpAssociationMode, NtpLeapIndicator, NtpPacket, RequestIdentifier}, @@ -81,7 +81,7 @@ pub struct NtpSource { impl> NtpSource { pub(crate) fn new( source_addr: SocketAddr, - source_defaults_config: SourceDefaultsConfig, + source_config: SourceConfig, protocol_version: ProtocolVersion, controller: Controller, nts: Option>, @@ -496,8 +496,8 @@ impl> NtpSource> NtpSource> NtpSource> NtpSource { synchronization_config: SynchronizationConfig, - source_defaults_config: SourceDefaultsConfig, system: SystemSnapshot, ip_list: Arc<[IpAddr]>, @@ -201,7 +200,6 @@ impl, ) -> Result::Error> { @@ -218,16 +216,10 @@ impl Result< OneWaySource, ::Error, > { self.ensure_controller_control()?; - let controller = self - .controller - .add_one_way_source(id, measurement_noise_estimate, None); + let controller = + self.controller + .add_one_way_source(id, source_config, measurement_noise_estimate, None); self.sources.insert(id, None); Ok(OneWaySource::new(controller)) } @@ -267,6 +260,7 @@ impl Result< @@ -274,9 +268,12 @@ impl::Error, > { self.ensure_controller_control()?; - let controller = - self.controller - .add_one_way_source(id, measurement_noise_estimate, Some(period)); + let controller = self.controller.add_one_way_source( + id, + source_config, + measurement_noise_estimate, + Some(period), + ); self.sources.insert(id, None); Ok(OneWaySource::new(controller)) } @@ -285,6 +282,7 @@ impl>, @@ -296,11 +294,11 @@ impl::Error, > { self.ensure_controller_control()?; - let controller = self.controller.add_source(id); + let controller = self.controller.add_source(id, source_config); self.sources.insert(id, None); Ok(NtpSource::new( source_addr, - self.source_defaults_config, + source_config, protocol_version, controller, nts, diff --git a/ntpd/src/daemon/config/mod.rs b/ntpd/src/daemon/config/mod.rs index c406c51f7..963ee89f2 100644 --- a/ntpd/src/daemon/config/mod.rs +++ b/ntpd/src/daemon/config/mod.rs @@ -5,7 +5,7 @@ pub mod subnet; use clock_steering::unix::UnixClock; #[cfg(feature = "unstable_ntpv5")] use ntp_proto::NtpVersion; -use ntp_proto::{AlgorithmConfig, SourceDefaultsConfig, SynchronizationConfig}; +use ntp_proto::{AlgorithmConfig, SourceConfig, SynchronizationConfig}; pub use ntp_source::*; use serde::{Deserialize, Deserializer}; pub use server::*; @@ -362,7 +362,7 @@ pub struct Config { #[serde(default)] pub synchronization: DaemonSynchronizationConfig, #[serde(default)] - pub source_defaults: SourceDefaultsConfig, + pub source_defaults: SourceConfig, #[serde(default)] pub observability: ObservabilityConfig, #[serde(default)] @@ -441,9 +441,9 @@ impl Config { match source { NtpSourceConfig::Standard(_) => count += 1, NtpSourceConfig::Nts(_) => count += 1, - NtpSourceConfig::Pool(config) => count += config.count, + NtpSourceConfig::Pool(config) => count += config.first.count, #[cfg(feature = "unstable_nts-pool")] - NtpSourceConfig::NtsPool(config) => count += config.count, + NtpSourceConfig::NtsPool(config) => count += config.first.count, NtpSourceConfig::Sock(_) => count += 1, NtpSourceConfig::Pps(_) => {} // PPS sources don't count } @@ -479,11 +479,19 @@ impl Config { if self.sources.iter().any(|config| match config { NtpSourceConfig::Sock(_) => false, NtpSourceConfig::Pps(_) => false, - NtpSourceConfig::Standard(config) => matches!(config.ntp_version, Some(NtpVersion::V5)), - NtpSourceConfig::Nts(config) => matches!(config.ntp_version, Some(NtpVersion::V5)), - NtpSourceConfig::Pool(config) => matches!(config.ntp_version, Some(NtpVersion::V5)), + NtpSourceConfig::Standard(config) => { + matches!(config.first.ntp_version, Some(NtpVersion::V5)) + } + NtpSourceConfig::Nts(config) => { + matches!(config.first.ntp_version, Some(NtpVersion::V5)) + } + NtpSourceConfig::Pool(config) => { + matches!(config.first.ntp_version, Some(NtpVersion::V5)) + } #[cfg(feature = "unstable_nts-pool")] - NtpSourceConfig::NtsPool(config) => matches!(config.ntp_version, Some(NtpVersion::V5)), + NtpSourceConfig::NtsPool(config) => { + matches!(config.first.ntp_version, Some(NtpVersion::V5)) + } }) { warn!("Forcing a source into NTPv5, which is still a draft. There is no guarantee that the server will remain compatible with this or future versions of ntpd-rs."); ok = false; @@ -534,10 +542,13 @@ mod tests { toml::from_str("[[source]]\nmode = \"server\"\naddress = \"example.com\"").unwrap(); assert_eq!( config.sources, - vec![NtpSourceConfig::Standard(StandardSource { - address: NormalizedAddress::new_unchecked("example.com", 123).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, + vec![NtpSourceConfig::Standard(FlattenedPair { + first: StandardSource { + address: NormalizedAddress::new_unchecked("example.com", 123).into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + second: Default::default() })] ); assert!(config.observability.log_level.is_none()); @@ -549,10 +560,13 @@ mod tests { assert_eq!(config.observability.log_level, Some(LogLevel::Info)); assert_eq!( config.sources, - vec![NtpSourceConfig::Standard(StandardSource { - address: NormalizedAddress::new_unchecked("example.com", 123).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, + vec![NtpSourceConfig::Standard(FlattenedPair { + first: StandardSource { + address: NormalizedAddress::new_unchecked("example.com", 123).into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + second: Default::default() })] ); @@ -562,10 +576,13 @@ mod tests { .unwrap(); assert_eq!( config.sources, - vec![NtpSourceConfig::Standard(StandardSource { - address: NormalizedAddress::new_unchecked("example.com", 123).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, + vec![NtpSourceConfig::Standard(FlattenedPair { + first: StandardSource { + address: NormalizedAddress::new_unchecked("example.com", 123).into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + second: Default::default() })] ); assert_eq!( @@ -591,10 +608,13 @@ mod tests { .unwrap(); assert_eq!( config.sources, - vec![NtpSourceConfig::Standard(StandardSource { - address: NormalizedAddress::new_unchecked("example.com", 123).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, + vec![NtpSourceConfig::Standard(FlattenedPair { + first: StandardSource { + address: NormalizedAddress::new_unchecked("example.com", 123).into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + second: Default::default() })] ); assert!(config @@ -635,10 +655,13 @@ mod tests { assert_eq!( config.sources, - vec![NtpSourceConfig::Standard(StandardSource { - address: NormalizedAddress::new_unchecked("example.com", 123).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, + vec![NtpSourceConfig::Standard(FlattenedPair { + first: StandardSource { + address: NormalizedAddress::new_unchecked("example.com", 123).into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + second: Default::default() })] ); diff --git a/ntpd/src/daemon/config/ntp_source.rs b/ntpd/src/daemon/config/ntp_source.rs index 99487d4eb..41b1cf7c0 100644 --- a/ntpd/src/daemon/config/ntp_source.rs +++ b/ntpd/src/daemon/config/ntp_source.rs @@ -9,6 +9,7 @@ use std::{ use ntp_proto::tls_utils::Certificate; #[cfg(feature = "unstable_ntpv5")] use ntp_proto::NtpVersion; +use ntp_proto::{PollInterval, PollIntervalLimits, SourceConfig}; use serde::{de, Deserialize, Deserializer}; use super::super::keyexchange::certificates_from_file; @@ -116,6 +117,53 @@ pub struct SockSourceConfig { pub measurement_noise_estimate: f64, } +#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)] +#[serde(deny_unknown_fields)] +pub struct PartialPollIntervalLimits { + pub min: Option, + pub max: Option, +} + +#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +pub struct PartialSourceConfig { + /// Minima and maxima for the poll interval of clients + #[serde(default)] + pub poll_interval_limits: PartialPollIntervalLimits, + + /// Initial poll interval of the system + pub initial_poll_interval: Option, +} + +impl PartialSourceConfig { + pub fn with_defaults(self, defaults: SourceConfig) -> SourceConfig { + SourceConfig { + poll_interval_limits: PollIntervalLimits { + min: self + .poll_interval_limits + .min + .unwrap_or(defaults.poll_interval_limits.min), + max: self + .poll_interval_limits + .max + .unwrap_or(defaults.poll_interval_limits.max), + }, + initial_poll_interval: self + .initial_poll_interval + .unwrap_or(defaults.initial_poll_interval), + } + } +} + +#[derive(Deserialize, Debug, PartialEq, Clone, Default)] +#[serde(deny_unknown_fields)] +pub struct FlattenedPair { + #[serde(flatten)] + pub first: T, + #[serde(flatten)] + pub second: U, +} + #[derive(Deserialize, Debug, PartialEq, Clone)] #[serde(deny_unknown_fields)] pub struct PpsSourceConfig { @@ -133,14 +181,14 @@ fn default_period() -> f64 { #[serde(tag = "mode")] pub enum NtpSourceConfig { #[serde(rename = "server")] - Standard(StandardSource), + Standard(FlattenedPair), #[serde(rename = "nts")] - Nts(NtsSourceConfig), + Nts(FlattenedPair), #[serde(rename = "pool")] - Pool(PoolSourceConfig), + Pool(FlattenedPair), #[cfg(feature = "unstable_nts-pool")] #[serde(rename = "nts-pool")] - NtsPool(NtsPoolSourceConfig), + NtsPool(FlattenedPair), #[serde(rename = "sock")] Sock(SockSourceConfig), #[serde(rename = "pps")] @@ -373,7 +421,12 @@ impl<'a> TryFrom<&'a str> for NtpSourceConfig { type Error = std::io::Error; fn try_from(value: &'a str) -> Result { - StandardSource::try_from(value).map(Self::Standard) + StandardSource::try_from(value).map(|first| { + Self::Standard(FlattenedPair { + first, + second: Default::default(), + }) + }) } } @@ -383,11 +436,11 @@ mod tests { fn source_addr(config: &NtpSourceConfig) -> String { match config { - NtpSourceConfig::Standard(c) => c.address.to_string(), - NtpSourceConfig::Nts(c) => c.address.to_string(), - NtpSourceConfig::Pool(c) => c.addr.to_string(), + NtpSourceConfig::Standard(c) => c.first.address.to_string(), + NtpSourceConfig::Nts(c) => c.first.address.to_string(), + NtpSourceConfig::Pool(c) => c.first.addr.to_string(), #[cfg(feature = "unstable_nts-pool")] - NtpSourceConfig::NtsPool(c) => c.addr.to_string(), + NtpSourceConfig::NtsPool(c) => c.first.addr.to_string(), NtpSourceConfig::Sock(_c) => "".to_string(), NtpSourceConfig::Pps(_c) => "".to_string(), } @@ -444,7 +497,7 @@ mod tests { assert!(matches!(test.source, NtpSourceConfig::Pool(_))); assert_eq!(source_addr(&test.source), "example.com:123"); if let NtpSourceConfig::Pool(config) = test.source { - assert_eq!(config.count, 4); + assert_eq!(config.first.count, 4); } let test: TestConfig = toml::from_str( @@ -459,7 +512,7 @@ mod tests { assert!(matches!(test.source, NtpSourceConfig::Pool(_))); assert_eq!(source_addr(&test.source), "example.com:123"); if let NtpSourceConfig::Pool(config) = test.source { - assert_eq!(config.count, 42); + assert_eq!(config.first.count, 42); } let test: TestConfig = toml::from_str( @@ -524,6 +577,35 @@ mod tests { assert!(matches!(source, NtpSourceConfig::Standard(_))); } + #[test] + fn test_source_config_parsing() { + #[derive(Deserialize, Debug)] + struct TestConfig { + #[allow(unused)] + source: NtpSourceConfig, + } + + let test: Result = toml::from_str( + r#" + [source] + mode = "server" + address = "example.com" + initial-poll-interval = 7 + "#, + ); + assert!(test.is_ok()); + + let test2: Result = toml::from_str( + r#" + [source] + mode = "server" + address = "example.com" + does-not-exist = 7 + "#, + ); + assert!(test2.is_err()); + } + #[test] fn test_normalize_addr() { let addr = NormalizedAddress::from_string_ntp("[::1]:456".into()).unwrap(); diff --git a/ntpd/src/daemon/ntp_source.rs b/ntpd/src/daemon/ntp_source.rs index 34b4de1fc..f3863fdc3 100644 --- a/ntpd/src/daemon/ntp_source.rs +++ b/ntpd/src/daemon/ntp_source.rs @@ -452,7 +452,7 @@ mod tests { use ntp_proto::{ AlgorithmConfig, KalmanClockController, KalmanControllerMessage, KalmanSourceMessage, - NoCipher, NtpDuration, NtpLeapIndicator, NtpPacket, ProtocolVersion, SourceDefaultsConfig, + NoCipher, NtpDuration, NtpLeapIndicator, NtpPacket, ProtocolVersion, SourceConfig, SynchronizationConfig, SystemSnapshot, TimeSnapshot, TwoWayKalmanSourceController, }; use timestamped_socket::socket::{open_ip, GeneralTimestampMode, Open}; @@ -599,7 +599,6 @@ mod tests { let mut system: ntp_proto::System<_, KalmanClockController<_, _>> = ntp_proto::System::new( TestClock {}, SynchronizationConfig::default(), - SourceDefaultsConfig::default(), AlgorithmConfig::default(), Arc::new([]), ) @@ -607,6 +606,7 @@ mod tests { let Ok((source, _)) = system.create_ntp_source( index, + SourceConfig::default(), SocketAddr::from((Ipv4Addr::LOCALHOST, port_base)), ProtocolVersion::default(), None, diff --git a/ntpd/src/daemon/sock_source.rs b/ntpd/src/daemon/sock_source.rs index 677c9fea8..424e8f0bd 100644 --- a/ntpd/src/daemon/sock_source.rs +++ b/ntpd/src/daemon/sock_source.rs @@ -244,7 +244,7 @@ mod tests { use ntp_proto::{ AlgorithmConfig, KalmanClockController, NtpClock, NtpDuration, NtpLeapIndicator, - NtpTimestamp, ReferenceId, SourceDefaultsConfig, SynchronizationConfig, + NtpTimestamp, ReferenceId, SourceConfig, SynchronizationConfig, }; use tokio::sync::mpsc; @@ -318,7 +318,6 @@ mod tests { let mut system: ntp_proto::System<_, KalmanClockController<_, _>> = ntp_proto::System::new( clock.clone(), SynchronizationConfig::default(), - SourceDefaultsConfig::default(), AlgorithmConfig::default(), Arc::new([]), ) @@ -336,7 +335,9 @@ mod tests { system_update_receiver, source_snapshots: Arc::new(RwLock::new(HashMap::new())), }, - system.create_sock_source(index, 0.001).unwrap(), + system + .create_sock_source(index, SourceConfig::default(), 0.001) + .unwrap(), ); // Send example data to socket diff --git a/ntpd/src/daemon/spawn/mod.rs b/ntpd/src/daemon/spawn/mod.rs index 98d881af3..a6d2b54d7 100644 --- a/ntpd/src/daemon/spawn/mod.rs +++ b/ntpd/src/daemon/spawn/mod.rs @@ -1,6 +1,6 @@ use std::{net::SocketAddr, path::PathBuf, sync::atomic::AtomicU64}; -use ntp_proto::{ProtocolVersion, SourceNtsData}; +use ntp_proto::{ProtocolVersion, SourceConfig, SourceNtsData}; use serde::{Deserialize, Serialize}; use tokio::{ sync::mpsc, @@ -119,6 +119,7 @@ impl SpawnAction { addr: SocketAddr, normalized_addr: NormalizedAddress, protocol_version: ProtocolVersion, + config: SourceConfig, nts: Option>, ) -> SpawnAction { SpawnAction::Create(SourceCreateParameters::Ntp(NtpSourceCreateParameters { @@ -126,6 +127,7 @@ impl SpawnAction { addr, normalized_addr, protocol_version, + config, nts, })) } @@ -162,6 +164,7 @@ pub struct NtpSourceCreateParameters { pub addr: SocketAddr, pub normalized_addr: NormalizedAddress, pub protocol_version: ProtocolVersion, + pub config: SourceConfig, pub nts: Option>, } @@ -169,6 +172,7 @@ pub struct NtpSourceCreateParameters { pub struct SockSourceCreateParameters { pub id: SourceId, pub path: PathBuf, + pub config: SourceConfig, pub noise_estimate: f64, } @@ -176,6 +180,7 @@ pub struct SockSourceCreateParameters { pub struct PpsSourceCreateParameters { pub id: SourceId, pub path: PathBuf, + pub config: SourceConfig, pub noise_estimate: f64, pub period: f64, } diff --git a/ntpd/src/daemon/spawn/nts.rs b/ntpd/src/daemon/spawn/nts.rs index 07b59cb25..026d36ad3 100644 --- a/ntpd/src/daemon/spawn/nts.rs +++ b/ntpd/src/daemon/spawn/nts.rs @@ -2,6 +2,7 @@ use std::fmt::Display; use std::net::SocketAddr; use std::ops::Deref; +use ntp_proto::SourceConfig; use tokio::sync::mpsc; use tracing::warn; @@ -11,6 +12,7 @@ use super::{SourceId, SourceRemovedEvent, SpawnAction, SpawnEvent, Spawner, Spaw pub struct NtsSpawner { config: NtsSourceConfig, + source_config: SourceConfig, id: SpawnerId, has_spawned: bool, } @@ -53,9 +55,10 @@ pub(super) async fn resolve_addr(address: (&str, u16)) -> Option { } impl NtsSpawner { - pub fn new(config: NtsSourceConfig) -> NtsSpawner { + pub fn new(config: NtsSourceConfig, source_config: SourceConfig) -> NtsSpawner { NtsSpawner { config, + source_config, id: Default::default(), has_spawned: false, } @@ -91,6 +94,7 @@ impl Spawner for NtsSpawner { address, self.config.address.deref().clone(), ke.protocol_version, + self.source_config, Some(ke.nts), ), )) diff --git a/ntpd/src/daemon/spawn/nts_pool.rs b/ntpd/src/daemon/spawn/nts_pool.rs index 7d2615197..edf1f0046 100644 --- a/ntpd/src/daemon/spawn/nts_pool.rs +++ b/ntpd/src/daemon/spawn/nts_pool.rs @@ -4,6 +4,8 @@ use std::ops::Deref; use tokio::sync::mpsc; use tracing::warn; +use ntp_proto::SourceConfig; + use super::super::{ config::NtsPoolSourceConfig, keyexchange::key_exchange_client_with_denied_servers, }; @@ -19,6 +21,7 @@ struct PoolSource { pub struct NtsPoolSpawner { config: NtsPoolSourceConfig, + source_config: SourceConfig, id: SpawnerId, current_sources: Vec, } @@ -45,12 +48,12 @@ impl From> for NtsPoolSpawnError { } impl NtsPoolSpawner { - pub fn new(config: NtsPoolSourceConfig) -> NtsPoolSpawner { + pub fn new(config: NtsPoolSourceConfig, source_config: SourceConfig) -> NtsPoolSpawner { NtsPoolSpawner { config, + source_config, id: Default::default(), current_sources: Default::default(), - //known_ips: Default::default(), } } @@ -99,6 +102,7 @@ impl Spawner for NtsPoolSpawner { address, self.config.addr.deref().clone(), ke.protocol_version, + self.source_config, Some(ke.nts), ), )) diff --git a/ntpd/src/daemon/spawn/pool.rs b/ntpd/src/daemon/spawn/pool.rs index 50077da09..9ddaf0f33 100644 --- a/ntpd/src/daemon/spawn/pool.rs +++ b/ntpd/src/daemon/spawn/pool.rs @@ -3,7 +3,7 @@ use std::{net::SocketAddr, ops::Deref}; #[cfg(feature = "unstable_ntpv5")] use ntp_proto::NtpVersion; -use ntp_proto::ProtocolVersion; +use ntp_proto::{ProtocolVersion, SourceConfig}; use tokio::sync::mpsc; use tracing::warn; @@ -18,6 +18,7 @@ struct PoolSource { pub struct PoolSpawner { config: PoolSourceConfig, + source_config: SourceConfig, id: SpawnerId, current_sources: Vec, known_ips: Vec, @@ -35,9 +36,10 @@ impl Display for PoolSpawnError { impl std::error::Error for PoolSpawnError {} impl PoolSpawner { - pub fn new(config: PoolSourceConfig) -> PoolSpawner { + pub fn new(config: PoolSourceConfig, source_config: SourceConfig) -> PoolSpawner { PoolSpawner { config, + source_config, id: Default::default(), current_sources: Default::default(), known_ips: Default::default(), @@ -93,6 +95,7 @@ impl Spawner for PoolSpawner { Some(NtpVersion::V5) => ProtocolVersion::V5, None => ProtocolVersion::default(), }, + self.source_config, None, ); tracing::debug!(?action, "intending to spawn new pool source at"); @@ -139,6 +142,7 @@ mod tests { #[cfg(feature = "unstable_ntpv5")] use ntp_proto::ProtocolVersion; + use ntp_proto::SourceConfig; use tokio::sync::mpsc::{self, error::TryRecvError}; use crate::daemon::{ @@ -155,14 +159,17 @@ mod tests { let address_strings = ["127.0.0.1:123", "127.0.0.2:123", "127.0.0.3:123"]; let addresses = address_strings.map(|addr| addr.parse().unwrap()); - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) - .into(), - count: 2, - ignore: vec![], - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) + .into(), + count: 2, + ignore: vec![], + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let spawner_id = pool.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -203,14 +210,17 @@ mod tests { let address_strings = ["127.0.0.1:123", "127.0.0.2:123", "127.0.0.3:123"]; let addresses = address_strings.map(|addr| addr.parse().unwrap()); - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) - .into(), - count: 2, - ignore: vec![], - #[cfg(feature = "unstable_ntpv5")] - ntp_version: Some(ntp_proto::NtpVersion::V5), - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) + .into(), + count: 2, + ignore: vec![], + #[cfg(feature = "unstable_ntpv5")] + ntp_version: Some(ntp_proto::NtpVersion::V5), + }, + SourceConfig::default(), + ); let spawner_id = pool.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -245,14 +255,17 @@ mod tests { let address_strings = ["127.0.0.1:123", "127.0.0.2:123", "127.0.0.3:123"]; let addresses = address_strings.map(|addr| addr.parse().unwrap()); - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) - .into(), - count: 2, - ignore: vec![], - #[cfg(feature = "unstable_ntpv5")] - ntp_version: Some(ntp_proto::NtpVersion::V4), - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) + .into(), + count: 2, + ignore: vec![], + #[cfg(feature = "unstable_ntpv5")] + ntp_version: Some(ntp_proto::NtpVersion::V4), + }, + SourceConfig::default(), + ); let spawner_id = pool.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -287,14 +300,17 @@ mod tests { let addresses = address_strings.map(|addr| addr.parse().unwrap()); let ignores = vec!["127.0.0.1".parse().unwrap()]; - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) - .into(), - count: 2, - ignore: ignores.clone(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) + .into(), + count: 2, + ignore: ignores.clone(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let spawner_id = pool.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -326,14 +342,17 @@ mod tests { let address_strings = ["127.0.0.1:123", "127.0.0.2:123", "127.0.0.3:123"]; let addresses = address_strings.map(|addr| addr.parse().unwrap()); - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) - .into(), - count: 2, - ignore: vec![], - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("example.com", 123, addresses.to_vec()) + .into(), + count: 2, + ignore: vec![], + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); assert!(!pool.is_complete()); @@ -370,13 +389,16 @@ mod tests { #[tokio::test] async fn works_if_address_does_not_resolve() { - let mut pool = PoolSpawner::new(PoolSourceConfig { - addr: NormalizedAddress::with_hardcoded_dns("does.not.resolve", 123, vec![]).into(), - count: 2, - ignore: vec![], - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut pool = PoolSpawner::new( + PoolSourceConfig { + addr: NormalizedAddress::with_hardcoded_dns("does.not.resolve", 123, vec![]).into(), + count: 2, + ignore: vec![], + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); assert!(!pool.is_complete()); pool.try_spawn(&action_tx).await.unwrap(); diff --git a/ntpd/src/daemon/spawn/pps.rs b/ntpd/src/daemon/spawn/pps.rs index 02ca82f4a..bf29eb479 100644 --- a/ntpd/src/daemon/spawn/pps.rs +++ b/ntpd/src/daemon/spawn/pps.rs @@ -1,3 +1,4 @@ +use ntp_proto::SourceConfig; use tokio::sync::mpsc; use crate::daemon::config::PpsSourceConfig; @@ -9,14 +10,16 @@ use super::{ pub struct PpsSpawner { config: PpsSourceConfig, + source_config: SourceConfig, id: SpawnerId, has_spawned: bool, } impl PpsSpawner { - pub fn new(config: PpsSourceConfig) -> PpsSpawner { + pub fn new(config: PpsSourceConfig, source_config: SourceConfig) -> PpsSpawner { PpsSpawner { config, + source_config, id: Default::default(), has_spawned: false, } @@ -37,6 +40,7 @@ impl Spawner for PpsSpawner { SpawnAction::Create(SourceCreateParameters::Pps(PpsSourceCreateParameters { id: SourceId::new(), path: self.config.path.clone(), + config: self.source_config, noise_estimate: self.config.measurement_noise_estimate, period: self.config.period, })), @@ -75,6 +79,7 @@ impl Spawner for PpsSpawner { #[cfg(test)] mod tests { + use ntp_proto::SourceConfig; use tokio::sync::mpsc; use crate::{ @@ -90,11 +95,14 @@ mod tests { async fn creates_a_source() { let socket_path = std::env::temp_dir().join(format!("ntp-test-stream-{}", alloc_port())); let noise_estimate = 1e-6; - let mut spawner = PpsSpawner::new(PpsSourceConfig { - path: socket_path.clone(), - measurement_noise_estimate: noise_estimate, - period: 1., - }); + let mut spawner = PpsSpawner::new( + PpsSourceConfig { + path: socket_path.clone(), + measurement_noise_estimate: noise_estimate, + period: 1., + }, + SourceConfig::default(), + ); let spawner_id = spawner.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); diff --git a/ntpd/src/daemon/spawn/sock.rs b/ntpd/src/daemon/spawn/sock.rs index 4530c3e96..d1d6334fc 100644 --- a/ntpd/src/daemon/spawn/sock.rs +++ b/ntpd/src/daemon/spawn/sock.rs @@ -1,3 +1,4 @@ +use ntp_proto::SourceConfig; use tokio::sync::mpsc; use crate::daemon::config::SockSourceConfig; @@ -9,14 +10,16 @@ use super::{ pub struct SockSpawner { config: SockSourceConfig, + source_config: SourceConfig, id: SpawnerId, has_spawned: bool, } impl SockSpawner { - pub fn new(config: SockSourceConfig) -> SockSpawner { + pub fn new(config: SockSourceConfig, source_config: SourceConfig) -> SockSpawner { SockSpawner { config, + source_config, id: Default::default(), has_spawned: false, } @@ -37,6 +40,7 @@ impl Spawner for SockSpawner { SpawnAction::Create(SourceCreateParameters::Sock(SockSourceCreateParameters { id: SourceId::new(), path: self.config.path.clone(), + config: self.source_config, noise_estimate: self.config.measurement_noise_estimate, })), )) @@ -74,6 +78,7 @@ impl Spawner for SockSpawner { #[cfg(test)] mod tests { + use ntp_proto::SourceConfig; use tokio::sync::mpsc; use crate::{ @@ -89,10 +94,13 @@ mod tests { async fn creates_a_source() { let socket_path = std::env::temp_dir().join(format!("ntp-test-stream-{}", alloc_port())); let noise_estimate = 1e-6; - let mut spawner = SockSpawner::new(SockSourceConfig { - path: socket_path.clone(), - measurement_noise_estimate: noise_estimate, - }); + let mut spawner = SockSpawner::new( + SockSourceConfig { + path: socket_path.clone(), + measurement_noise_estimate: noise_estimate, + }, + SourceConfig::default(), + ); let spawner_id = spawner.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); diff --git a/ntpd/src/daemon/spawn/standard.rs b/ntpd/src/daemon/spawn/standard.rs index 464cf355a..506d4b903 100644 --- a/ntpd/src/daemon/spawn/standard.rs +++ b/ntpd/src/daemon/spawn/standard.rs @@ -3,7 +3,7 @@ use std::{net::SocketAddr, ops::Deref}; #[cfg(feature = "unstable_ntpv5")] use ntp_proto::NtpVersion; -use ntp_proto::ProtocolVersion; +use ntp_proto::{ProtocolVersion, SourceConfig}; use tokio::sync::mpsc; use tracing::warn; @@ -16,6 +16,7 @@ use super::{ pub struct StandardSpawner { id: SpawnerId, config: StandardSource, + source_config: SourceConfig, resolved: Option, has_spawned: bool, } @@ -42,10 +43,11 @@ impl From> for StandardSpawnError { impl std::error::Error for StandardSpawnError {} impl StandardSpawner { - pub fn new(config: StandardSource) -> StandardSpawner { + pub fn new(config: StandardSource, source_config: SourceConfig) -> StandardSpawner { StandardSpawner { id: Default::default(), config, + source_config, resolved: None, has_spawned: false, } @@ -101,6 +103,7 @@ impl Spawner for StandardSpawner { Some(NtpVersion::V5) => ProtocolVersion::V5, None => ProtocolVersion::default(), }, + self.source_config, None, ), )) @@ -145,6 +148,7 @@ mod tests { #[cfg(feature = "unstable_ntpv5")] use ntp_proto::ProtocolVersion; + use ntp_proto::SourceConfig; use tokio::sync::mpsc::{self, error::TryRecvError}; use crate::daemon::{ @@ -158,16 +162,19 @@ mod tests { #[tokio::test] async fn creates_a_source() { - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns( - "example.com", - 123, - vec!["127.0.0.1:123".parse().unwrap()], - ) - .into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns( + "example.com", + 123, + vec!["127.0.0.1:123".parse().unwrap()], + ) + .into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let spawner_id = spawner.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -192,15 +199,18 @@ mod tests { #[cfg(feature = "unstable_ntpv5")] #[tokio::test] async fn respects_ntp_version_force_v5() { - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns( - "example.com", - 123, - vec!["127.0.0.1:123".parse().unwrap()], - ) - .into(), - ntp_version: Some(ntp_proto::NtpVersion::V5), - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns( + "example.com", + 123, + vec!["127.0.0.1:123".parse().unwrap()], + ) + .into(), + ntp_version: Some(ntp_proto::NtpVersion::V5), + }, + SourceConfig::default(), + ); let spawner_id = spawner.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -219,15 +229,18 @@ mod tests { #[cfg(feature = "unstable_ntpv5")] #[tokio::test] async fn respects_ntp_version_force_v4() { - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns( - "example.com", - 123, - vec!["127.0.0.1:123".parse().unwrap()], - ) - .into(), - ntp_version: Some(ntp_proto::NtpVersion::V4), - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns( + "example.com", + 123, + vec!["127.0.0.1:123".parse().unwrap()], + ) + .into(), + ntp_version: Some(ntp_proto::NtpVersion::V4), + }, + SourceConfig::default(), + ); let spawner_id = spawner.get_id(); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); @@ -245,16 +258,19 @@ mod tests { #[tokio::test] async fn recreates_a_source() { - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns( - "example.com", - 123, - vec!["127.0.0.1:123".parse().unwrap()], - ) - .into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns( + "example.com", + 123, + vec!["127.0.0.1:123".parse().unwrap()], + ) + .into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); assert!(!spawner.is_complete()); @@ -284,16 +300,19 @@ mod tests { let address_strings = ["127.0.0.1:123", "127.0.0.2:123", "127.0.0.3:123"]; let addresses = address_strings.map(|addr| addr.parse().unwrap()); - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns( - "europe.pool.ntp.org", - 123, - addresses.to_vec(), - ) - .into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns( + "europe.pool.ntp.org", + 123, + addresses.to_vec(), + ) + .into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); assert!(!spawner.is_complete()); @@ -343,11 +362,15 @@ mod tests { #[tokio::test] async fn works_if_address_does_not_resolve() { - let mut spawner = StandardSpawner::new(StandardSource { - address: NormalizedAddress::with_hardcoded_dns("does.not.resolve", 123, vec![]).into(), - #[cfg(feature = "unstable_ntpv5")] - ntp_version: None, - }); + let mut spawner = StandardSpawner::new( + StandardSource { + address: NormalizedAddress::with_hardcoded_dns("does.not.resolve", 123, vec![]) + .into(), + #[cfg(feature = "unstable_ntpv5")] + ntp_version: None, + }, + SourceConfig::default(), + ); let (action_tx, mut action_rx) = mpsc::channel(MESSAGE_BUFFER_SIZE); spawner.try_spawn(&action_tx).await.unwrap(); diff --git a/ntpd/src/daemon/system.rs b/ntpd/src/daemon/system.rs index 80091527e..e0e7a52df 100644 --- a/ntpd/src/daemon/system.rs +++ b/ntpd/src/daemon/system.rs @@ -28,7 +28,7 @@ use std::{ }; use ntp_proto::{ - KeySet, NtpClock, ObservableSourceState, SourceDefaultsConfig, SynchronizationConfig, System, + KeySet, NtpClock, ObservableSourceState, SourceConfig, SynchronizationConfig, System, SystemActionIterator, SystemSnapshot, SystemSourceUpdate, TimeSyncController, }; use timestamped_socket::interface::InterfaceName; @@ -93,7 +93,7 @@ pub struct DaemonChannels { pub async fn spawn>( synchronization_config: SynchronizationConfig, algorithm_config: Controller::AlgorithmConfig, - source_defaults_config: SourceDefaultsConfig, + source_defaults_config: SourceConfig, clock_config: ClockConfig, source_configs: &[NtpSourceConfig], server_configs: &[ServerConfig], @@ -107,7 +107,6 @@ pub async fn spawn { system - .add_spawner(StandardSpawner::new(cfg.clone())) + .add_spawner(StandardSpawner::new( + cfg.first.clone(), + cfg.second.clone().with_defaults(source_defaults_config), + )) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -125,7 +127,10 @@ pub async fn spawn { system - .add_spawner(NtsSpawner::new(cfg.clone())) + .add_spawner(NtsSpawner::new( + cfg.first.clone(), + cfg.second.clone().with_defaults(source_defaults_config), + )) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -133,7 +138,10 @@ pub async fn spawn { system - .add_spawner(PoolSpawner::new(cfg.clone())) + .add_spawner(PoolSpawner::new( + cfg.first.clone(), + cfg.second.clone().with_defaults(source_defaults_config), + )) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -142,7 +150,10 @@ pub async fn spawn { system - .add_spawner(NtsPoolSpawner::new(cfg.clone())) + .add_spawner(NtsPoolSpawner::new( + cfg.first.clone(), + cfg.second.clone().with_defaults(source_defaults_config), + )) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -150,7 +161,7 @@ pub async fn spawn { system - .add_spawner(SockSpawner::new(cfg.clone())) + .add_spawner(SockSpawner::new(cfg.clone(), source_defaults_config)) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -158,7 +169,7 @@ pub async fn spawn { system - .add_spawner(PpsSpawner::new(cfg.clone())) + .add_spawner(PpsSpawner::new(cfg.clone(), source_defaults_config)) .map_err(|e| { tracing::error!("Could not spawn source: {}", e); std::io::Error::new(std::io::ErrorKind::Other, e) @@ -234,7 +245,6 @@ impl< timestamp_mode: TimestampMode, synchronization_config: SynchronizationConfig, algorithm_config: Controller::AlgorithmConfig, - source_defaults_config: SourceDefaultsConfig, keyset: tokio::sync::watch::Receiver>, ip_list: tokio::sync::watch::Receiver>, have_sources: bool, @@ -242,7 +252,6 @@ impl< let Ok(mut system) = System::new( clock.clone(), synchronization_config, - source_defaults_config, algorithm_config, ip_list.borrow().clone(), ) else { @@ -503,6 +512,7 @@ impl< SourceCreateParameters::Ntp(ref mut params) => { let (source, initial_actions) = self.system.create_ntp_source( source_id, + params.config, params.addr, params.protocol_version, params.nts.take(), @@ -525,9 +535,11 @@ impl< ); } SourceCreateParameters::Sock(ref params) => { - let source = self - .system - .create_sock_source(source_id, params.noise_estimate)?; + let source = self.system.create_sock_source( + source_id, + params.config, + params.noise_estimate, + )?; SockSourceTask::spawn( source_id, params.path.clone(), @@ -543,6 +555,7 @@ impl< SourceCreateParameters::Pps(ref params) => { let source = self.system.create_pps_source( source_id, + params.config, params.noise_estimate, params.period, )?; diff --git a/ntpd/src/force_sync/algorithm.rs b/ntpd/src/force_sync/algorithm.rs index c94e6135f..d7167c738 100644 --- a/ntpd/src/force_sync/algorithm.rs +++ b/ntpd/src/force_sync/algorithm.rs @@ -2,7 +2,8 @@ use std::fmt::Debug; use std::{collections::HashMap, marker::PhantomData}; use ntp_proto::{ - Measurement, NtpClock, NtpDuration, PollInterval, SourceController, TimeSyncController, + Measurement, NtpClock, NtpDuration, PollInterval, SourceConfig, SourceController, + TimeSyncController, }; use serde::Deserialize; @@ -42,7 +43,6 @@ impl WrapMeasurements<()> for Measurement<()> { pub(crate) struct SingleShotController { pub(super) clock: C, sources: HashMap, - min_poll_interval: PollInterval, min_agreeing: usize, } @@ -133,13 +133,11 @@ impl TimeSyncController for SingleShotController { fn new( clock: Self::Clock, synchronization_config: ntp_proto::SynchronizationConfig, - source_defaults_config: ntp_proto::SourceDefaultsConfig, algorithm_config: Self::AlgorithmConfig, ) -> Result::Error> { Ok(SingleShotController { clock, sources: HashMap::new(), - min_poll_interval: source_defaults_config.poll_interval_limits.min, min_agreeing: synchronization_config .minimum_agreeing_sources .max(algorithm_config.expected_sources / 2), @@ -151,10 +149,14 @@ impl TimeSyncController for SingleShotController { Ok(()) } - fn add_source(&mut self, _id: Self::SourceId) -> Self::NtpSourceController { + fn add_source( + &mut self, + _id: Self::SourceId, + config: SourceConfig, + ) -> Self::NtpSourceController { SingleShotSourceController:: { delay_type: PhantomData, - min_poll_interval: self.min_poll_interval, + min_poll_interval: config.poll_interval_limits.min, done: false, ignore: false, } @@ -163,12 +165,13 @@ impl TimeSyncController for SingleShotController { fn add_one_way_source( &mut self, _id: Self::SourceId, + config: SourceConfig, _measurement_noise_estimate: f64, period: Option, ) -> Self::OneWaySourceController { SingleShotSourceController::<()> { delay_type: PhantomData, - min_poll_interval: self.min_poll_interval, + min_poll_interval: config.poll_interval_limits.min, done: false, ignore: period.is_some(), } diff --git a/ntpd/src/force_sync/mod.rs b/ntpd/src/force_sync/mod.rs index 41cc21cc6..bdcc3390f 100644 --- a/ntpd/src/force_sync/mod.rs +++ b/ntpd/src/force_sync/mod.rs @@ -9,12 +9,8 @@ use algorithm::{SingleShotController, SingleShotControllerConfig}; use ntp_proto::{NtpClock, NtpDuration}; use tokio::runtime::Builder; -#[cfg(feature = "unstable_nts-pool")] -use crate::daemon::config::NtsPoolSourceConfig; use crate::daemon::{ - config::{self, PoolSourceConfig}, - initialize_logging_parse_config, nts_key_provider, spawn, - tracing::LogLevel, + config, initialize_logging_parse_config, nts_key_provider, spawn, tracing::LogLevel, }; mod algorithm; @@ -135,13 +131,9 @@ pub(crate) fn force_sync(config: Option) -> std::io::Result { | config::NtpSourceConfig::Nts(_) | config::NtpSourceConfig::Sock(_) => total_sources += 1, config::NtpSourceConfig::Pps(_) => {} // PPS sources don't count - config::NtpSourceConfig::Pool(PoolSourceConfig { count, .. }) => { - total_sources += count - } + config::NtpSourceConfig::Pool(cfg) => total_sources += cfg.first.count, #[cfg(feature = "unstable_nts-pool")] - config::NtpSourceConfig::NtsPool(NtsPoolSourceConfig { count, .. }) => { - total_sources += count - } + config::NtpSourceConfig::NtsPool(cfg) => total_sources += cfg.first.count, } }