Compare commits

...

22 Commits

Author SHA1 Message Date
Miroslav Lichvar
db286ca6ea doc: update NEWS 2016-11-21 12:03:45 +01:00
Miroslav Lichvar
85fbfd9b15 sources: add new status for sources that overlap trusted sources
Sources that overlap trusted sources should be displayed in the chronyc
sources report with the '-' symbol and they shouldn't trigger a
replacement.
2016-11-21 12:03:45 +01:00
Miroslav Lichvar
b819c7fe55 refclock: don't compare sample time with samples from previous poll
This is an improvement of commit 0a848e2528.
2016-11-21 12:03:27 +01:00
Miroslav Lichvar
2b5c86b9a3 refclock: fix check for old samples
The fix in commit 0a848e2528 was
incorrect.
2016-11-21 12:03:15 +01:00
Miroslav Lichvar
0a848e2528 refclock: require new samples to have newer timestamp
If all or most SHM/SOCK samples collected in a polling interval had the
same local timestamp, the dispersion could end up as nan, which could
trigger an assert failure later in the code.

Before accumulating a refclock sample, check if the timestamp is newer
than the previous one.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
b443ec5ea5 test: add smooth unit test 2016-11-21 12:02:51 +01:00
Miroslav Lichvar
37d1467368 smooth: fix selection of 1st stage direction
When the smoothing process is updated with extremely small (e.g.
sub-nanosecond) values, both directions may give a negative length of
the 1st or 3rd stage due to numerical errors and the selection will fail
an in assertion. Rework the code to select the direction which gives a
smaller error.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
1d9d19d76b client: flush stdout after printing prompt
Apparently fgets() doesn't flush stdout in some libc implementations.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
9603f0552a client: fix printing of negative poll in sources report again
This was broken in commit 3f51805e62.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
12befc2afd ntp: fix processing of kernel timestamps on non-Linux systems
When the SO_TIMESTAMP socket option was enabled, the expected type of
control messages containing timestamps was SO_TIMESTAMP instead of
SCM_TIMESTAMP. This worked on Linux, where the two values are equal, but
not on the other supported systems. The timestamps were ignored and this
probably worsened the accuracy and stability of the synchronisation.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
78f20f7b3e conf: fix parsing of refclock directive
Don't accept refclock directive which has as the last argument an option
that requires a value.
2016-11-21 12:02:51 +01:00
Miroslav Lichvar
b703bc32c9 doc: update NEWS 2016-06-07 11:20:59 +02:00
Miroslav Lichvar
09afdd4b36 doc: update README 2016-06-07 11:20:59 +02:00
Miroslav Lichvar
5cadaf8d55 doc: add question about reference ID to FAQ 2016-06-07 11:20:59 +02:00
Stephen Wadeley
89ac745184 doc: improve chronyc man page
- fix redundant words, word order, articles, consistency, typos
- avoid slashes, contractions, `may`, dashes in running text
- add Oxford commas
- use colon before examples
2016-06-07 09:36:55 +02:00
Stephen Wadeley
e2422023c4 doc: improve chrony.conf man page
- fix word order, articles, consistency, and some typos
- avoid slashes, contractions, `may`, dashes in running text
- use colons before example and code blocks
- add Oxford commas
2016-06-07 09:36:55 +02:00
Miroslav Lichvar
1ec0813663 client: fix compiler warnings on NetBSD 2016-06-07 09:36:55 +02:00
Miroslav Lichvar
6ba7fad2a7 reference: suppress orphan option in special reference modes
This allows a server that will become the orphan source to initialize
its time with the initstepslew directive from the current orphan source
or its clients.
2016-05-30 14:12:42 +02:00
Miroslav Lichvar
962ca91574 doc: improve answer in FAQ for firewall issue 2016-05-23 09:01:10 +02:00
Miroslav Lichvar
91cbebb629 examples: update chrony.spec 2016-05-17 17:57:33 +02:00
Miroslav Lichvar
722f038f1f test: extend 105-ntpauth 2016-05-17 13:03:53 +02:00
Miroslav Lichvar
5e61c002a6 ntp: fix definition of minimum and maximum MAC length
The NTP_*_MAC_LENGTH macros didn't include the key ID, which caused the
NTP authentication check to ignore MACs with 512-bit hashes (SHA512,
WHIRLPOOL).

This was broken since update to NTPv4.
2016-05-17 12:57:28 +02:00
16 changed files with 500 additions and 344 deletions

11
NEWS
View File

@@ -1,3 +1,13 @@
New in version 2.4.1
====================
Bug fixes
---------
* Fix processing of kernel timestamps on non-Linux systems
* Fix crash with smoothtime directive
* Fix validation of refclock sample times
* Fix parsing of refclock directive
New in version 2.4
==================
@@ -19,6 +29,7 @@ Bug fixes
---------
* Fix SOCK refclock to work correctly when not specified as last refclock
* Fix initstepslew and -q/-Q options to accept time from own NTP clients
* Fix authentication with keys using 512-bit hash functions
* Fix crash on exit when multiple signals are received
* Fix conversion of very small floating-point numbers in command packets

4
README
View File

@@ -141,6 +141,7 @@ Erik Bryer <ebryer@spots.ab.ca>
Bryan Christianson <bryan@whatroute.net>
Support for Mac OS X
Support for privilege separation
Entries in contrib directory
Juliusz Chroboczek <jch@pps.jussieu.fr>
Fix install rule in Makefile if chronyd file is in use.
@@ -227,6 +228,9 @@ Andreas Piesk <apiesk@virbus.de>
Timo Teras <timo.teras@iki.fi>
Patch to reply correctly on multihomed hosts
Stephen Wadeley <swadeley@redhat.com>
Improvements to man pages
Wolfgang Weisselberg <weissel@netcologne.de>
Entries in contrib directory

View File

@@ -125,6 +125,7 @@ read_line(void)
return( line );
#else
printf("%s", prompt);
fflush(stdout);
#endif
}
if (fgets(line, sizeof(line), stdin)) {
@@ -1732,16 +1733,16 @@ print_report(const char *format, ...)
format++;
}
if (isdigit(*format)) {
if (isdigit((unsigned char)*format)) {
width = atoi(format);
while (isdigit(*format))
while (isdigit((unsigned char)*format))
format++;
}
if (*format == '.') {
format++;
prec = atoi(format);
while (isdigit(*format))
while (isdigit((unsigned char)*format))
format++;
}
@@ -2007,7 +2008,7 @@ process_cmd_sources(char *line)
print_report("%c%c %-27s %2d %2d %3o %I %+S[%+S] +/- %S\n",
mode_ch, state_ch, name,
ntohs(reply.data.source_data.stratum),
ntohs(reply.data.source_data.poll),
(int16_t)ntohs(reply.data.source_data.poll),
ntohs(reply.data.source_data.reachability),
(unsigned long)ntohl(reply.data.source_data.since_sample),
UTI_FloatNetworkToHost(reply.data.source_data.latest_meas),

7
conf.c
View File

@@ -696,9 +696,9 @@ parse_refclock(char *line)
line = CPS_SplitWord(line);
param = Strdup(p);
while (*line) {
cmd = line;
for (cmd = line; *cmd; line += n, cmd = line) {
line = CPS_SplitWord(line);
if (!strcasecmp(cmd, "refid")) {
if (sscanf(line, "%4s%n", (char *)ref, &n) != 1)
break;
@@ -756,10 +756,9 @@ parse_refclock(char *line)
other_parse_error("Invalid refclock option");
return;
}
line += n;
}
if (*line) {
if (*cmd) {
command_parse_error();
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -37,10 +37,10 @@ running.
If no commands are specified on the command line, *chronyc* will expect input
from the user. The prompt _chronyc>_ will be displayed when it is being run
from a terminal. If *chronyc*'s input or output are redirected from/to a file,
from a terminal. If *chronyc*'s input or output are redirected from or to a file,
the prompt is not shown.
There are two ways how *chronyc* can access *chronyd*. One is the Internet
There are two ways *chronyc* can access *chronyd*. One is the Internet
Protocol (IPv4 or IPv6) and the other is a Unix domain socket, which is
accessible locally by the root or _chrony_ user. By default, *chronyc* first
tries to connect to the Unix domain socket. The compiled-in default path is
@@ -48,18 +48,18 @@ _@CHRONYSOCKDIR@/chronyd.sock_. If that fails (e.g. because *chronyc* is
running under a non-root user), it will try to connect to 127.0.0.1 and then
::1.
Only the following monitoring commands, which don't affect the behaviour of
*chronyd*, are allowed from the internet: *activity*, *manual list*,
Only the following monitoring commands, which do not affect the behaviour of
*chronyd*, are allowed from the network: *activity*, *manual list*,
*rtcdata*, *smoothing*, *sources*, *sourcestats*, *tracking*, *waitsync*. The
set of hosts from which *chronyd* will accept these commands can be configured
with the <<chrony.conf.adoc#cmdallow,*cmdallow*>> directive in the *chronyd*'s
configuration file or the <<cmdallow,*cmdallow*>> command in *chronyc*. By
default, the commands are accepted only from the localhost (127.0.0.1 or ::1).
default, the commands are accepted only from localhost (127.0.0.1 or ::1).
All other commands are allowed only through the Unix domain socket. When sent
over the internet, *chronyd* will respond with a '`Not authorised`' error, even
if it's from the localhost. In chrony versions before 2.2 they were allowed
from the internet if they were authenticated with a password, but that is no
over the network, *chronyd* will respond with a '`Not authorised`' error, even
if it is from localhost. In chrony versions before 2.2 they were allowed
from the network if they were authenticated with a password, but that is no
longer supported.
Having full access to *chronyd* via *chronyc* is more or less equivalent to
@@ -85,7 +85,7 @@ to other units.
*-d*::
This option enables printing of debugging messages if *chronyc* was compiled
with debugging support).
with debugging support.
*-m*::
Normally, all arguments on the command line are interpreted as one command.
@@ -95,9 +95,9 @@ interpreted as a whole command.
*-h* _host_::
This option allows the user to specify which host (or comma-separated list of
addresses) running the *chronyd* program is to be contacted. This allows for
remote monitoring, without having to ssh to the other host first.
remote monitoring, without having to connect over SSH to the other host first.
+
The default is to contact *chronyd* running on the same host as that where
The default is to contact *chronyd* running on the same host where
*chronyc* is being run.
*-p* _port_::
@@ -147,7 +147,7 @@ The fields are explained as follows:
*Reference ID*:::
This is the reference ID and name (or IP address) of the server to which the
computer is currently synchronised. For IPv4 addresses, the reference ID is
equal to the address and for IPv6 addresses it's the first 32 bits of the MD5
equal to the address and for IPv6 addresses it is the first 32 bits of the MD5
sum of the address.
+
If it is _127.127.1.1_ it means the computer is not synchronised to any
@@ -164,7 +164,7 @@ This is the time (UTC) at which the last measurement from the reference
source was processed.
*System time*:::
In normal operation, *chronyd* by default never steps the system clock, because
any jump in the timescale can have adverse consequences for certain application
any jump in the time can have adverse consequences for certain application
programs. Instead, any error in the system clock is corrected by slightly
speeding up or slowing down the system clock until the error has been removed,
and then returning to the system clock's normal speed. A consequence of this is
@@ -184,7 +184,7 @@ has advanced 1 second, it has actually advanced by 1.000001 seconds relative to
true time.
+
As you can see in the example, the clock in the computer is not a very
good one - it would gain about 30 seconds per day if it wasn't corrected!
good one; it would gain about 30 seconds per day if it was not corrected!
*Residual freq*:::
This shows the '`residual frequency`' for the currently selected reference
source. This reflects any difference between what the measurements from the
@@ -200,7 +200,7 @@ computed for the new frequency, with weights depending on these accuracies.
If the measurements from the reference source follow a consistent trend, the
residual will be driven to zero over time.
*Skew*:::
This is the estimated error bound on the the frequency.
This is the estimated error bound on the frequency.
*Root delay*:::
This is the total of the network path delays to the stratum-1 computer from
which the computer is ultimately synchronised.
@@ -211,7 +211,7 @@ Dispersion is due to system clock resolution, statistical measurement
variations, etc.
+
An absolute bound on the computer's clock accuracy (assuming the stratum-1
computer is correct) is given by
computer is correct) is given by:
+
----
clock_error <= root_dispersion + (0.5 * |root_delay|)
@@ -226,7 +226,7 @@ second_ or _Not synchronised_.
*makestep* _threshold_ _limit_::
Normally *chronyd* will cause the system to gradually correct any time offset,
by slowing down or speeding up the clock as required. In certain situations,
the system clock may be so far adrift that this slewing process would take a
the system clock might be so far adrift that this slewing process would take a
very long time to correct the system clock.
+
The *makestep* command can be used in this situation. There are two forms of
@@ -237,7 +237,7 @@ equivalent amount, making it correct immediately.
The second form configures the automatic stepping, similarly to the
<<chrony.conf.adoc#makestep,*makestep*>> directive. It has two parameters,
stepping threshold (in seconds) and number of future clock updates for which
will be the threshold active. This can be used with the <<burst,*burst*>>
the threshold will be active. This can be used with the <<burst,*burst*>>
command to quickly make a new measurement and correct the clock by stepping if
needed, without waiting for *chronyd* to complete the measurement and update
the clock.
@@ -247,7 +247,7 @@ makestep 0.1 1
burst 1/2
----
+
BE WARNED - certain software will be seriously affected by such jumps to the
BE WARNED: Certain software will be seriously affected by such jumps in the
system time. (That is the reason why *chronyd* uses slewing normally.)
[[maxupdateskew]]*maxupdateskew* _skew-in-ppm_::
@@ -270,7 +270,7 @@ specified or zero, the value will not be checked.
The fourth argument is the interval specified in seconds in which the check is
repeated. The interval is 10 seconds by default.
+
An example is
An example is:
+
----
waitsync 60 0.01
@@ -311,13 +311,13 @@ This column indicates the state of the source.
* _-_ indicates acceptable sources which are excluded by the combining
algorithm.
* _?_ indicates sources to which connectivity has been lost or whose packets
don't pass all tests. It's also shown at start-up, until at least 3 samples
do not pass all tests. It is also shown at start-up, until at least 3 samples
have been gathered from it.
* _x_ indicates a clock which *chronyd* thinks is a falseticker (i.e. its
time is inconsistent with a majority of other sources).
* _~_ indicates a source whose time appears to have too much variability.
*Name/IP address*:::
This shows the name or the IP address of the source, or refid for reference
This shows the name or the IP address of the source, or reference ID for reference
clocks.
*Stratum*:::
This shows the stratum of the source, as reported in its most recently
@@ -331,23 +331,23 @@ logarithm of the interval in seconds. Thus, a value of 6 would indicate that
a measurement is being made every 64 seconds. *chronyd* automatically varies
the polling rate in response to prevailing conditions.
*Reach*:::
This shows the source's reachability register printed as octal number. The
This shows the source's reachability register printed as an octal number. The
register has 8 bits and is updated on every received or missed packet from
the source. A value of 377 indicates that a valid reply was received for all
from the last eight transmissions.
*LastRx*:::
This column shows how long ago the last sample was received from the source.
This is normally in seconds. The letters _m_, _h_, _d_ or _y_ indicate
minutes, hours, days or years.
minutes, hours, days, or years.
*Last sample*:::
This column shows the offset between the local clock and the source at the
last measurement. The number in the square brackets shows the actual measured
offset. This may be suffixed by _ns_ (indicating nanoseconds), _us_
offset. This can be suffixed by _ns_ (indicating nanoseconds), _us_
(indicating microseconds), _ms_ (indicating milliseconds), or _s_ (indicating
seconds). The number to the left of the square brackets shows the original
measurement, adjusted to allow for any slews applied to the local clock
since. The number following the _+/-_ indicator shows the margin of error in
the measurement. Positive offsets indicate that the local clock is fast of
the measurement. Positive offsets indicate that the local clock is ahead of
the source.
[[sourcestats]]*sourcestats* [*-v*]::
@@ -358,7 +358,7 @@ estimation process for each of the sources currently being examined by
The optional argument *-v* can be specified, meaning _verbose_. In this case,
extra caption lines are shown as a reminder of the meanings of the columns.
+
An example report is
An example report is:
+
----
210 Number of sources = 1
@@ -370,8 +370,8 @@ foo.example.net 11 5 46m -0.001 0.045 1us 25us
The columns are as follows:
+
*Name/IP Address*:::
This is the name or IP address of the NTP server (or peer) or refid of the
refclock to which the rest of the line relates.
This is the name or IP address of the NTP server (or peer) or reference ID of the
reference clock to which the rest of the line relates.
*NP*:::
This is the number of sample points currently being retained for the server.
The drift rate and current offset are estimated by performing a linear
@@ -398,7 +398,7 @@ This is the estimated offset of the source.
This is the estimated sample standard deviation.
[[reselect]]*reselect*::
To avoid excessive switching between sources, *chronyd* may stay synchronised
To avoid excessive switching between sources, *chronyd* can stay synchronised
to a source even when it is not currently the best one among the available
sources.
+
@@ -413,28 +413,28 @@ configuration file.
=== NTP sources
[[activity]]*activity*::
This command reports the number of servers/peers that are online and offline.
If the auto_offline option is used in specifying some of the servers/peers, the
*activity* command may be useful for detecting when all of them have entered
the offline state after the network link has been disconnected.
This command reports the number of servers and peers that are online and
offline. If the *auto_offline* option is used in specifying some of the servers
or peers, the *activity* command can be useful for detecting when all of them
have entered the offline state after the network link has been disconnected.
+
The report shows the number of servers/peers in 5 states:
The report shows the number of servers and peers in 5 states:
+
*online*:::
the server/peer is currently online (i.e. assumed by chronyd to be reachable)
the server or peer is currently online (i.e. assumed by *chronyd* to be reachable)
*offline*:::
the server/peer is currently offline (i.e. assumed by chronyd to be
the server or peer is currently offline (i.e. assumed by *chronyd* to be
unreachable, and no measurements from it will be attempted.)
*burst_online*:::
a burst command has been initiated for the server/peer and is being
performed; after the burst is complete, the server/peer will be returned to
a burst command has been initiated for the server or peer and is being
performed; after the burst is complete, the server or peer will be returned to
the online state.
*burst_offline*:::
a burst command has been initiated for the server/peer and is being
performed; after the burst is complete, the server/peer will be returned to
a burst command has been initiated for the server or peer and is being
performed; after the burst is complete, the server or peer will be returned to
the offline state.
*unresolved*:::
the name of the server/peer wasn't resolved to an address yet; this server is
the name of the server or peer was not resolved to an address yet; this source is
not visible in the *sources* and *sourcestats* reports.
[[add_peer]]*add peer* _address_ [_option_]...::
@@ -463,7 +463,7 @@ directive in the configuration file.
The following server options can be set in the command: *port*, *minpoll*,
*maxpoll*, *presend*, *maxdelayratio*, *maxdelay*, *key*.
+
An example of using this command is shown below.
An example of using this command is shown below:
+
----
add server foo.example.net minpoll 6 maxpoll 10 key 25
@@ -517,7 +517,7 @@ that source.
If no _mask_ or _masked-address_ arguments are provided, every source will be
matched.
+
An example of the two-argument form of the command is
An example of the two-argument form of the command is:
+
----
burst 2/10
@@ -527,7 +527,7 @@ This will cause *chronyd* to attempt to get two good measurements from each
source, stopping after two have been obtained, but in no event will it try more
than ten probes to the source.
+
Examples of the four-argument form of the command are
Examples of the four-argument form of the command are:
+
----
burst 2/10 255.255.0.0/1.2.0.0
@@ -539,7 +539,7 @@ whose IPv4 addresses are of the form _1.2.x.y_, where _x_ and _y_ are
arbitrary. In the second case, the sampling will be applied to sources whose
IPv6 addresses have first 48 bits equal to _2001:db8:789a_.
+
Example of the three-argument form of the command is
Example of the three-argument form of the command is:
+
----
burst 2/10 foo.example.net
@@ -594,13 +594,13 @@ local group of computers, and has a permanent connection to true time servers
outside the organisation. However, the external connection is heavily loaded at
certain times of the day and the measurements obtained are less reliable at
those times. In this case, it is probably most useful to determine the
gain/loss rate during the quiet periods and let the whole network coast through
gain or loss rate during the quiet periods and let the whole network coast through
the loaded periods. The *offline* and *online* commands can be used to achieve
this.
+
There are four forms of the *offline* command. The first form is a wildcard,
meaning all sources. The second form allows an IP address mask and a masked
address to be specified. The third form uses the CIDR notation. The fourth form
address to be specified. The third form uses CIDR notation. The fourth form
uses an IP address or a hostname. These forms are illustrated below.
+
----
@@ -614,10 +614,10 @@ The second form means that the *offline* command is to be applied to any source
whose IPv4 address is in the _1.2.3_ subnet. (The host's address is logically
and-ed with the mask, and if the result matches the _masked-address_ the host
is processed.) The third form means that the command is to be applied to all
sources whose IPv6 addresses have first 48 bits equal to _2001:db8:789a_. The
sources whose IPv6 addresses have their first 48 bits equal to _2001:db8:789a_. The
fourth form means that the command is to be applied only to that one source.
+
The wildcard form of the address is actually equivalent to
The wildcard form of the address is equivalent to:
+
----
offline 0.0.0.0/0.0.0.0
@@ -645,7 +645,7 @@ configured sources to IP addresses again, e.g. after suspending and resuming
the machine in a different network.
+
Sources that stop responding will be replaced with newly resolved addresses
automatically after 8 polling intervals, but this command may still be useful
automatically after 8 polling intervals, but this command can still be useful
to replace them immediately and not wait until they are marked as unreachable.
=== Manual time input
@@ -673,7 +673,7 @@ The *list* form of the command lists all the samples currently stored in
0 27Jan99 22:09:20 0.00 0.97 0.00
----
+
The columns as as follows:
The columns are as as follows:
+
. The sample index (used for the *manual delete* command).
. The date and time of the sample.
@@ -691,7 +691,7 @@ index of the sample, as shown in the first column of the output from *manual
list*. Following deletion of the data point, the current error and drift rate
are re-estimated from the remaining data points and the system clock trimmed if
necessary. This option is intended to allow '`outliers`' to be discarded, i.e.
samples where the administrator realises s/he has entered a very poor
samples where the administrator realises they have entered a very poor
timestamp.
+
The *reset* form of the command deletes all samples at once. The system clock
@@ -699,7 +699,7 @@ is left running as it was before the command was entered.
[[settime]]*settime* _time_::
The *settime* command allows the current time to be entered manually, if this
option has been configured into *chronyd*. (It may be configured either with
option has been configured into *chronyd*. (It can be configured either with
the <<chrony.conf.adoc#manual,*manual*>> directive in the configuration file,
or with the <<manual,*manual*>> command of *chronyc*.)
+
@@ -720,13 +720,13 @@ present run of *chronyd*. However, the entered measurement is used for
adjusting the current clock offset (rather than the estimated intercept from
the regression, which is ignored). Contrast what happens with the
<<manual,*manual delete*>> command, where the intercept is used to set the
current offset (since there is no measurement that has just been typed in in
current offset (since there is no measurement that has just been entered in
that case).
+
The time is parsed by the public domain _getdate_ algorithm. Consequently, you
can only specify time to the nearest second.
+
Examples of inputs that are valid are shown below.
Examples of inputs that are valid are shown below:
+
----
settime 16:30
@@ -734,7 +734,7 @@ settime 16:30:05
settime Nov 21, 2015 16:30:05
----
+
For a full description of getdate, get hold of the getdate documentation
For a full description of getdate, see the getdate documentation
(bundled, for example, with the source for GNU tar).
=== NTP access
@@ -752,15 +752,15 @@ accheck 2001:db8::1
----
+
This command can be used to examine the effect of a series of *allow*, *allow
all*, *deny* and *deny all* commands specified either via *chronyc*, or in
all*, *deny*, and *deny all* commands specified either via *chronyc*, or in
*chronyd*'s configuration file.
[[clients]]*clients*::
This command shows a list of clients that have accessed the server, through
either the NTP or command/monitoring ports. It doesn't include accesses over
the Unix domain comamnd socket. There are no arguments.
either the NTP or command ports. It does not include accesses over
the Unix domain command socket. There are no arguments.
+
An example of the output is
An example of the output is:
+
----
Hostname NTP Drop Int IntL Last Cmd Drop Int Last
@@ -889,7 +889,7 @@ time observed by clients is running slower than true time.
The current frequency wander of the served time. Negative value means the
time observed by clients is slowing down.
*Last update*:::
This field shows how long ago was the time smoothing process updated, e.g.
This field shows how long ago the time smoothing process was updated, e.g.
*chronyd* accumulated a new measurement.
*Remaining time*:::
The time it would take for the smoothing process to get to zero offset and
@@ -942,13 +942,13 @@ RTC is fast by : -1.632736 seconds
RTC gains time at : -107.623 ppm
----
+
The fields have the following meaning
The fields have the following meaning:
+
*RTC ref time (GMT)*:::
This is the RTC reading the last time its error was measured.
*Number of samples*:::
This is the number of previous measurements being used to determine the RTC
gain/loss rate.
gain or loss rate.
*Number of runs*:::
This is the number of runs of residuals of the same sign following the
regression fit for (RTC error) versus (RTC time). A value which is small
@@ -958,11 +958,11 @@ the fit.
*Sample span period*:::
This is the period that the measurements span (from the oldest to the
newest). Without a unit the value is in seconds; suffixes _m_ for minutes,
_h_ for hours, _d_ for days or _y_ for years may be used.
_h_ for hours, _d_ for days or _y_ for years can be used.
*RTC is fast by*:::
This is the estimate of how many seconds fast the RTC when it thought
the time was at the reference time (above). If this value is large, you
may (or may not) want to use the <<trimrtc,*trimrtc*>> command to bring the
might (or might not) want to use the <<trimrtc,*trimrtc*>> command to bring the
RTC into line with the system clock. (Note, a large error will not affect
*chronyd*'s operation, unless it becomes so big as to start causing rounding
errors.)
@@ -981,7 +981,7 @@ currently estimated at less than a second.
The command takes no arguments. It performs the following steps (if the RTC is
more than 1 second away from the system clock):
+
. Remember the currently estimated gain/loss rate of the RTC and flush the
. Remember the currently estimated gain or loss rate of the RTC and flush the
previous measurements.
. Step the real-time clock to bring it within a second of the system clock.
. Make several measurements to accurately determine the new offset between
@@ -1006,7 +1006,7 @@ The *trimrtc* command can be executed automatically by *chronyd* with the
file.
[[writertc]]*writertc*::
The *writertc* command writes the currently estimated error and gain/loss rate
The *writertc* command writes the currently estimated error and gain or loss rate
parameters for the RTC to the RTC file (specified with the
<<chrony.conf.adoc#rtcfile,*rtcfile*>> directive). This information is also
written automatically when *chronyd* is killed (by the SIGHUP, SIGINT, SIGQUIT
@@ -1037,7 +1037,7 @@ The *dump* command is somewhat equivalent to the
<<chrony.conf.adoc#dumponexit,*dumponexit*>> directive in the configuration
file.
+
To use the *dump*, you probably want to configure the name of the
To use the *dump* command, you might want to configure the name of the
directory into which the dump files will be written. This can only be
done in the configuration file with the <<chrony.conf.adoc#dumpdir,*dumpdir*>>
directive.
@@ -1045,7 +1045,7 @@ directive.
=== Client commands
[[dns]]*dns* _option_::
The *dns* command configures how are hostnames and IP addresses resolved in
The *dns* command configures how hostnames and IP addresses are resolved in
*chronyc*. IP addresses can be resolved to hostnames when printing results of
<<sources,*sources*>>, <<sourcestats,*sourcestats*>>, <<tracking,*tracking*>>
and <<clients,*clients*>> commands. Hostnames are resolved in commands that
@@ -1086,7 +1086,7 @@ The default is 2.
The *keygen* command generates a key that can be added to the
key file (specified with the <<chrony.conf.adoc#keyfile,*keyfile*>> directive)
to allow NTP authentication between server and client, or peers. The key is
generated from the _/dev/urandom_ device and it's printed to standard output.
generated from the _/dev/urandom_ device and it is printed to standard output.
+
The command has three optional arguments. The first argument is the key number
(by default 1), which will be specified with the *key* option of the *server*
@@ -1095,13 +1095,13 @@ function (by default SHA1 or MD5 if SHA1 is not available) and the third
argument is the number of bits the key should have, between 80 and 4096 bits
(by default 160 bits).
+
An example is
An example is:
+
----
keygen 73 SHA1 256
----
+
which generates a 256-bit SHA-1 key with number 73. The printed line would
which generates a 256-bit SHA1 key with number 73. The printed line should
then be securely transferred and added to the key files on both server and
client, or peers.
@@ -1123,4 +1123,4 @@ https://chrony.tuxfamily.org/.
== AUTHORS
chrony was written by Richard Curnow, Miroslav Lichvar and others.
chrony was written by Richard Curnow, Miroslav Lichvar, and others.

View File

@@ -205,13 +205,24 @@ following questions.
=== Behind a firewall?
If there is a firewall between you and the NTP server you're trying to use, the
packets may be blocked. Try using a tool like `wireshark` or `tcpdump` to see if
you're getting responses from the server. If you have an external modem, see
if the receive light blinks straight after the transmit light (when the link is
quiet apart from the NTP traffic). Try adding `log measurements` to the
_chrony.conf_ file and look in the _measurements.log_ file after `chronyd` has
been running for a short period. See if any measurements appear.
Check the `Reach` value printed by the ``chronyc``'s `sources` command. If it's
zero, it means `chronyd` did not get any valid responses from the NTP server
you are trying to use. If there is a firewall between you and the server, the
packets may be blocked. Try using a tool like `wireshark` or `tcpdump` to see
if you're getting any responses from the server.
When `chronyd` is receiving responses from the servers, the output of the
`sources` command issued few minutes after `chronyd` start might look like
this:
----
210 Number of sources = 3
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* foo.example.net 2 6 377 34 +484us[ -157us] +/- 30ms
^- bar.example.net 2 6 377 34 +33ms[ +32ms] +/- 47ms
^+ baz.example.net 3 6 377 35 -1397us[-2033us] +/- 60ms
----
=== Are NTP servers specified with the `offline` option?
@@ -274,6 +285,19 @@ configuration file needs to specify a file which contains keys (`keyfile`
directive) and which key in the key file should be used for `chronyc`
authentication (`commandkey` directive).
=== Why does `chronyc tracking` always print an IPv4 address as reference ID?
The reference ID is a 32-bit value and is always printed in quad-dotted
notation, even if the reference source doesn't have an IPv4 address. For IPv4
addresses, the reference ID is equal to the address, but for IPv6 addresses it
is the first 32 bits of the MD5 sum of the address. For reference clocks, the
reference ID is the value specified with the `refid` option in the `refclock`
directive.
If you need to get the IP address of the current reference source, use the `-n`
option to disable resolving of IP addresses and read the second field (printed
in parentheses) on the `Reference ID` line.
=== Is the `chronyc` / `chronyd` protocol documented anywhere?
Only by the source code. See _cmdmon.c_ (`chronyd` side) and _client.c_

View File

@@ -10,7 +10,6 @@ Source: chrony-%{version}%{?prerelease:-%{prerelease}}.tar.gz
License: GPLv2
Group: Applications/Utilities
BuildRoot: %{_tmppath}/%{name}-%{version}-root-%(id -u -n)
Requires: info
%description
chrony is a client and server for the Network Time Protocol (NTP).
@@ -28,29 +27,20 @@ manual input as time references.
--prefix=%{_prefix} \
--bindir=%{_bindir} \
--sbindir=%{_sbindir} \
--infodir=%{_infodir} \
--mandir=%{_mandir}
make
make chrony.txt
make chrony.info
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
rm -rf $RPM_BUILD_ROOT%{_docdir}
mkdir -p $RPM_BUILD_ROOT%{_infodir}
cp chrony.info* $RPM_BUILD_ROOT%{_infodir}
%files
%{_sbindir}/chronyd
%{_bindir}/chronyc
%{_infodir}/chrony.info*
%{_mandir}/man1/chronyc.1.gz
%{_mandir}/man5/chrony.conf.5.gz
%{_mandir}/man8/chronyd.8.gz
%doc README
%doc chrony.txt
%doc COPYING
%doc README FAQ NEWS COPYING
%doc examples/chrony.conf.example*
%doc examples/chrony.keys.example

6
ntp.h
View File

@@ -53,8 +53,8 @@ typedef uint32_t NTP_int32;
#define NTP_MAX_EXTENSIONS_LENGTH 1024
/* The minimum and maximum supported length of MAC */
#define NTP_MIN_MAC_LENGTH 16
#define NTP_MAX_MAC_LENGTH MAX_HASH_LENGTH
#define NTP_MIN_MAC_LENGTH (4 + 16)
#define NTP_MAX_MAC_LENGTH (4 + MAX_HASH_LENGTH)
/* Type definition for leap bits */
typedef enum {
@@ -91,7 +91,7 @@ typedef struct {
/* Optional message authentication code (MAC) */
NTP_int32 auth_keyid;
uint8_t auth_data[NTP_MAX_MAC_LENGTH];
uint8_t auth_data[NTP_MAX_MAC_LENGTH - 4];
} NTP_Packet;
#define NTP_NORMAL_PACKET_LENGTH (int)offsetof(NTP_Packet, auth_keyid)

View File

@@ -556,7 +556,7 @@ read_from_socket(void *anything)
#endif
#ifdef SO_TIMESTAMP
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) {
struct timeval tv;
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));

View File

@@ -92,7 +92,7 @@ static ARR_Instance refclocks;
static LOG_FileID logfileid;
static int valid_sample_time(RCL_Instance instance, struct timeval *tv);
static int valid_sample_time(RCL_Instance instance, struct timeval *raw, struct timeval *cooked);
static int pps_stratum(RCL_Instance instance, struct timeval *tv);
static void poll_timeout(void *arg);
static void slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
@@ -106,6 +106,7 @@ static void filter_reset(struct MedianFilter *filter);
static double filter_get_avg_sample_dispersion(struct MedianFilter *filter);
static void filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset, double dispersion);
static int filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
static int filter_get_samples(struct MedianFilter *filter);
static int filter_select_samples(struct MedianFilter *filter);
static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset);
@@ -372,7 +373,7 @@ RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset,
/* Make sure the timestamp and offset provided by the driver are sane */
if (!UTI_IsTimeOffsetSane(sample_time, offset) ||
!valid_sample_time(instance, sample_time))
!valid_sample_time(instance, sample_time, &cooked_time))
return 0;
switch (leap) {
@@ -412,7 +413,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
dispersion += instance->precision;
if (!UTI_IsTimeOffsetSane(pulse_time, 0.0) ||
!valid_sample_time(instance, pulse_time))
!valid_sample_time(instance, pulse_time, &cooked_time))
return 0;
rate = instance->pps_rate;
@@ -503,18 +504,25 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
}
static int
valid_sample_time(RCL_Instance instance, struct timeval *tv)
valid_sample_time(RCL_Instance instance, struct timeval *raw, struct timeval *cooked)
{
struct timeval raw_time;
double diff;
struct timeval raw_time, last_sample_time;
double diff, last_offset, last_dispersion;
LCL_ReadRawTime(&raw_time);
UTI_DiffTimevalsToDouble(&diff, &raw_time, tv);
if (diff < 0.0 || diff > UTI_Log2ToDouble(instance->poll + 1)) {
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f tv=%s",
UTI_RefidToString(instance->ref_id), diff, UTI_TimevalToString(tv));
UTI_DiffTimevalsToDouble(&diff, &raw_time, raw);
if (diff < 0.0 || diff > UTI_Log2ToDouble(instance->poll + 1) ||
(filter_get_samples(&instance->filter) > 0 &&
filter_get_last_sample(&instance->filter, &last_sample_time,
&last_offset, &last_dispersion) &&
UTI_CompareTimevals(&last_sample_time, cooked) >= 0)) {
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f raw=%s cooked=%s",
UTI_RefidToString(instance->ref_id), diff,
UTI_TimevalToString(raw), UTI_TimevalToString(cooked));
return 0;
}
return 1;
}
@@ -719,6 +727,12 @@ filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time,
return 1;
}
static int
filter_get_samples(struct MedianFilter *filter)
{
return filter->used;
}
static const struct FilterSample *tmp_sorted_array;
static int

View File

@@ -1248,7 +1248,7 @@ REF_GetOurStratum(void)
int
REF_GetOrphanStratum(void)
{
if (!enable_local_stratum || !local_orphan)
if (!enable_local_stratum || !local_orphan || mode != REF_ModeNormal)
return NTP_MAX_STRATUM;
return local_stratum;
}

View File

@@ -137,7 +137,7 @@ get_smoothing(struct timeval *now, double *poffset, double *pfreq,
static void
update_stages(void)
{
double s1, s2, s, l1, l2, l3, lc, f, f2;
double s1, s2, s, l1, l2, l3, lc, f, f2, l1t[2], l3t[2], err[2];
int i, dir;
/* Prepare the three stages so that the integral of the frequency offset
@@ -146,22 +146,41 @@ update_stages(void)
s1 = smooth_offset / max_wander;
s2 = smooth_freq * smooth_freq / (2.0 * max_wander * max_wander);
l1 = l2 = l3 = 0.0;
/* Calculate the lengths of the 1st and 3rd stage assuming there is no
frequency limit. If length of the 1st stage comes out negative, switch
its direction. */
for (dir = -1; dir <= 1; dir += 2) {
frequency limit. The direction of the 1st stage is selected so that
the lengths will not be negative. With extremely small offsets both
directions may give a negative length due to numerical errors, so select
the one which gives a smaller error. */
for (i = 0, dir = -1; i <= 1; i++, dir += 2) {
err[i] = 0.0;
s = dir * s1 + s2;
if (s >= 0.0) {
l3 = sqrt(s);
l1 = l3 - dir * smooth_freq / max_wander;
if (l1 >= 0.0)
break;
if (s < 0.0) {
err[i] += -s;
s = 0.0;
}
l3t[i] = sqrt(s);
l1t[i] = l3t[i] - dir * smooth_freq / max_wander;
if (l1t[i] < 0.0) {
err[i] += l1t[i] * l1t[i];
l1t[i] = 0.0;
}
}
assert(dir <= 1 && l1 >= 0.0 && l3 >= 0.0);
if (err[0] < err[1]) {
l1 = l1t[0];
l3 = l3t[0];
dir = -1;
} else {
l1 = l1t[1];
l3 = l3t[1];
dir = 1;
}
l2 = 0.0;
/* If the limit was reached, shorten 1st+3rd stages and set a 2nd stage */
f = dir * smooth_freq + l1 * max_wander - max_freq;

View File

@@ -74,6 +74,7 @@ typedef enum {
SRC_WAITS_STATS, /* Others have bad stats, selection postponed */
SRC_STALE, /* Has older samples than others */
SRC_ORPHAN, /* Has stratum equal or larger than orphan stratum */
SRC_UNTRUSTED, /* Overlaps trusted sources */
SRC_FALSETICKER, /* Doesn't agree with others */
SRC_JITTERY, /* Scatter worse than other's dispersion (not used) */
SRC_WAITS_SOURCES, /* Not enough sources, selection postponed */
@@ -890,6 +891,9 @@ SRC_SelectSource(SRC_Instance updated_inst)
if (sources[i]->sel_options & SRC_SELECT_REQUIRE)
sel_req_source = 0;
} else if (sources[i]->sel_info.lo_limit <= best_lo &&
sources[i]->sel_info.hi_limit >= best_hi) {
sources[i]->status = SRC_UNTRUSTED;
} else {
sources[i]->status = SRC_FALSETICKER;
}
@@ -1318,6 +1322,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
case SRC_JITTERY:
report->state = RPT_JITTERY;
break;
case SRC_UNTRUSTED:
case SRC_WAITS_SOURCES:
case SRC_NONPREFERRED:
case SRC_WAITS_UPDATE:

View File

@@ -4,17 +4,40 @@
test_start "NTP authentication"
server_conf="keyfile tmp/keys"
client_conf="keyfile tmp/keys"
server_conf="keyfile tmp/server.keys"
client_conf="keyfile tmp/client.keys"
cat > tmp/keys <<-EOF
1 $(tr -c -d 'a-zA-Z0-9' < /dev/urandom 2> /dev/null | head -c 24)
2 ASCII:$(tr -c -d 'a-zA-Z0-9' < /dev/urandom 2> /dev/null | head -c 24)
3 MD5 ASCII:$(tr -c -d 'a-zA-Z' < /dev/urandom 2> /dev/null | head -c 24)
4 MD5 HEX:$(tr -c -d '0-9A-F' < /dev/urandom 2> /dev/null | head -c 32)
cat > tmp/server.keys <<-EOF
1 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E
2 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E
3 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E
4 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E
EOF
for key in 1 2 3 4; do
cat > tmp/client.keys <<-EOF
1 k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^
2 ASCII:k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^
3 MD5 ASCII:k]<j.Jtw^Oo;z5E>n\_0-x=)yP\f<)Z^
4 MD5 HEX:6B5D3C6A2E4A74775E4F6F3B7A35453E6E5C5F302D783D2979505C663C295A5E
EOF
keys=4
if grep -q 'FEAT_SECHASH 1' ../../config.h; then
hashes="MD5 SHA1 SHA256 SHA384 SHA512"
else
hashes="MD5"
fi
for hash in $hashes; do
keys=$[$keys + 1]
key=$(echo $keys $hash HEX:$(tr -c -d '0-9A-F' < /dev/urandom 2> /dev/null | \
head -c $[$RANDOM % 64 * 2 + 2]))
echo "$key" >> tmp/server.keys
echo "$key" >> tmp/client.keys
done
for key in $(seq $keys); do
client_server_options="key $key"
run_test || test_fail
check_chronyd_exit || test_fail
@@ -31,7 +54,7 @@ check_chronyd_exit || test_fail
check_sync && test_fail
check_packet_interval || test_fail
server_conf="keyfile tmp/keys"
server_conf="keyfile tmp/server.keys"
client_conf=""
run_test || test_fail
@@ -40,7 +63,7 @@ check_chronyd_exit || test_fail
check_sync && test_fail
check_packet_interval || test_fail
client_conf="keyfile tmp/keys"
client_conf="keyfile tmp/client.keys"
clients=2
peers=2
max_sync_time=500

63
test/unit/smooth.c Normal file
View File

@@ -0,0 +1,63 @@
/*
**********************************************************************
* Copyright (C) Miroslav Lichvar 2016
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
**********************************************************************
*/
#include <smooth.c>
#include "test.h"
void
test_unit(void)
{
int i, j;
struct timeval tv;
double offset, freq, wander;
char conf[] = "smoothtime 300 0.01";
CNF_Initialise(0);
CNF_ParseLine(NULL, 1, conf);
LCL_Initialise();
SMT_Initialise();
locked = 0;
for (i = 0; i < 500; i++) {
tv.tv_sec = tv.tv_usec = 0;
SMT_Reset(&tv);
DEBUG_LOG(0, "iteration %d", i);
offset = (random() % 1000000 - 500000) / 1.0e6;
freq = (random() % 1000000 - 500000) / 1.0e9;
update_smoothing(&tv, offset, freq);
for (j = 0; j < 10000; j++) {
update_smoothing(&tv, 0.0, 0.0);
UTI_AddDoubleToTimeval(&tv, 16.0, &tv);
get_smoothing(&tv, &offset, &freq, &wander);
}
TEST_CHECK(fabs(offset) < 1e-12);
TEST_CHECK(fabs(freq) < 1e-12);
TEST_CHECK(fabs(wander) < 1e-12);
}
SMT_Finalise();
LCL_Finalise();
CNF_Finalise();
}