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