1 /*
2   chronyd/chronyc - Programs for keeping computer clocks accurate.
3 
4  **********************************************************************
5  * Copyright (C) Richard P. Curnow  1997-2003
6  * Copyright (C) Miroslav Lichvar  2009-2018, 2020
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of version 2 of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *
21  **********************************************************************
22 
23   =======================================================================
24 
25   This module keeps track of the source which we are claiming to be
26   our reference, for the purposes of generating outgoing NTP packets */
27 
28 #include "config.h"
29 
30 #include "sysincl.h"
31 
32 #include "memory.h"
33 #include "reference.h"
34 #include "util.h"
35 #include "conf.h"
36 #include "logging.h"
37 #include "local.h"
38 #include "sched.h"
39 
40 /* ================================================== */
41 
42 /* The minimum allowed skew */
43 #define MIN_SKEW 1.0e-12
44 
45 /* The update interval of the reference in the local reference mode */
46 #define LOCAL_REF_UPDATE_INTERVAL 64.0
47 
48 /* Interval between updates of the drift file */
49 #define MAX_DRIFTFILE_AGE 3600.0
50 
51 static int are_we_synchronised;
52 static int enable_local_stratum;
53 static int local_stratum;
54 static int local_orphan;
55 static double local_distance;
56 static struct timespec local_ref_time;
57 static NTP_Leap our_leap_status;
58 static int our_leap_sec;
59 static int our_tai_offset;
60 static int our_stratum;
61 static uint32_t our_ref_id;
62 static IPAddr our_ref_ip;
63 static struct timespec our_ref_time;
64 static double our_skew;
65 static double our_residual_freq;
66 static double our_root_delay;
67 static double our_root_dispersion;
68 static double our_offset_sd;
69 static double our_frequency_sd;
70 
71 static double max_update_skew;
72 
73 static double last_offset;
74 static double avg2_offset;
75 static int avg2_moving;
76 
77 static double correction_time_ratio;
78 
79 /* Flag indicating that we are initialised */
80 static int initialised = 0;
81 
82 /* Current operating mode */
83 static REF_Mode mode;
84 
85 /* Threshold and update limit for stepping clock */
86 static int make_step_limit;
87 static double make_step_threshold;
88 
89 /* Number of updates before offset checking, number of ignored updates
90    before exiting and the maximum allowed offset */
91 static int max_offset_delay;
92 static int max_offset_ignore;
93 static double max_offset;
94 
95 /* Threshold for logging clock changes to syslog */
96 static double log_change_threshold;
97 
98 /* Flag, threshold and user for sending mail notification on large clock changes */
99 static int do_mail_change;
100 static double mail_change_threshold;
101 static char *mail_change_user;
102 
103 /* Handler for mode ending */
104 static REF_ModeEndHandler mode_end_handler = NULL;
105 
106 /* Filename of the drift file. */
107 static char *drift_file=NULL;
108 static double drift_file_age;
109 
110 static void update_drift_file(double, double);
111 
112 /* Leap second handling mode */
113 static REF_LeapMode leap_mode;
114 
115 /* Time of UTC midnight of the upcoming or previous leap second */
116 static time_t leap_when;
117 
118 /* Flag indicating the clock was recently corrected for leap second and it may
119    not have correct time yet (missing 23:59:60 in the UTC time scale) */
120 static int leap_in_progress;
121 
122 /* Timer for the leap second handler */
123 static SCH_TimeoutID leap_timeout_id;
124 
125 /* Name of a system timezone containing leap seconds occuring at midnight */
126 static char *leap_tzname;
127 
128 /* ================================================== */
129 
130 static LOG_FileID logfileid;
131 
132 /* ================================================== */
133 
134 /* Exponential moving averages of absolute clock frequencies
135    used as a fallback when synchronisation is lost. */
136 
137 struct fb_drift {
138   double freq;
139   double secs;
140 };
141 
142 static int fb_drift_min;
143 static int fb_drift_max;
144 
145 static struct fb_drift *fb_drifts = NULL;
146 static int next_fb_drift;
147 static SCH_TimeoutID fb_drift_timeout_id;
148 
149 /* Monotonic timestamp of the last reference update */
150 static double last_ref_update;
151 static double last_ref_update_interval;
152 
153 /* ================================================== */
154 
155 static NTP_Leap get_tz_leap(time_t when, int *tai_offset);
156 static void update_leap_status(NTP_Leap leap, time_t now, int reset);
157 
158 /* ================================================== */
159 
160 static void
handle_slew(struct timespec * raw,struct timespec * cooked,double dfreq,double doffset,LCL_ChangeType change_type,void * anything)161 handle_slew(struct timespec *raw,
162             struct timespec *cooked,
163             double dfreq,
164             double doffset,
165             LCL_ChangeType change_type,
166             void *anything)
167 {
168   double delta;
169   struct timespec now;
170 
171   if (!UTI_IsZeroTimespec(&our_ref_time))
172     UTI_AdjustTimespec(&our_ref_time, cooked, &our_ref_time, &delta, dfreq, doffset);
173 
174   if (change_type == LCL_ChangeUnknownStep) {
175     last_ref_update = 0.0;
176     REF_SetUnsynchronised();
177   }
178 
179   /* When the clock was stepped, check if that doesn't change our leap status
180      and also reset the leap timeout to undo the shift in the scheduler */
181   if (change_type != LCL_ChangeAdjust && our_leap_sec && !leap_in_progress) {
182     LCL_ReadRawTime(&now);
183     update_leap_status(our_leap_status, now.tv_sec, 1);
184   }
185 }
186 
187 /* ================================================== */
188 
189 void
REF_Initialise(void)190 REF_Initialise(void)
191 {
192   FILE *in;
193   double file_freq_ppm, file_skew_ppm;
194   double our_frequency_ppm;
195   int tai_offset;
196 
197   mode = REF_ModeNormal;
198   are_we_synchronised = 0;
199   our_leap_status = LEAP_Unsynchronised;
200   our_leap_sec = 0;
201   our_tai_offset = 0;
202   initialised = 1;
203   our_root_dispersion = 1.0;
204   our_root_delay = 1.0;
205   our_frequency_ppm = 0.0;
206   our_skew = 1.0; /* i.e. rather bad */
207   our_residual_freq = 0.0;
208   our_frequency_sd = 0.0;
209   our_offset_sd = 0.0;
210   drift_file_age = 0.0;
211 
212   /* Now see if we can get the drift file opened */
213   drift_file = CNF_GetDriftFile();
214   if (drift_file) {
215     in = UTI_OpenFile(NULL, drift_file, NULL, 'r', 0);
216     if (in) {
217       if (fscanf(in, "%lf%lf", &file_freq_ppm, &file_skew_ppm) == 2) {
218         /* We have read valid data */
219         our_frequency_ppm = file_freq_ppm;
220         our_skew = 1.0e-6 * file_skew_ppm;
221         if (our_skew < MIN_SKEW)
222           our_skew = MIN_SKEW;
223         LOG(LOGS_INFO, "Frequency %.3f +/- %.3f ppm read from %s",
224             file_freq_ppm, file_skew_ppm, drift_file);
225         LCL_SetAbsoluteFrequency(our_frequency_ppm);
226       } else {
227         LOG(LOGS_WARN, "Could not read valid frequency and skew from driftfile %s",
228             drift_file);
229       }
230       fclose(in);
231     }
232   }
233 
234   if (our_frequency_ppm == 0.0) {
235     our_frequency_ppm = LCL_ReadAbsoluteFrequency();
236     if (our_frequency_ppm != 0.0) {
237       LOG(LOGS_INFO, "Initial frequency %.3f ppm", our_frequency_ppm);
238     }
239   }
240 
241   logfileid = CNF_GetLogTracking() ? LOG_FileOpen("tracking",
242       "   Date (UTC) Time     IP Address   St   Freq ppm   Skew ppm     Offset L Co  Offset sd Rem. corr. Root delay Root disp. Max. error")
243     : -1;
244 
245   max_update_skew = fabs(CNF_GetMaxUpdateSkew()) * 1.0e-6;
246 
247   correction_time_ratio = CNF_GetCorrectionTimeRatio();
248 
249   enable_local_stratum = CNF_AllowLocalReference(&local_stratum, &local_orphan, &local_distance);
250   UTI_ZeroTimespec(&local_ref_time);
251 
252   leap_when = 0;
253   leap_timeout_id = 0;
254   leap_in_progress = 0;
255   leap_mode = CNF_GetLeapSecMode();
256   /* Switch to step mode if the system driver doesn't support leap */
257   if (leap_mode == REF_LeapModeSystem && !LCL_CanSystemLeap())
258     leap_mode = REF_LeapModeStep;
259 
260   leap_tzname = CNF_GetLeapSecTimezone();
261   if (leap_tzname) {
262     /* Check that the timezone has good data for Jun 30 2012 and Dec 31 2012 */
263     if (get_tz_leap(1341014400, &tai_offset) == LEAP_InsertSecond && tai_offset == 34 &&
264         get_tz_leap(1356912000, &tai_offset) == LEAP_Normal && tai_offset == 35) {
265       LOG(LOGS_INFO, "Using %s timezone to obtain leap second data", leap_tzname);
266     } else {
267       LOG(LOGS_WARN, "Timezone %s failed leap second check, ignoring", leap_tzname);
268       leap_tzname = NULL;
269     }
270   }
271 
272   CNF_GetMakeStep(&make_step_limit, &make_step_threshold);
273   CNF_GetMaxChange(&max_offset_delay, &max_offset_ignore, &max_offset);
274   CNF_GetMailOnChange(&do_mail_change, &mail_change_threshold, &mail_change_user);
275   log_change_threshold = CNF_GetLogChange();
276 
277   CNF_GetFallbackDrifts(&fb_drift_min, &fb_drift_max);
278 
279   if (fb_drift_max >= fb_drift_min && fb_drift_min > 0) {
280     fb_drifts = MallocArray(struct fb_drift, fb_drift_max - fb_drift_min + 1);
281     memset(fb_drifts, 0, sizeof (struct fb_drift) * (fb_drift_max - fb_drift_min + 1));
282     next_fb_drift = 0;
283     fb_drift_timeout_id = 0;
284   }
285 
286   UTI_ZeroTimespec(&our_ref_time);
287   last_ref_update = 0.0;
288   last_ref_update_interval = 0.0;
289 
290   LCL_AddParameterChangeHandler(handle_slew, NULL);
291 
292   /* Make first entry in tracking log */
293   REF_SetUnsynchronised();
294 }
295 
296 /* ================================================== */
297 
298 void
REF_Finalise(void)299 REF_Finalise(void)
300 {
301   update_leap_status(LEAP_Unsynchronised, 0, 0);
302 
303   if (drift_file) {
304     update_drift_file(LCL_ReadAbsoluteFrequency(), our_skew);
305   }
306 
307   LCL_RemoveParameterChangeHandler(handle_slew, NULL);
308 
309   Free(fb_drifts);
310 
311   initialised = 0;
312 }
313 
314 /* ================================================== */
315 
REF_SetMode(REF_Mode new_mode)316 void REF_SetMode(REF_Mode new_mode)
317 {
318   mode = new_mode;
319 }
320 
321 /* ================================================== */
322 
323 REF_Mode
REF_GetMode(void)324 REF_GetMode(void)
325 {
326   return mode;
327 }
328 
329 /* ================================================== */
330 
331 void
REF_SetModeEndHandler(REF_ModeEndHandler handler)332 REF_SetModeEndHandler(REF_ModeEndHandler handler)
333 {
334   mode_end_handler = handler;
335 }
336 
337 /* ================================================== */
338 
339 REF_LeapMode
REF_GetLeapMode(void)340 REF_GetLeapMode(void)
341 {
342   return leap_mode;
343 }
344 
345 /* ================================================== */
346 /* Update the drift coefficients to the file. */
347 
348 static void
update_drift_file(double freq_ppm,double skew)349 update_drift_file(double freq_ppm, double skew)
350 {
351   FILE *out;
352 
353   /* Create a temporary file with a '.tmp' extension. */
354   out = UTI_OpenFile(NULL, drift_file, ".tmp", 'w', 0644);
355   if (!out)
356     return;
357 
358   /* Write the frequency and skew parameters in ppm */
359   fprintf(out, "%20.6f %20.6f\n", freq_ppm, 1.0e6 * skew);
360   fclose(out);
361 
362   /* Rename the temporary file to the correct location */
363   if (!UTI_RenameTempFile(NULL, drift_file, ".tmp", NULL))
364     ;
365 }
366 
367 /* ================================================== */
368 
369 static void
update_fb_drifts(double freq_ppm,double update_interval)370 update_fb_drifts(double freq_ppm, double update_interval)
371 {
372   int i, secs;
373 
374   assert(are_we_synchronised);
375 
376   if (next_fb_drift > 0) {
377 #if 0
378     /* Reset drifts that were used when we were unsynchronised */
379     for (i = 0; i < next_fb_drift - fb_drift_min; i++)
380       fb_drifts[i].secs = 0.0;
381 #endif
382     next_fb_drift = 0;
383   }
384 
385   SCH_RemoveTimeout(fb_drift_timeout_id);
386   fb_drift_timeout_id = 0;
387 
388   if (update_interval < 1.0 || update_interval > last_ref_update_interval * 4.0)
389     return;
390 
391   for (i = 0; i < fb_drift_max - fb_drift_min + 1; i++) {
392     secs = 1 << (i + fb_drift_min);
393     if (fb_drifts[i].secs < secs) {
394       /* Calculate average over 2 * secs interval before switching to
395          exponential updating */
396       fb_drifts[i].freq = (fb_drifts[i].freq * fb_drifts[i].secs +
397           update_interval * 0.5 * freq_ppm) / (update_interval * 0.5 + fb_drifts[i].secs);
398       fb_drifts[i].secs += update_interval * 0.5;
399     } else {
400       /* Update exponential moving average. The smoothing factor for update
401          interval equal to secs is about 0.63, for half interval about 0.39,
402          for double interval about 0.86. */
403       fb_drifts[i].freq += (1 - 1.0 / exp(update_interval / secs)) *
404         (freq_ppm - fb_drifts[i].freq);
405     }
406 
407     DEBUG_LOG("Fallback drift %d updated: %f ppm %f seconds",
408               i + fb_drift_min, fb_drifts[i].freq, fb_drifts[i].secs);
409   }
410 }
411 
412 /* ================================================== */
413 
414 static void
fb_drift_timeout(void * arg)415 fb_drift_timeout(void *arg)
416 {
417   assert(next_fb_drift >= fb_drift_min && next_fb_drift <= fb_drift_max);
418 
419   fb_drift_timeout_id = 0;
420 
421   DEBUG_LOG("Fallback drift %d active: %f ppm",
422             next_fb_drift, fb_drifts[next_fb_drift - fb_drift_min].freq);
423   LCL_SetAbsoluteFrequency(fb_drifts[next_fb_drift - fb_drift_min].freq);
424   REF_SetUnsynchronised();
425 }
426 
427 /* ================================================== */
428 
429 static void
schedule_fb_drift(void)430 schedule_fb_drift(void)
431 {
432   int i, c, secs;
433   double unsynchronised, now;
434 
435   if (fb_drift_timeout_id)
436     return; /* already scheduled */
437 
438   now = SCH_GetLastEventMonoTime();
439   unsynchronised = now - last_ref_update;
440 
441   for (c = secs = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
442     secs = 1 << i;
443 
444     if (fb_drifts[i - fb_drift_min].secs < secs)
445       continue;
446 
447     if (unsynchronised < secs && i > next_fb_drift)
448       break;
449 
450     c = i;
451   }
452 
453   if (c > next_fb_drift) {
454     LCL_SetAbsoluteFrequency(fb_drifts[c - fb_drift_min].freq);
455     next_fb_drift = c;
456     DEBUG_LOG("Fallback drift %d set", c);
457   }
458 
459   if (i <= fb_drift_max) {
460     next_fb_drift = i;
461     fb_drift_timeout_id = SCH_AddTimeoutByDelay(secs - unsynchronised, fb_drift_timeout, NULL);
462     DEBUG_LOG("Fallback drift %d scheduled", i);
463   }
464 }
465 
466 /* ================================================== */
467 
468 static void
end_ref_mode(int result)469 end_ref_mode(int result)
470 {
471   mode = REF_ModeIgnore;
472 
473   /* Dispatch the handler */
474   if (mode_end_handler)
475     (mode_end_handler)(result);
476 }
477 
478 /* ================================================== */
479 
480 #define BUFLEN 255
481 #define S_MAX_USER_LEN "128"
482 
483 static void
maybe_log_offset(double offset,time_t now)484 maybe_log_offset(double offset, time_t now)
485 {
486   double abs_offset;
487   FILE *p;
488   char buffer[BUFLEN], host[BUFLEN];
489   struct tm *tm;
490 
491   abs_offset = fabs(offset);
492 
493   if (abs_offset > log_change_threshold) {
494     LOG(LOGS_WARN, "System clock wrong by %.6f seconds", -offset);
495   }
496 
497   if (do_mail_change &&
498       (abs_offset > mail_change_threshold)) {
499     snprintf(buffer, sizeof (buffer), "%s -t", MAIL_PROGRAM);
500     p = popen(buffer, "w");
501     if (p) {
502       if (gethostname(host, sizeof(host)) < 0) {
503         strcpy(host, "<UNKNOWN>");
504       }
505       host[sizeof (host) - 1] = '\0';
506 
507       fprintf(p, "To: %s\n", mail_change_user);
508       fprintf(p, "Subject: chronyd reports change to system clock on node [%s]\n", host);
509       fputs("\n", p);
510 
511       tm = localtime(&now);
512       if (tm) {
513         strftime(buffer, sizeof (buffer),
514                  "On %A, %d %B %Y\n  with the system clock reading %H:%M:%S (%Z)", tm);
515         fputs(buffer, p);
516       }
517 
518       /* If offset < 0 the local clock is slow, so we are applying a
519          positive change to it to bring it into line, hence the
520          negation of 'offset' in the next statement (and earlier) */
521       fprintf(p,
522               "\n\nchronyd started to apply an adjustment of %.3f seconds to it,\n"
523               "  which exceeded the reporting threshold of %.3f seconds\n\n",
524               -offset, mail_change_threshold);
525       pclose(p);
526     } else {
527       LOG(LOGS_ERR, "Could not send mail notification to user %s\n",
528           mail_change_user);
529     }
530   }
531 
532 }
533 
534 /* ================================================== */
535 
536 static int
is_step_limit_reached(double offset,double offset_correction)537 is_step_limit_reached(double offset, double offset_correction)
538 {
539   if (make_step_limit == 0) {
540     return 0;
541   } else if (make_step_limit > 0) {
542     make_step_limit--;
543   }
544   return fabs(offset - offset_correction) > make_step_threshold;
545 }
546 
547 /* ================================================== */
548 
549 static int
is_offset_ok(double offset)550 is_offset_ok(double offset)
551 {
552   if (max_offset_delay < 0)
553     return 1;
554 
555   if (max_offset_delay > 0) {
556     max_offset_delay--;
557     return 1;
558   }
559 
560   if (fabs(offset) > max_offset) {
561     LOG(LOGS_WARN,
562         "Adjustment of %.3f seconds exceeds the allowed maximum of %.3f seconds (%s) ",
563         -offset, max_offset, !max_offset_ignore ? "exiting" : "ignored");
564     if (!max_offset_ignore)
565       end_ref_mode(0);
566     else if (max_offset_ignore > 0)
567       max_offset_ignore--;
568     return 0;
569   }
570   return 1;
571 }
572 
573 /* ================================================== */
574 
575 static int
is_leap_second_day(time_t when)576 is_leap_second_day(time_t when)
577 {
578   struct tm *stm;
579 
580   stm = gmtime(&when);
581   if (!stm)
582     return 0;
583 
584   /* Allow leap second only on the last day of June and December */
585   return (stm->tm_mon == 5 && stm->tm_mday == 30) ||
586          (stm->tm_mon == 11 && stm->tm_mday == 31);
587 }
588 
589 /* ================================================== */
590 
591 static NTP_Leap
get_tz_leap(time_t when,int * tai_offset)592 get_tz_leap(time_t when, int *tai_offset)
593 {
594   static time_t last_tz_leap_check;
595   static NTP_Leap tz_leap;
596   static int tz_tai_offset;
597 
598   struct tm stm, *tm;
599   time_t t;
600   char *tz_env, tz_orig[128];
601 
602   *tai_offset = tz_tai_offset;
603 
604   /* Do this check at most twice a day */
605   when = when / (12 * 3600) * (12 * 3600);
606   if (last_tz_leap_check == when)
607       return tz_leap;
608 
609   last_tz_leap_check = when;
610   tz_leap = LEAP_Normal;
611   tz_tai_offset = 0;
612 
613   tm = gmtime(&when);
614   if (!tm)
615     return tz_leap;
616 
617   stm = *tm;
618 
619   /* Temporarily switch to the timezone containing leap seconds */
620   tz_env = getenv("TZ");
621   if (tz_env) {
622     if (strlen(tz_env) >= sizeof (tz_orig))
623       return tz_leap;
624     strcpy(tz_orig, tz_env);
625   }
626   setenv("TZ", leap_tzname, 1);
627   tzset();
628 
629   /* Get the TAI-UTC offset, which started at the epoch at 10 seconds */
630   t = mktime(&stm);
631   if (t != -1)
632     tz_tai_offset = t - when + 10;
633 
634   /* Set the time to 23:59:60 and see how it overflows in mktime() */
635   stm.tm_sec = 60;
636   stm.tm_min = 59;
637   stm.tm_hour = 23;
638 
639   t = mktime(&stm);
640 
641   if (tz_env)
642     setenv("TZ", tz_orig, 1);
643   else
644     unsetenv("TZ");
645   tzset();
646 
647   if (t == -1)
648     return tz_leap;
649 
650   if (stm.tm_sec == 60)
651     tz_leap = LEAP_InsertSecond;
652   else if (stm.tm_sec == 1)
653     tz_leap = LEAP_DeleteSecond;
654 
655   *tai_offset = tz_tai_offset;
656 
657   return tz_leap;
658 }
659 
660 /* ================================================== */
661 
662 static void
leap_end_timeout(void * arg)663 leap_end_timeout(void *arg)
664 {
665   leap_timeout_id = 0;
666   leap_in_progress = 0;
667 
668   if (our_tai_offset)
669     our_tai_offset += our_leap_sec;
670   our_leap_sec = 0;
671 
672   if (leap_mode == REF_LeapModeSystem)
673     LCL_SetSystemLeap(our_leap_sec, our_tai_offset);
674 
675   if (our_leap_status == LEAP_InsertSecond ||
676       our_leap_status == LEAP_DeleteSecond)
677     our_leap_status = LEAP_Normal;
678 }
679 
680 /* ================================================== */
681 
682 static void
leap_start_timeout(void * arg)683 leap_start_timeout(void *arg)
684 {
685   leap_in_progress = 1;
686 
687   switch (leap_mode) {
688     case REF_LeapModeSystem:
689       DEBUG_LOG("Waiting for system clock leap second correction");
690       break;
691     case REF_LeapModeSlew:
692       LCL_NotifyLeap(our_leap_sec);
693       LCL_AccumulateOffset(our_leap_sec, 0.0);
694       LOG(LOGS_WARN, "Adjusting system clock for leap second");
695       break;
696     case REF_LeapModeStep:
697       LCL_NotifyLeap(our_leap_sec);
698       LCL_ApplyStepOffset(our_leap_sec);
699       LOG(LOGS_WARN, "System clock was stepped for leap second");
700       break;
701     case REF_LeapModeIgnore:
702       LOG(LOGS_WARN, "Ignoring leap second");
703       break;
704     default:
705       break;
706   }
707 
708   /* Wait until the leap second is over with some extra room to be safe */
709   leap_timeout_id = SCH_AddTimeoutByDelay(2.0, leap_end_timeout, NULL);
710 }
711 
712 /* ================================================== */
713 
714 static void
set_leap_timeout(time_t now)715 set_leap_timeout(time_t now)
716 {
717   struct timespec when;
718 
719   /* Stop old timer if there is one */
720   SCH_RemoveTimeout(leap_timeout_id);
721   leap_timeout_id = 0;
722   leap_in_progress = 0;
723 
724   if (!our_leap_sec)
725     return;
726 
727   leap_when = (now / (24 * 3600) + 1) * (24 * 3600);
728 
729   /* Insert leap second at 0:00:00 UTC, delete at 23:59:59 UTC.  If the clock
730      will be corrected by the system, timeout slightly sooner to be sure it
731      will happen before the system correction. */
732   when.tv_sec = leap_when;
733   when.tv_nsec = 0;
734   if (our_leap_sec < 0)
735     when.tv_sec--;
736   if (leap_mode == REF_LeapModeSystem) {
737     when.tv_sec--;
738     when.tv_nsec = 500000000;
739   }
740 
741   leap_timeout_id = SCH_AddTimeout(&when, leap_start_timeout, NULL);
742 }
743 
744 /* ================================================== */
745 
746 static void
update_leap_status(NTP_Leap leap,time_t now,int reset)747 update_leap_status(NTP_Leap leap, time_t now, int reset)
748 {
749   NTP_Leap tz_leap;
750   int leap_sec, tai_offset;
751 
752   leap_sec = 0;
753   tai_offset = 0;
754 
755   if (leap_tzname && now) {
756     tz_leap = get_tz_leap(now, &tai_offset);
757     if (leap == LEAP_Normal)
758       leap = tz_leap;
759   }
760 
761   if (leap == LEAP_InsertSecond || leap == LEAP_DeleteSecond) {
762     /* Check that leap second is allowed today */
763 
764     if (is_leap_second_day(now)) {
765       if (leap == LEAP_InsertSecond) {
766         leap_sec = 1;
767       } else {
768         leap_sec = -1;
769       }
770     } else {
771       leap = LEAP_Normal;
772     }
773   }
774 
775   if ((leap_sec != our_leap_sec || tai_offset != our_tai_offset)
776       && !REF_IsLeapSecondClose(NULL, 0.0)) {
777     our_leap_sec = leap_sec;
778     our_tai_offset = tai_offset;
779 
780     switch (leap_mode) {
781       case REF_LeapModeSystem:
782         LCL_SetSystemLeap(our_leap_sec, our_tai_offset);
783         /* Fall through */
784       case REF_LeapModeSlew:
785       case REF_LeapModeStep:
786       case REF_LeapModeIgnore:
787         set_leap_timeout(now);
788         break;
789       default:
790         assert(0);
791         break;
792     }
793   } else if (reset) {
794     set_leap_timeout(now);
795   }
796 
797   our_leap_status = leap;
798 }
799 
800 /* ================================================== */
801 
802 static double
get_root_dispersion(struct timespec * ts)803 get_root_dispersion(struct timespec *ts)
804 {
805   if (UTI_IsZeroTimespec(&our_ref_time))
806     return 1.0;
807 
808   return our_root_dispersion +
809          fabs(UTI_DiffTimespecsToDouble(ts, &our_ref_time)) *
810          (our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError());
811 }
812 
813 /* ================================================== */
814 
815 static void
update_sync_status(struct timespec * now)816 update_sync_status(struct timespec *now)
817 {
818   double elapsed;
819 
820   elapsed = fabs(UTI_DiffTimespecsToDouble(now, &our_ref_time));
821 
822   LCL_SetSyncStatus(are_we_synchronised,
823                     our_offset_sd + elapsed * our_frequency_sd,
824                     our_root_delay / 2.0 + get_root_dispersion(now));
825 }
826 
827 /* ================================================== */
828 
829 static void
write_log(struct timespec * now,int combined_sources,double freq,double offset,double offset_sd,double uncorrected_offset,double orig_root_distance)830 write_log(struct timespec *now, int combined_sources, double freq,
831           double offset, double offset_sd, double uncorrected_offset,
832           double orig_root_distance)
833 {
834   const char leap_codes[4] = {'N', '+', '-', '?'};
835   double root_dispersion, max_error;
836   static double last_sys_offset = 0.0;
837 
838   if (logfileid == -1)
839     return;
840 
841   max_error = orig_root_distance + fabs(last_sys_offset);
842   root_dispersion = get_root_dispersion(now);
843   last_sys_offset = offset - uncorrected_offset;
844 
845   LOG_FileWrite(logfileid,
846                 "%s %-15s %2d %10.3f %10.3f %10.3e %1c %2d %10.3e %10.3e %10.3e %10.3e %10.3e",
847                 UTI_TimeToLogForm(now->tv_sec),
848                 our_ref_ip.family != IPADDR_UNSPEC ?
849                   UTI_IPToString(&our_ref_ip) : UTI_RefidToString(our_ref_id),
850                 our_stratum, freq, 1.0e6 * our_skew, offset,
851                 leap_codes[our_leap_status], combined_sources, offset_sd,
852                 uncorrected_offset, our_root_delay, root_dispersion, max_error);
853 }
854 
855 /* ================================================== */
856 
857 static void
special_mode_sync(int valid,double offset)858 special_mode_sync(int valid, double offset)
859 {
860   int step;
861 
862   switch (mode) {
863     case REF_ModeInitStepSlew:
864       if (!valid) {
865         LOG(LOGS_WARN, "No suitable source for initstepslew");
866         end_ref_mode(0);
867         break;
868       }
869 
870       step = fabs(offset) >= CNF_GetInitStepThreshold();
871 
872       LOG(LOGS_INFO, "System's initial offset : %.6f seconds %s of true (%s)",
873           fabs(offset), offset >= 0 ? "fast" : "slow", step ? "step" : "slew");
874 
875       if (step)
876         LCL_ApplyStepOffset(offset);
877       else
878         LCL_AccumulateOffset(offset, 0.0);
879 
880       end_ref_mode(1);
881 
882       break;
883     case REF_ModeUpdateOnce:
884     case REF_ModePrintOnce:
885       if (!valid) {
886         LOG(LOGS_WARN, "No suitable source for synchronisation");
887         end_ref_mode(0);
888         break;
889       }
890 
891       step = mode == REF_ModeUpdateOnce;
892 
893       LOG(LOGS_INFO, "System clock wrong by %.6f seconds (%s)",
894           -offset, step ? "step" : "ignored");
895 
896       if (step)
897         LCL_ApplyStepOffset(offset);
898 
899       end_ref_mode(1);
900 
901       break;
902     case REF_ModeIgnore:
903       /* Do nothing until the mode is changed */
904       break;
905     default:
906       assert(0);
907   }
908 }
909 
910 /* ================================================== */
911 
912 static void
get_clock_estimates(int manual,double measured_freq,double measured_skew,double * estimated_freq,double * estimated_skew,double * residual_freq)913 get_clock_estimates(int manual,
914                     double measured_freq, double measured_skew,
915                     double *estimated_freq, double *estimated_skew,
916                     double *residual_freq)
917 {
918   double gain, expected_freq, expected_skew, extra_skew;
919 
920   /* We assume that the local clock is running according to our previously
921      determined value */
922   expected_freq = 0.0;
923   expected_skew = our_skew;
924 
925   /* Set new frequency based on weighted average of the expected and measured
926      skew.  Disable updates that are based on totally unreliable frequency
927      information unless it is a manual reference. */
928   if (manual) {
929     gain = 1.0;
930   } else if (fabs(measured_skew) > max_update_skew) {
931     DEBUG_LOG("Skew %f too large to track", measured_skew);
932     gain = 0.0;
933   } else {
934     gain = 3.0 * SQUARE(expected_skew) /
935            (3.0 * SQUARE(expected_skew) + SQUARE(measured_skew));
936   }
937 
938   gain = CLAMP(0.0, gain, 1.0);
939 
940   *estimated_freq = expected_freq + gain * (measured_freq - expected_freq);
941   *residual_freq = measured_freq - *estimated_freq;
942 
943   extra_skew = sqrt(SQUARE(expected_freq - *estimated_freq) * (1.0 - gain) +
944                     SQUARE(measured_freq - *estimated_freq) * gain);
945 
946   *estimated_skew = expected_skew + gain * (measured_skew - expected_skew) + extra_skew;
947 }
948 
949 /* ================================================== */
950 
951 static void
fuzz_ref_time(struct timespec * ts)952 fuzz_ref_time(struct timespec *ts)
953 {
954   uint32_t rnd;
955 
956   /* Add a random value from interval [-1.0, 0.0] */
957   UTI_GetRandomBytes(&rnd, sizeof (rnd));
958   UTI_AddDoubleToTimespec(ts, -(double)rnd / (uint32_t)-1, ts);
959 }
960 
961 /* ================================================== */
962 
963 void
REF_SetReference(int stratum,NTP_Leap leap,int combined_sources,uint32_t ref_id,IPAddr * ref_ip,struct timespec * ref_time,double offset,double offset_sd,double frequency,double frequency_sd,double skew,double root_delay,double root_dispersion)964 REF_SetReference(int stratum, NTP_Leap leap, int combined_sources,
965                  uint32_t ref_id, IPAddr *ref_ip, struct timespec *ref_time,
966                  double offset, double offset_sd,
967                  double frequency, double frequency_sd, double skew,
968                  double root_delay, double root_dispersion)
969 {
970   double uncorrected_offset, accumulate_offset, step_offset;
971   double residual_frequency, local_abs_frequency;
972   double elapsed, mono_now, update_interval, correction_rate, orig_root_distance;
973   struct timespec now, raw_now;
974   int manual;
975 
976   assert(initialised);
977 
978   /* Special modes are implemented elsewhere */
979   if (mode != REF_ModeNormal) {
980     special_mode_sync(1, offset);
981     return;
982   }
983 
984   manual = leap == LEAP_Unsynchronised;
985 
986   mono_now = SCH_GetLastEventMonoTime();
987   LCL_ReadRawTime(&raw_now);
988   LCL_GetOffsetCorrection(&raw_now, &uncorrected_offset, NULL);
989   UTI_AddDoubleToTimespec(&raw_now, uncorrected_offset, &now);
990 
991   elapsed = UTI_DiffTimespecsToDouble(&now, ref_time);
992   offset += elapsed * frequency;
993 
994   if (last_ref_update != 0.0) {
995     update_interval = mono_now - last_ref_update;
996   } else {
997     update_interval = 0.0;
998   }
999 
1000   /* Get new estimates of the frequency and skew including the new data */
1001   get_clock_estimates(manual, frequency, skew,
1002                       &frequency, &skew, &residual_frequency);
1003 
1004   if (!is_offset_ok(offset))
1005     return;
1006 
1007   orig_root_distance = our_root_delay / 2.0 + get_root_dispersion(&now);
1008 
1009   are_we_synchronised = leap != LEAP_Unsynchronised;
1010   our_stratum = stratum + 1;
1011   our_ref_id = ref_id;
1012   if (ref_ip)
1013     our_ref_ip = *ref_ip;
1014   else
1015     our_ref_ip.family = IPADDR_UNSPEC;
1016   our_ref_time = *ref_time;
1017   our_skew = skew;
1018   our_residual_freq = residual_frequency;
1019   our_root_delay = root_delay;
1020   our_root_dispersion = root_dispersion;
1021   our_frequency_sd = frequency_sd;
1022   our_offset_sd = offset_sd;
1023   last_ref_update = mono_now;
1024   last_ref_update_interval = update_interval;
1025   last_offset = offset;
1026 
1027   /* We want to correct the offset quickly, but we also want to keep the
1028      frequency error caused by the correction itself low.
1029 
1030      Define correction rate as the area of the region bounded by the graph of
1031      offset corrected in time. Set the rate so that the time needed to correct
1032      an offset equal to the current sourcestats stddev will be equal to the
1033      update interval multiplied by the correction time ratio (assuming linear
1034      adjustment). The offset and the time needed to make the correction are
1035      inversely proportional.
1036 
1037      This is only a suggestion and it's up to the system driver how the
1038      adjustment will be executed. */
1039 
1040   correction_rate = correction_time_ratio * 0.5 * offset_sd * update_interval;
1041 
1042   /* Check if the clock should be stepped */
1043   if (is_step_limit_reached(offset, uncorrected_offset)) {
1044     /* Cancel the uncorrected offset and correct the total offset by step */
1045     accumulate_offset = uncorrected_offset;
1046     step_offset = offset - uncorrected_offset;
1047   } else {
1048     accumulate_offset = offset;
1049     step_offset = 0.0;
1050   }
1051 
1052   /* Adjust the clock */
1053   LCL_AccumulateFrequencyAndOffset(frequency, accumulate_offset, correction_rate);
1054 
1055   maybe_log_offset(offset, raw_now.tv_sec);
1056 
1057   if (step_offset != 0.0) {
1058     if (LCL_ApplyStepOffset(step_offset))
1059       LOG(LOGS_WARN, "System clock was stepped by %.6f seconds", -step_offset);
1060   }
1061 
1062   update_leap_status(leap, raw_now.tv_sec, 0);
1063   update_sync_status(&now);
1064 
1065   /* Add a random error of up to one second to the reference time to make it
1066      less useful when disclosed to NTP and cmdmon clients for estimating
1067      receive timestamps in the interleaved symmetric NTP mode */
1068   fuzz_ref_time(&our_ref_time);
1069 
1070   local_abs_frequency = LCL_ReadAbsoluteFrequency();
1071 
1072   write_log(&now, combined_sources, local_abs_frequency,
1073             offset, offset_sd, uncorrected_offset, orig_root_distance);
1074 
1075   if (drift_file) {
1076     /* Update drift file at most once per hour */
1077     drift_file_age += update_interval;
1078     if (drift_file_age >= MAX_DRIFTFILE_AGE) {
1079       update_drift_file(local_abs_frequency, our_skew);
1080       drift_file_age = 0.0;
1081     }
1082   }
1083 
1084   /* Update fallback drifts */
1085   if (fb_drifts && are_we_synchronised) {
1086     update_fb_drifts(local_abs_frequency, update_interval);
1087     schedule_fb_drift();
1088   }
1089 
1090   /* Update the moving average of squares of offset, quickly on start */
1091   if (avg2_moving) {
1092     avg2_offset += 0.1 * (SQUARE(offset) - avg2_offset);
1093   } else {
1094     if (avg2_offset > 0.0 && avg2_offset < SQUARE(offset))
1095       avg2_moving = 1;
1096     avg2_offset = SQUARE(offset);
1097   }
1098 }
1099 
1100 /* ================================================== */
1101 
1102 void
REF_SetManualReference(struct timespec * ref_time,double offset,double frequency,double skew)1103 REF_SetManualReference
1104 (
1105  struct timespec *ref_time,
1106  double offset,
1107  double frequency,
1108  double skew
1109 )
1110 {
1111   /* We are not synchronised to an external source, as such.  This is
1112      only supposed to be used with the local source option, really.
1113      Log as MANU in the tracking log, packets will have NTP_REFID_LOCAL. */
1114   REF_SetReference(0, LEAP_Unsynchronised, 1, 0x4D414E55UL, NULL,
1115                    ref_time, offset, 0.0, frequency, skew, skew, 0.0, 0.0);
1116 }
1117 
1118 /* ================================================== */
1119 
1120 void
REF_SetUnsynchronised(void)1121 REF_SetUnsynchronised(void)
1122 {
1123   /* Variables required for logging to statistics log */
1124   struct timespec now, now_raw;
1125   double uncorrected_offset;
1126 
1127   assert(initialised);
1128 
1129   /* Special modes are implemented elsewhere */
1130   if (mode != REF_ModeNormal) {
1131     special_mode_sync(0, 0.0);
1132     return;
1133   }
1134 
1135   LCL_ReadRawTime(&now_raw);
1136   LCL_GetOffsetCorrection(&now_raw, &uncorrected_offset, NULL);
1137   UTI_AddDoubleToTimespec(&now_raw, uncorrected_offset, &now);
1138 
1139   if (fb_drifts) {
1140     schedule_fb_drift();
1141   }
1142 
1143   update_leap_status(LEAP_Unsynchronised, 0, 0);
1144   our_ref_ip.family = IPADDR_INET4;
1145   our_ref_ip.addr.in4 = 0;
1146   our_stratum = 0;
1147   are_we_synchronised = 0;
1148 
1149   LCL_SetSyncStatus(0, 0.0, 0.0);
1150 
1151   write_log(&now, 0, LCL_ReadAbsoluteFrequency(), 0.0, 0.0, uncorrected_offset,
1152             our_root_delay / 2.0 + get_root_dispersion(&now));
1153 }
1154 
1155 /* ================================================== */
1156 
1157 void
REF_UpdateLeapStatus(NTP_Leap leap)1158 REF_UpdateLeapStatus(NTP_Leap leap)
1159 {
1160   struct timespec raw_now, now;
1161 
1162   /* Wait for a full reference update if not already synchronised */
1163   if (!are_we_synchronised)
1164     return;
1165 
1166   SCH_GetLastEventTime(&now, NULL, &raw_now);
1167 
1168   update_leap_status(leap, raw_now.tv_sec, 0);
1169 
1170   /* Update also the synchronisation status */
1171   update_sync_status(&now);
1172 }
1173 
1174 /* ================================================== */
1175 
1176 void
REF_GetReferenceParams(struct timespec * local_time,int * is_synchronised,NTP_Leap * leap_status,int * stratum,uint32_t * ref_id,struct timespec * ref_time,double * root_delay,double * root_dispersion)1177 REF_GetReferenceParams
1178 (
1179  struct timespec *local_time,
1180  int *is_synchronised,
1181  NTP_Leap *leap_status,
1182  int *stratum,
1183  uint32_t *ref_id,
1184  struct timespec *ref_time,
1185  double *root_delay,
1186  double *root_dispersion
1187 )
1188 {
1189   double dispersion, delta;
1190 
1191   assert(initialised);
1192 
1193   if (are_we_synchronised) {
1194     dispersion = get_root_dispersion(local_time);
1195   } else {
1196     dispersion = 0.0;
1197   }
1198 
1199   /* Local reference is active when enabled and the clock is not synchronised
1200      or the root distance exceeds the threshold */
1201 
1202   if (are_we_synchronised &&
1203       !(enable_local_stratum && our_root_delay / 2 + dispersion > local_distance)) {
1204 
1205     *is_synchronised = 1;
1206 
1207     *stratum = our_stratum;
1208 
1209     *leap_status = !leap_in_progress ? our_leap_status : LEAP_Unsynchronised;
1210     *ref_id = our_ref_id;
1211     *ref_time = our_ref_time;
1212     *root_delay = our_root_delay;
1213     *root_dispersion = dispersion;
1214 
1215   } else if (enable_local_stratum) {
1216 
1217     *is_synchronised = 0;
1218 
1219     *stratum = local_stratum;
1220     *ref_id = NTP_REFID_LOCAL;
1221 
1222     /* Keep the reference timestamp up to date.  Adjust the timestamp to make
1223        sure that the transmit timestamp cannot come before this (which might
1224        fail a test of an NTP client). */
1225     delta = UTI_DiffTimespecsToDouble(local_time, &local_ref_time);
1226     if (delta > LOCAL_REF_UPDATE_INTERVAL || delta < 1.0) {
1227       UTI_AddDoubleToTimespec(local_time, -1.0, &local_ref_time);
1228       fuzz_ref_time(&local_ref_time);
1229     }
1230 
1231     *ref_time = local_ref_time;
1232 
1233     /* Not much else we can do for leap second bits - maybe need to
1234        have a way for the administrator to feed leap bits in */
1235     *leap_status = LEAP_Normal;
1236 
1237     *root_delay = 0.0;
1238     *root_dispersion = 0.0;
1239 
1240   } else {
1241 
1242     *is_synchronised = 0;
1243 
1244     *leap_status = LEAP_Unsynchronised;
1245     *stratum = NTP_MAX_STRATUM;
1246     *ref_id = NTP_REFID_UNSYNC;
1247     UTI_ZeroTimespec(ref_time);
1248     /* These values seem to be standard for a client, and
1249        any peer or client of ours will ignore them anyway because
1250        we don't claim to be synchronised */
1251     *root_dispersion = 1.0;
1252     *root_delay = 1.0;
1253 
1254   }
1255 }
1256 
1257 /* ================================================== */
1258 
1259 int
REF_GetOurStratum(void)1260 REF_GetOurStratum(void)
1261 {
1262   struct timespec now_cooked, ref_time;
1263   int synchronised, stratum;
1264   NTP_Leap leap_status;
1265   uint32_t ref_id;
1266   double root_delay, root_dispersion;
1267 
1268   SCH_GetLastEventTime(&now_cooked, NULL, NULL);
1269   REF_GetReferenceParams(&now_cooked, &synchronised, &leap_status, &stratum,
1270                          &ref_id, &ref_time, &root_delay, &root_dispersion);
1271 
1272   return stratum;
1273 }
1274 
1275 /* ================================================== */
1276 
1277 int
REF_GetOrphanStratum(void)1278 REF_GetOrphanStratum(void)
1279 {
1280   if (!enable_local_stratum || !local_orphan || mode != REF_ModeNormal)
1281     return NTP_MAX_STRATUM;
1282   return local_stratum;
1283 }
1284 
1285 /* ================================================== */
1286 
1287 double
REF_GetSkew(void)1288 REF_GetSkew(void)
1289 {
1290   return our_skew;
1291 }
1292 
1293 /* ================================================== */
1294 
1295 void
REF_ModifyMaxupdateskew(double new_max_update_skew)1296 REF_ModifyMaxupdateskew(double new_max_update_skew)
1297 {
1298   max_update_skew = new_max_update_skew * 1.0e-6;
1299 }
1300 
1301 /* ================================================== */
1302 
1303 void
REF_ModifyMakestep(int limit,double threshold)1304 REF_ModifyMakestep(int limit, double threshold)
1305 {
1306   make_step_limit = limit;
1307   make_step_threshold = threshold;
1308 }
1309 
1310 /* ================================================== */
1311 
1312 void
REF_EnableLocal(int stratum,double distance,int orphan)1313 REF_EnableLocal(int stratum, double distance, int orphan)
1314 {
1315   enable_local_stratum = 1;
1316   local_stratum = CLAMP(1, stratum, NTP_MAX_STRATUM - 1);
1317   local_distance = distance;
1318   local_orphan = !!orphan;
1319 }
1320 
1321 /* ================================================== */
1322 
1323 void
REF_DisableLocal(void)1324 REF_DisableLocal(void)
1325 {
1326   enable_local_stratum = 0;
1327 }
1328 
1329 /* ================================================== */
1330 
1331 #define LEAP_SECOND_CLOSE 5
1332 
1333 static int
is_leap_close(time_t t)1334 is_leap_close(time_t t)
1335 {
1336   return leap_when != 0 &&
1337          t >= leap_when - LEAP_SECOND_CLOSE && t < leap_when + LEAP_SECOND_CLOSE;
1338 }
1339 
1340 /* ================================================== */
1341 
REF_IsLeapSecondClose(struct timespec * ts,double offset)1342 int REF_IsLeapSecondClose(struct timespec *ts, double offset)
1343 {
1344   struct timespec now, now_raw;
1345 
1346   SCH_GetLastEventTime(&now, NULL, &now_raw);
1347 
1348   if (is_leap_close(now.tv_sec) || is_leap_close(now_raw.tv_sec))
1349     return 1;
1350 
1351   if (ts && (is_leap_close(ts->tv_sec) || is_leap_close(ts->tv_sec + offset)))
1352     return 1;
1353 
1354   return 0;
1355 }
1356 
1357 /* ================================================== */
1358 
1359 int
REF_GetTaiOffset(struct timespec * ts)1360 REF_GetTaiOffset(struct timespec *ts)
1361 {
1362   int tai_offset;
1363 
1364   get_tz_leap(ts->tv_sec, &tai_offset);
1365 
1366   return tai_offset;
1367 }
1368 
1369 /* ================================================== */
1370 
1371 void
REF_GetTrackingReport(RPT_TrackingReport * rep)1372 REF_GetTrackingReport(RPT_TrackingReport *rep)
1373 {
1374   struct timespec now_raw, now_cooked;
1375   double correction;
1376   int synchronised;
1377 
1378   LCL_ReadRawTime(&now_raw);
1379   LCL_GetOffsetCorrection(&now_raw, &correction, NULL);
1380   UTI_AddDoubleToTimespec(&now_raw, correction, &now_cooked);
1381 
1382   REF_GetReferenceParams(&now_cooked, &synchronised,
1383                          &rep->leap_status, &rep->stratum,
1384                          &rep->ref_id, &rep->ref_time,
1385                          &rep->root_delay, &rep->root_dispersion);
1386 
1387   if (rep->stratum == NTP_MAX_STRATUM && !synchronised)
1388     rep->stratum = 0;
1389 
1390   rep->ip_addr.family = IPADDR_UNSPEC;
1391   rep->current_correction = correction;
1392   rep->freq_ppm = LCL_ReadAbsoluteFrequency();
1393   rep->resid_freq_ppm = 0.0;
1394   rep->skew_ppm = 0.0;
1395   rep->last_update_interval = last_ref_update_interval;
1396   rep->last_offset = last_offset;
1397   rep->rms_offset = sqrt(avg2_offset);
1398 
1399   if (synchronised) {
1400     rep->ip_addr = our_ref_ip;
1401     rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
1402     rep->skew_ppm = 1.0e6 * our_skew;
1403   }
1404 }
1405