ntp_proto.c revision 182007
154359Sroberto/* 254359Sroberto * ntp_proto.c - NTP version 4 protocol machinery 354363Sroberto * 4132454Sroberto * ATTENTION: Get approval from Dave Mills on all changes to this file! 5132454Sroberto * 654359Sroberto */ 754359Sroberto#ifdef HAVE_CONFIG_H 854359Sroberto#include <config.h> 954359Sroberto#endif 1054359Sroberto 1154359Sroberto#include "ntpd.h" 1254359Sroberto#include "ntp_stdlib.h" 1354359Sroberto#include "ntp_unixtime.h" 1454359Sroberto#include "ntp_control.h" 1554359Sroberto#include "ntp_string.h" 1654359Sroberto 1782505Sroberto#include <stdio.h> 1882505Sroberto 1954359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/ 2054359Sroberto#include "ntp_refclock.h" 2154359Sroberto#endif 2254359Sroberto 2354359Sroberto#if defined(__FreeBSD__) && __FreeBSD__ >= 3 2454359Sroberto#include <sys/sysctl.h> 2554359Sroberto#endif 2654359Sroberto 2754359Sroberto/* 28182007Sroberto * This macro defines the authentication state. If x is 1 authentication 29182007Sroberto * is required; othewise it is optional. 30182007Sroberto */ 31182007Sroberto#define AUTH(x, y) ((x) ? (y) == AUTH_OK : (y) == AUTH_OK || \ 32182007Sroberto (y) == AUTH_NONE) 33182007Sroberto 34182007Sroberto/* 3582505Sroberto * System variables are declared here. See Section 3.2 of the 3654359Sroberto * specification. 3754359Sroberto */ 3854359Srobertou_char sys_leap; /* system leap indicator */ 3954359Srobertou_char sys_stratum; /* stratum of system */ 40182007Srobertos_char sys_precision; /* local clock precision (log2 s) */ 4182505Srobertodouble sys_rootdelay; /* roundtrip delay to primary source */ 4282505Srobertodouble sys_rootdispersion; /* dispersion to primary source */ 43182007Srobertou_int32 sys_refid; /* source/loop in network byte order */ 4454359Srobertostatic double sys_offset; /* current local clock offset */ 4554359Srobertol_fp sys_reftime; /* time we were last updated */ 46132454Srobertostruct peer *sys_peer; /* our current peer */ 47182007Srobertostruct peer *sys_pps; /* our PPS peer */ 4882505Srobertostruct peer *sys_prefer; /* our cherished peer */ 49132454Srobertoint sys_kod; /* kod credit */ 50132454Srobertoint sys_kod_rate = 2; /* max kod packets per second */ 51132454Sroberto#ifdef OPENSSL 5254359Srobertou_long sys_automax; /* maximum session key lifetime */ 53132454Sroberto#endif /* OPENSSL */ 5454359Sroberto 5554359Sroberto/* 5654359Sroberto * Nonspecified system state variables. 5754359Sroberto */ 58132454Srobertoint sys_bclient; /* broadcast client enable */ 59132454Srobertodouble sys_bdelay; /* broadcast client default delay */ 60132454Srobertoint sys_calldelay; /* modem callup delay (s) */ 6154359Srobertoint sys_authenticate; /* requre authentication for config */ 6254359Srobertol_fp sys_authdelay; /* authentication delay */ 63132454Srobertostatic u_long sys_authdly[2]; /* authentication delay shift reg */ 64182007Srobertostatic double sys_mindisp = MINDISPERSE; /* min disp increment (s) */ 65182007Srobertostatic double sys_maxdist = MAXDISTANCE; /* selection threshold (s) */ 66182007Srobertodouble sys_jitter; /* system jitter (s) */ 67182007Srobertostatic int sys_hopper; /* anticlockhop counter */ 68182007Srobertostatic int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */ 69182007Srobertoint leap_next; /* leap consensus */ 7082505Srobertokeyid_t sys_private; /* private value for session seed */ 7182505Srobertoint sys_manycastserver; /* respond to manycast client pkts */ 7282505Srobertoint peer_ntpdate; /* active peers in ntpdate mode */ 73132454Srobertoint sys_survivors; /* truest of the truechimers */ 74132454Sroberto#ifdef OPENSSL 7582505Srobertochar *sys_hostname; /* gethostname() name */ 76132454Sroberto#endif /* OPENSSL */ 7754359Sroberto 7854359Sroberto/* 79132454Sroberto * TOS and multicast mapping stuff 80132454Sroberto */ 81182007Srobertoint sys_floor = 0; /* cluster stratum floor */ 82182007Srobertoint sys_ceiling = STRATUM_UNSPEC; /* cluster stratum ceiling */ 83132454Srobertoint sys_minsane = 1; /* minimum candidates */ 84132454Srobertoint sys_minclock = NTP_MINCLOCK; /* minimum survivors */ 85182007Srobertoint sys_maxclock = NTP_MAXCLOCK; /* maximum candidates */ 86132454Srobertoint sys_cohort = 0; /* cohort switch */ 87182007Srobertoint sys_orphan = STRATUM_UNSPEC + 1; /* orphan stratum */ 88182007Srobertodouble sys_orphandelay = 0; /* orphan root delay */ 89182007Srobertoint sys_beacon = BEACON; /* manycast beacon interval */ 90132454Srobertoint sys_ttlmax; /* max ttl mapping vector index */ 91132454Srobertou_char sys_ttl[MAX_TTL]; /* ttl mapping vector */ 92132454Sroberto 93132454Sroberto/* 9454359Sroberto * Statistics counters 9554359Sroberto */ 96132454Srobertou_long sys_stattime; /* time since reset */ 97132454Srobertou_long sys_received; /* packets received */ 9854359Srobertou_long sys_processed; /* packets processed */ 99132454Srobertou_long sys_newversionpkt; /* current version */ 100132454Srobertou_long sys_oldversionpkt; /* recent version */ 101132454Srobertou_long sys_unknownversion; /* invalid version */ 102132454Srobertou_long sys_restricted; /* access denied */ 103132454Srobertou_long sys_badlength; /* bad length or format */ 104132454Srobertou_long sys_badauth; /* bad authentication */ 105132454Srobertou_long sys_limitrejected; /* rate exceeded */ 10654359Sroberto 10754359Srobertostatic double root_distance P((struct peer *)); 108182007Srobertostatic void clock_combine P((struct peer **, int)); 10954359Srobertostatic void peer_xmit P((struct peer *)); 110182007Srobertostatic void fast_xmit P((struct recvbuf *, int, keyid_t, 111182007Sroberto int)); 11254359Srobertostatic void clock_update P((void)); 113182007Srobertostatic int default_get_precision P((void)); 114132454Srobertostatic int peer_unfit P((struct peer *)); 11554359Sroberto 116182007Sroberto 11754359Sroberto/* 11854359Sroberto * transmit - Transmit Procedure. See Section 3.4.2 of the 11954359Sroberto * specification. 12054359Sroberto */ 12154359Srobertovoid 12254359Srobertotransmit( 12354359Sroberto struct peer *peer /* peer structure pointer */ 12454359Sroberto ) 12554359Sroberto{ 126132454Sroberto int hpoll; 12754359Sroberto 128132454Sroberto /* 129132454Sroberto * The polling state machine. There are two kinds of machines, 130132454Sroberto * those that never expect a reply (broadcast and manycast 131132454Sroberto * server modes) and those that do (all other modes). The dance 132132454Sroberto * is intricate... 133132454Sroberto */ 134182007Sroberto /* 135182007Sroberto * Orphan mode is active when enabled and when no servers less 136182007Sroberto * than the orphan statum are available. In this mode packets 137182007Sroberto * are sent at the orphan stratum. An orphan with no other 138182007Sroberto * synchronization source is an orphan parent. It assumes root 139182007Sroberto * delay zero and reference ID the loopback address. All others 140182007Sroberto * are orphan children with root delay randomized over a 1-s 141182007Sroberto * range. The root delay is used by the election algorithm to 142182007Sroberto * select the order of synchronization. 143182007Sroberto */ 14454359Sroberto hpoll = peer->hpoll; 145182007Sroberto if (sys_orphan < STRATUM_UNSPEC && sys_peer == NULL) { 146182007Sroberto sys_leap = LEAP_NOWARNING; 147182007Sroberto sys_stratum = sys_orphan; 148182007Sroberto sys_refid = htonl(LOOPBACKADR); 149182007Sroberto sys_rootdelay = 0; 150182007Sroberto sys_rootdispersion = 0; 151182007Sroberto } 152182007Sroberto 153182007Sroberto /* 154182007Sroberto * In broadcast mode the poll interval is never changed from 155182007Sroberto * minpoll. 156182007Sroberto */ 157132454Sroberto if (peer->cast_flags & (MDF_BCAST | MDF_MCAST)) { 158182007Sroberto peer->outdate = current_time; 159182007Sroberto peer_xmit(peer); 160182007Sroberto poll_update(peer, hpoll); 161182007Sroberto return; 162182007Sroberto } 16354359Sroberto 164182007Sroberto /* 165182007Sroberto * In manycast mode we start with unity ttl. The ttl is 166182007Sroberto * increased by one for each poll until either sys_maxclock 167182007Sroberto * servers have been found or the maximum ttl is reached. When 168182007Sroberto * sys_maxclock servers are found we stop polling until one or 169182007Sroberto * more servers have timed out or until less than minpoll 170182007Sroberto * associations turn up. In this case additional better servers 171182007Sroberto * are dragged in and preempt the existing ones. 172182007Sroberto */ 173182007Sroberto if (peer->cast_flags & MDF_ACAST) { 174182007Sroberto peer->outdate = current_time; 175182007Sroberto if (peer->unreach > sys_beacon) { 176182007Sroberto peer->unreach = 0; 177182007Sroberto peer->ttl = 0; 178182007Sroberto peer_xmit(peer); 179182007Sroberto } else if (sys_survivors < sys_minclock || 180182007Sroberto peer_preempt < sys_maxclock) { 181182007Sroberto if (peer->ttl < sys_ttlmax) 182182007Sroberto peer->ttl++; 183182007Sroberto peer_xmit(peer); 184182007Sroberto } 185182007Sroberto peer->unreach++; 186182007Sroberto poll_update(peer, hpoll); 187182007Sroberto return; 188182007Sroberto } 18982505Sroberto 190182007Sroberto /* 191182007Sroberto * In unicast modes the dance is much more intricate. It is 192182007Sroberto * desigmed to back off whenever possible to minimize network 193182007Sroberto * traffic. 194182007Sroberto */ 195182007Sroberto if (peer->burst == 0) { 196182007Sroberto u_char oreach; 197182007Sroberto 198132454Sroberto /* 199182007Sroberto * Update the reachability status. If not heard for 200182007Sroberto * three consecutive polls, stuff infinity in the clock 201182007Sroberto * filter. 202132454Sroberto */ 203182007Sroberto oreach = peer->reach; 204182007Sroberto peer->outdate = current_time; 205182007Sroberto if (peer == sys_peer) 206182007Sroberto sys_hopper++; 207182007Sroberto peer->reach <<= 1; 208182007Sroberto if (!(peer->reach & 0x07)) 209182007Sroberto clock_filter(peer, 0., 0., MAXDISPERSE); 210182007Sroberto if (!peer->reach) { 21182505Sroberto 212182007Sroberto /* 213182007Sroberto * Here the peer is unreachable. If it was 214182007Sroberto * previously reachable, raise a trap. 215182007Sroberto */ 216182007Sroberto if (oreach) { 217182007Sroberto report_event(EVNT_UNREACH, peer); 218182007Sroberto peer->timereachable = current_time; 219182007Sroberto } 220182007Sroberto 221182007Sroberto /* 222182007Sroberto * Send a burst if enabled, but only once after 223182007Sroberto * a peer becomes unreachable. If the prempt 224182007Sroberto * flag is dim, bump the unreach counter by one; 225182007Sroberto * otherwise, bump it by three. 226182007Sroberto */ 227182007Sroberto if (peer->flags & FLAG_IBURST && 228182007Sroberto peer->unreach == 0) { 229182007Sroberto peer->burst = NTP_BURST; 230182007Sroberto } 231182007Sroberto if (!(peer->flags & FLAG_PREEMPT)) 232182007Sroberto peer->unreach++; 233182007Sroberto else 234182007Sroberto peer->unreach += 3; 235182007Sroberto } else { 236182007Sroberto 237182007Sroberto /* 238182007Sroberto * Here the peer is reachable. Set the poll 239182007Sroberto * interval to the system poll interval. Send a 240182007Sroberto * burst only if enabled and the peer is fit. 241182007Sroberto * 242182007Sroberto * Respond to the peer evaluation produced by 243182007Sroberto * the selection algorithm. If less than the 244182007Sroberto * outlyer level, up the unreach by three. If 245182007Sroberto * there are excess associations, up the unreach 246182007Sroberto * by two if not a candidate and by one if so. 247182007Sroberto */ 248182007Sroberto if (!(peer->flags & FLAG_PREEMPT)) { 249182007Sroberto peer->unreach = 0; 250182007Sroberto } else if (peer->status < CTL_PST_SEL_SELCAND) { 251182007Sroberto peer->unreach += 3; 252182007Sroberto } else if (peer_preempt > sys_maxclock) { 253182007Sroberto if (peer->status < CTL_PST_SEL_SYNCCAND) 254182007Sroberto peer->unreach += 2; 255182007Sroberto else 256182007Sroberto peer->unreach++; 257182007Sroberto } else { 258182007Sroberto peer->unreach = 0; 259182007Sroberto } 260182007Sroberto hpoll = sys_poll; 261182007Sroberto if (peer->flags & FLAG_BURST && 262182007Sroberto !peer_unfit(peer)) 263182007Sroberto peer->burst = NTP_BURST; 264182007Sroberto } 265182007Sroberto 266132454Sroberto /* 267182007Sroberto * Watch for timeout. If ephemeral or preemptable, toss 268182007Sroberto * the rascal; otherwise, bump the poll interval. 269182007Sroberto */ 270132454Sroberto if (peer->unreach >= NTP_UNREACH) { 271182007Sroberto if (peer->flags & FLAG_PREEMPT || 272182007Sroberto !(peer->flags & FLAG_CONFIG)) { 273182007Sroberto peer_clear(peer, "TIME"); 27482505Sroberto unpeer(peer); 27582505Sroberto return; 276182007Sroberto } else { 277182007Sroberto hpoll++; 27882505Sroberto } 27982505Sroberto } 280182007Sroberto } else { 281182007Sroberto peer->burst--; 282182007Sroberto 283182007Sroberto /* 284182007Sroberto * If a broadcast client at this point, the burst has 285182007Sroberto * concluded, so we switch to client mode and purge the 286182007Sroberto * keylist, since no further transmissions will be made. 287182007Sroberto */ 288132454Sroberto if (peer->burst == 0) { 289182007Sroberto if (peer->cast_flags & MDF_BCLNT) { 290182007Sroberto peer->hmode = MODE_BCLIENT; 291182007Sroberto#ifdef OPENSSL 292182007Sroberto key_expire(peer); 293182007Sroberto#endif /* OPENSSL */ 29454359Sroberto } 29554359Sroberto 29654359Sroberto /* 297182007Sroberto * If ntpdate mode and the clock has not been 298182007Sroberto * set and all peers have completed the burst, 299182007Sroberto * we declare a successful failure. 30054359Sroberto */ 301182007Sroberto if (mode_ntpdate) { 302182007Sroberto peer_ntpdate--; 303182007Sroberto if (peer_ntpdate == 0) { 304132454Sroberto msyslog(LOG_NOTICE, 305132454Sroberto "no reply; clock not set"); 306132454Sroberto exit (0); 307132454Sroberto } 30854359Sroberto } 30954359Sroberto } 31054359Sroberto } 31154359Sroberto 31254359Sroberto /* 313182007Sroberto * Do not transmit if in broadcast client mode. 31454359Sroberto */ 315182007Sroberto if (peer->hmode != MODE_BCLIENT) 316182007Sroberto peer_xmit(peer); 317132454Sroberto poll_update(peer, hpoll); 31854359Sroberto} 31954359Sroberto 320182007Sroberto 32154359Sroberto/* 32254359Sroberto * receive - Receive Procedure. See section 3.4.3 in the specification. 32354359Sroberto */ 32454359Srobertovoid 32554359Srobertoreceive( 32654359Sroberto struct recvbuf *rbufp 32754359Sroberto ) 32854359Sroberto{ 329132454Sroberto register struct peer *peer; /* peer structure pointer */ 330132454Sroberto register struct pkt *pkt; /* receive packet pointer */ 331182007Sroberto int hisversion; /* packet version */ 332182007Sroberto int hisleap; /* packet leap indicator */ 333132454Sroberto int hismode; /* packet mode */ 334182007Sroberto int hisstratum; /* packet stratum */ 335132454Sroberto int restrict_mask; /* restrict bits */ 336132454Sroberto int has_mac; /* length of MAC field */ 337132454Sroberto int authlen; /* offset of MAC field */ 338182007Sroberto int is_authentic = 0; /* cryptosum ok */ 339132454Sroberto keyid_t skeyid = 0; /* key ID */ 340132454Sroberto struct sockaddr_storage *dstadr_sin; /* active runway */ 341132454Sroberto struct peer *peer2; /* aux peer structure pointer */ 342182007Sroberto l_fp p_org; /* origin timestamp */ 343182007Sroberto l_fp p_rec; /* receive timestamp */ 344132454Sroberto l_fp p_xmt; /* transmit timestamp */ 345132454Sroberto#ifdef OPENSSL 346132454Sroberto keyid_t tkeyid = 0; /* temporary key ID */ 347132454Sroberto keyid_t pkeyid = 0; /* previous key ID */ 348132454Sroberto struct autokey *ap; /* autokey structure pointer */ 349132454Sroberto int rval; /* cookie snatcher */ 350132454Sroberto#endif /* OPENSSL */ 35154359Sroberto int retcode = AM_NOMATCH; 352182007Sroberto int at_listhead; 35354359Sroberto 35454359Sroberto /* 35582505Sroberto * Monitor the packet and get restrictions. Note that the packet 35682505Sroberto * length for control and private mode packets must be checked 35782505Sroberto * by the service routines. Note that no statistics counters are 35882505Sroberto * recorded for restrict violations, since these counters are in 35982505Sroberto * the restriction routine. Note the careful distinctions here 36082505Sroberto * between a packet with a format error and a packet that is 36182505Sroberto * simply discarded without prejudice. Some restrictions have to 36282505Sroberto * be handled later in order to generate a kiss-of-death packet. 36354359Sroberto */ 364132454Sroberto /* 365132454Sroberto * Bogus port check is before anything, since it probably 366132454Sroberto * reveals a clogging attack. 367132454Sroberto */ 368132454Sroberto sys_received++; 369132454Sroberto if (SRCPORT(&rbufp->recv_srcadr) == 0) { 370132454Sroberto sys_badlength++; 371132454Sroberto return; /* bogus port */ 372132454Sroberto } 373182007Sroberto at_listhead = ntp_monitor(rbufp); 374182007Sroberto restrict_mask = restrictions(&rbufp->recv_srcadr, at_listhead); 37554359Sroberto#ifdef DEBUG 376132454Sroberto if (debug > 1) 377182007Sroberto printf("receive: at %ld %s<-%s flags %x restrict %03x\n", 378132454Sroberto current_time, stoa(&rbufp->dstadr->sin), 379182007Sroberto stoa(&rbufp->recv_srcadr), 380182007Sroberto rbufp->dstadr->flags, restrict_mask); 38154359Sroberto#endif 382132454Sroberto if (restrict_mask & RES_IGNORE) { 383132454Sroberto sys_restricted++; 384182007Sroberto return; /* ignore everything */ 385132454Sroberto } 38654359Sroberto pkt = &rbufp->recv_pkt; 387182007Sroberto hisversion = PKT_VERSION(pkt->li_vn_mode); 388182007Sroberto hisleap = PKT_LEAP(pkt->li_vn_mode); 389132454Sroberto hismode = (int)PKT_MODE(pkt->li_vn_mode); 390182007Sroberto hisstratum = PKT_TO_STRATUM(pkt->stratum); 391132454Sroberto if (hismode == MODE_PRIVATE) { 392132454Sroberto if (restrict_mask & RES_NOQUERY) { 393132454Sroberto sys_restricted++; 39482505Sroberto return; /* no query private */ 395132454Sroberto } 39656749Sroberto process_private(rbufp, ((restrict_mask & 39756749Sroberto RES_NOMODIFY) == 0)); 39854359Sroberto return; 39954359Sroberto } 400132454Sroberto if (hismode == MODE_CONTROL) { 401132454Sroberto if (restrict_mask & RES_NOQUERY) { 402132454Sroberto sys_restricted++; 40382505Sroberto return; /* no query control */ 404132454Sroberto } 40554359Sroberto process_control(rbufp, restrict_mask); 40654359Sroberto return; 40754359Sroberto } 408132454Sroberto if (restrict_mask & RES_DONTSERVE) { 409132454Sroberto sys_restricted++; 410132454Sroberto return; /* no time */ 411132454Sroberto } 41282505Sroberto if (rbufp->recv_length < LEN_PKT_NOMAC) { 41382505Sroberto sys_badlength++; 41482505Sroberto return; /* runt packet */ 41582505Sroberto } 416132454Sroberto 417132454Sroberto /* 418132454Sroberto * Version check must be after the query packets, since they 419132454Sroberto * intentionally use early version. 420132454Sroberto */ 421182007Sroberto if (hisversion == NTP_VERSION) { 422132454Sroberto sys_newversionpkt++; /* new version */ 423182007Sroberto } else if (!(restrict_mask & RES_VERSION) && hisversion >= 424182007Sroberto NTP_OLDVERSION) { 425132454Sroberto sys_oldversionpkt++; /* previous version */ 426132454Sroberto } else { 427132454Sroberto sys_unknownversion++; 428132454Sroberto return; /* old version */ 429132454Sroberto } 43054359Sroberto 43154359Sroberto /* 432132454Sroberto * Figure out his mode and validate the packet. This has some 433132454Sroberto * legacy raunch that probably should be removed. In very early 434132454Sroberto * NTP versions mode 0 was equivalent to what later versions 435132454Sroberto * would interpret as client mode. 43654359Sroberto */ 43782505Sroberto if (hismode == MODE_UNSPEC) { 438182007Sroberto if (hisversion == NTP_OLDVERSION) { 439132454Sroberto hismode = MODE_CLIENT; 440132454Sroberto } else { 441132454Sroberto sys_badlength++; 442132454Sroberto return; /* invalid mode */ 443132454Sroberto } 44482505Sroberto } 44554359Sroberto 44654359Sroberto /* 44782505Sroberto * Parse the extension field if present. We figure out whether 44882505Sroberto * an extension field is present by measuring the MAC size. If 449182007Sroberto * the number of words following the packet header is 0, no MAC 450182007Sroberto * is present and the packet is not authenticated. If 1, the 451182007Sroberto * packet is a crypto-NAK; if 3, the packet is authenticated 452182007Sroberto * with DES; if 5, the packet is authenticated with MD5. If 2 or 453182007Sroberto * 4, the packet is a runt and discarded forthwith. If greater 454182007Sroberto * than 5, an extension field is present, so we subtract the 455182007Sroberto * length of the field and go around again. 45654359Sroberto */ 45754359Sroberto authlen = LEN_PKT_NOMAC; 458132454Sroberto has_mac = rbufp->recv_length - authlen; 459132454Sroberto while (has_mac > 0) { 46082505Sroberto int temp; 46182505Sroberto 46282505Sroberto if (has_mac % 4 != 0 || has_mac < 0) { 46354359Sroberto sys_badlength++; 464132454Sroberto return; /* bad MAC length */ 46554359Sroberto } 46682505Sroberto if (has_mac == 1 * 4 || has_mac == 3 * 4 || has_mac == 46782505Sroberto MAX_MAC_LEN) { 46882505Sroberto skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]); 46982505Sroberto break; 47054359Sroberto 47182505Sroberto } else if (has_mac > MAX_MAC_LEN) { 47282505Sroberto temp = ntohl(((u_int32 *)pkt)[authlen / 4]) & 47382505Sroberto 0xffff; 474132454Sroberto if (temp < 4 || temp > NTP_MAXEXTEN || temp % 4 475132454Sroberto != 0) { 47682505Sroberto sys_badlength++; 477132454Sroberto return; /* bad MAC length */ 47882505Sroberto } 47982505Sroberto authlen += temp; 480132454Sroberto has_mac -= temp; 48182505Sroberto } else { 48282505Sroberto sys_badlength++; 483132454Sroberto return; /* bad MAC length */ 48482505Sroberto } 48554359Sroberto } 486132454Sroberto#ifdef OPENSSL 487132454Sroberto pkeyid = tkeyid = 0; 488132454Sroberto#endif /* OPENSSL */ 48954359Sroberto 49054359Sroberto /* 49182505Sroberto * We have tossed out as many buggy packets as possible early in 49282505Sroberto * the game to reduce the exposure to a clogging attack. Now we 49382505Sroberto * have to burn some cycles to find the association and 49482505Sroberto * authenticate the packet if required. Note that we burn only 495132454Sroberto * MD5 cycles, again to reduce exposure. There may be no 49682505Sroberto * matching association and that's okay. 49782505Sroberto * 49882505Sroberto * More on the autokey mambo. Normally the local interface is 49982505Sroberto * found when the association was mobilized with respect to a 50082505Sroberto * designated remote address. We assume packets arriving from 50182505Sroberto * the remote address arrive via this interface and the local 50282505Sroberto * address used to construct the autokey is the unicast address 50382505Sroberto * of the interface. However, if the sender is a broadcaster, 50482505Sroberto * the interface broadcast address is used instead. 505182007Sroberto & Notwithstanding this technobabble, if the sender is a 50682505Sroberto * multicaster, the broadcast address is null, so we use the 50782505Sroberto * unicast address anyway. Don't ask. 50854359Sroberto */ 509182007Sroberto peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr, hismode, 510182007Sroberto &retcode); 51182505Sroberto dstadr_sin = &rbufp->dstadr->sin; 512182007Sroberto NTOHL_FP(&pkt->org, &p_org); 513182007Sroberto NTOHL_FP(&pkt->rec, &p_rec); 514182007Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 515182007Sroberto 516182007Sroberto /* 517182007Sroberto * Authentication is conditioned by three switches: 518182007Sroberto * 519182007Sroberto * NOPEER (RES_NOPEER) do not mobilize an association unless 520182007Sroberto * authenticated 521182007Sroberto * NOTRUST (RES_DONTTRUST) do not allow access unless 522182007Sroberto * authenticated (implies NOPEER) 523182007Sroberto * enable (sys_authenticate) master NOPEER switch, by default 524182007Sroberto * on 525182007Sroberto * 526182007Sroberto * The NOPEER and NOTRUST can be specified on a per-client basis 527182007Sroberto * using the restrict command. The enable switch if on implies 528182007Sroberto * NOPEER for all clients. There are four outcomes: 529182007Sroberto * 530182007Sroberto * NONE The packet has no MAC. 531182007Sroberto * OK the packet has a MAC and authentication succeeds 532182007Sroberto * ERROR the packet has a MAC and authentication fails 533182007Sroberto * CRYPTO crypto-NAK. The MAC has four octets only. 534182007Sroberto * 535182007Sroberto * Note: The AUTH(x, y) macro is used to filter outcomes. If x 536182007Sroberto * is zero, acceptable outcomes of y are NONE and OK. If x is 537182007Sroberto * one, the only acceptable outcome of y is OK. 538182007Sroberto */ 53954359Sroberto if (has_mac == 0) { 540182007Sroberto is_authentic = AUTH_NONE; /* not required */ 54154359Sroberto#ifdef DEBUG 54254359Sroberto if (debug) 543182007Sroberto printf("receive: at %ld %s<-%s mode %d code %d auth %d\n", 544182007Sroberto current_time, stoa(dstadr_sin), 545182007Sroberto stoa(&rbufp->recv_srcadr), hismode, retcode, 546182007Sroberto is_authentic); 54754359Sroberto#endif 548182007Sroberto } else if (has_mac == 4) { 549182007Sroberto is_authentic = AUTH_CRYPTO; /* crypto-NAK */ 550182007Sroberto#ifdef DEBUG 551182007Sroberto if (debug) 552182007Sroberto printf( 553182007Sroberto "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n", 554182007Sroberto current_time, stoa(dstadr_sin), 555182007Sroberto stoa(&rbufp->recv_srcadr), hismode, retcode, 556182007Sroberto skeyid, authlen, has_mac, is_authentic); 557182007Sroberto#endif 55854359Sroberto } else { 559132454Sroberto#ifdef OPENSSL 56082505Sroberto /* 56182505Sroberto * For autokey modes, generate the session key 56282505Sroberto * and install in the key cache. Use the socket 56382505Sroberto * broadcast or unicast address as appropriate. 56482505Sroberto */ 56582505Sroberto if (skeyid > NTP_MAXKEY) { 56682505Sroberto 56782505Sroberto /* 56882505Sroberto * More on the autokey dance (AKD). A cookie is 56982505Sroberto * constructed from public and private values. 57082505Sroberto * For broadcast packets, the cookie is public 57182505Sroberto * (zero). For packets that match no 57282505Sroberto * association, the cookie is hashed from the 57382505Sroberto * addresses and private value. For server 57482505Sroberto * packets, the cookie was previously obtained 57582505Sroberto * from the server. For symmetric modes, the 57682505Sroberto * cookie was previously constructed using an 57782505Sroberto * agreement protocol; however, should PKI be 57882505Sroberto * unavailable, we construct a fake agreement as 57982505Sroberto * the EXOR of the peer and host cookies. 58082505Sroberto * 58182505Sroberto * hismode ephemeral persistent 58282505Sroberto * ======================================= 58382505Sroberto * active 0 cookie# 58482505Sroberto * passive 0% cookie# 58582505Sroberto * client sys cookie 0% 58682505Sroberto * server 0% sys cookie 58782505Sroberto * broadcast 0 0 58882505Sroberto * 58982505Sroberto * # if unsync, 0 59082505Sroberto * % can't happen 59182505Sroberto */ 59282505Sroberto if (hismode == MODE_BROADCAST) { 59354359Sroberto 59482505Sroberto /* 59582505Sroberto * For broadcaster, use the interface 59682505Sroberto * broadcast address when available; 59782505Sroberto * otherwise, use the unicast address 59882505Sroberto * found when the association was 599182007Sroberto * mobilized. However, if this is from 600182007Sroberto * the wildcard interface, game over. 60182505Sroberto */ 602182007Sroberto if (crypto_flags && rbufp->dstadr == 603182007Sroberto any_interface) { 604182007Sroberto sys_restricted++; 605182007Sroberto return; /* no wildcard */ 606182007Sroberto } 60782505Sroberto pkeyid = 0; 608132454Sroberto if (!SOCKNUL(&rbufp->dstadr->bcast)) 60982505Sroberto dstadr_sin = 61082505Sroberto &rbufp->dstadr->bcast; 61182505Sroberto } else if (peer == NULL) { 61282505Sroberto pkeyid = session_key( 61382505Sroberto &rbufp->recv_srcadr, dstadr_sin, 0, 61482505Sroberto sys_private, 0); 61582505Sroberto } else { 616132454Sroberto pkeyid = peer->pcookie; 61782505Sroberto } 61882505Sroberto 61954359Sroberto /* 62082505Sroberto * The session key includes both the public 62182505Sroberto * values and cookie. In case of an extension 62282505Sroberto * field, the cookie used for authentication 62382505Sroberto * purposes is zero. Note the hash is saved for 62482505Sroberto * use later in the autokey mambo. 62554359Sroberto */ 62682505Sroberto if (authlen > LEN_PKT_NOMAC && pkeyid != 0) { 62782505Sroberto session_key(&rbufp->recv_srcadr, 62882505Sroberto dstadr_sin, skeyid, 0, 2); 62954359Sroberto tkeyid = session_key( 63082505Sroberto &rbufp->recv_srcadr, dstadr_sin, 63182505Sroberto skeyid, pkeyid, 0); 63282505Sroberto } else { 63354359Sroberto tkeyid = session_key( 63482505Sroberto &rbufp->recv_srcadr, dstadr_sin, 63582505Sroberto skeyid, pkeyid, 2); 63654359Sroberto } 63754359Sroberto 63854359Sroberto } 639132454Sroberto#endif /* OPENSSL */ 64054359Sroberto 64154359Sroberto /* 64254359Sroberto * Compute the cryptosum. Note a clogging attack may 64382505Sroberto * succeed in bloating the key cache. If an autokey, 64482505Sroberto * purge it immediately, since we won't be needing it 645182007Sroberto * again. If the packet is authentic, it can mobilize an 646182007Sroberto * association. Note that there is no key zero. 64754359Sroberto */ 648182007Sroberto if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, 649132454Sroberto has_mac)) { 650182007Sroberto is_authentic = AUTH_ERROR; 651182007Sroberto sys_badauth++; 652132454Sroberto } else { 653182007Sroberto is_authentic = AUTH_OK; 654132454Sroberto } 655132454Sroberto#ifdef OPENSSL 65682505Sroberto if (skeyid > NTP_MAXKEY) 65782505Sroberto authtrust(skeyid, 0); 658132454Sroberto#endif /* OPENSSL */ 65954359Sroberto#ifdef DEBUG 66054359Sroberto if (debug) 66154359Sroberto printf( 66282505Sroberto "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n", 663132454Sroberto current_time, stoa(dstadr_sin), 664132454Sroberto stoa(&rbufp->recv_srcadr), hismode, retcode, 665182007Sroberto skeyid, authlen, has_mac, is_authentic); 66654359Sroberto#endif 66754359Sroberto } 66854359Sroberto 66954359Sroberto /* 67082505Sroberto * The association matching rules are implemented by a set of 671182007Sroberto * routines and an association table. A packet matching an 672182007Sroberto * association is processed by the peer process for that 673182007Sroberto * association. If there are no errors, an ephemeral association 674182007Sroberto * is mobilized: a broadcast packet mobilizes a broadcast client 675132454Sroberto * aassociation; a manycast server packet mobilizes a manycast 676132454Sroberto * client association; a symmetric active packet mobilizes a 677182007Sroberto * symmetric passive association. 67854359Sroberto */ 67954359Sroberto switch (retcode) { 680182007Sroberto 681182007Sroberto /* 682182007Sroberto * This is a client mode packet not matching any association. If 683182007Sroberto * an ordinary client, simply toss a server mode packet back 684182007Sroberto * over the fence. If a manycast client, we have to work a 685182007Sroberto * little harder. 686182007Sroberto */ 68754359Sroberto case AM_FXMIT: 68854359Sroberto 68956749Sroberto /* 690182007Sroberto * The vanilla case is when this is not a multicast 691182007Sroberto * interface. If authentication succeeds, return a 692182007Sroberto * server mode packet; if not and the key ID is nonzero, 693182007Sroberto * return a crypto-NAK. 69456749Sroberto */ 695182007Sroberto if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) { 696182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, 697182007Sroberto is_authentic)) 698182007Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 699182007Sroberto restrict_mask); 700182007Sroberto else if (is_authentic == AUTH_ERROR) 701182007Sroberto fast_xmit(rbufp, MODE_SERVER, 0, 702182007Sroberto restrict_mask); 703182007Sroberto return; /* hooray */ 70456749Sroberto } 70554359Sroberto 70656749Sroberto /* 707182007Sroberto * This must be manycast. Do not respond if not 708182007Sroberto * configured as a manycast server. 70956749Sroberto */ 710182007Sroberto if (!sys_manycastserver) { 711182007Sroberto sys_restricted++; 712182007Sroberto return; /* not enabled */ 713182007Sroberto } 714182007Sroberto 715182007Sroberto /* 716182007Sroberto * Do not respond if unsynchronized or stratum is below 717182007Sroberto * the floor or at or above the ceiling. 718182007Sroberto */ 719182007Sroberto if (sys_leap == LEAP_NOTINSYNC || sys_stratum < 720182007Sroberto sys_floor || sys_stratum >= sys_ceiling) 721182007Sroberto return; /* bad stratum */ 722182007Sroberto 723182007Sroberto /* 724182007Sroberto * Do not respond if our stratum is greater than the 725182007Sroberto * manycaster or it has already synchronized to us. 726182007Sroberto */ 727182007Sroberto if (sys_peer == NULL || hisstratum < sys_stratum || 728182007Sroberto (sys_cohort && hisstratum == sys_stratum) || 729182007Sroberto rbufp->dstadr->addr_refid == pkt->refid) 730182007Sroberto return; /* no help */ 731182007Sroberto 732182007Sroberto /* 733182007Sroberto * Respond only if authentication succeeds. Don't do a 734182007Sroberto * crypto-NAK, as that would not be useful. 735182007Sroberto */ 736182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) 73782505Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 73882505Sroberto restrict_mask); 73956749Sroberto 740182007Sroberto return; /* hooray */ 741182007Sroberto 742182007Sroberto /* 743182007Sroberto * This is a server mode packet returned in response to a client 744182007Sroberto * mode packet sent to a multicast group address. The origin 745182007Sroberto * timestamp is a good nonce to reliably associate the reply 746182007Sroberto * with what was sent. If there is no match, that's curious and 747182007Sroberto * could be an intruder attempting to clog, so we just ignore 748182007Sroberto * it. 749182007Sroberto * 750182007Sroberto * If the packet is authentic and the manycast association is 751182007Sroberto * found, we mobilize a client association and copy pertinent 752182007Sroberto * variables from the manycast association to the new client 753182007Sroberto * association. If not, just ignore the packet. 754182007Sroberto * 755182007Sroberto * There is an implosion hazard at the manycast client, since 756182007Sroberto * the manycast servers send the server packet immediately. If 757182007Sroberto * the guy is already here, don't fire up a duplicate. 758182007Sroberto */ 75954359Sroberto case AM_MANYCAST: 760182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 761182007Sroberto (RES_NOPEER | RES_DONTTRUST)), is_authentic)) 762182007Sroberto return; /* bad auth */ 76354359Sroberto 764182007Sroberto if ((peer2 = findmanycastpeer(rbufp)) == NULL) { 765132454Sroberto sys_restricted++; 766182007Sroberto return; /* not enabled */ 767132454Sroberto } 768182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 769182007Sroberto rbufp->dstadr, MODE_CLIENT, 770182007Sroberto hisversion, NTP_MINDPOLL, NTP_MAXDPOLL, 771182007Sroberto FLAG_IBURST | FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT, 772182007Sroberto 0, skeyid)) == NULL) 773132454Sroberto return; /* system error */ 774132454Sroberto 775132454Sroberto /* 776132454Sroberto * We don't need these, but it warms the billboards. 777132454Sroberto */ 778132454Sroberto peer->ttl = peer2->ttl; 77956749Sroberto break; 78056749Sroberto 781182007Sroberto /* 782182007Sroberto * This is the first packet received from a broadcast server. If 783182007Sroberto * the packet is authentic and we are enabled as broadcast 784182007Sroberto * client, mobilize a broadcast client association. We don't 785182007Sroberto * kiss any frogs here. 786182007Sroberto */ 787182007Sroberto case AM_NEWBCL: 788182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 789182007Sroberto (RES_NOPEER | RES_DONTTRUST)), is_authentic)) 790182007Sroberto return; /* bad auth */ 79154359Sroberto 79256749Sroberto /* 793182007Sroberto * Do not respond if unsynchronized or stratum is below 794182007Sroberto * the floor or at or above the ceiling. 79556749Sroberto */ 796182007Sroberto if (hisleap == LEAP_NOTINSYNC || hisstratum < 797182007Sroberto sys_floor || hisstratum >= sys_ceiling) 798182007Sroberto return; /* bad stratum */ 799132454Sroberto 800182007Sroberto switch (sys_bclient) { 80156749Sroberto 80256749Sroberto /* 803182007Sroberto * If not enabled, just skedaddle. 80456749Sroberto */ 805182007Sroberto case 0: 806132454Sroberto sys_restricted++; 807182007Sroberto return; /* not enabled */ 80882505Sroberto 809132454Sroberto /* 810182007Sroberto * Execute the initial volley in order to calibrate the 811182007Sroberto * propagation delay and run the Autokey protocol, if 812182007Sroberto * enabled. 813132454Sroberto */ 814182007Sroberto case 1: 815182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 816182007Sroberto rbufp->dstadr, MODE_CLIENT, hisversion, 817182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST | 818182007Sroberto FLAG_IBURST, MDF_BCLNT, 0, skeyid)) == 819182007Sroberto NULL) 820182007Sroberto return; /* system error */ 821182007Sroberto#ifdef OPENSSL 822182007Sroberto if (skeyid > NTP_MAXKEY) 823182007Sroberto crypto_recv(peer, rbufp); 824132454Sroberto#endif /* OPENSSL */ 825182007Sroberto return; /* hooray */ 82656749Sroberto 827132454Sroberto 828132454Sroberto /* 829182007Sroberto * Do not execute the initial volley. 83056749Sroberto */ 831182007Sroberto case 2: 832182007Sroberto#ifdef OPENSSL 833182007Sroberto /* 834182007Sroberto * If a two-way exchange is not possible, 835182007Sroberto * neither is Autokey. 836182007Sroberto */ 837182007Sroberto if (skeyid > NTP_MAXKEY) { 838182007Sroberto msyslog(LOG_INFO, 839182007Sroberto "receive: autokey requires two-way communication"); 840182007Sroberto return; /* no autokey */ 841182007Sroberto } 842182007Sroberto#endif /* OPENSSL */ 843182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 844182007Sroberto rbufp->dstadr, MODE_BCLIENT, hisversion, 845182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0, 846182007Sroberto skeyid)) == NULL) 847182007Sroberto return; /* system error */ 848132454Sroberto } 84956749Sroberto break; 85056749Sroberto 851182007Sroberto /* 852182007Sroberto * This is the first packet received from a symmetric active 853182007Sroberto * peer. If the packet is authentic and the first he sent, 854182007Sroberto * mobilize a passive association. If not, kiss the frog. 855182007Sroberto */ 856182007Sroberto case AM_NEWPASS: 85756749Sroberto 85856749Sroberto /* 859182007Sroberto * If the inbound packet is correctly authenticated and 860182007Sroberto * enabled, a symmetric passive association is 861182007Sroberto * mobilized. If not but correctly authenticated, a 862182007Sroberto * symmetric active response is sent. If authentication 863182007Sroberto * fails, send a crypto-NAK packet. 86456749Sroberto */ 865182007Sroberto if (!AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) 866182007Sroberto { 867182007Sroberto if (is_authentic == AUTH_ERROR) 868182007Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, 869182007Sroberto restrict_mask); 870182007Sroberto return; /* bad auth */ 871182007Sroberto } 872182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 873182007Sroberto RES_NOPEER), is_authentic)) { 874182007Sroberto fast_xmit(rbufp, MODE_ACTIVE, skeyid, 875182007Sroberto restrict_mask); 876182007Sroberto return; /* hooray */ 877182007Sroberto } 87854359Sroberto 879182007Sroberto /* 880182007Sroberto * Do not respond if stratum is below the floor. 881182007Sroberto */ 882182007Sroberto if (hisstratum < sys_floor) 883182007Sroberto return; /* bad stratum */ 884182007Sroberto 885182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 886182007Sroberto rbufp->dstadr, MODE_PASSIVE, hisversion, 887182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0, 888182007Sroberto skeyid)) == NULL) 889182007Sroberto return; /* system error */ 890182007Sroberto break; 891182007Sroberto 89254359Sroberto /* 893182007Sroberto * Process regular packet. Nothing special. 89454359Sroberto */ 895182007Sroberto case AM_PROCPKT: 896182007Sroberto break; 89754359Sroberto 89854359Sroberto /* 899182007Sroberto * A passive packet matches a passive association. This is 900182007Sroberto * usually the result of reconfiguring a client on the fly. As 901182007Sroberto * this association might be legitamate and this packet an 902182007Sroberto * attempt to deny service, just ignore it. 90354359Sroberto */ 904182007Sroberto case AM_ERR: 905182007Sroberto return; 906132454Sroberto 907132454Sroberto /* 908182007Sroberto * For everything else there is the bit bucket. 909132454Sroberto */ 910182007Sroberto default: 911182007Sroberto return; 912182007Sroberto } 913182007Sroberto peer->flash &= ~PKT_TEST_MASK; 914132454Sroberto 915132454Sroberto /* 916182007Sroberto * Next comes a rigorous schedule of timestamp checking. If the 917182007Sroberto * transmit timestamp is zero, the server is horribly broken. 918132454Sroberto */ 919182007Sroberto if (L_ISZERO(&p_xmt)) { 920182007Sroberto return; /* read rfc1305 */ 921132454Sroberto 922132454Sroberto /* 923182007Sroberto * If the transmit timestamp duplicates a previous one, the 924182007Sroberto * packet is a replay. This prevents the bad guys from replaying 925182007Sroberto * the most recent packet, authenticated or not. 926132454Sroberto */ 927182007Sroberto } else if (L_ISEQU(&peer->org, &p_xmt)) { 928182007Sroberto peer->flash |= TEST1; 929182007Sroberto peer->oldpkt++; 930182007Sroberto return; /* duplicate packet */ 931182007Sroberto 932132454Sroberto 933132454Sroberto /* 934182007Sroberto * If this is a broadcast mode packet, skip further checking. 935132454Sroberto */ 936182007Sroberto } else if (hismode != MODE_BROADCAST) { 937182007Sroberto if (L_ISZERO(&p_org)) 938182007Sroberto peer->flash |= TEST3; /* protocol unsynch */ 939182007Sroberto else if (!L_ISEQU(&p_org, &peer->xmt)) 940182007Sroberto peer->flash |= TEST2; /* bogus packet */ 941182007Sroberto } 942132454Sroberto 943132454Sroberto /* 944182007Sroberto * Update the origin and destination timestamps. If 945182007Sroberto * unsynchronized or bogus abandon ship. If the crypto machine 946182007Sroberto * breaks, light the crypto bit and plaint the log. 947132454Sroberto */ 948182007Sroberto peer->org = p_xmt; 949182007Sroberto peer->rec = rbufp->recv_time; 950182007Sroberto if (peer->flash & PKT_TEST_MASK) { 951182007Sroberto#ifdef OPENSSL 952182007Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 953182007Sroberto rval = crypto_recv(peer, rbufp); 954182007Sroberto if (rval != XEVNT_OK) { 955182007Sroberto peer_clear(peer, "CRYP"); 956182007Sroberto peer->flash |= TEST9; /* crypto error */ 957182007Sroberto } 958182007Sroberto } 959182007Sroberto#endif /* OPENSSL */ 960182007Sroberto return; /* unsynch */ 961182007Sroberto } 962132454Sroberto 963132454Sroberto /* 964182007Sroberto * The timestamps are valid and the receive packet matches the 965182007Sroberto * last one sent. If the packet is a crypto-NAK, the server 966182007Sroberto * might have just changed keys. We reset the association 967182007Sroberto * and restart the protocol. 968132454Sroberto */ 969182007Sroberto if (is_authentic == AUTH_CRYPTO) { 970182007Sroberto peer_clear(peer, "AUTH"); 971182007Sroberto return; /* crypto-NAK */ 972182007Sroberto 973182007Sroberto /* 974182007Sroberto * If the association is authenticated, the key ID is nonzero 975182007Sroberto * and received packets must be authenticated. This is designed 976182007Sroberto * to avoid a bait-and-switch attack, which was possible in past 977182007Sroberto * versions. If symmetric modes, return a crypto-NAK. The peer 978182007Sroberto * should restart the protocol. 979182007Sroberto */ 980182007Sroberto } else if (!AUTH(peer->keyid || (restrict_mask & RES_DONTTRUST), 981182007Sroberto is_authentic)) { 982182007Sroberto peer->flash |= TEST5; 983182007Sroberto if (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE) 984132454Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask); 985182007Sroberto return; /* bad auth */ 98654359Sroberto } 98754359Sroberto 988182007Sroberto /* 989182007Sroberto * That was hard and I am sweaty, but the packet is squeaky 990182007Sroberto * clean. Get on with real work. 991182007Sroberto */ 992182007Sroberto peer->received++; 993182007Sroberto peer->timereceived = current_time; 994182007Sroberto if (is_authentic == AUTH_OK) 995182007Sroberto peer->flags |= FLAG_AUTHENTIC; 996182007Sroberto else 997182007Sroberto peer->flags &= ~FLAG_AUTHENTIC; 998132454Sroberto#ifdef OPENSSL 99954359Sroberto /* 100082505Sroberto * More autokey dance. The rules of the cha-cha are as follows: 100182505Sroberto * 100282505Sroberto * 1. If there is no key or the key is not auto, do nothing. 100382505Sroberto * 1004132454Sroberto * 2. If this packet is in response to the one just previously 1005132454Sroberto * sent or from a broadcast server, do the extension fields. 1006132454Sroberto * Otherwise, assume bogosity and bail out. 1007132454Sroberto * 1008132454Sroberto * 3. If an extension field contains a verified signature, it is 100982505Sroberto * self-authenticated and we sit the dance. 101082505Sroberto * 1011132454Sroberto * 4. If this is a server reply, check only to see that the 101282505Sroberto * transmitted key ID matches the received key ID. 101382505Sroberto * 1014132454Sroberto * 5. Check to see that one or more hashes of the current key ID 101582505Sroberto * matches the previous key ID or ultimate original key ID 101682505Sroberto * obtained from the broadcaster or symmetric peer. If no 101782505Sroberto * match, sit the dance and wait for timeout. 1018182007Sroberto * 1019182007Sroberto * In case of crypto error, fire the orchestra and stop dancing. 1020182007Sroberto * This is considered a permanant error, so light the crypto bit 1021182007Sroberto * to suppress further requests. If preemptable or ephemeral, 1022182007Sroberto * scuttle the ship. 102354359Sroberto */ 1024132454Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 1025182007Sroberto peer->flash |= TEST8; 1026132454Sroberto rval = crypto_recv(peer, rbufp); 1027132454Sroberto if (rval != XEVNT_OK) { 1028182007Sroberto peer_clear(peer, "CRYP"); 1029182007Sroberto peer->flash |= TEST9; /* crypto error */ 1030182007Sroberto if (peer->flags & FLAG_PREEMPT || 1031182007Sroberto !(peer->flags & FLAG_CONFIG)) 1032182007Sroberto unpeer(peer); 1033182007Sroberto return; 1034132454Sroberto 1035132454Sroberto } else if (hismode == MODE_SERVER) { 103682505Sroberto if (skeyid == peer->keyid) 1037182007Sroberto peer->flash &= ~TEST8; 1038182007Sroberto } else if (!(peer->flash & TEST8)) { 103982505Sroberto peer->pkeyid = skeyid; 1040132454Sroberto } else if ((ap = (struct autokey *)peer->recval.ptr) != 1041132454Sroberto NULL) { 104282505Sroberto int i; 104382505Sroberto 104482505Sroberto for (i = 0; ; i++) { 104582505Sroberto if (tkeyid == peer->pkeyid || 1046132454Sroberto tkeyid == ap->key) { 1047182007Sroberto peer->flash &= ~TEST8; 104882505Sroberto peer->pkeyid = skeyid; 104982505Sroberto break; 105082505Sroberto } 1051132454Sroberto if (i > ap->seq) 105282505Sroberto break; 105354359Sroberto tkeyid = session_key( 105482505Sroberto &rbufp->recv_srcadr, dstadr_sin, 105582505Sroberto tkeyid, pkeyid, 0); 105654359Sroberto } 105754359Sroberto } 1058182007Sroberto if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */ 1059182007Sroberto peer->flash |= TEST8; /* not proventic */ 106082505Sroberto 106182505Sroberto /* 1062132454Sroberto * If the transmit queue is nonempty, clamp the host 1063132454Sroberto * poll interval to the packet poll interval. 106482505Sroberto */ 1065132454Sroberto if (peer->cmmd != 0) { 1066132454Sroberto peer->ppoll = pkt->ppoll; 1067182007Sroberto poll_update(peer, peer->hpoll); 1068132454Sroberto } 106954359Sroberto } 1070132454Sroberto#endif /* OPENSSL */ 107154359Sroberto 107254359Sroberto /* 1073182007Sroberto * The dance is complete and the flash bits have been lit. Toss 1074182007Sroberto * the packet over the fence for processing, which may light up 1075182007Sroberto * more flashers. 107654359Sroberto */ 1077182007Sroberto process_packet(peer, pkt); 1078182007Sroberto 1079182007Sroberto /* 1080182007Sroberto * Well, that was nice. If TEST4 is lit, either the crypto 1081182007Sroberto * machine jammed or a kiss-o'-death packet flew in, either of 1082182007Sroberto * which is fatal. 1083182007Sroberto */ 1084182007Sroberto if (peer->flash & TEST4) { 1085182007Sroberto msyslog(LOG_INFO, "receive: fatal error %04x for %s", 1086182007Sroberto peer->flash, stoa(&peer->srcadr)); 1087182007Sroberto return; 1088182007Sroberto } 108954359Sroberto} 109054359Sroberto 109154359Sroberto 109254359Sroberto/* 109354359Sroberto * process_packet - Packet Procedure, a la Section 3.4.4 of the 109454359Sroberto * specification. Or almost, at least. If we're in here we have a 109554359Sroberto * reasonable expectation that we will be having a long term 109654359Sroberto * relationship with this host. 109754359Sroberto */ 109882505Srobertovoid 109954359Srobertoprocess_packet( 110054359Sroberto register struct peer *peer, 1101182007Sroberto register struct pkt *pkt 110254359Sroberto ) 110354359Sroberto{ 1104182007Sroberto double t34, t21; 1105132454Sroberto double p_offset, p_del, p_disp; 1106132454Sroberto l_fp p_rec, p_xmt, p_org, p_reftime; 1107132454Sroberto l_fp ci; 1108132454Sroberto u_char pmode, pleap, pstratum; 110954359Sroberto 111054359Sroberto sys_processed++; 111154359Sroberto peer->processed++; 111254359Sroberto p_del = FPTOD(NTOHS_FP(pkt->rootdelay)); 111354359Sroberto p_disp = FPTOD(NTOHS_FP(pkt->rootdispersion)); 111454359Sroberto NTOHL_FP(&pkt->reftime, &p_reftime); 111554359Sroberto NTOHL_FP(&pkt->rec, &p_rec); 111654359Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 1117132454Sroberto pmode = PKT_MODE(pkt->li_vn_mode); 1118132454Sroberto pleap = PKT_LEAP(pkt->li_vn_mode); 1119132454Sroberto if (pmode != MODE_BROADCAST) 112054359Sroberto NTOHL_FP(&pkt->org, &p_org); 112154359Sroberto else 112254359Sroberto p_org = peer->rec; 1123132454Sroberto pstratum = PKT_TO_STRATUM(pkt->stratum); 112454359Sroberto 112554359Sroberto /* 1126182007Sroberto * Test for kiss-o'death packet) 112754359Sroberto */ 1128182007Sroberto if (pleap == LEAP_NOTINSYNC && pstratum == STRATUM_UNSPEC) { 1129182007Sroberto if (memcmp(&pkt->refid, "DENY", 4) == 0) { 1130182007Sroberto peer_clear(peer, "DENY"); 1131182007Sroberto peer->flash |= TEST4; /* access denied */ 1132182007Sroberto } 1133182007Sroberto } 113454359Sroberto 113554359Sroberto /* 1136182007Sroberto * Capture the header values. 113754359Sroberto */ 1138182007Sroberto record_raw_stats(&peer->srcadr, peer->dstadr ? &peer->dstadr->sin : NULL, &p_org, 1139182007Sroberto &p_rec, &p_xmt, &peer->rec); 1140132454Sroberto peer->leap = pleap; 1141182007Sroberto peer->stratum = min(pstratum, STRATUM_UNSPEC); 1142182007Sroberto peer->pmode = pmode; 1143182007Sroberto peer->ppoll = pkt->ppoll; 1144182007Sroberto peer->precision = pkt->precision; 1145182007Sroberto peer->rootdelay = p_del; 1146182007Sroberto peer->rootdispersion = p_disp; 1147182007Sroberto peer->refid = pkt->refid; /* network byte order */ 1148182007Sroberto peer->reftime = p_reftime; 114982505Sroberto 115082505Sroberto /* 1151182007Sroberto * Verify the server is synchronized; that is, the leap bits and 1152182007Sroberto * stratum are valid, the root delay and root dispersion are 1153182007Sroberto * valid and the reference timestamp is not later than the 1154182007Sroberto * transmit timestamp. 115582505Sroberto */ 1156132454Sroberto if (pleap == LEAP_NOTINSYNC || /* test 6 */ 1157182007Sroberto pstratum < sys_floor || pstratum >= sys_ceiling) 1158182007Sroberto peer->flash |= TEST6; /* peer not synch */ 1159182007Sroberto if (p_del < 0 || p_disp < 0 || p_del / /* test 7 */ 1160182007Sroberto 2 + p_disp >= MAXDISPERSE || !L_ISHIS(&p_xmt, &p_reftime)) 1161182007Sroberto peer->flash |= TEST7; /* bad header */ 1162132454Sroberto 1163132454Sroberto /* 1164132454Sroberto * If any tests fail at this point, the packet is discarded. 1165182007Sroberto * Note that some flashers may have already been set in the 1166182007Sroberto * receive() routine. 1167132454Sroberto */ 1168182007Sroberto if (peer->flash & PKT_TEST_MASK) { 116954359Sroberto#ifdef DEBUG 117054359Sroberto if (debug) 1171182007Sroberto printf("packet: flash header %04x\n", 117282505Sroberto peer->flash); 117354359Sroberto#endif 117482505Sroberto return; 117554359Sroberto } 117682505Sroberto if (!(peer->reach)) { 117754359Sroberto report_event(EVNT_REACH, peer); 117854359Sroberto peer->timereachable = current_time; 117954359Sroberto } 1180182007Sroberto poll_update(peer, peer->hpoll); 118154359Sroberto peer->reach |= 1; 118254359Sroberto 118354359Sroberto /* 1184182007Sroberto * For a client/server association, calculate the clock offset, 1185182007Sroberto * roundtrip delay and dispersion. The equations are reordered 1186182007Sroberto * from the spec for more efficient use of temporaries. For a 1187182007Sroberto * broadcast association, offset the last measurement by the 1188182007Sroberto * computed delay during the client/server volley. Note that 1189182007Sroberto * org has been set to the time of last reception. Note the 1190182007Sroberto * computation of dispersion includes the system precision plus 1191182007Sroberto * that due to the frequency error since the origin time. 119254359Sroberto * 1193182007Sroberto * It is very important to respect the hazards of overflow. The 1194182007Sroberto * only permitted operation on raw timestamps is subtraction, 1195182007Sroberto * where the result is a signed quantity spanning from 68 years 1196182007Sroberto * in the past to 68 years in the future. To avoid loss of 1197182007Sroberto * precision, these calculations are done using 64-bit integer 1198182007Sroberto * arithmetic. However, the offset and delay calculations are 1199182007Sroberto * sums and differences of these first-order differences, which 1200182007Sroberto * if done using 64-bit integer arithmetic, would be valid over 1201182007Sroberto * only half that span. Since the typical first-order 1202182007Sroberto * differences are usually very small, they are converted to 64- 1203182007Sroberto * bit doubles and all remaining calculations done in floating- 1204182007Sroberto * point arithmetic. This preserves the accuracy while retaining 1205182007Sroberto * the 68-year span. 1206182007Sroberto * 1207132454Sroberto * Let t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->rec: 120854359Sroberto */ 1209182007Sroberto ci = p_xmt; /* t3 - t4 */ 1210182007Sroberto L_SUB(&ci, &peer->rec); 1211182007Sroberto LFPTOD(&ci, t34); 1212182007Sroberto ci = p_rec; /* t2 - t1 */ 1213182007Sroberto L_SUB(&ci, &p_org); 1214182007Sroberto LFPTOD(&ci, t21); 1215132454Sroberto ci = peer->rec; /* t4 - t1 */ 1216132454Sroberto L_SUB(&ci, &p_org); 121754359Sroberto 121854359Sroberto /* 121956749Sroberto * If running in a broadcast association, the clock offset is 122056749Sroberto * (t1 - t0) corrected by the one-way delay, but we can't 122182505Sroberto * measure that directly. Therefore, we start up in MODE_CLIENT 122282505Sroberto * mode, set FLAG_MCAST and exchange eight messages to determine 122382505Sroberto * the clock offset. When the last message is sent, we switch to 122482505Sroberto * MODE_BCLIENT mode. The next broadcast message after that 122582505Sroberto * computes the broadcast offset and clears FLAG_MCAST. 122654359Sroberto */ 122754359Sroberto if (pmode == MODE_BROADCAST) { 1228182007Sroberto p_offset = t34; 122982505Sroberto if (peer->flags & FLAG_MCAST) { 123054359Sroberto peer->estbdelay = peer->offset - p_offset; 123182505Sroberto if (peer->hmode == MODE_CLIENT) 123282505Sroberto return; 123354359Sroberto 1234182007Sroberto peer->flags &= ~(FLAG_MCAST | FLAG_BURST); 123554359Sroberto } 1236182007Sroberto p_offset += peer->estbdelay; 123754359Sroberto p_del = peer->delay; 1238182007Sroberto p_disp = 0; 123954359Sroberto } else { 1240182007Sroberto p_offset = (t21 + t34) / 2.; 1241182007Sroberto p_del = t21 - t34; 1242182007Sroberto LFPTOD(&ci, p_disp); 1243182007Sroberto p_disp = LOGTOD(sys_precision) + 1244182007Sroberto LOGTOD(peer->precision) + clock_phi * p_disp; 124554359Sroberto } 124682505Sroberto p_del = max(p_del, LOGTOD(sys_precision)); 124782505Sroberto clock_filter(peer, p_offset, p_del, p_disp); 124854359Sroberto record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), 1249182007Sroberto peer->offset, peer->delay, peer->disp, peer->jitter); 125054359Sroberto} 125154359Sroberto 125254359Sroberto 125354359Sroberto/* 125454359Sroberto * clock_update - Called at system process update intervals. 125554359Sroberto */ 125654359Srobertostatic void 125754359Srobertoclock_update(void) 125854359Sroberto{ 1259182007Sroberto u_char oleap; 1260182007Sroberto u_char ostratum; 1261182007Sroberto double dtemp; 126254359Sroberto 126354359Sroberto /* 1264182007Sroberto * There must be a system peer at this point. If we just changed 1265182007Sroberto * the system peer, but have a newer sample from the old one, 1266182007Sroberto * wait until newer data are available. 126754359Sroberto */ 1268182007Sroberto if (sys_poll < sys_peer->minpoll) 1269182007Sroberto sys_poll = sys_peer->minpoll; 1270182007Sroberto if (sys_poll > sys_peer->maxpoll) 1271182007Sroberto sys_poll = sys_peer->maxpoll; 1272182007Sroberto poll_update(sys_peer, sys_poll); 1273182007Sroberto if (sys_peer->epoch <= sys_clocktime) 127454359Sroberto return; 1275182007Sroberto 127654359Sroberto#ifdef DEBUG 127754359Sroberto if (debug) 127854359Sroberto printf("clock_update: at %ld assoc %d \n", current_time, 127954359Sroberto peer_associations); 128054359Sroberto#endif 128154359Sroberto oleap = sys_leap; 128254359Sroberto ostratum = sys_stratum; 1283182007Sroberto switch (local_clock(sys_peer, sys_offset)) { 128454359Sroberto 128582505Sroberto /* 1286182007Sroberto * Clock exceeds panic threshold. Life as we know it ends. 128782505Sroberto */ 128882505Sroberto case -1: 1289132454Sroberto report_event(EVNT_SYSFAULT, NULL); 1290132454Sroberto exit (-1); 1291182007Sroberto /* not reached */ 129254359Sroberto 129382505Sroberto /* 129482505Sroberto * Clock was stepped. Flush all time values of all peers. 129582505Sroberto */ 1296182007Sroberto case 2: 129782505Sroberto clear_all(); 1298182007Sroberto sys_leap = LEAP_NOTINSYNC; 1299182007Sroberto sys_stratum = STRATUM_UNSPEC; 130082505Sroberto sys_peer = NULL; 1301182007Sroberto sys_rootdelay = 0; 1302182007Sroberto sys_rootdispersion = 0; 1303182007Sroberto memcpy(&sys_refid, "STEP", 4); 1304132454Sroberto report_event(EVNT_CLOCKRESET, NULL); 130554359Sroberto break; 130654359Sroberto 130782505Sroberto /* 1308182007Sroberto * Clock was slewed. Update the system stratum, leap bits, root 1309182007Sroberto * delay, root dispersion, reference ID and reference time. If 1310182007Sroberto * the leap changes, we gotta reroll the keys. Except for 1311182007Sroberto * reference clocks, the minimum dispersion increment is not 1312182007Sroberto * less than sys_mindisp. 131382505Sroberto */ 1314182007Sroberto case 1: 1315182007Sroberto sys_leap = leap_next; 1316182007Sroberto sys_stratum = min(sys_peer->stratum + 1, 1317182007Sroberto STRATUM_UNSPEC); 131854359Sroberto sys_reftime = sys_peer->rec; 1319182007Sroberto 1320182007Sroberto /* 1321182007Sroberto * In orphan mode the stratum defaults to the orphan 1322182007Sroberto * stratum. The root delay is set to a random value 1323182007Sroberto * generated at startup. The root dispersion is set from 1324182007Sroberto * the peer dispersion; the peer root dispersion is 1325182007Sroberto * ignored. 1326182007Sroberto */ 1327182007Sroberto dtemp = sys_peer->disp + clock_phi * (current_time - 1328182007Sroberto sys_peer->update) + sys_jitter + 1329182007Sroberto fabs(sys_peer->offset); 1330182007Sroberto#ifdef REFCLOCK 1331182007Sroberto if (!(sys_peer->flags & FLAG_REFCLOCK) && dtemp < 1332182007Sroberto sys_mindisp) 1333182007Sroberto dtemp = sys_mindisp; 1334182007Sroberto#else 1335182007Sroberto if (dtemp < sys_mindisp) 1336182007Sroberto dtemp = sys_mindisp; 1337182007Sroberto#endif /* REFCLOCK */ 1338182007Sroberto if (sys_stratum >= sys_orphan) { 1339182007Sroberto sys_stratum = sys_orphan; 1340182007Sroberto sys_rootdelay = sys_peer->delay; 1341182007Sroberto sys_rootdispersion = dtemp; 1342182007Sroberto } else { 1343182007Sroberto sys_rootdelay = sys_peer->delay + 1344182007Sroberto sys_peer->rootdelay; 1345182007Sroberto sys_rootdispersion = dtemp + 1346182007Sroberto sys_peer->rootdispersion; 1347182007Sroberto } 1348132454Sroberto if (oleap == LEAP_NOTINSYNC) { 1349132454Sroberto report_event(EVNT_SYNCCHG, NULL); 1350132454Sroberto#ifdef OPENSSL 1351132454Sroberto expire_all(); 1352182007Sroberto crypto_update(); 1353132454Sroberto#endif /* OPENSSL */ 1354132454Sroberto } 1355182007Sroberto break; 1356182007Sroberto /* 1357182007Sroberto * Popcorn spike or step threshold exceeded. Pretend it never 1358182007Sroberto * happened. 1359182007Sroberto */ 1360182007Sroberto default: 1361182007Sroberto break; 136254359Sroberto } 136354359Sroberto if (ostratum != sys_stratum) 1364132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 136554359Sroberto} 136654359Sroberto 136754359Sroberto 136854359Sroberto/* 136982505Sroberto * poll_update - update peer poll interval 137054359Sroberto */ 137154359Srobertovoid 137254359Srobertopoll_update( 137354359Sroberto struct peer *peer, 1374182007Sroberto int mpoll 137554359Sroberto ) 137654359Sroberto{ 1377182007Sroberto int hpoll; 137854359Sroberto 137954359Sroberto /* 1380182007Sroberto * This routine figures out when the next poll should be sent. 1381182007Sroberto * That turns out to be wickedly complicated. The big problem is 1382182007Sroberto * that sometimes the time for the next poll is in the past. 1383182007Sroberto * Watch out for races here between the receive process and the 1384182007Sroberto * poll process. The key assertion is that, if nextdate equals 1385182007Sroberto * current_time, the call is from the poll process; otherwise, 1386182007Sroberto * it is from the receive process. 1387182007Sroberto * 1388182007Sroberto * First, bracket the poll interval according to the type of 1389182007Sroberto * association and options. If a fixed interval is configured, 1390182007Sroberto * use minpoll. This primarily is for reference clocks, but 1391182007Sroberto * works for any association. 139254359Sroberto */ 1393182007Sroberto if (peer->flags & FLAG_FIXPOLL) { 1394182007Sroberto hpoll = peer->minpoll; 1395182007Sroberto 1396182007Sroberto /* 1397182007Sroberto * The ordinary case; clamp the poll interval between minpoll 1398182007Sroberto * and maxpoll. 1399182007Sroberto */ 1400182007Sroberto } else { 1401182007Sroberto hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll); 1402182007Sroberto } 1403132454Sroberto#ifdef OPENSSL 1404182007Sroberto /* 1405182007Sroberto * Bit of crass arrogance at this point. If the poll interval 1406182007Sroberto * has changed and we have a keylist, the lifetimes in the 1407182007Sroberto * keylist are probably bogus. In this case purge the keylist 1408182007Sroberto * and regenerate it later. 1409182007Sroberto */ 1410182007Sroberto if (hpoll != peer->hpoll) 1411182007Sroberto key_expire(peer); 1412132454Sroberto#endif /* OPENSSL */ 1413182007Sroberto peer->hpoll = hpoll; 141482505Sroberto 141582505Sroberto /* 1416182007Sroberto * Now we figure out if there is an override. If during the 1417182007Sroberto * crypto protocol and a message is pending, make it wait not 1418182007Sroberto * more than two seconds. 141982505Sroberto */ 1420132454Sroberto#ifdef OPENSSL 1421132454Sroberto if (peer->cmmd != NULL && (sys_leap != LEAP_NOTINSYNC || 1422132454Sroberto peer->crypto)) { 1423132454Sroberto peer->nextdate = current_time + RESP_DELAY; 1424182007Sroberto 1425182007Sroberto /* 1426182007Sroberto * If we get called from the receive routine while a burst is 1427182007Sroberto * pending, just slink away. If from the poll routine and a 1428182007Sroberto * reference clock or a pending crypto response, delay for one 1429182007Sroberto * second. If this is the first sent in a burst, wait for the 1430182007Sroberto * modem to come up. For others in the burst, delay two seconds. 1431182007Sroberto */ 1432132454Sroberto } else if (peer->burst > 0) { 1433132454Sroberto#else /* OPENSSL */ 143454359Sroberto if (peer->burst > 0) { 1435132454Sroberto#endif /* OPENSSL */ 1436182007Sroberto if (peer->nextdate != current_time) 143754359Sroberto return; 143882505Sroberto#ifdef REFCLOCK 143982505Sroberto else if (peer->flags & FLAG_REFCLOCK) 1440132454Sroberto peer->nextdate += RESP_DELAY; 1441182007Sroberto#endif /* REFCLOCK */ 1442132454Sroberto else if (peer->flags & (FLAG_IBURST | FLAG_BURST) && 1443132454Sroberto peer->burst == NTP_BURST) 1444132454Sroberto peer->nextdate += sys_calldelay; 144554359Sroberto else 1446132454Sroberto peer->nextdate += BURST_DELAY; 1447182007Sroberto /* 1448182007Sroberto * The ordinary case; use the minimum of the host and peer 1449182007Sroberto * intervals, but not less than minpoll. In other words, 1450182007Sroberto * oversampling is okay but understampling is evil. 1451182007Sroberto */ 145254359Sroberto } else { 1453182007Sroberto peer->nextdate = peer->outdate + 1454182007Sroberto RANDPOLL(max(min(peer->ppoll, hpoll), 1455182007Sroberto peer->minpoll)); 145654359Sroberto } 1457182007Sroberto 145882505Sroberto /* 1459182007Sroberto * If the time for the next poll has already happened, bring it 1460182007Sroberto * up to the next second after this one. This way the only way 1461182007Sroberto * to get nexdate == current time is from the poll routine. 146282505Sroberto */ 1463182007Sroberto if (peer->nextdate <= current_time) 1464182007Sroberto peer->nextdate = current_time + 1; 146554359Sroberto#ifdef DEBUG 146654359Sroberto if (debug > 1) 146782505Sroberto printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n", 146882505Sroberto current_time, ntoa(&peer->srcadr), peer->flags, 1469182007Sroberto peer->hpoll, peer->burst, peer->outdate, 147082505Sroberto peer->nextdate); 147154359Sroberto#endif 147254359Sroberto} 147354359Sroberto 147454359Sroberto/* 1475182007Sroberto * peer_crypto_clear - discard crypto information 147654359Sroberto */ 147754359Srobertovoid 1478182007Srobertopeer_crypto_clear( 1479182007Sroberto struct peer *peer 1480182007Sroberto ) 148154359Sroberto{ 148282505Sroberto /* 148382505Sroberto * If cryptographic credentials have been acquired, toss them to 148482505Sroberto * Valhalla. Note that autokeys are ephemeral, in that they are 148582505Sroberto * tossed immediately upon use. Therefore, the keylist can be 148682505Sroberto * purged anytime without needing to preserve random keys. Note 148782505Sroberto * that, if the peer is purged, the cryptographic variables are 148882505Sroberto * purged, too. This makes it much harder to sneak in some 148982505Sroberto * unauthenticated data in the clock filter. 149082505Sroberto */ 1491182007Sroberto DPRINTF(1, ("peer_crypto_clear: at %ld next %ld assoc ID %d\n", 1492182007Sroberto current_time, peer->nextdate, peer->associd)); 1493182007Sroberto 1494132454Sroberto#ifdef OPENSSL 1495182007Sroberto peer->assoc = 0; 1496182007Sroberto peer->crypto = 0; 1497182007Sroberto 1498132454Sroberto if (peer->pkey != NULL) 1499132454Sroberto EVP_PKEY_free(peer->pkey); 1500182007Sroberto peer->pkey = NULL; 1501182007Sroberto 1502182007Sroberto peer->digest = NULL; /* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */ 1503182007Sroberto 1504132454Sroberto if (peer->subject != NULL) 1505132454Sroberto free(peer->subject); 1506182007Sroberto peer->subject = NULL; 1507182007Sroberto 1508132454Sroberto if (peer->issuer != NULL) 1509132454Sroberto free(peer->issuer); 1510182007Sroberto peer->issuer = NULL; 1511182007Sroberto 1512182007Sroberto peer->pkeyid = 0; 1513182007Sroberto 1514182007Sroberto peer->pcookie = 0; 1515182007Sroberto 1516182007Sroberto if (peer->ident_pkey != NULL) 1517182007Sroberto EVP_PKEY_free(peer->ident_pkey); 1518182007Sroberto peer->ident_pkey = NULL; 1519182007Sroberto 1520182007Sroberto memset(&peer->fstamp, 0, sizeof(peer->fstamp)); 1521182007Sroberto 1522132454Sroberto if (peer->iffval != NULL) 1523132454Sroberto BN_free(peer->iffval); 1524182007Sroberto peer->iffval = NULL; 1525182007Sroberto 1526132454Sroberto if (peer->grpkey != NULL) 1527132454Sroberto BN_free(peer->grpkey); 1528182007Sroberto peer->grpkey = NULL; 1529182007Sroberto 1530132454Sroberto value_free(&peer->cookval); 1531132454Sroberto value_free(&peer->recval); 1532182007Sroberto 1533182007Sroberto if (peer->cmmd != NULL) { 1534182007Sroberto free(peer->cmmd); 1535182007Sroberto peer->cmmd = NULL; 1536182007Sroberto } 1537182007Sroberto 1538182007Sroberto key_expire(peer); 1539182007Sroberto 1540132454Sroberto value_free(&peer->encrypt); 1541132454Sroberto#endif /* OPENSSL */ 1542182007Sroberto} 154382505Sroberto 1544182007Sroberto/* 1545182007Sroberto * peer_clear - clear peer filter registers. See Section 3.4.8 of the spec. 1546182007Sroberto */ 1547182007Srobertovoid 1548182007Srobertopeer_clear( 1549182007Sroberto struct peer *peer, /* peer structure */ 1550182007Sroberto char *ident /* tally lights */ 1551182007Sroberto ) 1552182007Sroberto{ 1553182007Sroberto int i; 1554182007Sroberto 1555182007Sroberto peer_crypto_clear(peer); 1556182007Sroberto 1557182007Sroberto if (peer == sys_peer) 1558182007Sroberto sys_peer = NULL; 1559182007Sroberto 156082505Sroberto /* 1561132454Sroberto * Wipe the association clean and initialize the nonzero values. 156282505Sroberto */ 1563132454Sroberto memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO); 156454359Sroberto peer->estbdelay = sys_bdelay; 156582505Sroberto peer->ppoll = peer->maxpoll; 1566182007Sroberto peer->hpoll = peer->minpoll; 1567182007Sroberto peer->disp = MAXDISPERSE; 1568182007Sroberto peer->jitter = LOGTOD(sys_precision); 1569182007Sroberto for (i = 0; i < NTP_SHIFT; i++) { 1570182007Sroberto peer->filter_order[i] = i; 1571182007Sroberto peer->filter_disp[i] = MAXDISPERSE; 1572182007Sroberto } 157382505Sroberto#ifdef REFCLOCK 157482505Sroberto if (!(peer->flags & FLAG_REFCLOCK)) { 157582505Sroberto peer->leap = LEAP_NOTINSYNC; 157682505Sroberto peer->stratum = STRATUM_UNSPEC; 1577132454Sroberto memcpy(&peer->refid, ident, 4); 157882505Sroberto } 1579132454Sroberto#else 1580132454Sroberto peer->leap = LEAP_NOTINSYNC; 1581132454Sroberto peer->stratum = STRATUM_UNSPEC; 1582132454Sroberto memcpy(&peer->refid, ident, 4); 1583182007Sroberto#endif /* REFCLOCK */ 158454359Sroberto 158554359Sroberto /* 1586182007Sroberto * During initialization use the association count to spread out 1587182007Sroberto * the polls at one-second intervals. Othersie, randomize over 1588182007Sroberto * the minimum poll interval in order to avoid broadcast 1589182007Sroberto * implosion. 159054359Sroberto */ 1591132454Sroberto peer->nextdate = peer->update = peer->outdate = current_time; 1592182007Sroberto if (initializing) 1593182007Sroberto peer->nextdate += peer_associations; 1594182007Sroberto else if (peer->hmode == MODE_PASSIVE) 1595182007Sroberto peer->nextdate += RESP_DELAY; 1596132454Sroberto else 1597182007Sroberto peer->nextdate += (ntp_random() & ((1 << NTP_MINDPOLL) - 1598182007Sroberto 1)); 1599182007Sroberto 1600182007Sroberto DPRINTF(1, ("peer_clear: at %ld next %ld assoc ID %d refid %s\n", 1601182007Sroberto current_time, peer->nextdate, peer->associd, ident)); 160254359Sroberto} 160354359Sroberto 160454359Sroberto 160554359Sroberto/* 160654359Sroberto * clock_filter - add incoming clock sample to filter register and run 160754359Sroberto * the filter procedure to find the best sample. 160854359Sroberto */ 160954359Srobertovoid 161054359Srobertoclock_filter( 1611132454Sroberto struct peer *peer, /* peer structure pointer */ 1612132454Sroberto double sample_offset, /* clock offset */ 1613132454Sroberto double sample_delay, /* roundtrip delay */ 1614132454Sroberto double sample_disp /* dispersion */ 161554359Sroberto ) 161654359Sroberto{ 1617132454Sroberto double dst[NTP_SHIFT]; /* distance vector */ 1618132454Sroberto int ord[NTP_SHIFT]; /* index vector */ 1619132454Sroberto int i, j, k, m; 1620182007Sroberto double dtemp, etemp; 162154359Sroberto 162254359Sroberto /* 162382505Sroberto * Shift the new sample into the register and discard the oldest 162482505Sroberto * one. The new offset and delay come directly from the 162582505Sroberto * timestamp calculations. The dispersion grows from the last 162682505Sroberto * outbound packet or reference clock update to the present time 162782505Sroberto * and increased by the sum of the peer precision and the system 162882505Sroberto * precision. The delay can sometimes swing negative due to 162982505Sroberto * frequency skew, so it is clamped non-negative. 163054359Sroberto */ 163154359Sroberto j = peer->filter_nextpt; 163282505Sroberto peer->filter_offset[j] = sample_offset; 163382505Sroberto peer->filter_delay[j] = max(0, sample_delay); 1634182007Sroberto peer->filter_disp[j] = sample_disp; 1635182007Sroberto peer->filter_epoch[j] = current_time; 1636182007Sroberto j = (j + 1) % NTP_SHIFT; 1637182007Sroberto peer->filter_nextpt = j; 163854359Sroberto 163954359Sroberto /* 164082505Sroberto * Update dispersions since the last update and at the same 164182505Sroberto * time initialize the distance and index lists. The distance 164282505Sroberto * list uses a compound metric. If the sample is valid and 164382505Sroberto * younger than the minimum Allan intercept, use delay; 164482505Sroberto * otherwise, use biased dispersion. 164554359Sroberto */ 164682505Sroberto dtemp = clock_phi * (current_time - peer->update); 164782505Sroberto peer->update = current_time; 164882505Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 1649132454Sroberto if (i != 0) 165082505Sroberto peer->filter_disp[j] += dtemp; 1651132454Sroberto if (peer->filter_disp[j] >= MAXDISPERSE) 1652132454Sroberto peer->filter_disp[j] = MAXDISPERSE; 165382505Sroberto if (peer->filter_disp[j] >= MAXDISPERSE) 165482505Sroberto dst[i] = MAXDISPERSE; 165582505Sroberto else if (peer->update - peer->filter_epoch[j] > 165682505Sroberto allan_xpt) 1657182007Sroberto dst[i] = sys_maxdist + peer->filter_disp[j]; 165882505Sroberto else 1659132454Sroberto dst[i] = peer->filter_delay[j]; 166082505Sroberto ord[i] = j; 166182505Sroberto j++; j %= NTP_SHIFT; 166282505Sroberto } 166354359Sroberto 166482505Sroberto /* 1665182007Sroberto * If the clock discipline has stabilized, sort the samples in 1666182007Sroberto * both lists by distance. Note, we do not displace a higher 1667182007Sroberto * distance sample by a lower distance one unless lower by at 1668182007Sroberto * least the precision. 166954359Sroberto */ 1670182007Sroberto if (state == 4) { 1671182007Sroberto for (i = 1; i < NTP_SHIFT; i++) { 1672182007Sroberto for (j = 0; j < i; j++) { 1673182007Sroberto if (dst[j] > dst[i] + 1674182007Sroberto LOGTOD(sys_precision)) { 1675182007Sroberto k = ord[j]; 1676182007Sroberto ord[j] = ord[i]; 1677182007Sroberto ord[i] = k; 1678182007Sroberto etemp = dst[j]; 1679182007Sroberto dst[j] = dst[i]; 1680182007Sroberto dst[i] = etemp; 1681182007Sroberto } 168254359Sroberto } 168354359Sroberto } 168482505Sroberto } 168582505Sroberto 168682505Sroberto /* 168782505Sroberto * Copy the index list to the association structure so ntpq 168882505Sroberto * can see it later. Prune the distance list to samples less 1689182007Sroberto * than max distance, but keep at least two valid samples for 169082505Sroberto * jitter calculation. 169182505Sroberto */ 169282505Sroberto m = 0; 169382505Sroberto for (i = 0; i < NTP_SHIFT; i++) { 1694132454Sroberto peer->filter_order[i] = (u_char) ord[i]; 169582505Sroberto if (dst[i] >= MAXDISPERSE || (m >= 2 && dst[i] >= 1696182007Sroberto sys_maxdist)) 169782505Sroberto continue; 169882505Sroberto m++; 169982505Sroberto } 170054359Sroberto 170154359Sroberto /* 1702182007Sroberto * Compute the dispersion and jitter. The dispersion is weighted 1703182007Sroberto * exponentially by NTP_FWEIGHT (0.5) so it is normalized close 1704182007Sroberto * to 1.0. The jitter is the RMS differences relative to the 1705182007Sroberto * lowest delay sample. If no acceptable samples remain in the 1706182007Sroberto * shift register, quietly tiptoe home leaving only the 1707182007Sroberto * dispersion. 170854359Sroberto */ 1709182007Sroberto peer->disp = peer->jitter = 0; 171082505Sroberto k = ord[0]; 171154359Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 171282505Sroberto j = ord[i]; 171382505Sroberto peer->disp = NTP_FWEIGHT * (peer->disp + 171482505Sroberto peer->filter_disp[j]); 171582505Sroberto if (i < m) 1716182007Sroberto peer->jitter += DIFF(peer->filter_offset[j], 171782505Sroberto peer->filter_offset[k]); 171854359Sroberto } 171954359Sroberto 172054359Sroberto /* 172182505Sroberto * If no acceptable samples remain in the shift register, 172282505Sroberto * quietly tiptoe home leaving only the dispersion. Otherwise, 1723182007Sroberto * save the offset, delay and jitter. Note the jitter must not 1724182007Sroberto * be less than the precision. 172582505Sroberto */ 172682505Sroberto if (m == 0) 172782505Sroberto return; 1728182007Sroberto 1729132454Sroberto etemp = fabs(peer->offset - peer->filter_offset[k]); 173082505Sroberto peer->offset = peer->filter_offset[k]; 173182505Sroberto peer->delay = peer->filter_delay[k]; 173282505Sroberto if (m > 1) 1733182007Sroberto peer->jitter /= m - 1; 1734182007Sroberto peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision)); 173582505Sroberto 173682505Sroberto /* 173754359Sroberto * A new sample is useful only if it is younger than the last 1738182007Sroberto * one used. Note the order is FIFO if the clock discipline has 1739182007Sroberto * not stabilized. 174054359Sroberto */ 1741182007Sroberto if (peer->filter_epoch[k] <= peer->epoch) { 174254359Sroberto#ifdef DEBUG 174354359Sroberto if (debug) 174454359Sroberto printf("clock_filter: discard %lu\n", 174582505Sroberto peer->epoch - peer->filter_epoch[k]); 174654359Sroberto#endif 174754359Sroberto return; 174854359Sroberto } 174954359Sroberto 175054359Sroberto /* 175182505Sroberto * If the difference between the last offset and the current one 1752132454Sroberto * exceeds the jitter by CLOCK_SGATE and the interval since the 1753132454Sroberto * last update is less than twice the system poll interval, 175482505Sroberto * consider the update a popcorn spike and ignore it. 175554359Sroberto */ 1756182007Sroberto if (etemp > CLOCK_SGATE * peer->jitter && m > 1 && 1757182007Sroberto peer->filter_epoch[k] - peer->epoch < 2. * 1758182007Sroberto ULOGTOD(sys_poll)) { 175954359Sroberto#ifdef DEBUG 176054359Sroberto if (debug) 1761132454Sroberto printf("clock_filter: popcorn %.6f %.6f\n", 1762132454Sroberto etemp, dtemp); 176354359Sroberto#endif 176454359Sroberto return; 176554359Sroberto } 176682505Sroberto 176782505Sroberto /* 176882505Sroberto * The mitigated sample statistics are saved for later 1769182007Sroberto * processing. If not in a burst, tickle the select. 177082505Sroberto */ 177182505Sroberto peer->epoch = peer->filter_epoch[k]; 177254359Sroberto#ifdef DEBUG 177354359Sroberto if (debug) 177454359Sroberto printf( 177582505Sroberto "clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f, age %lu\n", 177682505Sroberto m, peer->offset, peer->delay, peer->disp, 1777182007Sroberto peer->jitter, current_time - peer->epoch); 177854359Sroberto#endif 1779182007Sroberto if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) 1780182007Sroberto clock_select(); 178154359Sroberto} 178254359Sroberto 178354359Sroberto 178454359Sroberto/* 178554359Sroberto * clock_select - find the pick-of-the-litter clock 1786132454Sroberto * 1787132454Sroberto * LOCKCLOCK: If the local clock is the prefer peer, it will always be 1788132454Sroberto * enabled, even if declared falseticker, (2) only the prefer peer can 1789132454Sroberto * be selected as the system peer, (3) if the external source is down, 1790132454Sroberto * the system leap bits are set to 11 and the stratum set to infinity. 179154359Sroberto */ 179254359Srobertovoid 179354359Srobertoclock_select(void) 179454359Sroberto{ 1795132454Sroberto struct peer *peer; 1796132454Sroberto int i, j, k, n; 1797132454Sroberto int nlist, nl3; 1798132454Sroberto 1799182007Sroberto int allow, osurv; 1800182007Sroberto double d, e, f, g; 1801132454Sroberto double high, low; 1802182007Sroberto double synch[NTP_MAXASSOC], error[NTP_MAXASSOC]; 180354359Sroberto struct peer *osys_peer; 180482505Sroberto struct peer *typeacts = NULL; 180582505Sroberto struct peer *typelocal = NULL; 180682505Sroberto struct peer *typesystem = NULL; 180754359Sroberto 180854359Sroberto static int list_alloc = 0; 180954359Sroberto static struct endpoint *endpoint = NULL; 181082505Sroberto static int *indx = NULL; 181154359Sroberto static struct peer **peer_list = NULL; 181254359Sroberto static u_int endpoint_size = 0; 181382505Sroberto static u_int indx_size = 0; 181454359Sroberto static u_int peer_list_size = 0; 181554359Sroberto 181654359Sroberto /* 181782505Sroberto * Initialize and create endpoint, index and peer lists big 181882505Sroberto * enough to handle all associations. 181954359Sroberto */ 182082505Sroberto osys_peer = sys_peer; 182182505Sroberto sys_peer = NULL; 1822182007Sroberto sys_pps = NULL; 1823182007Sroberto sys_prefer = NULL; 1824132454Sroberto osurv = sys_survivors; 1825132454Sroberto sys_survivors = 0; 1826132454Sroberto#ifdef LOCKCLOCK 1827132454Sroberto sys_leap = LEAP_NOTINSYNC; 1828132454Sroberto sys_stratum = STRATUM_UNSPEC; 1829132454Sroberto memcpy(&sys_refid, "DOWN", 4); 1830132454Sroberto#endif /* LOCKCLOCK */ 1831132454Sroberto nlist = 0; 1832182007Sroberto for (n = 0; n < NTP_HASH_SIZE; n++) 183354359Sroberto nlist += peer_hash_count[n]; 183454359Sroberto if (nlist > list_alloc) { 183554359Sroberto if (list_alloc > 0) { 183654359Sroberto free(endpoint); 183782505Sroberto free(indx); 183854359Sroberto free(peer_list); 183954359Sroberto } 184054359Sroberto while (list_alloc < nlist) { 184154359Sroberto list_alloc += 5; 184282505Sroberto endpoint_size += 5 * 3 * sizeof(*endpoint); 184382505Sroberto indx_size += 5 * 3 * sizeof(*indx); 184482505Sroberto peer_list_size += 5 * sizeof(*peer_list); 184554359Sroberto } 1846182007Sroberto endpoint = (struct endpoint *)emalloc(endpoint_size); 1847182007Sroberto indx = (int *)emalloc(indx_size); 1848182007Sroberto peer_list = (struct peer **)emalloc(peer_list_size); 184954359Sroberto } 185054359Sroberto 185154359Sroberto /* 185282505Sroberto * Initially, we populate the island with all the rifraff peers 185382505Sroberto * that happen to be lying around. Those with seriously 185482505Sroberto * defective clocks are immediately booted off the island. Then, 185582505Sroberto * the falsetickers are culled and put to sea. The truechimers 185682505Sroberto * remaining are subject to repeated rounds where the most 185782505Sroberto * unpopular at each round is kicked off. When the population 1858132454Sroberto * has dwindled to sys_minclock, the survivors split a million 1859132454Sroberto * bucks and collectively crank the chimes. 186054359Sroberto */ 186154359Sroberto nlist = nl3 = 0; /* none yet */ 1862182007Sroberto for (n = 0; n < NTP_HASH_SIZE; n++) { 186382505Sroberto for (peer = peer_hash[n]; peer != NULL; peer = 186482505Sroberto peer->next) { 186554359Sroberto peer->flags &= ~FLAG_SYSPEER; 186654359Sroberto peer->status = CTL_PST_SEL_REJECT; 186754359Sroberto 186854359Sroberto /* 1869132454Sroberto * Leave the island immediately if the peer is 1870132454Sroberto * unfit to synchronize. 1871132454Sroberto */ 1872132454Sroberto if (peer_unfit(peer)) 187382505Sroberto continue; 187482505Sroberto 187582505Sroberto /* 187682505Sroberto * Don't allow the local clock or modem drivers 187754359Sroberto * in the kitchen at this point, unless the 187854359Sroberto * prefer peer. Do that later, but only if 187982505Sroberto * nobody else is around. These guys are all 188082505Sroberto * configured, so we never throw them away. 188154359Sroberto */ 1882182007Sroberto#ifdef REFCLOCK 188354359Sroberto if (peer->refclktype == REFCLK_LOCALCLOCK 188454359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT) 1885132454Sroberto /* wjm: VMS_LOCALUNIT taken seriously */ 1886132454Sroberto && REFCLOCKUNIT(&peer->srcadr) != 1887132454Sroberto VMS_LOCALUNIT 188854359Sroberto#endif /* VMS && VMS_LOCALUNIT */ 188954359Sroberto ) { 189054359Sroberto typelocal = peer; 1891182007Sroberto#ifndef LOCKCLOCK 189254359Sroberto if (!(peer->flags & FLAG_PREFER)) 189354359Sroberto continue; /* no local clock */ 1894132454Sroberto#endif /* LOCKCLOCK */ 189554359Sroberto } 189654359Sroberto if (peer->sstclktype == CTL_SST_TS_TELEPHONE) { 189754359Sroberto typeacts = peer; 189854359Sroberto if (!(peer->flags & FLAG_PREFER)) 189954359Sroberto continue; /* no acts */ 190054359Sroberto } 1901182007Sroberto#endif /* REFCLOCK */ 190254359Sroberto 190354359Sroberto /* 190482505Sroberto * If we get this far, the peer can stay on the 190582505Sroberto * island, but does not yet have the immunity 190682505Sroberto * idol. 190754359Sroberto */ 190854359Sroberto peer->status = CTL_PST_SEL_SANE; 190954359Sroberto peer_list[nlist++] = peer; 191054359Sroberto 191154359Sroberto /* 191254359Sroberto * Insert each interval endpoint on the sorted 191354359Sroberto * list. 191454359Sroberto */ 191554359Sroberto e = peer->offset; /* Upper end */ 191654359Sroberto f = root_distance(peer); 191754359Sroberto e = e + f; 191854359Sroberto for (i = nl3 - 1; i >= 0; i--) { 191982505Sroberto if (e >= endpoint[indx[i]].val) 192054359Sroberto break; 1921182007Sroberto 192282505Sroberto indx[i + 3] = indx[i]; 192354359Sroberto } 192482505Sroberto indx[i + 3] = nl3; 192554359Sroberto endpoint[nl3].type = 1; 192654359Sroberto endpoint[nl3++].val = e; 192754359Sroberto 192854359Sroberto e = e - f; /* Center point */ 1929132454Sroberto for (; i >= 0; i--) { 193082505Sroberto if (e >= endpoint[indx[i]].val) 193154359Sroberto break; 1932182007Sroberto 193382505Sroberto indx[i + 2] = indx[i]; 193454359Sroberto } 193582505Sroberto indx[i + 2] = nl3; 193654359Sroberto endpoint[nl3].type = 0; 193754359Sroberto endpoint[nl3++].val = e; 193854359Sroberto 193954359Sroberto e = e - f; /* Lower end */ 1940132454Sroberto for (; i >= 0; i--) { 194182505Sroberto if (e >= endpoint[indx[i]].val) 194254359Sroberto break; 1943182007Sroberto 194482505Sroberto indx[i + 1] = indx[i]; 194554359Sroberto } 194682505Sroberto indx[i + 1] = nl3; 194754359Sroberto endpoint[nl3].type = -1; 194854359Sroberto endpoint[nl3++].val = e; 194954359Sroberto } 195054359Sroberto } 195154359Sroberto#ifdef DEBUG 195282505Sroberto if (debug > 2) 195354359Sroberto for (i = 0; i < nl3; i++) 195482505Sroberto printf("select: endpoint %2d %.6f\n", 195582505Sroberto endpoint[indx[i]].type, 195682505Sroberto endpoint[indx[i]].val); 195754359Sroberto#endif 1958132454Sroberto /* 1959132454Sroberto * This is the actual algorithm that cleaves the truechimers 1960132454Sroberto * from the falsetickers. The original algorithm was described 1961132454Sroberto * in Keith Marzullo's dissertation, but has been modified for 1962132454Sroberto * better accuracy. 1963132454Sroberto * 1964132454Sroberto * Briefly put, we first assume there are no falsetickers, then 1965132454Sroberto * scan the candidate list first from the low end upwards and 1966132454Sroberto * then from the high end downwards. The scans stop when the 1967132454Sroberto * number of intersections equals the number of candidates less 1968132454Sroberto * the number of falsetickers. If this doesn't happen for a 1969132454Sroberto * given number of falsetickers, we bump the number of 1970132454Sroberto * falsetickers and try again. If the number of falsetickers 1971132454Sroberto * becomes equal to or greater than half the number of 1972132454Sroberto * candidates, the Albanians have won the Byzantine wars and 1973132454Sroberto * correct synchronization is not possible. 1974132454Sroberto * 1975132454Sroberto * Here, nlist is the number of candidates and allow is the 1976182007Sroberto * number of falsetickers. Upon exit, the truechimers are the 1977182007Sroberto * susvivors with offsets not less than low and not greater than 1978182007Sroberto * high. There may be none of them. 1979132454Sroberto */ 1980132454Sroberto low = 1e9; 1981132454Sroberto high = -1e9; 1982132454Sroberto for (allow = 0; 2 * allow < nlist; allow++) { 1983132454Sroberto int found; 1984132454Sroberto 1985132454Sroberto /* 1986132454Sroberto * Bound the interval (low, high) as the largest 1987132454Sroberto * interval containing points from presumed truechimers. 1988132454Sroberto */ 1989132454Sroberto found = 0; 1990132454Sroberto n = 0; 1991132454Sroberto for (i = 0; i < nl3; i++) { 1992132454Sroberto low = endpoint[indx[i]].val; 1993132454Sroberto n -= endpoint[indx[i]].type; 1994132454Sroberto if (n >= nlist - allow) 199554359Sroberto break; 199682505Sroberto if (endpoint[indx[i]].type == 0) 199754359Sroberto found++; 199854359Sroberto } 1999132454Sroberto n = 0; 2000132454Sroberto for (j = nl3 - 1; j >= 0; j--) { 2001132454Sroberto high = endpoint[indx[j]].val; 200282505Sroberto n += endpoint[indx[j]].type; 2003132454Sroberto if (n >= nlist - allow) 200454359Sroberto break; 200582505Sroberto if (endpoint[indx[j]].type == 0) 200654359Sroberto found++; 200754359Sroberto } 2008132454Sroberto 2009132454Sroberto /* 2010132454Sroberto * If the number of candidates found outside the 2011132454Sroberto * interval is greater than the number of falsetickers, 2012132454Sroberto * then at least one truechimer is outside the interval, 2013132454Sroberto * so go around again. This is what makes this algorithm 2014132454Sroberto * different than Marzullo's. 2015132454Sroberto */ 201654359Sroberto if (found > allow) 2017132454Sroberto continue; 2018132454Sroberto 2019132454Sroberto /* 2020132454Sroberto * If an interval containing truechimers is found, stop. 2021132454Sroberto * If not, increase the number of falsetickers and go 2022132454Sroberto * around again. 2023132454Sroberto */ 2024132454Sroberto if (high > low) 202554359Sroberto break; 202654359Sroberto } 202754359Sroberto 202854359Sroberto /* 2029182007Sroberto * Clustering algorithm. Construct candidate list in order first 2030182007Sroberto * by stratum then by root distance, but keep only the best 2031182007Sroberto * NTP_MAXASSOC of them. Scan the list to find falsetickers, who 2032182007Sroberto * leave the island immediately. The TRUE peer is always a 2033182007Sroberto * truechimer. We must leave at least one peer to collect the 2034182007Sroberto * million bucks. If in orphan mode, rascals found with lower 2035182007Sroberto * stratum are guaranteed a seat on the bus. 2036182007Sroberto */ 2037182007Sroberto j = 0; 2038182007Sroberto for (i = 0; i < nlist; i++) { 2039182007Sroberto peer = peer_list[i]; 2040182007Sroberto if (nlist > 1 && (peer->offset <= low || peer->offset >= 2041182007Sroberto high) && !(peer->flags & FLAG_TRUE) && 2042182007Sroberto !(sys_stratum >= sys_orphan && peer->stratum < 2043182007Sroberto sys_orphan)) 2044182007Sroberto continue; 2045182007Sroberto 2046182007Sroberto peer->status = CTL_PST_SEL_DISTSYSPEER; 2047182007Sroberto 2048182007Sroberto /* 2049182007Sroberto * The order metric is formed from the stratum times 2050182007Sroberto * max distance (1.) plus the root distance. It strongly 2051182007Sroberto * favors the lowest stratum, but a higher stratum peer 2052182007Sroberto * can capture the clock if the low stratum dominant 2053182007Sroberto * hasn't been heard for awhile. 2054182007Sroberto */ 2055182007Sroberto d = root_distance(peer) + peer->stratum * sys_maxdist; 2056182007Sroberto if (j >= NTP_MAXASSOC) { 2057182007Sroberto if (d >= synch[j - 1]) 2058182007Sroberto continue; 2059182007Sroberto else 2060182007Sroberto j--; 2061182007Sroberto } 2062182007Sroberto for (k = j; k > 0; k--) { 2063182007Sroberto if (d >= synch[k - 1]) 2064182007Sroberto break; 2065182007Sroberto 2066182007Sroberto peer_list[k] = peer_list[k - 1]; 2067182007Sroberto error[k] = error[k - 1]; 2068182007Sroberto synch[k] = synch[k - 1]; 2069182007Sroberto } 2070182007Sroberto peer_list[k] = peer; 2071182007Sroberto error[k] = peer->jitter; 2072182007Sroberto synch[k] = d; 2073182007Sroberto j++; 2074182007Sroberto } 2075182007Sroberto nlist = j; 2076182007Sroberto 2077182007Sroberto /* 207882505Sroberto * If no survivors remain at this point, check if the local 207982505Sroberto * clock or modem drivers have been found. If so, nominate one 2080132454Sroberto * of them as the only survivor. Otherwise, give up and leave 2081132454Sroberto * the island to the rats. 208254359Sroberto */ 2083182007Sroberto if (nlist == 0) { 208454359Sroberto if (typeacts != 0) { 2085182007Sroberto typeacts->status = CTL_PST_SEL_DISTSYSPEER; 208654359Sroberto peer_list[0] = typeacts; 208754359Sroberto nlist = 1; 208854359Sroberto } else if (typelocal != 0) { 2089182007Sroberto typelocal->status = CTL_PST_SEL_DISTSYSPEER; 209054359Sroberto peer_list[0] = typelocal; 209154359Sroberto nlist = 1; 209254359Sroberto } else { 209382505Sroberto if (osys_peer != NULL) { 209482505Sroberto NLOG(NLOG_SYNCSTATUS) 209582505Sroberto msyslog(LOG_INFO, 2096132454Sroberto "no servers reachable"); 2097132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 209854359Sroberto } 209954359Sroberto } 210054359Sroberto } 210154359Sroberto 210254359Sroberto /* 2103132454Sroberto * We can only trust the survivors if the number of candidates 2104132454Sroberto * sys_minsane is at least the number required to detect and 2105132454Sroberto * cast out one falsticker. For the Byzantine agreement 2106132454Sroberto * algorithm used here, that number is 4; however, the default 2107132454Sroberto * sys_minsane is 1 to speed initial synchronization. Careful 2108182007Sroberto * operators will tinker a higher value and use at least that 2109132454Sroberto * number of synchronization sources. 2110132454Sroberto */ 2111132454Sroberto if (nlist < sys_minsane) 2112132454Sroberto return; 2113132454Sroberto 2114182007Sroberto for (i = 0; i < nlist; i++) 211582505Sroberto peer_list[i]->status = CTL_PST_SEL_SELCAND; 211654359Sroberto 211754359Sroberto /* 211882505Sroberto * Now, vote outlyers off the island by select jitter weighted 2119182007Sroberto * by root distance. Continue voting as long as there are more 2120182007Sroberto * than sys_minclock survivors and the minimum select jitter is 2121182007Sroberto * greater than the maximum peer jitter. Stop if we are about to 2122182007Sroberto * discard a TRUE or PREFER peer, who of course has the 2123182007Sroberto * immunity idol. 212454359Sroberto */ 212554359Sroberto while (1) { 212682505Sroberto d = 1e9; 212782505Sroberto e = -1e9; 2128182007Sroberto f = g = 0; 212982505Sroberto k = 0; 213082505Sroberto for (i = 0; i < nlist; i++) { 213182505Sroberto if (error[i] < d) 213282505Sroberto d = error[i]; 213382505Sroberto f = 0; 213482505Sroberto if (nlist > 1) { 213582505Sroberto for (j = 0; j < nlist; j++) 213682505Sroberto f += DIFF(peer_list[j]->offset, 213782505Sroberto peer_list[i]->offset); 2138182007Sroberto f = SQRT(f / (nlist - 1)); 213954359Sroberto } 214082505Sroberto if (f * synch[i] > e) { 2141182007Sroberto g = f; 214282505Sroberto e = f * synch[i]; 214354359Sroberto k = i; 214454359Sroberto } 214554359Sroberto } 2146182007Sroberto f = max(f, LOGTOD(sys_precision)); 2147132454Sroberto if (nlist <= sys_minclock || f <= d || 2148182007Sroberto peer_list[k]->flags & (FLAG_TRUE | FLAG_PREFER)) 2149132454Sroberto break; 215054359Sroberto#ifdef DEBUG 215182505Sroberto if (debug > 2) 215254359Sroberto printf( 2153132454Sroberto "select: drop %s select %.6f jitter %.6f\n", 2154182007Sroberto ntoa(&peer_list[k]->srcadr), g, d); 215554359Sroberto#endif 215654359Sroberto for (j = k + 1; j < nlist; j++) { 215754359Sroberto peer_list[j - 1] = peer_list[j]; 215854359Sroberto error[j - 1] = error[j]; 215954359Sroberto } 216054359Sroberto nlist--; 216154359Sroberto } 216282505Sroberto 216382505Sroberto /* 2164132454Sroberto * What remains is a list usually not greater than sys_minclock 216554359Sroberto * peers. We want only a peer at the lowest stratum to become 216654359Sroberto * the system peer, although all survivors are eligible for the 2167182007Sroberto * combining algorithm. Consider each peer in turn and OR the 2168182007Sroberto * leap bits on the assumption that, if some of them honk 2169182007Sroberto * nonzero bits, they must know what they are doing. Check for 2170182007Sroberto * prefer and pps peers at any stratum. Note that the head of 2171182007Sroberto * the list is at the lowest stratum and that unsynchronized 2172182007Sroberto * peers cannot survive this far. 217354359Sroberto */ 2174182007Sroberto leap_next = 0; 2175182007Sroberto for (i = 0; i < nlist; i++) { 217682505Sroberto peer = peer_list[i]; 2177182007Sroberto sys_survivors++; 2178182007Sroberto leap_next |= peer->leap; 217982505Sroberto peer->status = CTL_PST_SEL_SYNCCAND; 2180132454Sroberto if (peer->flags & FLAG_PREFER) 2181132454Sroberto sys_prefer = peer; 2182182007Sroberto if (peer == osys_peer) 2183132454Sroberto typesystem = peer; 2184182007Sroberto#ifdef REFCLOCK 2185182007Sroberto if (peer->refclktype == REFCLK_ATOM_PPS) 2186182007Sroberto sys_pps = peer; 2187182007Sroberto#endif /* REFCLOCK */ 2188182007Sroberto#if DEBUG 2189182007Sroberto if (debug > 1) 2190182007Sroberto printf("cluster: survivor %s metric %.6f\n", 2191182007Sroberto ntoa(&peer_list[i]->srcadr), synch[i]); 2192182007Sroberto#endif 219354359Sroberto } 219454359Sroberto 219554359Sroberto /* 2196182007Sroberto * Anticlockhop provision. Keep the current system peer if it is 2197182007Sroberto * a survivor but not first in the list. But do that only HOPPER 2198182007Sroberto * times. 2199132454Sroberto */ 2200182007Sroberto if (osys_peer == NULL || typesystem == NULL || typesystem == 2201182007Sroberto peer_list[0] || sys_hopper > sys_maxhop) { 2202182007Sroberto typesystem = peer_list[0]; 2203182007Sroberto sys_hopper = 0; 2204182007Sroberto } else { 2205182007Sroberto peer->selbroken++; 2206182007Sroberto } 2207132454Sroberto 2208132454Sroberto /* 220954359Sroberto * Mitigation rules of the game. There are several types of 2210182007Sroberto * peers that can be selected here: (1) orphan, (2) prefer peer 2211182007Sroberto * (flag FLAG_PREFER) (3) pps peers (type REFCLK_ATOM_PPS), (4) 2212182007Sroberto * the existing system peer, if any, and (5) the head of the 2213182007Sroberto * survivor list. 221454359Sroberto */ 2215182007Sroberto if (typesystem->stratum >= sys_orphan) { 2216182007Sroberto 2217182007Sroberto /* 2218182007Sroberto * If in orphan mode, choose the system peer. If the 2219182007Sroberto * lowest distance, we are the orphan parent and the 2220182007Sroberto * offset is zero. 2221182007Sroberto */ 2222182007Sroberto sys_peer = typesystem; 222354359Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2224182007Sroberto if (sys_orphandelay < sys_peer->rootdelay) { 2225182007Sroberto sys_offset = 0; 2226182007Sroberto sys_refid = htonl(LOOPBACKADR); 2227182007Sroberto } else { 2228182007Sroberto sys_offset = sys_peer->offset; 2229182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2230182007Sroberto } 2231182007Sroberto sys_jitter = LOGTOD(sys_precision); 223254359Sroberto#ifdef DEBUG 223354359Sroberto if (debug > 1) 2234182007Sroberto printf("select: orphan offset %.6f\n", 223556749Sroberto sys_offset); 223654359Sroberto#endif 2237182007Sroberto } else if (sys_prefer) { 2238182007Sroberto 2239182007Sroberto /* 2240182007Sroberto * If a pps peer is present, choose it; otherwise, 2241182007Sroberto * choose the prefer peer. 2242182007Sroberto */ 2243182007Sroberto if (sys_pps) { 2244182007Sroberto sys_peer = sys_pps; 2245182007Sroberto sys_peer->status = CTL_PST_SEL_PPS; 2246182007Sroberto sys_offset = sys_peer->offset; 2247182007Sroberto if (!pps_control) 2248182007Sroberto NLOG(NLOG_SYSEVENT) 2249182007Sroberto msyslog(LOG_INFO, 2250182007Sroberto "pps sync enabled"); 2251182007Sroberto pps_control = current_time; 225254359Sroberto#ifdef DEBUG 2253182007Sroberto if (debug > 1) 2254182007Sroberto printf("select: pps offset %.6f\n", 2255182007Sroberto sys_offset); 225654359Sroberto#endif 2257182007Sroberto } else { 2258182007Sroberto sys_peer = sys_prefer; 2259182007Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2260182007Sroberto sys_offset = sys_peer->offset; 2261182007Sroberto#ifdef DEBUG 2262182007Sroberto if (debug > 1) 2263182007Sroberto printf("select: prefer offset %.6f\n", 2264182007Sroberto sys_offset); 2265182007Sroberto#endif 2266182007Sroberto } 2267182007Sroberto if (sys_peer->stratum == STRATUM_REFCLOCK || 2268182007Sroberto sys_peer->stratum == STRATUM_UNSPEC) 2269182007Sroberto sys_refid = sys_peer->refid; 2270182007Sroberto else 2271182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2272182007Sroberto sys_jitter = sys_peer->jitter; 227354359Sroberto } else { 2274182007Sroberto 2275182007Sroberto /* 2276182007Sroberto * Otherwise, choose the anticlockhopper. 2277182007Sroberto */ 2278182007Sroberto sys_peer = typesystem; 2279182007Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2280182007Sroberto clock_combine(peer_list, nlist); 2281182007Sroberto if (sys_peer->stratum == STRATUM_REFCLOCK || 2282182007Sroberto sys_peer->stratum == STRATUM_UNSPEC) 2283182007Sroberto sys_refid = sys_peer->refid; 228482505Sroberto else 2285182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2286182007Sroberto sys_jitter = SQRT(SQUARE(sys_peer->jitter) + 2287182007Sroberto SQUARE(sys_jitter)); 228854359Sroberto#ifdef DEBUG 228954359Sroberto if (debug > 1) 229054359Sroberto printf("select: combine offset %.6f\n", 229154359Sroberto sys_offset); 229254359Sroberto#endif 229354359Sroberto } 2294182007Sroberto 2295182007Sroberto /* 2296182007Sroberto * We have found the alpha male. 2297182007Sroberto */ 2298182007Sroberto sys_peer->flags |= FLAG_SYSPEER; 2299132454Sroberto if (osys_peer != sys_peer) { 2300132454Sroberto char *src; 2301132454Sroberto 2302132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 2303132454Sroberto 2304132454Sroberto#ifdef REFCLOCK 2305182007Sroberto if (sys_peer->flags & FLAG_REFCLOCK) 2306132454Sroberto src = refnumtoa(&sys_peer->srcadr); 2307132454Sroberto else 2308182007Sroberto#endif /* REFCLOCK */ 2309132454Sroberto src = ntoa(&sys_peer->srcadr); 2310132454Sroberto NLOG(NLOG_SYNCSTATUS) 2311182007Sroberto msyslog(LOG_INFO, "synchronized to %s, stratum %d", 2312182007Sroberto src, sys_peer->stratum); 2313132454Sroberto } 231454359Sroberto clock_update(); 231554359Sroberto} 231654359Sroberto 2317182007Sroberto 231854359Sroberto/* 2319182007Sroberto * clock_combine - compute system offset and jitter from selected peers 232054359Sroberto */ 2321182007Srobertostatic void 232254359Srobertoclock_combine( 2323182007Sroberto struct peer **peers, /* survivor list */ 2324182007Sroberto int npeers /* number of survivors */ 232554359Sroberto ) 232654359Sroberto{ 2327132454Sroberto int i; 2328182007Sroberto double x, y, z, w; 2329132454Sroberto 2330182007Sroberto y = z = w = 0; 233154359Sroberto for (i = 0; i < npeers; i++) { 233254359Sroberto x = root_distance(peers[i]); 233354359Sroberto y += 1. / x; 233454359Sroberto z += peers[i]->offset / x; 2335182007Sroberto w += SQUARE(peers[i]->offset - peers[0]->offset) / x; 233654359Sroberto } 2337182007Sroberto sys_offset = z / y; 2338182007Sroberto sys_jitter = SQRT(w / y); 233954359Sroberto} 234054359Sroberto 234154359Sroberto/* 234254359Sroberto * root_distance - compute synchronization distance from peer to root 234354359Sroberto */ 234454359Srobertostatic double 234554359Srobertoroot_distance( 234654359Sroberto struct peer *peer 234754359Sroberto ) 234854359Sroberto{ 2349182007Sroberto double dist; 2350182007Sroberto 235182505Sroberto /* 235282505Sroberto * Careful squeak here. The value returned must be greater than 2353182007Sroberto * the minimum root dispersion in order to avoid clockhop with 2354182007Sroberto * highly precise reference clocks. In orphan mode lose the peer 2355182007Sroberto * root delay, as that is used by the election algorithm. 235682505Sroberto */ 2357182007Sroberto if (peer->stratum >= sys_orphan) 2358182007Sroberto dist = 0; 2359182007Sroberto else 2360182007Sroberto dist = peer->rootdelay; 2361182007Sroberto dist += max(sys_mindisp, dist + peer->delay) / 2 + 236282505Sroberto peer->rootdispersion + peer->disp + clock_phi * 2363182007Sroberto (current_time - peer->update) + peer->jitter; 2364182007Sroberto return (dist); 236554359Sroberto} 236654359Sroberto 236754359Sroberto/* 236854359Sroberto * peer_xmit - send packet for persistent association. 236954359Sroberto */ 237054359Srobertostatic void 237154359Srobertopeer_xmit( 237254359Sroberto struct peer *peer /* peer structure pointer */ 237354359Sroberto ) 237454359Sroberto{ 237582505Sroberto struct pkt xpkt; /* transmit packet */ 2376132454Sroberto int sendlen, authlen; 2377182007Sroberto keyid_t xkeyid = 0; /* transmit key ID */ 2378132454Sroberto l_fp xmt_tx; 237954359Sroberto 2380182007Sroberto if (!peer->dstadr) /* don't bother with peers without interface */ 2381182007Sroberto return; 2382182007Sroberto 238354359Sroberto /* 2384182007Sroberto * This is deliciously complicated. There are three cases. 2385182007Sroberto * 2386182007Sroberto * case leap stratum refid delay dispersion 2387182007Sroberto * 2388182007Sroberto * normal system system system system system 2389182007Sroberto * orphan child 00 orphan system orphan system 2390182007Sroberto * orphan parent 00 orphan loopbk 0 0 239154359Sroberto */ 2392182007Sroberto /* 2393182007Sroberto * This is a normal packet. Use the system variables. 2394182007Sroberto */ 2395182007Sroberto if (sys_stratum < sys_orphan) { 2396182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, 2397182007Sroberto peer->version, peer->hmode); 2398182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 2399182007Sroberto xpkt.refid = sys_refid; 2400182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2401182007Sroberto xpkt.rootdispersion = 2402182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2403182007Sroberto 2404182007Sroberto /* 2405182007Sroberto * This is a orphan child packet. The host is synchronized to an 2406182007Sroberto * orphan parent. Show leap synchronized, orphan stratum, system 2407182007Sroberto * reference ID, orphan root delay and system root dispersion. 2408182007Sroberto */ 2409182007Sroberto } else if (sys_peer != NULL) { 2410182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2411182007Sroberto peer->version, peer->hmode); 2412182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2413182007Sroberto xpkt.refid = htonl(LOOPBACKADR); 2414182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay)); 2415182007Sroberto xpkt.rootdispersion = 2416182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2417182007Sroberto 2418182007Sroberto /* 2419182007Sroberto * This is an orphan parent. Show leap synchronized, orphan 2420182007Sroberto * stratum, loopack reference ID and zero root delay and root 2421182007Sroberto * dispersion. 2422182007Sroberto */ 2423182007Sroberto } else { 2424182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2425182007Sroberto peer->version, peer->hmode); 2426182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2427182007Sroberto xpkt.refid = sys_refid; 2428182007Sroberto xpkt.rootdelay = 0; 2429182007Sroberto xpkt.rootdispersion = 0; 2430182007Sroberto } 243154359Sroberto xpkt.ppoll = peer->hpoll; 243254359Sroberto xpkt.precision = sys_precision; 243354359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 243454359Sroberto HTONL_FP(&peer->org, &xpkt.org); 243554359Sroberto HTONL_FP(&peer->rec, &xpkt.rec); 243654359Sroberto 243754359Sroberto /* 243882505Sroberto * If the received packet contains a MAC, the transmitted packet 243982505Sroberto * is authenticated and contains a MAC. If not, the transmitted 244082505Sroberto * packet is not authenticated. 244182505Sroberto * 2442182007Sroberto * It is most important when autokey is in use that the local 2443182007Sroberto * interface IP address be known before the first packet is 2444182007Sroberto * sent. Otherwise, it is not possible to compute a correct MAC 2445182007Sroberto * the recipient will accept. Thus, the I/O semantics have to do 2446182007Sroberto * a little more work. In particular, the wildcard interface 2447182007Sroberto * might not be usable. 244854359Sroberto */ 244954359Sroberto sendlen = LEN_PKT_NOMAC; 245082505Sroberto if (!(peer->flags & FLAG_AUTHENABLE)) { 245182505Sroberto get_systime(&peer->xmt); 245282505Sroberto HTONL_FP(&peer->xmt, &xpkt.xmt); 2453132454Sroberto sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], 2454182007Sroberto &xpkt, sendlen); 245582505Sroberto peer->sent++; 245682505Sroberto#ifdef DEBUG 245782505Sroberto if (debug) 245882505Sroberto printf("transmit: at %ld %s->%s mode %d\n", 2459182007Sroberto current_time, peer->dstadr ? stoa(&peer->dstadr->sin) : "-", 2460182007Sroberto stoa(&peer->srcadr), peer->hmode); 246182505Sroberto#endif 246282505Sroberto return; 246382505Sroberto } 246454359Sroberto 246582505Sroberto /* 246682505Sroberto * The received packet contains a MAC, so the transmitted packet 246782505Sroberto * must be authenticated. If autokey is enabled, fuss with the 2468182007Sroberto * various modes; otherwise, symmetric key cryptography is used. 246982505Sroberto */ 2470132454Sroberto#ifdef OPENSSL 2471132454Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 2472132454Sroberto struct exten *exten; /* extension field */ 247382505Sroberto 247454359Sroberto /* 247582505Sroberto * The Public Key Dance (PKD): Cryptographic credentials 247682505Sroberto * are contained in extension fields, each including a 247782505Sroberto * 4-octet length/code word followed by a 4-octet 247882505Sroberto * association ID and optional additional data. Optional 247982505Sroberto * data includes a 4-octet data length field followed by 248082505Sroberto * the data itself. Request messages are sent from a 248182505Sroberto * configured association; response messages can be sent 248282505Sroberto * from a configured association or can take the fast 248382505Sroberto * path without ever matching an association. Response 248482505Sroberto * messages have the same code as the request, but have 248582505Sroberto * a response bit and possibly an error bit set. In this 248682505Sroberto * implementation, a message may contain no more than 248782505Sroberto * one command and no more than one response. 248882505Sroberto * 248982505Sroberto * Cryptographic session keys include both a public and 249082505Sroberto * a private componet. Request and response messages 249182505Sroberto * using extension fields are always sent with the 249282505Sroberto * private component set to zero. Packets without 249382505Sroberto * extension fields indlude the private component when 249482505Sroberto * the session key is generated. 249554359Sroberto */ 249682505Sroberto while (1) { 249782505Sroberto 249854359Sroberto /* 249982505Sroberto * Allocate and initialize a keylist if not 250082505Sroberto * already done. Then, use the list in inverse 250182505Sroberto * order, discarding keys once used. Keep the 250282505Sroberto * latest key around until the next one, so 250382505Sroberto * clients can use client/server packets to 250482505Sroberto * compute propagation delay. 250582505Sroberto * 250682505Sroberto * Note that once a key is used from the list, 250782505Sroberto * it is retained in the key cache until the 250882505Sroberto * next key is used. This is to allow a client 250982505Sroberto * to retrieve the encrypted session key 251082505Sroberto * identifier to verify authenticity. 251182505Sroberto * 251282505Sroberto * If for some reason a key is no longer in the 251382505Sroberto * key cache, a birthday has happened and the 251482505Sroberto * pseudo-random sequence is probably broken. In 251582505Sroberto * that case, purge the keylist and regenerate 251682505Sroberto * it. 251754359Sroberto */ 251882505Sroberto if (peer->keynumber == 0) 251982505Sroberto make_keylist(peer, peer->dstadr); 252082505Sroberto else 252182505Sroberto peer->keynumber--; 252282505Sroberto xkeyid = peer->keylist[peer->keynumber]; 252382505Sroberto if (authistrusted(xkeyid)) 252482505Sroberto break; 252582505Sroberto else 252682505Sroberto key_expire(peer); 252754359Sroberto } 252882505Sroberto peer->keyid = xkeyid; 2529182007Sroberto exten = NULL; 253082505Sroberto switch (peer->hmode) { 253154359Sroberto 2532182007Sroberto /* 2533182007Sroberto * In broadcast server mode the autokey values are 2534182007Sroberto * required by the broadcast clients. Push them when a 2535182007Sroberto * new keylist is generated; otherwise, push the 2536182007Sroberto * association message so the client can request them at 2537182007Sroberto * other times. 2538182007Sroberto */ 253982505Sroberto case MODE_BROADCAST: 254082505Sroberto if (peer->flags & FLAG_ASSOC) 2541132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 2542182007Sroberto CRYPTO_RESP, NULL); 254382505Sroberto else 2544132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC | 2545182007Sroberto CRYPTO_RESP, NULL); 254682505Sroberto break; 254782505Sroberto 254854359Sroberto /* 2549132454Sroberto * In symmetric modes the digest, certificate, agreement 2550132454Sroberto * parameters, cookie and autokey values are required. 2551132454Sroberto * The leapsecond table is optional. But, a passive peer 2552132454Sroberto * will not believe the active peer until the latter has 2553132454Sroberto * synchronized, so the agreement must be postponed 2554132454Sroberto * until then. In any case, if a new keylist is 2555132454Sroberto * generated, the autokey values are pushed. 2556182007Sroberto * 2557182007Sroberto * If the crypto bit is lit, don't send requests. 255854359Sroberto */ 255982505Sroberto case MODE_ACTIVE: 256082505Sroberto case MODE_PASSIVE: 2561182007Sroberto if (peer->flash & TEST9) 2562182007Sroberto break; 2563182007Sroberto /* 2564182007Sroberto * Parameter and certificate. 2565182007Sroberto */ 256682505Sroberto if (!peer->crypto) 2567132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 2568182007Sroberto sys_hostname); 2569132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VALID)) 2570132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 2571182007Sroberto peer->issuer); 2572132454Sroberto 2573132454Sroberto /* 2574132454Sroberto * Identity. Note we have to sign the 2575132454Sroberto * certificate before the cookie to avoid a 2576132454Sroberto * deadlock when the passive peer is walking the 2577132454Sroberto * certificate trail. Awesome. 2578132454Sroberto */ 2579182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 2580182007Sroberto exten = crypto_args(peer, 2581182007Sroberto crypto_ident(peer), NULL); 2582132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2583182007Sroberto !(peer->crypto & CRYPTO_FLAG_SIGN)) 2584132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 2585182007Sroberto sys_hostname); 2586132454Sroberto 2587132454Sroberto /* 2588132454Sroberto * Autokey. We request the cookie only when the 2589132454Sroberto * server and client are synchronized and 2590132454Sroberto * signatures work both ways. On the other hand, 2591132454Sroberto * the active peer needs the autokey values 2592132454Sroberto * before then and when the passive peer is 2593132454Sroberto * waiting for the active peer to synchronize. 2594132454Sroberto * Any time we regenerate the key list, we offer 2595132454Sroberto * the autokey values without being asked. 2596132454Sroberto */ 2597132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2598182007Sroberto peer->leap != LEAP_NOTINSYNC && 2599182007Sroberto !(peer->crypto & CRYPTO_FLAG_AGREE)) 2600132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 2601182007Sroberto NULL); 2602132454Sroberto else if (peer->flags & FLAG_ASSOC) 2603132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 2604182007Sroberto CRYPTO_RESP, NULL); 2605132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 2606132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 2607182007Sroberto NULL); 2608132454Sroberto 2609132454Sroberto /* 2610132454Sroberto * Postamble. We trade leapseconds only when the 2611132454Sroberto * server and client are synchronized. 2612132454Sroberto */ 2613132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2614182007Sroberto peer->leap != LEAP_NOTINSYNC && 2615182007Sroberto peer->crypto & CRYPTO_FLAG_TAI && 2616182007Sroberto !(peer->crypto & CRYPTO_FLAG_LEAP)) 2617132454Sroberto exten = crypto_args(peer, CRYPTO_TAI, 2618182007Sroberto NULL); 261982505Sroberto break; 262082505Sroberto 262182505Sroberto /* 2622132454Sroberto * In client mode the digest, certificate, agreement 2623132454Sroberto * parameters and cookie are required. The leapsecond 2624132454Sroberto * table is optional. If broadcast client mode, the 2625132454Sroberto * autokey values are required as well. In broadcast 2626132454Sroberto * client mode, these values must be acquired during the 262782505Sroberto * client/server exchange to avoid having to wait until 262882505Sroberto * the next key list regeneration. Otherwise, the poor 262982505Sroberto * dude may die a lingering death until becoming 2630132454Sroberto * unreachable and attempting rebirth. 2631132454Sroberto * 2632132454Sroberto * If neither the server or client have the agreement 2633132454Sroberto * parameters, the protocol transmits the cookie in the 2634132454Sroberto * clear. If the server has the parameters, the client 2635132454Sroberto * requests them and the protocol blinds it using the 2636132454Sroberto * agreed key. It is a protocol error if the client has 2637132454Sroberto * the parameters but the server does not. 2638182007Sroberto * 2639182007Sroberto * If the crypto bit is lit, don't send requests. 264082505Sroberto */ 264182505Sroberto case MODE_CLIENT: 2642182007Sroberto if (peer->flash & TEST9) 2643182007Sroberto break; 2644182007Sroberto /* 2645182007Sroberto * Parameter and certificate. 2646182007Sroberto */ 264782505Sroberto if (!peer->crypto) 2648132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 2649182007Sroberto sys_hostname); 2650132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VALID)) 2651132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 2652182007Sroberto peer->issuer); 2653132454Sroberto 2654132454Sroberto /* 2655182007Sroberto * Identity 2656132454Sroberto */ 2657182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 2658182007Sroberto exten = crypto_args(peer, 2659182007Sroberto crypto_ident(peer), NULL); 2660132454Sroberto 2661132454Sroberto /* 2662132454Sroberto * Autokey 2663132454Sroberto */ 2664132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AGREE)) 2665132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 2666182007Sroberto NULL); 2667132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO) && 2668182007Sroberto (peer->cast_flags & MDF_BCLNT)) 2669132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 2670182007Sroberto NULL); 2671132454Sroberto 2672132454Sroberto /* 2673132454Sroberto * Postamble. We can sign the certificate here, 2674132454Sroberto * since there is no chance of deadlock. 2675132454Sroberto */ 2676132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2677182007Sroberto !(peer->crypto & CRYPTO_FLAG_SIGN)) 2678132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 2679182007Sroberto sys_hostname); 2680132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2681182007Sroberto peer->crypto & CRYPTO_FLAG_TAI && 2682182007Sroberto !(peer->crypto & CRYPTO_FLAG_LEAP)) 2683132454Sroberto exten = crypto_args(peer, CRYPTO_TAI, 2684182007Sroberto NULL); 268582505Sroberto break; 268682505Sroberto } 268782505Sroberto 268882505Sroberto /* 2689182007Sroberto * Build the extension fields as directed. A response to 2690182007Sroberto * a request is always sent, even if an error. If an 2691182007Sroberto * error occurs when sending a request, the crypto 2692182007Sroberto * machinery broke or was misconfigured. In that case 2693182007Sroberto * light the crypto bit to suppress further requests. 2694182007Sroberto */ 2695182007Sroberto if (peer->cmmd != NULL) { 2696182007Sroberto peer->cmmd->associd = htonl(peer->associd); 2697182007Sroberto sendlen += crypto_xmit(&xpkt, &peer->srcadr, 2698182007Sroberto sendlen, peer->cmmd, 0); 2699182007Sroberto free(peer->cmmd); 2700182007Sroberto peer->cmmd = NULL; 2701182007Sroberto } 2702182007Sroberto if (exten != NULL) { 2703182007Sroberto int ltemp = 0; 2704182007Sroberto 2705182007Sroberto if (exten->opcode != 0) { 2706182007Sroberto ltemp = crypto_xmit(&xpkt, 2707182007Sroberto &peer->srcadr, sendlen, exten, 0); 2708182007Sroberto if (ltemp == 0) { 2709182007Sroberto peer->flash |= TEST9; /* crypto error */ 2710182007Sroberto free(exten); 2711182007Sroberto return; 2712182007Sroberto } 2713182007Sroberto } 2714182007Sroberto sendlen += ltemp; 2715182007Sroberto free(exten); 2716182007Sroberto } 2717182007Sroberto 2718182007Sroberto /* 271982505Sroberto * If extension fields are present, we must use a 2720182007Sroberto * private cookie value of zero. Don't send if the 2721182007Sroberto * crypto bit is set and no extension field is present, 2722182007Sroberto * but in that case give back the key. Most intricate. 272382505Sroberto */ 2724182007Sroberto if (sendlen > LEN_PKT_NOMAC) { 272582505Sroberto session_key(&peer->dstadr->sin, &peer->srcadr, 272682505Sroberto xkeyid, 0, 2); 2727182007Sroberto } else if (peer->flash & TEST9) { 2728182007Sroberto authtrust(xkeyid, 0); 2729182007Sroberto return; 2730182007Sroberto } 273182505Sroberto } 2732132454Sroberto#endif /* OPENSSL */ 2733182007Sroberto 2734182007Sroberto /* 2735182007Sroberto * Stash the transmit timestamp corrected for the encryption 2736182007Sroberto * delay. If autokey, give back the key, as we use keys only 2737182007Sroberto * once. Check for errors such as missing keys, buffer overflow, 2738182007Sroberto * etc. 2739182007Sroberto */ 274082505Sroberto xkeyid = peer->keyid; 274182505Sroberto get_systime(&peer->xmt); 274282505Sroberto L_ADD(&peer->xmt, &sys_authdelay); 274382505Sroberto HTONL_FP(&peer->xmt, &xpkt.xmt); 274482505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 274582505Sroberto if (authlen == 0) { 2746182007Sroberto msyslog(LOG_INFO, "transmit: %s key %u not found", 2747182007Sroberto stoa(&peer->srcadr), xkeyid); 2748182007Sroberto peer->flash |= TEST9; /* no key found */ 274982505Sroberto return; 275082505Sroberto } 275182505Sroberto sendlen += authlen; 2752132454Sroberto#ifdef OPENSSL 275382505Sroberto if (xkeyid > NTP_MAXKEY) 275482505Sroberto authtrust(xkeyid, 0); 2755132454Sroberto#endif /* OPENSSL */ 275682505Sroberto get_systime(&xmt_tx); 275782505Sroberto if (sendlen > sizeof(xpkt)) { 275882505Sroberto msyslog(LOG_ERR, "buffer overflow %u", sendlen); 2759132454Sroberto exit (-1); 276082505Sroberto } 2761132454Sroberto sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt, 2762182007Sroberto sendlen); 276382505Sroberto 276482505Sroberto /* 276582505Sroberto * Calculate the encryption delay. Keep the minimum over 276682505Sroberto * the latest two samples. 276782505Sroberto */ 276882505Sroberto L_SUB(&xmt_tx, &peer->xmt); 276982505Sroberto L_ADD(&xmt_tx, &sys_authdelay); 277082505Sroberto sys_authdly[1] = sys_authdly[0]; 277182505Sroberto sys_authdly[0] = xmt_tx.l_uf; 277282505Sroberto if (sys_authdly[0] < sys_authdly[1]) 277382505Sroberto sys_authdelay.l_uf = sys_authdly[0]; 277482505Sroberto else 277582505Sroberto sys_authdelay.l_uf = sys_authdly[1]; 277682505Sroberto peer->sent++; 2777132454Sroberto#ifdef OPENSSL 277854359Sroberto#ifdef DEBUG 277982505Sroberto if (debug) 278082505Sroberto printf( 2781182007Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d index %d\n", 2782182007Sroberto current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-", 2783182007Sroberto ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen - 2784182007Sroberto authlen, authlen, peer->keynumber); 278554359Sroberto#endif 278682505Sroberto#else 278782505Sroberto#ifdef DEBUG 278882505Sroberto if (debug) 278982505Sroberto printf( 2790182007Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n", 2791182007Sroberto current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-", 2792182007Sroberto ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen - 2793182007Sroberto authlen, authlen); 279482505Sroberto#endif 2795132454Sroberto#endif /* OPENSSL */ 279654359Sroberto} 279754359Sroberto 279882505Sroberto 279954359Sroberto/* 280082505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that 280182505Sroberto * neither the source or destination can be a broadcast address. 280254359Sroberto */ 280354359Srobertostatic void 280454359Srobertofast_xmit( 280554359Sroberto struct recvbuf *rbufp, /* receive packet pointer */ 2806132454Sroberto int xmode, /* transmit mode */ 2807132454Sroberto keyid_t xkeyid, /* transmit key ID */ 2808132454Sroberto int mask /* restrict mask */ 280954359Sroberto ) 281054359Sroberto{ 2811132454Sroberto struct pkt xpkt; /* transmit packet structure */ 2812132454Sroberto struct pkt *rpkt; /* receive packet structure */ 2813132454Sroberto l_fp xmt_ts; /* timestamp */ 2814132454Sroberto l_fp xmt_tx; /* timestamp after authent */ 2815132454Sroberto int sendlen, authlen; 2816132454Sroberto#ifdef OPENSSL 2817132454Sroberto u_int32 temp32; 2818132454Sroberto#endif 281954359Sroberto 282054359Sroberto /* 282182505Sroberto * Initialize transmit packet header fields from the receive 282282505Sroberto * buffer provided. We leave some fields intact as received. If 2823182007Sroberto * the gazinta was from a multicast address, the gazoutta must 2824182007Sroberto * go out another way. 2825182007Sroberto * 2826182007Sroberto * The root delay field is special. If the system stratum is 2827182007Sroberto * less than the orphan stratum, send the real root delay. 2828182007Sroberto * Otherwise, if there is no system peer, send the orphan delay. 2829182007Sroberto * Otherwise, we must be an orphan parent, so send zero. 283054359Sroberto */ 283154359Sroberto rpkt = &rbufp->recv_pkt; 2832182007Sroberto if (rbufp->dstadr->flags & INT_MCASTOPEN) 283382505Sroberto rbufp->dstadr = findinterface(&rbufp->recv_srcadr); 283482505Sroberto 283582505Sroberto /* 2836182007Sroberto * This is deliciously complicated. There are four cases. 2837182007Sroberto * 2838182007Sroberto * case leap stratum refid delay dispersion 2839182007Sroberto * 2840182007Sroberto * KoD 11 16 KISS system system 2841182007Sroberto * normal system system system system system 2842182007Sroberto * orphan child 00 orphan system orphan system 2843182007Sroberto * orphan parent 00 orphan loopbk 0 0 284482505Sroberto */ 2845182007Sroberto /* 2846182007Sroberto * This is a kiss-of-death (KoD) packet. Show leap 2847182007Sroberto * unsynchronized, stratum zero, reference ID the four-character 2848182007Sroberto * kiss code and system root delay. Note the rate limit on these 2849182007Sroberto * packets. Once a second initialize a bucket counter. Every 2850182007Sroberto * packet sent decrements the counter until reaching zero. If 2851182007Sroberto * the counter is zero, drop the kiss. 2852182007Sroberto */ 2853182007Sroberto if (mask & RES_LIMITED) { 2854182007Sroberto sys_limitrejected++; 2855132454Sroberto if (sys_kod == 0 || !(mask & RES_DEMOBILIZE)) 285682505Sroberto return; 2857132454Sroberto 2858132454Sroberto sys_kod--; 2859132454Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 2860132454Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2861132454Sroberto xpkt.stratum = STRATUM_UNSPEC; 2862182007Sroberto memcpy(&xpkt.refid, "RATE", 4); 2863182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2864182007Sroberto xpkt.rootdispersion = 2865182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2866182007Sroberto 2867182007Sroberto /* 2868182007Sroberto * This is a normal packet. Use the system variables. 2869182007Sroberto */ 2870182007Sroberto } else if (sys_stratum < sys_orphan) { 287182505Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, 287282505Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 287382505Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 287482505Sroberto xpkt.refid = sys_refid; 2875182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2876182007Sroberto xpkt.rootdispersion = 2877182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2878182007Sroberto 2879182007Sroberto /* 2880182007Sroberto * This is a orphan child packet. The host is synchronized to an 2881182007Sroberto * orphan parent. Show leap synchronized, orphan stratum, system 2882182007Sroberto * reference ID and orphan root delay. 2883182007Sroberto */ 2884182007Sroberto } else if (sys_peer != NULL) { 2885182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2886182007Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2887182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2888182007Sroberto xpkt.refid = sys_refid; 2889182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay)); 2890182007Sroberto xpkt.rootdispersion = 2891182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2892182007Sroberto 2893182007Sroberto /* 2894182007Sroberto * This is an orphan parent. Show leap synchronized, orphan 2895182007Sroberto * stratum, loopack reference ID and zero root delay. 2896182007Sroberto */ 2897182007Sroberto } else { 2898182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2899182007Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2900182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2901182007Sroberto xpkt.refid = htonl(LOOPBACKADR); 2902182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(0)); 2903182007Sroberto xpkt.rootdispersion = HTONS_FP(DTOFP(0)); 290482505Sroberto } 290554359Sroberto xpkt.ppoll = rpkt->ppoll; 290654359Sroberto xpkt.precision = sys_precision; 2907182007Sroberto xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion)); 290854359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 290954359Sroberto xpkt.org = rpkt->xmt; 291054359Sroberto HTONL_FP(&rbufp->recv_time, &xpkt.rec); 291182505Sroberto 291282505Sroberto /* 291382505Sroberto * If the received packet contains a MAC, the transmitted packet 291482505Sroberto * is authenticated and contains a MAC. If not, the transmitted 291582505Sroberto * packet is not authenticated. 291682505Sroberto */ 291754359Sroberto sendlen = LEN_PKT_NOMAC; 291882505Sroberto if (rbufp->recv_length == sendlen) { 291954359Sroberto get_systime(&xmt_ts); 292054359Sroberto HTONL_FP(&xmt_ts, &xpkt.xmt); 292182505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, 292256749Sroberto sendlen); 292354359Sroberto#ifdef DEBUG 292454359Sroberto if (debug) 292582505Sroberto printf("transmit: at %ld %s->%s mode %d\n", 2926132454Sroberto current_time, stoa(&rbufp->dstadr->sin), 2927132454Sroberto stoa(&rbufp->recv_srcadr), xmode); 292854359Sroberto#endif 292982505Sroberto return; 293082505Sroberto } 293154359Sroberto 293282505Sroberto /* 293382505Sroberto * The received packet contains a MAC, so the transmitted packet 2934182007Sroberto * must be authenticated. For symmetric key cryptography, use 2935182007Sroberto * the predefined and trusted symmetric keys to generate the 2936182007Sroberto * cryptosum. For autokey cryptography, use the server private 2937182007Sroberto * value to generate the cookie, which is unique for every 2938182007Sroberto * source-destination-key ID combination. 293982505Sroberto */ 2940132454Sroberto#ifdef OPENSSL 294182505Sroberto if (xkeyid > NTP_MAXKEY) { 294282505Sroberto keyid_t cookie; 294382505Sroberto 294454359Sroberto /* 294582505Sroberto * The only way to get here is a reply to a legitimate 294682505Sroberto * client request message, so the mode must be 294782505Sroberto * MODE_SERVER. If an extension field is present, there 294882505Sroberto * can be only one and that must be a command. Do what 294982505Sroberto * needs, but with private value of zero so the poor 295082505Sroberto * jerk can decode it. If no extension field is present, 295182505Sroberto * use the cookie to generate the session key. 295254359Sroberto */ 295382505Sroberto cookie = session_key(&rbufp->recv_srcadr, 295482505Sroberto &rbufp->dstadr->sin, 0, sys_private, 0); 2955182007Sroberto if (rbufp->recv_length >= (int)(sendlen + MAX_MAC_LEN + 2956182007Sroberto 2 * sizeof(u_int32))) { 295782505Sroberto session_key(&rbufp->dstadr->sin, 295882505Sroberto &rbufp->recv_srcadr, xkeyid, 0, 2); 2959132454Sroberto temp32 = CRYPTO_RESP; 2960132454Sroberto rpkt->exten[0] |= htonl(temp32); 2961132454Sroberto sendlen += crypto_xmit(&xpkt, 2962132454Sroberto &rbufp->recv_srcadr, sendlen, 2963132454Sroberto (struct exten *)rpkt->exten, cookie); 296482505Sroberto } else { 296582505Sroberto session_key(&rbufp->dstadr->sin, 296682505Sroberto &rbufp->recv_srcadr, xkeyid, cookie, 2); 296782505Sroberto } 296882505Sroberto } 2969132454Sroberto#endif /* OPENSSL */ 297082505Sroberto get_systime(&xmt_ts); 297182505Sroberto L_ADD(&xmt_ts, &sys_authdelay); 297282505Sroberto HTONL_FP(&xmt_ts, &xpkt.xmt); 297382505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 297482505Sroberto sendlen += authlen; 2975132454Sroberto#ifdef OPENSSL 297682505Sroberto if (xkeyid > NTP_MAXKEY) 297782505Sroberto authtrust(xkeyid, 0); 2978132454Sroberto#endif /* OPENSSL */ 297982505Sroberto get_systime(&xmt_tx); 298082505Sroberto if (sendlen > sizeof(xpkt)) { 298182505Sroberto msyslog(LOG_ERR, "buffer overflow %u", sendlen); 2982132454Sroberto exit (-1); 298382505Sroberto } 298482505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); 298582505Sroberto 298682505Sroberto /* 298782505Sroberto * Calculate the encryption delay. Keep the minimum over the 298882505Sroberto * latest two samples. 298982505Sroberto */ 299082505Sroberto L_SUB(&xmt_tx, &xmt_ts); 299182505Sroberto L_ADD(&xmt_tx, &sys_authdelay); 299282505Sroberto sys_authdly[1] = sys_authdly[0]; 299382505Sroberto sys_authdly[0] = xmt_tx.l_uf; 299482505Sroberto if (sys_authdly[0] < sys_authdly[1]) 299582505Sroberto sys_authdelay.l_uf = sys_authdly[0]; 299682505Sroberto else 299782505Sroberto sys_authdelay.l_uf = sys_authdly[1]; 299854359Sroberto#ifdef DEBUG 299982505Sroberto if (debug) 300082505Sroberto printf( 300182505Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n", 300282505Sroberto current_time, ntoa(&rbufp->dstadr->sin), 3003132454Sroberto ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen - 3004132454Sroberto authlen, authlen); 300554359Sroberto#endif 300654359Sroberto} 300754359Sroberto 300882505Sroberto 3009132454Sroberto#ifdef OPENSSL 301054359Sroberto/* 301182505Sroberto * key_expire - purge the key list 301254359Sroberto */ 301382505Srobertovoid 301482505Srobertokey_expire( 301582505Sroberto struct peer *peer /* peer structure pointer */ 301654359Sroberto ) 301754359Sroberto{ 301854359Sroberto int i; 301954359Sroberto 3020132454Sroberto if (peer->keylist != NULL) { 302182505Sroberto for (i = 0; i <= peer->keynumber; i++) 302282505Sroberto authtrust(peer->keylist[i], 0); 302382505Sroberto free(peer->keylist); 302482505Sroberto peer->keylist = NULL; 302554359Sroberto } 3026132454Sroberto value_free(&peer->sndval); 3027132454Sroberto peer->keynumber = 0; 302882505Sroberto#ifdef DEBUG 302982505Sroberto if (debug) 303082505Sroberto printf("key_expire: at %lu\n", current_time); 303182505Sroberto#endif 303254359Sroberto} 3033132454Sroberto#endif /* OPENSSL */ 303454359Sroberto 3035132454Sroberto 303654359Sroberto/* 3037132454Sroberto * Determine if the peer is unfit for synchronization 3038132454Sroberto * 3039132454Sroberto * A peer is unfit for synchronization if 3040182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling 3041182007Sroberto * > TEST11 root distance exceeded 3042182007Sroberto * > TEST12 a direct or indirect synchronization loop would form 3043182007Sroberto * > TEST13 unreachable or noselect 3044132454Sroberto */ 3045182007Srobertoint /* FALSE if fit, TRUE if unfit */ 3046132454Srobertopeer_unfit( 3047132454Sroberto struct peer *peer /* peer structure pointer */ 3048132454Sroberto ) 3049132454Sroberto{ 3050182007Sroberto int rval = 0; 3051182007Sroberto 3052182007Sroberto /* 3053182007Sroberto * A stratum error occurs if (1) the server has never been 3054182007Sroberto * synchronized, (2) the server stratum is below the floor or 3055182007Sroberto * greater than or equal to the ceiling, (3) the system stratum 3056182007Sroberto * is below the orphan stratum and the server stratum is greater 3057182007Sroberto * than or equal to the orphan stratum. 3058182007Sroberto */ 3059182007Sroberto if (peer->leap == LEAP_NOTINSYNC || peer->stratum < sys_floor || 3060182007Sroberto peer->stratum >= sys_ceiling || (sys_stratum < sys_orphan && 3061182007Sroberto peer->stratum >= sys_orphan)) 3062182007Sroberto rval |= TEST10; /* stratum out of bounds */ 3063182007Sroberto 3064182007Sroberto /* 3065182007Sroberto * A distance error occurs if the root distance is greater than 3066182007Sroberto * or equal to the distance threshold plus the increment due to 3067182007Sroberto * one poll interval. 3068182007Sroberto */ 3069182007Sroberto if (root_distance(peer) >= sys_maxdist + clock_phi * 3070182007Sroberto ULOGTOD(sys_poll)) 3071182007Sroberto rval |= TEST11; /* distance exceeded */ 3072182007Sroberto 3073182007Sroberto /* 3074182007Sroberto * A loop error occurs if the remote peer is synchronized to the 3075182007Sroberto * local peer of if the remote peer is synchronized to the same 3076182007Sroberto * server as the local peer, but only if the remote peer is not 3077182007Sroberto * the orphan parent. 3078182007Sroberto */ 3079182007Sroberto if (peer->stratum > 1 && peer->refid != htonl(LOOPBACKADR) && 3080182007Sroberto ((!peer->dstadr || peer->refid == peer->dstadr->addr_refid) || 3081182007Sroberto peer->refid == sys_refid)) 3082182007Sroberto rval |= TEST12; /* synch loop */ 3083182007Sroberto 3084182007Sroberto /* 3085182007Sroberto * An unreachable error occurs if the server is unreachable or 3086182007Sroberto * the noselect bit is set. 3087182007Sroberto */ 3088182007Sroberto if (!peer->reach || peer->flags & FLAG_NOSELECT) 3089182007Sroberto rval |= TEST13; /* unreachable */ 3090182007Sroberto 3091182007Sroberto peer->flash &= ~PEER_TEST_MASK; 3092182007Sroberto peer->flash |= rval; 3093182007Sroberto return (rval); 3094132454Sroberto} 3095132454Sroberto 3096132454Sroberto 3097132454Sroberto/* 309854359Sroberto * Find the precision of this particular machine 309954359Sroberto */ 3100132454Sroberto#define MINSTEP 100e-9 /* minimum clock increment (s) */ 3101132454Sroberto#define MAXSTEP 20e-3 /* maximum clock increment (s) */ 3102132454Sroberto#define MINLOOPS 5 /* minimum number of step samples */ 310354359Sroberto 310454359Sroberto/* 3105132454Sroberto * This routine calculates the system precision, defined as the minimum 3106182007Sroberto * of a sequence of differences between successive readings of the 3107132454Sroberto * system clock. However, if the system clock can be read more than once 3108132454Sroberto * during a tick interval, the difference can be zero or one LSB unit, 3109132454Sroberto * where the LSB corresponds to one nanosecond or one microsecond. 3110132454Sroberto * Conceivably, if some other process preempts this one and reads the 3111132454Sroberto * clock, the difference can be more than one LSB unit. 3112132454Sroberto * 3113132454Sroberto * For hardware clock frequencies of 10 MHz or less, we assume the 3114132454Sroberto * logical clock advances only at the hardware clock tick. For higher 3115132454Sroberto * frequencies, we assume the logical clock can advance no more than 100 3116132454Sroberto * nanoseconds between ticks. 311754359Sroberto */ 311854359Srobertoint 311954359Srobertodefault_get_precision(void) 312054359Sroberto{ 3121132454Sroberto l_fp val; /* current seconds fraction */ 3122132454Sroberto l_fp last; /* last seconds fraction */ 3123132454Sroberto l_fp diff; /* difference */ 3124132454Sroberto double tick; /* computed tick value */ 3125132454Sroberto double dtemp; /* scratch */ 3126132454Sroberto int i; /* log2 precision */ 312754359Sroberto 3128132454Sroberto /* 3129132454Sroberto * Loop to find tick value in nanoseconds. Toss out outlyer 3130132454Sroberto * values less than the minimun tick value. In wacky cases, use 3131132454Sroberto * the default maximum value. 313254359Sroberto */ 3133132454Sroberto get_systime(&last); 3134132454Sroberto tick = MAXSTEP; 3135132454Sroberto for (i = 0; i < MINLOOPS;) { 3136132454Sroberto get_systime(&val); 3137132454Sroberto diff = val; 3138132454Sroberto L_SUB(&diff, &last); 3139132454Sroberto last = val; 3140132454Sroberto LFPTOD(&diff, dtemp); 3141132454Sroberto if (dtemp < MINSTEP) 3142132454Sroberto continue; 3143132454Sroberto i++; 3144132454Sroberto if (dtemp < tick) 3145132454Sroberto tick = dtemp; 314654359Sroberto } 3147132454Sroberto 3148132454Sroberto /* 3149132454Sroberto * Find the nearest power of two. 3150132454Sroberto */ 3151132454Sroberto NLOG(NLOG_SYSEVENT) 3152132454Sroberto msyslog(LOG_INFO, "precision = %.3f usec", tick * 1e6); 3153132454Sroberto for (i = 0; tick <= 1; i++) 3154132454Sroberto tick *= 2; 3155132454Sroberto if (tick - 1. > 1. - tick / 2) 3156132454Sroberto i--; 3157132454Sroberto return (-i); 315854359Sroberto} 315954359Sroberto 3160132454Sroberto 316154359Sroberto/* 3162132454Sroberto * kod_proto - called once per second to limit kiss-of-death packets 3163132454Sroberto */ 3164132454Srobertovoid 3165132454Srobertokod_proto(void) 3166132454Sroberto{ 3167132454Sroberto sys_kod = sys_kod_rate; 3168132454Sroberto} 3169132454Sroberto 3170132454Sroberto 3171132454Sroberto/* 317254359Sroberto * init_proto - initialize the protocol module's data 317354359Sroberto */ 317454359Srobertovoid 317554359Srobertoinit_proto(void) 317654359Sroberto{ 3177132454Sroberto l_fp dummy; 3178132454Sroberto int i; 317954359Sroberto 318054359Sroberto /* 318154359Sroberto * Fill in the sys_* stuff. Default is don't listen to 318254359Sroberto * broadcasting, authenticate. 318354359Sroberto */ 318454359Sroberto sys_leap = LEAP_NOTINSYNC; 318554359Sroberto sys_stratum = STRATUM_UNSPEC; 3186132454Sroberto memcpy(&sys_refid, "INIT", 4); 318754359Sroberto sys_precision = (s_char)default_get_precision(); 318882505Sroberto sys_jitter = LOGTOD(sys_precision); 318954359Sroberto sys_rootdelay = 0; 3190182007Sroberto sys_orphandelay = (double)(ntp_random() & 0xffff) / 65536. * 3191182007Sroberto sys_maxdist; 319254359Sroberto sys_rootdispersion = 0; 319354359Sroberto L_CLR(&sys_reftime); 319482505Sroberto sys_peer = NULL; 319582505Sroberto sys_survivors = 0; 319654359Sroberto get_systime(&dummy); 3197132454Sroberto sys_manycastserver = 0; 319854359Sroberto sys_bclient = 0; 319954359Sroberto sys_bdelay = DEFBROADDELAY; 3200132454Sroberto sys_calldelay = BURST_DELAY; 320154359Sroberto sys_authenticate = 1; 320254359Sroberto L_CLR(&sys_authdelay); 320354359Sroberto sys_authdly[0] = sys_authdly[1] = 0; 320454359Sroberto sys_stattime = 0; 3205132454Sroberto proto_clr_stats(); 3206132454Sroberto for (i = 0; i < MAX_TTL; i++) { 3207132454Sroberto sys_ttl[i] = (u_char)((i * 256) / MAX_TTL); 3208132454Sroberto sys_ttlmax = i; 3209132454Sroberto } 3210132454Sroberto#ifdef OPENSSL 321154359Sroberto sys_automax = 1 << NTP_AUTOMAX; 3212132454Sroberto#endif /* OPENSSL */ 321354359Sroberto 321454359Sroberto /* 321554359Sroberto * Default these to enable 321654359Sroberto */ 321754359Sroberto ntp_enable = 1; 321854359Sroberto#ifndef KERNEL_FLL_BUG 321954359Sroberto kern_enable = 1; 322054359Sroberto#endif 322182505Sroberto pps_enable = 0; 322254359Sroberto stats_control = 1; 322354359Sroberto} 322454359Sroberto 322554359Sroberto 322654359Sroberto/* 322754359Sroberto * proto_config - configure the protocol module 322854359Sroberto */ 322954359Srobertovoid 323054359Srobertoproto_config( 3231132454Sroberto int item, 3232132454Sroberto u_long value, 3233132454Sroberto double dvalue, 3234132454Sroberto struct sockaddr_storage* svalue 323554359Sroberto ) 323654359Sroberto{ 323754359Sroberto /* 323854359Sroberto * Figure out what he wants to change, then do it 323954359Sroberto */ 324054359Sroberto switch (item) { 3241132454Sroberto 3242132454Sroberto /* 3243132454Sroberto * Turn on/off kernel discipline. 3244132454Sroberto */ 324556749Sroberto case PROTO_KERNEL: 324654359Sroberto kern_enable = (int)value; 324754359Sroberto break; 324854359Sroberto 3249132454Sroberto /* 3250132454Sroberto * Turn on/off clock discipline. 3251132454Sroberto */ 325256749Sroberto case PROTO_NTP: 325354359Sroberto ntp_enable = (int)value; 325454359Sroberto break; 325554359Sroberto 3256132454Sroberto /* 3257132454Sroberto * Turn on/off monitoring. 3258132454Sroberto */ 325956749Sroberto case PROTO_MONITOR: 326054359Sroberto if (value) 326154359Sroberto mon_start(MON_ON); 326254359Sroberto else 326354359Sroberto mon_stop(MON_ON); 326454359Sroberto break; 326554359Sroberto 3266132454Sroberto /* 3267132454Sroberto * Turn on/off statistics. 3268132454Sroberto */ 326956749Sroberto case PROTO_FILEGEN: 327054359Sroberto stats_control = (int)value; 327154359Sroberto break; 327254359Sroberto 3273132454Sroberto /* 3274182007Sroberto * Turn on/off enable broadcasts. 3275132454Sroberto */ 327656749Sroberto case PROTO_BROADCLIENT: 327754359Sroberto sys_bclient = (int)value; 3278182007Sroberto if (sys_bclient == 0) 3279182007Sroberto io_unsetbclient(); 3280182007Sroberto else 328154359Sroberto io_setbclient(); 328254359Sroberto break; 328354359Sroberto 3284132454Sroberto /* 3285182007Sroberto * Turn on/off PPS discipline. 3286182007Sroberto */ 3287182007Sroberto case PROTO_PPS: 3288182007Sroberto pps_enable = (int)value; 3289182007Sroberto break; 3290182007Sroberto 3291182007Sroberto /* 3292132454Sroberto * Add muliticast group address. 3293132454Sroberto */ 329456749Sroberto case PROTO_MULTICAST_ADD: 3295132454Sroberto if (svalue) 3296132454Sroberto io_multicast_add(*svalue); 3297182007Sroberto sys_bclient = 1; 329854359Sroberto break; 329954359Sroberto 3300132454Sroberto /* 3301132454Sroberto * Delete multicast group address. 3302132454Sroberto */ 330356749Sroberto case PROTO_MULTICAST_DEL: 3304132454Sroberto if (svalue) 3305132454Sroberto io_multicast_del(*svalue); 330654359Sroberto break; 330754359Sroberto 3308132454Sroberto /* 3309132454Sroberto * Set default broadcast delay. 3310132454Sroberto */ 331156749Sroberto case PROTO_BROADDELAY: 331254359Sroberto sys_bdelay = dvalue; 331354359Sroberto break; 331454359Sroberto 3315132454Sroberto /* 3316132454Sroberto * Set modem call delay. 3317132454Sroberto */ 3318132454Sroberto case PROTO_CALLDELAY: 3319132454Sroberto sys_calldelay = (int)value; 3320132454Sroberto break; 3321132454Sroberto 3322132454Sroberto /* 3323182007Sroberto * Turn on/off authentication to mobilize ephemeral 3324182007Sroberto * associations. 3325132454Sroberto */ 332656749Sroberto case PROTO_AUTHENTICATE: 332754359Sroberto sys_authenticate = (int)value; 332854359Sroberto break; 332954359Sroberto 3330132454Sroberto /* 3331182007Sroberto * Set minimum number of survivors. 3332132454Sroberto */ 3333182007Sroberto case PROTO_MINCLOCK: 3334182007Sroberto sys_minclock = (int)dvalue; 333582505Sroberto break; 333682505Sroberto 3337132454Sroberto /* 3338182007Sroberto * Set maximum number of preemptable associations. 3339132454Sroberto */ 3340182007Sroberto case PROTO_MAXCLOCK: 3341182007Sroberto sys_maxclock = (int)dvalue; 3342132454Sroberto break; 3343132454Sroberto 3344132454Sroberto /* 3345182007Sroberto * Set minimum number of survivors. 3346132454Sroberto */ 3347132454Sroberto case PROTO_MINSANE: 3348132454Sroberto sys_minsane = (int)dvalue; 3349132454Sroberto break; 3350132454Sroberto 3351132454Sroberto /* 3352182007Sroberto * Set stratum floor. 3353132454Sroberto */ 3354132454Sroberto case PROTO_FLOOR: 3355132454Sroberto sys_floor = (int)dvalue; 3356132454Sroberto break; 3357132454Sroberto 3358132454Sroberto /* 3359182007Sroberto * Set stratum ceiling. 3360132454Sroberto */ 3361132454Sroberto case PROTO_CEILING: 3362132454Sroberto sys_ceiling = (int)dvalue; 3363132454Sroberto break; 3364132454Sroberto 3365132454Sroberto /* 3366182007Sroberto * Set orphan stratum. 3367132454Sroberto */ 3368182007Sroberto case PROTO_ORPHAN: 3369182007Sroberto sys_orphan = (int)dvalue; 3370182007Sroberto break; 3371182007Sroberto 3372182007Sroberto /* 3373182007Sroberto * Set cohort switch. 3374182007Sroberto */ 3375132454Sroberto case PROTO_COHORT: 3376182007Sroberto sys_cohort = (int)dvalue; 3377132454Sroberto break; 3378182007Sroberto 3379132454Sroberto /* 3380182007Sroberto * Set minimum dispersion increment. 3381132454Sroberto */ 3382182007Sroberto case PROTO_MINDISP: 3383182007Sroberto sys_mindisp = dvalue; 3384182007Sroberto break; 3385182007Sroberto 3386182007Sroberto /* 3387182007Sroberto * Set maximum distance (select threshold). 3388182007Sroberto */ 3389182007Sroberto case PROTO_MAXDIST: 3390182007Sroberto sys_maxdist = dvalue; 3391182007Sroberto break; 3392182007Sroberto 3393182007Sroberto /* 3394182007Sroberto * Set anticlockhop threshold. 3395182007Sroberto */ 3396182007Sroberto case PROTO_MAXHOP: 3397182007Sroberto sys_maxhop = (int)dvalue; 3398182007Sroberto break; 3399182007Sroberto 3400182007Sroberto /* 3401182007Sroberto * Set adjtime() resolution (s). 3402182007Sroberto */ 3403132454Sroberto case PROTO_ADJ: 3404132454Sroberto sys_tick = dvalue; 3405132454Sroberto break; 3406132454Sroberto 3407182007Sroberto /* 3408182007Sroberto * Set manycast beacon interval. 3409182007Sroberto */ 3410182007Sroberto case PROTO_BEACON: 3411182007Sroberto sys_beacon = (int)dvalue; 3412182007Sroberto break; 3413182007Sroberto 341482505Sroberto#ifdef REFCLOCK 3415132454Sroberto /* 3416132454Sroberto * Turn on/off refclock calibrate 3417132454Sroberto */ 341882505Sroberto case PROTO_CAL: 341982505Sroberto cal_enable = (int)value; 342082505Sroberto break; 3421182007Sroberto#endif /* REFCLOCK */ 342256749Sroberto default: 342356749Sroberto 342454359Sroberto /* 3425132454Sroberto * Log this error. 342654359Sroberto */ 3427132454Sroberto msyslog(LOG_INFO, 3428182007Sroberto "proto_config: illegal item %d, value %ld", item, 3429182007Sroberto value); 343054359Sroberto } 343154359Sroberto} 343254359Sroberto 343354359Sroberto 343454359Sroberto/* 343554359Sroberto * proto_clr_stats - clear protocol stat counters 343654359Sroberto */ 343754359Srobertovoid 343854359Srobertoproto_clr_stats(void) 343954359Sroberto{ 3440132454Sroberto sys_stattime = current_time; 3441132454Sroberto sys_received = 0; 3442132454Sroberto sys_processed = 0; 3443132454Sroberto sys_newversionpkt = 0; 344454359Sroberto sys_oldversionpkt = 0; 344554359Sroberto sys_unknownversion = 0; 3446132454Sroberto sys_restricted = 0; 344754359Sroberto sys_badlength = 0; 344854359Sroberto sys_badauth = 0; 344954359Sroberto sys_limitrejected = 0; 345054359Sroberto} 3451