Merge remote branch 'crater/DragonFly_RELEASE_3_0' into rel3_0
[dragonfly.git] / usr.sbin / dntpd / client.c
1 /*
2  * Copyright (c) 2005 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/usr.sbin/dntpd/client.c,v 1.13 2007/06/26 02:40:20 dillon Exp $
35  */
36
37 #include "defs.h"
38
39 static int client_insane(struct server_info **, int, server_info_t);
40
41 void
42 client_init(void)
43 {
44 }
45
46 int
47 client_main(struct server_info **info_ary, int count)
48 {
49     struct server_info *best_off;
50     struct server_info *best_freq;
51     double last_freq;
52     double freq;
53     double offset;
54     int calc_offset_correction;
55     int didreconnect;
56     int i;
57     int insane;
58
59     last_freq = 0.0;
60
61     for (;;) {
62         /*
63          * Subtract the interval from poll_sleep and poll the client
64          * if it reaches 0.
65          *
66          * Because we do not compensate for offset corrections which are
67          * in progress, we cannot accumulate data for an offset correction
68          * while a prior correction is still being worked through by the
69          * system.
70          */
71         calc_offset_correction = !sysntp_offset_correction_is_running();
72         for (i = 0; i < count; ++i)
73             client_poll(info_ary[i], min_sleep_opt, calc_offset_correction);
74
75         /*
76          * Find the best client (or synthesize one).  A different client
77          * can be chosen for frequency and offset.  Note in particular 
78          * that offset counters and averaging code gets reset when an
79          * offset correction is made (otherwise the averaging history will
80          * cause later corrections to overshoot).  
81          * 
82          * The regression used to calculate the frequency is a much 
83          * longer-term entity and is NOT reset, so it is still possible
84          * for the offset correction code to make minor adjustments to
85          * the frequency if it so desires.
86          *
87          * client_check may replace the server_info pointer with a new
88          * one.
89          */
90         best_off = NULL;
91         best_freq = NULL;
92         for (i = 0; i < count; ++i)
93             client_check(&info_ary[i], &best_off, &best_freq);
94
95         /*
96          * Check for server insanity.  In large NNTP pools some servers
97          * may just be dead wrong, but report that they are right.
98          */
99         if (best_off) {
100             insane = client_insane(info_ary, count, best_off);
101             if (insane > 0) {
102                 /* 
103                  * best_off meets the quorum requirements and is good
104                  * (keep best_off)
105                  */
106                 best_off->server_insane = 0;
107             } else if (insane == 0) {
108                 /*
109                  * best_off is probably good, but we do not have enough
110                  * servers reporting yet to meet the quorum requirements.
111                  */
112                 best_off = NULL;
113             } else {
114                 /*
115                  * best_off is ugly, mark the server as being insane for
116                  * 60 minutes.
117                  */
118                 best_off->server_insane = 60 * 60;
119                 logdebuginfo(best_off, 1, 
120                              "excessive offset deviation, mapping out\n");
121                 best_off = NULL;
122             }
123         }
124
125         /*
126          * Offset correction.
127          */
128         if (best_off) {
129             offset = best_off->lin_sumoffset / best_off->lin_countoffset;
130             lin_resetalloffsets(info_ary, count);
131             if (offset < -COURSE_OFFSET_CORRECTION_LIMIT ||
132                 offset > COURSE_OFFSET_CORRECTION_LIMIT ||
133                 quickset_opt
134             ) {
135                 freq = sysntp_correct_course_offset(offset);
136                 quickset_opt = 0;
137             } else {
138                 freq = sysntp_correct_offset(offset);
139             }
140         } else {
141             freq = 0.0;
142         }
143
144         /*
145          * Frequency correction (throw away minor freq adjusts from the
146          * offset code if we can't do a frequency correction here).  Do
147          * not reissue if it hasn't changed from the last issued correction.
148          */
149         if (best_freq) {
150             freq += best_freq->lin_cache_freq;
151             if (last_freq != freq) {
152                 sysntp_correct_freq(freq);
153                 last_freq = freq;
154             }
155         }
156
157         /*
158          * This function is responsible for managing the polling mode and
159          * figures out how long we should sleep.
160          */
161         didreconnect = 0;
162         for (i = 0; i < count; ++i)
163             client_manage_polling_mode(info_ary[i], &didreconnect);
164         if (didreconnect)
165             client_check_duplicate_ips(info_ary, count);
166
167         /*
168          * Polling loop sleep.
169          */
170         usleep(min_sleep_opt * 1000000 + random() % 500000);
171     }
172 }
173
174 void
175 client_poll(server_info_t info, int poll_interval, int calc_offset_correction)
176 {
177     struct timeval rtv;
178     struct timeval ltv;
179     struct timeval lbtv;
180     double offset;
181
182     /*
183      * Adjust the insane-server countdown
184      */
185     if (info->server_insane > poll_interval)
186         info->server_insane -= poll_interval;
187     else
188         info->server_insane = 0;
189
190     /*
191      * By default we always poll.  If the polling interval comes under
192      * active management the poll_sleep will be non-zero.
193      */
194     if (info->poll_sleep > poll_interval) {
195         info->poll_sleep -= poll_interval;
196         return;
197     }
198     info->poll_sleep = 0;
199
200     /*
201      * If the client isn't open don't mess with the poll_failed count
202      * or anything else.  We are left in the init or startup phase.
203      */
204     if (info->fd < 0) {
205         if (info->poll_failed < 0x7FFFFFFF)
206             ++info->poll_failed;
207         return;
208     }
209
210     logdebuginfo(info, 4, "poll, ");
211     if (udp_ntptimereq(info->fd, &rtv, &ltv, &lbtv) < 0) {
212         ++info->poll_failed;
213         logdebug(4, "no response (%d failures in a row)\n", info->poll_failed);
214         if (info->poll_failed == POLL_FAIL_RESET) {
215             if (info->lin_count != 0) {
216                 logdebuginfo(info, 4, "resetting regression due to failures\n");
217             }
218             lin_reset(info);
219         }
220         return;
221     }
222
223     /*
224      * Successful query.  Update polling info for the polling mode manager.
225      */
226     ++info->poll_count;
227     info->poll_failed = 0;
228
229     /*
230      * Figure out the offset (the difference between the reported
231      * time and our current time) for linear regression purposes.
232      */
233     offset = tv_delta_double(&rtv, &ltv);
234
235     while (info) {
236         /*
237          * Linear regression
238          */
239         if (debug_level >= 4) {
240             struct tm *tp;
241             char buf[64];
242             time_t t;
243
244             t = rtv.tv_sec;
245             tp = localtime(&t);
246             strftime(buf, sizeof(buf), "%d-%b-%Y %H:%M:%S", tp);
247             logdebug(4, "%s.%03ld ", buf, rtv.tv_usec / 1000);
248         }
249         lin_regress(info, &ltv, &lbtv, offset, calc_offset_correction);
250         info = info->altinfo;
251         if (info && debug_level >= 4) {
252             logdebug(4, "%*.*s: poll, ", 
253                 (int)strlen(info->target), 
254                 (int)strlen(info->target), "(alt)");
255         }
256     }
257 }
258
259 /*
260  * Find the best client (or synthesize a fake info structure to return).
261  * We can find separate best clients for offset and frequency.
262  */
263 void
264 client_check(struct server_info **checkp, 
265              struct server_info **best_off,
266              struct server_info **best_freq)
267 {
268     struct server_info *check = *checkp;
269     struct server_info *info;
270
271     /*
272      * Start an alternate linear regression once our current one
273      * has passed a certain point.
274      */
275     if (check->lin_count >= LIN_RESTART / 2 && check->altinfo == NULL) {
276         info = malloc(sizeof(*info));
277         assert(info != NULL);
278         /* note: check->altinfo is NULL as of the bcopy */
279         bcopy(check, info, sizeof(*info));
280         check->altinfo = info;
281         lin_reset(info);
282     }
283
284     /*
285      * Replace our current linear regression with the alternate once
286      * the current one has hit its limit (beyond a certain point the
287      * linear regression starts to work against us, preventing us from
288      * reacting to changing conditions).
289      *
290      * Report any significant change in the offset or ppm.
291      */
292     if (check->lin_count >= LIN_RESTART) {
293         if ((info = check->altinfo) && info->lin_count >= LIN_RESTART / 2) {
294             double freq_diff;
295
296             freq_diff = info->lin_cache_freq - check->lin_cache_freq;
297             logdebuginfo(info, 4, "Switching to alternate, Frequence "
298                          "difference is %6.3f ppm\n",
299                          freq_diff * 1.0E+6);
300             *checkp = info;
301             free(check);
302             check = info;
303         }
304     }
305
306     /*
307      * BEST CLIENT FOR FREQUENCY CORRECTION:
308      *
309      *  8 samples and a correlation > 0.99, or
310      * 16 samples and a correlation > 0.96
311      */
312     info = *best_freq;
313     if ((check->lin_count >= 8 && fabs(check->lin_cache_corr) >= 0.99) ||
314         (check->lin_count >= 16 && fabs(check->lin_cache_corr) >= 0.96)
315     ) {
316         if (info == NULL || 
317             fabs(check->lin_cache_corr) > fabs(info->lin_cache_corr)
318         ) {
319             info = check;
320             *best_freq = info;
321         }
322
323     }
324
325     /*
326      * BEST CLIENT FOR OFFSET CORRECTION:
327      *
328      * Use the standard-deviation and require at least 4 samples.  An
329      * offset correction is valid if the standard deviation is less then
330      * the average offset divided by 4.
331      *
332      * Servers marked as being insane are not allowed
333      */
334     info = *best_off;
335     if (check->lin_countoffset >= 4 && 
336         (check->lin_cache_stddev <
337          fabs(check->lin_sumoffset / check->lin_countoffset / 4)) &&
338         check->server_insane == 0
339      ) {
340         if (info == NULL || 
341             fabs(check->lin_cache_stddev) < fabs(info->lin_cache_stddev)
342         ) {
343             info = check;
344             *best_off = info;
345         }
346     }
347 }
348
349 /*
350  * Actively manage the polling interval.  Note that the poll_* fields are
351  * always transfered to the alternate regression when the check code replaces
352  * the current regression with a new one.
353  *
354  * This routine is called from the main loop for each base info structure.
355  * The polling mode applies to all alternates so we do not have to iterate
356  * through the alt's.
357  */
358 void
359 client_manage_polling_mode(struct server_info *info, int *didreconnect)
360 {
361     /*
362      * Permanently failed servers are ignored.
363      */
364     if (info->server_state == -2)
365         return;
366
367     /*
368      * Our polling interval has not yet passed.
369      */
370     if (info->poll_sleep)
371         return;
372
373     /*
374      * Standard polling mode progression
375      */
376     switch(info->poll_mode) {
377     case POLL_FIXED:
378         /*
379          * Initial state after connect or when a reconnect is required.
380          */
381         if (info->fd < 0) {
382             logdebuginfo(info, 2, "polling mode INIT, relookup & reconnect\n");
383             reconnect_server(info);
384             *didreconnect = 1;
385             if (info->fd < 0) {
386                 if (info->poll_failed >= POLL_RECOVERY_RESTART * 5)
387                     info->poll_sleep = max_sleep_opt;
388                 else if (info->poll_failed >= POLL_RECOVERY_RESTART)
389                     info->poll_sleep = nom_sleep_opt;
390                 else
391                     info->poll_sleep = min_sleep_opt;
392                 break;
393             }
394
395             /*
396              * Transition the server to the DNS lookup successful state.
397              * Note that the server state does not transition out of
398              * lookup successful if we relookup after a packet failure
399              * so the message is printed only once, usually.
400              */
401             client_setserverstate(info, 0, "DNS lookup success");
402
403             /*
404              * If we've failed many times switch to the startup state but
405              * do not fall through into it.  break the switch and a single
406              * poll will be made after the nominal polling interval.
407              */
408             if (info->poll_failed >= POLL_RECOVERY_RESTART * 5) {
409                 logdebuginfo(info, 2, "polling mode INIT->STARTUP (very slow)\n");
410                 info->poll_mode = POLL_STARTUP;
411                 info->poll_sleep = max_sleep_opt;
412                 info->poll_count = 0;
413                 break;
414             } else if (info->poll_failed >= POLL_RECOVERY_RESTART) {
415                 logdebuginfo(info, 2, "polling mode INIT->STARTUP (slow)\n");
416                 info->poll_mode = POLL_STARTUP;
417                 info->poll_count = 0;
418                 break;
419             }
420         }
421
422         /*
423          * Fall through to the startup state.
424          */
425         info->poll_mode = POLL_STARTUP;
426         logdebuginfo(info, 2, "polling mode INIT->STARTUP (normal)\n");
427         /* fall through */
428     case POLL_STARTUP:
429         /*
430          * Transition to a FAILED state if too many poll failures occured.
431          */
432         if (info->poll_failed >= POLL_FAIL_RESET) {
433             logdebuginfo(info, 2, "polling mode STARTUP->FAILED\n");
434             info->poll_mode = POLL_FAILED;
435             info->poll_count = 0;
436             break;
437         }
438
439         /*
440          * Transition the server to operational.  Do a number of minimum
441          * interval polls to try to get a good offset calculation quickly.
442          */
443         if (info->poll_count)
444             client_setserverstate(info, 1, "connected ok");
445         if (info->poll_count < POLL_STARTUP_MAX) {
446             info->poll_sleep = min_sleep_opt;
447             break;
448         }
449
450         /*
451          * Once we've got our polls fall through to aquisition mode to
452          * do aquisition processing.
453          */
454         info->poll_mode = POLL_ACQUIRE;
455         info->poll_count = 0;
456         logdebuginfo(info, 2, "polling mode STARTUP->ACQUIRE\n");
457         /* fall through */
458     case POLL_ACQUIRE:
459         /*
460          * Transition to a FAILED state if too many poll failures occured.
461          */
462         if (info->poll_failed >= POLL_FAIL_RESET) {
463             logdebuginfo(info, 2, "polling mode STARTUP->FAILED\n");
464             info->poll_mode = POLL_FAILED;
465             info->poll_count = 0;
466             break;
467         }
468
469         /*
470          * Acquisition mode using the nominal timeout.  We do not shift
471          * to maintainance mode unless the correlation is at least 0.90
472          */
473         if (info->poll_count < POLL_ACQUIRE_MAX ||
474             info->lin_count < 8 ||
475             fabs(info->lin_cache_corr) < 0.85
476         ) {
477             if (info->poll_count >= POLL_ACQUIRE_MAX && 
478                 info->lin_count == LIN_RESTART - 2
479             ) {
480                 logdebuginfo(info, 2, 
481                     "WARNING: Unable to shift this source to "
482                     "maintenance mode.  Target correlation is aweful\n");
483             }
484             break;
485         }
486         info->poll_mode = POLL_MAINTAIN;
487         info->poll_count = 0;
488         logdebuginfo(info, 2, "polling mode ACQUIRE->MAINTAIN\n");
489         /* fall through */
490     case POLL_MAINTAIN:
491         /*
492          * Transition to a FAILED state if too many poll failures occured.
493          */
494         if (info->poll_failed >= POLL_FAIL_RESET) {
495             logdebuginfo(info, 2, "polling mode STARTUP->FAILED\n");
496             info->poll_mode = POLL_FAILED;
497             info->poll_count = 0;
498             break;
499         }
500
501         /*
502          * Maintaince mode, max polling interval.
503          *
504          * Transition back to acquisition mode if we are unable to maintain
505          * this mode due to the correlation going bad.
506          */
507         if (info->lin_count >= LIN_RESTART / 2 && 
508             fabs(info->lin_cache_corr) < 0.70
509         ) {
510             logdebuginfo(info, 2, 
511                 "polling mode MAINTAIN->ACQUIRE.  Unable to maintain\n"
512                 "the maintenance mode because the correlation went"
513                 " bad!\n");
514             info->poll_mode = POLL_ACQUIRE;
515             info->poll_count = 0;
516             break;
517         }
518         info->poll_sleep = max_sleep_opt;
519         break;
520     case POLL_FAILED:
521         /*
522          * We have a communications failure.  A late recovery is possible 
523          * if we enter this state with a good poll.
524          */
525         if (info->poll_count != 0) {
526             logdebuginfo(info, 2, "polling mode FAILED->ACQUIRE\n");
527             if (info->poll_failed >= POLL_FAIL_RESET)
528                 info->poll_mode = POLL_STARTUP;
529             else
530                 info->poll_mode = POLL_ACQUIRE;
531             /* do not reset poll_count */
532             break;
533         }
534
535         /*
536          * If we have been failed too long, disconnect from the server
537          * and start us all over again.  Note that the failed count is not
538          * reset to 0.
539          */
540         if (info->poll_failed >= POLL_RECOVERY_RESTART) {
541             logdebuginfo(info, 2, "polling mode FAILED->INIT\n");
542             client_setserverstate(info, 0, "FAILED");
543             disconnect_server(info);
544             info->poll_mode = POLL_FIXED;
545             break;
546         }
547         break;
548     }
549
550     /*
551      * If the above state machine has not set a polling interval, set a
552      * nominal polling interval.
553      */
554     if (info->poll_sleep == 0)
555         info->poll_sleep = nom_sleep_opt;
556 }
557
558 /*
559  * Look for duplicate IP addresses.  This is done very inoften, so we do
560  * not use a particularly efficient algorithm.
561  *
562  * Only reconnect a client which has not done its initial poll.
563  */
564 void
565 client_check_duplicate_ips(struct server_info **info_ary, int count)
566 {
567     server_info_t info1;
568     server_info_t info2;
569     int tries;
570     int i;
571     int j;
572
573     for (i = 0; i < count; ++i) {
574         info1 = info_ary[i];
575         if (info1->fd < 0 || info1->server_state != 0)
576             continue;
577         for (tries = 0; tries < 10; ++tries) {
578             for (j = 0; j < count; ++j) {
579                 info2 = info_ary[j];
580                 if (i == j || info2->fd < 0)
581                     continue;
582                 if (info1->fd < 0 || /* info1 was lost in previous reconnect */
583                     strcmp(info1->ipstr, info2->ipstr) == 0) {
584                     reconnect_server(info1);
585                     break;
586                 }
587             }
588             if (j == count)
589                 break;
590         }
591         if (tries == 10) {
592             disconnect_server(info1);
593             client_setserverstate(info1, -2,
594                                   "permanently disabling duplicate server");
595         }
596     }
597 }
598
599 /*
600  * Calculate whether the server pointed to by *bestp is insane or not.
601  * For some reason some servers in e.g. the ntp pool are sometimes an hour
602  * off.  If we have at least three servers in the pool require that a
603  * quorum agree that the current best server's offset is reasonable.
604  *
605  * Allow +/- 0.5 seconds of error for now (settable with option).
606  *
607  * Returns -1 if insane, 0 if not enough samples, and 1 if ok
608  */
609 static
610 int
611 client_insane(struct server_info **info_ary, int count, server_info_t best)
612 {
613     server_info_t info;
614     double best_offset;
615     double info_offset;
616     int good;
617     int bad;
618     int skip;
619     int quorum;
620     int i;
621
622     /*
623      * If only one ntp server we cannot check to see if it is insane
624      */
625     if (count < 2)
626             return(1);
627     best_offset = best->lin_sumoffset / best->lin_countoffset;
628
629     /*
630      * Calculated the quorum.  Do not count permanently failed servers
631      * in the calculation.
632      *
633      * adjusted count   quorum
634      *   2                2
635      *   3                2
636      *   4                3
637      *   5                3
638      */
639     quorum = count;
640     for (i = 0; i < count; ++i) {
641         info = info_ary[i];
642         if (info->server_state == -2)
643             --quorum;
644     }
645
646     quorum = quorum / 2 + 1;
647     good = 0;
648     bad = 0;
649     skip = 0;
650
651     /*
652      * Find the good, the bad, and the ugly.  We need at least four samples
653      * and a stddev within the deviation being checked to count a server
654      * in the calculation.
655      */
656     for (i = 0; i < count; ++i) {
657         info = info_ary[i];
658         if (info->lin_countoffset < 4 ||
659             info->lin_cache_stddev > insane_deviation
660         ) {
661             ++skip;
662             continue;
663         }
664
665         info_offset = info->lin_sumoffset / info->lin_countoffset;
666         info_offset -= best_offset;
667         if (info_offset < -insane_deviation || info_offset > insane_deviation)
668                 ++bad;
669         else
670                 ++good;
671     }
672
673     /*
674      * Did we meet our quorum?
675      */
676     logdebuginfo(best, 5, "insanecheck good=%d bad=%d skip=%d "
677                           "quorum=%d (allowed=%-+8.6f)\n",
678                  good, bad, skip, quorum, insane_deviation);
679     if (good >= quorum)
680         return(1);
681     if (good + skip >= quorum)
682         return(0);
683     return(-1);
684 }
685
686 /*
687  * Linear regression.
688  *
689  *      ltv     local time as of when the offset error was calculated between
690  *              local time and remote time.
691  *
692  *      lbtv    base time as of when local time was obtained.  Used to
693  *              calculate the cumulative corrections made to the system's
694  *              real time clock so we can de-correct the offset for the
695  *              linear regression.
696  *
697  * X is the time axis, in seconds.
698  * Y is the uncorrected offset, in seconds.
699  */
700 void
701 lin_regress(server_info_t info, struct timeval *ltv, struct timeval *lbtv,
702             double offset, int calc_offset_correction)
703 {
704     double time_axis;
705     double uncorrected_offset;
706
707     /*
708      * De-correcting the offset:
709      *
710      *  The passed offset is (our_real_time - remote_real_time).  To remove
711      *  corrections from our_real_time we take the difference in the basetime
712      *  (new_base_time - old_base_time) and subtract that from the offset.
713      *  That is, if the basetime goesup, the uncorrected offset goes down.
714      */
715     if (info->lin_count == 0) {
716         info->lin_tv = *ltv;
717         info->lin_btv = *lbtv;
718         time_axis = 0;
719         uncorrected_offset = offset;
720     } else {
721         time_axis = tv_delta_double(&info->lin_tv, ltv);
722         uncorrected_offset = offset - tv_delta_double(&info->lin_btv, lbtv);
723     }
724
725     /*
726      * We have to use the uncorrected offset for frequency calculations.
727      */
728     ++info->lin_count;
729     info->lin_sumx += time_axis;
730     info->lin_sumx2 += time_axis * time_axis;
731     info->lin_sumy += uncorrected_offset;
732     info->lin_sumy2 += uncorrected_offset * uncorrected_offset;
733     info->lin_sumxy += time_axis * uncorrected_offset;
734
735     /*
736      * We have to use the corrected offset for offset calculations.
737      */
738     if (calc_offset_correction) {
739         ++info->lin_countoffset;
740         info->lin_sumoffset += offset;
741         info->lin_sumoffset2 += offset * offset;
742     }
743
744     /*
745      * Calculate various derived values.   This gets us slope, y-intercept,
746      * and correlation from the linear regression.
747      */
748     if (info->lin_count > 1) {
749         info->lin_cache_slope = 
750          (info->lin_count * info->lin_sumxy - info->lin_sumx * info->lin_sumy) /
751          (info->lin_count * info->lin_sumx2 - info->lin_sumx * info->lin_sumx);
752
753         info->lin_cache_yint = 
754          (info->lin_sumy - info->lin_cache_slope * info->lin_sumx) /
755          (info->lin_count);
756
757         info->lin_cache_corr =
758          (info->lin_count * info->lin_sumxy - info->lin_sumx * info->lin_sumy) /
759          sqrt((info->lin_count * info->lin_sumx2 - 
760                       info->lin_sumx * info->lin_sumx) *
761              (info->lin_count * info->lin_sumy2 - 
762                       info->lin_sumy * info->lin_sumy)
763          );
764     }
765
766     /*
767      * Calculate more derived values.  This gets us the standard-deviation
768      * of offsets.  The standard deviation approximately means that 68%
769      * of the samples fall within the calculated stddev of the mean.
770      */
771     if (info->lin_countoffset > 1) {
772          info->lin_cache_stddev = 
773              sqrt((info->lin_sumoffset2 - 
774                  ((info->lin_sumoffset * info->lin_sumoffset / 
775                    info->lin_countoffset))) /
776                  (info->lin_countoffset - 1.0));
777     }
778
779     /*
780      * Save the most recent offset, we might use it in the future.
781      * Save the frequency correction (we might scale the slope later so
782      * we have a separate field for the actual frequency correction in
783      * seconds per second).
784      */
785     info->lin_cache_offset = offset;
786     info->lin_cache_freq = info->lin_cache_slope;
787
788     if (debug_level >= 4) {
789         logdebuginfo(info, 4, "iter=%2d time=%7.3f off=%+.6f uoff=%+.6f",
790             (int)info->lin_count,
791             time_axis, offset, uncorrected_offset);
792         if (info->lin_count > 1) {
793             logdebug(4, " slope %+7.6f"
794                             " yint %+3.2f corr %+7.6f freq_ppm %+4.2f", 
795                 info->lin_cache_slope,
796                 info->lin_cache_yint,
797                 info->lin_cache_corr,
798                 info->lin_cache_freq * 1000000.0);
799         }
800         if (info->lin_countoffset > 1) {
801             logdebug(4, " stddev %7.6f", info->lin_cache_stddev);
802         } else if (calc_offset_correction == 0) {
803             /* cannot calculate offset correction due to prior correction */
804             logdebug(4, " offset_ignored");
805         }
806         logdebug(4, "\n");
807     }
808 }
809
810 /*
811  * Reset the linear regression data.  The info structure will not again be
812  * a candidate for frequency or offset correction until sufficient data
813  * has been accumulated to make a decision.
814  */
815 void
816 lin_reset(server_info_t info)
817 {
818     server_info_t scan;
819
820     info->lin_count = 0;
821     info->lin_sumx = 0;
822     info->lin_sumy = 0;
823     info->lin_sumxy = 0;
824     info->lin_sumx2 = 0;
825     info->lin_sumy2 = 0;
826
827     info->lin_countoffset = 0;
828     info->lin_sumoffset = 0;
829     info->lin_sumoffset2 = 0;
830
831     info->lin_cache_slope = 0;
832     info->lin_cache_yint = 0;
833     info->lin_cache_corr = 0;
834     info->lin_cache_offset = 0;
835     info->lin_cache_freq = 0;
836
837     /*
838      * Destroy any additional alternative regressions.
839      */
840     while ((scan = info->altinfo) != NULL) {
841         info->altinfo = scan->altinfo;
842         free(scan);
843     }
844 }
845
846 /*
847  * Sometimes we want to clean out the offset calculations without
848  * destroying the linear regression used to figure out the frequency
849  * correction.  This usually occurs whenever we issue an offset
850  * adjustment to the system, which invalidates any offset data accumulated
851  * up to that point.
852  */
853 void
854 lin_resetalloffsets(struct server_info **info_ary, int count)
855 {
856     server_info_t info;
857     int i;
858
859     for (i = 0; i < count; ++i) {
860         for (info = info_ary[i]; info; info = info->altinfo)
861             lin_resetoffsets(info);
862     }
863 }
864
865 void
866 lin_resetoffsets(server_info_t info)
867 {
868     info->lin_countoffset = 0;
869     info->lin_sumoffset = 0;
870     info->lin_sumoffset2 = 0;
871 }
872
873 void
874 client_setserverstate(server_info_t info, int state, const char *str)
875 {
876     if (info->server_state != state) {
877         info->server_state = state;
878         logdebuginfo(info, 1, "%s\n", str);
879     }
880 }
881