]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
local: clamp frequency offset
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 7 Apr 2015 12:13:41 +0000 (14:13 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 7 Apr 2015 12:13:41 +0000 (14:13 +0200)
Don't allow frequency offset larger than 50%, the tracked time must not
stop or run backwards.

local.c

diff --git a/local.c b/local.c
index f3dd15f241bd753a78378e2244a5ac6aac3342be..e3018022941becbf09807f7b5e84a1dad94297f7 100644 (file)
--- a/local.c
+++ b/local.c
 
 /* ================================================== */
 
+/* Maximum allowed frequency offset in ppm, the time must not stop
+   or run backwards */
+#define MAX_FREQ 500000.0
+
 /* Variable to store the current frequency, in ppm */
 static double current_freq_ppm;
 
@@ -398,6 +402,20 @@ LCL_ReadAbsoluteFrequency(void)
 }
 
 /* ================================================== */
+
+static double
+clamp_freq(double freq)
+{
+  if (freq <= MAX_FREQ && freq >= -MAX_FREQ)
+    return freq;
+
+  LOG(LOGS_WARN, LOGF_Local, "Frequency %.1f ppm exceeds allowed maximum", freq);
+
+  return freq >= MAX_FREQ ? MAX_FREQ : -MAX_FREQ;
+}
+
+/* ================================================== */
+
 /* This involves both setting the absolute frequency with the
    system-specific driver, as well as calling all notify handlers */
 
@@ -407,6 +425,8 @@ LCL_SetAbsoluteFrequency(double afreq_ppm)
   struct timeval raw, cooked;
   double dfreq;
   
+  afreq_ppm = clamp_freq(afreq_ppm);
+
   /* Apply temperature compensation */
   if (temp_comp_ppm != 0.0) {
     afreq_ppm = afreq_ppm * (1.0 - 1.0e-6 * temp_comp_ppm) - temp_comp_ppm;
@@ -444,6 +464,8 @@ LCL_AccumulateDeltaFrequency(double dfreq)
 
   current_freq_ppm += dfreq * (1.0e6 - current_freq_ppm);
 
+  current_freq_ppm = clamp_freq(current_freq_ppm);
+
   /* Call the system-specific driver for setting the frequency */
   current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
   dfreq = (current_freq_ppm - old_freq_ppm) / (1.0e6 - old_freq_ppm);
@@ -542,6 +564,8 @@ LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate)
    terms of the gradient of the (offset) v (local time) function. */
   current_freq_ppm += dfreq * (1.0e6 - current_freq_ppm);
 
+  current_freq_ppm = clamp_freq(current_freq_ppm);
+
   DEBUG_LOG(LOGF_Local, "old_freq=%.3fppm new_freq=%.3fppm offset=%.6fsec",
       old_freq_ppm, current_freq_ppm, doffset);