aboutsummaryrefslogtreecommitdiff
path: root/networking/ntpd.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-12-02 23:17:45 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-12-02 23:17:45 +0100
commit907647fb1540cb5303d90f2316dbfe89120db39c (patch)
tree1ec5716345ea491e9e37bc7af448023ad777fdd7 /networking/ntpd.c
parent4bd51893704e4db5dda0ecca19ebb1f39a574baa (diff)
downloadbusybox-w32-907647fb1540cb5303d90f2316dbfe89120db39c.tar.gz
busybox-w32-907647fb1540cb5303d90f2316dbfe89120db39c.tar.bz2
busybox-w32-907647fb1540cb5303d90f2316dbfe89120db39c.zip
ntpd: implement -x. shrink code a bit. -69 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r--networking/ntpd.c330
1 files changed, 156 insertions, 174 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 320477c13..3bca69a4c 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -14,11 +14,14 @@
14# error "Sorry, your kernel has to support IP_PKTINFO" 14# error "Sorry, your kernel has to support IP_PKTINFO"
15#endif 15#endif
16 16
17#define INTERVAL_QUERY_NORMAL 30 /* sync to peers every n secs */ 17
18/* Sync to peers every N secs */
19#define INTERVAL_QUERY_NORMAL 30
18#define INTERVAL_QUERY_PATHETIC 60 20#define INTERVAL_QUERY_PATHETIC 60
19#define INTERVAL_QUERY_AGRESSIVE 5 21#define INTERVAL_QUERY_AGRESSIVE 5
20 22
21#define TRUSTLEVEL_BADPEER 6 /* bad if *less than* TRUSTLEVEL_BADPEER */ 23/* Bad if *less than* TRUSTLEVEL_BADPEER */
24#define TRUSTLEVEL_BADPEER 6
22#define TRUSTLEVEL_PATHETIC 2 25#define TRUSTLEVEL_PATHETIC 2
23#define TRUSTLEVEL_AGRESSIVE 8 26#define TRUSTLEVEL_AGRESSIVE 8
24#define TRUSTLEVEL_MAX 10 27#define TRUSTLEVEL_MAX 10
@@ -26,30 +29,11 @@
26#define QSCALE_OFF_MIN 0.05 29#define QSCALE_OFF_MIN 0.05
27#define QSCALE_OFF_MAX 0.50 30#define QSCALE_OFF_MAX 0.50
28 31
29#define QUERYTIME_MAX 15 /* single query might take n secs max */ 32/* Single query might take n secs max */
30#define OFFSET_ARRAY_SIZE 8 33#define QUERYTIME_MAX 15
31#define SETTIME_MIN_OFFSET 180 /* min offset for settime at start */ 34/* Min offset for settime at start. "man ntpd" says it's 128 ms */
32#define SETTIME_TIMEOUT 15 /* max seconds to wait with -s */ 35#define STEPTIME_MIN_OFFSET 0.128
33
34/* Style borrowed from NTP ref/tcpdump and updated for SNTPv4 (RFC2030). */
35 36
36/*
37 * RFC Section 3
38 *
39 * 0 1 2 3
40 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | Integer Part |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Fraction Part |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 *
47 * 0 1 2 3
48 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * | Integer Part | Fraction Part |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52*/
53typedef struct { 37typedef struct {
54 uint32_t int_partl; 38 uint32_t int_partl;
55 uint32_t fractionl; 39 uint32_t fractionl;
@@ -85,7 +69,7 @@ typedef struct {
85enum { 69enum {
86 NTP_VERSION = 4, 70 NTP_VERSION = 4,
87 NTP_MAXSTRATUM = 15, 71 NTP_MAXSTRATUM = 15,
88 /* Leap Second Codes (high order two bits) */ 72 /* Leap Second Codes (high order two bits of m_status) */
89 LI_NOWARNING = (0 << 6), /* no warning */ 73 LI_NOWARNING = (0 << 6), /* no warning */
90 LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */ 74 LI_PLUSSEC = (1 << 6), /* add a second (61 seconds) */
91 LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */ 75 LI_MINUSSEC = (2 << 6), /* minus a second (59 seconds) */
@@ -121,33 +105,28 @@ typedef struct {
121 uint8_t o_good; 105 uint8_t o_good;
122} ntp_offset_t; 106} ntp_offset_t;
123 107
108#define OFFSET_ARRAY_SIZE 8
124typedef struct { 109typedef struct {
125//TODO: periodically re-resolve DNS names?
126 len_and_sockaddr *lsa; 110 len_and_sockaddr *lsa;
111 char *hostname;
127 char *dotted; 112 char *dotted;
128 double xmttime; 113 /* When to send new query (if fd == -1)
129 time_t next; 114 * or when receive times out (if fd >= 0): */
130 time_t deadline; 115 time_t next_action_time;
131 int fd; 116 int fd;
132 uint8_t state;
133 uint8_t shift; 117 uint8_t shift;
134 uint8_t trustlevel; 118 uint8_t trustlevel;
135 ntp_msg_t msg; 119 ntp_msg_t msg;
120 double xmttime;
136 ntp_offset_t update; 121 ntp_offset_t update;
137 ntp_offset_t reply[OFFSET_ARRAY_SIZE]; 122 ntp_offset_t reply[OFFSET_ARRAY_SIZE];
138} ntp_peer_t; 123} ntp_peer_t;
139/* for ntp_peer_t::state */
140enum {
141 STATE_NONE,
142 STATE_QUERY_SENT,
143 STATE_REPLY_RECEIVED,
144};
145 124
146enum { 125enum {
147 OPT_n = (1 << 0), 126 OPT_n = (1 << 0),
148 OPT_g = (1 << 1), 127 OPT_q = (1 << 1),
149 OPT_q = (1 << 2), 128 OPT_N = (1 << 2),
150 OPT_N = (1 << 3), 129 OPT_x = (1 << 3),
151 /* Insert new options above this line. */ 130 /* Insert new options above this line. */
152 /* Non-compat options: */ 131 /* Non-compat options: */
153 OPT_p = (1 << 4), 132 OPT_p = (1 << 4),
@@ -164,12 +143,13 @@ struct globals {
164#endif 143#endif
165 unsigned verbose; 144 unsigned verbose;
166 unsigned peer_cnt; 145 unsigned peer_cnt;
146 unsigned scale;
167 uint32_t refid; 147 uint32_t refid;
168 uint32_t refid4; 148 uint32_t refid4;
169 uint32_t scale;
170 uint8_t synced; 149 uint8_t synced;
171 uint8_t leap; 150 uint8_t leap;
172 int8_t precision; 151#define G_precision -6
152// int8_t precision;
173 uint8_t stratum; 153 uint8_t stratum;
174 uint8_t time_is_stepped; 154 uint8_t time_is_stepped;
175 uint8_t first_adj_done; 155 uint8_t first_adj_done;
@@ -183,32 +163,28 @@ static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;
183static void 163static void
184set_next(ntp_peer_t *p, unsigned t) 164set_next(ntp_peer_t *p, unsigned t)
185{ 165{
186 p->next = time(NULL) + t; 166 p->next_action_time = time(NULL) + t;
187 p->deadline = 0;
188} 167}
189 168
190static void 169static void
191add_peers(const char *s) 170add_peers(char *s)
192{ 171{
193 ntp_peer_t *p; 172 ntp_peer_t *p;
194 173
195 p = xzalloc(sizeof(*p)); 174 p = xzalloc(sizeof(*p));
196//TODO: big ntpd uses all IPs, not just 1st, do we need to mimic that? 175 p->hostname = s;
197 p->lsa = xhost2sockaddr(s, 123); 176 p->dotted = s;
198 p->dotted = xmalloc_sockaddr2dotted_noport(&p->lsa->u.sa);
199 p->fd = -1; 177 p->fd = -1;
200 p->msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); 178 p->msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
201 if (STATE_NONE != 0)
202 p->state = STATE_NONE;
203 p->trustlevel = TRUSTLEVEL_PATHETIC; 179 p->trustlevel = TRUSTLEVEL_PATHETIC;
204 set_next(p, 0); 180 p->next_action_time = time(NULL); /* = set_next(p, 0); */
205 181
206 llist_add_to(&G.ntp_peers, p); 182 llist_add_to(&G.ntp_peers, p);
207 G.peer_cnt++; 183 G.peer_cnt++;
208} 184}
209 185
210static double 186static double
211gettime1900fp(void) 187gettime1900d(void)
212{ 188{
213 struct timeval tv; 189 struct timeval tv;
214 gettimeofday(&tv, NULL); /* never fails */ 190 gettimeofday(&tv, NULL); /* never fails */
@@ -268,13 +244,6 @@ d_to_sfp(double d)
268} 244}
269#endif 245#endif
270 246
271static void
272set_deadline(ntp_peer_t *p, time_t t)
273{
274 p->deadline = time(NULL) + t;
275 p->next = 0;
276}
277
278static unsigned 247static unsigned
279error_interval(void) 248error_interval(void)
280{ 249{
@@ -328,8 +297,18 @@ send_query_to_peer(ntp_peer_t *p)
328 int fd, family; 297 int fd, family;
329 len_and_sockaddr *local_lsa; 298 len_and_sockaddr *local_lsa;
330 299
300//TODO: big ntpd uses all IPs, not just 1st, do we need to mimic that?
301//TODO: periodically re-resolve DNS names?
302 if (!p->lsa) {
303 p->lsa = host2sockaddr(p->hostname, 123);
304 if (!p->lsa) {
305 set_next(p, INTERVAL_QUERY_PATHETIC);
306 return -1;
307 }
308 p->dotted = xmalloc_sockaddr2dotted_noport(&p->lsa->u.sa);
309 }
310
331 family = p->lsa->u.sa.sa_family; 311 family = p->lsa->u.sa.sa_family;
332 //was: p->fd = xsocket(family, SOCK_DGRAM, 0);
333 p->fd = fd = xsocket_type(&local_lsa, family, SOCK_DGRAM); 312 p->fd = fd = xsocket_type(&local_lsa, family, SOCK_DGRAM);
334 /* local_lsa has "null" address and port 0 now. 313 /* local_lsa has "null" address and port 0 now.
335 * bind() ensures we have a *particular port* selected by kernel 314 * bind() ensures we have a *particular port* selected by kernel
@@ -362,23 +341,70 @@ send_query_to_peer(ntp_peer_t *p)
362 341
363 p->msg.m_xmttime.int_partl = random(); 342 p->msg.m_xmttime.int_partl = random();
364 p->msg.m_xmttime.fractionl = random(); 343 p->msg.m_xmttime.fractionl = random();
365 p->xmttime = gettime1900fp(); 344 p->xmttime = gettime1900d();
366 345
367 if (do_sendto(p->fd, /*from:*/ NULL, /*to:*/ &p->lsa->u.sa, /*addrlen:*/ p->lsa->len, 346 if (do_sendto(p->fd, /*from:*/ NULL, /*to:*/ &p->lsa->u.sa, /*addrlen:*/ p->lsa->len,
368 &p->msg, NTP_MSGSIZE_NOAUTH) == -1 347 &p->msg, NTP_MSGSIZE_NOAUTH) == -1
369 ) { 348 ) {
349 close(p->fd);
350 p->fd = -1;
370 set_next(p, INTERVAL_QUERY_PATHETIC); 351 set_next(p, INTERVAL_QUERY_PATHETIC);
371 return -1; 352 return -1;
372 } 353 }
373 354
374 if (G.verbose) 355 if (G.verbose)
375 bb_error_msg("sent query to %s", p->dotted); 356 bb_error_msg("sent query to %s", p->dotted);
376 p->state = STATE_QUERY_SENT; 357 set_next(p, QUERYTIME_MAX);
377 set_deadline(p, QUERYTIME_MAX);
378 358
379 return 0; 359 return 0;
380} 360}
381 361
362
363/* Time is stepped only once, when the first packet from a peer is received.
364 */
365static void
366step_time_once(double offset)
367{
368 llist_t *item;
369 struct timeval tv;
370 char buf[80];
371 time_t tval;
372
373 if (G.time_is_stepped)
374 goto bail;
375 G.time_is_stepped = 1;
376
377 /* if the offset is small, don't step, slew (later) */
378 if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET)
379 goto bail;
380
381 gettimeofday(&tv, NULL); /* never fails */
382 offset += tv.tv_sec;
383 offset += 1.0e-6 * tv.tv_usec;
384 d_to_tv(offset, &tv);
385
386 if (settimeofday(&tv, NULL) == -1)
387 bb_perror_msg_and_die("settimeofday");
388
389 tval = tv.tv_sec;
390 strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", localtime(&tval));
391
392 bb_error_msg("setting clock to %s (offset %fs)", buf, offset);
393
394 for (item = G.ntp_peers; item != NULL; item = item->link) {
395 ntp_peer_t *p = (ntp_peer_t *) item->data;
396 p->next_action_time -= offset;
397 }
398
399 bail:
400 if (option_mask32 & OPT_q)
401 exit(0);
402}
403
404
405/* Time is periodically slewed when we collect enough
406 * good data points.
407 */
382static int 408static int
383compare_offsets(const void *aa, const void *bb) 409compare_offsets(const void *aa, const void *bb)
384{ 410{
@@ -388,8 +414,7 @@ compare_offsets(const void *aa, const void *bb)
388 return -1; 414 return -1;
389 return ((*a)->update.o_offset > (*b)->update.o_offset); 415 return ((*a)->update.o_offset > (*b)->update.o_offset);
390} 416}
391 417static unsigned
392static uint32_t
393updated_scale(double offset) 418updated_scale(double offset)
394{ 419{
395 if (offset < 0) 420 if (offset < 0)
@@ -400,7 +425,6 @@ updated_scale(double offset)
400 return QSCALE_OFF_MAX / QSCALE_OFF_MIN; 425 return QSCALE_OFF_MAX / QSCALE_OFF_MIN;
401 return QSCALE_OFF_MAX / offset; 426 return QSCALE_OFF_MAX / offset;
402} 427}
403
404static void 428static void
405slew_time(void) 429slew_time(void)
406{ 430{
@@ -409,7 +433,6 @@ slew_time(void)
409 struct timeval tv; 433 struct timeval tv;
410 434
411 { 435 {
412 len_and_sockaddr *lsa;
413 ntp_peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt); 436 ntp_peer_t **peers = xzalloc(sizeof(peers[0]) * G.peer_cnt);
414 unsigned goodpeer_cnt = 0; 437 unsigned goodpeer_cnt = 0;
415 unsigned middle; 438 unsigned middle;
@@ -418,8 +441,10 @@ slew_time(void)
418 ntp_peer_t *p = (ntp_peer_t *) item->data; 441 ntp_peer_t *p = (ntp_peer_t *) item->data;
419 if (p->trustlevel < TRUSTLEVEL_BADPEER) 442 if (p->trustlevel < TRUSTLEVEL_BADPEER)
420 continue; 443 continue;
421 if (!p->update.o_good) 444 if (!p->update.o_good) {
445 free(peers);
422 return; 446 return;
447 }
423 peers[goodpeer_cnt++] = p; 448 peers[goodpeer_cnt++] = p;
424 } 449 }
425 450
@@ -442,38 +467,38 @@ slew_time(void)
442 } 467 }
443 G.leap = peers[middle]->update.o_leap; 468 G.leap = peers[middle]->update.o_leap;
444 G.refid4 = peers[middle]->update.o_refid4; 469 G.refid4 = peers[middle]->update.o_refid4;
445 lsa = peers[middle]->lsa;
446 G.refid = 470 G.refid =
447#if ENABLE_FEATURE_IPV6 471#if ENABLE_FEATURE_IPV6
448 lsa->u.sa.sa_family != AF_INET ? 472 peers[middle]->lsa->u.sa.sa_family != AF_INET ?
449 G.refid4 : 473 G.refid4 :
450#endif 474#endif
451 lsa->u.sin.sin_addr.s_addr; 475 peers[middle]->lsa->u.sin.sin_addr.s_addr;
452 free(peers); 476 free(peers);
453 } 477 }
478//TODO: if (offset_median > BIG) step_time(offset_median)?
454 479
455 bb_error_msg("adjusting clock by %fs, our stratum is %u", offset_median, G.stratum); 480 G.scale = updated_scale(offset_median);
481
482 bb_error_msg("adjusting clock by %fs, our stratum is %u, time scale %u",
483 offset_median, G.stratum, G.scale);
456 484
457 errno = 0; 485 errno = 0;
458 d_to_tv(offset_median, &tv); 486 d_to_tv(offset_median, &tv);
459 if (adjtime(&tv, &tv) == -1) { 487 if (adjtime(&tv, &tv) == -1)
460 bb_perror_msg("adjtime failed"); //TODO: maybe _and_die? 488 bb_perror_msg_and_die("adjtime failed");
461 } else { 489 if (G.verbose >= 2)
462 if (G.verbose >= 2) 490 bb_error_msg("old adjust: %d.%06u", (int)tv.tv_sec, (unsigned)tv.tv_usec);
463 bb_error_msg("old adjust: %d.%06u", (int)tv.tv_sec, (unsigned)tv.tv_usec); 491
464 if (G.first_adj_done) { 492 if (G.first_adj_done) {
465 uint8_t synced = (tv.tv_sec == 0 && tv.tv_usec == 0); 493 uint8_t synced = (tv.tv_sec == 0 && tv.tv_usec == 0);
466 if (synced != G.synced) { 494 if (synced != G.synced) {
467 G.synced = synced; 495 G.synced = synced;
468 bb_error_msg("clock is %ssynced", synced ? "" : "un"); 496 bb_error_msg("clock is %ssynced", synced ? "" : "un");
469 }
470 } 497 }
471 G.first_adj_done = 1;
472 } 498 }
499 G.first_adj_done = 1;
473 500
474 G.reftime = gettime1900fp(); 501 G.reftime = gettime1900d();
475//TODO: log if G.scale changed?
476 G.scale = updated_scale(offset_median);
477 502
478 clear_good: 503 clear_good:
479 for (item = G.ntp_peers; item != NULL; item = item->link) { 504 for (item = G.ntp_peers; item != NULL; item = item->link) {
@@ -483,52 +508,6 @@ slew_time(void)
483} 508}
484 509
485static void 510static void
486step_time_once(double offset)
487{
488 ntp_peer_t *p;
489 llist_t *item;
490 struct timeval tv;
491 char buf[80];
492 time_t tval;
493
494 if (G.time_is_stepped)
495 goto bail;
496 G.time_is_stepped = 1;
497
498 /* if the offset is small, don't call settimeofday */
499 if (offset < SETTIME_MIN_OFFSET && offset > -SETTIME_MIN_OFFSET)
500 goto bail;
501
502 gettimeofday(&tv, NULL); /* never fails */
503 offset += tv.tv_sec;
504 offset += 1.0e-6 * tv.tv_usec;
505 d_to_tv(offset, &tv);
506
507 if (settimeofday(&tv, NULL) == -1) {
508 bb_perror_msg("settimeofday");
509 goto bail;
510 }
511
512 tval = tv.tv_sec;
513 strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", localtime(&tval));
514
515// Do we want to print message below to system log when daemonized?
516 bb_error_msg("setting clock to %s (offset %fs)", buf, offset);
517
518 for (item = G.ntp_peers; item != NULL; item = item->link) {
519 p = (ntp_peer_t *) item->data;
520 if (p->next)
521 p->next -= offset;
522 if (p->deadline)
523 p->deadline -= offset;
524 }
525
526 bail:
527 if (option_mask32 & OPT_q)
528 exit(0);
529}
530
531static void
532update_peer_data(ntp_peer_t *p) 511update_peer_data(ntp_peer_t *p)
533{ 512{
534 /* Clock filter. 513 /* Clock filter.
@@ -567,7 +546,6 @@ scale_interval(unsigned requested)
567 r = (unsigned)random() % (unsigned)(MAX(5, interval / 10)); 546 r = (unsigned)random() % (unsigned)(MAX(5, interval / 10));
568 return (interval + r); 547 return (interval + r);
569} 548}
570
571static void 549static void
572recv_and_process_peer_pkt(ntp_peer_t *p) 550recv_and_process_peer_pkt(ntp_peer_t *p)
573{ 551{
@@ -631,7 +609,7 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
631 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2. 609 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2.
632 */ 610 */
633 611
634 T4 = gettime1900fp(); 612 T4 = gettime1900d();
635 T1 = p->xmttime; 613 T1 = p->xmttime;
636 T2 = lfp_to_d(msg.m_rectime); 614 T2 = lfp_to_d(msg.m_rectime);
637 T3 = lfp_to_d(msg.m_xmttime); 615 T3 = lfp_to_d(msg.m_xmttime);
@@ -668,7 +646,6 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
668 interval = scale_interval(INTERVAL_QUERY_NORMAL); 646 interval = scale_interval(INTERVAL_QUERY_NORMAL);
669 647
670 set_next(p, interval); 648 set_next(p, interval);
671 p->state = STATE_REPLY_RECEIVED;
672 649
673 /* every received reply which we do not discard increases trust */ 650 /* every received reply which we do not discard increases trust */
674 if (p->trustlevel < TRUSTLEVEL_MAX) { 651 if (p->trustlevel < TRUSTLEVEL_MAX) {
@@ -690,7 +667,7 @@ recv_and_process_peer_pkt(ntp_peer_t *p)
690 p->shift = 0; 667 p->shift = 0;
691 668
692 close_sock: 669 close_sock:
693 /* We do not expect any more packets for now. 670 /* We do not expect any more packets from this peer for now.
694 * Closing the socket informs kernel about it. 671 * Closing the socket informs kernel about it.
695 * We open a new socket when we send a new query. 672 * We open a new socket when we send a new query.
696 */ 673 */
@@ -723,10 +700,10 @@ recv_and_process_client_pkt(void /*int fd*/)
723 if (size < 0) { 700 if (size < 0) {
724 if (errno == EAGAIN) 701 if (errno == EAGAIN)
725 goto bail; 702 goto bail;
726 bb_perror_msg_and_die("recv_from_to"); 703 bb_perror_msg_and_die("recv");
727 } 704 }
728 addr = xmalloc_sockaddr2dotted_noport(from); 705 addr = xmalloc_sockaddr2dotted_noport(from);
729 bb_error_msg("malformed packet received from %s", addr); 706 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size);
730 free(addr); 707 free(addr);
731 goto bail; 708 goto bail;
732 } 709 }
@@ -743,11 +720,11 @@ recv_and_process_client_pkt(void /*int fd*/)
743 MODE_SERVER : MODE_SYM_PAS; 720 MODE_SERVER : MODE_SYM_PAS;
744 msg.m_stratum = G.stratum; 721 msg.m_stratum = G.stratum;
745 msg.m_ppoll = query_ppoll; 722 msg.m_ppoll = query_ppoll;
746 msg.m_precision = G.precision; 723 msg.m_precision = G_precision;
747 rectime = gettime1900fp(); 724 rectime = gettime1900d();
748 msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime); 725 msg.m_xmttime = msg.m_rectime = d_to_lfp(rectime);
749 msg.m_reftime = d_to_lfp(G.reftime); 726 msg.m_reftime = d_to_lfp(G.reftime);
750 //msg.m_xmttime = d_to_lfp(gettime1900fp()); // = msg.m_rectime 727 //msg.m_xmttime = d_to_lfp(gettime1900d()); // = msg.m_rectime
751 msg.m_orgtime = query_xmttime; 728 msg.m_orgtime = query_xmttime;
752 msg.m_rootdelay = d_to_sfp(G.rootdelay); 729 msg.m_rootdelay = d_to_sfp(G.rootdelay);
753 version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ 730 version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */
@@ -859,7 +836,6 @@ static NOINLINE void ntp_init(char **argv)
859 llist_t *peers; 836 llist_t *peers;
860 837
861 srandom(getpid()); 838 srandom(getpid());
862 /* tzset(); - why? it's called automatically when needed, no? */
863 839
864 if (getuid()) 840 if (getuid())
865 bb_error_msg_and_die(bb_msg_you_must_be_root); 841 bb_error_msg_and_die(bb_msg_you_must_be_root);
@@ -867,16 +843,15 @@ static NOINLINE void ntp_init(char **argv)
867 peers = NULL; 843 peers = NULL;
868 opt_complementary = "dd:p::"; /* d: counter, p: list */ 844 opt_complementary = "dd:p::"; /* d: counter, p: list */
869 opts = getopt32(argv, 845 opts = getopt32(argv,
870 "ngqN" /* compat */ 846 "nqNx" /* compat */
871 "p:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ 847 "p:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */
872 "d" /* compat */ 848 "d" /* compat */
873 "46aAbLx", /* compat, ignored */ 849 "46aAbgL", /* compat, ignored */
874 &peers, &G.verbose); 850 &peers, &G.verbose);
875 if (!(opts & (OPT_p|OPT_l))) 851 if (!(opts & (OPT_p|OPT_l)))
876 bb_show_usage(); 852 bb_show_usage();
877//WRONG 853 if (opts & OPT_x) /* disable stepping, only slew is allowed */
878// if (opts & OPT_g) 854 G.time_is_stepped = 1;
879// G.time_is_stepped = 1;
880 while (peers) 855 while (peers)
881 add_peers(llist_pop(&peers)); 856 add_peers(llist_pop(&peers));
882 if (!(opts & OPT_n)) { 857 if (!(opts & OPT_n)) {
@@ -896,23 +871,28 @@ static NOINLINE void ntp_init(char **argv)
896 setpriority(PRIO_PROCESS, 0, -15); 871 setpriority(PRIO_PROCESS, 0, -15);
897 872
898 /* Set some globals */ 873 /* Set some globals */
874#if 0
875 /* With constant b = 100, G.precision is also constant -6.
876 * Uncomment this and you'll see */
899 { 877 {
900 int prec = 0; 878 int prec = 0;
901 int b; 879 int b;
902#if 0 880# if 0
903 struct timespec tp; 881 struct timespec tp;
904 /* We can use sys_clock_getres but assuming 10ms tick should be fine */ 882 /* We can use sys_clock_getres but assuming 10ms tick should be fine */
905 clock_getres(CLOCK_REALTIME, &tp); 883 clock_getres(CLOCK_REALTIME, &tp);
906 tp.tv_sec = 0; 884 tp.tv_sec = 0;
907 tp.tv_nsec = 10000000; 885 tp.tv_nsec = 10000000;
908 b = 1000000000 / tp.tv_nsec; /* convert to Hz */ 886 b = 1000000000 / tp.tv_nsec; /* convert to Hz */
909#else 887# else
910 b = 100; /* b = 1000000000/10000000 = 100 */ 888 b = 100; /* b = 1000000000/10000000 = 100 */
911#endif 889# endif
912 while (b > 1) 890 while (b > 1)
913 prec--, b >>= 1; 891 prec--, b >>= 1;
914 G.precision = prec; 892 //G.precision = prec;
893 bb_error_msg("G.precision:%d", prec); /* -6 */
915 } 894 }
895#endif
916 G.scale = 1; 896 G.scale = 1;
917 897
918 bb_signals((1 << SIGTERM) | (1 << SIGINT), record_signo); 898 bb_signals((1 << SIGTERM) | (1 << SIGINT), record_signo);
@@ -963,31 +943,33 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
963 for (item = g.ntp_peers; item != NULL; item = item->link) { 943 for (item = g.ntp_peers; item != NULL; item = item->link) {
964 ntp_peer_t *p = (ntp_peer_t *) item->data; 944 ntp_peer_t *p = (ntp_peer_t *) item->data;
965 945
966 if (p->next != 0 && p->next <= cur_time) { 946 /* Overflow-safe "if (p->next_action_time <= cur_time) ..." */
967 /* Time to send new req */ 947 if ((int)(cur_time - p->next_action_time) >= 0) {
968 trial_cnt++; 948 if (p->fd == -1) {
969 if (send_query_to_peer(p) == 0) 949 /* Time to send new req */
970 sent_cnt++; 950 trial_cnt++;
971 } 951 if (send_query_to_peer(p) == 0)
972 if (p->deadline != 0 && p->deadline <= cur_time) { 952 sent_cnt++;
973 /* Timed out waiting for reply */ 953 } else {
974 timeout = error_interval(); 954 /* Timed out waiting for reply */
975 bb_error_msg("timed out waiting for %s, " 955 close(p->fd);
976 "next query in %us", p->dotted, timeout); 956 p->fd = -1;
977 if (p->trustlevel >= TRUSTLEVEL_BADPEER) { 957 timeout = error_interval();
978 p->trustlevel /= 2; 958 bb_error_msg("timed out waiting for %s, "
979 if (p->trustlevel < TRUSTLEVEL_BADPEER) 959 "next query in %us", p->dotted, timeout);
980 bb_error_msg("peer %s now invalid", p->dotted); 960 if (p->trustlevel >= TRUSTLEVEL_BADPEER) {
961 p->trustlevel /= 2;
962 if (p->trustlevel < TRUSTLEVEL_BADPEER)
963 bb_error_msg("peer %s now invalid", p->dotted);
964 }
965 set_next(p, timeout);
981 } 966 }
982 set_next(p, timeout);
983 } 967 }
984 968
985 if (p->next != 0 && p->next < nextaction) 969 if (p->next_action_time < nextaction)
986 nextaction = p->next; 970 nextaction = p->next_action_time;
987 if (p->deadline != 0 && p->deadline < nextaction)
988 nextaction = p->deadline;
989 971
990 if (p->state == STATE_QUERY_SENT) { 972 if (p->fd >= 0) {
991 /* Wait for reply from this peer */ 973 /* Wait for reply from this peer */
992 pfd[i].fd = p->fd; 974 pfd[i].fd = p->fd;
993 pfd[i].events = POLLIN; 975 pfd[i].events = POLLIN;
@@ -1005,7 +987,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
1005 987
1006 /* Here we may block */ 988 /* Here we may block */
1007 if (g.verbose >= 2) 989 if (g.verbose >= 2)
1008 bb_error_msg("poll %u sec, sockets:%u", timeout, i); 990 bb_error_msg("poll %us, sockets:%u", timeout, i);
1009 nfds = poll(pfd, i, timeout * 1000); 991 nfds = poll(pfd, i, timeout * 1000);
1010 if (nfds <= 0) 992 if (nfds <= 0)
1011 continue; 993 continue;