1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108#include "libbb.h"
109#include <math.h>
110#include <netinet/ip.h>
111#include <sys/timex.h>
112#ifndef IPTOS_DSCP_AF21
113# define IPTOS_DSCP_AF21 0x48
114#endif
115
116#if defined(__FreeBSD__)
117
118# define adjtimex ntp_adjtime
119# define ADJ_OFFSET MOD_OFFSET
120# define ADJ_STATUS MOD_STATUS
121# define ADJ_TIMECONST MOD_TIMECONST
122#endif
123
124
125
126
127
128#define MAX_VERBOSE 3
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163#define INITIAL_SAMPLES 3
164#define MIN_FREQHOLD 10
165#define BAD_DELAY_GROWTH 4
166
167#define RETRY_INTERVAL 32
168#define NOREPLY_INTERVAL 512
169#define RESPONSE_INTERVAL 16
170#define HOSTNAME_INTERVAL 4
171#define DNS_ERRORS_CAP 0x3f
172
173
174
175#define STEP_THRESHOLD 1
176
177
178
179#define SLEW_THRESHOLD 0.5
180
181
182
183
184
185
186
187
188
189#define BIGOFF STEP_THRESHOLD
190#define BIGOFF_INTERVAL (1 << 7)
191
192#define FREQ_TOLERANCE 0.000015
193#define BURSTPOLL 0
194#define MINPOLL 5
195
196
197
198#define BIGPOLL 9
199#define MAXPOLL 12
200
201
202
203
204
205#define MINDISP 0.01
206#define MAXDISP 16
207#define MAXSTRAT 16
208#define MAXDIST 1
209#define MIN_SELECTED 1
210#define MIN_CLUSTERED 3
211
212
213#define USING_KERNEL_PLL_LOOP 1
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230#define POLLADJ_LIMIT 40
231
232
233
234
235#define POLLADJ_GATE 4
236#define TIMECONST_HACK_GATE 2
237
238#define AVG 4
239
240#define MAX_KEY_NUMBER 65535
241#define KEYID_SIZE sizeof(uint32_t)
242
243enum {
244 NTP_VERSION = 4,
245 NTP_MAXSTRATUM = 15,
246
247 NTP_MD5_DIGESTSIZE = 16,
248 NTP_MSGSIZE_NOAUTH = 48,
249 NTP_MSGSIZE_MD5_AUTH = NTP_MSGSIZE_NOAUTH + KEYID_SIZE + NTP_MD5_DIGESTSIZE,
250 NTP_SHA1_DIGESTSIZE = 20,
251 NTP_MSGSIZE_SHA1_AUTH = NTP_MSGSIZE_NOAUTH + KEYID_SIZE + NTP_SHA1_DIGESTSIZE,
252
253
254 MODE_MASK = (7 << 0),
255 VERSION_MASK = (7 << 3),
256 VERSION_SHIFT = 3,
257 LI_MASK = (3 << 6),
258
259
260 LI_NOWARNING = (0 << 6),
261 LI_PLUSSEC = (1 << 6),
262 LI_MINUSSEC = (2 << 6),
263 LI_ALARM = (3 << 6),
264
265
266 MODE_RES0 = 0,
267 MODE_SYM_ACT = 1,
268 MODE_SYM_PAS = 2,
269 MODE_CLIENT = 3,
270 MODE_SERVER = 4,
271 MODE_BROADCAST = 5,
272 MODE_RES1 = 6,
273 MODE_RES2 = 7,
274};
275
276
277#define OFFSET_1900_1970 2208988800UL
278
279#define NUM_DATAPOINTS 8
280
281typedef struct {
282 uint32_t int_partl;
283 uint32_t fractionl;
284} l_fixedpt_t;
285
286typedef struct {
287 uint16_t int_parts;
288 uint16_t fractions;
289} s_fixedpt_t;
290
291typedef struct {
292 uint8_t m_status;
293 uint8_t m_stratum;
294 uint8_t m_ppoll;
295 int8_t m_precision_exp;
296 s_fixedpt_t m_rootdelay;
297 s_fixedpt_t m_rootdisp;
298 uint32_t m_refid;
299 l_fixedpt_t m_reftime;
300 l_fixedpt_t m_orgtime;
301 l_fixedpt_t m_rectime;
302 l_fixedpt_t m_xmttime;
303 uint32_t m_keyid;
304 uint8_t m_digest[ENABLE_FEATURE_NTP_AUTH ? NTP_SHA1_DIGESTSIZE : NTP_MD5_DIGESTSIZE];
305} msg_t;
306
307typedef struct {
308 double d_offset;
309 double d_recv_time;
310 double d_dispersion;
311} datapoint_t;
312
313#if ENABLE_FEATURE_NTP_AUTH
314enum {
315 HASH_MD5,
316 HASH_SHA1,
317};
318typedef struct {
319 unsigned id;
320 smalluint type;
321 smalluint msg_size;
322 smalluint key_length;
323 char key[0];
324} key_entry_t;
325#endif
326
327typedef struct {
328 len_and_sockaddr *p_lsa;
329 char *p_dotted;
330#if ENABLE_FEATURE_NTP_AUTH
331 key_entry_t *key_entry;
332#endif
333 int p_fd;
334 int datapoint_idx;
335#if ENABLE_FEATURE_NTPD_SERVER
336 uint32_t p_refid;
337#endif
338 uint32_t lastpkt_refid;
339 uint8_t lastpkt_status;
340 uint8_t lastpkt_stratum;
341 uint8_t reachable_bits;
342 uint8_t dns_errors;
343
344
345 double next_action_time;
346 double p_xmttime;
347 double p_raw_delay;
348
349
350 double lastpkt_recv_time;
351 double lastpkt_delay;
352 double lastpkt_rootdelay;
353 double lastpkt_rootdisp;
354
355 double filter_offset;
356 double filter_dispersion;
357 double filter_jitter;
358 datapoint_t filter_datapoint[NUM_DATAPOINTS];
359
360 msg_t p_xmt_msg;
361 char p_hostname[1];
362} peer_t;
363
364enum {
365 OPT_n = (1 << 0),
366 OPT_q = (1 << 1),
367 OPT_N = (1 << 2),
368 OPT_x = (1 << 3),
369 OPT_k = (1 << 4) * ENABLE_FEATURE_NTP_AUTH,
370
371
372 OPT_w = (1 << (4+ENABLE_FEATURE_NTP_AUTH)),
373 OPT_p = (1 << (5+ENABLE_FEATURE_NTP_AUTH)),
374 OPT_S = (1 << (6+ENABLE_FEATURE_NTP_AUTH)),
375 OPT_l = (1 << (7+ENABLE_FEATURE_NTP_AUTH)) * ENABLE_FEATURE_NTPD_SERVER,
376 OPT_I = (1 << (8+ENABLE_FEATURE_NTP_AUTH)) * ENABLE_FEATURE_NTPD_SERVER,
377
378 OPT_qq = (1 << 31),
379};
380
381struct globals {
382 double cur_time;
383
384 double rootdelay;
385
386 double reftime;
387
388 double rootdisp;
389
390 double last_script_run;
391 char *script_name;
392 llist_t *ntp_peers;
393#if ENABLE_FEATURE_NTPD_SERVER
394 int listen_fd;
395 char *if_name;
396# define G_listen_fd (G.listen_fd)
397#else
398# define G_listen_fd (-1)
399#endif
400 unsigned verbose;
401 unsigned peer_cnt;
402
403
404
405
406
407
408
409
410#if ENABLE_FEATURE_NTPD_SERVER
411 uint32_t refid;
412#endif
413 uint8_t ntp_status;
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440#define G_precision_exp -9
441
442
443
444
445
446
447#define G_precision_sec 0.002
448 uint8_t stratum;
449
450
451 uint8_t poll_exp;
452 int polladj_count;
453 int FREQHOLD_cnt;
454 long kernel_freq_drift;
455 peer_t *last_update_peer;
456 double last_update_offset;
457 double last_update_recv_time;
458 double discipline_jitter;
459
460
461
462 unsigned offset_to_jitter_ratio;
463
464
465#if !USING_KERNEL_PLL_LOOP
466 double discipline_freq_drift;
467
468 double discipline_wander;
469#endif
470};
471#define G (*ptr_to_globals)
472
473#define VERB1 if (MAX_VERBOSE && G.verbose)
474#define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2)
475#define VERB3 if (MAX_VERBOSE >= 3 && G.verbose >= 3)
476#define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4)
477#define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5)
478#define VERB6 if (MAX_VERBOSE >= 6 && G.verbose >= 6)
479
480
481static double LOG2D(int a)
482{
483 if (a < 0)
484 return 1.0 / (1UL << -a);
485 return 1UL << a;
486}
487static ALWAYS_INLINE double SQUARE(double x)
488{
489 return x * x;
490}
491static ALWAYS_INLINE double MAXD(double a, double b)
492{
493 if (a > b)
494 return a;
495 return b;
496}
497#if !USING_KERNEL_PLL_LOOP
498static ALWAYS_INLINE double MIND(double a, double b)
499{
500 if (a < b)
501 return a;
502 return b;
503}
504#endif
505static NOINLINE double my_SQRT(double X)
506{
507 union {
508 float f;
509 int32_t i;
510 } v;
511 double invsqrt;
512 double Xhalf = X * 0.5;
513
514
515 v.f = X;
516
517 v.i = 0x5f375a86 - (v.i >> 1);
518 invsqrt = v.f;
519
520
521
522
523
524
525
526 invsqrt = invsqrt * (1.5 - Xhalf * invsqrt * invsqrt);
527
528
529
530
531
532
533 return X * invsqrt;
534}
535static ALWAYS_INLINE double SQRT(double X)
536{
537
538 if (sizeof(float) != 4)
539 return sqrt(X);
540
541
542 return my_SQRT(X);
543}
544
545static double
546gettime1900d(void)
547{
548 struct timeval tv;
549 xgettimeofday(&tv);
550 G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970;
551 return G.cur_time;
552}
553
554static NOINLINE double
555lfp_to_d(l_fixedpt_t lfp)
556{
557 double ret;
558 lfp.int_partl = ntohl(lfp.int_partl);
559 lfp.fractionl = ntohl(lfp.fractionl);
560 ret = (double)lfp.int_partl + ((double)lfp.fractionl / (1ULL << 32));
561
562
563
564
565
566
567 if (lfp.int_partl < OFFSET_1900_1970)
568 ret += (double)(1ULL << 32);
569 return ret;
570}
571static NOINLINE double
572sfp_to_d(s_fixedpt_t sfp)
573{
574 double ret;
575 sfp.int_parts = ntohs(sfp.int_parts);
576 sfp.fractions = ntohs(sfp.fractions);
577 ret = (double)sfp.int_parts + ((double)sfp.fractions / (1 << 16));
578 return ret;
579}
580#if ENABLE_FEATURE_NTPD_SERVER
581static NOINLINE void
582d_to_lfp(l_fixedpt_t *lfp, double d)
583{
584 uint32_t intl;
585 uint32_t frac;
586 intl = (uint32_t)(time_t)d;
587 frac = (uint32_t)((d - (time_t)d) * 0xffffffff);
588 lfp->int_partl = htonl(intl);
589 lfp->fractionl = htonl(frac);
590}
591static NOINLINE void
592d_to_sfp(s_fixedpt_t *sfp, double d)
593{
594 uint16_t ints;
595 uint16_t frac;
596 ints = (uint16_t)d;
597 frac = (uint16_t)((d - ints) * 0xffff);
598 sfp->int_parts = htons(ints);
599 sfp->fractions = htons(frac);
600}
601#endif
602
603static double
604dispersion(const datapoint_t *dp)
605{
606 return dp->d_dispersion + FREQ_TOLERANCE * (G.cur_time - dp->d_recv_time);
607}
608
609static double
610root_distance(peer_t *p)
611{
612
613
614
615
616
617 return MAXD(MINDISP, p->lastpkt_rootdelay + p->lastpkt_delay) / 2
618 + p->lastpkt_rootdisp
619 + p->filter_dispersion
620 + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time)
621 + p->filter_jitter;
622}
623
624static void
625set_next(peer_t *p, unsigned t)
626{
627 p->next_action_time = G.cur_time + t;
628}
629
630
631
632
633static void
634filter_datapoints(peer_t *p)
635{
636 int i, idx;
637 double sum, wavg;
638 datapoint_t *fdp;
639
640
641
642
643
644
645 fdp = p->filter_datapoint;
646 idx = p->datapoint_idx;
647
648
649 p->filter_offset = fdp[idx].d_offset;
650
651
652
653
654
655
656
657
658 wavg = 0;
659 sum = 0;
660 for (i = 0; i < NUM_DATAPOINTS; i++) {
661 sum += dispersion(&fdp[idx]) / (2 << i);
662 wavg += fdp[idx].d_offset;
663 idx = (idx - 1) & (NUM_DATAPOINTS - 1);
664 }
665 wavg /= NUM_DATAPOINTS;
666 p->filter_dispersion = sum;
667
668
669
670
671
672
673
674
675
676
677
678
679 sum = 0;
680 for (i = 0; i < NUM_DATAPOINTS; i++) {
681 sum += SQUARE(wavg - fdp[i].d_offset);
682 }
683 sum = SQRT(sum / NUM_DATAPOINTS);
684 p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec;
685
686 VERB4 bb_error_msg("filter offset:%+f disp:%f jitter:%f",
687 p->filter_offset,
688 p->filter_dispersion,
689 p->filter_jitter);
690}
691
692static void
693reset_peer_stats(peer_t *p, double offset)
694{
695 int i;
696 bool small_ofs = fabs(offset) < STEP_THRESHOLD;
697
698
699
700
701
702
703
704
705
706
707
708
709
710 for (i = 0; i < NUM_DATAPOINTS; i++) {
711 if (small_ofs) {
712 p->filter_datapoint[i].d_recv_time += offset;
713 if (p->filter_datapoint[i].d_offset != 0) {
714 p->filter_datapoint[i].d_offset -= offset;
715
716
717
718
719 }
720 } else {
721 p->filter_datapoint[i].d_recv_time = G.cur_time;
722 p->filter_datapoint[i].d_offset = 0;
723
724 }
725 }
726 if (small_ofs) {
727 p->lastpkt_recv_time += offset;
728 } else {
729
730 p->lastpkt_recv_time = G.cur_time;
731 }
732 filter_datapoints(p);
733 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
734}
735
736#if ENABLE_FEATURE_NTPD_SERVER
737static uint32_t calculate_refid(len_and_sockaddr *lsa)
738{
739# if ENABLE_FEATURE_IPV6
740 if (lsa->u.sa.sa_family == AF_INET6) {
741 md5_ctx_t md5;
742 uint32_t res[MD5_OUTSIZE / 4];
743
744 md5_begin(&md5);
745 md5_hash(&md5, &lsa->u.sin6.sin6_addr, sizeof(lsa->u.sin6.sin6_addr));
746 md5_end(&md5, res);
747 return res[0];
748 }
749# endif
750 return lsa->u.sin.sin_addr.s_addr;
751}
752#endif
753
754static len_and_sockaddr*
755resolve_peer_hostname(peer_t *p)
756{
757 len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123);
758 if (lsa) {
759 free(p->p_lsa);
760 free(p->p_dotted);
761 p->p_lsa = lsa;
762 p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
763 VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0)
764 bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted);
765#if ENABLE_FEATURE_NTPD_SERVER
766 p->p_refid = calculate_refid(p->p_lsa);
767#endif
768 p->dns_errors = 0;
769 return lsa;
770 }
771 p->dns_errors = ((p->dns_errors << 1) | 1) & DNS_ERRORS_CAP;
772 return lsa;
773}
774
775#if !ENABLE_FEATURE_NTP_AUTH
776#define add_peers(s, key_entry) \
777 add_peers(s)
778#endif
779static void
780add_peers(const char *s, key_entry_t *key_entry)
781{
782 llist_t *item;
783 peer_t *p;
784
785 p = xzalloc(sizeof(*p) + strlen(s));
786 strcpy(p->p_hostname, s);
787 p->p_fd = -1;
788 p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
789 p->next_action_time = G.cur_time;
790 reset_peer_stats(p, STEP_THRESHOLD);
791
792
793
794
795
796 if (resolve_peer_hostname(p)) {
797 for (item = G.ntp_peers; item != NULL; item = item->link) {
798 peer_t *pp = (peer_t *) item->data;
799 if (pp->p_dotted && strcmp(p->p_dotted, pp->p_dotted) == 0) {
800 bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted);
801 free(p->p_lsa);
802 free(p->p_dotted);
803 free(p);
804 return;
805 }
806 }
807 }
808
809 IF_FEATURE_NTP_AUTH(p->key_entry = key_entry;)
810 llist_add_to(&G.ntp_peers, p);
811 G.peer_cnt++;
812}
813
814static int
815do_sendto(int fd,
816 const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen,
817 msg_t *msg, ssize_t len)
818{
819 ssize_t ret;
820
821 errno = 0;
822 if (!from) {
823 ret = sendto(fd, msg, len, MSG_DONTWAIT, to, addrlen);
824 } else {
825 ret = send_to_from(fd, msg, len, MSG_DONTWAIT, to, from, addrlen);
826 }
827 if (ret != len) {
828 bb_simple_perror_msg("send failed");
829 return -1;
830 }
831 return 0;
832}
833
834#if ENABLE_FEATURE_NTP_AUTH
835static void
836hash(key_entry_t *key_entry, const msg_t *msg, uint8_t *output)
837{
838 union {
839 md5_ctx_t m;
840 sha1_ctx_t s;
841 } ctx;
842 unsigned hash_size = sizeof(*msg) - sizeof(msg->m_keyid) - sizeof(msg->m_digest);
843
844 switch (key_entry->type) {
845 case HASH_MD5:
846 md5_begin(&ctx.m);
847 md5_hash(&ctx.m, key_entry->key, key_entry->key_length);
848 md5_hash(&ctx.m, msg, hash_size);
849 md5_end(&ctx.m, output);
850 break;
851 default:
852 sha1_begin(&ctx.s);
853 sha1_hash(&ctx.s, key_entry->key, key_entry->key_length);
854 sha1_hash(&ctx.s, msg, hash_size);
855 sha1_end(&ctx.s, output);
856 break;
857 }
858}
859
860static void
861hash_peer(peer_t *p)
862{
863 p->p_xmt_msg.m_keyid = htonl(p->key_entry->id);
864 hash(p->key_entry, &p->p_xmt_msg, p->p_xmt_msg.m_digest);
865}
866
867static int
868hashes_differ(peer_t *p, const msg_t *msg)
869{
870 uint8_t digest[NTP_SHA1_DIGESTSIZE];
871 hash(p->key_entry, msg, digest);
872 return memcmp(digest, msg->m_digest, p->key_entry->msg_size - NTP_MSGSIZE_NOAUTH - KEYID_SIZE);
873}
874#endif
875
876static void
877send_query_to_peer(peer_t *p)
878{
879 if (!p->p_lsa)
880 return;
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898#define PROBE_LOCAL_ADDR
899
900 if (p->p_fd == -1) {
901 int fd, family;
902 len_and_sockaddr *local_lsa;
903
904 family = p->p_lsa->u.sa.sa_family;
905 p->p_fd = fd = xsocket_type(&local_lsa, family, SOCK_DGRAM);
906
907
908
909
910
911 PROBE_LOCAL_ADDR
912 xbind(fd, &local_lsa->u.sa, local_lsa->len);
913 PROBE_LOCAL_ADDR
914#if ENABLE_FEATURE_IPV6
915 if (family == AF_INET)
916#endif
917 setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_DSCP_AF21);
918 free(local_lsa);
919 }
920
921
922
923
924
925 VERB1 bb_error_msg("sending query to %s", p->p_dotted);
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940 p->p_xmt_msg.m_xmttime.int_partl = rand();
941 p->p_xmt_msg.m_xmttime.fractionl = rand();
942 p->p_xmttime = gettime1900d();
943
944
945
946
947
948
949
950 p->reachable_bits <<= 1;
951
952#if ENABLE_FEATURE_NTP_AUTH
953 if (p->key_entry)
954 hash_peer(p);
955 if (do_sendto(p->p_fd, NULL, &p->p_lsa->u.sa, p->p_lsa->len,
956 &p->p_xmt_msg, !p->key_entry ? NTP_MSGSIZE_NOAUTH : p->key_entry->msg_size) == -1
957 )
958#else
959 if (do_sendto(p->p_fd, NULL, &p->p_lsa->u.sa, p->p_lsa->len,
960 &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1
961 )
962#endif
963 {
964 close(p->p_fd);
965 p->p_fd = -1;
966
967
968
969
970
971 set_next(p, RETRY_INTERVAL);
972 return;
973 }
974
975 set_next(p, RESPONSE_INTERVAL);
976}
977
978
979
980
981
982
983
984
985static void run_script(const char *action, double offset)
986{
987 char *argv[3];
988 char *env1, *env2, *env3, *env4;
989
990 G.last_script_run = G.cur_time;
991
992 if (!G.script_name)
993 return;
994
995 argv[0] = (char*) G.script_name;
996 argv[1] = (char*) action;
997 argv[2] = NULL;
998
999 VERB1 bb_error_msg("executing '%s %s'", G.script_name, action);
1000
1001 env1 = xasprintf("%s=%u", "stratum", G.stratum);
1002 putenv(env1);
1003 env2 = xasprintf("%s=%ld", "freq_drift_ppm", G.kernel_freq_drift);
1004 putenv(env2);
1005 env3 = xasprintf("%s=%u", "poll_interval", 1 << G.poll_exp);
1006 putenv(env3);
1007 env4 = xasprintf("%s=%f", "offset", offset);
1008 putenv(env4);
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018 spawn(argv);
1019
1020 unsetenv("stratum");
1021 unsetenv("freq_drift_ppm");
1022 unsetenv("poll_interval");
1023 unsetenv("offset");
1024 free(env1);
1025 free(env2);
1026 free(env3);
1027 free(env4);
1028}
1029
1030static NOINLINE void
1031step_time(double offset)
1032{
1033 llist_t *item;
1034 double dtime;
1035 struct timeval tvc, tvn;
1036 char buf[sizeof("yyyy-mm-dd hh:mm:ss") + 4];
1037 time_t tval;
1038
1039 xgettimeofday(&tvc);
1040
1041
1042
1043
1044
1045
1046
1047
1048 dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset;
1049 tvn.tv_sec = (time_t)dtime;
1050 tvn.tv_usec = (dtime - tvn.tv_sec) * 1000000;
1051 xsettimeofday(&tvn);
1052
1053 VERB2 {
1054 tval = tvc.tv_sec;
1055 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
1056 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec);
1057 }
1058 tval = tvn.tv_sec;
1059 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
1060 bb_info_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset);
1061
1062
1063
1064
1065
1066 G.cur_time += offset;
1067 G.last_update_recv_time += offset;
1068 G.last_script_run += offset;
1069
1070
1071 for (item = G.ntp_peers; item != NULL; item = item->link) {
1072 peer_t *pp = (peer_t *) item->data;
1073 reset_peer_stats(pp, offset);
1074
1075
1076 pp->next_action_time += offset;
1077 if (pp->p_fd >= 0) {
1078
1079
1080
1081
1082 close(pp->p_fd);
1083 pp->p_fd = -1;
1084 set_next(pp, RETRY_INTERVAL);
1085 }
1086 }
1087}
1088
1089static void clamp_pollexp_and_set_MAXSTRAT(void)
1090{
1091 if (G.poll_exp < MINPOLL)
1092 G.poll_exp = MINPOLL;
1093 if (G.poll_exp > BIGPOLL)
1094 G.poll_exp = BIGPOLL;
1095 G.polladj_count = 0;
1096 G.stratum = MAXSTRAT;
1097}
1098
1099
1100
1101
1102
1103typedef struct {
1104 peer_t *p;
1105 int type;
1106 double edge;
1107 double opt_rd;
1108} point_t;
1109static int
1110compare_point_edge(const void *aa, const void *bb)
1111{
1112 const point_t *a = aa;
1113 const point_t *b = bb;
1114 if (a->edge < b->edge) {
1115 return -1;
1116 }
1117 return (a->edge > b->edge);
1118}
1119typedef struct {
1120 peer_t *p;
1121 double metric;
1122} survivor_t;
1123static int
1124compare_survivor_metric(const void *aa, const void *bb)
1125{
1126 const survivor_t *a = aa;
1127 const survivor_t *b = bb;
1128 if (a->metric < b->metric) {
1129 return -1;
1130 }
1131 return (a->metric > b->metric);
1132}
1133static int
1134fit(peer_t *p, double rd)
1135{
1136 if ((p->reachable_bits & (p->reachable_bits-1)) == 0) {
1137
1138 VERB4 bb_error_msg("peer %s unfit for selection: "
1139 "unreachable", p->p_dotted);
1140 return 0;
1141 }
1142#if 0
1143 if ((p->lastpkt_status & LI_ALARM) == LI_ALARM
1144 || p->lastpkt_stratum >= MAXSTRAT
1145 ) {
1146 VERB4 bb_error_msg("peer %s unfit for selection: "
1147 "bad status/stratum", p->p_dotted);
1148 return 0;
1149 }
1150#endif
1151
1152 if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) {
1153 VERB3 bb_error_msg("peer %s unfit for selection: "
1154 "root distance %f too high, jitter:%f",
1155 p->p_dotted, rd, p->filter_jitter
1156 );
1157 return 0;
1158 }
1159
1160
1161
1162
1163 return 1;
1164}
1165static NOINLINE peer_t*
1166select_and_cluster(void)
1167{
1168 peer_t *p;
1169 llist_t *item;
1170 int i, j;
1171 int size = 3 * G.peer_cnt;
1172
1173 point_t point[size];
1174 unsigned num_points, num_candidates;
1175 double low, high;
1176 unsigned num_falsetickers;
1177
1178 survivor_t survivor[size];
1179 unsigned num_survivors;
1180
1181
1182
1183 num_points = 0;
1184 item = G.ntp_peers;
1185 while (item != NULL) {
1186 double rd, offset;
1187
1188 p = (peer_t *) item->data;
1189 rd = root_distance(p);
1190 offset = p->filter_offset;
1191 if (!fit(p, rd)) {
1192 item = item->link;
1193 continue;
1194 }
1195
1196 VERB5 bb_error_msg("interval: [%f %f %f] %s",
1197 offset - rd,
1198 offset,
1199 offset + rd,
1200 p->p_dotted
1201 );
1202 point[num_points].p = p;
1203 point[num_points].type = -1;
1204 point[num_points].edge = offset - rd;
1205 point[num_points].opt_rd = rd;
1206 num_points++;
1207 point[num_points].p = p;
1208 point[num_points].type = 0;
1209 point[num_points].edge = offset;
1210 point[num_points].opt_rd = rd;
1211 num_points++;
1212 point[num_points].p = p;
1213 point[num_points].type = 1;
1214 point[num_points].edge = offset + rd;
1215 point[num_points].opt_rd = rd;
1216 num_points++;
1217 item = item->link;
1218 }
1219 num_candidates = num_points / 3;
1220 if (num_candidates == 0) {
1221 VERB3 bb_error_msg("no valid datapoints%s", ", no peer selected");
1222 return NULL;
1223 }
1224
1225 qsort(point, num_points, sizeof(point[0]), compare_point_edge);
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 num_falsetickers = 0;
1238 while (1) {
1239 int c;
1240 unsigned num_midpoints = 0;
1241
1242 low = 1 << 9;
1243 high = - (1 << 9);
1244 c = 0;
1245 for (i = 0; i < num_points; i++) {
1246
1247
1248
1249
1250
1251 c -= point[i].type;
1252 if (c >= num_candidates - num_falsetickers) {
1253
1254 low = point[i].edge;
1255 break;
1256 }
1257 if (point[i].type == 0)
1258 num_midpoints++;
1259 }
1260 c = 0;
1261 for (i = num_points-1; i >= 0; i--) {
1262 c += point[i].type;
1263 if (c >= num_candidates - num_falsetickers) {
1264 high = point[i].edge;
1265 break;
1266 }
1267 if (point[i].type == 0)
1268 num_midpoints++;
1269 }
1270
1271
1272
1273
1274
1275 if (num_midpoints <= num_falsetickers && low < high)
1276 break;
1277 num_falsetickers++;
1278 if (num_falsetickers * 2 >= num_candidates) {
1279 VERB3 bb_error_msg("falsetickers:%d, candidates:%d%s",
1280 num_falsetickers, num_candidates,
1281 ", no peer selected");
1282 return NULL;
1283 }
1284 }
1285 VERB4 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d",
1286 low, high, num_candidates, num_falsetickers);
1287
1288
1289
1290
1291
1292
1293
1294
1295 num_survivors = 0;
1296 for (i = 0; i < num_points; i++) {
1297 if (point[i].edge < low || point[i].edge > high)
1298 continue;
1299 p = point[i].p;
1300 survivor[num_survivors].p = p;
1301
1302 survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd;
1303 VERB5 bb_error_msg("survivor[%d] metric:%f peer:%s",
1304 num_survivors, survivor[num_survivors].metric, p->p_dotted);
1305 num_survivors++;
1306 }
1307
1308
1309
1310
1311
1312 if (num_survivors < MIN_SELECTED) {
1313 VERB3 bb_error_msg("survivors:%d%s",
1314 num_survivors,
1315 ", no peer selected");
1316 return NULL;
1317 }
1318
1319
1320
1321 qsort(survivor, num_survivors, sizeof(survivor[0]), compare_survivor_metric);
1322
1323
1324
1325
1326
1327
1328
1329 while (1) {
1330 unsigned max_idx = max_idx;
1331 double max_selection_jitter = max_selection_jitter;
1332 double min_jitter = min_jitter;
1333
1334 if (num_survivors <= MIN_CLUSTERED) {
1335 VERB4 bb_error_msg("num_survivors %d <= %d, not discarding more",
1336 num_survivors, MIN_CLUSTERED);
1337 break;
1338 }
1339
1340
1341
1342
1343
1344
1345 for (i = 0; i < num_survivors; i++) {
1346 double selection_jitter_sq;
1347
1348 p = survivor[i].p;
1349 if (i == 0 || p->filter_jitter < min_jitter)
1350 min_jitter = p->filter_jitter;
1351
1352 selection_jitter_sq = 0;
1353 for (j = 0; j < num_survivors; j++) {
1354 peer_t *q = survivor[j].p;
1355 selection_jitter_sq += SQUARE(p->filter_offset - q->filter_offset);
1356 }
1357 if (i == 0 || selection_jitter_sq > max_selection_jitter) {
1358 max_selection_jitter = selection_jitter_sq;
1359 max_idx = i;
1360 }
1361 VERB6 bb_error_msg("survivor %d selection_jitter^2:%f",
1362 i, selection_jitter_sq);
1363 }
1364 max_selection_jitter = SQRT(max_selection_jitter / num_survivors);
1365 VERB5 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f",
1366 max_idx, max_selection_jitter, min_jitter);
1367
1368
1369
1370
1371
1372
1373 if (max_selection_jitter < min_jitter) {
1374 VERB4 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more",
1375 max_selection_jitter, min_jitter, num_survivors);
1376 break;
1377 }
1378
1379
1380
1381
1382 VERB6 bb_error_msg("dropping survivor %d", max_idx);
1383 num_survivors--;
1384 while (max_idx < num_survivors) {
1385 survivor[max_idx] = survivor[max_idx + 1];
1386 max_idx++;
1387 }
1388 }
1389
1390 if (0) {
1391
1392
1393
1394
1395
1396
1397
1398
1399 double x, y, z, w;
1400 y = z = w = 0;
1401 for (i = 0; i < num_survivors; i++) {
1402 p = survivor[i].p;
1403 x = root_distance(p);
1404 y += 1 / x;
1405 z += p->filter_offset / x;
1406 w += SQUARE(p->filter_offset - survivor[0].p->filter_offset) / x;
1407 }
1408
1409
1410 }
1411
1412
1413
1414
1415
1416
1417 p = survivor[0].p;
1418 if (G.last_update_peer
1419 && G.last_update_peer->lastpkt_stratum <= p->lastpkt_stratum
1420 ) {
1421
1422 for (i = 1; i < num_survivors; i++) {
1423 if (G.last_update_peer == survivor[i].p) {
1424 VERB5 bb_simple_error_msg("keeping old synced peer");
1425 p = G.last_update_peer;
1426 goto keep_old;
1427 }
1428 }
1429 }
1430 G.last_update_peer = p;
1431 keep_old:
1432 VERB4 bb_error_msg("selected peer %s filter_offset:%+f age:%f",
1433 p->p_dotted,
1434 p->filter_offset,
1435 G.cur_time - p->lastpkt_recv_time
1436 );
1437 return p;
1438}
1439
1440
1441
1442
1443
1444static void
1445set_new_values(double offset, double recv_time)
1446{
1447
1448
1449
1450
1451 VERB4 bb_error_msg("last update offset=%f recv_time=%f",
1452 offset, recv_time);
1453 G.last_update_offset = offset;
1454 G.last_update_recv_time = recv_time;
1455}
1456
1457static NOINLINE int
1458update_local_clock(peer_t *p)
1459{
1460 int rc;
1461 struct timex tmx;
1462
1463 double offset = p->filter_offset;
1464 double recv_time = p->lastpkt_recv_time;
1465 double abs_offset;
1466#if !USING_KERNEL_PLL_LOOP
1467 double freq_drift;
1468 double since_last_update;
1469#endif
1470 double etemp, dtemp;
1471
1472 abs_offset = fabs(offset);
1473
1474#if 0
1475
1476
1477
1478 if (abs_offset > PANIC_THRESHOLD) {
1479 bb_error_msg_and_die("offset %f far too big, exiting", offset);
1480 }
1481#endif
1482
1483
1484
1485
1486
1487 if (recv_time <= G.last_update_recv_time) {
1488 VERB3 bb_error_msg("update from %s: same or older datapoint, not using it",
1489 p->p_dotted);
1490 return 0;
1491 }
1492
1493
1494
1495
1496
1497#if !USING_KERNEL_PLL_LOOP
1498 since_last_update = recv_time - G.reftime;
1499 freq_drift = 0;
1500#endif
1501
1502
1503
1504
1505 if (abs_offset > STEP_THRESHOLD) {
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527 VERB4 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset);
1528 step_time(offset);
1529 if (option_mask32 & OPT_q) {
1530
1531 exit(0);
1532 }
1533
1534 clamp_pollexp_and_set_MAXSTRAT();
1535
1536 run_script("step", offset);
1537
1538 recv_time += offset;
1539
1540 abs_offset = offset = 0;
1541 set_new_values(offset, recv_time);
1542 } else {
1543
1544 if (option_mask32 & OPT_q) {
1545
1546
1547
1548 exit(0);
1549 }
1550
1551
1552
1553
1554 G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter;
1555
1556
1557
1558
1559 etemp = SQUARE(G.discipline_jitter);
1560 dtemp = SQUARE(offset - G.last_update_offset);
1561 G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG);
1562 if (G.discipline_jitter < G_precision_sec)
1563 G.discipline_jitter = G_precision_sec;
1564
1565#if !USING_KERNEL_PLL_LOOP
1566
1567
1568
1569
1570
1571
1572
1573
1574 if ((1 << G.poll_exp) > ALLAN / 2) {
1575 etemp = FLL - G.poll_exp;
1576 if (etemp < AVG)
1577 etemp = AVG;
1578 freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp);
1579 }
1580
1581
1582
1583
1584
1585 etemp = MIND(since_last_update, (1 << G.poll_exp));
1586 dtemp = (4 * PLL) << G.poll_exp;
1587 freq_drift += offset * etemp / SQUARE(dtemp);
1588#endif
1589 set_new_values(offset, recv_time);
1590 if (G.stratum != p->lastpkt_stratum + 1) {
1591 G.stratum = p->lastpkt_stratum + 1;
1592 run_script("stratum", offset);
1593 }
1594 }
1595
1596 G.reftime = G.cur_time;
1597 G.ntp_status = p->lastpkt_status;
1598#if ENABLE_FEATURE_NTPD_SERVER
1599
1600 G.refid = p->p_refid;
1601#endif
1602 G.rootdelay = p->lastpkt_rootdelay + p->lastpkt_delay;
1603 dtemp = p->filter_jitter;
1604 dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP);
1605 G.rootdisp = p->lastpkt_rootdisp + dtemp;
1606 VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted);
1607
1608
1609
1610
1611#if !USING_KERNEL_PLL_LOOP
1612
1613
1614
1615
1616
1617
1618 dtemp = G.discipline_freq_drift + freq_drift;
1619 G.discipline_freq_drift = MAXD(MIND(MAXDRIFT, dtemp), -MAXDRIFT);
1620 etemp = SQUARE(G.discipline_wander);
1621 dtemp = SQUARE(dtemp);
1622 G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG);
1623
1624 VERB4 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",
1625 G.discipline_freq_drift,
1626 (long)(G.discipline_freq_drift * 65536e6),
1627 freq_drift,
1628 G.discipline_wander);
1629#endif
1630 VERB4 {
1631 memset(&tmx, 0, sizeof(tmx));
1632 if (adjtimex(&tmx) < 0)
1633 bb_simple_perror_msg_and_die("adjtimex");
1634 bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld",
1635 (long)tmx.freq, (long)tmx.offset, tmx.status, (long)tmx.constant);
1636 }
1637
1638 memset(&tmx, 0, sizeof(tmx));
1639#if 0
1640
1641
1642
1643
1644 tmx.modes = ADJ_FREQUENCY | ADJ_OFFSET;
1645
1646 tmx.freq = G.discipline_freq_drift * 65536e6;
1647#endif
1648 tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;
1649
1650 tmx.offset = (long)(offset * 1000000);
1651 if (SLEW_THRESHOLD < STEP_THRESHOLD) {
1652 if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) {
1653 tmx.offset = (long)(SLEW_THRESHOLD * 1000000);
1654 }
1655 if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) {
1656 tmx.offset = -(long)(SLEW_THRESHOLD * 1000000);
1657 }
1658 }
1659
1660 tmx.status = STA_PLL;
1661 if (G.FREQHOLD_cnt != 0) {
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674 if (G.FREQHOLD_cnt < 0) {
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714 unsigned off_032 = abs((int)(tmx.offset >> 15));
1715 G.FREQHOLD_cnt = 1 + MIN_FREQHOLD + off_032;
1716 }
1717 G.FREQHOLD_cnt--;
1718 tmx.status |= STA_FREQHOLD;
1719 }
1720 if (G.ntp_status & LI_PLUSSEC)
1721 tmx.status |= STA_INS;
1722 if (G.ntp_status & LI_MINUSSEC)
1723 tmx.status |= STA_DEL;
1724
1725 tmx.constant = (int)G.poll_exp - 4;
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736 if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE)
1737 tmx.constant--;
1738 if (tmx.constant < 0)
1739 tmx.constant = 0;
1740
1741
1742
1743 rc = adjtimex(&tmx);
1744 if (rc < 0)
1745 bb_simple_perror_msg_and_die("adjtimex");
1746
1747
1748
1749 VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x",
1750 rc, (long)tmx.freq, (long)tmx.offset, tmx.status);
1751 G.kernel_freq_drift = tmx.freq / 65536;
1752 VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d",
1753 p->p_dotted,
1754 offset,
1755 p->p_raw_delay,
1756 G.discipline_jitter,
1757 (double)tmx.freq / 65536,
1758 (int)tmx.constant
1759 );
1760
1761 return 1;
1762}
1763
1764
1765
1766
1767
1768static unsigned
1769poll_interval(int upper_bound)
1770{
1771 unsigned interval, r, mask;
1772 interval = 1 << G.poll_exp;
1773 if (interval > upper_bound)
1774 interval = upper_bound;
1775 mask = ((interval-1) >> 4) | 1;
1776 r = rand();
1777 interval += r & mask;
1778 VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d)", interval, G.poll_exp);
1779 return interval;
1780}
1781static void
1782adjust_poll(int count)
1783{
1784 G.polladj_count += count;
1785 if (G.polladj_count > POLLADJ_LIMIT) {
1786 G.polladj_count = 0;
1787 if (G.poll_exp < MAXPOLL) {
1788 G.poll_exp++;
1789 VERB4 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d",
1790 G.discipline_jitter, G.poll_exp);
1791 }
1792 } else if (G.polladj_count < -POLLADJ_LIMIT || (count < 0 && G.poll_exp > BIGPOLL)) {
1793 G.polladj_count = 0;
1794 if (G.poll_exp > MINPOLL) {
1795 llist_t *item;
1796
1797 G.poll_exp--;
1798
1799
1800
1801
1802
1803
1804 for (item = G.ntp_peers; item != NULL; item = item->link) {
1805 peer_t *pp = (peer_t *) item->data;
1806 if (pp->p_fd < 0)
1807 pp->next_action_time -= (1 << G.poll_exp);
1808 }
1809 VERB4 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d",
1810 G.discipline_jitter, G.poll_exp);
1811 }
1812 } else {
1813 VERB4 bb_error_msg("polladj: count:%d", G.polladj_count);
1814 }
1815}
1816static NOINLINE void
1817recv_and_process_peer_pkt(peer_t *p)
1818{
1819 int rc;
1820 ssize_t size;
1821 msg_t msg;
1822 double T1, T2, T3, T4;
1823 double offset;
1824 double prev_delay, delay;
1825 unsigned interval;
1826 datapoint_t *datapoint;
1827 peer_t *q;
1828
1829 offset = 0;
1830
1831
1832
1833
1834
1835
1836
1837 if (p->p_fd < 0)
1838 return;
1839
1840
1841
1842
1843
1844 recv_again:
1845 size = recv(p->p_fd, &msg, sizeof(msg), MSG_DONTWAIT);
1846 if (size < 0) {
1847 if (errno == EINTR)
1848
1849 goto recv_again;
1850 if (errno == EAGAIN)
1851
1852
1853
1854
1855 return;
1856
1857
1858
1859
1860 bb_perror_msg_and_die("recv(%s) error", p->p_dotted);
1861 }
1862
1863#if ENABLE_FEATURE_NTP_AUTH
1864 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) {
1865 bb_error_msg("malformed packet received from %s: size %u", p->p_dotted, (int)size);
1866 return;
1867 }
1868 if (p->key_entry && hashes_differ(p, &msg)) {
1869 bb_error_msg("invalid cryptographic hash received from %s", p->p_dotted);
1870 return;
1871 }
1872#else
1873 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) {
1874 bb_error_msg("malformed packet received from %s: size %u", p->p_dotted, (int)size);
1875 return;
1876 }
1877#endif
1878
1879 if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl
1880 || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl
1881 ) {
1882
1883 return;
1884 }
1885
1886
1887
1888
1889
1890 close(p->p_fd);
1891 p->p_fd = -1;
1892
1893 if ((msg.m_status & LI_ALARM) == LI_ALARM
1894 || msg.m_stratum == 0
1895 || msg.m_stratum > NTP_MAXSTRATUM
1896 ) {
1897 bb_error_msg("reply from %s: peer is unsynced", p->p_dotted);
1898
1899
1900
1901
1902
1903
1904 if (G.poll_exp < BIGPOLL)
1905 goto increase_interval;
1906 goto pick_normal_interval;
1907 }
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927 T1 = p->p_xmttime;
1928 T2 = lfp_to_d(msg.m_rectime);
1929 T3 = lfp_to_d(msg.m_xmttime);
1930 T4 = G.cur_time;
1931 delay = (T4 - T1) - (T3 - T2);
1932
1933
1934
1935
1936
1937 prev_delay = p->p_raw_delay;
1938 p->p_raw_delay = (delay < 0 ? 0.0 : delay);
1939 if (p->reachable_bits
1940 && delay > prev_delay * BAD_DELAY_GROWTH
1941 && delay > 1.0 / (8 * 1024)
1942 ) {
1943 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay);
1944 goto pick_normal_interval;
1945 }
1946
1947
1948
1949
1950
1951
1952
1953 if (delay < G_precision_sec)
1954 delay = G_precision_sec;
1955 p->lastpkt_delay = delay;
1956 p->lastpkt_recv_time = T4;
1957 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);
1958 p->lastpkt_status = msg.m_status;
1959 p->lastpkt_stratum = msg.m_stratum;
1960 p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);
1961 p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);
1962 p->lastpkt_refid = msg.m_refid;
1963
1964 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;
1965 datapoint = &p->filter_datapoint[p->datapoint_idx];
1966 datapoint->d_recv_time = T4;
1967 datapoint->d_offset = offset = ((T2 - T1) + (T3 - T4)) / 2;
1968 datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec;
1969 if (!p->reachable_bits) {
1970
1971 int i;
1972 for (i = 0; i < NUM_DATAPOINTS; i++) {
1973 p->filter_datapoint[i].d_offset = offset;
1974 }
1975 }
1976
1977 p->reachable_bits |= 1;
1978 if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) {
1979 bb_info_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x",
1980 p->p_dotted,
1981 offset,
1982 p->p_raw_delay,
1983 p->lastpkt_status,
1984 p->lastpkt_stratum,
1985 p->lastpkt_refid,
1986 p->lastpkt_rootdelay,
1987 p->reachable_bits
1988
1989
1990
1991 );
1992 }
1993
1994
1995 filter_datapoints(p);
1996 q = select_and_cluster();
1997 rc = 0;
1998 if (q) {
1999 if (!(option_mask32 & OPT_w)) {
2000 rc = update_local_clock(q);
2001#if 0
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013 if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) {
2014 VERB4 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset);
2015 adjust_poll(-POLLADJ_LIMIT * 3);
2016 rc = 0;
2017 }
2018#endif
2019 }
2020 } else {
2021
2022
2023
2024 if (G.poll_exp < BIGPOLL)
2025 goto increase_interval;
2026 }
2027
2028 if (rc != 0) {
2029
2030
2031
2032
2033
2034
2035 if (rc > 0 && G.offset_to_jitter_ratio <= POLLADJ_GATE) {
2036
2037
2038 increase_interval:
2039 adjust_poll(MINPOLL);
2040 } else {
2041 VERB3 if (rc > 0)
2042 bb_error_msg("want smaller interval: offset/jitter = %u",
2043 G.offset_to_jitter_ratio);
2044 adjust_poll(-G.poll_exp * 2);
2045 }
2046 }
2047
2048
2049 pick_normal_interval:
2050 interval = poll_interval(INT_MAX);
2051 if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) {
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063 interval = BIGOFF_INTERVAL;
2064 }
2065
2066 set_next(p, interval);
2067}
2068
2069#if ENABLE_FEATURE_NTPD_SERVER
2070static NOINLINE void
2071recv_and_process_client_pkt(void )
2072{
2073 ssize_t size;
2074
2075 len_and_sockaddr *to;
2076 struct sockaddr *from;
2077 msg_t msg;
2078 uint8_t query_status;
2079 l_fixedpt_t query_xmttime;
2080
2081 to = get_sock_lsa(G_listen_fd);
2082 from = xzalloc(to->len);
2083
2084 size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);
2085
2086
2087
2088
2089
2090
2091
2092# if ENABLE_FEATURE_NTP_AUTH
2093 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH)
2094# else
2095 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH)
2096# endif
2097 {
2098 char *addr;
2099 if (size < 0) {
2100 if (errno == EAGAIN)
2101 goto bail;
2102 bb_simple_perror_msg_and_die("recv");
2103 }
2104 addr = xmalloc_sockaddr2dotted_noport(from);
2105 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size);
2106 free(addr);
2107 goto bail;
2108 }
2109
2110
2111 if ((msg.m_status & MODE_MASK) != MODE_CLIENT
2112 && (msg.m_status & MODE_MASK) != MODE_SYM_ACT
2113 ) {
2114 goto bail;
2115 }
2116
2117 query_status = msg.m_status;
2118 query_xmttime = msg.m_xmttime;
2119
2120
2121 memset(&msg, 0, sizeof(msg));
2122 msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM;
2123 msg.m_status |= (query_status & VERSION_MASK);
2124 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ?
2125 MODE_SERVER : MODE_SYM_PAS;
2126 msg.m_stratum = G.stratum;
2127 msg.m_ppoll = G.poll_exp;
2128 msg.m_precision_exp = G_precision_exp;
2129
2130 d_to_lfp(&msg.m_rectime, G.cur_time);
2131 d_to_lfp(&msg.m_xmttime, gettime1900d());
2132 if (G.peer_cnt == 0) {
2133
2134 G.reftime = G.cur_time;
2135 }
2136 d_to_lfp(&msg.m_reftime, G.reftime);
2137 msg.m_orgtime = query_xmttime;
2138 d_to_sfp(&msg.m_rootdelay, G.rootdelay);
2139
2140 d_to_sfp(&msg.m_rootdisp, G.rootdisp);
2141
2142 msg.m_refid = G.refid;
2143
2144
2145
2146 do_sendto(G_listen_fd,
2147 &to->u.sa, from, to->len,
2148 &msg, size);
2149 VERB3 {
2150 char *addr;
2151 addr = xmalloc_sockaddr2dotted_noport(from);
2152 bb_error_msg("responded to query from %s", addr);
2153 free(addr);
2154 }
2155
2156 bail:
2157 free(to);
2158 free(from);
2159}
2160#endif
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246#if ENABLE_FEATURE_NTP_AUTH
2247static key_entry_t *
2248find_key_entry(llist_t *key_entries, unsigned id)
2249{
2250 while (key_entries) {
2251 key_entry_t *cur = (key_entry_t*) key_entries->data;
2252 if (cur->id == id)
2253 return cur;
2254 key_entries = key_entries->link;
2255 }
2256 bb_error_msg_and_die("key %u is not defined", id);
2257}
2258#endif
2259
2260
2261
2262
2263static NOINLINE void ntp_init(char **argv)
2264{
2265 unsigned opts;
2266 llist_t *peers;
2267#if ENABLE_FEATURE_NTP_AUTH
2268 llist_t *key_entries;
2269 char *key_file_path;
2270#endif
2271
2272 srand(getpid());
2273
2274
2275 G.discipline_jitter = G_precision_sec;
2276 G.stratum = MAXSTRAT;
2277 if (BURSTPOLL != 0)
2278 G.poll_exp = BURSTPOLL;
2279 G.last_script_run = G.reftime = G.last_update_recv_time = gettime1900d();
2280 G.FREQHOLD_cnt = -1;
2281
2282
2283 peers = NULL;
2284 IF_FEATURE_NTP_AUTH(key_entries = NULL;)
2285 opts = getopt32(argv, "^"
2286 "nqNx"
2287 IF_FEATURE_NTP_AUTH("k:")
2288 "wp:*S:"IF_FEATURE_NTPD_SERVER("l")
2289 IF_FEATURE_NTPD_SERVER("I:")
2290 "d"
2291 "46aAbgL"
2292 "\0"
2293 "=0"
2294 ":dd:wn"
2295 IF_FEATURE_NTPD_SERVER(":Il")
2296 IF_FEATURE_NTP_AUTH(, &key_file_path)
2297 , &peers, &G.script_name
2298 IF_FEATURE_NTPD_SERVER(, &G.if_name)
2299 , &G.verbose
2300 );
2301
2302
2303
2304
2305#if ENABLE_FEATURE_NTPD_SERVER
2306 G_listen_fd = -1;
2307 if (opts & OPT_l) {
2308 G_listen_fd = create_and_bind_dgram_or_die(NULL, 123);
2309 if (G.if_name) {
2310 if (setsockopt_bindtodevice(G_listen_fd, G.if_name))
2311 xfunc_die();
2312 }
2313 socket_want_pktinfo(G_listen_fd);
2314 setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_DSCP_AF21);
2315 }
2316#endif
2317
2318 if (opts & OPT_N)
2319 setpriority(PRIO_PROCESS, 0, -15);
2320
2321 if (!(opts & OPT_n)) {
2322 bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);
2323 logmode = LOGMODE_NONE;
2324 }
2325
2326#if ENABLE_FEATURE_NTP_AUTH
2327 if (opts & OPT_k) {
2328 char *tokens[4];
2329 parser_t *parser;
2330
2331 parser = config_open(key_file_path);
2332 while (config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL | PARSE_MIN_DIE) == 3) {
2333 key_entry_t *key_entry;
2334 char buffer[40];
2335 smalluint hash_type;
2336 smalluint msg_size;
2337 smalluint key_length;
2338 char *key;
2339
2340 if ((tokens[1][0] | 0x20) == 'm')
2341
2342 hash_type = HASH_MD5;
2343 else
2344 if (strncasecmp(tokens[1], "sha", 3) == 0)
2345
2346 hash_type = HASH_SHA1;
2347 else
2348 bb_simple_error_msg_and_die("only MD5 and SHA1 keys supported");
2349
2350
2351
2352
2353
2354
2355
2356
2357 key_length = strnlen(tokens[2], sizeof(buffer)+1);
2358 if (key_length >= sizeof(buffer)+1) {
2359 err:
2360 bb_error_msg_and_die("malformed key at line %u", parser->lineno);
2361 }
2362 if (hash_type == HASH_MD5) {
2363 key = tokens[2];
2364 msg_size = NTP_MSGSIZE_MD5_AUTH;
2365 } else
2366 if (!(key_length & 1)) {
2367 key_length >>= 1;
2368 if (!hex2bin(buffer, tokens[2], key_length))
2369 goto err;
2370 key = buffer;
2371 msg_size = NTP_MSGSIZE_SHA1_AUTH;
2372 } else {
2373 goto err;
2374 }
2375 key_entry = xzalloc(sizeof(*key_entry) + key_length);
2376 key_entry->type = hash_type;
2377 key_entry->msg_size = msg_size;
2378 key_entry->key_length = key_length;
2379 memcpy(key_entry->key, key, key_length);
2380 key_entry->id = xatou_range(tokens[0], 1, MAX_KEY_NUMBER);
2381 llist_add_to(&key_entries, key_entry);
2382 }
2383 config_close(parser);
2384 }
2385#endif
2386 if (peers) {
2387#if ENABLE_FEATURE_NTP_AUTH
2388 while (peers) {
2389 char *peer = llist_pop(&peers);
2390 key_entry_t *key_entry = NULL;
2391 if (strncmp(peer, "keyno:", 6) == 0) {
2392 char *end;
2393 int key_id;
2394 peer += 6;
2395 end = strchr(peer, ':');
2396 if (!end) bb_show_usage();
2397 *end = '\0';
2398 key_id = xatou_range(peer, 1, MAX_KEY_NUMBER);
2399 *end = ':';
2400 key_entry = find_key_entry(key_entries, key_id);
2401 peer = end + 1;
2402 }
2403 add_peers(peer, key_entry);
2404 }
2405#else
2406 while (peers)
2407 add_peers(llist_pop(&peers), NULL);
2408#endif
2409 }
2410#if ENABLE_FEATURE_NTPD_CONF
2411 else {
2412 parser_t *parser;
2413 char *token[3 + 2*ENABLE_FEATURE_NTP_AUTH];
2414
2415 parser = config_open("/etc/ntp.conf");
2416 while (config_read(parser, token, 3 + 2*ENABLE_FEATURE_NTP_AUTH, 1, "# \t", PARSE_NORMAL)) {
2417 if (strcmp(token[0], "server") == 0 && token[1]) {
2418# if ENABLE_FEATURE_NTP_AUTH
2419 key_entry_t *key_entry = NULL;
2420 if (token[2] && token[3] && strcmp(token[2], "key") == 0) {
2421 unsigned key_id = xatou_range(token[3], 1, MAX_KEY_NUMBER);
2422 key_entry = find_key_entry(key_entries, key_id);
2423 }
2424 add_peers(token[1], key_entry);
2425# else
2426 add_peers(token[1], NULL);
2427# endif
2428 continue;
2429 }
2430 bb_error_msg("skipping %s:%u: unimplemented command '%s'",
2431 "/etc/ntp.conf", parser->lineno, token[0]
2432 );
2433 }
2434 config_close(parser);
2435 }
2436#endif
2437 if (G.peer_cnt == 0) {
2438 if (!(opts & OPT_l))
2439 bb_show_usage();
2440
2441 G.stratum = 1;
2442 }
2443
2444 if (!(opts & OPT_n))
2445 write_pidfile_std_path_and_ext("ntpd");
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456 if (opts & OPT_q) {
2457 option_mask32 |= OPT_qq;
2458 alarm(10);
2459 }
2460
2461 bb_signals(0
2462 | (1 << SIGTERM)
2463 | (1 << SIGINT)
2464 | (1 << SIGALRM)
2465 , record_signo
2466 );
2467 bb_signals(0
2468 | (1 << SIGPIPE)
2469 | (1 << SIGCHLD)
2470 , SIG_IGN
2471 );
2472
2473}
2474
2475int ntpd_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE;
2476int ntpd_main(int argc UNUSED_PARAM, char **argv)
2477{
2478#undef G
2479 struct globals G;
2480 struct pollfd *pfd;
2481 peer_t **idx2peer;
2482 unsigned cnt;
2483
2484 memset(&G, 0, sizeof(G));
2485 SET_PTR_TO_GLOBALS(&G);
2486
2487 ntp_init(argv);
2488
2489
2490 cnt = G.peer_cnt + ENABLE_FEATURE_NTPD_SERVER;
2491 idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt);
2492 pfd = xzalloc(sizeof(pfd[0]) * cnt);
2493
2494
2495
2496
2497
2498
2499
2500
2501 cnt = G.peer_cnt * (INITIAL_SAMPLES + 1);
2502
2503 while (!bb_got_signal) {
2504 llist_t *item;
2505 unsigned i, j;
2506 int nfds, timeout;
2507 double nextaction;
2508
2509
2510
2511 nextaction = G.last_script_run + (11*60);
2512 if (nextaction < G.cur_time + 1)
2513 nextaction = G.cur_time + 1;
2514
2515 i = 0;
2516#if ENABLE_FEATURE_NTPD_SERVER
2517 if (G_listen_fd != -1) {
2518 pfd[0].fd = G_listen_fd;
2519 pfd[0].events = POLLIN;
2520 i++;
2521 }
2522#endif
2523
2524 for (item = G.ntp_peers; item != NULL; item = item->link) {
2525 peer_t *p = (peer_t *) item->data;
2526
2527 if (p->next_action_time <= G.cur_time) {
2528 if (p->p_fd == -1) {
2529
2530 if (--cnt == 0) {
2531 VERB4 bb_simple_error_msg("disabling burst mode");
2532 G.polladj_count = 0;
2533 G.poll_exp = MINPOLL;
2534 }
2535 send_query_to_peer(p);
2536 } else {
2537
2538 close(p->p_fd);
2539 p->p_fd = -1;
2540
2541 if (G.poll_exp < BIGPOLL)
2542 adjust_poll(MINPOLL);
2543 timeout = poll_interval(NOREPLY_INTERVAL);
2544 bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us",
2545 p->p_dotted, p->reachable_bits, timeout);
2546
2547
2548 if (p->reachable_bits == 0)
2549 resolve_peer_hostname(p);
2550
2551 set_next(p, timeout);
2552 }
2553 }
2554
2555 if (p->next_action_time < nextaction)
2556 nextaction = p->next_action_time;
2557
2558 if (p->p_fd >= 0) {
2559
2560 pfd[i].fd = p->p_fd;
2561 pfd[i].events = POLLIN;
2562 idx2peer[i] = p;
2563 i++;
2564 }
2565 }
2566
2567 timeout = nextaction - G.cur_time;
2568 if (timeout < 0)
2569 timeout = 0;
2570 timeout++;
2571
2572
2573 VERB3 {
2574 if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) {
2575
2576
2577
2578
2579
2580 nfds = poll(pfd, i, 1000);
2581 if (nfds != 0)
2582 goto did_poll;
2583 if (--timeout <= 0)
2584 goto did_poll;
2585 }
2586 bb_error_msg("poll:%us sockets:%u interval:%us", timeout, i, 1 << G.poll_exp);
2587 }
2588 nfds = poll(pfd, i, timeout * 1000);
2589 did_poll:
2590 gettime1900d();
2591 if (nfds <= 0) {
2592 double ct;
2593 int dns_error;
2594
2595 if (bb_got_signal)
2596 break;
2597
2598 if (G.cur_time - G.last_script_run > 11*60) {
2599
2600 run_script("periodic", G.last_update_offset);
2601 gettime1900d();
2602 }
2603
2604
2605
2606
2607
2608
2609 dns_error = 0;
2610 ct = G.cur_time;
2611 for (item = G.ntp_peers; item != NULL; item = item->link) {
2612 peer_t *p = (peer_t *) item->data;
2613 if (p->next_action_time <= ct && !p->p_lsa) {
2614
2615 dns_error |= (!resolve_peer_hostname(p));
2616 }
2617 }
2618 if (!dns_error)
2619 goto check_unsync;
2620
2621 gettime1900d();
2622 for (item = G.ntp_peers; item != NULL; item = item->link) {
2623 peer_t *p = (peer_t *) item->data;
2624 if (p->next_action_time <= ct && !p->p_lsa) {
2625 set_next(p, HOSTNAME_INTERVAL * p->dns_errors);
2626 }
2627 }
2628 goto check_unsync;
2629 }
2630
2631
2632 j = 0;
2633#if ENABLE_FEATURE_NTPD_SERVER
2634 if (G.listen_fd != -1) {
2635 if (pfd[0].revents ) {
2636 nfds--;
2637 recv_and_process_client_pkt();
2638 gettime1900d();
2639 }
2640 j = 1;
2641 }
2642#endif
2643 for (; nfds != 0 && j < i; j++) {
2644 if (pfd[j].revents ) {
2645
2646
2647
2648
2649
2650 if (option_mask32 & OPT_qq) {
2651 option_mask32 &= ~OPT_qq;
2652 alarm(50);
2653 }
2654 nfds--;
2655 recv_and_process_peer_pkt(idx2peer[j]);
2656 gettime1900d();
2657 }
2658 }
2659
2660 check_unsync:
2661 if (G.ntp_peers && G.stratum != MAXSTRAT) {
2662 for (item = G.ntp_peers; item != NULL; item = item->link) {
2663 peer_t *p = (peer_t *) item->data;
2664 if (p->reachable_bits)
2665 goto have_reachable_peer;
2666 }
2667
2668 clamp_pollexp_and_set_MAXSTRAT();
2669 run_script("unsync", 0.0);
2670 have_reachable_peer: ;
2671 }
2672 }
2673
2674 remove_pidfile_std_path_and_ext("ntpd");
2675 kill_myself_with_sig(bb_got_signal);
2676}
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687#if 0
2688static double
2689direct_freq(double fp_offset)
2690{
2691#ifdef KERNEL_PLL
2692
2693
2694
2695
2696 if (pll_control && kern_enable) {
2697 memset(&ntv, 0, sizeof(ntv));
2698 ntp_adjtime(&ntv);
2699#ifdef STA_NANO
2700 clock_offset = ntv.offset / 1e9;
2701#else
2702 clock_offset = ntv.offset / 1e6;
2703#endif
2704 drift_comp = FREQTOD(ntv.freq);
2705 }
2706#endif
2707 set_freq((fp_offset - clock_offset) / (current_time - clock_epoch) + drift_comp);
2708 wander_resid = 0;
2709 return drift_comp;
2710}
2711
2712static void
2713set_freq(double freq)
2714{
2715 char tbuf[80];
2716
2717 drift_comp = freq;
2718
2719#ifdef KERNEL_PLL
2720
2721
2722
2723 if (pll_control && kern_enable) {
2724 memset(&ntv, 0, sizeof(ntv));
2725 ntv.modes = MOD_FREQUENCY;
2726 ntv.freq = DTOFREQ(drift_comp);
2727 ntp_adjtime(&ntv);
2728 snprintf(tbuf, sizeof(tbuf), "kernel %.3f PPM", drift_comp * 1e6);
2729 report_event(EVNT_FSET, NULL, tbuf);
2730 } else {
2731 snprintf(tbuf, sizeof(tbuf), "ntpd %.3f PPM", drift_comp * 1e6);
2732 report_event(EVNT_FSET, NULL, tbuf);
2733 }
2734#else
2735 snprintf(tbuf, sizeof(tbuf), "ntpd %.3f PPM", drift_comp * 1e6);
2736 report_event(EVNT_FSET, NULL, tbuf);
2737#endif
2738}
2739
2740...
2741...
2742...
2743
2744#ifdef KERNEL_PLL
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760 if (pll_control && kern_enable) {
2761
2762#define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | MOD_STATUS | MOD_TIMECONST)
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775 memset(&ntv, 0, sizeof(ntv));
2776 if (ext_enable) {
2777 ntv.modes = MOD_STATUS;
2778 } else {
2779#ifdef STA_NANO
2780 ntv.modes = MOD_BITS | MOD_NANO;
2781#else
2782 ntv.modes = MOD_BITS;
2783#endif
2784 if (clock_offset < 0)
2785 dtemp = -.5;
2786 else
2787 dtemp = .5;
2788#ifdef STA_NANO
2789 ntv.offset = (int32)(clock_offset * 1e9 + dtemp);
2790 ntv.constant = sys_poll;
2791#else
2792 ntv.offset = (int32)(clock_offset * 1e6 + dtemp);
2793 ntv.constant = sys_poll - 4;
2794#endif
2795 ntv.esterror = (u_int32)(clock_jitter * 1e6);
2796 ntv.maxerror = (u_int32)((sys_rootdelay / 2 + sys_rootdisp) * 1e6);
2797 ntv.status = STA_PLL;
2798
2799
2800
2801
2802 if (pps_enable) {
2803 if (!(pll_status & STA_PPSTIME))
2804 report_event(EVNT_KERN,
2805 NULL, "PPS enabled");
2806 ntv.status |= STA_PPSTIME | STA_PPSFREQ;
2807 } else {
2808 if (pll_status & STA_PPSTIME)
2809 report_event(EVNT_KERN,
2810 NULL, "PPS disabled");
2811 ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ);
2812 }
2813 if (sys_leap == LEAP_ADDSECOND)
2814 ntv.status |= STA_INS;
2815 else if (sys_leap == LEAP_DELSECOND)
2816 ntv.status |= STA_DEL;
2817 }
2818
2819
2820
2821
2822
2823
2824 if (ntp_adjtime(&ntv) == TIME_ERROR) {
2825 if (!(ntv.status & STA_PPSSIGNAL))
2826 report_event(EVNT_KERN, NULL,
2827 "PPS no signal");
2828 }
2829 pll_status = ntv.status;
2830#ifdef STA_NANO
2831 clock_offset = ntv.offset / 1e9;
2832#else
2833 clock_offset = ntv.offset / 1e6;
2834#endif
2835 clock_frequency = FREQTOD(ntv.freq);
2836
2837
2838
2839
2840 if (ntv.status & STA_PPSTIME) {
2841#ifdef STA_NANO
2842 clock_jitter = ntv.jitter / 1e9;
2843#else
2844 clock_jitter = ntv.jitter / 1e6;
2845#endif
2846 }
2847
2848#if defined(STA_NANO) && NTP_API == 4
2849
2850
2851
2852 if (loop_tai != sys_tai) {
2853 loop_tai = sys_tai;
2854 ntv.modes = MOD_TAI;
2855 ntv.constant = sys_tai;
2856 ntp_adjtime(&ntv);
2857 }
2858#endif
2859 }
2860#endif
2861#endif
2862