Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/networking/ntpd.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/networking/ntpd.c
r2725 r3232 28 28 *********************************************************************** 29 29 */ 30 31 //usage:#define ntpd_trivial_usage 32 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l")"] [-S PROG] [-p PEER]..." 33 //usage:#define ntpd_full_usage "\n\n" 34 //usage: "NTP client/server\n" 35 //usage: "\n -d Verbose" 36 //usage: "\n -n Do not daemonize" 37 //usage: "\n -q Quit after clock is set" 38 //usage: "\n -N Run at high priority" 39 //usage: "\n -w Do not set time (only query peers), implies -n" 40 //usage: IF_FEATURE_NTPD_SERVER( 41 //usage: "\n -l Run as server on port 123" 42 //usage: ) 43 //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" 44 //usage: "\n -p PEER Obtain time from PEER (may be repeated)" 45 30 46 #include "libbb.h" 31 47 #include <math.h> 32 48 #include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ 49 #include <sys/resource.h> /* setpriority */ 33 50 #include <sys/timex.h> 34 51 #ifndef IPTOS_LOWDELAY … … 92 109 #define BURSTPOLL 0 /* initial poll */ 93 110 #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ 94 #define BIGPOLL 10 /* drop to lower poll at any trouble (10: 17 min) */ 111 /* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL, 112 * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_). 113 */ 114 #define BIGPOLL 10 /* 2^10 sec ~= 17 min */ 95 115 #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ 96 116 /* Actively lower poll when we see such big offsets. 97 117 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively 98 * if offset increases over 0.03sec */99 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 4)118 * if offset increases over ~0.04 sec */ 119 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) 100 120 #define MINDISP 0.01 /* minimum dispersion (sec) */ 101 121 #define MAXDISP 16 /* maximum dispersion (sec) */ … … 109 129 /* Poll-adjust threshold. 110 130 * When we see that offset is small enough compared to discipline jitter, 111 * we grow a counter: += MINPOLL. When itgoes over POLLADJ_LIMIT,131 * we grow a counter: += MINPOLL. When counter goes over POLLADJ_LIMIT, 112 132 * we poll_exp++. If offset isn't small, counter -= poll_exp*2, 113 * and when it goes below -POLLADJ_LIMIT, we poll_exp-- 114 * ( bumped from 30 to 36since otherwise I often see poll_exp going *2* steps down)133 * and when it goes below -POLLADJ_LIMIT, we poll_exp--. 134 * (Bumped from 30 to 40 since otherwise I often see poll_exp going *2* steps down) 115 135 */ 116 #define POLLADJ_LIMIT 36117 /* If offset < POLLADJ_GATE * discipline_jitter, then we canincrease136 #define POLLADJ_LIMIT 40 137 /* If offset < discipline_jitter * POLLADJ_GATE, then we decide to increase 118 138 * poll interval (we think we can't improve timekeeping 119 139 * by staying at smaller poll). 120 140 */ 121 141 #define POLLADJ_GATE 4 142 #define TIMECONST_HACK_GATE 2 122 143 /* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ 123 144 #define ALLAN 512 … … 193 214 194 215 typedef struct { 216 double d_offset; 195 217 double d_recv_time; 196 double d_offset;197 218 double d_dispersion; 198 219 } datapoint_t; … … 201 222 len_and_sockaddr *p_lsa; 202 223 char *p_dotted; 203 /* when to send new query (if p_fd == -1)204 * or when receive times out (if p_fd >= 0): */205 224 int p_fd; 206 225 int datapoint_idx; … … 209 228 uint8_t lastpkt_stratum; 210 229 uint8_t reachable_bits; 230 /* when to send new query (if p_fd == -1) 231 * or when receive times out (if p_fd >= 0): */ 211 232 double next_action_time; 212 233 double p_xmttime; … … 239 260 OPT_S = (1 << 6), 240 261 OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER, 262 /* We hijack some bits for other purposes */ 263 OPT_qq = (1 << 31), 241 264 }; 242 265 … … 255 278 #if ENABLE_FEATURE_NTPD_SERVER 256 279 int listen_fd; 280 # define G_listen_fd (G.listen_fd) 281 #else 282 # define G_listen_fd (-1) 257 283 #endif 258 284 unsigned verbose; 259 285 unsigned peer_cnt; 260 286 /* refid: 32-bit code identifying the particular server or reference clock 261 * in stratum 0 packets this is a four-character ASCII string, 262 * called the kiss code, used for debugging and monitoring 263 * in stratum 1 packets this is a four-character ASCII string 264 * assigned to the reference clock by IANA. Example: "GPS " 265 * in stratum 2+ packets, it's IPv4 address or 4 first bytes of MD5 hash of IPv6 287 * in stratum 0 packets this is a four-character ASCII string, 288 * called the kiss code, used for debugging and monitoring 289 * in stratum 1 packets this is a four-character ASCII string 290 * assigned to the reference clock by IANA. Example: "GPS " 291 * in stratum 2+ packets, it's IPv4 address or 4 first bytes 292 * of MD5 hash of IPv6 266 293 */ 267 294 uint32_t refid; … … 272 299 * system clock hardware representation is to the nanosecond. 273 300 * 274 * Delays, jitters of various kinds are clampe rdown to precision.301 * Delays, jitters of various kinds are clamped down to precision. 275 302 * 276 303 * If precision_sec is too large, discipline_jitter gets clamped to it 277 * and if offset is much smaller than discipline_jitter, poll interval278 * grows even though we really can benefit from staying at smaller one,279 * collecting non-lagged datapoits and correcting theoffset.304 * and if offset is smaller than discipline_jitter * POLLADJ_GATE, poll 305 * interval grows even though we really can benefit from staying at 306 * smaller one, collecting non-lagged datapoits and correcting offset. 280 307 * (Lagged datapoits exist when poll_exp is large but we still have 281 308 * systematic offset error - the time distance between datapoints 282 * is significa t and older datapoints have smaller offsets.309 * is significant and older datapoints have smaller offsets. 283 310 * This makes our offset estimation a bit smaller than reality) 284 311 * Due to this effect, setting G_precision_sec close to … … 286 313 * too big and we will step. I observed it with -6. 287 314 * 288 * OTOH, setting precision too small would result in futile attempts289 * to syncronize to theunachievable precision.315 * OTOH, setting precision_sec far too small would result in futile 316 * attempts to syncronize to an unachievable precision. 290 317 * 291 318 * -6 is 1/64 sec, -7 is 1/128 sec and so on. 292 */ 293 #define G_precision_exp -8 294 #define G_precision_sec (1.0 / (1 << (- G_precision_exp))) 319 * -8 is 1/256 ~= 0.003906 (worked well for me --vda) 320 * -9 is 1/512 ~= 0.001953 (let's try this for some time) 321 */ 322 #define G_precision_exp -9 323 /* 324 * G_precision_exp is used only for construction outgoing packets. 325 * It's ok to set G_precision_sec to a slightly different value 326 * (One which is "nicer looking" in logs). 327 * Exact value would be (1.0 / (1 << (- G_precision_exp))): 328 */ 329 #define G_precision_sec 0.002 295 330 uint8_t stratum; 296 331 /* Bool. After set to 1, never goes back to 0: */ … … 310 345 double last_update_recv_time; // s.t 311 346 double discipline_jitter; // c.jitter 347 /* Since we only compare it with ints, can simplify code 348 * by not making this variable floating point: 349 */ 350 unsigned offset_to_jitter_ratio; 312 351 //double cluster_offset; // s.offset 313 352 //double cluster_jitter; // s.jitter … … 483 522 { 484 523 int i, idx; 524 double sum, wavg; 525 datapoint_t *fdp; 526 527 #if 0 528 /* Simulations have shown that use of *averaged* offset for p->filter_offset 529 * is in fact worse than simply using last received one: with large poll intervals 530 * (>= 2048) averaging code uses offset values which are outdated by hours, 531 * and time/frequency correction goes totally wrong when fed essentially bogus offsets. 532 */ 485 533 int got_newest; 486 double minoff, maxoff, w avg, sum, w;534 double minoff, maxoff, w; 487 535 double x = x; /* for compiler */ 488 536 double oldest_off = oldest_off; … … 491 539 double newest_age = newest_age; 492 540 493 minoff = maxoff = p->filter_datapoint[0].d_offset; 541 fdp = p->filter_datapoint; 542 543 minoff = maxoff = fdp[0].d_offset; 494 544 for (i = 1; i < NUM_DATAPOINTS; i++) { 495 if (minoff > p->filter_datapoint[i].d_offset)496 minoff = p->filter_datapoint[i].d_offset;497 if (maxoff < p->filter_datapoint[i].d_offset)498 maxoff = p->filter_datapoint[i].d_offset;499 } 500 501 idx = p->datapoint_idx; /* most recent datapoint */545 if (minoff > fdp[i].d_offset) 546 minoff = fdp[i].d_offset; 547 if (maxoff < fdp[i].d_offset) 548 maxoff = fdp[i].d_offset; 549 } 550 551 idx = p->datapoint_idx; /* most recent datapoint's index */ 502 552 /* Average offset: 503 553 * Drop two outliers and take weighted average of the rest: … … 521 571 bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", 522 572 i, 523 p->filter_datapoint[idx].d_offset,524 p->filter_datapoint[idx].d_dispersion, dispersion(&p->filter_datapoint[idx]),525 G.cur_time - p->filter_datapoint[idx].d_recv_time,526 (minoff == p->filter_datapoint[idx].d_offset || maxoff == p->filter_datapoint[idx].d_offset)573 fdp[idx].d_offset, 574 fdp[idx].d_dispersion, dispersion(&fdp[idx]), 575 G.cur_time - fdp[idx].d_recv_time, 576 (minoff == fdp[idx].d_offset || maxoff == fdp[idx].d_offset) 527 577 ? " (outlier by offset)" : "" 528 578 ); 529 579 } 530 580 531 sum += dispersion(& p->filter_datapoint[idx]) / (2 << i);532 533 if (minoff == p->filter_datapoint[idx].d_offset) {581 sum += dispersion(&fdp[idx]) / (2 << i); 582 583 if (minoff == fdp[idx].d_offset) { 534 584 minoff -= 1; /* so that we don't match it ever again */ 535 585 } else 536 if (maxoff == p->filter_datapoint[idx].d_offset) {586 if (maxoff == fdp[idx].d_offset) { 537 587 maxoff += 1; 538 588 } else { 539 oldest_off = p->filter_datapoint[idx].d_offset;540 oldest_age = G.cur_time - p->filter_datapoint[idx].d_recv_time;589 oldest_off = fdp[idx].d_offset; 590 oldest_age = G.cur_time - fdp[idx].d_recv_time; 541 591 if (!got_newest) { 542 592 got_newest = 1; … … 570 620 } 571 621 p->filter_offset = wavg; 622 623 #else 624 625 fdp = p->filter_datapoint; 626 idx = p->datapoint_idx; /* most recent datapoint's index */ 627 628 /* filter_offset: simply use the most recent value */ 629 p->filter_offset = fdp[idx].d_offset; 630 631 /* n-1 632 * --- dispersion(i) 633 * filter_dispersion = \ ------------- 634 * / (i+1) 635 * --- 2 636 * i=0 637 */ 638 wavg = 0; 639 sum = 0; 640 for (i = 0; i < NUM_DATAPOINTS; i++) { 641 sum += dispersion(&fdp[idx]) / (2 << i); 642 wavg += fdp[idx].d_offset; 643 idx = (idx - 1) & (NUM_DATAPOINTS - 1); 644 } 645 wavg /= NUM_DATAPOINTS; 646 p->filter_dispersion = sum; 647 #endif 572 648 573 649 /* +----- -----+ ^ 1/2 … … 584 660 sum = 0; 585 661 for (i = 0; i < NUM_DATAPOINTS; i++) { 586 sum += SQUARE(wavg - p->filter_datapoint[i].d_offset);662 sum += SQUARE(wavg - fdp[i].d_offset); 587 663 } 588 664 sum = SQRT(sum / NUM_DATAPOINTS); 589 665 p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; 590 666 591 VERB3 bb_error_msg("filter offset:% f(corr:%e)disp:%f jitter:%f",592 p->filter_offset, x,667 VERB3 bb_error_msg("filter offset:%+f disp:%f jitter:%f", 668 p->filter_offset, 593 669 p->filter_dispersion, 594 670 p->filter_jitter); … … 605 681 p->filter_datapoint[i].d_recv_time += offset; 606 682 if (p->filter_datapoint[i].d_offset != 0) { 607 p->filter_datapoint[i].d_offset += offset; 683 p->filter_datapoint[i].d_offset -= offset; 684 //bb_error_msg("p->filter_datapoint[%d].d_offset %f -> %f", 685 // i, 686 // p->filter_datapoint[i].d_offset + offset, 687 // p->filter_datapoint[i].d_offset); 608 688 } 609 689 } else { … … 702 782 } 703 783 784 /* Emit message _before_ attempted send. Think of a very short 785 * roundtrip networks: we need to go back to recv loop ASAP, 786 * to reduce delay. Printing messages after send works against that. 787 */ 788 VERB1 bb_error_msg("sending query to %s", p->p_dotted); 789 704 790 /* 705 791 * Send out a random 64-bit number as our transmit time. The NTP … … 729 815 730 816 p->reachable_bits <<= 1; 731 VERB1 bb_error_msg("sent query to %s", p->p_dotted);732 817 set_next(p, RESPONSE_INTERVAL); 733 818 } … … 791 876 llist_t *item; 792 877 double dtime; 793 struct timeval tv ;794 char buf[ 80];878 struct timeval tvc, tvn; 879 char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4]; 795 880 time_t tval; 796 881 797 gettimeofday(&tv, NULL); /* never fails */ 798 dtime = offset + tv.tv_sec; 799 dtime += 1.0e-6 * tv.tv_usec; 800 d_to_tv(dtime, &tv); 801 802 if (settimeofday(&tv, NULL) == -1) 882 gettimeofday(&tvc, NULL); /* never fails */ 883 dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; 884 d_to_tv(dtime, &tvn); 885 if (settimeofday(&tvn, NULL) == -1) 803 886 bb_perror_msg_and_die("settimeofday"); 804 887 805 tval = tv.tv_sec; 806 strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", localtime(&tval)); 807 808 bb_error_msg("setting clock to %s (offset %fs)", buf, offset); 888 VERB2 { 889 tval = tvc.tv_sec; 890 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 891 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec); 892 } 893 tval = tvn.tv_sec; 894 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 895 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 809 896 810 897 /* Correct various fields which contain time-relative values: */ 898 899 /* Globals: */ 900 G.cur_time += offset; 901 G.last_update_recv_time += offset; 902 G.last_script_run += offset; 811 903 812 904 /* p->lastpkt_recv_time, p->next_action_time and such: */ … … 814 906 peer_t *pp = (peer_t *) item->data; 815 907 reset_peer_stats(pp, offset); 816 //bb_error_msg("offset:% f pp->next_action_time:%f -> %f",908 //bb_error_msg("offset:%+f pp->next_action_time:%f -> %f", 817 909 // offset, pp->next_action_time, pp->next_action_time + offset); 818 910 pp->next_action_time += offset; 819 } 820 /* Globals: */ 821 G.cur_time += offset; 822 G.last_update_recv_time += offset; 823 G.last_script_run += offset; 911 if (pp->p_fd >= 0) { 912 /* We wait for reply from this peer too. 913 * But due to step we are doing, reply's data is no longer 914 * useful (in fact, it'll be bogus). Stop waiting for it. 915 */ 916 close(pp->p_fd); 917 pp->p_fd = -1; 918 set_next(pp, RETRY_INTERVAL); 919 } 920 } 824 921 } 825 922 … … 883 980 // if (p->refid == p->dstaddr || p->refid == s.refid) 884 981 // return 0; 885 982 return 1; 886 983 } 887 984 static peer_t* … … 1150 1247 G.last_update_peer = p; 1151 1248 keep_old: 1152 VERB3 bb_error_msg("selected peer %s filter_offset:% f age:%f",1249 VERB3 bb_error_msg("selected peer %s filter_offset:%+f age:%f", 1153 1250 p->p_dotted, 1154 1251 p->filter_offset, … … 1241 1338 case STATE_SYNC: 1242 1339 /* The first outlyer: ignore it, switch to SPIK state */ 1243 VERB3 bb_error_msg("offset:% f - spike detected", offset);1340 VERB3 bb_error_msg("offset:%+f - spike detected", offset); 1244 1341 G.discipline_state = STATE_SPIK; 1245 1342 return -1; /* "decrease poll interval" */ … … 1278 1375 * intervals. 1279 1376 */ 1280 VERB3 bb_error_msg("stepping time by % f; poll_exp=MINPOLL", offset);1377 VERB3 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); 1281 1378 step_time(offset); 1282 1379 if (option_mask32 & OPT_q) { … … 1297 1394 } 1298 1395 #endif 1299 set_new_values(STATE_SYNC, /*offset:*/ 0, recv_time); 1396 abs_offset = offset = 0; 1397 set_new_values(STATE_SYNC, offset, recv_time); 1300 1398 1301 1399 } else { /* abs_offset <= STEP_THRESHOLD */ 1302 1400 1303 1401 if (G.poll_exp < MINPOLL && G.initial_poll_complete) { 1304 VERB3 bb_error_msg("small offset:% f, disabling burst mode", offset);1402 VERB3 bb_error_msg("small offset:%+f, disabling burst mode", offset); 1305 1403 G.polladj_count = 0; 1306 1404 G.poll_exp = MINPOLL; … … 1311 1409 */ 1312 1410 etemp = SQUARE(G.discipline_jitter); 1313 dtemp = SQUARE( MAXD(fabs(offset - G.last_update_offset), G_precision_sec));1411 dtemp = SQUARE(offset - G.last_update_offset); 1314 1412 G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); 1315 VERB3 bb_error_msg("discipline jitter=%f", G.discipline_jitter);1316 1413 1317 1414 switch (G.discipline_state) { … … 1390 1487 } 1391 1488 1489 if (G.discipline_jitter < G_precision_sec) 1490 G.discipline_jitter = G_precision_sec; 1491 G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter; 1492 1392 1493 G.reftime = G.cur_time; 1393 1494 G.ntp_status = p->lastpkt_status; … … 1401 1502 /* We are in STATE_SYNC now, but did not do adjtimex yet. 1402 1503 * (Any other state does not reach this, they all return earlier) 1403 * By this time, freq_drift and G.last_update_offset are set1504 * By this time, freq_drift and offset are set 1404 1505 * to values suitable for adjtimex. 1405 1506 */ … … 1427 1528 if (adjtimex(&tmx) < 0) 1428 1529 bb_perror_msg_and_die("adjtimex"); 1429 VERB3 bb_error_msg("p adjtimex freq:%ld offset:%ld constant:%ld status:0x%x",1430 tmx.freq, tmx.offset, tmx. constant, tmx.status);1530 bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", 1531 tmx.freq, tmx.offset, tmx.status, tmx.constant); 1431 1532 } 1432 1533 … … 1440 1541 /* 65536 is one ppm */ 1441 1542 tmx.freq = G.discipline_freq_drift * 65536e6; 1442 tmx.offset = G.last_update_offset * 1000000; /* usec */1443 1543 #endif 1444 1544 tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; 1445 tmx.offset = (G.last_update_offset * 1000000); /* usec */ 1446 /* + (G.last_update_offset < 0 ? -0.5 : 0.5) - too small to bother */ 1545 tmx.offset = (offset * 1000000); /* usec */ 1447 1546 tmx.status = STA_PLL; 1448 1547 if (G.ntp_status & LI_PLUSSEC) … … 1450 1549 if (G.ntp_status & LI_MINUSSEC) 1451 1550 tmx.status |= STA_DEL; 1551 1452 1552 tmx.constant = G.poll_exp - 4; 1453 //tmx.esterror = (u_int32)(clock_jitter * 1e6); 1454 //tmx.maxerror = (u_int32)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); 1553 /* EXPERIMENTAL. 1554 * The below if statement should be unnecessary, but... 1555 * It looks like Linux kernel's PLL is far too gentle in changing 1556 * tmx.freq in response to clock offset. Offset keeps growing 1557 * and eventually we fall back to smaller poll intervals. 1558 * We can make correction more agressive (about x2) by supplying 1559 * PLL time constant which is one less than the real one. 1560 * To be on a safe side, let's do it only if offset is significantly 1561 * larger than jitter. 1562 */ 1563 if (tmx.constant > 0 && G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) 1564 tmx.constant--; 1565 1566 //tmx.esterror = (uint32_t)(clock_jitter * 1e6); 1567 //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); 1455 1568 rc = adjtimex(&tmx); 1456 1569 if (rc < 0) … … 1459 1572 * Not sure why. Perhaps it is normal. 1460 1573 */ 1461 VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%ld constant:%ld status:0x%x", 1462 rc, tmx.freq, tmx.offset, tmx.constant, tmx.status); 1463 #if 0 1464 VERB3 { 1465 /* always gives the same output as above msg */ 1466 memset(&tmx, 0, sizeof(tmx)); 1467 if (adjtimex(&tmx) < 0) 1468 bb_perror_msg_and_die("adjtimex"); 1469 VERB3 bb_error_msg("c adjtimex freq:%ld offset:%ld constant:%ld status:0x%x", 1470 tmx.freq, tmx.offset, tmx.constant, tmx.status); 1471 } 1472 #endif 1574 VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", 1575 rc, tmx.freq, tmx.offset, tmx.status); 1473 1576 G.kernel_freq_drift = tmx.freq / 65536; 1474 VERB2 bb_error_msg("update peer:%s, offset:%f, clock drift:%ld ppm",1475 p->p_dotted, G.last_update_offset, G.kernel_freq_drift);1577 VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", 1578 p->p_dotted, offset, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant); 1476 1579 1477 1580 return 1; /* "ok to increase poll interval" */ … … 1532 1635 //TODO: always do this? 1533 1636 interval = retry_interval(); 1534 goto set_next_and_ close_sock;1637 goto set_next_and_ret; 1535 1638 } 1536 1639 xfunc_die(); … … 1539 1642 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { 1540 1643 bb_error_msg("malformed packet received from %s", p->p_dotted); 1541 goto bail;1644 return; 1542 1645 } 1543 1646 … … 1545 1648 || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl 1546 1649 ) { 1547 goto bail; 1548 } 1650 /* Somebody else's packet */ 1651 return; 1652 } 1653 1654 /* We do not expect any more packets from this peer for now. 1655 * Closing the socket informs kernel about it. 1656 * We open a new socket when we send a new query. 1657 */ 1658 close(p->p_fd); 1659 p->p_fd = -1; 1549 1660 1550 1661 if ((msg.m_status & LI_ALARM) == LI_ALARM … … 1556 1667 // "RATE" - peer is overloaded, reduce polling freq 1557 1668 interval = poll_interval(0); 1558 bb_error_msg("reply from %s: notsynced, next query in %us", p->p_dotted, interval);1559 goto set_next_and_ close_sock;1669 bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); 1670 goto set_next_and_ret; 1560 1671 } 1561 1672 … … 1609 1720 /* 1st datapoint ever - replicate offset in every element */ 1610 1721 int i; 1611 for (i = 1; i < NUM_DATAPOINTS; i++) {1722 for (i = 0; i < NUM_DATAPOINTS; i++) { 1612 1723 p->filter_datapoint[i].d_offset = datapoint->d_offset; 1613 1724 } … … 1616 1727 p->reachable_bits |= 1; 1617 1728 if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { 1618 bb_error_msg("reply from %s: reach 0x%02x offset %f delay %f status 0x%02x strat %d refid 0x%08x rootdelay %f",1729 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 1619 1730 p->p_dotted, 1620 p->reachable_bits,1621 1731 datapoint->d_offset, 1622 1732 p->lastpkt_delay, … … 1624 1734 p->lastpkt_stratum, 1625 1735 p->lastpkt_refid, 1626 p->lastpkt_rootdelay 1736 p->lastpkt_rootdelay, 1737 p->reachable_bits 1627 1738 /* not shown: m_ppoll, m_precision_exp, m_rootdisp, 1628 1739 * m_reftime, m_orgtime, m_rectime, m_xmttime … … 1643 1754 */ 1644 1755 if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { 1645 VERB3 bb_error_msg("offset:% f > POLLDOWN_OFFSET", q->filter_offset);1756 VERB3 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1646 1757 goto poll_down; 1647 1758 } … … 1657 1768 * helps calm the dance. Works best using burst mode. 1658 1769 */ 1659 VERB4 if (rc > 0) { 1660 bb_error_msg("offset:%f POLLADJ_GATE*discipline_jitter:%f poll:%s", 1661 q->filter_offset, POLLADJ_GATE * G.discipline_jitter, 1662 fabs(q->filter_offset) < POLLADJ_GATE * G.discipline_jitter 1663 ? "grows" : "falls" 1664 ); 1665 } 1666 if (rc > 0 && fabs(q->filter_offset) < POLLADJ_GATE * G.discipline_jitter) { 1770 if (rc > 0 && G.offset_to_jitter_ratio <= POLLADJ_GATE) { 1667 1771 /* was += G.poll_exp but it is a bit 1668 1772 * too optimistic for my taste at high poll_exp's */ … … 1710 1814 interval = poll_interval(0); 1711 1815 1712 set_next_and_ close_sock:1816 set_next_and_ret: 1713 1817 set_next(p, interval); 1714 /* We do not expect any more packets from this peer for now.1715 * Closing the socket informs kernel about it.1716 * We open a new socket when we send a new query.1717 */1718 close(p->p_fd);1719 p->p_fd = -1;1720 bail:1721 return;1722 1818 } 1723 1819 … … 1727 1823 { 1728 1824 ssize_t size; 1729 uint8_t version;1825 //uint8_t version; 1730 1826 len_and_sockaddr *to; 1731 1827 struct sockaddr *from; … … 1734 1830 l_fixedpt_t query_xmttime; 1735 1831 1736 to = get_sock_lsa(G .listen_fd);1832 to = get_sock_lsa(G_listen_fd); 1737 1833 from = xzalloc(to->len); 1738 1834 1739 size = recv_from_to(G .listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);1835 size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len); 1740 1836 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { 1741 1837 char *addr; … … 1756 1852 /* Build a reply packet */ 1757 1853 memset(&msg, 0, sizeof(msg)); 1758 msg.m_status = G.stratum < MAXSTRAT ? G.ntp_status: LI_ALARM;1854 msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM; 1759 1855 msg.m_status |= (query_status & VERSION_MASK); 1760 1856 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? 1761 1857 MODE_SERVER : MODE_SYM_PAS; 1762 1858 msg.m_stratum = G.stratum; 1763 1859 msg.m_ppoll = G.poll_exp; … … 1775 1871 //simple code does not do this, fix simple code! 1776 1872 msg.m_rootdisp = d_to_sfp(G.rootdisp); 1777 version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */1873 //version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ 1778 1874 msg.m_refid = G.refid; // (version > (3 << VERSION_SHIFT)) ? G.refid : G.refid3; 1779 1875 1780 1876 /* We reply from the local address packet was sent to, 1781 1877 * this makes to/from look swapped here: */ 1782 do_sendto(G .listen_fd,1878 do_sendto(G_listen_fd, 1783 1879 /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, 1784 1880 &msg, size); … … 1919 2015 } 1920 2016 #if ENABLE_FEATURE_NTPD_SERVER 1921 G .listen_fd = -1;2017 G_listen_fd = -1; 1922 2018 if (opts & OPT_l) { 1923 G .listen_fd = create_and_bind_dgram_or_die(NULL, 123);1924 socket_want_pktinfo(G .listen_fd);1925 setsockopt(G .listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));2019 G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); 2020 socket_want_pktinfo(G_listen_fd); 2021 setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); 1926 2022 } 1927 2023 #endif … … 1931 2027 1932 2028 /* If network is up, syncronization occurs in ~10 seconds. 1933 * We give "ntpd -q" a full minute to finish, then we exit. 2029 * We give "ntpd -q" 10 seconds to get first reply, 2030 * then another 50 seconds to finish syncing. 1934 2031 * 1935 2032 * I tested ntpd 4.2.6p1 and apparently it never exits … … 1938 2035 * after a reasonably small period of polling, or fail. 1939 2036 */ 1940 if (opts & OPT_q) 1941 alarm(60); 2037 if (opts & OPT_q) { 2038 option_mask32 |= OPT_qq; 2039 alarm(10); 2040 } 1942 2041 1943 2042 bb_signals(0 … … 1982 2081 cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); 1983 2082 2083 write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); 2084 1984 2085 while (!bb_got_signal) { 1985 2086 llist_t *item; … … 1994 2095 i = 0; 1995 2096 #if ENABLE_FEATURE_NTPD_SERVER 1996 if (G .listen_fd != -1) {1997 pfd[0].fd = G .listen_fd;2097 if (G_listen_fd != -1) { 2098 pfd[0].fd = G_listen_fd; 1998 2099 pfd[0].events = POLLIN; 1999 2100 i++; … … 2040 2141 2041 2142 /* Here we may block */ 2042 VERB2 bb_error_msg("poll %us, sockets:%u, poll interval:%us", timeout, i, 1 << G.poll_exp); 2143 VERB2 { 2144 if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) { 2145 /* We wait for at least one reply. 2146 * Poll for it, without wasting time for message. 2147 * Since replies often come under 1 second, this also 2148 * reduces clutter in logs. 2149 */ 2150 nfds = poll(pfd, i, 1000); 2151 if (nfds != 0) 2152 goto did_poll; 2153 if (--timeout <= 0) 2154 goto did_poll; 2155 } 2156 bb_error_msg("poll:%us sockets:%u interval:%us", timeout, i, 1 << G.poll_exp); 2157 } 2043 2158 nfds = poll(pfd, i, timeout * 1000); 2159 did_poll: 2044 2160 gettime1900d(); /* sets G.cur_time */ 2045 2161 if (nfds <= 0) { … … 2066 2182 for (; nfds != 0 && j < i; j++) { 2067 2183 if (pfd[j].revents /* & (POLLIN|POLLERR)*/) { 2184 /* 2185 * At init, alarm was set to 10 sec. 2186 * Now we did get a reply. 2187 * Increase timeout to 50 seconds to finish syncing. 2188 */ 2189 if (option_mask32 & OPT_qq) { 2190 option_mask32 &= ~OPT_qq; 2191 alarm(50); 2192 } 2068 2193 nfds--; 2069 2194 recv_and_process_peer_pkt(idx2peer[j]); … … 2073 2198 } /* while (!bb_got_signal) */ 2074 2199 2200 remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); 2075 2201 kill_myself_with_sig(bb_got_signal); 2076 2202 } … … 2203 2329 if (!(pll_status & STA_PPSTIME)) 2204 2330 report_event(EVNT_KERN, 2205 2331 NULL, "PPS enabled"); 2206 2332 ntv.status |= STA_PPSTIME | STA_PPSFREQ; 2207 2333 } else { 2208 2334 if (pll_status & STA_PPSTIME) 2209 2335 report_event(EVNT_KERN, 2210 NULL, "PPS disabled"); 2211 ntv.status &= ~(STA_PPSTIME | 2212 STA_PPSFREQ); 2336 NULL, "PPS disabled"); 2337 ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ); 2213 2338 } 2214 2339 if (sys_leap == LEAP_ADDSECOND) … … 2226 2351 if (!(ntv.status & STA_PPSSIGNAL)) 2227 2352 report_event(EVNT_KERN, NULL, 2228 2353 "PPS no signal"); 2229 2354 } 2230 2355 pll_status = ntv.status;
Note:
See TracChangeset
for help on using the changeset viewer.