draft-ietf-ntp-ntpv4-proto-12.txt   draft-ietf-ntp-ntpv4-proto-13.txt 
NTP WG J. Burbank NTP WG J. Burbank
Internet-Draft W. Kasch Internet-Draft W. Kasch
Obsoletes: RFC 4330, RFC 1305 JHU/APL Obsoletes: RFC 4330, RFC 1305 JHU/APL
(if approved) J. Martin, Ed. (if approved) J. Martin, Ed.
Intended status: Standards Track Daedelus Intended status: Standards Track Daedelus
Expires: April 11, 2010 D. Mills Expires: April 12, 2010 D. Mills
U. Delaware U. Delaware
October 8, 2009 October 9, 2009
Network Time Protocol Version 4 Protocol And Algorithms Specification Network Time Protocol Version 4 Protocol And Algorithms Specification
draft-ietf-ntp-ntpv4-proto-12 draft-ietf-ntp-ntpv4-proto-13
Status of this Memo Status of this Memo
This Internet-Draft is submitted to IETF in full conformance with the This Internet-Draft is submitted to IETF in full conformance with the
provisions of BCP 78 and BCP 79. This document may contain material provisions of BCP 78 and BCP 79. This document may contain material
from IETF Documents or IETF Contributions published or made publicly from IETF Documents or IETF Contributions published or made publicly
available before November 10, 2008. The person(s) controlling the available before November 10, 2008. The person(s) controlling the
copyright in some of this material may not have granted the IETF copyright in some of this material may not have granted the IETF
Trust the right to allow modifications of such material outside the Trust the right to allow modifications of such material outside the
IETF Standards Process. Without obtaining an adequate license from IETF Standards Process. Without obtaining an adequate license from
skipping to change at page 1, line 46 skipping to change at page 1, line 46
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt. http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html. http://www.ietf.org/shadow.html.
This Internet-Draft will expire on April 11, 2010. This Internet-Draft will expire on April 12, 2010.
Copyright Notice Copyright Notice
Copyright (c) 2009 IETF Trust and the persons identified as the Copyright (c) 2009 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents in effect on the date of Provisions Relating to IETF Documents in effect on the date of
publication of this document (http://trustee.ietf.org/license-info). publication of this document (http://trustee.ietf.org/license-info).
Please review these documents carefully, as they describe your rights Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. and restrictions with respect to this document.
skipping to change at page 3, line 49 skipping to change at page 3, line 49
16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 59 16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 59
17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 60 17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 60
18. References . . . . . . . . . . . . . . . . . . . . . . . . . 60 18. References . . . . . . . . . . . . . . . . . . . . . . . . . 60
18.1. Normative References . . . . . . . . . . . . . . . . . . 60 18.1. Normative References . . . . . . . . . . . . . . . . . . 60
18.2. Informative References . . . . . . . . . . . . . . . . . 60 18.2. Informative References . . . . . . . . . . . . . . . . . 60
Appendix A. Code Skeleton . . . . . . . . . . . . . . . . . . . 61 Appendix A. Code Skeleton . . . . . . . . . . . . . . . . . . . 61
A.1. Global Definitions . . . . . . . . . . . . . . . . . . . 62 A.1. Global Definitions . . . . . . . . . . . . . . . . . . . 62
A.1.1. Definitions, Constants, Parameters . . . . . . . . . 62 A.1.1. Definitions, Constants, Parameters . . . . . . . . . 62
A.1.2. Packet Data Structures . . . . . . . . . . . . . . . 65 A.1.2. Packet Data Structures . . . . . . . . . . . . . . . 65
A.1.3. Association Data Structures . . . . . . . . . . . . 66 A.1.3. Association Data Structures . . . . . . . . . . . . 66
A.1.4. System Data Structures . . . . . . . . . . . . . . . 68 A.1.4. System Data Structures . . . . . . . . . . . . . . . 69
A.1.5. Local Clock Data Structures . . . . . . . . . . . . 69 A.1.5. Local Clock Data Structures . . . . . . . . . . . . 70
A.1.6. Function Prototypes . . . . . . . . . . . . . . . . 69 A.1.6. Function Prototypes . . . . . . . . . . . . . . . . 70
A.2. Main Program and Utility Routines . . . . . . . . . . . . 70 A.2. Main Program and Utility Routines . . . . . . . . . . . . 71
A.3. Kernel Input/Output Interface . . . . . . . . . . . . . . 73 A.3. Kernel Input/Output Interface . . . . . . . . . . . . . . 74
A.4. Kernel System Clock Interface . . . . . . . . . . . . . . 73 A.4. Kernel System Clock Interface . . . . . . . . . . . . . . 74
A.5. Peer Process . . . . . . . . . . . . . . . . . . . . . . 75 A.5. Peer Process . . . . . . . . . . . . . . . . . . . . . . 76
A.5.1. receive() . . . . . . . . . . . . . . . . . . . . . 76 A.5.1. receive() . . . . . . . . . . . . . . . . . . . . . 77
A.5.2. clock_filter() . . . . . . . . . . . . . . . . . . . 83 A.5.2. clock_filter() . . . . . . . . . . . . . . . . . . . 84
A.5.3. fast_xmit() . . . . . . . . . . . . . . . . . . . . 87 A.5.3. fast_xmit() . . . . . . . . . . . . . . . . . . . . 88
A.5.4. access() . . . . . . . . . . . . . . . . . . . . . . 88 A.5.4. access() . . . . . . . . . . . . . . . . . . . . . . 89
A.5.5. System Process . . . . . . . . . . . . . . . . . . . 88 A.5.5. System Process . . . . . . . . . . . . . . . . . . . 89
A.5.6. Clock Adjust Process . . . . . . . . . . . . . . . . 103 A.5.6. Clock Adjust Process . . . . . . . . . . . . . . . . 104
A.5.7. Poll Process . . . . . . . . . . . . . . . . . . . . 104 A.5.7. Poll Process . . . . . . . . . . . . . . . . . . . . 105
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 111 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 112
1. Introduction 1. Introduction
This document defines the Network Time Protocol Version 4 (NTPv4), This document defines the Network Time Protocol Version 4 (NTPv4),
which is widely used to synchronize system clocks among a set of which is widely used to synchronize system clocks among a set of
distributed time servers and clients. It describes the core distributed time servers and clients. It describes the core
architecture, protocol, state machines, data structures and architecture, protocol, state machines, data structures and
algorithms. NTPv4 introduces new functionality to NTPv3, as algorithms. NTPv4 introduces new functionality to NTPv3, as
described in [RFC1305], and functionality expanded from SNTPv4 as described in [RFC1305], and functionality expanded from SNTPv4 as
described in [RFC4330] (SNTPv4 is a subset of NTPv4). This document described in [RFC4330] (SNTPv4 is a subset of NTPv4). This document
skipping to change at page 63, line 17 skipping to change at page 63, line 17
/* /*
* Timestamp conversion macroni * Timestamp conversion macroni
*/ */
#define FRIC 65536. /* 2^16 as a double */ #define FRIC 65536. /* 2^16 as a double */
#define D2FP(r) ((tdist)((r) * FRIC)) /* NTP short */ #define D2FP(r) ((tdist)((r) * FRIC)) /* NTP short */
#define FP2D(r) ((double)(r) / FRIC) #define FP2D(r) ((double)(r) / FRIC)
#define FRAC 4294967296. /* 2^32 as a double */ #define FRAC 4294967296. /* 2^32 as a double */
#define D2LFP(a) ((tstamp)((a) * FRAC)) /* NTP timestamp */ #define D2LFP(a) ((tstamp)((a) * FRAC)) /* NTP timestamp */
#define LFP2D(a) ((double)(a) / FRAC) #define LFP2D(a) ((double)(a) / FRAC)
#define U2LFP(a) ((a).tv_sec + JAN_1970 << 32 + (unsigned long long) \ #define U2LFP(a) (((unsigned long long) \
((a).tv_sec + JAN_1970) << 32) + \
(unsigned long long) \
((a).tv_usec / 1e6 * FRAC)) ((a).tv_usec / 1e6 * FRAC))
/* /*
* Arithmetic conversions * Arithmetic conversions
*/ */
#define LOG2D(a) ((a) < 0 ? 1. / (1L << -(a)) : \ #define LOG2D(a) ((a) < 0 ? 1. / (1L << -(a)) : \
1L << (a)) /* poll, etc. */ 1L << (a)) /* poll, etc. */
#define SQUARE(x) (x * x) #define SQUARE(x) (x * x)
#define SQRT(x) (sqrt(x)) #define SQRT(x) (sqrt(x))
skipping to change at page 66, line 12 skipping to change at page 66, line 17
char poll; /* poll interval */ char poll; /* poll interval */
s_char precision; /* precision */ s_char precision; /* precision */
tdist rootdelay; /* root delay */ tdist rootdelay; /* root delay */
tdist rootdisp; /* root dispersion */ tdist rootdisp; /* root dispersion */
char refid; /* reference ID */ char refid; /* reference ID */
tstamp reftime; /* reference time */ tstamp reftime; /* reference time */
tstamp org; /* origin timestamp */ tstamp org; /* origin timestamp */
tstamp rec; /* receive timestamp */ tstamp rec; /* receive timestamp */
tstamp xmt; /* transmit timestamp */ tstamp xmt; /* transmit timestamp */
int keyid; /* key ID */ int keyid; /* key ID */
digest dgst; /* message digest */ digest mac; /* message digest */
tstamp dst; /* destination timestamp */ tstamp dst; /* destination timestamp */
} r; } r;
/* /*
* Transmit packet * Transmit packet
*/ */
struct x { struct x {
ipaddr dstaddr; /* source (local) address */ ipaddr dstaddr; /* source (local) address */
ipaddr srcaddr; /* destination (remote) address */ ipaddr srcaddr; /* destination (remote) address */
char version; /* version number */ char version; /* version number */
skipping to change at page 71, line 45 skipping to change at page 72, line 45
/* /*
* Start the system timer, which ticks once per second. Then * Start the system timer, which ticks once per second. Then
* read packets as they arrive, strike receive timestamp and * read packets as they arrive, strike receive timestamp and
* call the receive() routine. * call the receive() routine.
*/ */
while (0) { while (0) {
r = recv_packet(); r = recv_packet();
r->dst = get_time(); r->dst = get_time();
receive(r); receive(r);
} }
return(0);
} }
/* /*
* mobilize() - mobilize and initialize an association * mobilize() - mobilize and initialize an association
*/ */
struct p struct p
*mobilize( *mobilize(
ipaddr srcaddr, /* IP source address */ ipaddr srcaddr, /* IP source address */
ipaddr dstaddr, /* IP destination address */ ipaddr dstaddr, /* IP destination address */
int version, /* version */ int version, /* version */
skipping to change at page 72, line 24 skipping to change at page 73, line 26
* Allocate and initialize association memory * Allocate and initialize association memory
*/ */
p = malloc(sizeof(struct p)); p = malloc(sizeof(struct p));
p->srcaddr = srcaddr; p->srcaddr = srcaddr;
p->dstaddr = dstaddr; p->dstaddr = dstaddr;
p->version = version; p->version = version;
p->hmode = mode; p->hmode = mode;
p->keyid = keyid; p->keyid = keyid;
p->hpoll = MINPOLL; p->hpoll = MINPOLL;
clear(p, X_INIT); clear(p, X_INIT);
p->flags == flags; p->flags = flags;
return (p); return (p);
} }
/* /*
* find_assoc() - find a matching association * find_assoc() - find a matching association
*/ */
struct p /* peer structure pointer or NULL */ struct p /* peer structure pointer or NULL */
*find_assoc( *find_assoc(
struct r *r /* receive packet pointer */ struct r *r /* receive packet pointer */
) )
skipping to change at page 74, line 48 skipping to change at page 75, line 50
{ {
struct timeval unix_time; struct timeval unix_time;
tstamp ntp_time; tstamp ntp_time;
/* /*
* Convert from double to native format (signed) and add to the * Convert from double to native format (signed) and add to the
* current time. Note the addition is done in native format to * current time. Note the addition is done in native format to
* avoid overflow or loss of precision. * avoid overflow or loss of precision.
*/ */
gettimeofday(&unix_time, NULL); gettimeofday(&unix_time, NULL);
ntp_time = D2LFP(offset) + U2LFP(unix_time);; ntp_time = D2LFP(offset) + U2LFP(unix_time);
unix_time.tv_sec = ntp_time >> 32; unix_time.tv_sec = ntp_time >> 32;
unix_time.tv_usec = (long)((ntp_time - unix_time.tv_sec << unix_time.tv_usec = (long)(((ntp_time - unix_time.tv_sec) <<
32) / FRAC * 1e6); 32) / FRAC * 1e6);
settimeofday(&unix_time, NULL); settimeofday(&unix_time, NULL);
} }
/* /*
* adjust_time() - slew system clock to given offset value * adjust_time() - slew system clock to given offset value
*/ */
void void
adjust_time( adjust_time(
double offset /* clock offset */ double offset /* clock offset */
skipping to change at page 75, line 25 skipping to change at page 76, line 27
{ {
struct timeval unix_time; struct timeval unix_time;
tstamp ntp_time; tstamp ntp_time;
/* /*
* Convert from double to native format (signed) and add to the * Convert from double to native format (signed) and add to the
* current time. * current time.
*/ */
ntp_time = D2LFP(offset); ntp_time = D2LFP(offset);
unix_time.tv_sec = ntp_time >> 32; unix_time.tv_sec = ntp_time >> 32;
unix_time.tv_usec = (long)((ntp_time - unix_time.tv_sec << unix_time.tv_usec = (long)(((ntp_time - unix_time.tv_sec) <<
32) / FRAC * 1e6); 32) / FRAC * 1e6);
adjtime(&unix_time, NULL); adjtime(&unix_time, NULL);
} }
A.5. Peer Process A.5. Peer Process
/* /*
* A crypto-NAK packet includes the NTP header followed by a MAC * A crypto-NAK packet includes the NTP header followed by a MAC
* consisting only of the key identifier with value zero. It tells the * consisting only of the key identifier with value zero. It tells the
* receiver that a prior request could not be properly authenticated, * receiver that a prior request could not be properly authenticated,
skipping to change at page 77, line 6 skipping to change at page 78, line 8
A.5.1. receive() A.5.1. receive()
/* /*
* receive() - receive packet and decode modes * receive() - receive packet and decode modes
*/ */
void void
receive( receive(
struct r *r /* receive packet pointer */ struct r *r /* receive packet pointer */
) )
{ {
struct p *p; /* peer structure pointer struct p *p; /* peer structure pointer */
int auth; /* authentication code */ int auth; /* authentication code */
int has_mac; /* size of MAC */ int has_mac; /* size of MAC */
int synch; /* synchronized switch */ int synch; /* synchronized switch */
int auth; /* authentication code */
/* /*
* Check access control lists. The intent here is to implement a * Check access control lists. The intent here is to implement a
* whitelist of those IP addresses specifically accepted and/or * whitelist of those IP addresses specifically accepted and/or
* a blacklist of those IP addresses specifically rejected. * a blacklist of those IP addresses specifically rejected.
* There could be different lists for authenticated clients and * There could be different lists for authenticated clients and
* unauthenticated clients. * unauthenticated clients.
*/ */
if (!access(r)) if (!access(r))
return; /* access denied */ return; /* access denied */
skipping to change at page 77, line 51 skipping to change at page 79, line 4
* A_NONE the packet has no MAC * A_NONE the packet has no MAC
* A_OK the packet has a MAC and authentication * A_OK the packet has a MAC and authentication
* succeeds * succeeds
* A_ERROR the packet has a MAC and authentication fails * A_ERROR the packet has a MAC and authentication fails
* A_CRYPTO crypto-NAK. The MAC has four octets only. * A_CRYPTO crypto-NAK. The MAC has four octets only.
* *
* Note: The AUTH(x, y) macro is used to filter outcomes. If x * Note: The AUTH(x, y) macro is used to filter outcomes. If x
* is zero, acceptable outcomes of y are NONE and OK. If x is * is zero, acceptable outcomes of y are NONE and OK. If x is
* one, the only acceptable outcome of y is OK. * one, the only acceptable outcome of y is OK.
*/ */
has_mac = /* length of MAC field */ 0; has_mac = /* length of MAC field */ 0;
if (has_mac == 0) { if (has_mac == 0) {
auth = A_NONE; /* not required */ auth = A_NONE; /* not required */
} else if (has_mac == 4) { } else if (has_mac == 4) {
auth == A_CRYPTO; /* crypto-NAK */ auth = A_CRYPTO; /* crypto-NAK */
} else { } else {
if (r->mac != md5(r->keyid)) if (r->mac != md5(r->keyid))
auth = A_ERROR; /* auth error */ auth = A_ERROR; /* auth error */
else else
auth = A_OK; /* auth OK */ auth = A_OK; /* auth OK */
} }
/* /*
* Find association and dispatch code. If there is no * Find association and dispatch code. If there is no
* association to match, the value of p->hmode is assumed NULL. * association to match, the value of p->hmode is assumed NULL.
*/ */
p = find_assoc(r); p = find_assoc(r);
switch(table[p->hmode][r->mode]) { switch(table[(unsigned int)(p->hmode)][(unsigned int)(r->mode)]) {
/* /*
* Client packet and no association. Send server reply without * Client packet and no association. Send server reply without
* saving state. * saving state.
*/ */
case FXMIT: case FXMIT:
/* /*
* If unicast destination address, send server packet. * If unicast destination address, send server packet.
* If authentication fails, send a crypto-NAK packet. * If authentication fails, send a crypto-NAK packet.
*/ */
/* not multicast dstaddr */ /* not multicast dstaddr */
if (!IN_MULTICAST(dstaddr)) { if (0) {
if (AUTH(p->flags & P_NOTRUST, auth)) if (AUTH(p->flags & P_NOTRUST, auth))
fast_xmit(r, M_SERV, auth); fast_xmit(r, M_SERV, auth);
else if (auth == A_ERROR) else if (auth == A_ERROR)
fast_xmit(r, M_SERV, A_CRYPTO); fast_xmit(r, M_SERV, A_CRYPTO);
return; /* M_SERV packet sent */ return; /* M_SERV packet sent */
} }
/* /*
* This must be manycast. Do not respond if we are not * This must be manycast. Do not respond if we are not
* synchronized or if our stratum is above the * synchronized or if our stratum is above the
skipping to change at page 79, line 51 skipping to change at page 81, line 4
} }
p = mobilize(r->srcaddr, r->dstaddr, r->version, M_PASV, p = mobilize(r->srcaddr, r->dstaddr, r->version, M_PASV,
r->keyid, P_EPHEM); r->keyid, P_EPHEM);
break; break;
/* /*
* New broadcast client association. It is mobilized in the same * New broadcast client association. It is mobilized in the same
* version as in the packet. If authentication fails, ignore the * version as in the packet. If authentication fails, ignore the
* packet. Note this code does not support the initial volley * packet. Note this code does not support the initial volley
* feature in the reference implementation. * feature in the reference implementation.
*/
*/
case NEWBC: case NEWBC:
if (!AUTH(p->flags & (P_NOTRUST | P_NOPEER), auth)) if (!AUTH(p->flags & (P_NOTRUST | P_NOPEER), auth))
return; /* authentication error */ return; /* authentication error */
if (!(s.flags & S_BCSTENAB)) if (!(s.flags & S_BCSTENAB))
return; /* broadcast not enabled */ return; /* broadcast not enabled */
p = mobilize(r->srcaddr, r->dstaddr, r->version, M_BCLN, p = mobilize(r->srcaddr, r->dstaddr, r->version, M_BCLN,
r->keyid, P_EPHEM); r->keyid, P_EPHEM);
break; /* processing continues */ break; /* processing continues */
skipping to change at page 81, line 51 skipping to change at page 83, line 4
* to avoid a bait-and-switch attack, which was possible in past * to avoid a bait-and-switch attack, which was possible in past
* versions. * versions.
*/ */
if (!AUTH(p->keyid || (p->flags & P_NOTRUST), auth)) if (!AUTH(p->keyid || (p->flags & P_NOTRUST), auth))
return; /* bad auth */ return; /* bad auth */
/* /*
* Everything possible has been done to validate the timestamps * Everything possible has been done to validate the timestamps
* and prevent bad guys from disrupting the protocol or * and prevent bad guys from disrupting the protocol or
* injecting bogus data. Earn some revenue. * injecting bogus data. Earn some revenue.
*/
*/
packet(p, r); packet(p, r);
} }
A.5.1.1. packet() A.5.1.1. packet()
/* /*
* packet() - process packet and compute offset, delay and * packet() - process packet and compute offset, delay and
* dispersion. * dispersion.
*/ */
void void
skipping to change at page 82, line 52 skipping to change at page 84, line 4
/* /*
* Verify the server is synchronized with valid stratum and * Verify the server is synchronized with valid stratum and
* reference time not later than the transmit time. * reference time not later than the transmit time.
*/ */
if (p->leap == NOSYNC || p->stratum >= MAXSTRAT) if (p->leap == NOSYNC || p->stratum >= MAXSTRAT)
return; /* unsynchronized */ return; /* unsynchronized */
/* /*
* Verify valid root distance. * Verify valid root distance.
*/
*/
if (r->rootdelay / 2 + r->rootdisp >= MAXDISP || p->reftime > if (r->rootdelay / 2 + r->rootdisp >= MAXDISP || p->reftime >
r->xmt) r->xmt)
return; /* invalid header values */ return; /* invalid header values */
poll_update(p, p->hpoll); poll_update(p, p->hpoll);
p->reach |= 1; p->reach |= 1;
/* /*
* Calculate offset, delay and dispersion, then pass to the * Calculate offset, delay and dispersion, then pass to the
* clock filter. Note carefully the implied processing. The * clock filter. Note carefully the implied processing. The
skipping to change at page 85, line 51 skipping to change at page 87, line 4
* interval. * interval.
*/ */
if (root_dist(p) > MAXDIST + PHI * LOG2D(s.poll)) if (root_dist(p) > MAXDIST + PHI * LOG2D(s.poll))
return (FALSE); return (FALSE);
/* /*
* A loop error occurs if the remote peer is synchronized to the * A loop error occurs if the remote peer is synchronized to the
* local peer or the remote peer is synchronized to the current * local peer or the remote peer is synchronized to the current
* system peer. Note this is the behavior for IPv4; for IPv6 the * system peer. Note this is the behavior for IPv4; for IPv6 the
* MD5 hash is used instead. * MD5 hash is used instead.
*/
*/
if (p->refid == p->dstaddr || p->refid == s.refid) if (p->refid == p->dstaddr || p->refid == s.refid)
return (FALSE); return (FALSE);
/* /*
* An unreachable error occurs if the server is unreachable. * An unreachable error occurs if the server is unreachable.
*/ */
if (p->reach == 0) if (p->reach == 0)
return (FALSE); return (FALSE);
return (TRUE); return (TRUE);
skipping to change at page 104, line 30 skipping to change at page 105, line 30
while (/* all associations */ 0) { while (/* all associations */ 0) {
struct p *p; /* dummy peer structure pointer */ struct p *p; /* dummy peer structure pointer */
if (c.t >= p->nextdate) if (c.t >= p->nextdate)
poll(p); poll(p);
} }
/* /*
* Once per hour write the clock frequency to a file * Once per hour write the clock frequency to a file
*/ */
if (c.t % 3600 == 3599) /*
/* write c.freq to file */ 0; * if (c.t % 3600 == 3599)
* write c.freq to file
*/
} }
A.5.7. Poll Process A.5.7. Poll Process
/* /*
* Poll process parameters and constants * Poll process parameters and constants
*/ */
#define UNREACH 12 /* unreach counter threshold */ #define UNREACH 12 /* unreach counter threshold */
#define BCOUNT 8 /* packets in a burst */ #define BCOUNT 8 /* packets in a burst */
#define BTIME 2 /* burst interval (s) */ #define BTIME 2 /* burst interval (s) */
skipping to change at page 106, line 9 skipping to change at page 107, line 11
if (p->burst == 0) { if (p->burst == 0) {
/* /*
* We are not in a burst. Shift the reachability * We are not in a burst. Shift the reachability
* register to the left. Hopefully, some time before the * register to the left. Hopefully, some time before the
* next poll a packet will arrive and set the rightmost * next poll a packet will arrive and set the rightmost
* bit. * bit.
*/ */
oreach = p->reach; oreach = p->reach;
p->outdate = c.t; p->outdate = c.t;
p->reach << 1; p->reach = p->reach << 1;
if (!(p->reach & 0x7)) if (!(p->reach & 0x7))
clock_filter(p, 0, 0, MAXDISP); clock_filter(p, 0, 0, MAXDISP);
if (!p->reach) { if (!p->reach) {
/* /*
* The server is unreachable, so bump the * The server is unreachable, so bump the
* unreach counter. If the unreach threshold has * unreach counter. If the unreach threshold has
* been reached, double the poll interval to * been reached, double the poll interval to
* minimize wasted network traffic. Send a burst * minimize wasted network traffic. Send a burst
* only if enabled and the unreach threshold has * only if enabled and the unreach threshold has
 End of changes. 28 change blocks. 
37 lines changed or deleted 43 lines changed or added

This html diff was produced by rfcdiff 1.37a. The latest version is available from http://tools.ietf.org/tools/rfcdiff/