RFC Errata


Errata Search

 
Source of RFC  
Summary Table Full Records

Found 20 records.

Status: Verified (4)

RFC 5905, "Network Time Protocol Version 4: Protocol and Algorithms Specification", June 2010

Source of RFC: ntp (int)

Errata ID: 3007

Status: Verified
Type: Technical

Reported By: Danny Mayer
Date Reported: 2011-10-28
Verifier Name: Brian Haberman
Date Verified: 2012-04-27

Section 7.4 says:

b.  For kiss code RATE, the client MUST immediately reduce its
       polling interval to that server and continue to reduce it each
       time it receives a RATE kiss code.

It should say:

b.  For kiss code RATE, the client MUST immediately increase its
       polling interval to that server and continue to increase it each
       time it receives a RATE kiss code.

Notes:

The client needs to poll the server for new timestamps less often

Errata ID: 3627

Status: Verified
Type: Technical

Reported By: Tal Mizrahi
Date Reported: 2013-05-17
Verifier Name: Brian Haberman
Date Verified: 2014-05-16

Section 7.5 says:

In NTPv4, one or more extension fields can be inserted after the 
header and before the MAC, which is always present when an extension 
field is present.

It should say:

In NTPv4, one or more extension fields can be inserted after the 
header and before the MAC, if a MAC is present. If a MAC is not 
present, one or more extension fields can be inserted after the 
header, according to the following rules:
o If the packet includes a single extension field, the length of the 
  extension  field MUST be at least 7 words, i.e., at least 28 octets.
o If the packet includes more than one extension field, the length of 
  the last extension field MUST be at least 28 octets. The length of 
  the other extension fields in this case MUST be at least 16 octets 
  each.

Notes:

The usage of NTP extension fields without authentication is aligned with Section 10 of RFC 5906:

The extension field parser initializes a pointer to the first octet beyond the NTP packet header and calculates the number of octets remaining to the end of the packet If the remaining length is 20 (128-bit digest plus 4-octet key ID) or 22 (160-bit digest plus 4-octet key ID), the remaining data are the MAC and parsing is complete. If the remaining length is greater than 22, an extension field is present. If the remaining length is less than 8 or not a multiple of 4, a format error has occurred and the packet is discarded; otherwise, the parser increments the pointer by the extension field length and then uses the same rules as above to determine whether a MAC is present or another extension field.

Errata ID: 4019

Status: Verified
Type: Editorial

Reported By: Teruaki Kitasuka
Date Reported: 2014-06-20
Verifier Name: Brian Haberman
Date Verified: 2014-06-20

Section 11.2.1 says:

   An
   example of this calculation is shown by the rootdist() routine in
   Appendix A.5.1.1.

It should say:

   An
   example of this calculation is shown by the root_dist() routine in
   Appendix A.5.5.2.

Notes:

No rootdist() routine is in Appendix. root_dist() appears in Appendix A.5.5.2.

Errata ID: 4121

Status: Verified
Type: Editorial

Reported By: Marina Gertsvolf
Date Reported: 2014-09-23
Verifier Name: Brian Haberman
Date Verified: 2014-10-21

Section 8 says:

In the exchange above, a packet is duplicate or
   replay if the transmit timestamp t3 in the packet matches the org
   state variable T3. 

It should say:

In the exchange above, a packet is duplicate or
   replay if the transmit timestamp t3 in the packet matches the org
   state variable. 

Notes:

The org state variable for peer A has not yet been assigned the value T3.

Status: Reported (2)

RFC 5905, "Network Time Protocol Version 4: Protocol and Algorithms Specification", June 2010

Source of RFC: ntp (int)

Errata ID: 4504

Status: Reported
Type: Technical

Reported By: Miroslav Lichvar
Date Reported: 2015-10-15

Section 7.2 says:

   LI Leap Indicator (leap): 2-bit integer warning of an impending leap
   second to be inserted or deleted in the last minute of the current
   month with values defined in Figure 9.

           +-------+----------------------------------------+
           | Value | Meaning                                |
           +-------+----------------------------------------+
           | 0     | no warning                             |
           | 1     | last minute of the day has 61 seconds  |
           | 2     | last minute of the day has 59 seconds  |

It should say:

   LI Leap Indicator (leap): 2-bit integer warning of an impending leap
   second to be inserted or deleted in the last minute of the current
   day with values defined in Figure 9.

           +-------+----------------------------------------+
           | Value | Meaning                                |
           +-------+----------------------------------------+
           | 0     | no warning                             |
           | 1     | last minute of the day has 61 seconds  |
           | 2     | last minute of the day has 59 seconds  |

Notes:

There is an inconsistency (day vs month) between the LI description and the description of values in the Figure 9. Few paragraphs before that text there is: Except for a minor variation when using the IPv6 address family, these fields are backwards compatible with NTPv3.

If it was month instead of day it would not be compatible with RFC 1305 (NTPv3) and RFC 4330 (SNTPv4), which were obsoleted by RFC 5905.

Errata ID: 4680

Status: Reported
Type: Editorial

Reported By: Riccardo Brama
Date Reported: 2016-04-29

Section 6, Fig 3 says:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           Era Number                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           Era Offset                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      |                           Fraction                            |
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                              NTP Date Format

It should say:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           Era Number                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                           Era Offset                          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      +                           Fraction                            +
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                              NTP Date Format

Notes:

This allows to better appreciate only two 32b rows really form the Fraction part, leading to an overall type length of 128b instead of 160b as it could otherwise be misunderstood in the original figure.

Status: Held for Document Update (12)

RFC 5905, "Network Time Protocol Version 4: Protocol and Algorithms Specification", June 2010

Source of RFC: ntp (int)

Errata ID: 3125

Status: Held for Document Update
Type: Technical

Reported By: Richard Walters
Date Reported: 2012-02-16
Held for Document Update by: Brian Haberman

Section A.5.1.1 says:

        /*
         * Calculate offset, delay and dispersion, then pass to the
         * clock filter.  Note carefully the implied processing.  The
         * first-order difference is done directly in 64-bit arithmetic,
         * then the result is converted to floating double.  All further
         * processing is in floating-double arithmetic with rounding
         * done by the hardware.  This is necessary in order to avoid
         * overflow and preserve precision.
         *
         * The delay calculation is a special case.  In cases where the
         * server and client clocks are running at different rates and
         * with very fast networks, the delay can appear negative.  In
         * order to avoid violating the Principle of Least Astonishment,
         * the delay is clamped not less than the system precision.
         */
        if (p->pmode == M_BCST) {
                offset = LFP2D(r->xmt - r->dst);
                delay = BDELAY;
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    2 * BDELAY;
        } else {
                offset = (LFP2D(r->rec - r->org) + LFP2D(r->dst -
                    r->xmt)) / 2;
                delay = max(LFP2D(r->dst - r->org) - LFP2D(r->rec -
                    r->xmt), LOG2D(s.precision));
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    LFP2D(r->dst - r->org);
        }
        clock_filter(p, offset, delay, disp);

It should say:

        /*
         * Calculate offset, delay and dispersion, then pass to the
         * clock filter.  Note carefully the implied processing.  The
         * first-order difference is done directly in 64-bit arithmetic,
         * then the result is converted to floating double.  All further
         * processing is in floating-double arithmetic with rounding
         * done by the hardware.  This is necessary in order to avoid
         * overflow and preserve precision.
         *
         * The delay calculation is a special case.  In cases where the
         * server and client clocks are running at different rates and
         * with very fast networks, the delay can appear negative.  In
         * order to avoid violating the Principle of Least Astonishment,
         * the delay is clamped not less than the system precision.
         */
        if (p->pmode == M_BCST) {
                offset = LFP2D(r->xmt - r->dst);
                delay = BDELAY;
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    2 * BDELAY;
        } else {
                offset = (LFP2D(r->rec - r->org) + LFP2D(r->xmt -
                    r->dst)) / 2;
                delay = max(LFP2D(r->dst - r->org) - LFP2D(r->xmt -
                    r->rec), LOG2D(s.precision));
                disp = LOG2D(r->precision) + LOG2D(s.precision) + PHI *
                    LFP2D(r->dst - r->org);
        }
        clock_filter(p, offset, delay, disp);

Notes:

Calculations of 'offset' and 'delay' have terms that are incorrectly swapped. In the calculation of 'offset', term 'r->dst' should be 'r->xmt', and term 'r->xmt' should be 'r->dst'. In the calculation of 'delay', term 'r->rec' should be 'r->xmt', and term 'r->xmt' should be 'r->rec'.

See the text from section 8:

"In the figure, the first packet transmitted by A contains only the
origin timestamp t1, which is then copied to T1. B receives the
packet at t2 and copies t1 to T1 and the receive timestamp t2 to T2.
At this time or some time later at t3, B sends a packet to A
containing t1 and t2 and the transmit timestamp t3. All three
timestamps are copied to the corresponding state variables. A
receives the packet at t4 containing the three timestamps t1, t2, and
t3 and the destination timestamp t4. These four timestamps are used
to compute the offset and delay of B relative to A, as described
below.

...

"The four most recent timestamps, T1 through T4, are used to compute
the offset of B relative to A

theta = T(B) - T(A) = 1/2 * [(T2-T1) + (T3-T4)]

and the round-trip delay

delta = T(ABA) = (T4-T1) - (T3-T2)."

Noting that, from the perspective of A at time t4:

T1 = t1 = origin timestamp (r->org)
T2 = t2 = receive timestamp (r->rec)
T3 = t3 = transmit timestamp (r->xmt)
T4 = t4 = destination timestamp (r->dst)

An alternative correction would be to change the '+' to a '-' in the calculation of 'offset', and change the '-' to a '+' in the calculation of 'delay'. However, this would deviate from the operators used in the formulas from section 8.

Errata ID: 2476

Status: Held for Document Update
Type: Technical

Reported By: Joerg Weilbier
Date Reported: 2010-08-19
Held for Document Update by: Brian Haberman

Section 7.3. says:

For instance, a value of -18 corresponds to a precision of about one microsecond.

It should say:

For instance, a value of -20 corresponds to a precision of about one microsecond.

Notes:

2**-20 = 0.954 usec
2**-18 = 3.815 usec

Errata ID: 3404

Status: Held for Document Update
Type: Technical

Reported By: Philippe Verdy
Date Reported: 2012-11-08
Held for Document Update by: Brian Haberman

Section A.1.1. says:

#define SQUARE(x)       (x * x)

It should say:

#define SQUARE(x)       ((x) * (x))

Notes:

This macro is used in the example code to square differences:

//- in clock_filter() {...} (page 85) :

p->jitter += SQUARE(f[i].offset - f[0].offset);

//- in clock_select() { ... } (page 92) :

dtemp += SQUARE(p->offset - q->offset);

//- in clock_combine() { ... } (page 96) :

w += SQUARE(p->offset - s.v[0].p->offset) / x;

//- in local_clock() { ... } (page 99) :

dtemp = SQUARE(max(fabs(offset - c.last),
LOG2D(s.precision)));


These expressions are using differences of double values: the .offset member in a Filter stage structure (f), and the .jitter member in an Association structure (p), or in a Local clock structure (c), or in a System structure (s).

All these occurences of macro substitions of SQUARE() will be wrong if the C macro does not surrounds its parameter expression by adding parentheses around them !

This is a very classic error made by beginners in C programming using "utility" macros with side effects... At least newer programmers avoid these kind of macros and prefer defining inline functions

Errata ID: 3127

Status: Held for Document Update
Type: Technical

Reported By: Richard Walters
Date Reported: 2012-02-17
Held for Document Update by: Brian Haberman

Section A.5.5.1 says:

                /*
                 * Scan the chime list from lowest to highest to find
                 * the lower endpoint.
                 */
                found = 0;
                chime = 0;
                for (i = 0; i < n; i++) {
                        chime -= s.m[i].type;
                        if (chime >= n - found) {
                                low = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

                /*
                 * Scan the chime list from highest to lowest to find
                 * the upper endpoint.
                 */
                chime = 0;
                for (i = n - 1; i >= 0; i--) {
                        chime += s.m[i].type;
                        if (chime >= n - found) {
                                high = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

It should say:

                /*
                 * Scan the chime list from lowest to highest to find
                 * the lower endpoint.
                 */
                found = 0;
                chime = 0;
                for (i = 0; i < n; i++) {
                        chime -= s.m[i].type;
                        if (chime >= n - allow) {
                                low = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

                /*
                 * Scan the chime list from highest to lowest to find
                 * the upper endpoint.
                 */
                chime = 0;
                for (i = n - 1; i >= 0; i--) {
                        chime += s.m[i].type;
                        if (chime >= n - allow) {
                                high = s.m[i].edge;
                                break;
                        }
                        if (s.m[i].type == 0)
                                found++;
                }

Notes:

In both scans (lowest to highest, and highest to lowest)

chime >= n - found

needs to be:

chime >= n - allow

Errata ID: 3608

Status: Held for Document Update
Type: Technical

Reported By: Cristian Rodríguez
Date Reported: 2013-04-29
Held for Document Update by: Brian Haberman

Section A.2. says:

/*
         * Read command line options and initialize system variables.
         * The reference implementation measures the precision specific
         * to each machine by measuring the clock increments to read the
         * system clock.
         */
        memset(&s, sizeof(s), 0);

.....
/*
         * Initialize local clock variables
         */
        memset(&c, sizeof(c), 0);

It should say:

/*
         * Read command line options and initialize system variables.
         * The reference implementation measures the precision specific
         * to each machine by measuring the clock increments to read the
         * system clock.
         */
        memset(&s, 0. sizeof(s));
...

/*
         * Initialize local clock variables
         */
        memset(&c, 0, sizeof(c));

Notes:

Paramters 2 and 3 of the memset functions are inverted everywhere in the example code, not just in section A2

Errata ID: 4366

Status: Held for Document Update
Type: Technical

Reported By: Vyacheslav
Date Reported: 2015-05-13
Held for Document Update by: Brian Haberman
Date Held: 2015-09-14

Section 11.2.1 says:

5.  Is d = f and l < u?  If yes, then follow step 5A; else, follow
   step 5B.

It should say:

5.  Is d <= f and l < u?  If yes, then follow step 5A; else, follow
   step 5B.

Notes:

Original text doesn't correspond to sample implementation at A.5.5.1. And, I suppose, described algorithm may throw out reasonable set of measures.

Errata ID: 2514

Status: Held for Document Update
Type: Editorial

Reported By: Jerzy Miernik
Date Reported: 2010-09-08
Held for Document Update by: Brian Haberman

Section A.5.1 says:

if (0) { ...

It should say:

if (unicast ...) { ...

Notes:

expression under if is needed, even using pseudo-code

Errata ID: 2826

Status: Held for Document Update
Type: Editorial

Reported By: Christian Aistleitner
Date Reported: 2011-06-10
Held for Document Update by: Brian Haberman

Section 6 says:

[...] and a 64-bit fraction field resolving .05 attosecond (i.e., 0.5e-18).

It should say:

[...] and a 64-bit fraction field resolving .05 attosecond (i.e., 0.05e-18).

Notes:

"atto" is the prefix for 1e-18.

Errata ID: 3126

Status: Held for Document Update
Type: Editorial

Reported By: Richard Walters
Date Reported: 2012-02-16
Held for Document Update by: Brian Haberman

Section 3 says:

          +-------------------+-------------------+------------------+
          |  Association Mode | Assoc. Mode Value | Packet Mode Value|
          +-------------------+-------------------+------------------+
          | Symmetric Active  |         1         | 1 or 2           |
          | Symmetric Passive |         2         | 1                |
          | Client            |         3         | 4                |
          | Server            |         4         | 3                |
          | Broadcast Server  |         5         | 5                |
          | Broadcast Client  |         6         | N/A              |
          +-------------------+-------------------+------------------+

                  Figure 1: Association and Packet Modes

   In the client/server variant, a persistent client sends packet mode 4
   packets to a server, which returns packet mode 3 packets.

It should say:

          +-------------------+-------------------+------------------+
          |  Association Mode | Assoc. Mode Value | Packet Mode Value|
          +-------------------+-------------------+------------------+
          | Symmetric Active  |         1         | 1 or 2           |
          | Symmetric Passive |         2         | 1                |
          | Client            |         3         | 4                |
          | Server            |         4         | 3                |
          | Broadcast Server  |         5         | N/A              |
          | Broadcast Client  |         6         | 5                |
          +-------------------+-------------------+------------------+

                  Figure 1: Association and Packet Modes

   In the client/server variant, a persistent client sends packet mode 3
   packets to a server, which returns packet mode 4 packets.

Notes:

The majority of the rows in Figure 1 are correct if the 'Packet Mode Value' refers to the mode of packets which are expected to be received by an NTP speaker which has mobilized an association with the corresponding 'Association Mode'. Assuming this is the case, the last two rows are incorrect:

* A peer with a mobilized 'Broadcast Server' mode association is not expected to receive any packets at all for this association -- a broadcast server does not receive anything back (see 'Broadcast' mode row in Section 9.2, Figure 20, where each column in that row is 'DSCRD'.) Therefore, the value of 'Packet Mode Value' for 'Broadcast Server' should be 'N/A', not '5'.

* A peer with a mobilized 'Broadcast Client' mode association is expected to receive packets with a 'Packet Mode Value' of 5 for this association (see 'Bcast Client' mode row in Section 9.2, Figure 20, where each column in that row is 'DSCRD' except for the '5' column, which is 'PROC'.) Therefore, the value of 'Packet Mode Value' for 'Broadcast Client' should be '5', not 'N/A'.

It might help the clarity of Figure 1 if the row labeled 'Packet Mode Value' were to be changed to 'Receive Packet Mode Value(s)'.

The text immediately following Figure 1 also has the packet mode values swapped. As made clear throughout the RFC (for example, see Section 9.2 where is says, "FXMIT. This indicates a client (mode 3) packet matching no association (mode 0). If the destination address is not a broadcast address, the server constructs a server (mode 4) packet and returns it to the client without retaining state."), clients send servers packet mode 3 packets, not packet mode 4 packets; it is servers which send clients packet mode 4 packets, not packet mode 3 packets.

Just to make it perfectly clear, here are the modes of packets sent:

* Time t0: client mobilizes 'Client' mode association for server (via configuration, or due to reception of manycast server packet)
* Time t1: client transmits mode 3 packet to server (e.g. via poll(p) => peer_xmit(p) when c.t >= p->nextdate)
* Time t2: server receives mode 3 packet from client (dispatch: FXMIT; no association found or mobilized)
* Time t3: server transmits mode 4 packet to client
* Time t4: client receives mode 4 packet from server (matches previously mobilized association -- dispatch: PROC)

Errata ID: 3132

Status: Held for Document Update
Type: Editorial

Reported By: Richard Walters
Date Reported: 2012-02-21
Held for Document Update by: Brian Haberman

Section 11.2.1 says:

   First, those servers that are unusable according to the rules of the
   protocol are detected and discarded as shown by the accept() routine
   in Appendix A.5.5.3.

It should say:

   First, those servers that are unusable according to the rules of the
   protocol are detected and discarded as shown by the fit() routine
   in Appendix A.5.2.

Notes:

The fit() and accept() routines are identical. Since accept() is not called from, nor mentioned anywhere else, whereas fit() is called from two places and listed in the function prototypes, just drop accept() and use fit() instead in section 11.2.1.

Errata ID: 4025

Status: Held for Document Update
Type: Editorial

Reported By: Julien Cretin
Date Reported: 2014-06-25
Held for Document Update by: Brian Haberman
Date Held: 2014-06-25

Section 6 says:

-678,491

It should say:

-678,941

Notes:

In Figure 4, the MJD of 1 Jan 0 has a typo.

There are 365 (not 815) days from 1 Jan -1 to 1 Jan 0, and 366 (not -84) from 1 Jan 0 to 1 Jan 1. I took NTP Timestamp Era Offset as a reference for the number of days in these years.

Errata ID: 4263

Status: Held for Document Update
Type: Editorial

Reported By: Priyesh Patel
Date Reported: 2015-02-05
Held for Document Update by: Brian Haberman
Date Held: 2015-02-06

Section 7.3, Fig 8 says:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |LI | VN  |Mode |    Stratum     |     Poll      |  Precision   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

It should say:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |LI | VN  |Mode |    Stratum    |     Poll      |  Precision    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Notes:

The field boundaries are not aligned with the bit boundaries in "Figure 8: Packet Header Format".

Status: Rejected (2)

RFC 5905, "Network Time Protocol Version 4: Protocol and Algorithms Specification", June 2010

Source of RFC: ntp (int)

Errata ID: 3613

Status: Rejected
Type: Technical

Reported By: Tony O'Brien
Date Reported: 2013-05-06
Rejected by: Brian Haberman
Date Rejected: 2013-05-06

Section 8 says:


Notes:

In the paragraph explaining the sanity checks on received packets, it states: "In the exchange above, a packet is duplicate or replay if the transmit timestamp t3 in the packet matches the org state variable T3." But in the pseudo-code in A.5.1 it states
/*
* If the transmit timestamp duplicates a previous one, the
* packet is a replay.
*/
if (r->xmt == p->xmt)
i.e. comparing the transmit timestamp p->xmt with the xmt state variable T1. Which is correct?

Similarly for the check for a bogus packet, Section 8 states: "A packet is bogus if the origin timestamp t1 in the packet does not match the xmt state variable T1. But the pseudo-code says:
/*
* If this is a broadcast mode packet, skip further checking.
* If the origin timestamp is zero, the sender has not yet heard
* from us. Otherwise, if the origin timestamp does not match
* the transmit timestamp, the packet is bogus.
*/
synch = TRUE;
if (r->mode != M_BCST) {
if (r->org == 0)
synch = FALSE; /* unsynchronized */

else if (r->org != p->xmt)
synch = FALSE; /* bogus packet */
}
i.e. it is comparing the transmit timestamp t3 in the packet with the org state variable T3.

Which is correct? Looking at Figure 15 my guess would be Section 8 is correct but I have seen code that more closely follows the pseudo-code.
--VERIFIER NOTES--
The Introduction of the document clearly states that the pseudo-code in the appendix is non-normative. Therefore the text in the main body of the specification describes the conformant behavior:

"The contents of Appendix A are non-normative examples designed to illustrate the protocol's operation and are not a requirement for a conforming implementation."

Errata ID: 4505

Status: Rejected
Type: Technical

Reported By: Miroslav Lichvar
Date Reported: 2015-10-15
Rejected by: Brian Haberman
Date Rejected: 2015-12-14

Section A.5.1 says:

        /*
         * Update the origin and destination timestamps.  If
         * unsynchronized or bogus, abandon ship.
         */
        p->org = r->xmt;
        p->rec = r->dst;
        if (!synch)
                return;                 /* unsynch */

        /*
         * The timestamps are valid and the receive packet matches the
         * last one sent.  If the packet is a crypto-NAK, the server
         * might have just changed keys.  We demobilize the association
         * and wait for better times.
         */
        if (auth == A_CRYPTO) {
                clear(p, X_CRYPTO);
                return;                 /* crypto-NAK */
        }

        /*
         * If the association is authenticated, the key ID is nonzero
         * and received packets must be authenticated.  This is designed
         * to avoid a bait-and-switch attack, which was possible in past
         * versions.
         */
        if (!AUTH(p->keyid || (p->flags & P_NOTRUST), auth))
                return;                 /* bad auth */

It should say:

        /*
         * If the packet is a valid crypto-NAK, the server might have
         * just changed keys.  We demobilize the association and wait
         * for better times.
         */
        if (synch && auth == A_CRYPTO) {
                clear(p, X_CRYPTO);
                return;                 /* crypto-NAK */
        }

        /*
         * If the association is authenticated, the key ID is nonzero
         * and received packets must be authenticated.  This is designed
         * to avoid a bait-and-switch attack, which was possible in past
         * versions.
         */
        if (!AUTH(p->keyid || (p->flags & P_NOTRUST), auth))
                return;                 /* bad auth */

        /*
         * Update the origin and destination timestamps.  If
         * unsynchronized or bogus, abandon ship.
         */
        p->org = r->xmt;
        p->rec = r->dst;
        if (!synch)
                return;                 /* unsynch */

Notes:

The state variables must be updated after the authentication is checked in order to prevent DoS attacks on authenticated symmetric associations (CVE-2015-1799).
--VERIFIER NOTES--
The appendix is not the normative description of the protocol behavior. A change such as this needs consensus within the working group. To do that, a draft should be submitted with the proposed changes.

Report New Errata



Search RFCs
Advanced Search
×