[Git][NTPsec/ntpsec][master] Documentation updates
Gary E. Miller
gitlab at mg.gitlab.com
Mon Aug 6 21:20:46 UTC 2018
Gary E. Miller pushed to branch master at NTPsec / ntpsec
96f0cdd7 by James Browning at 2018-08-06T21:16:10Z
- - - - -
5 changed files:
@@ -20,7 +20,7 @@ ifdex-ignores::
Lists and explains a large number of internal configuration symbols.
- Script for building a release tarball.
+ The script for building a release tarball.
Design notes towards NTPv5.
@@ -29,7 +29,7 @@ pre-release.txt::
A collection of ideas about testing before a release.
- Script for shipping a release.
+ The script for shipping a release.
List of items the NTPsec developers are working on.
@@ -21,7 +21,7 @@ to a minimum.
Time-critical code must be written in C. Use Python for any code that
is not time-critical, as this reduces line count and complexity (thus,
-also, expected defect rates). If you need a NTP-specific C function
+also, expected defect rates). If you need an NTP-specific C function
not available in Python, try to improve the libntpc extension
in ../libntp/pymodule.c to expose it.
@@ -29,7 +29,7 @@ The only scripting language allowed and supported other than Python is
POSIX sh (this is more restricted than bash!). Python is preferred, as
it's easier to verify portability in Python than it is in sh.
-Please read our C and Python guidelines carefully. They're not just
+Please read our C and Python guidelines carefully; they're not just
about style, they're serious measures to reduce defect rates.
== C Guidelines ==
@@ -48,15 +48,15 @@ You *may* use C11-style anonymous unions.
Only POSIX-1.2001/SUSv3 library functions should be used (a few
specific exceptions are noted below). If a library
-function not in that standard is required, then a wrapper function for back
+function not in that standard is required, then a wrapper function for backward
compatibility must be provided. One notable case is clock_gettime()
which is used, when available, for increased accuracy, and has a
fallback implementation using native time calls.
-You can view POSIX-1.2001, with 2004 Corrigendum, online for free here:
+You can read POSIX-1.2001, with 2004 Corrigendum, online for free here:
-You can view POSIX.1-2001, SUSv3, online for free here:
+You can see POSIX.1-2001, SUSv3, online for free here:
POSIX threads *are* considered part of the standardized API and may be used.
@@ -109,16 +109,16 @@ Don't use gettimeofday(2). While this is nominally POSIX, it is
deprecated and may be removed in the future. Use clock_gettime(2)
-Use pselect(2) rather that select(2), to avoid introducing struct
+Use pselect(2) rather than select(2), to avoid introducing struct
In general, avoid introducing the type struct timeval into the code,
in favor of the higher-resolution struct timespec. Early on in
-NTPsec's history we found a bug introduced by poor data management
+NTPsec's history, we found a bug introduced by poor data management
where these two time representations bumped into each other; we don't
want that to happen again. Thus, if you must refer to struct timeval due to
an external interface, move the data to/from a struct timespec as
-close to that callsite as possible.
+close to that call site as possible.
=== Coding style and indentation ===
@@ -128,7 +128,7 @@ likes. It's a bit archaic, but we've stuck with it to preserve
continuity; you should, too.
A discussion about using uncrustify to mass convert all the C sources
-to a more modern indentation and format style is ongoing. As it will
+to a more current indentation and format style is ongoing. As it will
result in a coordinated flag day in ongoing development, it will be
carefully announced in the mailto:devel at ntpsec.org mailing list before
being merged and pushed.
@@ -153,7 +153,7 @@ HAVE_*_H::
Guard symbol derived by configuration logic from checking
for the presence of a system header. For example, the symbol
HAVE_SYS_FOOBAR_H gets defined only if waf configure detects
- the presence of a sys/foobar.h in the system include directory.
+ the presence of sys/foobar.h in the system include directory.
Without an H suffix, a HAVE symbol is set on the availability
@@ -168,7 +168,7 @@ NEED_*::
Override a default for debugging purposes. These are values
(buffer lengths and the like) which waf is not expected to
- normally override but which might need to be forced.
+ override normally but which might need to be forced.
Use symbols are set internally within other conditionals to
@@ -196,7 +196,7 @@ Do not rely on assumptions about how structure or unions are padded.
Historically, the NTP code assumed self-alignment. We're trying
to eliminate that assumption, but the work isn't finished.
-Do not assume pointers can be cast to ints, or vice-versa. While this
+Do not assume you can cast pointers to ints, or vice-versa. While this
is true on effectively all modern hardware, the code runs on some
sufficiently old iron that this is not necessarily the case even if
the compiler and toolchain have been modernized.
@@ -211,14 +211,14 @@ specify multiple module names in an import rather than going strictly
with one per line. The point is to encourage you to group your import
declarations in informative ways.
-You *must* write Python code to be 'polyglot', that is able to run
+You *must* write Python code to be 'polyglot', that can run
unaltered under 2 or 3. Practices for doing so are documented in
Note that Python 3.x versions before 3.3 had sufficiently serious
-back-compatibility issues that trying to make them run is probably
+backward-compatibility issues that trying to make them run is probably
doomed. The first 3.x version under which our Python has been
extensively tested is 3.5.
@@ -240,15 +240,15 @@ caused many problems. The waf script is embedded in the top level of
the distribution; run "./waf --help" or consult INSTALL for basic
-Full waf documentation is at: https://waf.io/
+Full waf documentation is at https://waf.io/
=== Naming conventions ===
-Every binary and script we install has an "ntp" prefix on the name,
+Every binary and script we install has an "ntp" prefix on the name
because namespace pollution is rude. If you write a new tool that you
want us to install, follow this convention.
-Generally we favor "ntp" rather than "ntp-" for consistency and to
+Generally, we favor "ntp" rather than "ntp-" for consistency and to
reduce the amount people have to type. Choose tastefully.
=== Well-tempered output ===
@@ -256,14 +256,14 @@ reduce the amount people have to type. Choose tastefully.
We are devotees of the Unix rule that programs should play nicely
with other programs. We like output formats that are simple,
regular, and machine-parseable without ambiguity. The practical
-goal to aim at, given our choice of scripting languages, is
+goal to aim at, given our choice of scripting languages,
is to make writing script wrappers in Python easy.
There is more than one way to arrange this. If you can design a
simple tabular output format, or something resembling an RFC 2822 header
that's easy for both human eyes and programs to parse, do that.
Besides being simple, formats like these are easily handled by either
-Python or shellscripts.
+Python or shell scripts.
Such simplicity is often difficult or impractical for heterogeneous
data that needs to be both grouped and labeled, so we have another
@@ -272,7 +272,7 @@ convention for those cases. Here it is:
Wherever it is reasonable, tools that generate complex reports to
standard output should be able to emit two formats. The default can be
-relatively unstructured multiline text for human eyeballs. There
+[a] relatively unstructured multiline text for human eyeballs. There
should also be a -j/--json option that emits a self-describing JSON
@@ -284,7 +284,7 @@ and no JSON option, it is quite likely to be rejected.
Our preferred format for dates is RFC 3339 (a version of ISO 8601 for
UTC with some options frozen; full year required, medial T required,
explicit Zulu timezone). Local times should be expressed in ISO 8601,
-always with full 4-digit year.
+always with the full 4-digit year.
=== Copyrights and licenses ===
@@ -308,7 +308,7 @@ When you create a new file, mark it as follows (updating the year)
-/* Copyright 2017 by the NTPsec project contributors
+/* Copyright 2018 by the NTPsec project contributors
* SPDX-License-Identifier: BSD-2-Clause
@@ -316,7 +316,7 @@ as required:
-// Copyright 2017 by the NTPsec project contributors
+// Copyright 2018 by the NTPsec project contributors
// SPDX-License-Identifier: CC-BY-4.0
@@ -328,11 +328,11 @@ When you modify a file, leave existing copyright markings in place -
especially all references to Dr. Dave Mills, to Mr. Harlan Stenn, and
to the Network Time Foundation.
-You *may* add a project copyright and replace the inline license
+You *may* add project copyright and replace the inline license
with an SPDX tag. For example:
-/* Copyright 2017 by the NTPsec project contributors
+/* Copyright 2018 by the NTPsec project contributors
* SPDX-License-Identifier: NTP
@@ -347,7 +347,7 @@ before moving.
When you change anything user-visible, you are expected to update the
relevant documentation *in the same commit*. No exceptions.
-Otherwise we'd have to inflict long, tedious document reviews on
+Otherwise, we'd have to inflict long, tedious document reviews on
everybody. Nobody wants that.
=== Documentation format and structure ===
@@ -379,14 +379,14 @@ that appears on a man page.
=== Version number ===
-We use a variant of three part Semantic Versioning, of the form X.Y.Z.
+We use a variant of three-part Semantic Versioning, of the form X.Y.Z.
X, Y, and Z are non-negative decimal integers.
X is the "major" version number.
Y is the "minor" version number.
Z is the "revision" number.
-Each release will result in an incremented version number, and the
+Each release will result in an incremented version number and the
version number string will be tagged into the git repository.
We have dropped even/odd minor version number stable/development
@@ -447,8 +447,8 @@ Our GitLab group is at https://gitlab.com/groups/NTPsec
Please use the issue tracker and the pull request process at GitLab.com.
If you wish, you can request to join the GitLab project team at
-https://gitlab.com/groups/NTPsec/group_members and we will add you to the
-team with Guest access. This will cause GitLab to send issue tracker
+https://gitlab.com/groups/NTPsec/group_members, and we will add you to the
+team with Guest access; this will cause GitLab to send issue tracker
updates and pipeline updates to your email address. You do not have
to formally be a member of the GitLab team to participate, contribute,
or send issues, patches, or pull requests.
@@ -470,13 +470,13 @@ at least send context (-c) or unified (-u) diffs rather than the
default ed (-e) style, which is very brittle.
You can email your patch to mailto:devel at ntpsec.org if you are a member of
-that mailing list, or you can email your patch to
+that mailing list or you can email your patch to
mailto:contact at ntpsec.org if you are not.
Please make sure your "From:" header in the email is correct, as that
-is what will be used as attribution of the commit.
+is what will be used as the attribution of the commit.
-The person on the team that merges in your patch will use the git
+The team member who merges your patch will use the git
parameter ---author from the email From header and the git parameter
--date from the email Date header.
@@ -503,7 +503,7 @@ should consist of:
git format-patch. Bulleted list items are also OK.
* In some cases it may be appropriate to end your summary line with a comma
- or ellipsis ("...") to indicate that it runs directly into a following
+ or ellipsis ("...") to indicate that it runs directly into the following
paragraph. You should still try to make the summary self-contained when
you do this.
@@ -517,14 +517,14 @@ change and you can easily fit it in the summary line along with your
Yes, we know the pre-git portions of the history violate some of these.
-That was then, this is now.
+That was then; this is now.
=== How to refer to previous commits ===
The best (most human-friendly) way to reference a commit is by quoting its
-summary line. If you need to disambiguate, give its date and author.
+summary line; if you need to disambiguate, give its date and author.
-The worst way is to quote its git hash, because humans are not good at
+The worst way is to quote its git hash because humans are not good at
keeping random strings of hex digits in working memory. Besides, hashes
will break if the history is ever moved to another VCS or the repository
has to be surgically altered.
@@ -539,7 +539,7 @@ of the bubble commute cleanly, but the developer on one side or the other
forgot to rebase so his commit would be a fast-forward.
We strongly dislike unnecessary merge bubbles. They make the
-repository history difficult to read, and can make bisection tests
+repository history hard to read, and can make bisection tests
trickier. We prefer the code to have a simple, close-to-linear
history even if that means older commits are sometimes fast-forwarded
from new ones because a long-lived branch was rebased.
@@ -556,8 +556,8 @@ local commits on the new tip. You may find it helpful to set
rebase = true
-Setting this option adds --rebase to all your pulls. This may cause
-minor inconvenience when you have uncommitted local changes; you
+Setting this option adds --rebase to all your pulls; this may cause
+a minor inconvenience when you have uncommitted local changes; you
should be able to use "git stash" to get around that.
== Logging tags ==
@@ -602,7 +602,7 @@ each release.
. Modify the .../VERSION file with the new version number.
Version number strings look like "1.1.1"
-. Modify the .../NEWS file, changing the "Repository head".
+. Modify the .../NEWS file, changing the "Repository head"
to the current date and the version string.
. Run the "release" script in this (devel) directory.
@@ -1,7 +1,7 @@
= Preliminary design notes for the NTPv5 protocol =
NTPv4 is showing its age. There are functional capabilities that
-would be very useful if they could be standardized, but
+would be very useful if they could be standardized but
currently are not.
This document will first list these missing bits, then discuss
@@ -14,8 +14,8 @@ ways to incorporate them.
Reference IDs are used by Stratum 1 sources to identify clocks and
clock types, and by hosts at higher strata to perform loop detection.
-The REFID field is 4 octets long, sufficient to hold an IPv4 address
-for loop detection. This is inadequate for IPv6, so the reference ID of
+The REFID field is four octets long, sufficient to hold an IPv4 address
+for loop detection; this is inadequate for IPv6, so the reference ID of
an IPv6 host is a 4-octet hash of its actual address. Hash collisions
have been observed in the wild, possibly resulting in false-positive
@@ -29,7 +29,7 @@ Most servers ship UTC. Some ship TAI. Some perform leap-second
smearing, some do not.
The new protocol should enable a server to advertise its timescale,
-including, if applicable in its timescale, its current leapsecond offset.
+including, if applicable in its timescale, its current leap second offset.
=== Era ===
@@ -61,12 +61,12 @@ not incremented; "v5" becomes a set of required extension blocks.
A difficulty with this approach is that some firewalls and routers are
known to silently discard RFC7822 extension blocks as a way of
-preventing DoS attacks. This would create propagation issues
+preventing DoS attacks; this would create propagation issues
difficult to diagnose.
=== NTPNG ===
-In this approach, a new port number is allocated. The protocol is
+In this approach, a new port number is allocated. The protocol
design is unconstrained except that it must carry the semantic
content of the v4 header minus the unused Reference Timestamp
@@ -81,7 +81,7 @@ the first byte of the v4 packet header structure, so that the version
number and packet mode are at the same offset as in v4. The version
field *is* incremented to 5.
-The following payload is design is unconstrained except that it must
+The following payload design is unconstrained except that it must
carry the semantic content of the v4 header minus the unused Reference
@@ -117,7 +117,7 @@ A chunk system appropriate for NTP can be summarized as follows:
* If the first character is not uppercase, the chunk is non-critical
and may be skipped.
-* Chunk content is not constrained and is interpreted based in the
+* Chunk content is not constrained and is interpreted based on the
Note that this is not identical to PNG chunk layout; one difference is
@@ -135,10 +135,10 @@ worthwhile would incorporate at least most of the following:
something that runs over HTTPS on the NTS-KE port.
2. Let client and server packets be formatted differently. Achieve
-data minimization by just taking the unnecessary fields out of client
+data minimization by just taking unnecessary fields out of client
-3. Forbid use of the legacy MAC field, thus fixing the hairiness
+3. Forbid the use of the legacy MAC field, thus fixing the hairiness
around extension parsing.
4. Make NTS mandatory. In the NTPv5 packet format, the version, mode,
@@ -16,14 +16,14 @@ that says
ntpq: can't find Python NTP library -- check PYTHONPATH.
-you *may* have a problem. A lot of what was C code in legacy versions
+You *may* have a problem. A lot of what was C code in legacy versions
(pretty much everything except ntpd itself, in fact) has been moved to
-Python in order to improve maintainability and decrease attack
+Python to improve maintainability and decrease attack
surface. Most of these tools share a Python library of critical
functions. If you can't load that library, you can't test effectively.
The waf build is supposed to create a symbolic link from
-build/main/ntpclients/ntp to pylib in the build directory. This should enable
+build/main/ntpclients/ntp to pylib in the build directory; this should enable
ntpq to "import ntp" before you install to rootspace. If that link is not
created or doesn't point to pylib/ under your build directory, report
this as a bug. If it is, but ./ntpq startup fails anyway, you may
@@ -40,7 +40,7 @@ report it as a bug.
Be aware that if this sort of problem occurs in an NTPsec instance
installed from a binary package, it is almost certainly not an NTPsec
bug but a packaging error that the NTPsec maintainers themselves can't
-fix. In that case you need to report it to your distribution
+fix. In that case, you need to report it to your distribution
== Preliminary one-off test ==
@@ -64,7 +64,7 @@ Run "ntpq -p" to see if things look normal.
== Full qualification test ==
-For a longer test, including over reboots...
+For a longer test, including over reboots.
Install your new code using "./waf install" (as root).
That will install your new ntpd into /usr/local/sbin/ntpd
@@ -87,7 +87,7 @@ Note that under Fedora and CentOS, "dnf update" may undo that edit
and revert to running the system version.
Older versions used /etc/rc.d/init.d/ntpd. The file /etc/sysconfig/ntpd
-gets sourced into the init script so you can put real code in there
+gets sourced into the init script so you can put the real code in there
(systemd doesn't do that) You can insert this:
@@ -17,9 +17,9 @@ a higher-level view than individual comments.
=== l_fp, s_fp, u_fp ===
-C doesn't have any native fixed-point types, only float types. In
-order to do certain time calculations without loss of precision, NTP
-home-brews three fixed-point types of its own. Of these l_fp is the
+C doesn't have any native fixed-point types, only float types.
+To do certain time calculations without loss of precision, NTP
+home-brews three fixed-point types of its own. Of these, l_fp is the
most common, with 32 bits of precision in both integer and fractional
parts. Gory details are in include/ntp_fp.h.
@@ -32,24 +32,24 @@ become an l_fp. For most calculations with l_fp it's easier to
envision it as a 64bit integer that represents time with a unit of
2^-32s, slightly short of 233 ps.
-When used to represent dates internally an l_fp must be interpreted in
-relation to the NTP era (the left 32 bits of the integer part of the
+When used to represent dates internally an l_fp must be interpreted
+relative to the NTP era (the left 32 bits of the integer part of the
NTP date that got cut off). The NTP prime epoch (or epoch 0) is then
an *unsigned* number of seconds since 1900-01-01T00:00:00Z and
-unsigned decimal fractional seconds. Just to complicate matters,
-however, some uses of l_fp are time offsets with a signed seconds
+unsigned decimal fractional seconds, just to complicate matters.
+However, some uses of l_fp are time offsets with a signed seconds
part. Under the assumption that only adjacent epochs get compared,
the offset calculations work correctly without taking the era number
-Most time offsets are much smaller than the NTP epoch, so a 32 bit
-representation is used for these. Actually, there were two of these:
-s_fp for signed offsets and u_fp for strictly non-negative ones. The
-signed version has already been removed in NTPsec.
+Most time offsets are much smaller than the NTP epoch, so a 32-bit
+representation is used for these. There were two of these:
+s_fp for signed offsets and u_fp for strictly non-negative ones.
+NTPsec has already removed the singed version
The comments in libntp/ntp_calendar.c are pretty illuminating about
calendar representations. A high-level point they don't make is
-that ignoring time cycles in l_fp is exactly how NTP gets around the
+that ignoring time cycles in l_fp is how NTP gets around the
Y2K38 problem. As long as the average clock skew between machines
is much less than the length of a calendar cycle (which it generally
will be, by a factor of at least five million) we can map all incoming
@@ -62,10 +62,10 @@ NTP was written well before the 64-bit word size became common. While
compilers on 32-bit machines sometimes have had "long long" as an
integral 64-bit type, this was not guaranteed before C99.
-Thus in order to do calendar arithmetic, NTP used to carry a "vint64"
+Thus to do calendar arithmetic, NTP used to carry a "vint64"
(variant 64-bit int) type that was actually a union with several
-different interpretations. This has been replaced with a scalar
-time64_t which is used the same way but implemented as a uint64_t.
+different interpretations; the scalar time64_t which is used the same
+way but implemented as a uint64_t has already replaced this.
This still has some utility because NTP still runs on 32-bit machines
with a 32-bit time_t.
@@ -80,7 +80,7 @@ In a clock sample (a time-sync packet with stratum number 1), the
refid is interpreted as 4 ASCII characters of clock identification.
In a time-synchronization packet with stratum 2 or higher the refid
identifies the originating time server; it may be an IPv4 or a hash of
-an IPv6 address. (If and when the protocol is fully redesigned for
+an IPv6 address. (If and when the protocol is redesigned for
IPv6 the field length will go to 128 bits and it will become a full
@@ -96,7 +96,7 @@ types ship the refid "GPS". It is possible to fudge this ID to
something more informative in the ntpd configuration command
for the driver.
-The conflation of ID-for-humans with loop-detection cookie is not quite
+The conflation of ID-for-humans with the loop-detection cookie is not quite
the design error it looks like, as refclocks aren't implicated in
@@ -115,7 +115,7 @@ the millennium. The struct timespec is newer and associated with
The NTP code was written well before calls like clock_gettime(2) that
-use it were standardized, but as part of of its general cleanup NTPsec
+use it were standardized, but as part of its general cleanup NTPsec
has been updated to do all its internal computations at nanosecond
precision or better.
@@ -123,7 +123,7 @@ Thus, when you see a struct timeval in the NTPsec code, it's due to
a precision limit imposed by an external interface. One such is in
the code for using the old BSD adjtime(2) call; another is in getting
packet timestamps from the IP layer. Our practice is to convert from
-or to nanosecond precision as close to these callsites as possible;
+or to nanosecond precision as close to these call sites as possible;
this doesn't pull additional accuracy out of thin air, but it does
avoid loss-of-precision bugs due to mixing these structures.
@@ -133,10 +133,10 @@ In ntpd, there are peer control blocks - one per upstream synchronization
source - that have an IP address in them. That's what the main
control logic works with.
-The peer buffer holds the last 8 samples from the upstream source.
-The normal logic uses the one with the lowest round trip time. That's
+The peer buffer holds the last eight samples from the upstream source.
+The normal logic uses the one with the lowest round-trip time. That's
a hack to minimize errors from queuing delays out on the big bad
-internet. Refclock data always has a round trip time of 0 and the
+internet. Refclock data always has a round trip time of zero, and the
code that finds the lowest RTT picks the most recent slot when the
RTTs are equal.
@@ -147,7 +147,7 @@ There is no type T_Unsigned. Range checking may not work right.
== ntpd control flow ==
-In normal operation, after initialization, ntpd simply loops forever
+In normal operation, after initialization, ntpd loops forever
waiting for a UDP packet to arrive on some set of open interfaces, or
a clock sample to arrive from a locally-attached reference clock.
Incoming packets and clock samples are fed to a protocol state
@@ -157,20 +157,20 @@ captured by a function in ntpd/ntpd.c tellingly named 'mainloop()'.
This main loop is interrupted once per second by a timer tick that
sets an alarm flag visible to the mainloop() logic. When execution
gets back around to where that flag is checked, a timer() function may
-fire. This is used to adjust the system clock in time and frequency,
+fire; this is used to adjust the system clock in time and frequency,
implement the kiss-o'-death function and the association polling
There may be one asynchronous thread. It does DNS lookups of server
-and pool hostnames. This is intended to avoid adding startup delay
+and pool hostnames; this is intended to avoid adding startup delay
and jitter to the time synchronization logic due to address lookups
of unpredictable length.
Input handling used to be a lot more complex. Due to inability to get
arrival timestamps from the host's UDP layer, the code used to do
-asynchronous I/O with packet I/O indicated by signal, with packets
+asynchronous I/O with packet I/O indicated by a signal, with packets
(and their arrival timestamps) being stashed in a ring of buffers that
-was consumed by the protocol main loop. Some of this code hasn't been
+was consumed by the main protocol loop. Some of this code hasn't been
cleaned up yet.
This looked partly like a performance hack, but if so it was an
@@ -183,30 +183,30 @@ dropped.
get those arrival timestamps from the UDP layer ASAP, rather than
looking at packet read time in userspace. The cost of the latter,
naive approach is additional jitter dominated by process-scheduling
-time. This used to be significant relative to users' accuracy
+time; this used to be significant relative to users' accuracy
expectations for NTP, but scheduler timeslices have since decreased
by orders of magnitude and squashed the issue. We know this from some
tests setup having run for six months with packet-timestamp fetching
-accidentally disabled... But they weren't horribly busy systems.)
+accidentally disabled... But they weren't busy systems.)
The new organization stops pretending; it simply spins on a select
across all interfaces. If inbound traffic is more than the daemon can
handle, packets will pile up in the UDP layer and be dropped at that
level. The main difference is that dropped packets are less likely to
-be visible in the statistics the server can gather. (In order to show,
+be visible in the statistics the server can gather. (To show,
they'd have to make it out of the system IP layer to userland at a
higher rate than ntpd can process; this is very unlikely.)
There was internal evidence in the NTP Classic build machinery that
-asynchronous I/O on Unix machines probably hadn't actually worked for
+asynchronous I/O on Unix machines probably hadn't worked for
quite a while before NTPsec removed it.
== System call interface and the PLL ==
-All of ntpd's clock management is done through four system calls:
+All of ntpds clock management is done through four system calls:
clock_gettime(2), clock_settime(2), and either ntp_adjtime(2) or (in
exceptional cases) the older BSD adjtime(2) call. For ntp_adjtime(),
-ntpd actually uses a thin wrapper that hides the difference between
+ntpd uses a thin wrapper that hides the difference between
systems with nanosecond-precision and those with only microsecond
precision; internally, ntpd does all its calculations with nanosecond
@@ -269,21 +269,21 @@ ntp_adjtime(2). ntp_adjtime(2)/adjtimex(2) uses a kernel interface to
do its work, using a control technique called a PLL/FLL (phase-locked
loop/frequency-locked loop) to do it.
-The older BSD adjtime(2) can be used for slewing as well, but doesn't
-assume a kernel-level PLL is available. It is used only when
+The older BSD adjtime(2) can be used for slewing as well but doesn't
+assume a kernel-level PLL is available. It is used when
ntp_adjtime() calls generate a SIGSYS because the system call has not
-been implemented. Without the PLL calls, convergence to good time is
-observably a lot slower and tracking will accordingly be less
+been implemented. Without the PLL calls, convergence to a good time is
+observably a lot slower, and tracking will accordingly be less
reliable; support for systems that lack them (notably OpenBSD and
-older Mac OS X versions) has been dropped fom NTPsec.
+older Mac OS X versions) has been dropped from NTPsec.
Deep-in-the weeds details about the kernel PLL from Hal Murray follow.
-If you can follow these you may be qualified to maintain this code...
+If you can follow these, you may be qualified to maintain this code.
Deep inside the kernel, there is code that updates the time by reading the
cycle counter, subtracting off the previous cycle count and multiplying by
the time/cycle. The actual implementation is complicated mostly to maintain
-accuracy. You need ballpark of 9 digits of accuracy on the time/cycle and
+accuracy. You need ballpark of 9 digits of accuracy on the time/cycle, and
that has to get carried through the calculations.
On PCs, Linux measures the time/cycle at boot time by comparing with another
@@ -301,13 +301,13 @@ You can grep for "MHz" to find these.
the clock fuzzing to smear the EMI over a broader band to comply with
FCC rules. It rounds down to make sure the CPU isn't overclocked.)
-There is an API call to adjust the time/cycle. That adjustment is ntpd's
+There is an API call to adjust the time/cycle. That adjustment is ntpds
drift. That covers manufacturing errors and temperature changes and such.
The manufacturing error part is typically under 50 PPM. I have a few systems
off by over 100. The temperature part varies by ballpark of 1 PPM / C.
-There is another error source which is errors in the calibration code and/or
-time keeping code. If your timekeeping code rounds down occasionally, you
+There is another error source which is errors in the calibration code and
+timekeeping code. If your timekeeping code rounds down occasionally, you
can correct for that by tweaking the time/cycle.
There is another API that says "slew the clock by X seconds". That is
@@ -320,7 +320,7 @@ implemented in user code with reduced accuracy.
There is a PLL kernel option to track a PPS. It's not compiled into most
Linux kernels. (It doesn't work with tickless.) There is an API to turn it
-on. Then ntpd basically sits off to the side and watches.
+on. Then ntpd sits off to the side and watches.
RFC 1589 covers the above timekeeping and slewing and kernel PLL.
@@ -335,10 +335,10 @@ that the clock is actually a peer." The code mostly hides the
difference between clock samples and sync updates from peers.
Internally, each refclock has a FIFO holding the last ~64 samples. For
-things like NMEA, each time the driver gets a valid sample it adds it to the
+things like NMEA, each time the driver, gets a valid sample it adds it to the
FIFO. For the Atom/PPS driver there is a hook that gets called/polled each
second. If it finds good data, it adds a sample to the FIFO. The FIFO is
-actually a ring buffer. On overflow, old samples are dropped.
+a ring buffer. On overflow, old samples are dropped.
At the polling interval, the driver is "polled". (Note the possible
confusion on "poll".) That is parallel with sending a packet to the
@@ -352,7 +352,7 @@ injects that into the peer buffer for the refclock.
== Asynchronous DNS lookup ==
-The DNS code runs in a separate thread in order to avoid stalling
+The DNS code runs in a separate thread to avoid stalling
the main loop while it waits for a DNS lookup to return. And DNS
lookups can take a *long* time. Hal Murray notes that
he thinks he's seen 40 seconds on a failing case.
@@ -365,7 +365,7 @@ need - notably an input-buffer pool. (It also had an obscure bug.)
The DNS lookups during initialization - of hostnames specified on the
command line or server lines in ntp.conf - could be done synchronously.
-But that would delay startup and there are two cases we know of where
+But that would delay startup, and there are two cases we know of where
ntpd has to do a DNS lookup during normal operation.
One is the try again when DNS for the normal server case doesn't work during
@@ -386,23 +386,23 @@ rather than only replacing dead servers.
== The build recipe ==
The build recipe is, essentially, a big Python program using a set of
-specialized procedures caled 'waf'. To learn about waf itself see
+specialized procedures called 'waf'. To learn about waf itself see
the https://waf.io/book/[Waf Book]; this section is about the
organization and particular quirks of NTPsec's build.
If you are used to autoconf, you will find the waf recipe
odd at first. We replaced autoconf because with waf the
-build recipe is literally orders of magnitude less complex,
+build recipe is orders of magnitude less complex,
faster, and more maintainable.
-The top level wscript calls wscript files in various subdirectories
+The top-level wscript calls wscript files in various subdirectories
using the ctx.recurse() function. These subfiles are all relatively
simple, consisting mainly of calls to the waf function ctx(). Each
such call declares a build target to be composed (often using the
compiler) from various prerequisites.
The top-level wscript does not itself declare a lot of targets (the
-exceptions are a handful of installable shellscripts and man pages).
+exceptions are a handful of installable shell scripts and man pages).
It is mainly concerned with setting up various assumptions for the
configure and build phases.
@@ -410,7 +410,7 @@ If you are used to working with Makefiles, you may find the absence
of object files and binaries from the source directory after a build
surprising. Look under the build/ directory.
-Most of the complexity in this build is in the configure phase, when
+Most of the complexity in this build is in the configure phase when
the build engine is probing the environment. The product of this
phase is the file build/config.h, which the C programs include to
get symbols that describe the environment's capabilities and
@@ -421,7 +421,7 @@ in the wafhelpers/ directory. The entire collection is structured as
a loadable Python module. Here are a few useful generalizations:
* The main sequence of the configuration logic, and most of the simpler
- checks, lives in configure.py.
+ checks live in configure.py.
* Some generic but bulky helper functions live in probes.py.
@@ -476,7 +476,7 @@ re-used.
=== ntpdig ===
-ntpdig also uses the pylib library, but doesn't speak Mode 6.
+ntpdig also uses the pylib library but doesn't speak Mode 6.
Instead, it builds and interprets time-synchronization packets
using some of the same machinery.
@@ -492,7 +492,7 @@ layers of segment reassembly. The lower layer is the vanilla UDP
fragment reassembly encapsulated in do_query() and shared with the
other request types.
-In order to avoid blocking for long periods of time, and in order to
+To avoid blocking for long periods of time, and to
be cleanly interruptible by control-C, the upper layer does a sequence
of requests for MRU spans, which are multi-frag sequences of
ASCIIizations of MRU records, oldest to newest. The spans include
@@ -506,12 +506,12 @@ has finished.
The code collects all the data, maybe sorts it, then prints it out.
There is also a direct mode that prints the individual slots
-as they come in. This avoids needing lots of memory if you want
+as they come in; this avoids needing lots of memory if you want
to get the MRU data from a system that keeps lots of history.
-A further interesting complication is use of a nonce to foil DDoSes by
+A further interesting complication is the use of a nonce to foil DDoSes by
source-address spoofing. The mrulist() code begins by requesting a
-nonce from ntpd, which it then replays between span requets to
+nonce from ntpd, which it then replays between span requests to
convince ntpd that the address it's firehosing all that MRU data at is
the same one that asked for the nonce. To foil replay attacks, the
nonce is timed out; you have to re-request another every 16 seconds
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/96f0cdd7c825756863bf796f64bd0d901e4c9254
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/96f0cdd7c825756863bf796f64bd0d901e4c9254
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the vc