Move logging of falsetickers and system peers to the mark_source()
function. Use an array to flag already logged messages in preparation
for logging of other status. Support variable number of arguments in the
logging functions.
Replace the hardcoded list of open commands (accessible over UDP),
with a list that can be configured with a new "opencommands" directive.
The default matches the original list. All read-only commands except
accheck and cmdaccheck can be enabled. The naming follows the chronyc
naming. Enable the N_SOURCES request only when needed.
This makes it possible to have a full monitoring access without access
to the Unix domain socket. It also allows restricting the monitoring
access to a smaller number of commands if some commands from the default
list are not needed.
Mention in the man page that the protocol of the non-default commands is
not consider stable and the information they provide may have security
implications.
Try to simplify the code and make it more robust to potential bugs.
Instead of maintaing a table mapping all commands to open/auth
permissions, use a short list of open commands. Split the processing
of the commands into two groups, read-write commands and read-only
(monitoring) commands, where the first group is processed only with full
access. Check both the socket descriptor and address type before giving
full access. While moving the code, reorder the commands alphabetically.
Handle the NULL and LOGON requests as unknown (invalid) instead of
returning the success and failed status respectively. They have
been unused for very long time now.
Add a function to fill the Unix sockaddr for binding, connecting and
sending to avoid code duplication. Use memcpy() instead of snprintf()
and provide the minimum length of the address containing the terminating
null byte. This makes it easier to support abstract sockets if needed in
future (e.g. for systemd support).
On Linux, if the NOTIFY_SOCKET variable is set, send a "READY=1"
and "STOPPING=1" message to the Unix domain socket after initialization
and before finalization respectively. This is used with the systemd
"notify" service type as documented in the sd_notity(3) man page. It's
a recommended alternative to the "forking" service type, which does not
need the PID file to determine the main process.
Support pathname Unix sockets only. Abstract sockets don't seem to be
used by systemd for notifications since version 212.
Switch the example services to the notify type, but keep the PID
file. It's still useful to prevent start of other chronyd instances.
systemd doesn't seem to care about the content of the file and should
just remove it in case chronyd didn't terminate cleanly.
Suggested-by: Luca Boccassi <bluca@debian.org>
In the refclock initialization, if the driver provides a poll()
function and 2^(poll-dpoll) is smaller than the configured length of the
median filter (64 by default), the filter is shortened to 2^(poll-dpoll)
samples, assuming the driver provides samples only in the poll()
function and at most one per call, to avoid wasting memory and before
commit 12237bf283 ("refclock: stop requiring 4 samples in median
filter") also simplify configuration (for polling drivers only)
But this assumption is not always correct. The PHC driver can read
external PPS timestamps independently from the driver polling and the
RTC driver can timestamp interrupts. If the dpoll was too large to cover
the sample rate, some samples would be lost.
Drop the adjustment of the filter length to avoid this unexpected impact
on filtering and make it work as documented.
This refclock uses an RTC as reference source. If the RTC doesn't
support reporting an update event this source is quite coarse as it
usually needs a slow bus access to be read and has a precision of only
one second. If reporting an update event is available, the time is read
just after such an event which improves precision.
Depending on hardware capabilities you might want to combine it with a
PPS reference clock sourced from the same chip.
Note that you can enable UIE emulation in the Linux kernel to make a RTC
without interrupt support look like one with irqs in return for some
system and bus overhead.
Co-authored-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
For use with RCL_AddSample in the incoming RTC reference clock driver,
we'll want access not to the cooked timestamps, but to the raw ones.
Otherwise, the core reference clock code complains:
(valid_sample_time) RTC0 refclock sample time 1721242673.092211891
not valid age=-3.092007
Support both use cases by have the RTC_Linux_ReadTime_* functions take
two nullable pointers, one for cooked and the other for raw time.
We have code to read RTC time and handle the error associated with
having no UIE interrupt, which we currently use as part of maintaining
the correction file.
In a later commit, we will need the same functionality for using the RTC
as reference clock, so export the function and give it a descriptive
name appropriate for a globally visible function.
We have code to read time after an RTC's UIE interrupt, which we
currently use as part of maintaining the correction file.
In a later commit, we will need the same functionality for using the RTC
as reference clock, so export the function and give it a descriptive
name appropriate for a globally visible function.
We have code to enable and disable the RTC's UIE interrupt, as well as
check whether it occurred and skip the first interrupt as it may be
bogus.
This is currently used as part of maintaining the correction file.
In a later commit, we will need the same functionality for using the RTC
as reference clock, so export the functions and give them descriptive
names appropriate for globally visible functions.
rtc_from_t() and t_from_rtc() call either gmtime or localtime depending
on the value of a global rtc_on_utc variable.
This will not be appropriate anymore when we start exporting functions
that call rtc_from_t() and t_from_rtc() for use outside of rtc_linux.c
as the rtc_on_utc variable may not have been initialized yet or at all.
Therefore make whether the RTC is on UTC a function parameter of these
functions, so the value can be propagated from the callers.
Both functions operate on struct tm even though the struct tm is only
used as intermediary format from struct rtc_time.
In the case of rtc_from_t, the code to convert from struct tm to struct
rtc is even duplicated.
Let's simplify code a bit by moving the struct translation code into
these conversion functions.
Close the other end of the pipe in the grandparent process before exit
to avoid valgrind error.
Also, in the daemon process avoid closing the pipe for second time in
the 0-1024 close() loop to avoid another error.
Add a new parameter to limit the negative value of the step state
variable. It's set as a maximum delay in number of updates before the
actual step applied to the quantile estimate starts growing from the
minimum step when the input value is consistently larger or smaller than
the estimate.
This prevents the algorithm from effectively becoming the slower 1U
variant if the quantile estimate is stable most of the time.
Set it to 100 updates for the NTP delay and 1000 updates for the hwclock
delay. An option could be added later to make it configurable.
The algorithm was designed for estimating quantiles in streams of
integer values. When the estimate is equal to the input value, the
step state variable does not change. This causes problems for the
floating-point adaptation used for measurents of delay in chrony.
One problem is numerical instability due to the strict comparison of
the input value and the current estimate.
Another problem is with signals that are so stable that the nanosecond
resolution of the system functions becomes the limitation. There is a
large difference in the value of the step state variable, which
determines how quickly the estimate will adapt to a new distribution,
between signals that are constant in the nanosecond resolution and
signals that can move in two nanoseconds.
Change the estimate update to never consider the input value equal to
the current estimate and don't set the estimate exactly to the input
value. Keep it off by a quarter of the minimum step to force jumping
around the input value if it's constant and decreasing the step variable
to negative values. Also fix the initial adjustment to step at least by
the minimum step (the original algorithm is described with ceil(), not
fabs()).
Extend the interval of accepted delays by half of the quantile minimum
step in both directions to make room for floating-point errors in the
quantile calculation and an error that will be intentionally added in
the next commit.
Nettle (>=3.6) and GnuTLS (>=3.6.14) with the AES-SIV-CMAC support
required for NTS are now widely available in operating systems. Drop
the internal Nettle-based implementation.
Reduce the minimum number of samples required by the filter from
min(4, length) to 1.
This makes the filtering less confusing. The sample lifetime is limited
to one poll and the default filtering of the SOCK refclock (where the
maximum number of samples per poll is unknown) is identical to the other
refclocks.
A concern with potential variability in number of samples per poll below
4 is switching between different calculations of dispersion in
combine_selected_samples() in samplefilt.c.
The 106-refclock test shows how the order of refclocks in the config can
impact the first filtered sample and selection. If the PPS refclock
follows SHM, a single low-quality PPS sample is accepted in the same
poll where SHM is selected and the initial clock correction started,
which causes larger skew later and delays the first selection of the PPS
refclock.
Update the reachability register of a refclock source by 1 if a valid
measurement is received by the drivers between source polls, and not
only when it is accumulated to sourcestats, similarly to how
reachability works with NTP sources.
This avoids drops in the reported reachability when a PHC refclock is
dropping samples due to significant changes in the measured delay (e.g.
due to high PCIe load), or a PPS refclock dropping samples due to failed
lock.
If the client included the NTS-KE record requesting compliant key
exporter context for AES-128-GCM-SIV, but the server doesn't select this
AEAD algorithm (it's not supported by the crypto library or it is
disabled by the ntsaeads directive), don't include the NTS-KE record in
the response. It's not relevant to the other AEAD algorithms.
Add ntsaeads directive to specify a list of AEAD algorithms enabled for
NTS. The list is shared between the server and client. For the client it
also specifies the order of priority. The default is "30 15", matching
the previously hardcoded preference of AES-128-GCM-SIV (30) over
AES-SIV-CMAC-256 (15).
Make sure the TLS session is not NULL in NKSN_GetKeys() before trying to
export the keys in case some future code tried to call the function
outside of the NTS-KE message handler.
Implement a fallback for the NTS-NTP client to switch to the compliant
AES-128-GCM-SIV exporter context when the server is using the compliant
context, but does not support the new NTS-KE record negotiating its use,
assuming it can respond with an NTS NAK to the request authenticated
with the incorrect key.
Export both sets of keys when processing the NTS-KE response. If an NTS
NAK is the only valid response from the server after the last NTS-KE
session, switch to the keys exported with the compliant context for the
following requests instead of dropping all cookies and restarting
NTS-KE. Don't switch back to the original keys if an NTS NAK is received
again.