aboutsummaryrefslogtreecommitdiff
path: root/networking/ntpd.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-12-30 18:38:05 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-12-30 18:38:05 +0100
commitd2fe69f9dc3d5dbfa38215ab4bb6387cfc79e4f8 (patch)
tree6f24173f1ab2806a96c26550bb97714cfd59a580 /networking/ntpd.c
parentbd1de181ad9a3486ad35e71272fe2cf21d63916c (diff)
downloadbusybox-w32-d2fe69f9dc3d5dbfa38215ab4bb6387cfc79e4f8.tar.gz
busybox-w32-d2fe69f9dc3d5dbfa38215ab4bb6387cfc79e4f8.tar.bz2
busybox-w32-d2fe69f9dc3d5dbfa38215ab4bb6387cfc79e4f8.zip
ntpd: preparatory patches, no functional changes
function old new delta ntp_init 354 357 +3 ntpd_main 2945 2898 -47 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r--networking/ntpd.c118
1 files changed, 60 insertions, 58 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 1c53e3152..5e48306c7 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -29,7 +29,7 @@
29#define QSCALE_OFF_MIN 0.05 29#define QSCALE_OFF_MIN 0.05
30#define QSCALE_OFF_MAX 0.50 30#define QSCALE_OFF_MAX 0.50
31 31
32/* Single query might take n secs max */ 32/* Single query might take N secs max */
33#define QUERYTIME_MAX 15 33#define QUERYTIME_MAX 15
34/* Min offset for settime at start. "man ntpd" says it's 128 ms */ 34/* Min offset for settime at start. "man ntpd" says it's 128 ms */
35#define STEPTIME_MIN_OFFSET 0.128 35#define STEPTIME_MIN_OFFSET 0.128
@@ -54,7 +54,7 @@ typedef struct {
54 uint8_t m_status; /* status of local clock and leap info */ 54 uint8_t m_status; /* status of local clock and leap info */
55 uint8_t m_stratum; /* stratum level */ 55 uint8_t m_stratum; /* stratum level */
56 uint8_t m_ppoll; /* poll value */ 56 uint8_t m_ppoll; /* poll value */
57 int8_t m_precision; 57 int8_t m_precision_exp;
58 s_fixedpt_t m_rootdelay; 58 s_fixedpt_t m_rootdelay;
59 s_fixedpt_t m_dispersion; 59 s_fixedpt_t m_dispersion;
60 uint32_t m_refid; 60 uint32_t m_refid;
@@ -64,16 +64,11 @@ typedef struct {
64 l_fixedpt_t m_xmttime; 64 l_fixedpt_t m_xmttime;
65 uint32_t m_keyid; 65 uint32_t m_keyid;
66 uint8_t m_digest[NTP_DIGESTSIZE]; 66 uint8_t m_digest[NTP_DIGESTSIZE];
67} ntp_msg_t; 67} msg_t;
68 68
69enum { 69enum {
70 NTP_VERSION = 4, 70 NTP_VERSION = 4,
71 NTP_MAXSTRATUM = 15, 71 NTP_MAXSTRATUM = 15,
72 /* Leap Second Codes (high order two bits of m_status) */
73 LI_NOWARNING = (0 << 6), /* no warning */
74 LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */
75 LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */
76 LI_ALARM = (3 << 6), /* alarm condition */
77 72
78 /* Status Masks */ 73 /* Status Masks */
79 MODE_MASK = (7 << 0), 74 MODE_MASK = (7 << 0),
@@ -81,6 +76,12 @@ enum {
81 VERSION_SHIFT = 3, 76 VERSION_SHIFT = 3,
82 LI_MASK = (3 << 6), 77 LI_MASK = (3 << 6),
83 78
79 /* Leap Second Codes (high order two bits of m_status) */
80 LI_NOWARNING = (0 << 6), /* no warning */
81 LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */
82 LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */
83 LI_ALARM = (3 << 6), /* alarm condition */
84
84 /* Mode values */ 85 /* Mode values */
85 MODE_RES0 = 0, /* reserved */ 86 MODE_RES0 = 0, /* reserved */
86 MODE_SYM_ACT = 1, /* symmetric active */ 87 MODE_SYM_ACT = 1, /* symmetric active */
@@ -103,7 +104,7 @@ typedef struct {
103 uint8_t d_leap; 104 uint8_t d_leap;
104 uint8_t d_stratum; 105 uint8_t d_stratum;
105 uint8_t d_good; 106 uint8_t d_good;
106} ntp_datapoint_t; 107} datapoint_t;
107 108
108#define NUM_DATAPOINTS 8 109#define NUM_DATAPOINTS 8
109typedef struct { 110typedef struct {
@@ -114,12 +115,12 @@ typedef struct {
114 time_t next_action_time; 115 time_t next_action_time;
115 int p_fd; 116 int p_fd;
116 uint8_t p_datapoint_idx; 117 uint8_t p_datapoint_idx;
117 uint8_t trustlevel; 118 uint8_t p_trustlevel;
118 ntp_msg_t msg;
119 double p_xmttime; 119 double p_xmttime;
120 ntp_datapoint_t update; 120 datapoint_t update;
121 ntp_datapoint_t p_datapoint[NUM_DATAPOINTS]; 121 datapoint_t p_datapoint[NUM_DATAPOINTS];
122} ntp_peer_t; 122 msg_t p_xmt_msg;
123} peer_t;
123 124
124enum { 125enum {
125 OPT_n = (1 << 0), 126 OPT_n = (1 << 0),
@@ -134,7 +135,9 @@ enum {
134 135
135 136
136struct globals { 137struct globals {
138 /* total round trip delay to currently selected reference clock */
137 double rootdelay; 139 double rootdelay;
140 /* reference timestamp: time when the system clock was last set or corrected */
138 double reftime; 141 double reftime;
139 llist_t *ntp_peers; 142 llist_t *ntp_peers;
140#if ENABLE_FEATURE_NTPD_SERVER 143#if ENABLE_FEATURE_NTPD_SERVER
@@ -155,12 +158,11 @@ struct globals {
155}; 158};
156#define G (*ptr_to_globals) 159#define G (*ptr_to_globals)
157 160
158
159static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY; 161static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;
160 162
161 163
162static void 164static void
163set_next(ntp_peer_t *p, unsigned t) 165set_next(peer_t *p, unsigned t)
164{ 166{
165 p->next_action_time = time(NULL) + t; 167 p->next_action_time = time(NULL) + t;
166} 168}
@@ -168,14 +170,14 @@ set_next(ntp_peer_t *p, unsigned t)
168static void 170static void
169add_peers(char *s) 171add_peers(char *s)
170{ 172{
171 ntp_peer_t *p; 173 peer_t *p;
172 174
173 p = xzalloc(sizeof(*p)); 175 p = xzalloc(sizeof(*p));
174 p->p_lsa = xhost2sockaddr(s, 123); 176 p->p_lsa = xhost2sockaddr(s, 123);
175 p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); 177 p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa);
176 p->p_fd = -1; 178 p->p_fd = -1;
177 p->msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); 179 p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
178 p->trustlevel = TRUSTLEVEL_PATHETIC; 180 p->p_trustlevel = TRUSTLEVEL_PATHETIC;
179 p->next_action_time = time(NULL); /* = set_next(p, 0); */ 181 p->next_action_time = time(NULL); /* = set_next(p, 0); */
180 182
181 llist_add_to(&G.ntp_peers, p); 183 llist_add_to(&G.ntp_peers, p);
@@ -255,7 +257,7 @@ error_interval(void)
255static int 257static int
256do_sendto(int fd, 258do_sendto(int fd,
257 const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen, 259 const struct sockaddr *from, const struct sockaddr *to, socklen_t addrlen,
258 ntp_msg_t *msg, ssize_t len) 260 msg_t *msg, ssize_t len)
259{ 261{
260 ssize_t ret; 262 ssize_t ret;
261 263
@@ -273,7 +275,7 @@ do_sendto(int fd,
273} 275}
274 276
275static int 277static int
276send_query_to_peer(ntp_peer_t *p) 278send_query_to_peer(peer_t *p)
277{ 279{
278 // Why do we need to bind()? 280 // Why do we need to bind()?
279 // See what happens when we don't bind: 281 // See what happens when we don't bind:
@@ -326,12 +328,12 @@ send_query_to_peer(ntp_peer_t *p)
326 * 328 *
327 * Save the real transmit timestamp locally. 329 * Save the real transmit timestamp locally.
328 */ 330 */
329 p->msg.m_xmttime.int_partl = random(); 331 p->p_xmt_msg.m_xmttime.int_partl = random();
330 p->msg.m_xmttime.fractionl = random(); 332 p->p_xmt_msg.m_xmttime.fractionl = random();
331 p->p_xmttime = gettime1900d(); 333 p->p_xmttime = gettime1900d();
332 334
333 if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, 335 if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len,
334 &p->msg, NTP_MSGSIZE_NOAUTH) == -1 336 &p->p_xmt_msg, NTP_MSGSIZE_NOAUTH) == -1
335 ) { 337 ) {
336 close(p->p_fd); 338 close(p->p_fd);
337 p->p_fd = -1; 339 p->p_fd = -1;
@@ -380,7 +382,7 @@ step_time_once(double offset)
380 bb_error_msg("setting clock to %s (offset %fs)", buf, offset); 382 bb_error_msg("setting clock to %s (offset %fs)", buf, offset);
381 383
382 for (item = G.ntp_peers; item != NULL; item = item->link) { 384 for (item = G.ntp_peers; item != NULL; item = item->link) {
383 ntp_peer_t *p = (ntp_peer_t *) item->data; 385 peer_t *p = (peer_t *) item->data;
384 p->next_action_time -= (time_t)offset; 386 p->next_action_time -= (time_t)offset;
385 } 387 }
386 388
@@ -396,8 +398,8 @@ step_time_once(double offset)
396static int 398static int
397compare_offsets(const void *aa, const void *bb) 399compare_offsets(const void *aa, const void *bb)
398{ 400{
399 const ntp_peer_t *const *a = aa; 401 const peer_t *const *a = aa;
400 const ntp_peer_t *const *b = bb; 402 const peer_t *const *b = bb;
401 if ((*a)->update.d_offset < (*b)->update.d_offset) 403 if ((*a)->update.d_offset < (*b)->update.d_offset)
402 return -1; 404 return -1;
403 return ((*a)->update.d_offset > (*b)->update.d_offset); 405 return ((*a)->update.d_offset > (*b)->update.d_offset);
@@ -421,13 +423,13 @@ slew_time(void)
421 struct timeval tv; 423 struct timeval tv;
422 424
423 { 425 {
424 ntp_peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt); 426 peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt);
425 unsigned goodpeer_cnt = 0; 427 unsigned goodpeer_cnt = 0;
426 unsigned middle; 428 unsigned middle;
427 429
428 for (item = G.ntp_peers; item != NULL; item = item->link) { 430 for (item = G.ntp_peers; item != NULL; item = item->link) {
429 ntp_peer_t *p = (ntp_peer_t *) item->data; 431 peer_t *p = (peer_t *) item->data;
430 if (p->trustlevel < TRUSTLEVEL_BADPEER) 432 if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
431 continue; 433 continue;
432 if (!p->update.d_good) { 434 if (!p->update.d_good) {
433 free(peers); 435 free(peers);
@@ -490,13 +492,13 @@ slew_time(void)
490 492
491 clear_good: 493 clear_good:
492 for (item = G.ntp_peers; item != NULL; item = item->link) { 494 for (item = G.ntp_peers; item != NULL; item = item->link) {
493 ntp_peer_t *p = (ntp_peer_t *) item->data; 495 peer_t *p = (peer_t *) item->data;
494 p->update.d_good = 0; 496 p->update.d_good = 0;
495 } 497 }
496} 498}
497 499
498static void 500static void
499update_peer_data(ntp_peer_t *p) 501update_peer_data(peer_t *p)
500{ 502{
501 /* Clock filter. 503 /* Clock filter.
502 * Find the datapoint with the lowest delay. 504 * Find the datapoint with the lowest delay.
@@ -535,13 +537,13 @@ scale_interval(unsigned requested)
535 return (interval + r); 537 return (interval + r);
536} 538}
537static void 539static void
538recv_and_process_peer_pkt(ntp_peer_t *p) 540recv_and_process_peer_pkt(peer_t *p)
539{ 541{
540 ssize_t size; 542 ssize_t size;
541 ntp_msg_t msg; 543 msg_t msg;
542 double T1, T2, T3, T4; 544 double T1, T2, T3, T4;
543 unsigned interval; 545 unsigned interval;
544 ntp_datapoint_t *datapoint; 546 datapoint_t *datapoint;
545 547
546 /* We can recvfrom here and check from.IP, but some multihomed 548 /* We can recvfrom here and check from.IP, but some multihomed
547 * ntp servers reply from their *other IP*. 549 * ntp servers reply from their *other IP*.
@@ -567,8 +569,8 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
567 goto bail; 569 goto bail;
568 } 570 }
569 571
570 if (msg.m_orgtime.int_partl != p->msg.m_xmttime.int_partl 572 if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl
571 || msg.m_orgtime.fractionl != p->msg.m_xmttime.fractionl 573 || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl
572 ) { 574 ) {
573 goto bail; 575 goto bail;
574 } 576 }
@@ -599,10 +601,10 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
599 * 601 *
600 * delay = (T4 - T1) - (T3 - T2); offset = ((T2 - T1) + (T3 - T4)) / 2 602 * delay = (T4 - T1) - (T3 - T2); offset = ((T2 - T1) + (T3 - T4)) / 2
601 */ 603 */
602 T4 = gettime1900d();
603 T1 = p->p_xmttime; 604 T1 = p->p_xmttime;
604 T2 = lfp_to_d(msg.m_rectime); 605 T2 = lfp_to_d(msg.m_rectime);
605 T3 = lfp_to_d(msg.m_xmttime); 606 T3 = lfp_to_d(msg.m_xmttime);
607 T4 = gettime1900d();
606 608
607 datapoint = &p->p_datapoint[p->p_datapoint_idx]; 609 datapoint = &p->p_datapoint[p->p_datapoint_idx];
608 610
@@ -619,7 +621,7 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
619 datapoint->d_good = 1; 621 datapoint->d_good = 1;
620 622
621 datapoint->d_leap = (msg.m_status & LI_MASK); 623 datapoint->d_leap = (msg.m_status & LI_MASK);
622 //UNUSED: datapoint->o_precision = msg.m_precision; 624 //UNUSED: datapoint->o_precision = msg.m_precision_exp;
623 //UNUSED: datapoint->o_rootdelay = sfp_to_d(msg.m_rootdelay); 625 //UNUSED: datapoint->o_rootdelay = sfp_to_d(msg.m_rootdelay);
624 //UNUSED: datapoint->o_rootdispersion = sfp_to_d(msg.m_dispersion); 626 //UNUSED: datapoint->o_rootdispersion = sfp_to_d(msg.m_dispersion);
625 //UNUSED: datapoint->d_refid = ntohl(msg.m_refid); 627 //UNUSED: datapoint->d_refid = ntohl(msg.m_refid);
@@ -628,19 +630,19 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
628 //UNUSED: datapoint->o_poll = msg.m_ppoll; 630 //UNUSED: datapoint->o_poll = msg.m_ppoll;
629 datapoint->d_stratum = msg.m_stratum; 631 datapoint->d_stratum = msg.m_stratum;
630 632
631 if (p->trustlevel < TRUSTLEVEL_PATHETIC) 633 if (p->p_trustlevel < TRUSTLEVEL_PATHETIC)
632 interval = scale_interval(INTERVAL_QUERY_PATHETIC); 634 interval = scale_interval(INTERVAL_QUERY_PATHETIC);
633 else if (p->trustlevel < TRUSTLEVEL_AGRESSIVE) 635 else if (p->p_trustlevel < TRUSTLEVEL_AGRESSIVE)
634 interval = scale_interval(INTERVAL_QUERY_AGRESSIVE); 636 interval = scale_interval(INTERVAL_QUERY_AGRESSIVE);
635 else 637 else
636 interval = scale_interval(INTERVAL_QUERY_NORMAL); 638 interval = scale_interval(INTERVAL_QUERY_NORMAL);
637 639
638 set_next(p, interval); 640 set_next(p, interval);
639 641
640 /* every received reply which we do not discard increases trust */ 642 /* Every received reply which we do not discard increases trust */
641 if (p->trustlevel < TRUSTLEVEL_MAX) { 643 if (p->p_trustlevel < TRUSTLEVEL_MAX) {
642 p->trustlevel++; 644 p->p_trustlevel++;
643 if (p->trustlevel == TRUSTLEVEL_BADPEER) 645 if (p->p_trustlevel == TRUSTLEVEL_BADPEER)
644 bb_error_msg("peer %s now valid", p->p_dotted); 646 bb_error_msg("peer %s now valid", p->p_dotted);
645 } 647 }
646 648
@@ -676,7 +678,7 @@ recv_and_process_client_pkt(void /*int fd*/)
676 double rectime; 678 double rectime;
677 len_and_sockaddr *to; 679 len_and_sockaddr *to;
678 struct sockaddr *from; 680 struct sockaddr *from;
679 ntp_msg_t msg; 681 msg_t msg;
680 uint8_t query_status; 682 uint8_t query_status;
681 uint8_t query_ppoll; 683 uint8_t query_ppoll;
682 l_fixedpt_t query_xmttime; 684 l_fixedpt_t query_xmttime;
@@ -710,7 +712,7 @@ recv_and_process_client_pkt(void /*int fd*/)
710 MODE_SERVER : MODE_SYM_PAS; 712 MODE_SERVER : MODE_SYM_PAS;
711 msg.m_stratum = G.stratum; 713 msg.m_stratum = G.stratum;
712 msg.m_ppoll = query_ppoll; 714 msg.m_ppoll = query_ppoll;
713 msg.m_precision = G_precision_exp; 715 msg.m_precision_exp = G_precision_exp;
714 rectime = gettime1900d(); 716 rectime = gettime1900d();
715 msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime); 717 msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime);
716 msg.m_reftime = d_to_lfp(G.reftime); 718 msg.m_reftime = d_to_lfp(G.reftime);
@@ -894,7 +896,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
894{ 896{
895 struct globals g; 897 struct globals g;
896 struct pollfd *pfd; 898 struct pollfd *pfd;
897 ntp_peer_t **idx2peer; 899 peer_t **idx2peer;
898 900
899 memset(&g, 0, sizeof(g)); 901 memset(&g, 0, sizeof(g));
900 SET_PTR_TO_GLOBALS(&g); 902 SET_PTR_TO_GLOBALS(&g);
@@ -902,10 +904,10 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
902 ntp_init(argv); 904 ntp_init(argv);
903 905
904 { 906 {
905 unsigned cnt = g.peer_cnt;
906 /* if ENABLE_FEATURE_NTPD_SERVER, + 1 for listen_fd: */ 907 /* if ENABLE_FEATURE_NTPD_SERVER, + 1 for listen_fd: */
907 idx2peer = xzalloc(sizeof(void *) * (cnt + ENABLE_FEATURE_NTPD_SERVER)); 908 unsigned cnt = g.peer_cnt + ENABLE_FEATURE_NTPD_SERVER;
908 pfd = xzalloc(sizeof(pfd[0]) * (cnt + ENABLE_FEATURE_NTPD_SERVER)); 909 idx2peer = xzalloc(sizeof(idx2peer[0]) * cnt);
910 pfd = xzalloc(sizeof(pfd[0]) * cnt);
909 } 911 }
910 912
911 while (!bb_got_signal) { 913 while (!bb_got_signal) {
@@ -931,7 +933,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
931 /* Pass over peer list, send requests, time out on receives */ 933 /* Pass over peer list, send requests, time out on receives */
932 sent_cnt = trial_cnt = 0; 934 sent_cnt = trial_cnt = 0;
933 for (item = g.ntp_peers; item != NULL; item = item->link) { 935 for (item = g.ntp_peers; item != NULL; item = item->link) {
934 ntp_peer_t *p = (ntp_peer_t *) item->data; 936 peer_t *p = (peer_t *) item->data;
935 937
936 /* Overflow-safe "if (p->next_action_time <= cur_time) ..." */ 938 /* Overflow-safe "if (p->next_action_time <= cur_time) ..." */
937 if ((int)(cur_time - p->next_action_time) >= 0) { 939 if ((int)(cur_time - p->next_action_time) >= 0) {
@@ -947,9 +949,9 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
947 timeout = error_interval(); 949 timeout = error_interval();
948 bb_error_msg("timed out waiting for %s, " 950 bb_error_msg("timed out waiting for %s, "
949 "next query in %us", p->p_dotted, timeout); 951 "next query in %us", p->p_dotted, timeout);
950 if (p->trustlevel >= TRUSTLEVEL_BADPEER) { 952 if (p->p_trustlevel >= TRUSTLEVEL_BADPEER) {
951 p->trustlevel /= 2; 953 p->p_trustlevel /= 2;
952 if (p->trustlevel < TRUSTLEVEL_BADPEER) 954 if (p->p_trustlevel < TRUSTLEVEL_BADPEER)
953 bb_error_msg("peer %s now invalid", p->p_dotted); 955 bb_error_msg("peer %s now invalid", p->p_dotted);
954 } 956 }
955 set_next(p, timeout); 957 set_next(p, timeout);