2 * Copyright (c) 2005 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
34 * $DragonFly: src/usr.sbin/dntpd/client.h,v 1.7 2007/06/25 21:33:36 dillon Exp $
38 int fd
; /* udp descriptor */
39 int server_state
; /* -1 (no dns), 0 (dns good), or 1 (pkt good) */
40 int server_insane
; /* insanity check */
41 int poll_sleep
; /* countdown for poll (in seconds) */
42 int poll_mode
; /* mode of operation */
43 int poll_count
; /* number of polls in current mode */
44 int poll_failed
; /* count of NTP failures */
45 struct sockaddr
*sam
; /* udp connection info */
46 struct sockaddr_storage sam_st
; /* udp connection info (stor) */
47 char *target
; /* target hostname or IP (string) */
48 char *ipstr
; /* IP string */
51 * A second linear regression playing hopskip with the first. This
52 * is maintained by the check function.
54 struct server_info
*altinfo
;
57 * Linear regression accumulator
59 * note: the starting base time is where all corrections get applied
60 * to eventually. The linear regression makes a relative microseconds
61 * calculation between the current base time and the starting base
62 * time to figure out what corrections the system has made to the
65 struct timeval lin_tv
; /* starting real time */
66 struct timeval lin_btv
; /* starting base time */
67 double lin_count
; /* samples */
68 double lin_sumx
; /* sum(x) */
69 double lin_sumy
; /* sum(y) */
70 double lin_sumxy
; /* sum(x*y) */
71 double lin_sumx2
; /* sum(x^2) */
72 double lin_sumy2
; /* sum(y^2) */
75 * Offsets are accumulated for a straight average. When a
76 * correction is made we have to reset the averaging code
77 * or follow-up corrections will oscillate wildly because
78 * the new offsets simply cannot compete with the dozens
79 * of previously polls in the sum.
81 double lin_sumoffset
; /* sum of compensated offsets */
82 double lin_sumoffset2
; /* sum of compensated offsets^2 */
83 double lin_countoffset
; /* count is reset after a correction is made */
88 double lin_cache_slope
; /* (freq calculations) */
89 double lin_cache_yint
; /* (freq calculations) */
90 double lin_cache_corr
; /* (freq calculations) */
91 double lin_cache_stddev
; /* (offset calculations) */
93 double lin_cache_offset
; /* last sampled offset (NOT an average) */
94 double lin_cache_freq
; /* last frequency correction (s/s) */
98 * Polling modes and max polls for specific modes. Note that the polling
99 * mode basically just effects the polling rate. It does not effect the
102 #define POLL_FIXED 0 /* fixed internal (nom_sleep_opt seconds) */
103 #define POLL_STARTUP 1 /* startup poll for offset adjust (min) */
104 #define POLL_ACQUIRE 2 /* acquisition for frequency adjust (nom) */
105 #define POLL_MAINTAIN 3 /* maintainance mode (max) */
106 #define POLL_FAILED 4 /* failure state (nom) */
108 #define POLL_STARTUP_MAX 6 /* max polls in this mode */
109 #define POLL_ACQUIRE_MAX 16 /* max polls in this mode */
110 #define POLL_FAIL_RESET 3 /* reset the regression after 3 fails */
111 #define POLL_RECOVERY_RESTART 10 /* ->ACQ vs ->STARTUP after recovery */
114 * We start a second linear regression a LIN_RESTART / 2 and it
115 * replaces the first one (and we start a third) at LIN_RESTART.
117 #define LIN_RESTART 30
120 * A course correction is made if the time gets more then 2 minutes
123 #define COURSE_OFFSET_CORRECTION_LIMIT 120.0
125 typedef struct server_info
*server_info_t
;
127 void client_init(void);
128 int client_main(struct server_info
**info_ary
, int count
);
129 void client_poll(server_info_t info
, int poll_interval
,
130 int calc_offset_correction
);
131 void client_check(struct server_info
**check
,
132 struct server_info
**best_off
,
133 struct server_info
**best_freq
);
134 void client_check_duplicate_ips(struct server_info
**info_ary
, int count
);
135 void client_manage_polling_mode(struct server_info
*info
, int *didreconnect
);
136 void client_setserverstate(server_info_t info
, int state
, const char *str
);
138 void lin_regress(server_info_t info
,
139 struct timeval
*ltv
, struct timeval
*lbtv
,
140 double offset
, int calc_offset_correction
);
141 void lin_reset(server_info_t info
);
142 void lin_resetalloffsets(struct server_info
**info_ary
, int count
);
143 void lin_resetoffsets(server_info_t info
);