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++; 652276158Sdes return; 653132454Sroberto } else { 654182007Sroberto is_authentic = AUTH_OK; 655132454Sroberto } 656132454Sroberto#ifdef OPENSSL 65782505Sroberto if (skeyid > NTP_MAXKEY) 65882505Sroberto authtrust(skeyid, 0); 659132454Sroberto#endif /* OPENSSL */ 66054359Sroberto#ifdef DEBUG 66154359Sroberto if (debug) 66254359Sroberto printf( 66382505Sroberto "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n", 664132454Sroberto current_time, stoa(dstadr_sin), 665132454Sroberto stoa(&rbufp->recv_srcadr), hismode, retcode, 666182007Sroberto skeyid, authlen, has_mac, is_authentic); 66754359Sroberto#endif 66854359Sroberto } 66954359Sroberto 67054359Sroberto /* 67182505Sroberto * The association matching rules are implemented by a set of 672182007Sroberto * routines and an association table. A packet matching an 673182007Sroberto * association is processed by the peer process for that 674182007Sroberto * association. If there are no errors, an ephemeral association 675182007Sroberto * is mobilized: a broadcast packet mobilizes a broadcast client 676132454Sroberto * aassociation; a manycast server packet mobilizes a manycast 677132454Sroberto * client association; a symmetric active packet mobilizes a 678182007Sroberto * symmetric passive association. 67954359Sroberto */ 68054359Sroberto switch (retcode) { 681182007Sroberto 682182007Sroberto /* 683182007Sroberto * This is a client mode packet not matching any association. If 684182007Sroberto * an ordinary client, simply toss a server mode packet back 685182007Sroberto * over the fence. If a manycast client, we have to work a 686182007Sroberto * little harder. 687182007Sroberto */ 68854359Sroberto case AM_FXMIT: 68954359Sroberto 69056749Sroberto /* 691182007Sroberto * The vanilla case is when this is not a multicast 692182007Sroberto * interface. If authentication succeeds, return a 693182007Sroberto * server mode packet; if not and the key ID is nonzero, 694182007Sroberto * return a crypto-NAK. 69556749Sroberto */ 696182007Sroberto if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) { 697182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, 698182007Sroberto is_authentic)) 699182007Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 700182007Sroberto restrict_mask); 701182007Sroberto else if (is_authentic == AUTH_ERROR) 702182007Sroberto fast_xmit(rbufp, MODE_SERVER, 0, 703182007Sroberto restrict_mask); 704182007Sroberto return; /* hooray */ 70556749Sroberto } 70654359Sroberto 70756749Sroberto /* 708182007Sroberto * This must be manycast. Do not respond if not 709182007Sroberto * configured as a manycast server. 71056749Sroberto */ 711182007Sroberto if (!sys_manycastserver) { 712182007Sroberto sys_restricted++; 713182007Sroberto return; /* not enabled */ 714182007Sroberto } 715182007Sroberto 716182007Sroberto /* 717182007Sroberto * Do not respond if unsynchronized or stratum is below 718182007Sroberto * the floor or at or above the ceiling. 719182007Sroberto */ 720182007Sroberto if (sys_leap == LEAP_NOTINSYNC || sys_stratum < 721182007Sroberto sys_floor || sys_stratum >= sys_ceiling) 722182007Sroberto return; /* bad stratum */ 723182007Sroberto 724182007Sroberto /* 725182007Sroberto * Do not respond if our stratum is greater than the 726182007Sroberto * manycaster or it has already synchronized to us. 727182007Sroberto */ 728182007Sroberto if (sys_peer == NULL || hisstratum < sys_stratum || 729182007Sroberto (sys_cohort && hisstratum == sys_stratum) || 730182007Sroberto rbufp->dstadr->addr_refid == pkt->refid) 731182007Sroberto return; /* no help */ 732182007Sroberto 733182007Sroberto /* 734182007Sroberto * Respond only if authentication succeeds. Don't do a 735182007Sroberto * crypto-NAK, as that would not be useful. 736182007Sroberto */ 737182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) 73882505Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 73982505Sroberto restrict_mask); 74056749Sroberto 741182007Sroberto return; /* hooray */ 742182007Sroberto 743182007Sroberto /* 744182007Sroberto * This is a server mode packet returned in response to a client 745182007Sroberto * mode packet sent to a multicast group address. The origin 746182007Sroberto * timestamp is a good nonce to reliably associate the reply 747182007Sroberto * with what was sent. If there is no match, that's curious and 748182007Sroberto * could be an intruder attempting to clog, so we just ignore 749182007Sroberto * it. 750182007Sroberto * 751182007Sroberto * If the packet is authentic and the manycast association is 752182007Sroberto * found, we mobilize a client association and copy pertinent 753182007Sroberto * variables from the manycast association to the new client 754182007Sroberto * association. If not, just ignore the packet. 755182007Sroberto * 756182007Sroberto * There is an implosion hazard at the manycast client, since 757182007Sroberto * the manycast servers send the server packet immediately. If 758182007Sroberto * the guy is already here, don't fire up a duplicate. 759182007Sroberto */ 76054359Sroberto case AM_MANYCAST: 761182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 762182007Sroberto (RES_NOPEER | RES_DONTTRUST)), is_authentic)) 763182007Sroberto return; /* bad auth */ 76454359Sroberto 765182007Sroberto if ((peer2 = findmanycastpeer(rbufp)) == NULL) { 766132454Sroberto sys_restricted++; 767182007Sroberto return; /* not enabled */ 768132454Sroberto } 769182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 770182007Sroberto rbufp->dstadr, MODE_CLIENT, 771182007Sroberto hisversion, NTP_MINDPOLL, NTP_MAXDPOLL, 772182007Sroberto FLAG_IBURST | FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT, 773182007Sroberto 0, skeyid)) == NULL) 774132454Sroberto return; /* system error */ 775132454Sroberto 776132454Sroberto /* 777132454Sroberto * We don't need these, but it warms the billboards. 778132454Sroberto */ 779132454Sroberto peer->ttl = peer2->ttl; 78056749Sroberto break; 78156749Sroberto 782182007Sroberto /* 783182007Sroberto * This is the first packet received from a broadcast server. If 784182007Sroberto * the packet is authentic and we are enabled as broadcast 785182007Sroberto * client, mobilize a broadcast client association. We don't 786182007Sroberto * kiss any frogs here. 787182007Sroberto */ 788182007Sroberto case AM_NEWBCL: 789182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 790182007Sroberto (RES_NOPEER | RES_DONTTRUST)), is_authentic)) 791182007Sroberto return; /* bad auth */ 79254359Sroberto 79356749Sroberto /* 794182007Sroberto * Do not respond if unsynchronized or stratum is below 795182007Sroberto * the floor or at or above the ceiling. 79656749Sroberto */ 797182007Sroberto if (hisleap == LEAP_NOTINSYNC || hisstratum < 798182007Sroberto sys_floor || hisstratum >= sys_ceiling) 799182007Sroberto return; /* bad stratum */ 800132454Sroberto 801182007Sroberto switch (sys_bclient) { 80256749Sroberto 80356749Sroberto /* 804182007Sroberto * If not enabled, just skedaddle. 80556749Sroberto */ 806182007Sroberto case 0: 807132454Sroberto sys_restricted++; 808182007Sroberto return; /* not enabled */ 80982505Sroberto 810132454Sroberto /* 811182007Sroberto * Execute the initial volley in order to calibrate the 812182007Sroberto * propagation delay and run the Autokey protocol, if 813182007Sroberto * enabled. 814132454Sroberto */ 815182007Sroberto case 1: 816182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 817182007Sroberto rbufp->dstadr, MODE_CLIENT, hisversion, 818182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST | 819182007Sroberto FLAG_IBURST, MDF_BCLNT, 0, skeyid)) == 820182007Sroberto NULL) 821182007Sroberto return; /* system error */ 822182007Sroberto#ifdef OPENSSL 823182007Sroberto if (skeyid > NTP_MAXKEY) 824182007Sroberto crypto_recv(peer, rbufp); 825132454Sroberto#endif /* OPENSSL */ 826182007Sroberto return; /* hooray */ 82756749Sroberto 828132454Sroberto 829132454Sroberto /* 830182007Sroberto * Do not execute the initial volley. 83156749Sroberto */ 832182007Sroberto case 2: 833182007Sroberto#ifdef OPENSSL 834182007Sroberto /* 835182007Sroberto * If a two-way exchange is not possible, 836182007Sroberto * neither is Autokey. 837182007Sroberto */ 838182007Sroberto if (skeyid > NTP_MAXKEY) { 839182007Sroberto msyslog(LOG_INFO, 840182007Sroberto "receive: autokey requires two-way communication"); 841182007Sroberto return; /* no autokey */ 842182007Sroberto } 843182007Sroberto#endif /* OPENSSL */ 844182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 845182007Sroberto rbufp->dstadr, MODE_BCLIENT, hisversion, 846182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0, 847182007Sroberto skeyid)) == NULL) 848182007Sroberto return; /* system error */ 849132454Sroberto } 85056749Sroberto break; 85156749Sroberto 852182007Sroberto /* 853182007Sroberto * This is the first packet received from a symmetric active 854182007Sroberto * peer. If the packet is authentic and the first he sent, 855182007Sroberto * mobilize a passive association. If not, kiss the frog. 856182007Sroberto */ 857182007Sroberto case AM_NEWPASS: 85856749Sroberto 85956749Sroberto /* 860182007Sroberto * If the inbound packet is correctly authenticated and 861182007Sroberto * enabled, a symmetric passive association is 862182007Sroberto * mobilized. If not but correctly authenticated, a 863182007Sroberto * symmetric active response is sent. If authentication 864182007Sroberto * fails, send a crypto-NAK packet. 86556749Sroberto */ 866182007Sroberto if (!AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) 867182007Sroberto { 868182007Sroberto if (is_authentic == AUTH_ERROR) 869182007Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, 870182007Sroberto restrict_mask); 871182007Sroberto return; /* bad auth */ 872182007Sroberto } 873182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 874182007Sroberto RES_NOPEER), is_authentic)) { 875182007Sroberto fast_xmit(rbufp, MODE_ACTIVE, skeyid, 876182007Sroberto restrict_mask); 877182007Sroberto return; /* hooray */ 878182007Sroberto } 87954359Sroberto 880182007Sroberto /* 881182007Sroberto * Do not respond if stratum is below the floor. 882182007Sroberto */ 883182007Sroberto if (hisstratum < sys_floor) 884182007Sroberto return; /* bad stratum */ 885182007Sroberto 886182007Sroberto if ((peer = newpeer(&rbufp->recv_srcadr, 887182007Sroberto rbufp->dstadr, MODE_PASSIVE, hisversion, 888182007Sroberto NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0, 889182007Sroberto skeyid)) == NULL) 890182007Sroberto return; /* system error */ 891182007Sroberto break; 892182007Sroberto 89354359Sroberto /* 894182007Sroberto * Process regular packet. Nothing special. 89554359Sroberto */ 896182007Sroberto case AM_PROCPKT: 897182007Sroberto break; 89854359Sroberto 89954359Sroberto /* 900182007Sroberto * A passive packet matches a passive association. This is 901182007Sroberto * usually the result of reconfiguring a client on the fly. As 902182007Sroberto * this association might be legitamate and this packet an 903182007Sroberto * attempt to deny service, just ignore it. 90454359Sroberto */ 905182007Sroberto case AM_ERR: 906182007Sroberto return; 907132454Sroberto 908132454Sroberto /* 909182007Sroberto * For everything else there is the bit bucket. 910132454Sroberto */ 911182007Sroberto default: 912182007Sroberto return; 913182007Sroberto } 914182007Sroberto peer->flash &= ~PKT_TEST_MASK; 915132454Sroberto 916132454Sroberto /* 917182007Sroberto * Next comes a rigorous schedule of timestamp checking. If the 918182007Sroberto * transmit timestamp is zero, the server is horribly broken. 919132454Sroberto */ 920182007Sroberto if (L_ISZERO(&p_xmt)) { 921182007Sroberto return; /* read rfc1305 */ 922132454Sroberto 923132454Sroberto /* 924182007Sroberto * If the transmit timestamp duplicates a previous one, the 925182007Sroberto * packet is a replay. This prevents the bad guys from replaying 926182007Sroberto * the most recent packet, authenticated or not. 927132454Sroberto */ 928182007Sroberto } else if (L_ISEQU(&peer->org, &p_xmt)) { 929182007Sroberto peer->flash |= TEST1; 930182007Sroberto peer->oldpkt++; 931182007Sroberto return; /* duplicate packet */ 932182007Sroberto 933132454Sroberto 934132454Sroberto /* 935182007Sroberto * If this is a broadcast mode packet, skip further checking. 936132454Sroberto */ 937182007Sroberto } else if (hismode != MODE_BROADCAST) { 938182007Sroberto if (L_ISZERO(&p_org)) 939182007Sroberto peer->flash |= TEST3; /* protocol unsynch */ 940182007Sroberto else if (!L_ISEQU(&p_org, &peer->xmt)) 941182007Sroberto peer->flash |= TEST2; /* bogus packet */ 942182007Sroberto } 943132454Sroberto 944132454Sroberto /* 945182007Sroberto * Update the origin and destination timestamps. If 946182007Sroberto * unsynchronized or bogus abandon ship. If the crypto machine 947182007Sroberto * breaks, light the crypto bit and plaint the log. 948132454Sroberto */ 949182007Sroberto peer->org = p_xmt; 950182007Sroberto peer->rec = rbufp->recv_time; 951182007Sroberto if (peer->flash & PKT_TEST_MASK) { 952182007Sroberto#ifdef OPENSSL 953182007Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 954182007Sroberto rval = crypto_recv(peer, rbufp); 955182007Sroberto if (rval != XEVNT_OK) { 956182007Sroberto peer_clear(peer, "CRYP"); 957182007Sroberto peer->flash |= TEST9; /* crypto error */ 958182007Sroberto } 959182007Sroberto } 960182007Sroberto#endif /* OPENSSL */ 961182007Sroberto return; /* unsynch */ 962182007Sroberto } 963132454Sroberto 964132454Sroberto /* 965182007Sroberto * The timestamps are valid and the receive packet matches the 966182007Sroberto * last one sent. If the packet is a crypto-NAK, the server 967182007Sroberto * might have just changed keys. We reset the association 968182007Sroberto * and restart the protocol. 969132454Sroberto */ 970182007Sroberto if (is_authentic == AUTH_CRYPTO) { 971182007Sroberto peer_clear(peer, "AUTH"); 972182007Sroberto return; /* crypto-NAK */ 973182007Sroberto 974182007Sroberto /* 975182007Sroberto * If the association is authenticated, the key ID is nonzero 976182007Sroberto * and received packets must be authenticated. This is designed 977182007Sroberto * to avoid a bait-and-switch attack, which was possible in past 978182007Sroberto * versions. If symmetric modes, return a crypto-NAK. The peer 979182007Sroberto * should restart the protocol. 980182007Sroberto */ 981182007Sroberto } else if (!AUTH(peer->keyid || (restrict_mask & RES_DONTTRUST), 982182007Sroberto is_authentic)) { 983182007Sroberto peer->flash |= TEST5; 984182007Sroberto if (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE) 985132454Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask); 986182007Sroberto return; /* bad auth */ 98754359Sroberto } 98854359Sroberto 989182007Sroberto /* 990182007Sroberto * That was hard and I am sweaty, but the packet is squeaky 991182007Sroberto * clean. Get on with real work. 992182007Sroberto */ 993182007Sroberto peer->received++; 994182007Sroberto peer->timereceived = current_time; 995182007Sroberto if (is_authentic == AUTH_OK) 996182007Sroberto peer->flags |= FLAG_AUTHENTIC; 997182007Sroberto else 998182007Sroberto peer->flags &= ~FLAG_AUTHENTIC; 999132454Sroberto#ifdef OPENSSL 100054359Sroberto /* 100182505Sroberto * More autokey dance. The rules of the cha-cha are as follows: 100282505Sroberto * 100382505Sroberto * 1. If there is no key or the key is not auto, do nothing. 100482505Sroberto * 1005132454Sroberto * 2. If this packet is in response to the one just previously 1006132454Sroberto * sent or from a broadcast server, do the extension fields. 1007132454Sroberto * Otherwise, assume bogosity and bail out. 1008132454Sroberto * 1009132454Sroberto * 3. If an extension field contains a verified signature, it is 101082505Sroberto * self-authenticated and we sit the dance. 101182505Sroberto * 1012132454Sroberto * 4. If this is a server reply, check only to see that the 101382505Sroberto * transmitted key ID matches the received key ID. 101482505Sroberto * 1015132454Sroberto * 5. Check to see that one or more hashes of the current key ID 101682505Sroberto * matches the previous key ID or ultimate original key ID 101782505Sroberto * obtained from the broadcaster or symmetric peer. If no 101882505Sroberto * match, sit the dance and wait for timeout. 1019182007Sroberto * 1020182007Sroberto * In case of crypto error, fire the orchestra and stop dancing. 1021182007Sroberto * This is considered a permanant error, so light the crypto bit 1022182007Sroberto * to suppress further requests. If preemptable or ephemeral, 1023182007Sroberto * scuttle the ship. 102454359Sroberto */ 1025132454Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 1026182007Sroberto peer->flash |= TEST8; 1027132454Sroberto rval = crypto_recv(peer, rbufp); 1028132454Sroberto if (rval != XEVNT_OK) { 1029182007Sroberto peer_clear(peer, "CRYP"); 1030182007Sroberto peer->flash |= TEST9; /* crypto error */ 1031182007Sroberto if (peer->flags & FLAG_PREEMPT || 1032182007Sroberto !(peer->flags & FLAG_CONFIG)) 1033182007Sroberto unpeer(peer); 1034182007Sroberto return; 1035132454Sroberto 1036132454Sroberto } else if (hismode == MODE_SERVER) { 103782505Sroberto if (skeyid == peer->keyid) 1038182007Sroberto peer->flash &= ~TEST8; 1039182007Sroberto } else if (!(peer->flash & TEST8)) { 104082505Sroberto peer->pkeyid = skeyid; 1041132454Sroberto } else if ((ap = (struct autokey *)peer->recval.ptr) != 1042132454Sroberto NULL) { 104382505Sroberto int i; 104482505Sroberto 104582505Sroberto for (i = 0; ; i++) { 104682505Sroberto if (tkeyid == peer->pkeyid || 1047132454Sroberto tkeyid == ap->key) { 1048182007Sroberto peer->flash &= ~TEST8; 104982505Sroberto peer->pkeyid = skeyid; 105082505Sroberto break; 105182505Sroberto } 1052132454Sroberto if (i > ap->seq) 105382505Sroberto break; 105454359Sroberto tkeyid = session_key( 105582505Sroberto &rbufp->recv_srcadr, dstadr_sin, 105682505Sroberto tkeyid, pkeyid, 0); 105754359Sroberto } 105854359Sroberto } 1059182007Sroberto if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */ 1060182007Sroberto peer->flash |= TEST8; /* not proventic */ 106182505Sroberto 106282505Sroberto /* 1063132454Sroberto * If the transmit queue is nonempty, clamp the host 1064132454Sroberto * poll interval to the packet poll interval. 106582505Sroberto */ 1066132454Sroberto if (peer->cmmd != 0) { 1067132454Sroberto peer->ppoll = pkt->ppoll; 1068182007Sroberto poll_update(peer, peer->hpoll); 1069132454Sroberto } 107054359Sroberto } 1071132454Sroberto#endif /* OPENSSL */ 107254359Sroberto 107354359Sroberto /* 1074182007Sroberto * The dance is complete and the flash bits have been lit. Toss 1075182007Sroberto * the packet over the fence for processing, which may light up 1076182007Sroberto * more flashers. 107754359Sroberto */ 1078182007Sroberto process_packet(peer, pkt); 1079182007Sroberto 1080182007Sroberto /* 1081182007Sroberto * Well, that was nice. If TEST4 is lit, either the crypto 1082182007Sroberto * machine jammed or a kiss-o'-death packet flew in, either of 1083182007Sroberto * which is fatal. 1084182007Sroberto */ 1085182007Sroberto if (peer->flash & TEST4) { 1086182007Sroberto msyslog(LOG_INFO, "receive: fatal error %04x for %s", 1087182007Sroberto peer->flash, stoa(&peer->srcadr)); 1088182007Sroberto return; 1089182007Sroberto } 109054359Sroberto} 109154359Sroberto 109254359Sroberto 109354359Sroberto/* 109454359Sroberto * process_packet - Packet Procedure, a la Section 3.4.4 of the 109554359Sroberto * specification. Or almost, at least. If we're in here we have a 109654359Sroberto * reasonable expectation that we will be having a long term 109754359Sroberto * relationship with this host. 109854359Sroberto */ 109982505Srobertovoid 110054359Srobertoprocess_packet( 110154359Sroberto register struct peer *peer, 1102182007Sroberto register struct pkt *pkt 110354359Sroberto ) 110454359Sroberto{ 1105182007Sroberto double t34, t21; 1106132454Sroberto double p_offset, p_del, p_disp; 1107132454Sroberto l_fp p_rec, p_xmt, p_org, p_reftime; 1108132454Sroberto l_fp ci; 1109132454Sroberto u_char pmode, pleap, pstratum; 111054359Sroberto 111154359Sroberto sys_processed++; 111254359Sroberto peer->processed++; 111354359Sroberto p_del = FPTOD(NTOHS_FP(pkt->rootdelay)); 111454359Sroberto p_disp = FPTOD(NTOHS_FP(pkt->rootdispersion)); 111554359Sroberto NTOHL_FP(&pkt->reftime, &p_reftime); 111654359Sroberto NTOHL_FP(&pkt->rec, &p_rec); 111754359Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 1118132454Sroberto pmode = PKT_MODE(pkt->li_vn_mode); 1119132454Sroberto pleap = PKT_LEAP(pkt->li_vn_mode); 1120132454Sroberto if (pmode != MODE_BROADCAST) 112154359Sroberto NTOHL_FP(&pkt->org, &p_org); 112254359Sroberto else 112354359Sroberto p_org = peer->rec; 1124132454Sroberto pstratum = PKT_TO_STRATUM(pkt->stratum); 112554359Sroberto 112654359Sroberto /* 1127182007Sroberto * Test for kiss-o'death packet) 112854359Sroberto */ 1129182007Sroberto if (pleap == LEAP_NOTINSYNC && pstratum == STRATUM_UNSPEC) { 1130182007Sroberto if (memcmp(&pkt->refid, "DENY", 4) == 0) { 1131182007Sroberto peer_clear(peer, "DENY"); 1132182007Sroberto peer->flash |= TEST4; /* access denied */ 1133182007Sroberto } 1134182007Sroberto } 113554359Sroberto 113654359Sroberto /* 1137182007Sroberto * Capture the header values. 113854359Sroberto */ 1139182007Sroberto record_raw_stats(&peer->srcadr, peer->dstadr ? &peer->dstadr->sin : NULL, &p_org, 1140182007Sroberto &p_rec, &p_xmt, &peer->rec); 1141132454Sroberto peer->leap = pleap; 1142182007Sroberto peer->stratum = min(pstratum, STRATUM_UNSPEC); 1143182007Sroberto peer->pmode = pmode; 1144182007Sroberto peer->ppoll = pkt->ppoll; 1145182007Sroberto peer->precision = pkt->precision; 1146182007Sroberto peer->rootdelay = p_del; 1147182007Sroberto peer->rootdispersion = p_disp; 1148182007Sroberto peer->refid = pkt->refid; /* network byte order */ 1149182007Sroberto peer->reftime = p_reftime; 115082505Sroberto 115182505Sroberto /* 1152182007Sroberto * Verify the server is synchronized; that is, the leap bits and 1153182007Sroberto * stratum are valid, the root delay and root dispersion are 1154182007Sroberto * valid and the reference timestamp is not later than the 1155182007Sroberto * transmit timestamp. 115682505Sroberto */ 1157132454Sroberto if (pleap == LEAP_NOTINSYNC || /* test 6 */ 1158182007Sroberto pstratum < sys_floor || pstratum >= sys_ceiling) 1159182007Sroberto peer->flash |= TEST6; /* peer not synch */ 1160182007Sroberto if (p_del < 0 || p_disp < 0 || p_del / /* test 7 */ 1161182007Sroberto 2 + p_disp >= MAXDISPERSE || !L_ISHIS(&p_xmt, &p_reftime)) 1162182007Sroberto peer->flash |= TEST7; /* bad header */ 1163132454Sroberto 1164132454Sroberto /* 1165132454Sroberto * If any tests fail at this point, the packet is discarded. 1166182007Sroberto * Note that some flashers may have already been set in the 1167182007Sroberto * receive() routine. 1168132454Sroberto */ 1169182007Sroberto if (peer->flash & PKT_TEST_MASK) { 117054359Sroberto#ifdef DEBUG 117154359Sroberto if (debug) 1172182007Sroberto printf("packet: flash header %04x\n", 117382505Sroberto peer->flash); 117454359Sroberto#endif 117582505Sroberto return; 117654359Sroberto } 117782505Sroberto if (!(peer->reach)) { 117854359Sroberto report_event(EVNT_REACH, peer); 117954359Sroberto peer->timereachable = current_time; 118054359Sroberto } 1181182007Sroberto poll_update(peer, peer->hpoll); 118254359Sroberto peer->reach |= 1; 118354359Sroberto 118454359Sroberto /* 1185182007Sroberto * For a client/server association, calculate the clock offset, 1186182007Sroberto * roundtrip delay and dispersion. The equations are reordered 1187182007Sroberto * from the spec for more efficient use of temporaries. For a 1188182007Sroberto * broadcast association, offset the last measurement by the 1189182007Sroberto * computed delay during the client/server volley. Note that 1190182007Sroberto * org has been set to the time of last reception. Note the 1191182007Sroberto * computation of dispersion includes the system precision plus 1192182007Sroberto * that due to the frequency error since the origin time. 119354359Sroberto * 1194182007Sroberto * It is very important to respect the hazards of overflow. The 1195182007Sroberto * only permitted operation on raw timestamps is subtraction, 1196182007Sroberto * where the result is a signed quantity spanning from 68 years 1197182007Sroberto * in the past to 68 years in the future. To avoid loss of 1198182007Sroberto * precision, these calculations are done using 64-bit integer 1199182007Sroberto * arithmetic. However, the offset and delay calculations are 1200182007Sroberto * sums and differences of these first-order differences, which 1201182007Sroberto * if done using 64-bit integer arithmetic, would be valid over 1202182007Sroberto * only half that span. Since the typical first-order 1203182007Sroberto * differences are usually very small, they are converted to 64- 1204182007Sroberto * bit doubles and all remaining calculations done in floating- 1205182007Sroberto * point arithmetic. This preserves the accuracy while retaining 1206182007Sroberto * the 68-year span. 1207182007Sroberto * 1208132454Sroberto * Let t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->rec: 120954359Sroberto */ 1210182007Sroberto ci = p_xmt; /* t3 - t4 */ 1211182007Sroberto L_SUB(&ci, &peer->rec); 1212182007Sroberto LFPTOD(&ci, t34); 1213182007Sroberto ci = p_rec; /* t2 - t1 */ 1214182007Sroberto L_SUB(&ci, &p_org); 1215182007Sroberto LFPTOD(&ci, t21); 1216132454Sroberto ci = peer->rec; /* t4 - t1 */ 1217132454Sroberto L_SUB(&ci, &p_org); 121854359Sroberto 121954359Sroberto /* 122056749Sroberto * If running in a broadcast association, the clock offset is 122156749Sroberto * (t1 - t0) corrected by the one-way delay, but we can't 122282505Sroberto * measure that directly. Therefore, we start up in MODE_CLIENT 122382505Sroberto * mode, set FLAG_MCAST and exchange eight messages to determine 122482505Sroberto * the clock offset. When the last message is sent, we switch to 122582505Sroberto * MODE_BCLIENT mode. The next broadcast message after that 122682505Sroberto * computes the broadcast offset and clears FLAG_MCAST. 122754359Sroberto */ 122854359Sroberto if (pmode == MODE_BROADCAST) { 1229182007Sroberto p_offset = t34; 123082505Sroberto if (peer->flags & FLAG_MCAST) { 123154359Sroberto peer->estbdelay = peer->offset - p_offset; 123282505Sroberto if (peer->hmode == MODE_CLIENT) 123382505Sroberto return; 123454359Sroberto 1235182007Sroberto peer->flags &= ~(FLAG_MCAST | FLAG_BURST); 123654359Sroberto } 1237182007Sroberto p_offset += peer->estbdelay; 123854359Sroberto p_del = peer->delay; 1239182007Sroberto p_disp = 0; 124054359Sroberto } else { 1241182007Sroberto p_offset = (t21 + t34) / 2.; 1242182007Sroberto p_del = t21 - t34; 1243182007Sroberto LFPTOD(&ci, p_disp); 1244182007Sroberto p_disp = LOGTOD(sys_precision) + 1245182007Sroberto LOGTOD(peer->precision) + clock_phi * p_disp; 124654359Sroberto } 124782505Sroberto p_del = max(p_del, LOGTOD(sys_precision)); 124882505Sroberto clock_filter(peer, p_offset, p_del, p_disp); 124954359Sroberto record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), 1250182007Sroberto peer->offset, peer->delay, peer->disp, peer->jitter); 125154359Sroberto} 125254359Sroberto 125354359Sroberto 125454359Sroberto/* 125554359Sroberto * clock_update - Called at system process update intervals. 125654359Sroberto */ 125754359Srobertostatic void 125854359Srobertoclock_update(void) 125954359Sroberto{ 1260182007Sroberto u_char oleap; 1261182007Sroberto u_char ostratum; 1262182007Sroberto double dtemp; 126354359Sroberto 126454359Sroberto /* 1265182007Sroberto * There must be a system peer at this point. If we just changed 1266182007Sroberto * the system peer, but have a newer sample from the old one, 1267182007Sroberto * wait until newer data are available. 126854359Sroberto */ 1269182007Sroberto if (sys_poll < sys_peer->minpoll) 1270182007Sroberto sys_poll = sys_peer->minpoll; 1271182007Sroberto if (sys_poll > sys_peer->maxpoll) 1272182007Sroberto sys_poll = sys_peer->maxpoll; 1273182007Sroberto poll_update(sys_peer, sys_poll); 1274182007Sroberto if (sys_peer->epoch <= sys_clocktime) 127554359Sroberto return; 1276182007Sroberto 127754359Sroberto#ifdef DEBUG 127854359Sroberto if (debug) 127954359Sroberto printf("clock_update: at %ld assoc %d \n", current_time, 128054359Sroberto peer_associations); 128154359Sroberto#endif 128254359Sroberto oleap = sys_leap; 128354359Sroberto ostratum = sys_stratum; 1284182007Sroberto switch (local_clock(sys_peer, sys_offset)) { 128554359Sroberto 128682505Sroberto /* 1287182007Sroberto * Clock exceeds panic threshold. Life as we know it ends. 128882505Sroberto */ 128982505Sroberto case -1: 1290132454Sroberto report_event(EVNT_SYSFAULT, NULL); 1291132454Sroberto exit (-1); 1292182007Sroberto /* not reached */ 129354359Sroberto 129482505Sroberto /* 129582505Sroberto * Clock was stepped. Flush all time values of all peers. 129682505Sroberto */ 1297182007Sroberto case 2: 129882505Sroberto clear_all(); 1299182007Sroberto sys_leap = LEAP_NOTINSYNC; 1300182007Sroberto sys_stratum = STRATUM_UNSPEC; 130182505Sroberto sys_peer = NULL; 1302182007Sroberto sys_rootdelay = 0; 1303182007Sroberto sys_rootdispersion = 0; 1304182007Sroberto memcpy(&sys_refid, "STEP", 4); 1305132454Sroberto report_event(EVNT_CLOCKRESET, NULL); 130654359Sroberto break; 130754359Sroberto 130882505Sroberto /* 1309182007Sroberto * Clock was slewed. Update the system stratum, leap bits, root 1310182007Sroberto * delay, root dispersion, reference ID and reference time. If 1311182007Sroberto * the leap changes, we gotta reroll the keys. Except for 1312182007Sroberto * reference clocks, the minimum dispersion increment is not 1313182007Sroberto * less than sys_mindisp. 131482505Sroberto */ 1315182007Sroberto case 1: 1316182007Sroberto sys_leap = leap_next; 1317182007Sroberto sys_stratum = min(sys_peer->stratum + 1, 1318182007Sroberto STRATUM_UNSPEC); 131954359Sroberto sys_reftime = sys_peer->rec; 1320182007Sroberto 1321182007Sroberto /* 1322182007Sroberto * In orphan mode the stratum defaults to the orphan 1323182007Sroberto * stratum. The root delay is set to a random value 1324182007Sroberto * generated at startup. The root dispersion is set from 1325182007Sroberto * the peer dispersion; the peer root dispersion is 1326182007Sroberto * ignored. 1327182007Sroberto */ 1328182007Sroberto dtemp = sys_peer->disp + clock_phi * (current_time - 1329182007Sroberto sys_peer->update) + sys_jitter + 1330182007Sroberto fabs(sys_peer->offset); 1331182007Sroberto#ifdef REFCLOCK 1332182007Sroberto if (!(sys_peer->flags & FLAG_REFCLOCK) && dtemp < 1333182007Sroberto sys_mindisp) 1334182007Sroberto dtemp = sys_mindisp; 1335182007Sroberto#else 1336182007Sroberto if (dtemp < sys_mindisp) 1337182007Sroberto dtemp = sys_mindisp; 1338182007Sroberto#endif /* REFCLOCK */ 1339182007Sroberto if (sys_stratum >= sys_orphan) { 1340182007Sroberto sys_stratum = sys_orphan; 1341182007Sroberto sys_rootdelay = sys_peer->delay; 1342182007Sroberto sys_rootdispersion = dtemp; 1343182007Sroberto } else { 1344182007Sroberto sys_rootdelay = sys_peer->delay + 1345182007Sroberto sys_peer->rootdelay; 1346182007Sroberto sys_rootdispersion = dtemp + 1347182007Sroberto sys_peer->rootdispersion; 1348182007Sroberto } 1349132454Sroberto if (oleap == LEAP_NOTINSYNC) { 1350132454Sroberto report_event(EVNT_SYNCCHG, NULL); 1351132454Sroberto#ifdef OPENSSL 1352132454Sroberto expire_all(); 1353182007Sroberto crypto_update(); 1354132454Sroberto#endif /* OPENSSL */ 1355132454Sroberto } 1356182007Sroberto break; 1357182007Sroberto /* 1358182007Sroberto * Popcorn spike or step threshold exceeded. Pretend it never 1359182007Sroberto * happened. 1360182007Sroberto */ 1361182007Sroberto default: 1362182007Sroberto break; 136354359Sroberto } 136454359Sroberto if (ostratum != sys_stratum) 1365132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 136654359Sroberto} 136754359Sroberto 136854359Sroberto 136954359Sroberto/* 137082505Sroberto * poll_update - update peer poll interval 137154359Sroberto */ 137254359Srobertovoid 137354359Srobertopoll_update( 137454359Sroberto struct peer *peer, 1375182007Sroberto int mpoll 137654359Sroberto ) 137754359Sroberto{ 1378182007Sroberto int hpoll; 137954359Sroberto 138054359Sroberto /* 1381182007Sroberto * This routine figures out when the next poll should be sent. 1382182007Sroberto * That turns out to be wickedly complicated. The big problem is 1383182007Sroberto * that sometimes the time for the next poll is in the past. 1384182007Sroberto * Watch out for races here between the receive process and the 1385182007Sroberto * poll process. The key assertion is that, if nextdate equals 1386182007Sroberto * current_time, the call is from the poll process; otherwise, 1387182007Sroberto * it is from the receive process. 1388182007Sroberto * 1389182007Sroberto * First, bracket the poll interval according to the type of 1390182007Sroberto * association and options. If a fixed interval is configured, 1391182007Sroberto * use minpoll. This primarily is for reference clocks, but 1392182007Sroberto * works for any association. 139354359Sroberto */ 1394182007Sroberto if (peer->flags & FLAG_FIXPOLL) { 1395182007Sroberto hpoll = peer->minpoll; 1396182007Sroberto 1397182007Sroberto /* 1398182007Sroberto * The ordinary case; clamp the poll interval between minpoll 1399182007Sroberto * and maxpoll. 1400182007Sroberto */ 1401182007Sroberto } else { 1402182007Sroberto hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll); 1403182007Sroberto } 1404132454Sroberto#ifdef OPENSSL 1405182007Sroberto /* 1406182007Sroberto * Bit of crass arrogance at this point. If the poll interval 1407182007Sroberto * has changed and we have a keylist, the lifetimes in the 1408182007Sroberto * keylist are probably bogus. In this case purge the keylist 1409182007Sroberto * and regenerate it later. 1410182007Sroberto */ 1411182007Sroberto if (hpoll != peer->hpoll) 1412182007Sroberto key_expire(peer); 1413132454Sroberto#endif /* OPENSSL */ 1414182007Sroberto peer->hpoll = hpoll; 141582505Sroberto 141682505Sroberto /* 1417182007Sroberto * Now we figure out if there is an override. If during the 1418182007Sroberto * crypto protocol and a message is pending, make it wait not 1419182007Sroberto * more than two seconds. 142082505Sroberto */ 1421132454Sroberto#ifdef OPENSSL 1422132454Sroberto if (peer->cmmd != NULL && (sys_leap != LEAP_NOTINSYNC || 1423132454Sroberto peer->crypto)) { 1424132454Sroberto peer->nextdate = current_time + RESP_DELAY; 1425182007Sroberto 1426182007Sroberto /* 1427182007Sroberto * If we get called from the receive routine while a burst is 1428182007Sroberto * pending, just slink away. If from the poll routine and a 1429182007Sroberto * reference clock or a pending crypto response, delay for one 1430182007Sroberto * second. If this is the first sent in a burst, wait for the 1431182007Sroberto * modem to come up. For others in the burst, delay two seconds. 1432182007Sroberto */ 1433132454Sroberto } else if (peer->burst > 0) { 1434132454Sroberto#else /* OPENSSL */ 143554359Sroberto if (peer->burst > 0) { 1436132454Sroberto#endif /* OPENSSL */ 1437182007Sroberto if (peer->nextdate != current_time) 143854359Sroberto return; 143982505Sroberto#ifdef REFCLOCK 144082505Sroberto else if (peer->flags & FLAG_REFCLOCK) 1441132454Sroberto peer->nextdate += RESP_DELAY; 1442182007Sroberto#endif /* REFCLOCK */ 1443132454Sroberto else if (peer->flags & (FLAG_IBURST | FLAG_BURST) && 1444132454Sroberto peer->burst == NTP_BURST) 1445132454Sroberto peer->nextdate += sys_calldelay; 144654359Sroberto else 1447132454Sroberto peer->nextdate += BURST_DELAY; 1448182007Sroberto /* 1449182007Sroberto * The ordinary case; use the minimum of the host and peer 1450182007Sroberto * intervals, but not less than minpoll. In other words, 1451182007Sroberto * oversampling is okay but understampling is evil. 1452182007Sroberto */ 145354359Sroberto } else { 1454182007Sroberto peer->nextdate = peer->outdate + 1455182007Sroberto RANDPOLL(max(min(peer->ppoll, hpoll), 1456182007Sroberto peer->minpoll)); 145754359Sroberto } 1458182007Sroberto 145982505Sroberto /* 1460182007Sroberto * If the time for the next poll has already happened, bring it 1461182007Sroberto * up to the next second after this one. This way the only way 1462182007Sroberto * to get nexdate == current time is from the poll routine. 146382505Sroberto */ 1464182007Sroberto if (peer->nextdate <= current_time) 1465182007Sroberto peer->nextdate = current_time + 1; 146654359Sroberto#ifdef DEBUG 146754359Sroberto if (debug > 1) 146882505Sroberto printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n", 146982505Sroberto current_time, ntoa(&peer->srcadr), peer->flags, 1470182007Sroberto peer->hpoll, peer->burst, peer->outdate, 147182505Sroberto peer->nextdate); 147254359Sroberto#endif 147354359Sroberto} 147454359Sroberto 147554359Sroberto/* 1476182007Sroberto * peer_crypto_clear - discard crypto information 147754359Sroberto */ 147854359Srobertovoid 1479182007Srobertopeer_crypto_clear( 1480182007Sroberto struct peer *peer 1481182007Sroberto ) 148254359Sroberto{ 148382505Sroberto /* 148482505Sroberto * If cryptographic credentials have been acquired, toss them to 148582505Sroberto * Valhalla. Note that autokeys are ephemeral, in that they are 148682505Sroberto * tossed immediately upon use. Therefore, the keylist can be 148782505Sroberto * purged anytime without needing to preserve random keys. Note 148882505Sroberto * that, if the peer is purged, the cryptographic variables are 148982505Sroberto * purged, too. This makes it much harder to sneak in some 149082505Sroberto * unauthenticated data in the clock filter. 149182505Sroberto */ 1492182007Sroberto DPRINTF(1, ("peer_crypto_clear: at %ld next %ld assoc ID %d\n", 1493182007Sroberto current_time, peer->nextdate, peer->associd)); 1494182007Sroberto 1495132454Sroberto#ifdef OPENSSL 1496182007Sroberto peer->assoc = 0; 1497182007Sroberto peer->crypto = 0; 1498182007Sroberto 1499132454Sroberto if (peer->pkey != NULL) 1500132454Sroberto EVP_PKEY_free(peer->pkey); 1501182007Sroberto peer->pkey = NULL; 1502182007Sroberto 1503182007Sroberto peer->digest = NULL; /* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */ 1504182007Sroberto 1505132454Sroberto if (peer->subject != NULL) 1506132454Sroberto free(peer->subject); 1507182007Sroberto peer->subject = NULL; 1508182007Sroberto 1509132454Sroberto if (peer->issuer != NULL) 1510132454Sroberto free(peer->issuer); 1511182007Sroberto peer->issuer = NULL; 1512182007Sroberto 1513182007Sroberto peer->pkeyid = 0; 1514182007Sroberto 1515182007Sroberto peer->pcookie = 0; 1516182007Sroberto 1517182007Sroberto if (peer->ident_pkey != NULL) 1518182007Sroberto EVP_PKEY_free(peer->ident_pkey); 1519182007Sroberto peer->ident_pkey = NULL; 1520182007Sroberto 1521182007Sroberto memset(&peer->fstamp, 0, sizeof(peer->fstamp)); 1522182007Sroberto 1523132454Sroberto if (peer->iffval != NULL) 1524132454Sroberto BN_free(peer->iffval); 1525182007Sroberto peer->iffval = NULL; 1526182007Sroberto 1527132454Sroberto if (peer->grpkey != NULL) 1528132454Sroberto BN_free(peer->grpkey); 1529182007Sroberto peer->grpkey = NULL; 1530182007Sroberto 1531132454Sroberto value_free(&peer->cookval); 1532132454Sroberto value_free(&peer->recval); 1533182007Sroberto 1534182007Sroberto if (peer->cmmd != NULL) { 1535182007Sroberto free(peer->cmmd); 1536182007Sroberto peer->cmmd = NULL; 1537182007Sroberto } 1538182007Sroberto 1539182007Sroberto key_expire(peer); 1540182007Sroberto 1541132454Sroberto value_free(&peer->encrypt); 1542132454Sroberto#endif /* OPENSSL */ 1543182007Sroberto} 154482505Sroberto 1545182007Sroberto/* 1546182007Sroberto * peer_clear - clear peer filter registers. See Section 3.4.8 of the spec. 1547182007Sroberto */ 1548182007Srobertovoid 1549182007Srobertopeer_clear( 1550182007Sroberto struct peer *peer, /* peer structure */ 1551182007Sroberto char *ident /* tally lights */ 1552182007Sroberto ) 1553182007Sroberto{ 1554182007Sroberto int i; 1555182007Sroberto 1556182007Sroberto peer_crypto_clear(peer); 1557182007Sroberto 1558182007Sroberto if (peer == sys_peer) 1559182007Sroberto sys_peer = NULL; 1560182007Sroberto 156182505Sroberto /* 1562132454Sroberto * Wipe the association clean and initialize the nonzero values. 156382505Sroberto */ 1564132454Sroberto memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO); 156554359Sroberto peer->estbdelay = sys_bdelay; 156682505Sroberto peer->ppoll = peer->maxpoll; 1567182007Sroberto peer->hpoll = peer->minpoll; 1568182007Sroberto peer->disp = MAXDISPERSE; 1569182007Sroberto peer->jitter = LOGTOD(sys_precision); 1570182007Sroberto for (i = 0; i < NTP_SHIFT; i++) { 1571182007Sroberto peer->filter_order[i] = i; 1572182007Sroberto peer->filter_disp[i] = MAXDISPERSE; 1573182007Sroberto } 157482505Sroberto#ifdef REFCLOCK 157582505Sroberto if (!(peer->flags & FLAG_REFCLOCK)) { 157682505Sroberto peer->leap = LEAP_NOTINSYNC; 157782505Sroberto peer->stratum = STRATUM_UNSPEC; 1578132454Sroberto memcpy(&peer->refid, ident, 4); 157982505Sroberto } 1580132454Sroberto#else 1581132454Sroberto peer->leap = LEAP_NOTINSYNC; 1582132454Sroberto peer->stratum = STRATUM_UNSPEC; 1583132454Sroberto memcpy(&peer->refid, ident, 4); 1584182007Sroberto#endif /* REFCLOCK */ 158554359Sroberto 158654359Sroberto /* 1587182007Sroberto * During initialization use the association count to spread out 1588182007Sroberto * the polls at one-second intervals. Othersie, randomize over 1589182007Sroberto * the minimum poll interval in order to avoid broadcast 1590182007Sroberto * implosion. 159154359Sroberto */ 1592132454Sroberto peer->nextdate = peer->update = peer->outdate = current_time; 1593182007Sroberto if (initializing) 1594182007Sroberto peer->nextdate += peer_associations; 1595182007Sroberto else if (peer->hmode == MODE_PASSIVE) 1596182007Sroberto peer->nextdate += RESP_DELAY; 1597132454Sroberto else 1598182007Sroberto peer->nextdate += (ntp_random() & ((1 << NTP_MINDPOLL) - 1599182007Sroberto 1)); 1600182007Sroberto 1601182007Sroberto DPRINTF(1, ("peer_clear: at %ld next %ld assoc ID %d refid %s\n", 1602182007Sroberto current_time, peer->nextdate, peer->associd, ident)); 160354359Sroberto} 160454359Sroberto 160554359Sroberto 160654359Sroberto/* 160754359Sroberto * clock_filter - add incoming clock sample to filter register and run 160854359Sroberto * the filter procedure to find the best sample. 160954359Sroberto */ 161054359Srobertovoid 161154359Srobertoclock_filter( 1612132454Sroberto struct peer *peer, /* peer structure pointer */ 1613132454Sroberto double sample_offset, /* clock offset */ 1614132454Sroberto double sample_delay, /* roundtrip delay */ 1615132454Sroberto double sample_disp /* dispersion */ 161654359Sroberto ) 161754359Sroberto{ 1618132454Sroberto double dst[NTP_SHIFT]; /* distance vector */ 1619132454Sroberto int ord[NTP_SHIFT]; /* index vector */ 1620132454Sroberto int i, j, k, m; 1621182007Sroberto double dtemp, etemp; 162254359Sroberto 162354359Sroberto /* 162482505Sroberto * Shift the new sample into the register and discard the oldest 162582505Sroberto * one. The new offset and delay come directly from the 162682505Sroberto * timestamp calculations. The dispersion grows from the last 162782505Sroberto * outbound packet or reference clock update to the present time 162882505Sroberto * and increased by the sum of the peer precision and the system 162982505Sroberto * precision. The delay can sometimes swing negative due to 163082505Sroberto * frequency skew, so it is clamped non-negative. 163154359Sroberto */ 163254359Sroberto j = peer->filter_nextpt; 163382505Sroberto peer->filter_offset[j] = sample_offset; 163482505Sroberto peer->filter_delay[j] = max(0, sample_delay); 1635182007Sroberto peer->filter_disp[j] = sample_disp; 1636182007Sroberto peer->filter_epoch[j] = current_time; 1637182007Sroberto j = (j + 1) % NTP_SHIFT; 1638182007Sroberto peer->filter_nextpt = j; 163954359Sroberto 164054359Sroberto /* 164182505Sroberto * Update dispersions since the last update and at the same 164282505Sroberto * time initialize the distance and index lists. The distance 164382505Sroberto * list uses a compound metric. If the sample is valid and 164482505Sroberto * younger than the minimum Allan intercept, use delay; 164582505Sroberto * otherwise, use biased dispersion. 164654359Sroberto */ 164782505Sroberto dtemp = clock_phi * (current_time - peer->update); 164882505Sroberto peer->update = current_time; 164982505Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 1650132454Sroberto if (i != 0) 165182505Sroberto peer->filter_disp[j] += dtemp; 1652132454Sroberto if (peer->filter_disp[j] >= MAXDISPERSE) 1653132454Sroberto peer->filter_disp[j] = MAXDISPERSE; 165482505Sroberto if (peer->filter_disp[j] >= MAXDISPERSE) 165582505Sroberto dst[i] = MAXDISPERSE; 165682505Sroberto else if (peer->update - peer->filter_epoch[j] > 165782505Sroberto allan_xpt) 1658182007Sroberto dst[i] = sys_maxdist + peer->filter_disp[j]; 165982505Sroberto else 1660132454Sroberto dst[i] = peer->filter_delay[j]; 166182505Sroberto ord[i] = j; 166282505Sroberto j++; j %= NTP_SHIFT; 166382505Sroberto } 166454359Sroberto 166582505Sroberto /* 1666182007Sroberto * If the clock discipline has stabilized, sort the samples in 1667182007Sroberto * both lists by distance. Note, we do not displace a higher 1668182007Sroberto * distance sample by a lower distance one unless lower by at 1669182007Sroberto * least the precision. 167054359Sroberto */ 1671182007Sroberto if (state == 4) { 1672182007Sroberto for (i = 1; i < NTP_SHIFT; i++) { 1673182007Sroberto for (j = 0; j < i; j++) { 1674182007Sroberto if (dst[j] > dst[i] + 1675182007Sroberto LOGTOD(sys_precision)) { 1676182007Sroberto k = ord[j]; 1677182007Sroberto ord[j] = ord[i]; 1678182007Sroberto ord[i] = k; 1679182007Sroberto etemp = dst[j]; 1680182007Sroberto dst[j] = dst[i]; 1681182007Sroberto dst[i] = etemp; 1682182007Sroberto } 168354359Sroberto } 168454359Sroberto } 168582505Sroberto } 168682505Sroberto 168782505Sroberto /* 168882505Sroberto * Copy the index list to the association structure so ntpq 168982505Sroberto * can see it later. Prune the distance list to samples less 1690182007Sroberto * than max distance, but keep at least two valid samples for 169182505Sroberto * jitter calculation. 169282505Sroberto */ 169382505Sroberto m = 0; 169482505Sroberto for (i = 0; i < NTP_SHIFT; i++) { 1695132454Sroberto peer->filter_order[i] = (u_char) ord[i]; 169682505Sroberto if (dst[i] >= MAXDISPERSE || (m >= 2 && dst[i] >= 1697182007Sroberto sys_maxdist)) 169882505Sroberto continue; 169982505Sroberto m++; 170082505Sroberto } 170154359Sroberto 170254359Sroberto /* 1703182007Sroberto * Compute the dispersion and jitter. The dispersion is weighted 1704182007Sroberto * exponentially by NTP_FWEIGHT (0.5) so it is normalized close 1705182007Sroberto * to 1.0. The jitter is the RMS differences relative to the 1706182007Sroberto * lowest delay sample. If no acceptable samples remain in the 1707182007Sroberto * shift register, quietly tiptoe home leaving only the 1708182007Sroberto * dispersion. 170954359Sroberto */ 1710182007Sroberto peer->disp = peer->jitter = 0; 171182505Sroberto k = ord[0]; 171254359Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 171382505Sroberto j = ord[i]; 171482505Sroberto peer->disp = NTP_FWEIGHT * (peer->disp + 171582505Sroberto peer->filter_disp[j]); 171682505Sroberto if (i < m) 1717182007Sroberto peer->jitter += DIFF(peer->filter_offset[j], 171882505Sroberto peer->filter_offset[k]); 171954359Sroberto } 172054359Sroberto 172154359Sroberto /* 172282505Sroberto * If no acceptable samples remain in the shift register, 172382505Sroberto * quietly tiptoe home leaving only the dispersion. Otherwise, 1724182007Sroberto * save the offset, delay and jitter. Note the jitter must not 1725182007Sroberto * be less than the precision. 172682505Sroberto */ 172782505Sroberto if (m == 0) 172882505Sroberto return; 1729182007Sroberto 1730132454Sroberto etemp = fabs(peer->offset - peer->filter_offset[k]); 173182505Sroberto peer->offset = peer->filter_offset[k]; 173282505Sroberto peer->delay = peer->filter_delay[k]; 173382505Sroberto if (m > 1) 1734182007Sroberto peer->jitter /= m - 1; 1735182007Sroberto peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision)); 173682505Sroberto 173782505Sroberto /* 173854359Sroberto * A new sample is useful only if it is younger than the last 1739182007Sroberto * one used. Note the order is FIFO if the clock discipline has 1740182007Sroberto * not stabilized. 174154359Sroberto */ 1742182007Sroberto if (peer->filter_epoch[k] <= peer->epoch) { 174354359Sroberto#ifdef DEBUG 174454359Sroberto if (debug) 174554359Sroberto printf("clock_filter: discard %lu\n", 174682505Sroberto peer->epoch - peer->filter_epoch[k]); 174754359Sroberto#endif 174854359Sroberto return; 174954359Sroberto } 175054359Sroberto 175154359Sroberto /* 175282505Sroberto * If the difference between the last offset and the current one 1753132454Sroberto * exceeds the jitter by CLOCK_SGATE and the interval since the 1754132454Sroberto * last update is less than twice the system poll interval, 175582505Sroberto * consider the update a popcorn spike and ignore it. 175654359Sroberto */ 1757182007Sroberto if (etemp > CLOCK_SGATE * peer->jitter && m > 1 && 1758182007Sroberto peer->filter_epoch[k] - peer->epoch < 2. * 1759182007Sroberto ULOGTOD(sys_poll)) { 176054359Sroberto#ifdef DEBUG 176154359Sroberto if (debug) 1762132454Sroberto printf("clock_filter: popcorn %.6f %.6f\n", 1763132454Sroberto etemp, dtemp); 176454359Sroberto#endif 176554359Sroberto return; 176654359Sroberto } 176782505Sroberto 176882505Sroberto /* 176982505Sroberto * The mitigated sample statistics are saved for later 1770182007Sroberto * processing. If not in a burst, tickle the select. 177182505Sroberto */ 177282505Sroberto peer->epoch = peer->filter_epoch[k]; 177354359Sroberto#ifdef DEBUG 177454359Sroberto if (debug) 177554359Sroberto printf( 177682505Sroberto "clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f, age %lu\n", 177782505Sroberto m, peer->offset, peer->delay, peer->disp, 1778182007Sroberto peer->jitter, current_time - peer->epoch); 177954359Sroberto#endif 1780182007Sroberto if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) 1781182007Sroberto clock_select(); 178254359Sroberto} 178354359Sroberto 178454359Sroberto 178554359Sroberto/* 178654359Sroberto * clock_select - find the pick-of-the-litter clock 1787132454Sroberto * 1788132454Sroberto * LOCKCLOCK: If the local clock is the prefer peer, it will always be 1789132454Sroberto * enabled, even if declared falseticker, (2) only the prefer peer can 1790132454Sroberto * be selected as the system peer, (3) if the external source is down, 1791132454Sroberto * the system leap bits are set to 11 and the stratum set to infinity. 179254359Sroberto */ 179354359Srobertovoid 179454359Srobertoclock_select(void) 179554359Sroberto{ 1796132454Sroberto struct peer *peer; 1797132454Sroberto int i, j, k, n; 1798132454Sroberto int nlist, nl3; 1799132454Sroberto 1800182007Sroberto int allow, osurv; 1801182007Sroberto double d, e, f, g; 1802132454Sroberto double high, low; 1803182007Sroberto double synch[NTP_MAXASSOC], error[NTP_MAXASSOC]; 180454359Sroberto struct peer *osys_peer; 180582505Sroberto struct peer *typeacts = NULL; 180682505Sroberto struct peer *typelocal = NULL; 180782505Sroberto struct peer *typesystem = NULL; 180854359Sroberto 180954359Sroberto static int list_alloc = 0; 181054359Sroberto static struct endpoint *endpoint = NULL; 181182505Sroberto static int *indx = NULL; 181254359Sroberto static struct peer **peer_list = NULL; 181354359Sroberto static u_int endpoint_size = 0; 181482505Sroberto static u_int indx_size = 0; 181554359Sroberto static u_int peer_list_size = 0; 181654359Sroberto 181754359Sroberto /* 181882505Sroberto * Initialize and create endpoint, index and peer lists big 181982505Sroberto * enough to handle all associations. 182054359Sroberto */ 182182505Sroberto osys_peer = sys_peer; 182282505Sroberto sys_peer = NULL; 1823182007Sroberto sys_pps = NULL; 1824182007Sroberto sys_prefer = NULL; 1825132454Sroberto osurv = sys_survivors; 1826132454Sroberto sys_survivors = 0; 1827132454Sroberto#ifdef LOCKCLOCK 1828132454Sroberto sys_leap = LEAP_NOTINSYNC; 1829132454Sroberto sys_stratum = STRATUM_UNSPEC; 1830132454Sroberto memcpy(&sys_refid, "DOWN", 4); 1831132454Sroberto#endif /* LOCKCLOCK */ 1832132454Sroberto nlist = 0; 1833182007Sroberto for (n = 0; n < NTP_HASH_SIZE; n++) 183454359Sroberto nlist += peer_hash_count[n]; 183554359Sroberto if (nlist > list_alloc) { 183654359Sroberto if (list_alloc > 0) { 183754359Sroberto free(endpoint); 183882505Sroberto free(indx); 183954359Sroberto free(peer_list); 184054359Sroberto } 184154359Sroberto while (list_alloc < nlist) { 184254359Sroberto list_alloc += 5; 184382505Sroberto endpoint_size += 5 * 3 * sizeof(*endpoint); 184482505Sroberto indx_size += 5 * 3 * sizeof(*indx); 184582505Sroberto peer_list_size += 5 * sizeof(*peer_list); 184654359Sroberto } 1847182007Sroberto endpoint = (struct endpoint *)emalloc(endpoint_size); 1848182007Sroberto indx = (int *)emalloc(indx_size); 1849182007Sroberto peer_list = (struct peer **)emalloc(peer_list_size); 185054359Sroberto } 185154359Sroberto 185254359Sroberto /* 185382505Sroberto * Initially, we populate the island with all the rifraff peers 185482505Sroberto * that happen to be lying around. Those with seriously 185582505Sroberto * defective clocks are immediately booted off the island. Then, 185682505Sroberto * the falsetickers are culled and put to sea. The truechimers 185782505Sroberto * remaining are subject to repeated rounds where the most 185882505Sroberto * unpopular at each round is kicked off. When the population 1859132454Sroberto * has dwindled to sys_minclock, the survivors split a million 1860132454Sroberto * bucks and collectively crank the chimes. 186154359Sroberto */ 186254359Sroberto nlist = nl3 = 0; /* none yet */ 1863182007Sroberto for (n = 0; n < NTP_HASH_SIZE; n++) { 186482505Sroberto for (peer = peer_hash[n]; peer != NULL; peer = 186582505Sroberto peer->next) { 186654359Sroberto peer->flags &= ~FLAG_SYSPEER; 186754359Sroberto peer->status = CTL_PST_SEL_REJECT; 186854359Sroberto 186954359Sroberto /* 1870132454Sroberto * Leave the island immediately if the peer is 1871132454Sroberto * unfit to synchronize. 1872132454Sroberto */ 1873132454Sroberto if (peer_unfit(peer)) 187482505Sroberto continue; 187582505Sroberto 187682505Sroberto /* 187782505Sroberto * Don't allow the local clock or modem drivers 187854359Sroberto * in the kitchen at this point, unless the 187954359Sroberto * prefer peer. Do that later, but only if 188082505Sroberto * nobody else is around. These guys are all 188182505Sroberto * configured, so we never throw them away. 188254359Sroberto */ 1883182007Sroberto#ifdef REFCLOCK 188454359Sroberto if (peer->refclktype == REFCLK_LOCALCLOCK 188554359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT) 1886132454Sroberto /* wjm: VMS_LOCALUNIT taken seriously */ 1887132454Sroberto && REFCLOCKUNIT(&peer->srcadr) != 1888132454Sroberto VMS_LOCALUNIT 188954359Sroberto#endif /* VMS && VMS_LOCALUNIT */ 189054359Sroberto ) { 189154359Sroberto typelocal = peer; 1892182007Sroberto#ifndef LOCKCLOCK 189354359Sroberto if (!(peer->flags & FLAG_PREFER)) 189454359Sroberto continue; /* no local clock */ 1895132454Sroberto#endif /* LOCKCLOCK */ 189654359Sroberto } 189754359Sroberto if (peer->sstclktype == CTL_SST_TS_TELEPHONE) { 189854359Sroberto typeacts = peer; 189954359Sroberto if (!(peer->flags & FLAG_PREFER)) 190054359Sroberto continue; /* no acts */ 190154359Sroberto } 1902182007Sroberto#endif /* REFCLOCK */ 190354359Sroberto 190454359Sroberto /* 190582505Sroberto * If we get this far, the peer can stay on the 190682505Sroberto * island, but does not yet have the immunity 190782505Sroberto * idol. 190854359Sroberto */ 190954359Sroberto peer->status = CTL_PST_SEL_SANE; 191054359Sroberto peer_list[nlist++] = peer; 191154359Sroberto 191254359Sroberto /* 191354359Sroberto * Insert each interval endpoint on the sorted 191454359Sroberto * list. 191554359Sroberto */ 191654359Sroberto e = peer->offset; /* Upper end */ 191754359Sroberto f = root_distance(peer); 191854359Sroberto e = e + f; 191954359Sroberto for (i = nl3 - 1; i >= 0; i--) { 192082505Sroberto if (e >= endpoint[indx[i]].val) 192154359Sroberto break; 1922182007Sroberto 192382505Sroberto indx[i + 3] = indx[i]; 192454359Sroberto } 192582505Sroberto indx[i + 3] = nl3; 192654359Sroberto endpoint[nl3].type = 1; 192754359Sroberto endpoint[nl3++].val = e; 192854359Sroberto 192954359Sroberto e = e - f; /* Center point */ 1930132454Sroberto for (; i >= 0; i--) { 193182505Sroberto if (e >= endpoint[indx[i]].val) 193254359Sroberto break; 1933182007Sroberto 193482505Sroberto indx[i + 2] = indx[i]; 193554359Sroberto } 193682505Sroberto indx[i + 2] = nl3; 193754359Sroberto endpoint[nl3].type = 0; 193854359Sroberto endpoint[nl3++].val = e; 193954359Sroberto 194054359Sroberto e = e - f; /* Lower end */ 1941132454Sroberto for (; i >= 0; i--) { 194282505Sroberto if (e >= endpoint[indx[i]].val) 194354359Sroberto break; 1944182007Sroberto 194582505Sroberto indx[i + 1] = indx[i]; 194654359Sroberto } 194782505Sroberto indx[i + 1] = nl3; 194854359Sroberto endpoint[nl3].type = -1; 194954359Sroberto endpoint[nl3++].val = e; 195054359Sroberto } 195154359Sroberto } 195254359Sroberto#ifdef DEBUG 195382505Sroberto if (debug > 2) 195454359Sroberto for (i = 0; i < nl3; i++) 195582505Sroberto printf("select: endpoint %2d %.6f\n", 195682505Sroberto endpoint[indx[i]].type, 195782505Sroberto endpoint[indx[i]].val); 195854359Sroberto#endif 1959132454Sroberto /* 1960132454Sroberto * This is the actual algorithm that cleaves the truechimers 1961132454Sroberto * from the falsetickers. The original algorithm was described 1962132454Sroberto * in Keith Marzullo's dissertation, but has been modified for 1963132454Sroberto * better accuracy. 1964132454Sroberto * 1965132454Sroberto * Briefly put, we first assume there are no falsetickers, then 1966132454Sroberto * scan the candidate list first from the low end upwards and 1967132454Sroberto * then from the high end downwards. The scans stop when the 1968132454Sroberto * number of intersections equals the number of candidates less 1969132454Sroberto * the number of falsetickers. If this doesn't happen for a 1970132454Sroberto * given number of falsetickers, we bump the number of 1971132454Sroberto * falsetickers and try again. If the number of falsetickers 1972132454Sroberto * becomes equal to or greater than half the number of 1973132454Sroberto * candidates, the Albanians have won the Byzantine wars and 1974132454Sroberto * correct synchronization is not possible. 1975132454Sroberto * 1976132454Sroberto * Here, nlist is the number of candidates and allow is the 1977182007Sroberto * number of falsetickers. Upon exit, the truechimers are the 1978182007Sroberto * susvivors with offsets not less than low and not greater than 1979182007Sroberto * high. There may be none of them. 1980132454Sroberto */ 1981132454Sroberto low = 1e9; 1982132454Sroberto high = -1e9; 1983132454Sroberto for (allow = 0; 2 * allow < nlist; allow++) { 1984132454Sroberto int found; 1985132454Sroberto 1986132454Sroberto /* 1987132454Sroberto * Bound the interval (low, high) as the largest 1988132454Sroberto * interval containing points from presumed truechimers. 1989132454Sroberto */ 1990132454Sroberto found = 0; 1991132454Sroberto n = 0; 1992132454Sroberto for (i = 0; i < nl3; i++) { 1993132454Sroberto low = endpoint[indx[i]].val; 1994132454Sroberto n -= endpoint[indx[i]].type; 1995132454Sroberto if (n >= nlist - allow) 199654359Sroberto break; 199782505Sroberto if (endpoint[indx[i]].type == 0) 199854359Sroberto found++; 199954359Sroberto } 2000132454Sroberto n = 0; 2001132454Sroberto for (j = nl3 - 1; j >= 0; j--) { 2002132454Sroberto high = endpoint[indx[j]].val; 200382505Sroberto n += endpoint[indx[j]].type; 2004132454Sroberto if (n >= nlist - allow) 200554359Sroberto break; 200682505Sroberto if (endpoint[indx[j]].type == 0) 200754359Sroberto found++; 200854359Sroberto } 2009132454Sroberto 2010132454Sroberto /* 2011132454Sroberto * If the number of candidates found outside the 2012132454Sroberto * interval is greater than the number of falsetickers, 2013132454Sroberto * then at least one truechimer is outside the interval, 2014132454Sroberto * so go around again. This is what makes this algorithm 2015132454Sroberto * different than Marzullo's. 2016132454Sroberto */ 201754359Sroberto if (found > allow) 2018132454Sroberto continue; 2019132454Sroberto 2020132454Sroberto /* 2021132454Sroberto * If an interval containing truechimers is found, stop. 2022132454Sroberto * If not, increase the number of falsetickers and go 2023132454Sroberto * around again. 2024132454Sroberto */ 2025132454Sroberto if (high > low) 202654359Sroberto break; 202754359Sroberto } 202854359Sroberto 202954359Sroberto /* 2030182007Sroberto * Clustering algorithm. Construct candidate list in order first 2031182007Sroberto * by stratum then by root distance, but keep only the best 2032182007Sroberto * NTP_MAXASSOC of them. Scan the list to find falsetickers, who 2033182007Sroberto * leave the island immediately. The TRUE peer is always a 2034182007Sroberto * truechimer. We must leave at least one peer to collect the 2035182007Sroberto * million bucks. If in orphan mode, rascals found with lower 2036182007Sroberto * stratum are guaranteed a seat on the bus. 2037182007Sroberto */ 2038182007Sroberto j = 0; 2039182007Sroberto for (i = 0; i < nlist; i++) { 2040182007Sroberto peer = peer_list[i]; 2041182007Sroberto if (nlist > 1 && (peer->offset <= low || peer->offset >= 2042182007Sroberto high) && !(peer->flags & FLAG_TRUE) && 2043182007Sroberto !(sys_stratum >= sys_orphan && peer->stratum < 2044182007Sroberto sys_orphan)) 2045182007Sroberto continue; 2046182007Sroberto 2047182007Sroberto peer->status = CTL_PST_SEL_DISTSYSPEER; 2048182007Sroberto 2049182007Sroberto /* 2050182007Sroberto * The order metric is formed from the stratum times 2051182007Sroberto * max distance (1.) plus the root distance. It strongly 2052182007Sroberto * favors the lowest stratum, but a higher stratum peer 2053182007Sroberto * can capture the clock if the low stratum dominant 2054182007Sroberto * hasn't been heard for awhile. 2055182007Sroberto */ 2056182007Sroberto d = root_distance(peer) + peer->stratum * sys_maxdist; 2057182007Sroberto if (j >= NTP_MAXASSOC) { 2058182007Sroberto if (d >= synch[j - 1]) 2059182007Sroberto continue; 2060182007Sroberto else 2061182007Sroberto j--; 2062182007Sroberto } 2063182007Sroberto for (k = j; k > 0; k--) { 2064182007Sroberto if (d >= synch[k - 1]) 2065182007Sroberto break; 2066182007Sroberto 2067182007Sroberto peer_list[k] = peer_list[k - 1]; 2068182007Sroberto error[k] = error[k - 1]; 2069182007Sroberto synch[k] = synch[k - 1]; 2070182007Sroberto } 2071182007Sroberto peer_list[k] = peer; 2072182007Sroberto error[k] = peer->jitter; 2073182007Sroberto synch[k] = d; 2074182007Sroberto j++; 2075182007Sroberto } 2076182007Sroberto nlist = j; 2077182007Sroberto 2078182007Sroberto /* 207982505Sroberto * If no survivors remain at this point, check if the local 208082505Sroberto * clock or modem drivers have been found. If so, nominate one 2081132454Sroberto * of them as the only survivor. Otherwise, give up and leave 2082132454Sroberto * the island to the rats. 208354359Sroberto */ 2084182007Sroberto if (nlist == 0) { 208554359Sroberto if (typeacts != 0) { 2086182007Sroberto typeacts->status = CTL_PST_SEL_DISTSYSPEER; 208754359Sroberto peer_list[0] = typeacts; 208854359Sroberto nlist = 1; 208954359Sroberto } else if (typelocal != 0) { 2090182007Sroberto typelocal->status = CTL_PST_SEL_DISTSYSPEER; 209154359Sroberto peer_list[0] = typelocal; 209254359Sroberto nlist = 1; 209354359Sroberto } else { 209482505Sroberto if (osys_peer != NULL) { 209582505Sroberto NLOG(NLOG_SYNCSTATUS) 209682505Sroberto msyslog(LOG_INFO, 2097132454Sroberto "no servers reachable"); 2098132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 209954359Sroberto } 210054359Sroberto } 210154359Sroberto } 210254359Sroberto 210354359Sroberto /* 2104132454Sroberto * We can only trust the survivors if the number of candidates 2105132454Sroberto * sys_minsane is at least the number required to detect and 2106132454Sroberto * cast out one falsticker. For the Byzantine agreement 2107132454Sroberto * algorithm used here, that number is 4; however, the default 2108132454Sroberto * sys_minsane is 1 to speed initial synchronization. Careful 2109182007Sroberto * operators will tinker a higher value and use at least that 2110132454Sroberto * number of synchronization sources. 2111132454Sroberto */ 2112132454Sroberto if (nlist < sys_minsane) 2113132454Sroberto return; 2114132454Sroberto 2115182007Sroberto for (i = 0; i < nlist; i++) 211682505Sroberto peer_list[i]->status = CTL_PST_SEL_SELCAND; 211754359Sroberto 211854359Sroberto /* 211982505Sroberto * Now, vote outlyers off the island by select jitter weighted 2120182007Sroberto * by root distance. Continue voting as long as there are more 2121182007Sroberto * than sys_minclock survivors and the minimum select jitter is 2122182007Sroberto * greater than the maximum peer jitter. Stop if we are about to 2123182007Sroberto * discard a TRUE or PREFER peer, who of course has the 2124182007Sroberto * immunity idol. 212554359Sroberto */ 212654359Sroberto while (1) { 212782505Sroberto d = 1e9; 212882505Sroberto e = -1e9; 2129182007Sroberto f = g = 0; 213082505Sroberto k = 0; 213182505Sroberto for (i = 0; i < nlist; i++) { 213282505Sroberto if (error[i] < d) 213382505Sroberto d = error[i]; 213482505Sroberto f = 0; 213582505Sroberto if (nlist > 1) { 213682505Sroberto for (j = 0; j < nlist; j++) 213782505Sroberto f += DIFF(peer_list[j]->offset, 213882505Sroberto peer_list[i]->offset); 2139182007Sroberto f = SQRT(f / (nlist - 1)); 214054359Sroberto } 214182505Sroberto if (f * synch[i] > e) { 2142182007Sroberto g = f; 214382505Sroberto e = f * synch[i]; 214454359Sroberto k = i; 214554359Sroberto } 214654359Sroberto } 2147182007Sroberto f = max(f, LOGTOD(sys_precision)); 2148132454Sroberto if (nlist <= sys_minclock || f <= d || 2149182007Sroberto peer_list[k]->flags & (FLAG_TRUE | FLAG_PREFER)) 2150132454Sroberto break; 215154359Sroberto#ifdef DEBUG 215282505Sroberto if (debug > 2) 215354359Sroberto printf( 2154132454Sroberto "select: drop %s select %.6f jitter %.6f\n", 2155182007Sroberto ntoa(&peer_list[k]->srcadr), g, d); 215654359Sroberto#endif 215754359Sroberto for (j = k + 1; j < nlist; j++) { 215854359Sroberto peer_list[j - 1] = peer_list[j]; 215954359Sroberto error[j - 1] = error[j]; 216054359Sroberto } 216154359Sroberto nlist--; 216254359Sroberto } 216382505Sroberto 216482505Sroberto /* 2165132454Sroberto * What remains is a list usually not greater than sys_minclock 216654359Sroberto * peers. We want only a peer at the lowest stratum to become 216754359Sroberto * the system peer, although all survivors are eligible for the 2168182007Sroberto * combining algorithm. Consider each peer in turn and OR the 2169182007Sroberto * leap bits on the assumption that, if some of them honk 2170182007Sroberto * nonzero bits, they must know what they are doing. Check for 2171182007Sroberto * prefer and pps peers at any stratum. Note that the head of 2172182007Sroberto * the list is at the lowest stratum and that unsynchronized 2173182007Sroberto * peers cannot survive this far. 217454359Sroberto */ 2175182007Sroberto leap_next = 0; 2176182007Sroberto for (i = 0; i < nlist; i++) { 217782505Sroberto peer = peer_list[i]; 2178182007Sroberto sys_survivors++; 2179182007Sroberto leap_next |= peer->leap; 218082505Sroberto peer->status = CTL_PST_SEL_SYNCCAND; 2181132454Sroberto if (peer->flags & FLAG_PREFER) 2182132454Sroberto sys_prefer = peer; 2183182007Sroberto if (peer == osys_peer) 2184132454Sroberto typesystem = peer; 2185182007Sroberto#ifdef REFCLOCK 2186182007Sroberto if (peer->refclktype == REFCLK_ATOM_PPS) 2187182007Sroberto sys_pps = peer; 2188182007Sroberto#endif /* REFCLOCK */ 2189182007Sroberto#if DEBUG 2190182007Sroberto if (debug > 1) 2191182007Sroberto printf("cluster: survivor %s metric %.6f\n", 2192182007Sroberto ntoa(&peer_list[i]->srcadr), synch[i]); 2193182007Sroberto#endif 219454359Sroberto } 219554359Sroberto 219654359Sroberto /* 2197182007Sroberto * Anticlockhop provision. Keep the current system peer if it is 2198182007Sroberto * a survivor but not first in the list. But do that only HOPPER 2199182007Sroberto * times. 2200132454Sroberto */ 2201182007Sroberto if (osys_peer == NULL || typesystem == NULL || typesystem == 2202182007Sroberto peer_list[0] || sys_hopper > sys_maxhop) { 2203182007Sroberto typesystem = peer_list[0]; 2204182007Sroberto sys_hopper = 0; 2205182007Sroberto } else { 2206182007Sroberto peer->selbroken++; 2207182007Sroberto } 2208132454Sroberto 2209132454Sroberto /* 221054359Sroberto * Mitigation rules of the game. There are several types of 2211182007Sroberto * peers that can be selected here: (1) orphan, (2) prefer peer 2212182007Sroberto * (flag FLAG_PREFER) (3) pps peers (type REFCLK_ATOM_PPS), (4) 2213182007Sroberto * the existing system peer, if any, and (5) the head of the 2214182007Sroberto * survivor list. 221554359Sroberto */ 2216182007Sroberto if (typesystem->stratum >= sys_orphan) { 2217182007Sroberto 2218182007Sroberto /* 2219182007Sroberto * If in orphan mode, choose the system peer. If the 2220182007Sroberto * lowest distance, we are the orphan parent and the 2221182007Sroberto * offset is zero. 2222182007Sroberto */ 2223182007Sroberto sys_peer = typesystem; 222454359Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2225182007Sroberto if (sys_orphandelay < sys_peer->rootdelay) { 2226182007Sroberto sys_offset = 0; 2227182007Sroberto sys_refid = htonl(LOOPBACKADR); 2228182007Sroberto } else { 2229182007Sroberto sys_offset = sys_peer->offset; 2230182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2231182007Sroberto } 2232182007Sroberto sys_jitter = LOGTOD(sys_precision); 223354359Sroberto#ifdef DEBUG 223454359Sroberto if (debug > 1) 2235182007Sroberto printf("select: orphan offset %.6f\n", 223656749Sroberto sys_offset); 223754359Sroberto#endif 2238182007Sroberto } else if (sys_prefer) { 2239182007Sroberto 2240182007Sroberto /* 2241182007Sroberto * If a pps peer is present, choose it; otherwise, 2242182007Sroberto * choose the prefer peer. 2243182007Sroberto */ 2244182007Sroberto if (sys_pps) { 2245182007Sroberto sys_peer = sys_pps; 2246182007Sroberto sys_peer->status = CTL_PST_SEL_PPS; 2247182007Sroberto sys_offset = sys_peer->offset; 2248182007Sroberto if (!pps_control) 2249182007Sroberto NLOG(NLOG_SYSEVENT) 2250182007Sroberto msyslog(LOG_INFO, 2251182007Sroberto "pps sync enabled"); 2252182007Sroberto pps_control = current_time; 225354359Sroberto#ifdef DEBUG 2254182007Sroberto if (debug > 1) 2255182007Sroberto printf("select: pps offset %.6f\n", 2256182007Sroberto sys_offset); 225754359Sroberto#endif 2258182007Sroberto } else { 2259182007Sroberto sys_peer = sys_prefer; 2260182007Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2261182007Sroberto sys_offset = sys_peer->offset; 2262182007Sroberto#ifdef DEBUG 2263182007Sroberto if (debug > 1) 2264182007Sroberto printf("select: prefer offset %.6f\n", 2265182007Sroberto sys_offset); 2266182007Sroberto#endif 2267182007Sroberto } 2268182007Sroberto if (sys_peer->stratum == STRATUM_REFCLOCK || 2269182007Sroberto sys_peer->stratum == STRATUM_UNSPEC) 2270182007Sroberto sys_refid = sys_peer->refid; 2271182007Sroberto else 2272182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2273182007Sroberto sys_jitter = sys_peer->jitter; 227454359Sroberto } else { 2275182007Sroberto 2276182007Sroberto /* 2277182007Sroberto * Otherwise, choose the anticlockhopper. 2278182007Sroberto */ 2279182007Sroberto sys_peer = typesystem; 2280182007Sroberto sys_peer->status = CTL_PST_SEL_SYSPEER; 2281182007Sroberto clock_combine(peer_list, nlist); 2282182007Sroberto if (sys_peer->stratum == STRATUM_REFCLOCK || 2283182007Sroberto sys_peer->stratum == STRATUM_UNSPEC) 2284182007Sroberto sys_refid = sys_peer->refid; 228582505Sroberto else 2286182007Sroberto sys_refid = addr2refid(&sys_peer->srcadr); 2287182007Sroberto sys_jitter = SQRT(SQUARE(sys_peer->jitter) + 2288182007Sroberto SQUARE(sys_jitter)); 228954359Sroberto#ifdef DEBUG 229054359Sroberto if (debug > 1) 229154359Sroberto printf("select: combine offset %.6f\n", 229254359Sroberto sys_offset); 229354359Sroberto#endif 229454359Sroberto } 2295182007Sroberto 2296182007Sroberto /* 2297182007Sroberto * We have found the alpha male. 2298182007Sroberto */ 2299182007Sroberto sys_peer->flags |= FLAG_SYSPEER; 2300132454Sroberto if (osys_peer != sys_peer) { 2301132454Sroberto char *src; 2302132454Sroberto 2303132454Sroberto report_event(EVNT_PEERSTCHG, NULL); 2304132454Sroberto 2305132454Sroberto#ifdef REFCLOCK 2306182007Sroberto if (sys_peer->flags & FLAG_REFCLOCK) 2307132454Sroberto src = refnumtoa(&sys_peer->srcadr); 2308132454Sroberto else 2309182007Sroberto#endif /* REFCLOCK */ 2310132454Sroberto src = ntoa(&sys_peer->srcadr); 2311132454Sroberto NLOG(NLOG_SYNCSTATUS) 2312182007Sroberto msyslog(LOG_INFO, "synchronized to %s, stratum %d", 2313182007Sroberto src, sys_peer->stratum); 2314132454Sroberto } 231554359Sroberto clock_update(); 231654359Sroberto} 231754359Sroberto 2318182007Sroberto 231954359Sroberto/* 2320182007Sroberto * clock_combine - compute system offset and jitter from selected peers 232154359Sroberto */ 2322182007Srobertostatic void 232354359Srobertoclock_combine( 2324182007Sroberto struct peer **peers, /* survivor list */ 2325182007Sroberto int npeers /* number of survivors */ 232654359Sroberto ) 232754359Sroberto{ 2328132454Sroberto int i; 2329182007Sroberto double x, y, z, w; 2330132454Sroberto 2331182007Sroberto y = z = w = 0; 233254359Sroberto for (i = 0; i < npeers; i++) { 233354359Sroberto x = root_distance(peers[i]); 233454359Sroberto y += 1. / x; 233554359Sroberto z += peers[i]->offset / x; 2336182007Sroberto w += SQUARE(peers[i]->offset - peers[0]->offset) / x; 233754359Sroberto } 2338182007Sroberto sys_offset = z / y; 2339182007Sroberto sys_jitter = SQRT(w / y); 234054359Sroberto} 234154359Sroberto 234254359Sroberto/* 234354359Sroberto * root_distance - compute synchronization distance from peer to root 234454359Sroberto */ 234554359Srobertostatic double 234654359Srobertoroot_distance( 234754359Sroberto struct peer *peer 234854359Sroberto ) 234954359Sroberto{ 2350182007Sroberto double dist; 2351182007Sroberto 235282505Sroberto /* 235382505Sroberto * Careful squeak here. The value returned must be greater than 2354182007Sroberto * the minimum root dispersion in order to avoid clockhop with 2355182007Sroberto * highly precise reference clocks. In orphan mode lose the peer 2356182007Sroberto * root delay, as that is used by the election algorithm. 235782505Sroberto */ 2358182007Sroberto if (peer->stratum >= sys_orphan) 2359182007Sroberto dist = 0; 2360182007Sroberto else 2361182007Sroberto dist = peer->rootdelay; 2362182007Sroberto dist += max(sys_mindisp, dist + peer->delay) / 2 + 236382505Sroberto peer->rootdispersion + peer->disp + clock_phi * 2364182007Sroberto (current_time - peer->update) + peer->jitter; 2365182007Sroberto return (dist); 236654359Sroberto} 236754359Sroberto 236854359Sroberto/* 236954359Sroberto * peer_xmit - send packet for persistent association. 237054359Sroberto */ 237154359Srobertostatic void 237254359Srobertopeer_xmit( 237354359Sroberto struct peer *peer /* peer structure pointer */ 237454359Sroberto ) 237554359Sroberto{ 237682505Sroberto struct pkt xpkt; /* transmit packet */ 2377132454Sroberto int sendlen, authlen; 2378182007Sroberto keyid_t xkeyid = 0; /* transmit key ID */ 2379132454Sroberto l_fp xmt_tx; 238054359Sroberto 2381182007Sroberto if (!peer->dstadr) /* don't bother with peers without interface */ 2382182007Sroberto return; 2383182007Sroberto 238454359Sroberto /* 2385182007Sroberto * This is deliciously complicated. There are three cases. 2386182007Sroberto * 2387182007Sroberto * case leap stratum refid delay dispersion 2388182007Sroberto * 2389182007Sroberto * normal system system system system system 2390182007Sroberto * orphan child 00 orphan system orphan system 2391182007Sroberto * orphan parent 00 orphan loopbk 0 0 239254359Sroberto */ 2393182007Sroberto /* 2394182007Sroberto * This is a normal packet. Use the system variables. 2395182007Sroberto */ 2396182007Sroberto if (sys_stratum < sys_orphan) { 2397182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, 2398182007Sroberto peer->version, peer->hmode); 2399182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 2400182007Sroberto xpkt.refid = sys_refid; 2401182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2402182007Sroberto xpkt.rootdispersion = 2403182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2404182007Sroberto 2405182007Sroberto /* 2406182007Sroberto * This is a orphan child packet. The host is synchronized to an 2407182007Sroberto * orphan parent. Show leap synchronized, orphan stratum, system 2408182007Sroberto * reference ID, orphan root delay and system root dispersion. 2409182007Sroberto */ 2410182007Sroberto } else if (sys_peer != NULL) { 2411182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2412182007Sroberto peer->version, peer->hmode); 2413182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2414182007Sroberto xpkt.refid = htonl(LOOPBACKADR); 2415182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay)); 2416182007Sroberto xpkt.rootdispersion = 2417182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2418182007Sroberto 2419182007Sroberto /* 2420182007Sroberto * This is an orphan parent. Show leap synchronized, orphan 2421182007Sroberto * stratum, loopack reference ID and zero root delay and root 2422182007Sroberto * dispersion. 2423182007Sroberto */ 2424182007Sroberto } else { 2425182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2426182007Sroberto peer->version, peer->hmode); 2427182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2428182007Sroberto xpkt.refid = sys_refid; 2429182007Sroberto xpkt.rootdelay = 0; 2430182007Sroberto xpkt.rootdispersion = 0; 2431182007Sroberto } 243254359Sroberto xpkt.ppoll = peer->hpoll; 243354359Sroberto xpkt.precision = sys_precision; 243454359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 243554359Sroberto HTONL_FP(&peer->org, &xpkt.org); 243654359Sroberto HTONL_FP(&peer->rec, &xpkt.rec); 243754359Sroberto 243854359Sroberto /* 243982505Sroberto * If the received packet contains a MAC, the transmitted packet 244082505Sroberto * is authenticated and contains a MAC. If not, the transmitted 244182505Sroberto * packet is not authenticated. 244282505Sroberto * 2443182007Sroberto * It is most important when autokey is in use that the local 2444182007Sroberto * interface IP address be known before the first packet is 2445182007Sroberto * sent. Otherwise, it is not possible to compute a correct MAC 2446182007Sroberto * the recipient will accept. Thus, the I/O semantics have to do 2447182007Sroberto * a little more work. In particular, the wildcard interface 2448182007Sroberto * might not be usable. 244954359Sroberto */ 245054359Sroberto sendlen = LEN_PKT_NOMAC; 245182505Sroberto if (!(peer->flags & FLAG_AUTHENABLE)) { 245282505Sroberto get_systime(&peer->xmt); 245382505Sroberto HTONL_FP(&peer->xmt, &xpkt.xmt); 2454132454Sroberto sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], 2455182007Sroberto &xpkt, sendlen); 245682505Sroberto peer->sent++; 245782505Sroberto#ifdef DEBUG 245882505Sroberto if (debug) 245982505Sroberto printf("transmit: at %ld %s->%s mode %d\n", 2460182007Sroberto current_time, peer->dstadr ? stoa(&peer->dstadr->sin) : "-", 2461182007Sroberto stoa(&peer->srcadr), peer->hmode); 246282505Sroberto#endif 246382505Sroberto return; 246482505Sroberto } 246554359Sroberto 246682505Sroberto /* 246782505Sroberto * The received packet contains a MAC, so the transmitted packet 246882505Sroberto * must be authenticated. If autokey is enabled, fuss with the 2469182007Sroberto * various modes; otherwise, symmetric key cryptography is used. 247082505Sroberto */ 2471132454Sroberto#ifdef OPENSSL 2472132454Sroberto if (crypto_flags && (peer->flags & FLAG_SKEY)) { 2473132454Sroberto struct exten *exten; /* extension field */ 247482505Sroberto 247554359Sroberto /* 247682505Sroberto * The Public Key Dance (PKD): Cryptographic credentials 247782505Sroberto * are contained in extension fields, each including a 247882505Sroberto * 4-octet length/code word followed by a 4-octet 247982505Sroberto * association ID and optional additional data. Optional 248082505Sroberto * data includes a 4-octet data length field followed by 248182505Sroberto * the data itself. Request messages are sent from a 248282505Sroberto * configured association; response messages can be sent 248382505Sroberto * from a configured association or can take the fast 248482505Sroberto * path without ever matching an association. Response 248582505Sroberto * messages have the same code as the request, but have 248682505Sroberto * a response bit and possibly an error bit set. In this 248782505Sroberto * implementation, a message may contain no more than 248882505Sroberto * one command and no more than one response. 248982505Sroberto * 249082505Sroberto * Cryptographic session keys include both a public and 249182505Sroberto * a private componet. Request and response messages 249282505Sroberto * using extension fields are always sent with the 249382505Sroberto * private component set to zero. Packets without 249482505Sroberto * extension fields indlude the private component when 249582505Sroberto * the session key is generated. 249654359Sroberto */ 249782505Sroberto while (1) { 249882505Sroberto 249954359Sroberto /* 250082505Sroberto * Allocate and initialize a keylist if not 250182505Sroberto * already done. Then, use the list in inverse 250282505Sroberto * order, discarding keys once used. Keep the 250382505Sroberto * latest key around until the next one, so 250482505Sroberto * clients can use client/server packets to 250582505Sroberto * compute propagation delay. 250682505Sroberto * 250782505Sroberto * Note that once a key is used from the list, 250882505Sroberto * it is retained in the key cache until the 250982505Sroberto * next key is used. This is to allow a client 251082505Sroberto * to retrieve the encrypted session key 251182505Sroberto * identifier to verify authenticity. 251282505Sroberto * 251382505Sroberto * If for some reason a key is no longer in the 251482505Sroberto * key cache, a birthday has happened and the 251582505Sroberto * pseudo-random sequence is probably broken. In 251682505Sroberto * that case, purge the keylist and regenerate 251782505Sroberto * it. 251854359Sroberto */ 251982505Sroberto if (peer->keynumber == 0) 252082505Sroberto make_keylist(peer, peer->dstadr); 252182505Sroberto else 252282505Sroberto peer->keynumber--; 252382505Sroberto xkeyid = peer->keylist[peer->keynumber]; 252482505Sroberto if (authistrusted(xkeyid)) 252582505Sroberto break; 252682505Sroberto else 252782505Sroberto key_expire(peer); 252854359Sroberto } 252982505Sroberto peer->keyid = xkeyid; 2530182007Sroberto exten = NULL; 253182505Sroberto switch (peer->hmode) { 253254359Sroberto 2533182007Sroberto /* 2534182007Sroberto * In broadcast server mode the autokey values are 2535182007Sroberto * required by the broadcast clients. Push them when a 2536182007Sroberto * new keylist is generated; otherwise, push the 2537182007Sroberto * association message so the client can request them at 2538182007Sroberto * other times. 2539182007Sroberto */ 254082505Sroberto case MODE_BROADCAST: 254182505Sroberto if (peer->flags & FLAG_ASSOC) 2542132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 2543182007Sroberto CRYPTO_RESP, NULL); 254482505Sroberto else 2545132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC | 2546182007Sroberto CRYPTO_RESP, NULL); 254782505Sroberto break; 254882505Sroberto 254954359Sroberto /* 2550132454Sroberto * In symmetric modes the digest, certificate, agreement 2551132454Sroberto * parameters, cookie and autokey values are required. 2552132454Sroberto * The leapsecond table is optional. But, a passive peer 2553132454Sroberto * will not believe the active peer until the latter has 2554132454Sroberto * synchronized, so the agreement must be postponed 2555132454Sroberto * until then. In any case, if a new keylist is 2556132454Sroberto * generated, the autokey values are pushed. 2557182007Sroberto * 2558182007Sroberto * If the crypto bit is lit, don't send requests. 255954359Sroberto */ 256082505Sroberto case MODE_ACTIVE: 256182505Sroberto case MODE_PASSIVE: 2562182007Sroberto if (peer->flash & TEST9) 2563182007Sroberto break; 2564182007Sroberto /* 2565182007Sroberto * Parameter and certificate. 2566182007Sroberto */ 256782505Sroberto if (!peer->crypto) 2568132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 2569182007Sroberto sys_hostname); 2570132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VALID)) 2571132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 2572182007Sroberto peer->issuer); 2573132454Sroberto 2574132454Sroberto /* 2575132454Sroberto * Identity. Note we have to sign the 2576132454Sroberto * certificate before the cookie to avoid a 2577132454Sroberto * deadlock when the passive peer is walking the 2578132454Sroberto * certificate trail. Awesome. 2579132454Sroberto */ 2580182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 2581182007Sroberto exten = crypto_args(peer, 2582182007Sroberto crypto_ident(peer), NULL); 2583132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2584182007Sroberto !(peer->crypto & CRYPTO_FLAG_SIGN)) 2585132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 2586182007Sroberto sys_hostname); 2587132454Sroberto 2588132454Sroberto /* 2589132454Sroberto * Autokey. We request the cookie only when the 2590132454Sroberto * server and client are synchronized and 2591132454Sroberto * signatures work both ways. On the other hand, 2592132454Sroberto * the active peer needs the autokey values 2593132454Sroberto * before then and when the passive peer is 2594132454Sroberto * waiting for the active peer to synchronize. 2595132454Sroberto * Any time we regenerate the key list, we offer 2596132454Sroberto * the autokey values without being asked. 2597132454Sroberto */ 2598132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2599182007Sroberto peer->leap != LEAP_NOTINSYNC && 2600182007Sroberto !(peer->crypto & CRYPTO_FLAG_AGREE)) 2601132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 2602182007Sroberto NULL); 2603132454Sroberto else if (peer->flags & FLAG_ASSOC) 2604132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 2605182007Sroberto CRYPTO_RESP, NULL); 2606132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 2607132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 2608182007Sroberto NULL); 2609132454Sroberto 2610132454Sroberto /* 2611132454Sroberto * Postamble. We trade leapseconds only when the 2612132454Sroberto * server and client are synchronized. 2613132454Sroberto */ 2614132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2615182007Sroberto peer->leap != LEAP_NOTINSYNC && 2616182007Sroberto peer->crypto & CRYPTO_FLAG_TAI && 2617182007Sroberto !(peer->crypto & CRYPTO_FLAG_LEAP)) 2618132454Sroberto exten = crypto_args(peer, CRYPTO_TAI, 2619182007Sroberto NULL); 262082505Sroberto break; 262182505Sroberto 262282505Sroberto /* 2623132454Sroberto * In client mode the digest, certificate, agreement 2624132454Sroberto * parameters and cookie are required. The leapsecond 2625132454Sroberto * table is optional. If broadcast client mode, the 2626132454Sroberto * autokey values are required as well. In broadcast 2627132454Sroberto * client mode, these values must be acquired during the 262882505Sroberto * client/server exchange to avoid having to wait until 262982505Sroberto * the next key list regeneration. Otherwise, the poor 263082505Sroberto * dude may die a lingering death until becoming 2631132454Sroberto * unreachable and attempting rebirth. 2632132454Sroberto * 2633132454Sroberto * If neither the server or client have the agreement 2634132454Sroberto * parameters, the protocol transmits the cookie in the 2635132454Sroberto * clear. If the server has the parameters, the client 2636132454Sroberto * requests them and the protocol blinds it using the 2637132454Sroberto * agreed key. It is a protocol error if the client has 2638132454Sroberto * the parameters but the server does not. 2639182007Sroberto * 2640182007Sroberto * If the crypto bit is lit, don't send requests. 264182505Sroberto */ 264282505Sroberto case MODE_CLIENT: 2643182007Sroberto if (peer->flash & TEST9) 2644182007Sroberto break; 2645182007Sroberto /* 2646182007Sroberto * Parameter and certificate. 2647182007Sroberto */ 264882505Sroberto if (!peer->crypto) 2649132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 2650182007Sroberto sys_hostname); 2651132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VALID)) 2652132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 2653182007Sroberto peer->issuer); 2654132454Sroberto 2655132454Sroberto /* 2656182007Sroberto * Identity 2657132454Sroberto */ 2658182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 2659182007Sroberto exten = crypto_args(peer, 2660182007Sroberto crypto_ident(peer), NULL); 2661132454Sroberto 2662132454Sroberto /* 2663132454Sroberto * Autokey 2664132454Sroberto */ 2665132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AGREE)) 2666132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 2667182007Sroberto NULL); 2668132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO) && 2669182007Sroberto (peer->cast_flags & MDF_BCLNT)) 2670132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 2671182007Sroberto NULL); 2672132454Sroberto 2673132454Sroberto /* 2674132454Sroberto * Postamble. We can sign the certificate here, 2675132454Sroberto * since there is no chance of deadlock. 2676132454Sroberto */ 2677132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2678182007Sroberto !(peer->crypto & CRYPTO_FLAG_SIGN)) 2679132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 2680182007Sroberto sys_hostname); 2681132454Sroberto else if (sys_leap != LEAP_NOTINSYNC && 2682182007Sroberto peer->crypto & CRYPTO_FLAG_TAI && 2683182007Sroberto !(peer->crypto & CRYPTO_FLAG_LEAP)) 2684132454Sroberto exten = crypto_args(peer, CRYPTO_TAI, 2685182007Sroberto NULL); 268682505Sroberto break; 268782505Sroberto } 268882505Sroberto 268982505Sroberto /* 2690182007Sroberto * Build the extension fields as directed. A response to 2691182007Sroberto * a request is always sent, even if an error. If an 2692182007Sroberto * error occurs when sending a request, the crypto 2693182007Sroberto * machinery broke or was misconfigured. In that case 2694182007Sroberto * light the crypto bit to suppress further requests. 2695182007Sroberto */ 2696182007Sroberto if (peer->cmmd != NULL) { 2697182007Sroberto peer->cmmd->associd = htonl(peer->associd); 2698182007Sroberto sendlen += crypto_xmit(&xpkt, &peer->srcadr, 2699182007Sroberto sendlen, peer->cmmd, 0); 2700182007Sroberto free(peer->cmmd); 2701182007Sroberto peer->cmmd = NULL; 2702182007Sroberto } 2703182007Sroberto if (exten != NULL) { 2704182007Sroberto int ltemp = 0; 2705182007Sroberto 2706182007Sroberto if (exten->opcode != 0) { 2707182007Sroberto ltemp = crypto_xmit(&xpkt, 2708182007Sroberto &peer->srcadr, sendlen, exten, 0); 2709182007Sroberto if (ltemp == 0) { 2710182007Sroberto peer->flash |= TEST9; /* crypto error */ 2711182007Sroberto free(exten); 2712182007Sroberto return; 2713182007Sroberto } 2714182007Sroberto } 2715182007Sroberto sendlen += ltemp; 2716182007Sroberto free(exten); 2717182007Sroberto } 2718182007Sroberto 2719182007Sroberto /* 272082505Sroberto * If extension fields are present, we must use a 2721182007Sroberto * private cookie value of zero. Don't send if the 2722182007Sroberto * crypto bit is set and no extension field is present, 2723182007Sroberto * but in that case give back the key. Most intricate. 272482505Sroberto */ 2725182007Sroberto if (sendlen > LEN_PKT_NOMAC) { 272682505Sroberto session_key(&peer->dstadr->sin, &peer->srcadr, 272782505Sroberto xkeyid, 0, 2); 2728182007Sroberto } else if (peer->flash & TEST9) { 2729182007Sroberto authtrust(xkeyid, 0); 2730182007Sroberto return; 2731182007Sroberto } 273282505Sroberto } 2733132454Sroberto#endif /* OPENSSL */ 2734182007Sroberto 2735182007Sroberto /* 2736182007Sroberto * Stash the transmit timestamp corrected for the encryption 2737182007Sroberto * delay. If autokey, give back the key, as we use keys only 2738182007Sroberto * once. Check for errors such as missing keys, buffer overflow, 2739182007Sroberto * etc. 2740182007Sroberto */ 274182505Sroberto xkeyid = peer->keyid; 274282505Sroberto get_systime(&peer->xmt); 274382505Sroberto L_ADD(&peer->xmt, &sys_authdelay); 274482505Sroberto HTONL_FP(&peer->xmt, &xpkt.xmt); 274582505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 274682505Sroberto if (authlen == 0) { 2747182007Sroberto msyslog(LOG_INFO, "transmit: %s key %u not found", 2748182007Sroberto stoa(&peer->srcadr), xkeyid); 2749182007Sroberto peer->flash |= TEST9; /* no key found */ 275082505Sroberto return; 275182505Sroberto } 275282505Sroberto sendlen += authlen; 2753132454Sroberto#ifdef OPENSSL 275482505Sroberto if (xkeyid > NTP_MAXKEY) 275582505Sroberto authtrust(xkeyid, 0); 2756132454Sroberto#endif /* OPENSSL */ 275782505Sroberto get_systime(&xmt_tx); 275882505Sroberto if (sendlen > sizeof(xpkt)) { 275982505Sroberto msyslog(LOG_ERR, "buffer overflow %u", sendlen); 2760132454Sroberto exit (-1); 276182505Sroberto } 2762132454Sroberto sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt, 2763182007Sroberto sendlen); 276482505Sroberto 276582505Sroberto /* 276682505Sroberto * Calculate the encryption delay. Keep the minimum over 276782505Sroberto * the latest two samples. 276882505Sroberto */ 276982505Sroberto L_SUB(&xmt_tx, &peer->xmt); 277082505Sroberto L_ADD(&xmt_tx, &sys_authdelay); 277182505Sroberto sys_authdly[1] = sys_authdly[0]; 277282505Sroberto sys_authdly[0] = xmt_tx.l_uf; 277382505Sroberto if (sys_authdly[0] < sys_authdly[1]) 277482505Sroberto sys_authdelay.l_uf = sys_authdly[0]; 277582505Sroberto else 277682505Sroberto sys_authdelay.l_uf = sys_authdly[1]; 277782505Sroberto peer->sent++; 2778132454Sroberto#ifdef OPENSSL 277954359Sroberto#ifdef DEBUG 278082505Sroberto if (debug) 278182505Sroberto printf( 2782182007Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d index %d\n", 2783182007Sroberto current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-", 2784182007Sroberto ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen - 2785182007Sroberto authlen, authlen, peer->keynumber); 278654359Sroberto#endif 278782505Sroberto#else 278882505Sroberto#ifdef DEBUG 278982505Sroberto if (debug) 279082505Sroberto printf( 2791182007Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n", 2792182007Sroberto current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-", 2793182007Sroberto ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen - 2794182007Sroberto authlen, authlen); 279582505Sroberto#endif 2796132454Sroberto#endif /* OPENSSL */ 279754359Sroberto} 279854359Sroberto 279982505Sroberto 280054359Sroberto/* 280182505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that 280282505Sroberto * neither the source or destination can be a broadcast address. 280354359Sroberto */ 280454359Srobertostatic void 280554359Srobertofast_xmit( 280654359Sroberto struct recvbuf *rbufp, /* receive packet pointer */ 2807132454Sroberto int xmode, /* transmit mode */ 2808132454Sroberto keyid_t xkeyid, /* transmit key ID */ 2809132454Sroberto int mask /* restrict mask */ 281054359Sroberto ) 281154359Sroberto{ 2812132454Sroberto struct pkt xpkt; /* transmit packet structure */ 2813132454Sroberto struct pkt *rpkt; /* receive packet structure */ 2814132454Sroberto l_fp xmt_ts; /* timestamp */ 2815132454Sroberto l_fp xmt_tx; /* timestamp after authent */ 2816132454Sroberto int sendlen, authlen; 2817132454Sroberto#ifdef OPENSSL 2818132454Sroberto u_int32 temp32; 2819132454Sroberto#endif 282054359Sroberto 282154359Sroberto /* 282282505Sroberto * Initialize transmit packet header fields from the receive 282382505Sroberto * buffer provided. We leave some fields intact as received. If 2824182007Sroberto * the gazinta was from a multicast address, the gazoutta must 2825182007Sroberto * go out another way. 2826182007Sroberto * 2827182007Sroberto * The root delay field is special. If the system stratum is 2828182007Sroberto * less than the orphan stratum, send the real root delay. 2829182007Sroberto * Otherwise, if there is no system peer, send the orphan delay. 2830182007Sroberto * Otherwise, we must be an orphan parent, so send zero. 283154359Sroberto */ 283254359Sroberto rpkt = &rbufp->recv_pkt; 2833182007Sroberto if (rbufp->dstadr->flags & INT_MCASTOPEN) 283482505Sroberto rbufp->dstadr = findinterface(&rbufp->recv_srcadr); 283582505Sroberto 283682505Sroberto /* 2837182007Sroberto * This is deliciously complicated. There are four cases. 2838182007Sroberto * 2839182007Sroberto * case leap stratum refid delay dispersion 2840182007Sroberto * 2841182007Sroberto * KoD 11 16 KISS system system 2842182007Sroberto * normal system system system system system 2843182007Sroberto * orphan child 00 orphan system orphan system 2844182007Sroberto * orphan parent 00 orphan loopbk 0 0 284582505Sroberto */ 2846182007Sroberto /* 2847182007Sroberto * This is a kiss-of-death (KoD) packet. Show leap 2848182007Sroberto * unsynchronized, stratum zero, reference ID the four-character 2849182007Sroberto * kiss code and system root delay. Note the rate limit on these 2850182007Sroberto * packets. Once a second initialize a bucket counter. Every 2851182007Sroberto * packet sent decrements the counter until reaching zero. If 2852182007Sroberto * the counter is zero, drop the kiss. 2853182007Sroberto */ 2854182007Sroberto if (mask & RES_LIMITED) { 2855182007Sroberto sys_limitrejected++; 2856132454Sroberto if (sys_kod == 0 || !(mask & RES_DEMOBILIZE)) 285782505Sroberto return; 2858132454Sroberto 2859132454Sroberto sys_kod--; 2860132454Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 2861132454Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2862132454Sroberto xpkt.stratum = STRATUM_UNSPEC; 2863182007Sroberto memcpy(&xpkt.refid, "RATE", 4); 2864182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2865182007Sroberto xpkt.rootdispersion = 2866182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2867182007Sroberto 2868182007Sroberto /* 2869182007Sroberto * This is a normal packet. Use the system variables. 2870182007Sroberto */ 2871182007Sroberto } else if (sys_stratum < sys_orphan) { 287282505Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, 287382505Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 287482505Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 287582505Sroberto xpkt.refid = sys_refid; 2876182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 2877182007Sroberto xpkt.rootdispersion = 2878182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2879182007Sroberto 2880182007Sroberto /* 2881182007Sroberto * This is a orphan child packet. The host is synchronized to an 2882182007Sroberto * orphan parent. Show leap synchronized, orphan stratum, system 2883182007Sroberto * reference ID and orphan root delay. 2884182007Sroberto */ 2885182007Sroberto } else if (sys_peer != NULL) { 2886182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2887182007Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2888182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2889182007Sroberto xpkt.refid = sys_refid; 2890182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay)); 2891182007Sroberto xpkt.rootdispersion = 2892182007Sroberto HTONS_FP(DTOUFP(sys_rootdispersion)); 2893182007Sroberto 2894182007Sroberto /* 2895182007Sroberto * This is an orphan parent. Show leap synchronized, orphan 2896182007Sroberto * stratum, loopack reference ID and zero root delay. 2897182007Sroberto */ 2898182007Sroberto } else { 2899182007Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 2900182007Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 2901182007Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_orphan); 2902182007Sroberto xpkt.refid = htonl(LOOPBACKADR); 2903182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(0)); 2904182007Sroberto xpkt.rootdispersion = HTONS_FP(DTOFP(0)); 290582505Sroberto } 290654359Sroberto xpkt.ppoll = rpkt->ppoll; 290754359Sroberto xpkt.precision = sys_precision; 2908182007Sroberto xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion)); 290954359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 291054359Sroberto xpkt.org = rpkt->xmt; 291154359Sroberto HTONL_FP(&rbufp->recv_time, &xpkt.rec); 291282505Sroberto 291382505Sroberto /* 291482505Sroberto * If the received packet contains a MAC, the transmitted packet 291582505Sroberto * is authenticated and contains a MAC. If not, the transmitted 291682505Sroberto * packet is not authenticated. 291782505Sroberto */ 291854359Sroberto sendlen = LEN_PKT_NOMAC; 291982505Sroberto if (rbufp->recv_length == sendlen) { 292054359Sroberto get_systime(&xmt_ts); 292154359Sroberto HTONL_FP(&xmt_ts, &xpkt.xmt); 292282505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, 292356749Sroberto sendlen); 292454359Sroberto#ifdef DEBUG 292554359Sroberto if (debug) 292682505Sroberto printf("transmit: at %ld %s->%s mode %d\n", 2927132454Sroberto current_time, stoa(&rbufp->dstadr->sin), 2928132454Sroberto stoa(&rbufp->recv_srcadr), xmode); 292954359Sroberto#endif 293082505Sroberto return; 293182505Sroberto } 293254359Sroberto 293382505Sroberto /* 293482505Sroberto * The received packet contains a MAC, so the transmitted packet 2935182007Sroberto * must be authenticated. For symmetric key cryptography, use 2936182007Sroberto * the predefined and trusted symmetric keys to generate the 2937182007Sroberto * cryptosum. For autokey cryptography, use the server private 2938182007Sroberto * value to generate the cookie, which is unique for every 2939182007Sroberto * source-destination-key ID combination. 294082505Sroberto */ 2941132454Sroberto#ifdef OPENSSL 294282505Sroberto if (xkeyid > NTP_MAXKEY) { 294382505Sroberto keyid_t cookie; 294482505Sroberto 294554359Sroberto /* 294682505Sroberto * The only way to get here is a reply to a legitimate 294782505Sroberto * client request message, so the mode must be 294882505Sroberto * MODE_SERVER. If an extension field is present, there 294982505Sroberto * can be only one and that must be a command. Do what 295082505Sroberto * needs, but with private value of zero so the poor 295182505Sroberto * jerk can decode it. If no extension field is present, 295282505Sroberto * use the cookie to generate the session key. 295354359Sroberto */ 295482505Sroberto cookie = session_key(&rbufp->recv_srcadr, 295582505Sroberto &rbufp->dstadr->sin, 0, sys_private, 0); 2956182007Sroberto if (rbufp->recv_length >= (int)(sendlen + MAX_MAC_LEN + 2957182007Sroberto 2 * sizeof(u_int32))) { 295882505Sroberto session_key(&rbufp->dstadr->sin, 295982505Sroberto &rbufp->recv_srcadr, xkeyid, 0, 2); 2960132454Sroberto temp32 = CRYPTO_RESP; 2961132454Sroberto rpkt->exten[0] |= htonl(temp32); 2962132454Sroberto sendlen += crypto_xmit(&xpkt, 2963132454Sroberto &rbufp->recv_srcadr, sendlen, 2964132454Sroberto (struct exten *)rpkt->exten, cookie); 296582505Sroberto } else { 296682505Sroberto session_key(&rbufp->dstadr->sin, 296782505Sroberto &rbufp->recv_srcadr, xkeyid, cookie, 2); 296882505Sroberto } 296982505Sroberto } 2970132454Sroberto#endif /* OPENSSL */ 297182505Sroberto get_systime(&xmt_ts); 297282505Sroberto L_ADD(&xmt_ts, &sys_authdelay); 297382505Sroberto HTONL_FP(&xmt_ts, &xpkt.xmt); 297482505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 297582505Sroberto sendlen += authlen; 2976132454Sroberto#ifdef OPENSSL 297782505Sroberto if (xkeyid > NTP_MAXKEY) 297882505Sroberto authtrust(xkeyid, 0); 2979132454Sroberto#endif /* OPENSSL */ 298082505Sroberto get_systime(&xmt_tx); 298182505Sroberto if (sendlen > sizeof(xpkt)) { 298282505Sroberto msyslog(LOG_ERR, "buffer overflow %u", sendlen); 2983132454Sroberto exit (-1); 298482505Sroberto } 298582505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); 298682505Sroberto 298782505Sroberto /* 298882505Sroberto * Calculate the encryption delay. Keep the minimum over the 298982505Sroberto * latest two samples. 299082505Sroberto */ 299182505Sroberto L_SUB(&xmt_tx, &xmt_ts); 299282505Sroberto L_ADD(&xmt_tx, &sys_authdelay); 299382505Sroberto sys_authdly[1] = sys_authdly[0]; 299482505Sroberto sys_authdly[0] = xmt_tx.l_uf; 299582505Sroberto if (sys_authdly[0] < sys_authdly[1]) 299682505Sroberto sys_authdelay.l_uf = sys_authdly[0]; 299782505Sroberto else 299882505Sroberto sys_authdelay.l_uf = sys_authdly[1]; 299954359Sroberto#ifdef DEBUG 300082505Sroberto if (debug) 300182505Sroberto printf( 300282505Sroberto "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n", 300382505Sroberto current_time, ntoa(&rbufp->dstadr->sin), 3004132454Sroberto ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen - 3005132454Sroberto authlen, authlen); 300654359Sroberto#endif 300754359Sroberto} 300854359Sroberto 300982505Sroberto 3010132454Sroberto#ifdef OPENSSL 301154359Sroberto/* 301282505Sroberto * key_expire - purge the key list 301354359Sroberto */ 301482505Srobertovoid 301582505Srobertokey_expire( 301682505Sroberto struct peer *peer /* peer structure pointer */ 301754359Sroberto ) 301854359Sroberto{ 301954359Sroberto int i; 302054359Sroberto 3021132454Sroberto if (peer->keylist != NULL) { 302282505Sroberto for (i = 0; i <= peer->keynumber; i++) 302382505Sroberto authtrust(peer->keylist[i], 0); 302482505Sroberto free(peer->keylist); 302582505Sroberto peer->keylist = NULL; 302654359Sroberto } 3027132454Sroberto value_free(&peer->sndval); 3028132454Sroberto peer->keynumber = 0; 302982505Sroberto#ifdef DEBUG 303082505Sroberto if (debug) 303182505Sroberto printf("key_expire: at %lu\n", current_time); 303282505Sroberto#endif 303354359Sroberto} 3034132454Sroberto#endif /* OPENSSL */ 303554359Sroberto 3036132454Sroberto 303754359Sroberto/* 3038132454Sroberto * Determine if the peer is unfit for synchronization 3039132454Sroberto * 3040132454Sroberto * A peer is unfit for synchronization if 3041182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling 3042182007Sroberto * > TEST11 root distance exceeded 3043182007Sroberto * > TEST12 a direct or indirect synchronization loop would form 3044182007Sroberto * > TEST13 unreachable or noselect 3045132454Sroberto */ 3046182007Srobertoint /* FALSE if fit, TRUE if unfit */ 3047132454Srobertopeer_unfit( 3048132454Sroberto struct peer *peer /* peer structure pointer */ 3049132454Sroberto ) 3050132454Sroberto{ 3051182007Sroberto int rval = 0; 3052182007Sroberto 3053182007Sroberto /* 3054182007Sroberto * A stratum error occurs if (1) the server has never been 3055182007Sroberto * synchronized, (2) the server stratum is below the floor or 3056182007Sroberto * greater than or equal to the ceiling, (3) the system stratum 3057182007Sroberto * is below the orphan stratum and the server stratum is greater 3058182007Sroberto * than or equal to the orphan stratum. 3059182007Sroberto */ 3060182007Sroberto if (peer->leap == LEAP_NOTINSYNC || peer->stratum < sys_floor || 3061182007Sroberto peer->stratum >= sys_ceiling || (sys_stratum < sys_orphan && 3062182007Sroberto peer->stratum >= sys_orphan)) 3063182007Sroberto rval |= TEST10; /* stratum out of bounds */ 3064182007Sroberto 3065182007Sroberto /* 3066182007Sroberto * A distance error occurs if the root distance is greater than 3067182007Sroberto * or equal to the distance threshold plus the increment due to 3068182007Sroberto * one poll interval. 3069182007Sroberto */ 3070182007Sroberto if (root_distance(peer) >= sys_maxdist + clock_phi * 3071182007Sroberto ULOGTOD(sys_poll)) 3072182007Sroberto rval |= TEST11; /* distance exceeded */ 3073182007Sroberto 3074182007Sroberto /* 3075182007Sroberto * A loop error occurs if the remote peer is synchronized to the 3076182007Sroberto * local peer of if the remote peer is synchronized to the same 3077182007Sroberto * server as the local peer, but only if the remote peer is not 3078182007Sroberto * the orphan parent. 3079182007Sroberto */ 3080182007Sroberto if (peer->stratum > 1 && peer->refid != htonl(LOOPBACKADR) && 3081182007Sroberto ((!peer->dstadr || peer->refid == peer->dstadr->addr_refid) || 3082182007Sroberto peer->refid == sys_refid)) 3083182007Sroberto rval |= TEST12; /* synch loop */ 3084182007Sroberto 3085182007Sroberto /* 3086182007Sroberto * An unreachable error occurs if the server is unreachable or 3087182007Sroberto * the noselect bit is set. 3088182007Sroberto */ 3089182007Sroberto if (!peer->reach || peer->flags & FLAG_NOSELECT) 3090182007Sroberto rval |= TEST13; /* unreachable */ 3091182007Sroberto 3092182007Sroberto peer->flash &= ~PEER_TEST_MASK; 3093182007Sroberto peer->flash |= rval; 3094182007Sroberto return (rval); 3095132454Sroberto} 3096132454Sroberto 3097132454Sroberto 3098132454Sroberto/* 309954359Sroberto * Find the precision of this particular machine 310054359Sroberto */ 3101132454Sroberto#define MINSTEP 100e-9 /* minimum clock increment (s) */ 3102132454Sroberto#define MAXSTEP 20e-3 /* maximum clock increment (s) */ 3103132454Sroberto#define MINLOOPS 5 /* minimum number of step samples */ 310454359Sroberto 310554359Sroberto/* 3106132454Sroberto * This routine calculates the system precision, defined as the minimum 3107182007Sroberto * of a sequence of differences between successive readings of the 3108132454Sroberto * system clock. However, if the system clock can be read more than once 3109132454Sroberto * during a tick interval, the difference can be zero or one LSB unit, 3110132454Sroberto * where the LSB corresponds to one nanosecond or one microsecond. 3111132454Sroberto * Conceivably, if some other process preempts this one and reads the 3112132454Sroberto * clock, the difference can be more than one LSB unit. 3113132454Sroberto * 3114132454Sroberto * For hardware clock frequencies of 10 MHz or less, we assume the 3115132454Sroberto * logical clock advances only at the hardware clock tick. For higher 3116132454Sroberto * frequencies, we assume the logical clock can advance no more than 100 3117132454Sroberto * nanoseconds between ticks. 311854359Sroberto */ 311954359Srobertoint 312054359Srobertodefault_get_precision(void) 312154359Sroberto{ 3122132454Sroberto l_fp val; /* current seconds fraction */ 3123132454Sroberto l_fp last; /* last seconds fraction */ 3124132454Sroberto l_fp diff; /* difference */ 3125132454Sroberto double tick; /* computed tick value */ 3126132454Sroberto double dtemp; /* scratch */ 3127132454Sroberto int i; /* log2 precision */ 312854359Sroberto 3129132454Sroberto /* 3130132454Sroberto * Loop to find tick value in nanoseconds. Toss out outlyer 3131132454Sroberto * values less than the minimun tick value. In wacky cases, use 3132132454Sroberto * the default maximum value. 313354359Sroberto */ 3134132454Sroberto get_systime(&last); 3135132454Sroberto tick = MAXSTEP; 3136132454Sroberto for (i = 0; i < MINLOOPS;) { 3137132454Sroberto get_systime(&val); 3138132454Sroberto diff = val; 3139132454Sroberto L_SUB(&diff, &last); 3140132454Sroberto last = val; 3141132454Sroberto LFPTOD(&diff, dtemp); 3142132454Sroberto if (dtemp < MINSTEP) 3143132454Sroberto continue; 3144132454Sroberto i++; 3145132454Sroberto if (dtemp < tick) 3146132454Sroberto tick = dtemp; 314754359Sroberto } 3148132454Sroberto 3149132454Sroberto /* 3150132454Sroberto * Find the nearest power of two. 3151132454Sroberto */ 3152132454Sroberto NLOG(NLOG_SYSEVENT) 3153132454Sroberto msyslog(LOG_INFO, "precision = %.3f usec", tick * 1e6); 3154132454Sroberto for (i = 0; tick <= 1; i++) 3155132454Sroberto tick *= 2; 3156132454Sroberto if (tick - 1. > 1. - tick / 2) 3157132454Sroberto i--; 3158132454Sroberto return (-i); 315954359Sroberto} 316054359Sroberto 3161132454Sroberto 316254359Sroberto/* 3163132454Sroberto * kod_proto - called once per second to limit kiss-of-death packets 3164132454Sroberto */ 3165132454Srobertovoid 3166132454Srobertokod_proto(void) 3167132454Sroberto{ 3168132454Sroberto sys_kod = sys_kod_rate; 3169132454Sroberto} 3170132454Sroberto 3171132454Sroberto 3172132454Sroberto/* 317354359Sroberto * init_proto - initialize the protocol module's data 317454359Sroberto */ 317554359Srobertovoid 317654359Srobertoinit_proto(void) 317754359Sroberto{ 3178132454Sroberto l_fp dummy; 3179132454Sroberto int i; 318054359Sroberto 318154359Sroberto /* 318254359Sroberto * Fill in the sys_* stuff. Default is don't listen to 318354359Sroberto * broadcasting, authenticate. 318454359Sroberto */ 318554359Sroberto sys_leap = LEAP_NOTINSYNC; 318654359Sroberto sys_stratum = STRATUM_UNSPEC; 3187132454Sroberto memcpy(&sys_refid, "INIT", 4); 318854359Sroberto sys_precision = (s_char)default_get_precision(); 318982505Sroberto sys_jitter = LOGTOD(sys_precision); 319054359Sroberto sys_rootdelay = 0; 3191182007Sroberto sys_orphandelay = (double)(ntp_random() & 0xffff) / 65536. * 3192182007Sroberto sys_maxdist; 319354359Sroberto sys_rootdispersion = 0; 319454359Sroberto L_CLR(&sys_reftime); 319582505Sroberto sys_peer = NULL; 319682505Sroberto sys_survivors = 0; 319754359Sroberto get_systime(&dummy); 3198132454Sroberto sys_manycastserver = 0; 319954359Sroberto sys_bclient = 0; 320054359Sroberto sys_bdelay = DEFBROADDELAY; 3201132454Sroberto sys_calldelay = BURST_DELAY; 320254359Sroberto sys_authenticate = 1; 320354359Sroberto L_CLR(&sys_authdelay); 320454359Sroberto sys_authdly[0] = sys_authdly[1] = 0; 320554359Sroberto sys_stattime = 0; 3206132454Sroberto proto_clr_stats(); 3207132454Sroberto for (i = 0; i < MAX_TTL; i++) { 3208132454Sroberto sys_ttl[i] = (u_char)((i * 256) / MAX_TTL); 3209132454Sroberto sys_ttlmax = i; 3210132454Sroberto } 3211132454Sroberto#ifdef OPENSSL 321254359Sroberto sys_automax = 1 << NTP_AUTOMAX; 3213132454Sroberto#endif /* OPENSSL */ 321454359Sroberto 321554359Sroberto /* 321654359Sroberto * Default these to enable 321754359Sroberto */ 321854359Sroberto ntp_enable = 1; 321954359Sroberto#ifndef KERNEL_FLL_BUG 322054359Sroberto kern_enable = 1; 322154359Sroberto#endif 322282505Sroberto pps_enable = 0; 322354359Sroberto stats_control = 1; 322454359Sroberto} 322554359Sroberto 322654359Sroberto 322754359Sroberto/* 322854359Sroberto * proto_config - configure the protocol module 322954359Sroberto */ 323054359Srobertovoid 323154359Srobertoproto_config( 3232132454Sroberto int item, 3233132454Sroberto u_long value, 3234132454Sroberto double dvalue, 3235132454Sroberto struct sockaddr_storage* svalue 323654359Sroberto ) 323754359Sroberto{ 323854359Sroberto /* 323954359Sroberto * Figure out what he wants to change, then do it 324054359Sroberto */ 324154359Sroberto switch (item) { 3242132454Sroberto 3243132454Sroberto /* 3244132454Sroberto * Turn on/off kernel discipline. 3245132454Sroberto */ 324656749Sroberto case PROTO_KERNEL: 324754359Sroberto kern_enable = (int)value; 324854359Sroberto break; 324954359Sroberto 3250132454Sroberto /* 3251132454Sroberto * Turn on/off clock discipline. 3252132454Sroberto */ 325356749Sroberto case PROTO_NTP: 325454359Sroberto ntp_enable = (int)value; 325554359Sroberto break; 325654359Sroberto 3257132454Sroberto /* 3258132454Sroberto * Turn on/off monitoring. 3259132454Sroberto */ 326056749Sroberto case PROTO_MONITOR: 326154359Sroberto if (value) 326254359Sroberto mon_start(MON_ON); 326354359Sroberto else 326454359Sroberto mon_stop(MON_ON); 326554359Sroberto break; 326654359Sroberto 3267132454Sroberto /* 3268132454Sroberto * Turn on/off statistics. 3269132454Sroberto */ 327056749Sroberto case PROTO_FILEGEN: 327154359Sroberto stats_control = (int)value; 327254359Sroberto break; 327354359Sroberto 3274132454Sroberto /* 3275182007Sroberto * Turn on/off enable broadcasts. 3276132454Sroberto */ 327756749Sroberto case PROTO_BROADCLIENT: 327854359Sroberto sys_bclient = (int)value; 3279182007Sroberto if (sys_bclient == 0) 3280182007Sroberto io_unsetbclient(); 3281182007Sroberto else 328254359Sroberto io_setbclient(); 328354359Sroberto break; 328454359Sroberto 3285132454Sroberto /* 3286182007Sroberto * Turn on/off PPS discipline. 3287182007Sroberto */ 3288182007Sroberto case PROTO_PPS: 3289182007Sroberto pps_enable = (int)value; 3290182007Sroberto break; 3291182007Sroberto 3292182007Sroberto /* 3293132454Sroberto * Add muliticast group address. 3294132454Sroberto */ 329556749Sroberto case PROTO_MULTICAST_ADD: 3296132454Sroberto if (svalue) 3297132454Sroberto io_multicast_add(*svalue); 3298182007Sroberto sys_bclient = 1; 329954359Sroberto break; 330054359Sroberto 3301132454Sroberto /* 3302132454Sroberto * Delete multicast group address. 3303132454Sroberto */ 330456749Sroberto case PROTO_MULTICAST_DEL: 3305132454Sroberto if (svalue) 3306132454Sroberto io_multicast_del(*svalue); 330754359Sroberto break; 330854359Sroberto 3309132454Sroberto /* 3310132454Sroberto * Set default broadcast delay. 3311132454Sroberto */ 331256749Sroberto case PROTO_BROADDELAY: 331354359Sroberto sys_bdelay = dvalue; 331454359Sroberto break; 331554359Sroberto 3316132454Sroberto /* 3317132454Sroberto * Set modem call delay. 3318132454Sroberto */ 3319132454Sroberto case PROTO_CALLDELAY: 3320132454Sroberto sys_calldelay = (int)value; 3321132454Sroberto break; 3322132454Sroberto 3323132454Sroberto /* 3324182007Sroberto * Turn on/off authentication to mobilize ephemeral 3325182007Sroberto * associations. 3326132454Sroberto */ 332756749Sroberto case PROTO_AUTHENTICATE: 332854359Sroberto sys_authenticate = (int)value; 332954359Sroberto break; 333054359Sroberto 3331132454Sroberto /* 3332182007Sroberto * Set minimum number of survivors. 3333132454Sroberto */ 3334182007Sroberto case PROTO_MINCLOCK: 3335182007Sroberto sys_minclock = (int)dvalue; 333682505Sroberto break; 333782505Sroberto 3338132454Sroberto /* 3339182007Sroberto * Set maximum number of preemptable associations. 3340132454Sroberto */ 3341182007Sroberto case PROTO_MAXCLOCK: 3342182007Sroberto sys_maxclock = (int)dvalue; 3343132454Sroberto break; 3344132454Sroberto 3345132454Sroberto /* 3346182007Sroberto * Set minimum number of survivors. 3347132454Sroberto */ 3348132454Sroberto case PROTO_MINSANE: 3349132454Sroberto sys_minsane = (int)dvalue; 3350132454Sroberto break; 3351132454Sroberto 3352132454Sroberto /* 3353182007Sroberto * Set stratum floor. 3354132454Sroberto */ 3355132454Sroberto case PROTO_FLOOR: 3356132454Sroberto sys_floor = (int)dvalue; 3357132454Sroberto break; 3358132454Sroberto 3359132454Sroberto /* 3360182007Sroberto * Set stratum ceiling. 3361132454Sroberto */ 3362132454Sroberto case PROTO_CEILING: 3363132454Sroberto sys_ceiling = (int)dvalue; 3364132454Sroberto break; 3365132454Sroberto 3366132454Sroberto /* 3367182007Sroberto * Set orphan stratum. 3368132454Sroberto */ 3369182007Sroberto case PROTO_ORPHAN: 3370182007Sroberto sys_orphan = (int)dvalue; 3371182007Sroberto break; 3372182007Sroberto 3373182007Sroberto /* 3374182007Sroberto * Set cohort switch. 3375182007Sroberto */ 3376132454Sroberto case PROTO_COHORT: 3377182007Sroberto sys_cohort = (int)dvalue; 3378132454Sroberto break; 3379182007Sroberto 3380132454Sroberto /* 3381182007Sroberto * Set minimum dispersion increment. 3382132454Sroberto */ 3383182007Sroberto case PROTO_MINDISP: 3384182007Sroberto sys_mindisp = dvalue; 3385182007Sroberto break; 3386182007Sroberto 3387182007Sroberto /* 3388182007Sroberto * Set maximum distance (select threshold). 3389182007Sroberto */ 3390182007Sroberto case PROTO_MAXDIST: 3391182007Sroberto sys_maxdist = dvalue; 3392182007Sroberto break; 3393182007Sroberto 3394182007Sroberto /* 3395182007Sroberto * Set anticlockhop threshold. 3396182007Sroberto */ 3397182007Sroberto case PROTO_MAXHOP: 3398182007Sroberto sys_maxhop = (int)dvalue; 3399182007Sroberto break; 3400182007Sroberto 3401182007Sroberto /* 3402182007Sroberto * Set adjtime() resolution (s). 3403182007Sroberto */ 3404132454Sroberto case PROTO_ADJ: 3405132454Sroberto sys_tick = dvalue; 3406132454Sroberto break; 3407132454Sroberto 3408182007Sroberto /* 3409182007Sroberto * Set manycast beacon interval. 3410182007Sroberto */ 3411182007Sroberto case PROTO_BEACON: 3412182007Sroberto sys_beacon = (int)dvalue; 3413182007Sroberto break; 3414182007Sroberto 341582505Sroberto#ifdef REFCLOCK 3416132454Sroberto /* 3417132454Sroberto * Turn on/off refclock calibrate 3418132454Sroberto */ 341982505Sroberto case PROTO_CAL: 342082505Sroberto cal_enable = (int)value; 342182505Sroberto break; 3422182007Sroberto#endif /* REFCLOCK */ 342356749Sroberto default: 342456749Sroberto 342554359Sroberto /* 3426132454Sroberto * Log this error. 342754359Sroberto */ 3428132454Sroberto msyslog(LOG_INFO, 3429182007Sroberto "proto_config: illegal item %d, value %ld", item, 3430182007Sroberto value); 343154359Sroberto } 343254359Sroberto} 343354359Sroberto 343454359Sroberto 343554359Sroberto/* 343654359Sroberto * proto_clr_stats - clear protocol stat counters 343754359Sroberto */ 343854359Srobertovoid 343954359Srobertoproto_clr_stats(void) 344054359Sroberto{ 3441132454Sroberto sys_stattime = current_time; 3442132454Sroberto sys_received = 0; 3443132454Sroberto sys_processed = 0; 3444132454Sroberto sys_newversionpkt = 0; 344554359Sroberto sys_oldversionpkt = 0; 344654359Sroberto sys_unknownversion = 0; 3447132454Sroberto sys_restricted = 0; 344854359Sroberto sys_badlength = 0; 344954359Sroberto sys_badauth = 0; 345054359Sroberto sys_limitrejected = 0; 345154359Sroberto} 3452