Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking/ntpd.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/networking/ntpd.c
r3232 r3621 2 2 * NTP client/server, based on OpenNTPD 3.9p1 3 3 * 4 * Author: Adam Tkac<vonsch@gmail.com>4 * Busybox port author: Adam Tkac (C) 2009 <vonsch@gmail.com> 5 5 * 6 * Licensed under GPLv2, see file LICENSE in this source tree. 6 * OpenNTPd 3.9p1 copyright holders: 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org> 9 * 10 * OpenNTPd code is licensed under ISC-style licence: 11 * 12 * Permission to use, copy, modify, and distribute this software for any 13 * purpose with or without fee is hereby granted, provided that the above 14 * copyright notice and this permission notice appear in all copies. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 17 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 19 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 21 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 23 *********************************************************************** 7 24 * 8 25 * Parts of OpenNTPD clock syncronization code is replaced by 9 * code which is based on ntp-4.2.6, wh uch carries the following26 * code which is based on ntp-4.2.6, which carries the following 10 27 * copyright notice: 11 28 * 12 *********************************************************************** 13 * * 14 * Copyright (c) University of Delaware 1992-2009 * 15 * * 16 * Permission to use, copy, modify, and distribute this software and * 17 * its documentation for any purpose with or without fee is hereby * 18 * granted, provided that the above copyright notice appears in all * 19 * copies and that both the copyright notice and this permission * 20 * notice appear in supporting documentation, and that the name * 21 * University of Delaware not be used in advertising or publicity * 22 * pertaining to distribution of the software without specific, * 23 * written prior permission. The University of Delaware makes no * 24 * representations about the suitability this software for any * 25 * purpose. It is provided "as is" without express or implied * 26 * warranty. * 27 * * 29 * Copyright (c) University of Delaware 1992-2009 30 * 31 * Permission to use, copy, modify, and distribute this software and 32 * its documentation for any purpose with or without fee is hereby 33 * granted, provided that the above copyright notice appears in all 34 * copies and that both the copyright notice and this permission 35 * notice appear in supporting documentation, and that the name 36 * University of Delaware not be used in advertising or publicity 37 * pertaining to distribution of the software without specific, 38 * written prior permission. The University of Delaware makes no 39 * representations about the suitability this software for any 40 * purpose. It is provided "as is" without express or implied warranty. 28 41 *********************************************************************** 29 42 */ 30 43 31 44 //usage:#define ntpd_trivial_usage 32 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l ")"] [-S PROG] [-p PEER]..."45 //usage: "[-dnqNw"IF_FEATURE_NTPD_SERVER("l -I IFACE")"] [-S PROG] [-p PEER]..." 33 46 //usage:#define ntpd_full_usage "\n\n" 34 47 //usage: "NTP client/server\n" … … 38 51 //usage: "\n -N Run at high priority" 39 52 //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 53 //usage: "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" 44 54 //usage: "\n -p PEER Obtain time from PEER (may be repeated)" 55 //usage: IF_FEATURE_NTPD_CONF( 56 //usage: "\n If -p is not given, 'server HOST' lines" 57 //usage: "\n from /etc/ntp.conf are used" 58 //usage: ) 59 //usage: IF_FEATURE_NTPD_SERVER( 60 //usage: "\n -l Also run as server on port 123" 61 //usage: "\n -I IFACE Bind server to IFACE, implies -l" 62 //usage: ) 63 64 // -l and -p options are not compatible with "standard" ntpd: 65 // it has them as "-l logfile" and "-p pidfile". 66 // -S and -w are not compat either, "standard" ntpd has no such opts. 45 67 46 68 #include "libbb.h" … … 52 74 # define IPTOS_LOWDELAY 0x10 53 75 #endif 54 #ifndef IP_PKTINFO55 # error "Sorry, your kernel has to support IP_PKTINFO"56 #endif57 76 58 77 59 78 /* Verbosity control (max level of -dddd options accepted). 60 * max 5 is very talkative (and bloated). 2is non-bloated,79 * max 6 is very talkative (and bloated). 3 is non-bloated, 61 80 * production level setting. 62 81 */ 63 #define MAX_VERBOSE 282 #define MAX_VERBOSE 3 64 83 65 84 … … 91 110 * then the time is stepped, all datapoints are discarded, 92 111 * and we go back to steady state. 112 * 113 * Made some changes to speed up re-syncing after our clock goes bad 114 * (tested with suspending my laptop): 115 * - if largish offset (>= STEP_THRESHOLD == 1 sec) is seen 116 * from a peer, schedule next query for this peer soon 117 * without drastically lowering poll interval for everybody. 118 * This makes us collect enough data for step much faster: 119 * e.g. at poll = 10 (1024 secs), step was done within 5 minutes 120 * after first reply which indicated that our clock is 14 seconds off. 121 * - on step, do not discard d_dispersion data of the existing datapoints, 122 * do not clear reachable_bits. This prevents discarding first ~8 123 * datapoints after the step. 93 124 */ 94 125 95 #define RETRY_INTERVAL 5 /* on error, retry in N secs */ 96 #define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */ 97 #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 98 99 /* Clock discipline parameters and constants */ 126 #define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 127 #define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ 128 129 #define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ 130 #define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */ 131 #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ 100 132 101 133 /* Step threshold (sec). std ntpd uses 0.128. 102 * Using exact power of 2 (1/8) results in smaller code */ 103 #define STEP_THRESHOLD 0.125 104 #define WATCH_THRESHOLD 128 /* stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ 134 */ 135 #define STEP_THRESHOLD 1 136 /* Slew threshold (sec): adjtimex() won't accept offsets larger than this. 137 * Using exact power of 2 (1/8) results in smaller code 138 */ 139 #define SLEW_THRESHOLD 0.125 140 /* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ 141 #define WATCH_THRESHOLD 128 105 142 /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ 106 143 //UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ 144 145 /* 146 * If we got |offset| > BIGOFF from a peer, cap next query interval 147 * for this peer by this many seconds: 148 */ 149 #define BIGOFF STEP_THRESHOLD 150 #define BIGOFF_INTERVAL (1 << 7) /* 128 s */ 107 151 108 152 #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ 109 153 #define BURSTPOLL 0 /* initial poll */ 110 154 #define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ 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_). 155 /* 156 * If offset > discipline_jitter * POLLADJ_GATE, and poll interval is > 2^BIGPOLL, 157 * then it is decreased _at once_. (If <= 2^BIGPOLL, it will be decreased _eventually_). 113 158 */ 114 #define BIGPOLL 10 /* 2^10 sec ~= 17min */159 #define BIGPOLL 9 /* 2^9 sec ~= 8.5 min */ 115 160 #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ 116 /* Actively lower poll when we see such big offsets. 117 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively 118 * if offset increases over ~0.04 sec */ 119 #define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) 161 /* 162 * Actively lower poll when we see such big offsets. 163 * With SLEW_THRESHOLD = 0.125, it means we try to sync more aggressively 164 * if offset increases over ~0.04 sec 165 */ 166 //#define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) 120 167 #define MINDISP 0.01 /* minimum dispersion (sec) */ 121 168 #define MAXDISP 16 /* maximum dispersion (sec) */ … … 228 275 uint8_t lastpkt_stratum; 229 276 uint8_t reachable_bits; 230 231 277 /* when to send new query (if p_fd == -1) 278 * or when receive times out (if p_fd >= 0): */ 232 279 double next_action_time; 233 280 double p_xmttime; 281 double p_raw_delay; 282 /* p_raw_delay is set even by "high delay" packets */ 283 /* lastpkt_delay isn't */ 234 284 double lastpkt_recv_time; 235 285 double lastpkt_delay; … … 243 293 /* last sent packet: */ 244 294 msg_t p_xmt_msg; 295 char p_hostname[1]; 245 296 } peer_t; 246 297 … … 260 311 OPT_S = (1 << 6), 261 312 OPT_l = (1 << 7) * ENABLE_FEATURE_NTPD_SERVER, 313 OPT_I = (1 << 8) * ENABLE_FEATURE_NTPD_SERVER, 262 314 /* We hijack some bits for other purposes */ 263 315 OPT_qq = (1 << 31), … … 278 330 #if ENABLE_FEATURE_NTPD_SERVER 279 331 int listen_fd; 332 char *if_name; 280 333 # define G_listen_fd (G.listen_fd) 281 334 #else … … 329 382 #define G_precision_sec 0.002 330 383 uint8_t stratum; 331 /* Bool. After set to 1, never goes back to 0: */332 smallint initial_poll_complete;333 384 334 385 #define STATE_NSET 0 /* initial state, "nothing is set" */ 335 386 //#define STATE_FSET 1 /* frequency set from file */ 336 #define STATE_SPIK2 /* spike detected */387 //#define STATE_SPIK 2 /* spike detected */ 337 388 //#define STATE_FREQ 3 /* initial frequency */ 338 389 #define STATE_SYNC 4 /* clock synchronized (normal operation) */ … … 359 410 #define G (*ptr_to_globals) 360 411 361 static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY;362 363 412 364 413 #define VERB1 if (MAX_VERBOSE && G.verbose) … … 367 416 #define VERB4 if (MAX_VERBOSE >= 4 && G.verbose >= 4) 368 417 #define VERB5 if (MAX_VERBOSE >= 5 && G.verbose >= 5) 418 #define VERB6 if (MAX_VERBOSE >= 6 && G.verbose >= 6) 369 419 370 420 … … 568 618 sum = 0; 569 619 for (i = 0; i < NUM_DATAPOINTS; i++) { 570 VERB 4{620 VERB5 { 571 621 bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", 572 622 i, … … 665 715 p->filter_jitter = sum > G_precision_sec ? sum : G_precision_sec; 666 716 667 VERB 3bb_error_msg("filter offset:%+f disp:%f jitter:%f",717 VERB4 bb_error_msg("filter offset:%+f disp:%f jitter:%f", 668 718 p->filter_offset, 669 719 p->filter_dispersion, … … 675 725 { 676 726 int i; 677 bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; 727 bool small_ofs = fabs(offset) < STEP_THRESHOLD; 728 729 /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP 730 * and clear reachable bits, but this proved to be too agressive: 731 * after step (tested with suspending laptop for ~30 secs), 732 * this caused all previous data to be considered invalid, 733 * making us needing to collect full ~8 datapoins per peer 734 * after step in order to start trusting them. 735 * In turn, this was making poll interval decrease even after 736 * step was done. (Poll interval decreases already before step 737 * in this scenario, because we see large offsets and end up with 738 * no good peer to select). 739 */ 678 740 679 741 for (i = 0; i < NUM_DATAPOINTS; i++) { … … 690 752 p->filter_datapoint[i].d_recv_time = G.cur_time; 691 753 p->filter_datapoint[i].d_offset = 0; 692 p->filter_datapoint[i].d_dispersion = MAXDISP;754 /*p->filter_datapoint[i].d_dispersion = MAXDISP;*/ 693 755 } 694 756 } … … 696 758 p->lastpkt_recv_time += offset; 697 759 } else { 698 p->reachable_bits = 0;760 /*p->reachable_bits = 0;*/ 699 761 p->lastpkt_recv_time = G.cur_time; 700 762 } 701 763 filter_datapoints(p); /* recalc p->filter_xxx */ 702 VERB 5bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);764 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 703 765 } 704 766 705 767 static void 706 add_peers(char *s) 707 { 768 resolve_peer_hostname(peer_t *p, int loop_on_fail) 769 { 770 len_and_sockaddr *lsa; 771 772 again: 773 lsa = host2sockaddr(p->p_hostname, 123); 774 if (!lsa) { 775 /* error message already emitted by host2sockaddr() */ 776 if (!loop_on_fail) 777 return; 778 //FIXME: do this to avoid infinite looping on typo in a hostname? 779 //well... in which case, what is a good value for loop_on_fail? 780 //if (--loop_on_fail == 0) 781 // xfunc_die(); 782 sleep(5); 783 goto again; 784 } 785 free(p->p_lsa); 786 free(p->p_dotted); 787 p->p_lsa = lsa; 788 p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); 789 } 790 791 static void 792 add_peers(const char *s) 793 { 794 llist_t *item; 708 795 peer_t *p; 709 796 710 p = xzalloc(sizeof(*p)); 711 p->p_lsa = xhost2sockaddr(s, 123); 712 p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); 797 p = xzalloc(sizeof(*p) + strlen(s)); 798 strcpy(p->p_hostname, s); 799 resolve_peer_hostname(p, /*loop_on_fail=*/ 1); 800 801 /* Names like N.<country2chars>.pool.ntp.org are randomly resolved 802 * to a pool of machines. Sometimes different N's resolve to the same IP. 803 * It is not useful to have two peers with same IP. We skip duplicates. 804 */ 805 for (item = G.ntp_peers; item != NULL; item = item->link) { 806 peer_t *pp = (peer_t *) item->data; 807 if (strcmp(p->p_dotted, pp->p_dotted) == 0) { 808 bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); 809 free(p->p_lsa); 810 free(p->p_dotted); 811 free(p); 812 return; 813 } 814 } 815 713 816 p->p_fd = -1; 714 817 p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); 715 818 p->next_action_time = G.cur_time; /* = set_next(p, 0); */ 716 reset_peer_stats(p, 16 *STEP_THRESHOLD);819 reset_peer_stats(p, STEP_THRESHOLD); 717 820 718 821 llist_add_to(&G.ntp_peers, p); … … 778 881 if (family == AF_INET) 779 882 #endif 780 setsockopt (fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY));883 setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 781 884 free(local_lsa); 782 885 } … … 801 904 * Save the real transmit timestamp locally. 802 905 */ 803 p->p_xmt_msg.m_xmttime.int_partl = rand om();804 p->p_xmt_msg.m_xmttime.fractionl = rand om();906 p->p_xmt_msg.m_xmttime.int_partl = rand(); 907 p->p_xmt_msg.m_xmttime.fractionl = rand(); 805 908 p->p_xmttime = gettime1900d(); 909 910 /* Were doing it only if sendto worked, but 911 * loss of sync detection needs reachable_bits updated 912 * even if sending fails *locally*: 913 * "network is unreachable" because cable was pulled? 914 * We still need to declare "unsync" if this condition persists. 915 */ 916 p->reachable_bits <<= 1; 806 917 807 918 if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, … … 810 921 close(p->p_fd); 811 922 p->p_fd = -1; 923 /* 924 * We know that we sent nothing. 925 * We can retry *soon* without fearing 926 * that we are flooding the peer. 927 */ 812 928 set_next(p, RETRY_INTERVAL); 813 929 return; 814 930 } 815 931 816 p->reachable_bits <<= 1;817 932 set_next(p, RESPONSE_INTERVAL); 818 933 } … … 820 935 821 936 /* Note that there is no provision to prevent several run_scripts 822 * to be donein quick succession. In fact, it happens rather often937 * to be started in quick succession. In fact, it happens rather often 823 938 * if initial syncronization results in a step. 824 939 * You will see "step" and then "stratum" script runs, sometimes … … 830 945 char *argv[3]; 831 946 char *env1, *env2, *env3, *env4; 947 948 G.last_script_run = G.cur_time; 832 949 833 950 if (!G.script_name) … … 867 984 free(env3); 868 985 free(env4); 869 870 G.last_script_run = G.cur_time;871 986 } 872 987 … … 888 1003 VERB2 { 889 1004 tval = tvc.tv_sec; 890 strftime (buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval));1005 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); 891 1006 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec); 892 1007 } 893 1008 tval = tvn.tv_sec; 894 strftime (buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval));1009 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); 895 1010 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 896 1011 … … 921 1036 } 922 1037 1038 static void clamp_pollexp_and_set_MAXSTRAT(void) 1039 { 1040 if (G.poll_exp < MINPOLL) 1041 G.poll_exp = MINPOLL; 1042 if (G.poll_exp > BIGPOLL) 1043 G.poll_exp = BIGPOLL; 1044 G.polladj_count = 0; 1045 G.stratum = MAXSTRAT; 1046 } 1047 923 1048 924 1049 /* … … 960 1085 if ((p->reachable_bits & (p->reachable_bits-1)) == 0) { 961 1086 /* One or zero bits in reachable_bits */ 962 VERB 3bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted);1087 VERB4 bb_error_msg("peer %s unfit for selection: unreachable", p->p_dotted); 963 1088 return 0; 964 1089 } … … 967 1092 || p->lastpkt_stratum >= MAXSTRAT 968 1093 ) { 969 VERB 3bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted);1094 VERB4 bb_error_msg("peer %s unfit for selection: bad status/stratum", p->p_dotted); 970 1095 return 0; 971 1096 } … … 973 1098 /* rd is root_distance(p) */ 974 1099 if (rd > MAXDIST + FREQ_TOLERANCE * (1 << G.poll_exp)) { 975 VERB 3bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted);1100 VERB4 bb_error_msg("peer %s unfit for selection: root distance too high", p->p_dotted); 976 1101 return 0; 977 1102 } … … 1002 1127 num_points = 0; 1003 1128 item = G.ntp_peers; 1004 if (G.initial_poll_complete)while (item != NULL) {1129 while (item != NULL) { 1005 1130 double rd, offset; 1006 1131 … … 1013 1138 } 1014 1139 1015 VERB 4bb_error_msg("interval: [%f %f %f] %s",1140 VERB5 bb_error_msg("interval: [%f %f %f] %s", 1016 1141 offset - rd, 1017 1142 offset, … … 1038 1163 num_candidates = num_points / 3; 1039 1164 if (num_candidates == 0) { 1040 VERB3 bb_error_msg("no valid datapoints , no peer selected");1165 VERB3 bb_error_msg("no valid datapoints%s", ", no peer selected"); 1041 1166 return NULL; 1042 1167 } … … 1096 1221 num_falsetickers++; 1097 1222 if (num_falsetickers * 2 >= num_candidates) { 1098 VERB3 bb_error_msg("too many falsetickers:%d (candidates:%d), no peer selected", 1099 num_falsetickers, num_candidates); 1223 VERB3 bb_error_msg("falsetickers:%d, candidates:%d%s", 1224 num_falsetickers, num_candidates, 1225 ", no peer selected"); 1100 1226 return NULL; 1101 1227 } 1102 1228 } 1103 VERB 3bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d",1229 VERB4 bb_error_msg("selected interval: [%f, %f]; candidates:%d falsetickers:%d", 1104 1230 low, high, num_candidates, num_falsetickers); 1105 1231 … … 1119 1245 /* x.opt_rd == root_distance(p); */ 1120 1246 survivor[num_survivors].metric = MAXDIST * p->lastpkt_stratum + point[i].opt_rd; 1121 VERB 4bb_error_msg("survivor[%d] metric:%f peer:%s",1247 VERB5 bb_error_msg("survivor[%d] metric:%f peer:%s", 1122 1248 num_survivors, survivor[num_survivors].metric, p->p_dotted); 1123 1249 num_survivors++; … … 1129 1255 */ 1130 1256 if (num_survivors < MIN_SELECTED) { 1131 VERB3 bb_error_msg("num_survivors %d < %d, no peer selected", 1132 num_survivors, MIN_SELECTED); 1257 VERB3 bb_error_msg("survivors:%d%s", 1258 num_survivors, 1259 ", no peer selected"); 1133 1260 return NULL; 1134 1261 } … … 1150 1277 1151 1278 if (num_survivors <= MIN_CLUSTERED) { 1152 VERB 3bb_error_msg("num_survivors %d <= %d, not discarding more",1279 VERB4 bb_error_msg("num_survivors %d <= %d, not discarding more", 1153 1280 num_survivors, MIN_CLUSTERED); 1154 1281 break; … … 1176 1303 max_idx = i; 1177 1304 } 1178 VERB 5bb_error_msg("survivor %d selection_jitter^2:%f",1305 VERB6 bb_error_msg("survivor %d selection_jitter^2:%f", 1179 1306 i, selection_jitter_sq); 1180 1307 } 1181 1308 max_selection_jitter = SQRT(max_selection_jitter / num_survivors); 1182 VERB 4bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f",1309 VERB5 bb_error_msg("max_selection_jitter (at %d):%f min_jitter:%f", 1183 1310 max_idx, max_selection_jitter, min_jitter); 1184 1311 … … 1189 1316 */ 1190 1317 if (max_selection_jitter < min_jitter) { 1191 VERB 3bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more",1318 VERB4 bb_error_msg("max_selection_jitter:%f < min_jitter:%f, num_survivors:%d, not discarding more", 1192 1319 max_selection_jitter, min_jitter, num_survivors); 1193 1320 break; … … 1197 1324 * and go around again. 1198 1325 */ 1199 VERB 5bb_error_msg("dropping survivor %d", max_idx);1326 VERB6 bb_error_msg("dropping survivor %d", max_idx); 1200 1327 num_survivors--; 1201 1328 while (max_idx < num_survivors) { … … 1239 1366 for (i = 1; i < num_survivors; i++) { 1240 1367 if (G.last_update_peer == survivor[i].p) { 1241 VERB 4bb_error_msg("keeping old synced peer");1368 VERB5 bb_error_msg("keeping old synced peer"); 1242 1369 p = G.last_update_peer; 1243 1370 goto keep_old; … … 1247 1374 G.last_update_peer = p; 1248 1375 keep_old: 1249 VERB 3bb_error_msg("selected peer %s filter_offset:%+f age:%f",1376 VERB4 bb_error_msg("selected peer %s filter_offset:%+f age:%f", 1250 1377 p->p_dotted, 1251 1378 p->filter_offset, … … 1266 1393 * the current time. 1267 1394 */ 1268 VERB 3bb_error_msg("disc_state=%d last update offset=%f recv_time=%f",1395 VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", 1269 1396 disc_state, offset, recv_time); 1270 1397 G.discipline_state = disc_state; … … 1285 1412 double freq_drift; 1286 1413 #endif 1414 #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION 1287 1415 double since_last_update; 1416 #endif 1288 1417 double etemp, dtemp; 1289 1418 … … 1304 1433 */ 1305 1434 if (recv_time <= G.last_update_recv_time) { 1306 VERB3 bb_error_msg(" same or older datapoint: %f >= %f, not using it",1307 G.last_update_recv_time, recv_time);1435 VERB3 bb_error_msg("update from %s: same or older datapoint, not using it", 1436 p->p_dotted); 1308 1437 return 0; /* "leave poll interval as is" */ 1309 1438 } … … 1313 1442 * and frequency errors. 1314 1443 */ 1444 #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION 1315 1445 since_last_update = recv_time - G.reftime; 1446 #endif 1316 1447 #if !USING_KERNEL_PLL_LOOP 1317 1448 freq_drift = 0; … … 1321 1452 /* Ignore updates until the stepout threshold */ 1322 1453 if (since_last_update < WATCH_THRESHOLD) { 1323 VERB 3bb_error_msg("measuring drift, datapoint ignored, %f sec remains",1454 VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", 1324 1455 WATCH_THRESHOLD - since_last_update); 1325 1456 return 0; /* "leave poll interval as is" */ … … 1335 1466 */ 1336 1467 if (abs_offset > STEP_THRESHOLD) { 1468 #if 0 1469 double remains; 1470 1471 // This "spike state" seems to be useless, peer selection already drops 1472 // occassional "bad" datapoints. If we are here, there were _many_ 1473 // large offsets. When a few first large offsets are seen, 1474 // we end up in "no valid datapoints, no peer selected" state. 1475 // Only when enough of them are seen (which means it's not a fluke), 1476 // we end up here. Looks like _our_ clock is off. 1337 1477 switch (G.discipline_state) { 1338 1478 case STATE_SYNC: 1339 1479 /* The first outlyer: ignore it, switch to SPIK state */ 1340 VERB3 bb_error_msg("offset:%+f - spike detected", offset); 1480 VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", 1481 p->p_dotted, offset, 1482 ""); 1341 1483 G.discipline_state = STATE_SPIK; 1342 1484 return -1; /* "decrease poll interval" */ … … 1346 1488 * is found or the stepout threshold is exceeded. 1347 1489 */ 1348 if (since_last_update < WATCH_THRESHOLD) { 1349 VERB3 bb_error_msg("spike detected, datapoint ignored, %f sec remains", 1350 WATCH_THRESHOLD - since_last_update); 1490 remains = WATCH_THRESHOLD - since_last_update; 1491 if (remains > 0) { 1492 VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", 1493 p->p_dotted, offset, 1494 ", datapoint ignored"); 1351 1495 return -1; /* "decrease poll interval" */ 1352 1496 } 1353 1497 /* fall through: we need to step */ 1354 1498 } /* switch */ 1499 #endif 1355 1500 1356 1501 /* Step the time and clamp down the poll interval. … … 1375 1520 * intervals. 1376 1521 */ 1377 VERB 3bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset);1522 VERB4 bb_error_msg("stepping time by %+f; poll_exp=MINPOLL", offset); 1378 1523 step_time(offset); 1379 1524 if (option_mask32 & OPT_q) { … … 1382 1527 } 1383 1528 1384 G.polladj_count = 0; 1385 G.poll_exp = MINPOLL; 1386 G.stratum = MAXSTRAT; 1529 clamp_pollexp_and_set_MAXSTRAT(); 1387 1530 1388 1531 run_script("step", offset); 1532 1533 recv_time += offset; 1389 1534 1390 1535 #if USING_INITIAL_FREQ_ESTIMATION … … 1396 1541 abs_offset = offset = 0; 1397 1542 set_new_values(STATE_SYNC, offset, recv_time); 1398 1399 1543 } else { /* abs_offset <= STEP_THRESHOLD */ 1400 1544 1401 if (G.poll_exp < MINPOLL && G.initial_poll_complete) { 1402 VERB3 bb_error_msg("small offset:%+f, disabling burst mode", offset); 1403 G.polladj_count = 0; 1404 G.poll_exp = MINPOLL; 1405 } 1545 /* The ratio is calculated before jitter is updated to make 1546 * poll adjust code more sensitive to large offsets. 1547 */ 1548 G.offset_to_jitter_ratio = abs_offset / G.discipline_jitter; 1406 1549 1407 1550 /* Compute the clock jitter as the RMS of exponentially … … 1411 1554 dtemp = SQUARE(offset - G.last_update_offset); 1412 1555 G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); 1556 if (G.discipline_jitter < G_precision_sec) 1557 G.discipline_jitter = G_precision_sec; 1413 1558 1414 1559 switch (G.discipline_state) { … … 1429 1574 set_new_values(STATE_SYNC, offset, recv_time); 1430 1575 #endif 1431 VERB 3bb_error_msg("transitioning to FREQ, datapoint ignored");1576 VERB4 bb_error_msg("transitioning to FREQ, datapoint ignored"); 1432 1577 return 0; /* "leave poll interval as is" */ 1433 1578 … … 1487 1632 } 1488 1633 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 1493 1634 G.reftime = G.cur_time; 1494 1635 G.ntp_status = p->lastpkt_status; … … 1498 1639 dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); 1499 1640 G.rootdisp = p->lastpkt_rootdisp + dtemp; 1500 VERB 3bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted);1641 VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); 1501 1642 1502 1643 /* We are in STATE_SYNC now, but did not do adjtimex yet. … … 1518 1659 G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG); 1519 1660 1520 VERB 3bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",1661 VERB4 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f", 1521 1662 G.discipline_freq_drift, 1522 1663 (long)(G.discipline_freq_drift * 65536e6), … … 1524 1665 G.discipline_wander); 1525 1666 #endif 1526 VERB 3{1667 VERB4 { 1527 1668 memset(&tmx, 0, sizeof(tmx)); 1528 1669 if (adjtimex(&tmx) < 0) … … 1543 1684 #endif 1544 1685 tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; 1545 tmx.offset = (offset * 1000000); /* usec */ 1546 tmx.status = STA_PLL; 1547 if (G.ntp_status & LI_PLUSSEC) 1548 tmx.status |= STA_INS; 1549 if (G.ntp_status & LI_MINUSSEC) 1550 tmx.status |= STA_DEL; 1551 1552 tmx.constant = G.poll_exp - 4; 1686 tmx.constant = (int)G.poll_exp - 4; 1553 1687 /* EXPERIMENTAL. 1554 1688 * The below if statement should be unnecessary, but... … … 1561 1695 * larger than jitter. 1562 1696 */ 1563 if ( tmx.constant > 0 &&G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE)1697 if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) 1564 1698 tmx.constant--; 1699 tmx.offset = (long)(offset * 1000000); /* usec */ 1700 if (SLEW_THRESHOLD < STEP_THRESHOLD) { 1701 if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { 1702 tmx.offset = (long)(SLEW_THRESHOLD * 1000000); 1703 tmx.constant--; 1704 } 1705 if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) { 1706 tmx.offset = -(long)(SLEW_THRESHOLD * 1000000); 1707 tmx.constant--; 1708 } 1709 } 1710 if (tmx.constant < 0) 1711 tmx.constant = 0; 1712 1713 tmx.status = STA_PLL; 1714 if (G.ntp_status & LI_PLUSSEC) 1715 tmx.status |= STA_INS; 1716 if (G.ntp_status & LI_MINUSSEC) 1717 tmx.status |= STA_DEL; 1565 1718 1566 1719 //tmx.esterror = (uint32_t)(clock_jitter * 1e6); … … 1572 1725 * Not sure why. Perhaps it is normal. 1573 1726 */ 1574 VERB 3bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x",1727 VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", 1575 1728 rc, tmx.freq, tmx.offset, tmx.status); 1576 1729 G.kernel_freq_drift = tmx.freq / 65536; 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); 1730 VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", 1731 p->p_dotted, 1732 offset, 1733 p->lastpkt_delay, 1734 G.discipline_jitter, 1735 (double)tmx.freq / 65536, 1736 (int)tmx.constant 1737 ); 1579 1738 1580 1739 return 1; /* "ok to increase poll interval" */ … … 1587 1746 */ 1588 1747 static unsigned 1589 retry_interval(void) 1590 { 1591 /* Local problem, want to retry soon */ 1592 unsigned interval, r; 1593 interval = RETRY_INTERVAL; 1594 r = random(); 1595 interval += r % (unsigned)(RETRY_INTERVAL / 4); 1596 VERB3 bb_error_msg("chose retry interval:%u", interval); 1748 poll_interval(int upper_bound) 1749 { 1750 unsigned interval, r, mask; 1751 interval = 1 << G.poll_exp; 1752 if (interval > upper_bound) 1753 interval = upper_bound; 1754 mask = ((interval-1) >> 4) | 1; 1755 r = rand(); 1756 interval += r & mask; /* ~ random(0..1) * interval/16 */ 1757 VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d)", interval, G.poll_exp); 1597 1758 return interval; 1598 1759 } 1599 static unsigned 1600 poll_interval(int exponent) 1601 { 1602 unsigned interval, r; 1603 exponent = G.poll_exp + exponent; 1604 if (exponent < 0) 1605 exponent = 0; 1606 interval = 1 << exponent; 1607 r = random(); 1608 interval += ((r & (interval-1)) >> 4) + ((r >> 8) & 1); /* + 1/16 of interval, max */ 1609 VERB3 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); 1610 return interval; 1760 static void 1761 adjust_poll(int count) 1762 { 1763 G.polladj_count += count; 1764 if (G.polladj_count > POLLADJ_LIMIT) { 1765 G.polladj_count = 0; 1766 if (G.poll_exp < MAXPOLL) { 1767 G.poll_exp++; 1768 VERB4 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", 1769 G.discipline_jitter, G.poll_exp); 1770 } 1771 } else if (G.polladj_count < -POLLADJ_LIMIT || (count < 0 && G.poll_exp > BIGPOLL)) { 1772 G.polladj_count = 0; 1773 if (G.poll_exp > MINPOLL) { 1774 llist_t *item; 1775 1776 G.poll_exp--; 1777 /* Correct p->next_action_time in each peer 1778 * which waits for sending, so that they send earlier. 1779 * Old pp->next_action_time are on the order 1780 * of t + (1 << old_poll_exp) + small_random, 1781 * we simply need to subtract ~half of that. 1782 */ 1783 for (item = G.ntp_peers; item != NULL; item = item->link) { 1784 peer_t *pp = (peer_t *) item->data; 1785 if (pp->p_fd < 0) 1786 pp->next_action_time -= (1 << G.poll_exp); 1787 } 1788 VERB4 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", 1789 G.discipline_jitter, G.poll_exp); 1790 } 1791 } else { 1792 VERB4 bb_error_msg("polladj: count:%d", G.polladj_count); 1793 } 1611 1794 } 1612 1795 static NOINLINE void … … 1617 1800 msg_t msg; 1618 1801 double T1, T2, T3, T4; 1802 double offset; 1803 double prev_delay, delay; 1619 1804 unsigned interval; 1620 1805 datapoint_t *datapoint; 1621 1806 peer_t *q; 1622 1807 1808 offset = 0; 1809 1623 1810 /* We can recvfrom here and check from.IP, but some multihomed 1624 1811 * ntp servers reply from their *other IP*. 1625 1812 * TODO: maybe we should check at least what we can: from.port == 123? 1626 1813 */ 1814 recv_again: 1627 1815 size = recv(p->p_fd, &msg, sizeof(msg), MSG_DONTWAIT); 1628 if (size == -1) { 1629 bb_perror_msg("recv(%s) error", p->p_dotted); 1630 if (errno == EHOSTUNREACH || errno == EHOSTDOWN 1631 || errno == ENETUNREACH || errno == ENETDOWN 1632 || errno == ECONNREFUSED || errno == EADDRNOTAVAIL 1633 || errno == EAGAIN 1634 ) { 1635 //TODO: always do this? 1636 interval = retry_interval(); 1637 goto set_next_and_ret; 1638 } 1639 xfunc_die(); 1816 if (size < 0) { 1817 if (errno == EINTR) 1818 /* Signal caught */ 1819 goto recv_again; 1820 if (errno == EAGAIN) 1821 /* There was no packet after all 1822 * (poll() returning POLLIN for a fd 1823 * is not a ironclad guarantee that data is there) 1824 */ 1825 return; 1826 /* 1827 * If you need a different handling for a specific 1828 * errno, always explain it in comment. 1829 */ 1830 bb_perror_msg_and_die("recv(%s) error", p->p_dotted); 1640 1831 } 1641 1832 … … 1663 1854 || msg.m_stratum > NTP_MAXSTRATUM 1664 1855 ) { 1665 // TODO: stratum 0 responses may have commands in 32-bit m_refid field: 1666 // "DENY", "RSTR" - peer does not like us at all 1667 // "RATE" - peer is overloaded, reduce polling freq 1668 interval = poll_interval(0); 1669 bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); 1670 goto set_next_and_ret; 1856 bb_error_msg("reply from %s: peer is unsynced", p->p_dotted); 1857 /* 1858 * Stratum 0 responses may have commands in 32-bit m_refid field: 1859 * "DENY", "RSTR" - peer does not like us at all, 1860 * "RATE" - peer is overloaded, reduce polling freq. 1861 * If poll interval is small, increase it. 1862 */ 1863 if (G.poll_exp < BIGPOLL) 1864 goto increase_interval; 1865 goto pick_normal_interval; 1671 1866 } 1672 1867 … … 1674 1869 // if (msg.m_rootdelay / 2 + msg.m_rootdisp >= MAXDISP || p->lastpkt_reftime > msg.m_xmt) 1675 1870 // return; /* invalid header values */ 1676 1677 p->lastpkt_status = msg.m_status;1678 p->lastpkt_stratum = msg.m_stratum;1679 p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay);1680 p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp);1681 p->lastpkt_refid = msg.m_refid;1682 1871 1683 1872 /* … … 1700 1889 T4 = G.cur_time; 1701 1890 1702 p->lastpkt_recv_time = T4;1703 1704 VERB5 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time);1705 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0;1706 datapoint = &p->filter_datapoint[p->datapoint_idx];1707 datapoint->d_recv_time = T4;1708 datapoint->d_offset = ((T2 - T1) + (T3 - T4)) / 2;1709 1891 /* The delay calculation is a special case. In cases where the 1710 1892 * server and client clocks are running at different rates and … … 1713 1895 * the delay is clamped not less than the system precision. 1714 1896 */ 1715 p->lastpkt_delay = (T4 - T1) - (T3 - T2); 1716 if (p->lastpkt_delay < G_precision_sec) 1717 p->lastpkt_delay = G_precision_sec; 1897 delay = (T4 - T1) - (T3 - T2); 1898 if (delay < G_precision_sec) 1899 delay = G_precision_sec; 1900 /* 1901 * If this packet's delay is much bigger than the last one, 1902 * it's better to just ignore it than use its much less precise value. 1903 */ 1904 prev_delay = p->p_raw_delay; 1905 p->p_raw_delay = delay; 1906 if (p->reachable_bits && delay > prev_delay * BAD_DELAY_GROWTH) { 1907 bb_error_msg("reply from %s: delay %f is too high, ignoring", p->p_dotted, delay); 1908 goto pick_normal_interval; 1909 } 1910 1911 p->lastpkt_delay = delay; 1912 p->lastpkt_recv_time = T4; 1913 VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); 1914 p->lastpkt_status = msg.m_status; 1915 p->lastpkt_stratum = msg.m_stratum; 1916 p->lastpkt_rootdelay = sfp_to_d(msg.m_rootdelay); 1917 p->lastpkt_rootdisp = sfp_to_d(msg.m_rootdisp); 1918 p->lastpkt_refid = msg.m_refid; 1919 1920 p->datapoint_idx = p->reachable_bits ? (p->datapoint_idx + 1) % NUM_DATAPOINTS : 0; 1921 datapoint = &p->filter_datapoint[p->datapoint_idx]; 1922 datapoint->d_recv_time = T4; 1923 datapoint->d_offset = offset = ((T2 - T1) + (T3 - T4)) / 2; 1718 1924 datapoint->d_dispersion = LOG2D(msg.m_precision_exp) + G_precision_sec; 1719 1925 if (!p->reachable_bits) { … … 1721 1927 int i; 1722 1928 for (i = 0; i < NUM_DATAPOINTS; i++) { 1723 p->filter_datapoint[i].d_offset = datapoint->d_offset;1929 p->filter_datapoint[i].d_offset = offset; 1724 1930 } 1725 1931 } … … 1729 1935 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 1730 1936 p->p_dotted, 1731 datapoint->d_offset,1937 offset, 1732 1938 p->lastpkt_delay, 1733 1939 p->lastpkt_status, … … 1745 1951 filter_datapoints(p); 1746 1952 q = select_and_cluster(); 1747 rc = -1;1953 rc = 0; 1748 1954 if (q) { 1749 rc = 0;1750 1955 if (!(option_mask32 & OPT_w)) { 1751 1956 rc = update_local_clock(q); 1957 #if 0 1958 //Disabled this because there is a case where largish offsets 1959 //are unavoidable: if network round-trip delay is, say, ~0.6s, 1960 //error in offset estimation would be ~delay/2 ~= 0.3s. 1961 //Thus, offsets will be usually in -0.3...0.3s range. 1962 //In this case, this code would keep poll interval small, 1963 //but it won't be helping. 1964 //BIGOFF check below deals with a case of seeing multi-second offsets. 1965 1752 1966 /* If drift is dangerously large, immediately 1753 1967 * drop poll interval one step down. 1754 1968 */ 1755 1969 if (fabs(q->filter_offset) >= POLLDOWN_OFFSET) { 1756 VERB3 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1757 goto poll_down; 1970 VERB4 bb_error_msg("offset:%+f > POLLDOWN_OFFSET", q->filter_offset); 1971 adjust_poll(-POLLADJ_LIMIT * 3); 1972 rc = 0; 1758 1973 } 1759 } 1760 } 1761 /* else: no peer selected, rc = -1: we want to poll more often */ 1974 #endif 1975 } 1976 } else { 1977 /* No peer selected. 1978 * If poll interval is small, increase it. 1979 */ 1980 if (G.poll_exp < BIGPOLL) 1981 goto increase_interval; 1982 } 1762 1983 1763 1984 if (rc != 0) { … … 1771 1992 /* was += G.poll_exp but it is a bit 1772 1993 * too optimistic for my taste at high poll_exp's */ 1773 G.polladj_count += MINPOLL; 1774 if (G.polladj_count > POLLADJ_LIMIT) { 1775 G.polladj_count = 0; 1776 if (G.poll_exp < MAXPOLL) { 1777 G.poll_exp++; 1778 VERB3 bb_error_msg("polladj: discipline_jitter:%f ++poll_exp=%d", 1779 G.discipline_jitter, G.poll_exp); 1780 } 1781 } else { 1782 VERB3 bb_error_msg("polladj: incr:%d", G.polladj_count); 1783 } 1994 increase_interval: 1995 adjust_poll(MINPOLL); 1784 1996 } else { 1785 G.polladj_count -= G.poll_exp * 2; 1786 if (G.polladj_count < -POLLADJ_LIMIT || G.poll_exp >= BIGPOLL) { 1787 poll_down: 1788 G.polladj_count = 0; 1789 if (G.poll_exp > MINPOLL) { 1790 llist_t *item; 1791 1792 G.poll_exp--; 1793 /* Correct p->next_action_time in each peer 1794 * which waits for sending, so that they send earlier. 1795 * Old pp->next_action_time are on the order 1796 * of t + (1 << old_poll_exp) + small_random, 1797 * we simply need to subtract ~half of that. 1798 */ 1799 for (item = G.ntp_peers; item != NULL; item = item->link) { 1800 peer_t *pp = (peer_t *) item->data; 1801 if (pp->p_fd < 0) 1802 pp->next_action_time -= (1 << G.poll_exp); 1803 } 1804 VERB3 bb_error_msg("polladj: discipline_jitter:%f --poll_exp=%d", 1805 G.discipline_jitter, G.poll_exp); 1806 } 1807 } else { 1808 VERB3 bb_error_msg("polladj: decr:%d", G.polladj_count); 1809 } 1997 VERB3 if (rc > 0) 1998 bb_error_msg("want smaller interval: offset/jitter = %u", 1999 G.offset_to_jitter_ratio); 2000 adjust_poll(-G.poll_exp * 2); 1810 2001 } 1811 2002 } 1812 2003 1813 2004 /* Decide when to send new query for this peer */ 1814 interval = poll_interval(0); 1815 1816 set_next_and_ret: 2005 pick_normal_interval: 2006 interval = poll_interval(INT_MAX); 2007 if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) { 2008 /* If we are synced, offsets are less than SLEW_THRESHOLD, 2009 * or at the very least not much larger than it. 2010 * Now we see a largish one. 2011 * Either this peer is feeling bad, or packet got corrupted, 2012 * or _our_ clock is wrong now and _all_ peers will show similar 2013 * largish offsets too. 2014 * I observed this with laptop suspend stopping clock. 2015 * In any case, it makes sense to make next request soonish: 2016 * cases 1 and 2: get a better datapoint, 2017 * case 3: allows to resync faster. 2018 */ 2019 interval = BIGOFF_INTERVAL; 2020 } 2021 1817 2022 set_next(p, interval); 1818 2023 } … … 1844 2049 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size); 1845 2050 free(addr); 2051 goto bail; 2052 } 2053 2054 /* Respond only to client and symmetric active packets */ 2055 if ((msg.m_status & MODE_MASK) != MODE_CLIENT 2056 && (msg.m_status & MODE_MASK) != MODE_SYM_ACT 2057 ) { 1846 2058 goto bail; 1847 2059 } … … 1979 2191 llist_t *peers; 1980 2192 1981 srand om(getpid());2193 srand(getpid()); 1982 2194 1983 2195 if (getuid()) … … 1985 2197 1986 2198 /* Set some globals */ 2199 G.discipline_jitter = G_precision_sec; 1987 2200 G.stratum = MAXSTRAT; 1988 2201 if (BURSTPOLL != 0) … … 1992 2205 /* Parse options */ 1993 2206 peers = NULL; 1994 opt_complementary = "dd:p::wn"; /* d: counter; p: list; -w implies -n */ 2207 opt_complementary = "dd:p::wn" /* -d: counter; -p: list; -w implies -n */ 2208 IF_FEATURE_NTPD_SERVER(":Il"); /* -I implies -l */ 1995 2209 opts = getopt32(argv, 1996 2210 "nqNx" /* compat */ 1997 2211 "wp:S:"IF_FEATURE_NTPD_SERVER("l") /* NOT compat */ 2212 IF_FEATURE_NTPD_SERVER("I:") /* compat */ 1998 2213 "d" /* compat */ 1999 2214 "46aAbgL", /* compat, ignored */ 2000 &peers, &G.script_name, &G.verbose); 2001 if (!(opts & (OPT_p|OPT_l))) 2002 bb_show_usage(); 2215 &peers,&G.script_name, 2216 #if ENABLE_FEATURE_NTPD_SERVER 2217 &G.if_name, 2218 #endif 2219 &G.verbose); 2220 2003 2221 // if (opts & OPT_x) /* disable stepping, only slew is allowed */ 2004 2222 // G.time_was_stepped = 1; … … 2006 2224 while (peers) 2007 2225 add_peers(llist_pop(&peers)); 2008 } else { 2226 } 2227 #if ENABLE_FEATURE_NTPD_CONF 2228 else { 2229 parser_t *parser; 2230 char *token[3]; 2231 2232 parser = config_open("/etc/ntp.conf"); 2233 while (config_read(parser, token, 3, 1, "# \t", PARSE_NORMAL)) { 2234 if (strcmp(token[0], "server") == 0 && token[1]) { 2235 add_peers(token[1]); 2236 continue; 2237 } 2238 bb_error_msg("skipping %s:%u: unimplemented command '%s'", 2239 "/etc/ntp.conf", parser->lineno, token[0] 2240 ); 2241 } 2242 config_close(parser); 2243 } 2244 #endif 2245 if (G.peer_cnt == 0) { 2246 if (!(opts & OPT_l)) 2247 bb_show_usage(); 2009 2248 /* -l but no peers: "stratum 1 server" mode */ 2010 2249 G.stratum = 1; 2011 }2012 if (!(opts & OPT_n)) {2013 bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv);2014 logmode = LOGMODE_NONE;2015 2250 } 2016 2251 #if ENABLE_FEATURE_NTPD_SERVER … … 2018 2253 if (opts & OPT_l) { 2019 2254 G_listen_fd = create_and_bind_dgram_or_die(NULL, 123); 2255 if (opts & OPT_I) { 2256 if (setsockopt_bindtodevice(G_listen_fd, G.if_name)) 2257 xfunc_die(); 2258 } 2020 2259 socket_want_pktinfo(G_listen_fd); 2021 setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); 2022 } 2023 #endif 2260 setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 2261 } 2262 #endif 2263 if (!(opts & OPT_n)) { 2264 bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO, argv); 2265 logmode = LOGMODE_NONE; 2266 } 2024 2267 /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */ 2025 2268 if (opts & OPT_N) … … 2109 2352 /* Time to send new req */ 2110 2353 if (--cnt == 0) { 2111 G.initial_poll_complete = 1; 2354 VERB4 bb_error_msg("disabling burst mode"); 2355 G.polladj_count = 0; 2356 G.poll_exp = MINPOLL; 2112 2357 } 2113 2358 send_query_to_peer(p); … … 2116 2361 close(p->p_fd); 2117 2362 p->p_fd = -1; 2118 timeout = poll_interval(-2); /* -2: try a bit sooner */ 2363 /* If poll interval is small, increase it */ 2364 if (G.poll_exp < BIGPOLL) 2365 adjust_poll(MINPOLL); 2366 timeout = poll_interval(NOREPLY_INTERVAL); 2119 2367 bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", 2120 2368 p->p_dotted, p->reachable_bits, timeout); 2369 2370 /* What if don't see it because it changed its IP? */ 2371 if (p->reachable_bits == 0) 2372 resolve_peer_hostname(p, /*loop_on_fail=*/ 0); 2373 2121 2374 set_next(p, timeout); 2122 2375 } … … 2160 2413 gettime1900d(); /* sets G.cur_time */ 2161 2414 if (nfds <= 0) { 2162 if (G.script_name && G.cur_time - G.last_script_run > 11*60) { 2415 if (!bb_got_signal /* poll wasn't interrupted by a signal */ 2416 && G.cur_time - G.last_script_run > 11*60 2417 ) { 2163 2418 /* Useful for updating battery-backed RTC and such */ 2164 2419 run_script("periodic", G.last_update_offset); 2165 2420 gettime1900d(); /* sets G.cur_time */ 2166 2421 } 2167 continue;2422 goto check_unsync; 2168 2423 } 2169 2424 … … 2195 2450 gettime1900d(); /* sets G.cur_time */ 2196 2451 } 2452 } 2453 2454 check_unsync: 2455 if (G.ntp_peers && G.stratum != MAXSTRAT) { 2456 for (item = G.ntp_peers; item != NULL; item = item->link) { 2457 peer_t *p = (peer_t *) item->data; 2458 if (p->reachable_bits) 2459 goto have_reachable_peer; 2460 } 2461 /* No peer responded for last 8 packets, panic */ 2462 clamp_pollexp_and_set_MAXSTRAT(); 2463 run_script("unsync", 0.0); 2464 have_reachable_peer: ; 2197 2465 } 2198 2466 } /* while (!bb_got_signal) */
Note:
See TracChangeset
for help on using the changeset viewer.