154359Sroberto/* 254359Sroberto * ntp_proto.c - NTP version 4 protocol machinery 354363Sroberto * 4330106Sdelphij * ATTENTION: Get approval from Harlan on all changes to this file! 5330106Sdelphij * (Harlan will be discussing these changes with Dave Mills.) 6132454Sroberto * 754359Sroberto */ 854359Sroberto#ifdef HAVE_CONFIG_H 954359Sroberto#include <config.h> 1054359Sroberto#endif 1154359Sroberto 1254359Sroberto#include "ntpd.h" 1354359Sroberto#include "ntp_stdlib.h" 1454359Sroberto#include "ntp_unixtime.h" 1554359Sroberto#include "ntp_control.h" 1654359Sroberto#include "ntp_string.h" 17280849Scy#include "ntp_leapsec.h" 18358659Scy#include "ntp_psl.h" 19285169Scy#include "refidsmear.h" 20293423Sdelphij#include "lib_strbuf.h" 2154359Sroberto 2282505Sroberto#include <stdio.h> 23280849Scy#ifdef HAVE_LIBSCF_H 24280849Scy#include <libscf.h> 2554359Sroberto#endif 26280849Scy#ifdef HAVE_UNISTD_H 27280849Scy#include <unistd.h> 2854359Sroberto#endif 2954359Sroberto 30298695Sdelphij/* [Bug 3031] define automatic broadcastdelay cutoff preset */ 31298695Sdelphij#ifndef BDELAY_DEFAULT 32298695Sdelphij# define BDELAY_DEFAULT (-0.050) 33298695Sdelphij#endif 34298695Sdelphij 35358659Scy#define SRVFUZ_SHIFT 6 /* 64 seconds */ 36358659Scy#define SRVRSP_FUZZ(x) \ 37358659Scy do { \ 38358659Scy x.l_uf &= 0; \ 39358659Scy x.l_ui &= ~((1 << SRVFUZ_SHIFT) - 1U); \ 40358659Scy } while(0) 41358659Scy 4254359Sroberto/* 43182007Sroberto * This macro defines the authentication state. If x is 1 authentication 44338530Sdelphij * is required; otherwise it is optional. 45182007Sroberto */ 46289764Sglebius#define AUTH(x, y) ((x) ? (y) == AUTH_OK \ 47289764Sglebius : (y) == AUTH_OK || (y) == AUTH_NONE) 48182007Sroberto 49330106Sdelphijtypedef enum 50330106Sdelphijauth_state { 51330106Sdelphij AUTH_UNKNOWN = -1, /* Unknown */ 52330106Sdelphij AUTH_NONE, /* authentication not required */ 53330106Sdelphij AUTH_OK, /* authentication OK */ 54330106Sdelphij AUTH_ERROR, /* authentication error */ 55330106Sdelphij AUTH_CRYPTO /* crypto_NAK */ 56330106Sdelphij} auth_code; 57280849Scy 58182007Sroberto/* 59289764Sglebius * Set up Kiss Code values 60289764Sglebius */ 61289764Sglebius 62330106Sdelphijtypedef enum 63330106Sdelphijkiss_codes { 64289764Sglebius NOKISS, /* No Kiss Code */ 65289764Sglebius RATEKISS, /* Rate limit Kiss Code */ 66289764Sglebius DENYKISS, /* Deny Kiss */ 67289764Sglebius RSTRKISS, /* Restricted Kiss */ 68330106Sdelphij XKISS /* Experimental Kiss */ 69330106Sdelphij} kiss_code; 70289764Sglebius 71330106Sdelphijtypedef enum 72330106Sdelphijnak_error_codes { 73298695Sdelphij NONAK, /* No NAK seen */ 74298695Sdelphij INVALIDNAK, /* NAK cannot be used */ 75298695Sdelphij VALIDNAK /* NAK is valid */ 76330106Sdelphij} nak_code; 77298695Sdelphij 78289764Sglebius/* 79280849Scy * traffic shaping parameters 8054359Sroberto */ 81280849Scy#define NTP_IBURST 6 /* packets in iburst */ 82280849Scy#define RESP_DELAY 1 /* refclock burst delay (s) */ 83280849Scy 84280849Scy/* 85280849Scy * pool soliciting restriction duration (s) 86280849Scy */ 87280849Scy#define POOL_SOLICIT_WINDOW 8 88280849Scy 89280849Scy/* 90358659Scy * flag bits propagated from pool to individual peers 91358659Scy */ 92358659Scy#define POOL_FLAG_PMASK (FLAG_IBURST | FLAG_NOSELECT) 93358659Scy 94358659Scy/* 95280849Scy * peer_select groups statistics for a peer used by clock_select() and 96280849Scy * clock_cluster(). 97280849Scy */ 98280849Scytypedef struct peer_select_tag { 99280849Scy struct peer * peer; 100280849Scy double synch; /* sync distance */ 101280849Scy double error; /* jitter */ 102280849Scy double seljit; /* selection jitter */ 103280849Scy} peer_select; 104280849Scy 105280849Scy/* 106280849Scy * System variables are declared here. Unless specified otherwise, all 107280849Scy * times are in seconds. 108280849Scy */ 109285169Scyu_char sys_leap; /* system leap indicator, use set_sys_leap() to change this */ 110285169Scyu_char xmt_leap; /* leap indicator sent in client requests, set up by set_sys_leap() */ 111280849Scyu_char sys_stratum; /* system stratum */ 112182007Srobertos_char sys_precision; /* local clock precision (log2 s) */ 113358659Scydouble sys_rootdelay; /* roundtrip delay to root (primary source) */ 114358659Scydouble sys_rootdisp; /* dispersion to root (primary source) */ 115358659Scydouble prev_rootdisp; /* previous root dispersion */ 116358659Scydouble p2_rootdisp; /* previous previous root dispersion */ 117280849Scyu_int32 sys_refid; /* reference id (network byte order) */ 118280849Scyl_fp sys_reftime; /* last update time */ 119358659Scyl_fp prev_reftime; /* previous sys_reftime */ 120358659Scyl_fp p2_reftime; /* previous previous sys_reftime */ 121358659Scyu_long prev_time; /* "current_time" when saved prev_time */ 122358659Scyu_long p2_time; /* previous prev_time */ 123280849Scystruct peer *sys_peer; /* current peer */ 12454359Sroberto 125285169Scy#ifdef LEAP_SMEAR 126285169Scystruct leap_smear_info leap_smear; 127285169Scy#endif 128285169Scyint leap_sec_in_progress; 129285169Scy 13054359Sroberto/* 131280849Scy * Rate controls. Leaky buckets are used to throttle the packet 132280849Scy * transmission rates in order to protect busy servers such as at NIST 133280849Scy * and USNO. There is a counter for each association and another for KoD 134280849Scy * packets. The association counter decrements each second, but not 135280849Scy * below zero. Each time a packet is sent the counter is incremented by 136280849Scy * a configurable value representing the average interval between 137280849Scy * packets. A packet is delayed as long as the counter is greater than 138280849Scy * zero. Note this does not affect the time value computations. 13954359Sroberto */ 140280849Scy/* 141280849Scy * Nonspecified system state variables 142280849Scy */ 143132454Srobertoint sys_bclient; /* broadcast client enable */ 144132454Srobertodouble sys_bdelay; /* broadcast client default delay */ 14554359Srobertoint sys_authenticate; /* requre authentication for config */ 14654359Srobertol_fp sys_authdelay; /* authentication delay */ 147280849Scydouble sys_offset; /* current local clock offset */ 148280849Scydouble sys_mindisp = MINDISPERSE; /* minimum distance (s) */ 149280849Scydouble sys_maxdist = MAXDISTANCE; /* selection threshold */ 150280849Scydouble sys_jitter; /* system jitter */ 151280849Scyu_long sys_epoch; /* last clock update time */ 152280849Scystatic double sys_clockhop; /* clockhop threshold */ 153280849Scystatic int leap_vote_ins; /* leap consensus for insert */ 154280849Scystatic int leap_vote_del; /* leap consensus for delete */ 15582505Srobertokeyid_t sys_private; /* private value for session seed */ 15682505Srobertoint sys_manycastserver; /* respond to manycast client pkts */ 157280849Scyint ntp_mode7; /* respond to ntpdc (mode7) */ 15882505Srobertoint peer_ntpdate; /* active peers in ntpdate mode */ 159132454Srobertoint sys_survivors; /* truest of the truechimers */ 160280849Scychar *sys_ident = NULL; /* identity scheme */ 16154359Sroberto 16254359Sroberto/* 163132454Sroberto * TOS and multicast mapping stuff 164132454Sroberto */ 165182007Srobertoint sys_floor = 0; /* cluster stratum floor */ 166309007Sdelphiju_char sys_bcpollbstep = 0; /* Broadcast Poll backstep gate */ 167280849Scyint sys_ceiling = STRATUM_UNSPEC - 1; /* cluster stratum ceiling */ 168132454Srobertoint sys_minsane = 1; /* minimum candidates */ 169280849Scyint sys_minclock = NTP_MINCLOCK; /* minimum candidates */ 170182007Srobertoint sys_maxclock = NTP_MAXCLOCK; /* maximum candidates */ 171132454Srobertoint sys_cohort = 0; /* cohort switch */ 172182007Srobertoint sys_orphan = STRATUM_UNSPEC + 1; /* orphan stratum */ 173280849Scyint sys_orphwait = NTP_ORPHWAIT; /* orphan wait */ 174182007Srobertoint sys_beacon = BEACON; /* manycast beacon interval */ 175316068Sdelphiju_int sys_ttlmax; /* max ttl mapping vector index */ 176132454Srobertou_char sys_ttl[MAX_TTL]; /* ttl mapping vector */ 177132454Sroberto 178132454Sroberto/* 179280849Scy * Statistics counters - first the good, then the bad 18054359Sroberto */ 181280849Scyu_long sys_stattime; /* elapsed time */ 182132454Srobertou_long sys_received; /* packets received */ 183280849Scyu_long sys_processed; /* packets for this host */ 184280849Scyu_long sys_newversion; /* current version */ 185280849Scyu_long sys_oldversion; /* old version */ 186132454Srobertou_long sys_restricted; /* access denied */ 187132454Srobertou_long sys_badlength; /* bad length or format */ 188132454Srobertou_long sys_badauth; /* bad authentication */ 189280849Scyu_long sys_declined; /* declined */ 190132454Srobertou_long sys_limitrejected; /* rate exceeded */ 191280849Scyu_long sys_kodsent; /* KoD sent */ 19254359Sroberto 193294554Sdelphij/* 194301247Sdelphij * Mechanism knobs: how soon do we peer_clear() or unpeer()? 195294554Sdelphij * 196294554Sdelphij * The default way is "on-receipt". If this was a packet from a 197294554Sdelphij * well-behaved source, on-receipt will offer the fastest recovery. 198294554Sdelphij * If this was from a DoS attack, the default way makes it easier 199294554Sdelphij * for a bad-guy to DoS us. So look and see what bites you harder 200294554Sdelphij * and choose according to your environment. 201294554Sdelphij */ 202301247Sdelphijint peer_clear_digest_early = 1; /* bad digest (TEST5) and Autokey */ 203294554Sdelphijint unpeer_crypto_early = 1; /* bad crypto (TEST9) */ 204294554Sdelphijint unpeer_crypto_nak_early = 1; /* crypto_NAK (TEST5) */ 205294554Sdelphijint unpeer_digest_early = 1; /* bad digest (TEST5) */ 206294554Sdelphij 207298695Sdelphijint dynamic_interleave = DYNAMIC_INTERLEAVE; /* Bug 2978 mitigation */ 208298695Sdelphij 209298695Sdelphijint kiss_code_check(u_char hisleap, u_char hisstratum, u_char hismode, u_int32 refid); 210330106Sdelphijnak_code valid_NAK (struct peer *peer, struct recvbuf *rbufp, u_char hismode); 211280849Scystatic double root_distance (struct peer *); 212280849Scystatic void clock_combine (peer_select *, int, int); 213280849Scystatic void peer_xmit (struct peer *); 214280849Scystatic void fast_xmit (struct recvbuf *, int, keyid_t, int); 215280849Scystatic void pool_xmit (struct peer *); 216280849Scystatic void clock_update (struct peer *); 217280849Scystatic void measure_precision(void); 218280849Scystatic double measure_tick_fuzz(void); 219280849Scystatic int local_refid (struct peer *); 220280849Scystatic int peer_unfit (struct peer *); 221280849Scy#ifdef AUTOKEY 222280849Scystatic int group_test (char *, char *); 223280849Scy#endif /* AUTOKEY */ 224280849Scy#ifdef WORKER 225280849Scyvoid pool_name_resolved (int, int, void *, const char *, 226280849Scy const char *, const struct addrinfo *, 227280849Scy const struct addrinfo *); 228280849Scy#endif /* WORKER */ 22954359Sroberto 230293423Sdelphijconst char * amtoa (int am); 231293423Sdelphij 232293423Sdelphij 233285169Scyvoid 234293423Sdelphijset_sys_leap( 235293423Sdelphij u_char new_sys_leap 236293423Sdelphij ) 237293423Sdelphij{ 238285169Scy sys_leap = new_sys_leap; 239285169Scy xmt_leap = sys_leap; 240182007Sroberto 241285169Scy /* 242285169Scy * Under certain conditions we send faked leap bits to clients, so 243285169Scy * eventually change xmt_leap below, but never change LEAP_NOTINSYNC. 244285169Scy */ 245285169Scy if (xmt_leap != LEAP_NOTINSYNC) { 246285169Scy if (leap_sec_in_progress) { 247285169Scy /* always send "not sync" */ 248285169Scy xmt_leap = LEAP_NOTINSYNC; 249285169Scy } 250285169Scy#ifdef LEAP_SMEAR 251285169Scy else { 252285169Scy /* 253293423Sdelphij * If leap smear is enabled in general we must 254293423Sdelphij * never send a leap second warning to clients, 255293423Sdelphij * so make sure we only send "in sync". 256285169Scy */ 257285169Scy if (leap_smear.enabled) 258285169Scy xmt_leap = LEAP_NOWARNING; 259285169Scy } 260285169Scy#endif /* LEAP_SMEAR */ 261285169Scy } 262285169Scy} 263285169Scy 264293423Sdelphij 265289764Sglebius/* 266289764Sglebius * Kiss Code check 267289764Sglebius */ 268293423Sdelphijint 269293423Sdelphijkiss_code_check( 270293423Sdelphij u_char hisleap, 271293423Sdelphij u_char hisstratum, 272293423Sdelphij u_char hismode, 273293423Sdelphij u_int32 refid 274293423Sdelphij ) 275293423Sdelphij{ 276285169Scy 277293423Sdelphij if ( hismode == MODE_SERVER 278293423Sdelphij && hisleap == LEAP_NOTINSYNC 279293423Sdelphij && hisstratum == STRATUM_UNSPEC) { 280293423Sdelphij if(memcmp(&refid,"RATE", 4) == 0) { 281293423Sdelphij return (RATEKISS); 282293423Sdelphij } else if(memcmp(&refid,"DENY", 4) == 0) { 283293423Sdelphij return (DENYKISS); 284293423Sdelphij } else if(memcmp(&refid,"RSTR", 4) == 0) { 285293423Sdelphij return (RSTRKISS); 286293423Sdelphij } else if(memcmp(&refid,"X", 1) == 0) { 287293423Sdelphij return (XKISS); 288289764Sglebius } 289293423Sdelphij } 290330106Sdelphij return (NOKISS); 291289764Sglebius} 292293423Sdelphij 293293423Sdelphij 294338530Sdelphij/* 295298695Sdelphij * Check that NAK is valid 296298695Sdelphij */ 297330106Sdelphijnak_code 298298695Sdelphijvalid_NAK( 299298695Sdelphij struct peer *peer, 300298695Sdelphij struct recvbuf *rbufp, 301298695Sdelphij u_char hismode 302298695Sdelphij ) 303298695Sdelphij{ 304309007Sdelphij int base_packet_length = MIN_V4_PKT_LEN; 305301247Sdelphij int remainder_size; 306301247Sdelphij struct pkt * rpkt; 307301247Sdelphij int keyid; 308301247Sdelphij l_fp p_org; /* origin timestamp */ 309301247Sdelphij const l_fp * myorg; /* selected peer origin */ 310298695Sdelphij 311298695Sdelphij /* 312298695Sdelphij * Check to see if there is something beyond the basic packet 313298695Sdelphij */ 314298695Sdelphij if (rbufp->recv_length == base_packet_length) { 315298695Sdelphij return NONAK; 316298695Sdelphij } 317298695Sdelphij 318298695Sdelphij remainder_size = rbufp->recv_length - base_packet_length; 319298695Sdelphij /* 320298695Sdelphij * Is this a potential NAK? 321298695Sdelphij */ 322298695Sdelphij if (remainder_size != 4) { 323298695Sdelphij return NONAK; 324298695Sdelphij } 325298695Sdelphij 326298695Sdelphij /* 327298695Sdelphij * Only server responses can contain NAK's 328298695Sdelphij */ 329298695Sdelphij 330298695Sdelphij if (hismode != MODE_SERVER && 331298695Sdelphij hismode != MODE_ACTIVE && 332298695Sdelphij hismode != MODE_PASSIVE 333298695Sdelphij ) { 334301247Sdelphij return INVALIDNAK; 335298695Sdelphij } 336298695Sdelphij 337338530Sdelphij /* 338298695Sdelphij * Make sure that the extra field in the packet is all zeros 339298695Sdelphij */ 340298695Sdelphij rpkt = &rbufp->recv_pkt; 341298695Sdelphij keyid = ntohl(((u_int32 *)rpkt)[base_packet_length / 4]); 342298695Sdelphij if (keyid != 0) { 343301247Sdelphij return INVALIDNAK; 344298695Sdelphij } 345298695Sdelphij 346338530Sdelphij /* 347338530Sdelphij * During the first few packets of the autokey dance there will 348338530Sdelphij * not (yet) be a keyid, but in this case FLAG_SKEY is set. 349338530Sdelphij * So the NAK is invalid if either there's no peer, or 350338530Sdelphij * if the keyid is 0 and FLAG_SKEY is not set. 351298695Sdelphij */ 352338530Sdelphij if (!peer || (!peer->keyid && !(peer->flags & FLAG_SKEY))) { 353301247Sdelphij return INVALIDNAK; 354298695Sdelphij } 355301247Sdelphij 356301247Sdelphij /* 357301247Sdelphij * The ORIGIN must match, or this cannot be a valid NAK, either. 358301247Sdelphij */ 359358659Scy 360358659Scy if (FLAG_LOOPNONCE & peer->flags) { 361358659Scy myorg = &peer->nonce; 362358659Scy } else { 363358659Scy if (peer->flip > 0) { 364358659Scy myorg = &peer->borg; 365358659Scy } else { 366358659Scy myorg = &peer->aorg; 367358659Scy } 368358659Scy } 369358659Scy 370301247Sdelphij NTOHL_FP(&rpkt->org, &p_org); 371309007Sdelphij 372301247Sdelphij if (L_ISZERO(&p_org) || 373301247Sdelphij L_ISZERO( myorg) || 374301247Sdelphij !L_ISEQU(&p_org, myorg)) { 375301247Sdelphij return INVALIDNAK; 376298695Sdelphij } 377301247Sdelphij 378301247Sdelphij /* If we ever passed all that checks, we should be safe. Well, 379301247Sdelphij * as safe as we can ever be with an unauthenticated crypto-nak. 380301247Sdelphij */ 381301247Sdelphij return VALIDNAK; 382298695Sdelphij} 383298695Sdelphij 384298695Sdelphij 38554359Sroberto/* 386280849Scy * transmit - transmit procedure called by poll timeout 38754359Sroberto */ 38854359Srobertovoid 38954359Srobertotransmit( 39054359Sroberto struct peer *peer /* peer structure pointer */ 39154359Sroberto ) 39254359Sroberto{ 393280849Scy u_char hpoll; 39454359Sroberto 395132454Sroberto /* 396132454Sroberto * The polling state machine. There are two kinds of machines, 397132454Sroberto * those that never expect a reply (broadcast and manycast 398132454Sroberto * server modes) and those that do (all other modes). The dance 399132454Sroberto * is intricate... 400132454Sroberto */ 40154359Sroberto hpoll = peer->hpoll; 402182007Sroberto 403182007Sroberto /* 404338530Sdelphij * If we haven't received anything (even if unsync) since last 405338530Sdelphij * send, reset ppoll. 406338530Sdelphij */ 407338530Sdelphij if (peer->outdate > peer->timelastrec && !peer->reach) 408338530Sdelphij peer->ppoll = peer->maxpoll; 409338530Sdelphij 410338530Sdelphij /* 411182007Sroberto * In broadcast mode the poll interval is never changed from 412182007Sroberto * minpoll. 413182007Sroberto */ 414132454Sroberto if (peer->cast_flags & (MDF_BCAST | MDF_MCAST)) { 415182007Sroberto peer->outdate = current_time; 416358659Scy poll_update(peer, hpoll, 0); 417280849Scy if (sys_leap != LEAP_NOTINSYNC) 418280849Scy peer_xmit(peer); 419182007Sroberto return; 420182007Sroberto } 42154359Sroberto 422182007Sroberto /* 423182007Sroberto * In manycast mode we start with unity ttl. The ttl is 424182007Sroberto * increased by one for each poll until either sys_maxclock 425182007Sroberto * servers have been found or the maximum ttl is reached. When 426182007Sroberto * sys_maxclock servers are found we stop polling until one or 427280849Scy * more servers have timed out or until less than sys_minclock 428182007Sroberto * associations turn up. In this case additional better servers 429280849Scy * are dragged in and preempt the existing ones. Once every 430280849Scy * sys_beacon seconds we are to transmit unconditionally, but 431280849Scy * this code is not quite right -- peer->unreach counts polls 432280849Scy * and is being compared with sys_beacon, so the beacons happen 433280849Scy * every sys_beacon polls. 434182007Sroberto */ 435182007Sroberto if (peer->cast_flags & MDF_ACAST) { 436182007Sroberto peer->outdate = current_time; 437358659Scy poll_update(peer, hpoll, 0); 438182007Sroberto if (peer->unreach > sys_beacon) { 439182007Sroberto peer->unreach = 0; 440182007Sroberto peer->ttl = 0; 441182007Sroberto peer_xmit(peer); 442289764Sglebius } else if ( sys_survivors < sys_minclock 443289764Sglebius || peer_associations < sys_maxclock) { 444316068Sdelphij if (peer->ttl < sys_ttlmax) 445182007Sroberto peer->ttl++; 446182007Sroberto peer_xmit(peer); 447182007Sroberto } 448182007Sroberto peer->unreach++; 449182007Sroberto return; 450182007Sroberto } 45182505Sroberto 452182007Sroberto /* 453280849Scy * Pool associations transmit unicast solicitations when there 454280849Scy * are less than a hard limit of 2 * sys_maxclock associations, 455280849Scy * and either less than sys_minclock survivors or less than 456280849Scy * sys_maxclock associations. The hard limit prevents unbounded 457280849Scy * growth in associations if the system clock or network quality 458280849Scy * result in survivor count dipping below sys_minclock often. 459280849Scy * This was observed testing with pool, where sys_maxclock == 12 460280849Scy * resulted in 60 associations without the hard limit. A 461280849Scy * similar hard limit on manycastclient ephemeral associations 462280849Scy * may be appropriate. 463280849Scy */ 464280849Scy if (peer->cast_flags & MDF_POOL) { 465280849Scy peer->outdate = current_time; 466358659Scy poll_update(peer, hpoll, 0); 467289764Sglebius if ( (peer_associations <= 2 * sys_maxclock) 468289764Sglebius && ( peer_associations < sys_maxclock 469293423Sdelphij || sys_survivors < sys_minclock)) 470280849Scy pool_xmit(peer); 471280849Scy return; 472280849Scy } 473280849Scy 474280849Scy /* 475182007Sroberto * In unicast modes the dance is much more intricate. It is 476280849Scy * designed to back off whenever possible to minimize network 477182007Sroberto * traffic. 478182007Sroberto */ 479182007Sroberto if (peer->burst == 0) { 480182007Sroberto u_char oreach; 481182007Sroberto 482132454Sroberto /* 483182007Sroberto * Update the reachability status. If not heard for 484182007Sroberto * three consecutive polls, stuff infinity in the clock 485282408Scy * filter. 486132454Sroberto */ 487182007Sroberto oreach = peer->reach; 488182007Sroberto peer->outdate = current_time; 489280849Scy peer->unreach++; 490182007Sroberto peer->reach <<= 1; 491182007Sroberto if (!peer->reach) { 49282505Sroberto 493182007Sroberto /* 494182007Sroberto * Here the peer is unreachable. If it was 495280849Scy * previously reachable raise a trap. Send a 496280849Scy * burst if enabled. 497182007Sroberto */ 498280849Scy clock_filter(peer, 0., 0., MAXDISPERSE); 499182007Sroberto if (oreach) { 500280849Scy peer_unfit(peer); 501280849Scy report_event(PEVNT_UNREACH, peer, NULL); 502182007Sroberto } 503289764Sglebius if ( (peer->flags & FLAG_IBURST) 504289764Sglebius && peer->retry == 0) 505280849Scy peer->retry = NTP_RETRY; 506182007Sroberto } else { 507182007Sroberto 508182007Sroberto /* 509280849Scy * Here the peer is reachable. Send a burst if 510280849Scy * enabled and the peer is fit. Reset unreach 511280849Scy * for persistent and ephemeral associations. 512280849Scy * Unreach is also reset for survivors in 513280849Scy * clock_select(). 514182007Sroberto */ 515280849Scy hpoll = sys_poll; 516280849Scy if (!(peer->flags & FLAG_PREEMPT)) 517182007Sroberto peer->unreach = 0; 518289764Sglebius if ( (peer->flags & FLAG_BURST) 519289764Sglebius && peer->retry == 0 520289764Sglebius && !peer_unfit(peer)) 521280849Scy peer->retry = NTP_RETRY; 522182007Sroberto } 523182007Sroberto 524132454Sroberto /* 525280849Scy * Watch for timeout. If ephemeral, toss the rascal; 526280849Scy * otherwise, bump the poll interval. Note the 527280849Scy * poll_update() routine will clamp it to maxpoll. 528280849Scy * If preemptible and we have more peers than maxclock, 529280849Scy * and this peer has the minimum score of preemptibles, 530280849Scy * demobilize. 531282408Scy */ 532132454Sroberto if (peer->unreach >= NTP_UNREACH) { 533280849Scy hpoll++; 534280849Scy /* ephemeral: no FLAG_CONFIG nor FLAG_PREEMPT */ 535280849Scy if (!(peer->flags & (FLAG_CONFIG | FLAG_PREEMPT))) { 536280849Scy report_event(PEVNT_RESTART, peer, "timeout"); 537182007Sroberto peer_clear(peer, "TIME"); 53882505Sroberto unpeer(peer); 53982505Sroberto return; 54082505Sroberto } 541289764Sglebius if ( (peer->flags & FLAG_PREEMPT) 542289764Sglebius && (peer_associations > sys_maxclock) 543289764Sglebius && score_all(peer)) { 544280849Scy report_event(PEVNT_RESTART, peer, "timeout"); 545280849Scy peer_clear(peer, "TIME"); 546280849Scy unpeer(peer); 547280849Scy return; 548280849Scy } 54982505Sroberto } 550182007Sroberto } else { 551182007Sroberto peer->burst--; 552132454Sroberto if (peer->burst == 0) { 55354359Sroberto 55454359Sroberto /* 555182007Sroberto * If ntpdate mode and the clock has not been 556182007Sroberto * set and all peers have completed the burst, 557182007Sroberto * we declare a successful failure. 55854359Sroberto */ 559182007Sroberto if (mode_ntpdate) { 560182007Sroberto peer_ntpdate--; 561182007Sroberto if (peer_ntpdate == 0) { 562132454Sroberto msyslog(LOG_NOTICE, 563280849Scy "ntpd: no servers found"); 564280849Scy if (!msyslog_term) 565280849Scy printf( 566280849Scy "ntpd: no servers found\n"); 567132454Sroberto exit (0); 568132454Sroberto } 56954359Sroberto } 57054359Sroberto } 57154359Sroberto } 572280849Scy if (peer->retry > 0) 573280849Scy peer->retry--; 57454359Sroberto 57554359Sroberto /* 576282408Scy * Do not transmit if in broadcast client mode. 57754359Sroberto */ 578358659Scy poll_update(peer, hpoll, (peer->hmode == MODE_CLIENT)); 579182007Sroberto if (peer->hmode != MODE_BCLIENT) 580182007Sroberto peer_xmit(peer); 581293423Sdelphij 582293423Sdelphij return; 58354359Sroberto} 58454359Sroberto 585182007Sroberto 586293423Sdelphijconst char * 587293423Sdelphijamtoa( 588293423Sdelphij int am 589293423Sdelphij ) 590293423Sdelphij{ 591293423Sdelphij char *bp; 592293423Sdelphij 593293423Sdelphij switch(am) { 594293423Sdelphij case AM_ERR: return "AM_ERR"; 595293423Sdelphij case AM_NOMATCH: return "AM_NOMATCH"; 596293423Sdelphij case AM_PROCPKT: return "AM_PROCPKT"; 597293423Sdelphij case AM_BCST: return "AM_BCST"; 598293423Sdelphij case AM_FXMIT: return "AM_FXMIT"; 599293423Sdelphij case AM_MANYCAST: return "AM_MANYCAST"; 600293423Sdelphij case AM_NEWPASS: return "AM_NEWPASS"; 601293423Sdelphij case AM_NEWBCL: return "AM_NEWBCL"; 602293423Sdelphij case AM_POSSBCL: return "AM_POSSBCL"; 603293423Sdelphij default: 604293423Sdelphij LIB_GETBUF(bp); 605293423Sdelphij snprintf(bp, LIB_BUFLENGTH, "AM_#%d", am); 606293423Sdelphij return bp; 607293423Sdelphij } 608293423Sdelphij} 609293423Sdelphij 610293423Sdelphij 61154359Sroberto/* 612280849Scy * receive - receive procedure called for each packet received 61354359Sroberto */ 61454359Srobertovoid 61554359Srobertoreceive( 61654359Sroberto struct recvbuf *rbufp 61754359Sroberto ) 61854359Sroberto{ 619132454Sroberto register struct peer *peer; /* peer structure pointer */ 620132454Sroberto register struct pkt *pkt; /* receive packet pointer */ 621280849Scy u_char hisversion; /* packet version */ 622280849Scy u_char hisleap; /* packet leap indicator */ 623280849Scy u_char hismode; /* packet mode */ 624280849Scy u_char hisstratum; /* packet stratum */ 625330106Sdelphij r4addr r4a; /* address restrictions */ 626280849Scy u_short restrict_mask; /* restrict bits */ 627293423Sdelphij const char *hm_str; /* hismode string */ 628293423Sdelphij const char *am_str; /* association match string */ 629293423Sdelphij int kissCode = NOKISS; /* Kiss Code */ 630132454Sroberto int has_mac; /* length of MAC field */ 631132454Sroberto int authlen; /* offset of MAC field */ 632330106Sdelphij auth_code is_authentic = AUTH_UNKNOWN; /* Was AUTH_NONE */ 633330106Sdelphij nak_code crypto_nak_test; /* result of crypto-NAK check */ 634280849Scy int retcode = AM_NOMATCH; /* match code */ 635280849Scy keyid_t skeyid = 0; /* key IDs */ 636280849Scy u_int32 opcode = 0; /* extension field opcode */ 637293423Sdelphij sockaddr_u *dstadr_sin; /* active runway */ 638132454Sroberto struct peer *peer2; /* aux peer structure pointer */ 639293423Sdelphij endpt *match_ep; /* newpeer() local address */ 640182007Sroberto l_fp p_org; /* origin timestamp */ 641182007Sroberto l_fp p_rec; /* receive timestamp */ 642132454Sroberto l_fp p_xmt; /* transmit timestamp */ 643280849Scy#ifdef AUTOKEY 644280849Scy char hostname[NTP_MAXSTRLEN + 1]; 645280849Scy char *groupname = NULL; 646132454Sroberto struct autokey *ap; /* autokey structure pointer */ 647132454Sroberto int rval; /* cookie snatcher */ 648280849Scy keyid_t pkeyid = 0, tkeyid = 0; /* key IDs */ 649280849Scy#endif /* AUTOKEY */ 650280849Scy#ifdef HAVE_NTP_SIGND 651280849Scy static unsigned char zero_key[16]; 652280849Scy#endif /* HAVE_NTP_SIGND */ 65354359Sroberto 65454359Sroberto /* 655330106Sdelphij * Note that there are many places we do not call record_raw_stats(). 656330106Sdelphij * 657330106Sdelphij * We only want to call it *after* we've sent a response, or perhaps 658330106Sdelphij * when we've decided to drop a packet. 659330106Sdelphij */ 660330106Sdelphij 661330106Sdelphij /* 66282505Sroberto * Monitor the packet and get restrictions. Note that the packet 66382505Sroberto * length for control and private mode packets must be checked 664280849Scy * by the service routines. Some restrictions have to be handled 665280849Scy * later in order to generate a kiss-o'-death packet. 66654359Sroberto */ 667132454Sroberto /* 668132454Sroberto * Bogus port check is before anything, since it probably 669358659Scy * reveals a clogging attack. Likewise the mimimum packet size 670358659Scy * of 2 bytes (for mode 6/7) must be checked first. 671132454Sroberto */ 672132454Sroberto sys_received++; 673358659Scy if (0 == SRCPORT(&rbufp->recv_srcadr) || rbufp->recv_length < 2) { 674132454Sroberto sys_badlength++; 675358659Scy return; /* bogus port / length */ 676132454Sroberto } 677330106Sdelphij restrictions(&rbufp->recv_srcadr, &r4a); 678330106Sdelphij restrict_mask = r4a.rflags; 679330106Sdelphij 680293423Sdelphij pkt = &rbufp->recv_pkt; 681182007Sroberto hisversion = PKT_VERSION(pkt->li_vn_mode); 682132454Sroberto hismode = (int)PKT_MODE(pkt->li_vn_mode); 683330106Sdelphij 684280849Scy if (restrict_mask & RES_IGNORE) { 685330106Sdelphij DPRINTF(2, ("receive: drop: RES_IGNORE\n")); 686280849Scy sys_restricted++; 687280849Scy return; /* ignore everything */ 688280849Scy } 689132454Sroberto if (hismode == MODE_PRIVATE) { 690280849Scy if (!ntp_mode7 || (restrict_mask & RES_NOQUERY)) { 691330106Sdelphij DPRINTF(2, ("receive: drop: RES_NOQUERY\n")); 692132454Sroberto sys_restricted++; 69382505Sroberto return; /* no query private */ 694132454Sroberto } 69556749Sroberto process_private(rbufp, ((restrict_mask & 69656749Sroberto RES_NOMODIFY) == 0)); 69754359Sroberto return; 69854359Sroberto } 699132454Sroberto if (hismode == MODE_CONTROL) { 700132454Sroberto if (restrict_mask & RES_NOQUERY) { 701330106Sdelphij DPRINTF(2, ("receive: drop: RES_NOQUERY\n")); 702132454Sroberto sys_restricted++; 70382505Sroberto return; /* no query control */ 704132454Sroberto } 70554359Sroberto process_control(rbufp, restrict_mask); 70654359Sroberto return; 70754359Sroberto } 708132454Sroberto if (restrict_mask & RES_DONTSERVE) { 709330106Sdelphij DPRINTF(2, ("receive: drop: RES_DONTSERVE\n")); 710132454Sroberto sys_restricted++; 711280849Scy return; /* no time serve */ 712132454Sroberto } 713280849Scy 714358659Scy 715358659Scy /* If we arrive here, we should have a standard NTP packet. We 716358659Scy * check that the minimum size is available and fetch some more 717358659Scy * items from the packet once we can be sure they are indeed 718358659Scy * there. 719358659Scy */ 720358659Scy if (rbufp->recv_length < LEN_PKT_NOMAC) { 721358659Scy sys_badlength++; 722358659Scy return; /* bogus length */ 723358659Scy } 724358659Scy 725358659Scy hisleap = PKT_LEAP(pkt->li_vn_mode); 726358659Scy hisstratum = PKT_TO_STRATUM(pkt->stratum); 727358659Scy INSIST(0 != hisstratum); /* paranoia check PKT_TO_STRATUM result */ 728358659Scy 729358659Scy DPRINTF(1, ("receive: at %ld %s<-%s ippeerlimit %d mode %d iflags %s " 730358659Scy "restrict %s org %#010x.%08x xmt %#010x.%08x\n", 731358659Scy current_time, stoa(&rbufp->dstadr->sin), 732358659Scy stoa(&rbufp->recv_srcadr), r4a.ippeerlimit, hismode, 733358659Scy build_iflags(rbufp->dstadr->flags), 734358659Scy build_rflags(restrict_mask), 735358659Scy ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 736358659Scy ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 737358659Scy 738280849Scy /* 739280849Scy * This is for testing. If restricted drop ten percent of 740280849Scy * surviving packets. 741280849Scy */ 742280849Scy if (restrict_mask & RES_FLAKE) { 743280849Scy if ((double)ntp_random() / 0x7fffffff < .1) { 744330106Sdelphij DPRINTF(2, ("receive: drop: RES_FLAKE\n")); 745280849Scy sys_restricted++; 746280849Scy return; /* no flakeway */ 747280849Scy } 74882505Sroberto } 749282408Scy 750132454Sroberto /* 751330106Sdelphij ** Format Layer Checks 752330106Sdelphij ** 753330106Sdelphij ** Validate the packet format. The packet size, packet header, 754330106Sdelphij ** and any extension field lengths are checked. We identify 755330106Sdelphij ** the beginning of the MAC, to identify the upper limit of 756330106Sdelphij ** of the hash computation. 757330106Sdelphij ** 758330106Sdelphij ** In case of a format layer check violation, the packet is 759330106Sdelphij ** discarded with no further processing. 760330106Sdelphij */ 761330106Sdelphij 762330106Sdelphij /* 763132454Sroberto * Version check must be after the query packets, since they 764280849Scy * intentionally use an early version. 765132454Sroberto */ 766182007Sroberto if (hisversion == NTP_VERSION) { 767280849Scy sys_newversion++; /* new version */ 768289764Sglebius } else if ( !(restrict_mask & RES_VERSION) 769289764Sglebius && hisversion >= NTP_OLDVERSION) { 770280849Scy sys_oldversion++; /* previous version */ 771132454Sroberto } else { 772330106Sdelphij DPRINTF(2, ("receive: drop: RES_VERSION\n")); 773280849Scy sys_badlength++; 774132454Sroberto return; /* old version */ 775132454Sroberto } 77654359Sroberto 77754359Sroberto /* 778132454Sroberto * Figure out his mode and validate the packet. This has some 779132454Sroberto * legacy raunch that probably should be removed. In very early 780132454Sroberto * NTP versions mode 0 was equivalent to what later versions 781132454Sroberto * would interpret as client mode. 78254359Sroberto */ 78382505Sroberto if (hismode == MODE_UNSPEC) { 784182007Sroberto if (hisversion == NTP_OLDVERSION) { 785132454Sroberto hismode = MODE_CLIENT; 786132454Sroberto } else { 787330106Sdelphij DPRINTF(2, ("receive: drop: MODE_UNSPEC\n")); 788132454Sroberto sys_badlength++; 789338530Sdelphij return; /* invalid mode */ 790132454Sroberto } 79182505Sroberto } 79254359Sroberto 79354359Sroberto /* 79482505Sroberto * Parse the extension field if present. We figure out whether 79582505Sroberto * an extension field is present by measuring the MAC size. If 796182007Sroberto * the number of words following the packet header is 0, no MAC 797182007Sroberto * is present and the packet is not authenticated. If 1, the 798182007Sroberto * packet is a crypto-NAK; if 3, the packet is authenticated 799280849Scy * with DES; if 5, the packet is authenticated with MD5; if 6, 800280849Scy * the packet is authenticated with SHA. If 2 or * 4, the packet 801280849Scy * is a runt and discarded forthwith. If greater than 6, an 802280849Scy * extension field is present, so we subtract the length of the 803280849Scy * field and go around again. 804330106Sdelphij * 805330106Sdelphij * Note the above description is lame. We should/could also check 806330106Sdelphij * the two bytes that make up the EF type and subtype, and then 807330106Sdelphij * check the two bytes that tell us the EF length. A legacy MAC 808330106Sdelphij * has a 4 byte keyID, and for conforming symmetric keys its value 809330106Sdelphij * must be <= 64k, meaning the top two bytes will always be zero. 810330106Sdelphij * Since the EF Type of 0 is reserved/unused, there's no way a 811330106Sdelphij * conforming legacy MAC could ever be misinterpreted as an EF. 812330106Sdelphij * 813330106Sdelphij * There is more, but this isn't the place to document it. 81454359Sroberto */ 815298695Sdelphij 81654359Sroberto authlen = LEN_PKT_NOMAC; 817132454Sroberto has_mac = rbufp->recv_length - authlen; 818132454Sroberto while (has_mac > 0) { 819280849Scy u_int32 len; 820280849Scy#ifdef AUTOKEY 821280849Scy u_int32 hostlen; 822280849Scy struct exten *ep; 823280849Scy#endif /*AUTOKEY */ 82482505Sroberto 825280849Scy if (has_mac % 4 != 0 || has_mac < (int)MIN_MAC_LEN) { 826330106Sdelphij DPRINTF(2, ("receive: drop: bad post-packet length\n")); 82754359Sroberto sys_badlength++; 828280849Scy return; /* bad length */ 82954359Sroberto } 830330106Sdelphij /* 831330106Sdelphij * This next test is clearly wrong - it needlessly 832330106Sdelphij * prohibits short EFs (which don't yet exist) 833330106Sdelphij */ 834280849Scy if (has_mac <= (int)MAX_MAC_LEN) { 83582505Sroberto skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]); 83682505Sroberto break; 83754359Sroberto 838280849Scy } else { 839280849Scy opcode = ntohl(((u_int32 *)pkt)[authlen / 4]); 840280849Scy len = opcode & 0xffff; 841289764Sglebius if ( len % 4 != 0 842289764Sglebius || len < 4 843289764Sglebius || (int)len + authlen > rbufp->recv_length) { 844330106Sdelphij DPRINTF(2, ("receive: drop: bad EF length\n")); 84582505Sroberto sys_badlength++; 846280849Scy return; /* bad length */ 84782505Sroberto } 848280849Scy#ifdef AUTOKEY 849280849Scy /* 850280849Scy * Extract calling group name for later. If 851280849Scy * sys_groupname is non-NULL, there must be 852280849Scy * a group name provided to elicit a response. 853280849Scy */ 854289764Sglebius if ( (opcode & 0x3fff0000) == CRYPTO_ASSOC 855289764Sglebius && sys_groupname != NULL) { 856280849Scy ep = (struct exten *)&((u_int32 *)pkt)[authlen / 4]; 857280849Scy hostlen = ntohl(ep->vallen); 858289764Sglebius if ( hostlen >= sizeof(hostname) 859289764Sglebius || hostlen > len - 860289764Sglebius offsetof(struct exten, pkt)) { 861330106Sdelphij DPRINTF(2, ("receive: drop: bad autokey hostname length\n")); 862280849Scy sys_badlength++; 863280849Scy return; /* bad length */ 864280849Scy } 865280849Scy memcpy(hostname, &ep->pkt, hostlen); 866280849Scy hostname[hostlen] = '\0'; 867280849Scy groupname = strchr(hostname, '@'); 868280849Scy if (groupname == NULL) { 869330106Sdelphij DPRINTF(2, ("receive: drop: empty autokey groupname\n")); 870280849Scy sys_declined++; 871280849Scy return; 872280849Scy } 873280849Scy groupname++; 874280849Scy } 875280849Scy#endif /* AUTOKEY */ 876280849Scy authlen += len; 877280849Scy has_mac -= len; 87882505Sroberto } 87954359Sroberto } 88054359Sroberto 88154359Sroberto /* 882280849Scy * If has_mac is < 0 we had a malformed packet. 883280849Scy */ 884280849Scy if (has_mac < 0) { 885330106Sdelphij DPRINTF(2, ("receive: drop: post-packet under-read\n")); 886280849Scy sys_badlength++; 887280849Scy return; /* bad length */ 888280849Scy } 889280849Scy 890280849Scy /* 891330106Sdelphij ** Packet Data Verification Layer 892330106Sdelphij ** 893338530Sdelphij ** This layer verifies the packet data content. If 894330106Sdelphij ** authentication is required, a MAC must be present. 895330106Sdelphij ** If a MAC is present, it must validate. 896330106Sdelphij ** Crypto-NAK? Look - a shiny thing! 897330106Sdelphij ** 898330106Sdelphij ** If authentication fails, we're done. 899330106Sdelphij */ 900330106Sdelphij 901330106Sdelphij /* 902330106Sdelphij * If authentication is explicitly required, a MAC must be present. 903280849Scy */ 904280849Scy if (restrict_mask & RES_DONTTRUST && has_mac == 0) { 905330106Sdelphij DPRINTF(2, ("receive: drop: RES_DONTTRUST\n")); 906280849Scy sys_restricted++; 907280849Scy return; /* access denied */ 908280849Scy } 909280849Scy 910280849Scy /* 911280849Scy * Update the MRU list and finger the cloggers. It can be a 912280849Scy * little expensive, so turn it off for production use. 913280849Scy * RES_LIMITED and RES_KOD will be cleared in the returned 914280849Scy * restrict_mask unless one or both actions are warranted. 915280849Scy */ 916280849Scy restrict_mask = ntp_monitor(rbufp, restrict_mask); 917280849Scy if (restrict_mask & RES_LIMITED) { 918280849Scy sys_limitrejected++; 919289764Sglebius if ( !(restrict_mask & RES_KOD) 920289764Sglebius || MODE_BROADCAST == hismode 921289764Sglebius || MODE_SERVER == hismode) { 922330106Sdelphij if (MODE_SERVER == hismode) { 923280849Scy DPRINTF(1, ("Possibly self-induced rate limiting of MODE_SERVER from %s\n", 924280849Scy stoa(&rbufp->recv_srcadr))); 925330106Sdelphij } else { 926330106Sdelphij DPRINTF(2, ("receive: drop: RES_KOD\n")); 927330106Sdelphij } 928280849Scy return; /* rate exceeded */ 929280849Scy } 930358659Scy if (hismode == MODE_CLIENT) { 931280849Scy fast_xmit(rbufp, MODE_SERVER, skeyid, 932280849Scy restrict_mask); 933358659Scy } else { 934280849Scy fast_xmit(rbufp, MODE_ACTIVE, skeyid, 935280849Scy restrict_mask); 936358659Scy } 937280849Scy return; /* rate exceeded */ 938280849Scy } 939280849Scy restrict_mask &= ~RES_KOD; 940280849Scy 941280849Scy /* 94282505Sroberto * We have tossed out as many buggy packets as possible early in 94382505Sroberto * the game to reduce the exposure to a clogging attack. Now we 94482505Sroberto * have to burn some cycles to find the association and 94582505Sroberto * authenticate the packet if required. Note that we burn only 946280849Scy * digest cycles, again to reduce exposure. There may be no 94782505Sroberto * matching association and that's okay. 94882505Sroberto * 94982505Sroberto * More on the autokey mambo. Normally the local interface is 95082505Sroberto * found when the association was mobilized with respect to a 95182505Sroberto * designated remote address. We assume packets arriving from 95282505Sroberto * the remote address arrive via this interface and the local 95382505Sroberto * address used to construct the autokey is the unicast address 95482505Sroberto * of the interface. However, if the sender is a broadcaster, 95582505Sroberto * the interface broadcast address is used instead. 956280849Scy * Notwithstanding this technobabble, if the sender is a 95782505Sroberto * multicaster, the broadcast address is null, so we use the 95882505Sroberto * unicast address anyway. Don't ask. 95954359Sroberto */ 960330106Sdelphij 961280849Scy peer = findpeer(rbufp, hismode, &retcode); 96282505Sroberto dstadr_sin = &rbufp->dstadr->sin; 963182007Sroberto NTOHL_FP(&pkt->org, &p_org); 964182007Sroberto NTOHL_FP(&pkt->rec, &p_rec); 965182007Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 966293423Sdelphij hm_str = modetoa(hismode); 967293423Sdelphij am_str = amtoa(retcode); 968182007Sroberto 969182007Sroberto /* 970182007Sroberto * Authentication is conditioned by three switches: 971182007Sroberto * 972182007Sroberto * NOPEER (RES_NOPEER) do not mobilize an association unless 973182007Sroberto * authenticated 974182007Sroberto * NOTRUST (RES_DONTTRUST) do not allow access unless 975182007Sroberto * authenticated (implies NOPEER) 976182007Sroberto * enable (sys_authenticate) master NOPEER switch, by default 977182007Sroberto * on 978182007Sroberto * 979182007Sroberto * The NOPEER and NOTRUST can be specified on a per-client basis 980182007Sroberto * using the restrict command. The enable switch if on implies 981182007Sroberto * NOPEER for all clients. There are four outcomes: 982182007Sroberto * 983182007Sroberto * NONE The packet has no MAC. 984182007Sroberto * OK the packet has a MAC and authentication succeeds 985182007Sroberto * ERROR the packet has a MAC and authentication fails 986182007Sroberto * CRYPTO crypto-NAK. The MAC has four octets only. 987182007Sroberto * 988182007Sroberto * Note: The AUTH(x, y) macro is used to filter outcomes. If x 989182007Sroberto * is zero, acceptable outcomes of y are NONE and OK. If x is 990182007Sroberto * one, the only acceptable outcome of y is OK. 991182007Sroberto */ 992298695Sdelphij crypto_nak_test = valid_NAK(peer, rbufp, hismode); 993280849Scy 994298695Sdelphij /* 995298695Sdelphij * Drop any invalid crypto-NAKs 996298695Sdelphij */ 997298695Sdelphij if (crypto_nak_test == INVALIDNAK) { 998298695Sdelphij report_event(PEVNT_AUTH, peer, "Invalid_NAK"); 999298695Sdelphij if (0 != peer) { 1000298695Sdelphij peer->badNAK++; 1001298695Sdelphij } 1002338530Sdelphij msyslog(LOG_ERR, "Invalid-NAK error at %ld %s<-%s", 1003298695Sdelphij current_time, stoa(dstadr_sin), stoa(&rbufp->recv_srcadr)); 1004298695Sdelphij return; 1005298695Sdelphij } 1006298695Sdelphij 100754359Sroberto if (has_mac == 0) { 1008280849Scy restrict_mask &= ~RES_MSSNTP; 1009182007Sroberto is_authentic = AUTH_NONE; /* not required */ 1010338530Sdelphij DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n", 1011182007Sroberto current_time, stoa(dstadr_sin), 1012293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 1013293423Sdelphij authlen, 1014293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1015293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 1016298695Sdelphij } else if (crypto_nak_test == VALIDNAK) { 1017280849Scy restrict_mask &= ~RES_MSSNTP; 1018280849Scy is_authentic = AUTH_CRYPTO; /* crypto-NAK */ 1019338530Sdelphij DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x CRYPTONAK\n", 1020182007Sroberto current_time, stoa(dstadr_sin), 1021293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 1022293423Sdelphij skeyid, authlen + has_mac, is_authentic, 1023293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1024293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 1025280849Scy 1026280849Scy#ifdef HAVE_NTP_SIGND 1027280849Scy /* 1028280849Scy * If the signature is 20 bytes long, the last 16 of 1029280849Scy * which are zero, then this is a Microsoft client 1030280849Scy * wanting AD-style authentication of the server's 1031282408Scy * reply. 1032280849Scy * 1033280849Scy * This is described in Microsoft's WSPP docs, in MS-SNTP: 1034280849Scy * http://msdn.microsoft.com/en-us/library/cc212930.aspx 1035280849Scy */ 1036289764Sglebius } else if ( has_mac == MAX_MD5_LEN 1037289764Sglebius && (restrict_mask & RES_MSSNTP) 1038289764Sglebius && (retcode == AM_FXMIT || retcode == AM_NEWPASS) 1039289764Sglebius && (memcmp(zero_key, (char *)pkt + authlen + 4, 1040293423Sdelphij MAX_MD5_LEN - 4) == 0)) { 1041280849Scy is_authentic = AUTH_NONE; 1042338530Sdelphij DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x SIGND\n", 1043338530Sdelphij current_time, stoa(dstadr_sin), 1044338530Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 1045338530Sdelphij authlen, 1046338530Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1047338530Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 1048280849Scy#endif /* HAVE_NTP_SIGND */ 1049280849Scy 105054359Sroberto } else { 1051330106Sdelphij /* 1052330106Sdelphij * has_mac is not 0 1053330106Sdelphij * Not a VALID_NAK 1054338530Sdelphij * Not an MS-SNTP SIGND packet 1055330106Sdelphij * 1056330106Sdelphij * So there is a MAC here. 1057330106Sdelphij */ 1058330106Sdelphij 1059280849Scy restrict_mask &= ~RES_MSSNTP; 1060280849Scy#ifdef AUTOKEY 106182505Sroberto /* 106282505Sroberto * For autokey modes, generate the session key 106382505Sroberto * and install in the key cache. Use the socket 106482505Sroberto * broadcast or unicast address as appropriate. 106582505Sroberto */ 1066280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) { 1067282408Scy 106882505Sroberto /* 106982505Sroberto * More on the autokey dance (AKD). A cookie is 107082505Sroberto * constructed from public and private values. 107182505Sroberto * For broadcast packets, the cookie is public 107282505Sroberto * (zero). For packets that match no 107382505Sroberto * association, the cookie is hashed from the 107482505Sroberto * addresses and private value. For server 107582505Sroberto * packets, the cookie was previously obtained 107682505Sroberto * from the server. For symmetric modes, the 107782505Sroberto * cookie was previously constructed using an 107882505Sroberto * agreement protocol; however, should PKI be 107982505Sroberto * unavailable, we construct a fake agreement as 108082505Sroberto * the EXOR of the peer and host cookies. 108182505Sroberto * 108282505Sroberto * hismode ephemeral persistent 108382505Sroberto * ======================================= 108482505Sroberto * active 0 cookie# 108582505Sroberto * passive 0% cookie# 108682505Sroberto * client sys cookie 0% 108782505Sroberto * server 0% sys cookie 108882505Sroberto * broadcast 0 0 108982505Sroberto * 109082505Sroberto * # if unsync, 0 109182505Sroberto * % can't happen 109282505Sroberto */ 1093280849Scy if (has_mac < (int)MAX_MD5_LEN) { 1094330106Sdelphij DPRINTF(2, ("receive: drop: MD5 digest too short\n")); 1095280849Scy sys_badauth++; 1096280849Scy return; 1097280849Scy } 109882505Sroberto if (hismode == MODE_BROADCAST) { 109954359Sroberto 110082505Sroberto /* 110182505Sroberto * For broadcaster, use the interface 110282505Sroberto * broadcast address when available; 110382505Sroberto * otherwise, use the unicast address 110482505Sroberto * found when the association was 1105182007Sroberto * mobilized. However, if this is from 1106182007Sroberto * the wildcard interface, game over. 110782505Sroberto */ 1108289764Sglebius if ( crypto_flags 1109289764Sglebius && rbufp->dstadr == 1110289764Sglebius ANY_INTERFACE_CHOOSE(&rbufp->recv_srcadr)) { 1111330106Sdelphij DPRINTF(2, ("receive: drop: BCAST from wildcard\n")); 1112182007Sroberto sys_restricted++; 1113338530Sdelphij return; /* no wildcard */ 1114182007Sroberto } 111582505Sroberto pkeyid = 0; 1116280849Scy if (!SOCK_UNSPEC(&rbufp->dstadr->bcast)) 111782505Sroberto dstadr_sin = 111882505Sroberto &rbufp->dstadr->bcast; 111982505Sroberto } else if (peer == NULL) { 112082505Sroberto pkeyid = session_key( 112182505Sroberto &rbufp->recv_srcadr, dstadr_sin, 0, 112282505Sroberto sys_private, 0); 112382505Sroberto } else { 1124132454Sroberto pkeyid = peer->pcookie; 112582505Sroberto } 112682505Sroberto 112754359Sroberto /* 112882505Sroberto * The session key includes both the public 112982505Sroberto * values and cookie. In case of an extension 113082505Sroberto * field, the cookie used for authentication 113182505Sroberto * purposes is zero. Note the hash is saved for 113282505Sroberto * use later in the autokey mambo. 113354359Sroberto */ 1134280849Scy if (authlen > (int)LEN_PKT_NOMAC && pkeyid != 0) { 113582505Sroberto session_key(&rbufp->recv_srcadr, 113682505Sroberto dstadr_sin, skeyid, 0, 2); 113754359Sroberto tkeyid = session_key( 113882505Sroberto &rbufp->recv_srcadr, dstadr_sin, 113982505Sroberto skeyid, pkeyid, 0); 114082505Sroberto } else { 114154359Sroberto tkeyid = session_key( 114282505Sroberto &rbufp->recv_srcadr, dstadr_sin, 114382505Sroberto skeyid, pkeyid, 2); 114454359Sroberto } 114554359Sroberto 114654359Sroberto } 1147280849Scy#endif /* AUTOKEY */ 114854359Sroberto 114954359Sroberto /* 115054359Sroberto * Compute the cryptosum. Note a clogging attack may 115182505Sroberto * succeed in bloating the key cache. If an autokey, 115282505Sroberto * purge it immediately, since we won't be needing it 1153182007Sroberto * again. If the packet is authentic, it can mobilize an 1154182007Sroberto * association. Note that there is no key zero. 115554359Sroberto */ 1156182007Sroberto if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, 1157280849Scy has_mac)) 1158182007Sroberto is_authentic = AUTH_ERROR; 1159280849Scy else 1160182007Sroberto is_authentic = AUTH_OK; 1161280849Scy#ifdef AUTOKEY 1162280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) 116382505Sroberto authtrust(skeyid, 0); 1164280849Scy#endif /* AUTOKEY */ 1165338530Sdelphij DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC\n", 1166132454Sroberto current_time, stoa(dstadr_sin), 1167293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 1168293423Sdelphij skeyid, authlen + has_mac, is_authentic, 1169293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1170293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 117154359Sroberto } 117254359Sroberto 1173330106Sdelphij 117454359Sroberto /* 1175330106Sdelphij * Bug 3454: 1176330106Sdelphij * 1177330106Sdelphij * Now come at this from a different perspective: 1178330106Sdelphij * - If we expect a MAC and it's not there, we drop it. 1179330106Sdelphij * - If we expect one keyID and get another, we drop it. 1180330106Sdelphij * - If we have a MAC ahd it hasn't been validated yet, try. 1181330106Sdelphij * - if the provided MAC doesn't validate, we drop it. 1182330106Sdelphij * 1183330106Sdelphij * There might be more to this. 1184330106Sdelphij */ 1185330106Sdelphij if (0 != peer && 0 != peer->keyid) { 1186330106Sdelphij /* Should we msyslog() any of these? */ 1187330106Sdelphij 1188330106Sdelphij /* 1189330106Sdelphij * This should catch: 1190330106Sdelphij * - no keyID where one is expected, 1191330106Sdelphij * - different keyID than what we expect. 1192330106Sdelphij */ 1193330106Sdelphij if (peer->keyid != skeyid) { 1194330106Sdelphij DPRINTF(2, ("receive: drop: Wanted keyID %d, got %d from %s\n", 1195330106Sdelphij peer->keyid, skeyid, 1196330106Sdelphij stoa(&rbufp->recv_srcadr))); 1197330106Sdelphij sys_restricted++; 1198330106Sdelphij return; /* drop: access denied */ 1199330106Sdelphij } 1200330106Sdelphij 1201330106Sdelphij /* 1202330106Sdelphij * if has_mac != 0 ... 1203330106Sdelphij * - If it has not yet been validated, do so. 1204330106Sdelphij * (under what circumstances might that happen?) 1205330106Sdelphij * - if missing or bad MAC, log and drop. 1206330106Sdelphij */ 1207330106Sdelphij if (0 != has_mac) { 1208330106Sdelphij if (is_authentic == AUTH_UNKNOWN) { 1209330106Sdelphij /* How can this happen? */ 1210330106Sdelphij DPRINTF(2, ("receive: 3454 check: AUTH_UNKNOWN from %s\n", 1211330106Sdelphij stoa(&rbufp->recv_srcadr))); 1212330106Sdelphij if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, 1213330106Sdelphij has_mac)) { 1214330106Sdelphij /* MAC invalid or not found */ 1215330106Sdelphij is_authentic = AUTH_ERROR; 1216330106Sdelphij } else { 1217330106Sdelphij is_authentic = AUTH_OK; 1218330106Sdelphij } 1219330106Sdelphij } 1220330106Sdelphij if (is_authentic != AUTH_OK) { 1221330106Sdelphij DPRINTF(2, ("receive: drop: missing or bad MAC from %s\n", 1222330106Sdelphij stoa(&rbufp->recv_srcadr))); 1223330106Sdelphij sys_restricted++; 1224330106Sdelphij return; /* drop: access denied */ 1225330106Sdelphij } 1226330106Sdelphij } 1227330106Sdelphij } 1228330106Sdelphij /**/ 1229330106Sdelphij 1230330106Sdelphij /* 1231330106Sdelphij ** On-Wire Protocol Layer 1232330106Sdelphij ** 1233330106Sdelphij ** Verify protocol operations consistent with the on-wire protocol. 1234330106Sdelphij ** The protocol discards bogus and duplicate packets as well as 1235330106Sdelphij ** minimizes disruptions doe to protocol restarts and dropped 1236330106Sdelphij ** packets. The operations are controlled by two timestamps: 1237330106Sdelphij ** the transmit timestamp saved in the client state variables, 1238330106Sdelphij ** and the origin timestamp in the server packet header. The 1239330106Sdelphij ** comparison of these two timestamps is called the loopback test. 1240330106Sdelphij ** The transmit timestamp functions as a nonce to verify that the 1241330106Sdelphij ** response corresponds to the original request. The transmit 1242330106Sdelphij ** timestamp also serves to discard replays of the most recent 1243330106Sdelphij ** packet. Upon failure of either test, the packet is discarded 1244330106Sdelphij ** with no further action. 1245330106Sdelphij */ 1246330106Sdelphij 1247330106Sdelphij /* 124882505Sroberto * The association matching rules are implemented by a set of 1249182007Sroberto * routines and an association table. A packet matching an 1250182007Sroberto * association is processed by the peer process for that 1251182007Sroberto * association. If there are no errors, an ephemeral association 1252182007Sroberto * is mobilized: a broadcast packet mobilizes a broadcast client 1253132454Sroberto * aassociation; a manycast server packet mobilizes a manycast 1254132454Sroberto * client association; a symmetric active packet mobilizes a 1255182007Sroberto * symmetric passive association. 125654359Sroberto */ 1257338530Sdelphij DPRINTF(1, ("receive: MATCH_ASSOC dispatch: mode %d/%s:%s \n", 1258338530Sdelphij hismode, hm_str, am_str)); 125954359Sroberto switch (retcode) { 1260182007Sroberto 1261182007Sroberto /* 1262182007Sroberto * This is a client mode packet not matching any association. If 1263182007Sroberto * an ordinary client, simply toss a server mode packet back 1264182007Sroberto * over the fence. If a manycast client, we have to work a 1265182007Sroberto * little harder. 1266330106Sdelphij * 1267330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1268182007Sroberto */ 126954359Sroberto case AM_FXMIT: 127054359Sroberto 127156749Sroberto /* 1272280849Scy * If authentication OK, send a server reply; otherwise, 1273280849Scy * send a crypto-NAK. 127456749Sroberto */ 1275182007Sroberto if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) { 1276330106Sdelphij /* HMS: would be nice to log FAST_XMIT|BADAUTH|RESTRICTED */ 1277330106Sdelphij record_raw_stats(&rbufp->recv_srcadr, 1278330106Sdelphij &rbufp->dstadr->sin, 1279330106Sdelphij &p_org, &p_rec, &p_xmt, &rbufp->recv_time, 1280330106Sdelphij PKT_LEAP(pkt->li_vn_mode), 1281330106Sdelphij PKT_VERSION(pkt->li_vn_mode), 1282330106Sdelphij PKT_MODE(pkt->li_vn_mode), 1283330106Sdelphij PKT_TO_STRATUM(pkt->stratum), 1284330106Sdelphij pkt->ppoll, 1285330106Sdelphij pkt->precision, 1286330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdelay)), 1287330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdisp)), 1288330106Sdelphij pkt->refid, 1289330106Sdelphij rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 1290330106Sdelphij 1291182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, 1292280849Scy is_authentic)) { 1293358659Scy /* Bug 3596: Do we want to fuzz the reftime? */ 1294182007Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 1295182007Sroberto restrict_mask); 1296280849Scy } else if (is_authentic == AUTH_ERROR) { 1297358659Scy /* Bug 3596: Do we want to fuzz the reftime? */ 1298182007Sroberto fast_xmit(rbufp, MODE_SERVER, 0, 1299182007Sroberto restrict_mask); 1300280849Scy sys_badauth++; 1301280849Scy } else { 1302330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: !mcast restricted\n")); 1303280849Scy sys_restricted++; 1304280849Scy } 1305330106Sdelphij 1306182007Sroberto return; /* hooray */ 130756749Sroberto } 130854359Sroberto 130956749Sroberto /* 1310182007Sroberto * This must be manycast. Do not respond if not 1311182007Sroberto * configured as a manycast server. 131256749Sroberto */ 1313182007Sroberto if (!sys_manycastserver) { 1314330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: Not manycastserver\n")); 1315182007Sroberto sys_restricted++; 1316182007Sroberto return; /* not enabled */ 1317182007Sroberto } 1318182007Sroberto 1319280849Scy#ifdef AUTOKEY 1320182007Sroberto /* 1321280849Scy * Do not respond if not the same group. 1322182007Sroberto */ 1323280849Scy if (group_test(groupname, NULL)) { 1324330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: empty groupname\n")); 1325280849Scy sys_declined++; 1326280849Scy return; 1327280849Scy } 1328280849Scy#endif /* AUTOKEY */ 1329182007Sroberto 1330182007Sroberto /* 1331280849Scy * Do not respond if we are not synchronized or our 1332280849Scy * stratum is greater than the manycaster or the 1333280849Scy * manycaster has already synchronized to us. 1334182007Sroberto */ 1335289764Sglebius if ( sys_leap == LEAP_NOTINSYNC 1336362716Scy || sys_stratum > hisstratum + 1 1337289764Sglebius || (!sys_cohort && sys_stratum == hisstratum + 1) 1338289764Sglebius || rbufp->dstadr->addr_refid == pkt->refid) { 1339362716Scy DPRINTF(2, ("receive: sys leap: %0x, sys_stratum %d > hisstratum+1 %d, !sys_cohort %d && sys_stratum == hisstratum+1, loop refid %#x == pkt refid %#x\n", sys_leap, sys_stratum, hisstratum + 1, !sys_cohort, rbufp->dstadr->addr_refid, pkt->refid)); 1340330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: LEAP_NOTINSYNC || stratum || loop\n")); 1341280849Scy sys_declined++; 1342182007Sroberto return; /* no help */ 1343280849Scy } 1344182007Sroberto 1345182007Sroberto /* 1346182007Sroberto * Respond only if authentication succeeds. Don't do a 1347182007Sroberto * crypto-NAK, as that would not be useful. 1348182007Sroberto */ 1349330106Sdelphij if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) { 1350330106Sdelphij record_raw_stats(&rbufp->recv_srcadr, 1351330106Sdelphij &rbufp->dstadr->sin, 1352330106Sdelphij &p_org, &p_rec, &p_xmt, &rbufp->recv_time, 1353330106Sdelphij PKT_LEAP(pkt->li_vn_mode), 1354330106Sdelphij PKT_VERSION(pkt->li_vn_mode), 1355330106Sdelphij PKT_MODE(pkt->li_vn_mode), 1356330106Sdelphij PKT_TO_STRATUM(pkt->stratum), 1357330106Sdelphij pkt->ppoll, 1358330106Sdelphij pkt->precision, 1359330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdelay)), 1360330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdisp)), 1361330106Sdelphij pkt->refid, 1362330106Sdelphij rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 1363330106Sdelphij 1364358659Scy /* Bug 3596: Do we want to fuzz the reftime? */ 136582505Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 136682505Sroberto restrict_mask); 1367330106Sdelphij } 1368182007Sroberto return; /* hooray */ 1369182007Sroberto 1370182007Sroberto /* 1371182007Sroberto * This is a server mode packet returned in response to a client 1372280849Scy * mode packet sent to a multicast group address (for 1373280849Scy * manycastclient) or to a unicast address (for pool). The 1374280849Scy * origin timestamp is a good nonce to reliably associate the 1375280849Scy * reply with what was sent. If there is no match, that's 1376280849Scy * curious and could be an intruder attempting to clog, so we 1377280849Scy * just ignore it. 1378182007Sroberto * 1379282408Scy * If the packet is authentic and the manycastclient or pool 1380280849Scy * association is found, we mobilize a client association and 1381280849Scy * copy pertinent variables from the manycastclient or pool 1382280849Scy * association to the new client association. If not, just 1383280849Scy * ignore the packet. 1384182007Sroberto * 1385182007Sroberto * There is an implosion hazard at the manycast client, since 1386182007Sroberto * the manycast servers send the server packet immediately. If 1387182007Sroberto * the guy is already here, don't fire up a duplicate. 1388330106Sdelphij * 1389330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1390182007Sroberto */ 139154359Sroberto case AM_MANYCAST: 139254359Sroberto 1393280849Scy#ifdef AUTOKEY 1394280849Scy /* 1395280849Scy * Do not respond if not the same group. 1396280849Scy */ 1397280849Scy if (group_test(groupname, NULL)) { 1398330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: empty groupname\n")); 1399280849Scy sys_declined++; 1400280849Scy return; 1401280849Scy } 1402280849Scy#endif /* AUTOKEY */ 1403182007Sroberto if ((peer2 = findmanycastpeer(rbufp)) == NULL) { 1404330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: No manycast peer\n")); 1405132454Sroberto sys_restricted++; 1406182007Sroberto return; /* not enabled */ 1407132454Sroberto } 1408289764Sglebius if (!AUTH( (!(peer2->cast_flags & MDF_POOL) 1409289764Sglebius && sys_authenticate) 1410289764Sglebius || (restrict_mask & (RES_NOPEER | 1411330106Sdelphij RES_DONTTRUST)), is_authentic) 1412330106Sdelphij /* MC: RES_NOEPEER? */ 1413330106Sdelphij ) { 1414330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: bad auth || (NOPEER|DONTTRUST)\n")); 1415280849Scy sys_restricted++; 1416280849Scy return; /* access denied */ 1417280849Scy } 1418132454Sroberto 1419132454Sroberto /* 1420280849Scy * Do not respond if unsynchronized or stratum is below 1421280849Scy * the floor or at or above the ceiling. 1422132454Sroberto */ 1423289764Sglebius if ( hisleap == LEAP_NOTINSYNC 1424289764Sglebius || hisstratum < sys_floor 1425289764Sglebius || hisstratum >= sys_ceiling) { 1426330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: unsync/stratum\n")); 1427280849Scy sys_declined++; 1428280849Scy return; /* no help */ 1429280849Scy } 1430280849Scy peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr, 1431330106Sdelphij r4a.ippeerlimit, MODE_CLIENT, hisversion, 1432330106Sdelphij peer2->minpoll, peer2->maxpoll, 1433358659Scy (FLAG_PREEMPT | (POOL_FLAG_PMASK & peer2->flags)), 1434358659Scy (MDF_UCAST | MDF_UCLNT), 0, skeyid, sys_ident); 1435280849Scy if (NULL == peer) { 1436330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: duplicate\n")); 1437280849Scy sys_declined++; 1438338530Sdelphij return; /* ignore duplicate */ 1439280849Scy } 144056749Sroberto 1441280849Scy /* 1442280849Scy * After each ephemeral pool association is spun, 1443280849Scy * accelerate the next poll for the pool solicitor so 1444280849Scy * the pool will fill promptly. 1445280849Scy */ 1446280849Scy if (peer2->cast_flags & MDF_POOL) 1447280849Scy peer2->nextdate = current_time + 1; 1448280849Scy 1449280849Scy /* 1450280849Scy * Further processing of the solicitation response would 1451280849Scy * simply detect its origin timestamp as bogus for the 1452280849Scy * brand-new association (it matches the prototype 1453280849Scy * association) and tinker with peer->nextdate delaying 1454280849Scy * first sync. 1455280849Scy */ 1456280849Scy return; /* solicitation response handled */ 1457280849Scy 1458182007Sroberto /* 1459182007Sroberto * This is the first packet received from a broadcast server. If 1460182007Sroberto * the packet is authentic and we are enabled as broadcast 1461182007Sroberto * client, mobilize a broadcast client association. We don't 1462182007Sroberto * kiss any frogs here. 1463330106Sdelphij * 1464330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1465182007Sroberto */ 1466182007Sroberto case AM_NEWBCL: 1467280849Scy 1468280849Scy#ifdef AUTOKEY 1469280849Scy /* 1470280849Scy * Do not respond if not the same group. 1471280849Scy */ 1472280849Scy if (group_test(groupname, sys_ident)) { 1473330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: groupname mismatch\n")); 1474280849Scy sys_declined++; 1475280849Scy return; 1476280849Scy } 1477280849Scy#endif /* AUTOKEY */ 1478280849Scy if (sys_bclient == 0) { 1479330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: not a bclient\n")); 1480280849Scy sys_restricted++; 1481280849Scy return; /* not enabled */ 1482280849Scy } 1483182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 1484330106Sdelphij (RES_NOPEER | RES_DONTTRUST)), is_authentic) 1485330106Sdelphij /* NEWBCL: RES_NOEPEER? */ 1486330106Sdelphij ) { 1487330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: AUTH failed\n")); 1488280849Scy sys_restricted++; 1489280849Scy return; /* access denied */ 1490280849Scy } 149154359Sroberto 149256749Sroberto /* 1493182007Sroberto * Do not respond if unsynchronized or stratum is below 1494182007Sroberto * the floor or at or above the ceiling. 149556749Sroberto */ 1496289764Sglebius if ( hisleap == LEAP_NOTINSYNC 1497289764Sglebius || hisstratum < sys_floor 1498289764Sglebius || hisstratum >= sys_ceiling) { 1499330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Unsync or bad stratum\n")); 1500280849Scy sys_declined++; 1501280849Scy return; /* no help */ 1502280849Scy } 1503132454Sroberto 1504280849Scy#ifdef AUTOKEY 150556749Sroberto /* 1506280849Scy * Do not respond if Autokey and the opcode is not a 1507280849Scy * CRYPTO_ASSOC response with association ID. 150856749Sroberto */ 1509289764Sglebius if ( crypto_flags && skeyid > NTP_MAXKEY 1510289764Sglebius && (opcode & 0xffff0000) != (CRYPTO_ASSOC | CRYPTO_RESP)) { 1511330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not CRYPTO_ASSOC\n")); 1512280849Scy sys_declined++; 1513280849Scy return; /* protocol error */ 1514280849Scy } 1515280849Scy#endif /* AUTOKEY */ 151682505Sroberto 1517132454Sroberto /* 1518280849Scy * Broadcasts received via a multicast address may 1519280849Scy * arrive after a unicast volley has begun 1520280849Scy * with the same remote address. newpeer() will not 1521280849Scy * find duplicate associations on other local endpoints 1522280849Scy * if a non-NULL endpoint is supplied. multicastclient 1523280849Scy * ephemeral associations are unique across all local 1524280849Scy * endpoints. 1525132454Sroberto */ 1526280849Scy if (!(INT_MCASTOPEN & rbufp->dstadr->flags)) 1527280849Scy match_ep = rbufp->dstadr; 1528280849Scy else 1529280849Scy match_ep = NULL; 153056749Sroberto 1531132454Sroberto /* 1532280849Scy * Determine whether to execute the initial volley. 153356749Sroberto */ 1534298695Sdelphij if (sys_bdelay > 0.0) { 1535280849Scy#ifdef AUTOKEY 1536182007Sroberto /* 1537182007Sroberto * If a two-way exchange is not possible, 1538182007Sroberto * neither is Autokey. 1539182007Sroberto */ 1540280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) { 1541280849Scy sys_restricted++; 1542330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not 2-way\n")); 1543182007Sroberto return; /* no autokey */ 1544182007Sroberto } 1545280849Scy#endif /* AUTOKEY */ 1546280849Scy 1547280849Scy /* 1548280849Scy * Do not execute the volley. Start out in 1549280849Scy * broadcast client mode. 1550280849Scy */ 1551330106Sdelphij peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, 1552330106Sdelphij r4a.ippeerlimit, MODE_BCLIENT, hisversion, 1553330106Sdelphij pkt->ppoll, pkt->ppoll, 1554330106Sdelphij FLAG_PREEMPT, MDF_BCLNT, 0, skeyid, sys_ident); 1555280849Scy if (NULL == peer) { 1556330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: duplicate\n")); 1557280849Scy sys_restricted++; 1558280849Scy return; /* ignore duplicate */ 1559280849Scy 1560280849Scy } else { 1561280849Scy peer->delay = sys_bdelay; 1562294554Sdelphij peer->bxmt = p_xmt; 1563280849Scy } 1564280849Scy break; 1565132454Sroberto } 156656749Sroberto 1567280849Scy /* 1568280849Scy * Execute the initial volley in order to calibrate the 1569280849Scy * propagation delay and run the Autokey protocol. 1570280849Scy * 1571280849Scy * Note that the minpoll is taken from the broadcast 1572280849Scy * packet, normally 6 (64 s) and that the poll interval 1573280849Scy * is fixed at this value. 1574280849Scy */ 1575280849Scy peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, 1576338530Sdelphij r4a.ippeerlimit, MODE_CLIENT, hisversion, 1577338530Sdelphij pkt->ppoll, pkt->ppoll, 1578338530Sdelphij FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT, 1579338530Sdelphij 0, skeyid, sys_ident); 1580280849Scy if (NULL == peer) { 1581330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: empty newpeer() failed\n")); 1582280849Scy sys_restricted++; 1583280849Scy return; /* ignore duplicate */ 1584280849Scy } 1585294554Sdelphij peer->bxmt = p_xmt; 1586280849Scy#ifdef AUTOKEY 1587280849Scy if (skeyid > NTP_MAXKEY) 1588280849Scy crypto_recv(peer, rbufp); 1589280849Scy#endif /* AUTOKEY */ 1590280849Scy 1591280849Scy return; /* hooray */ 1592280849Scy 1593182007Sroberto /* 1594338530Sdelphij * This is the first packet received from a potential ephemeral 1595338530Sdelphij * symmetric active peer. First, deal with broken Windows clients. 1596338530Sdelphij * Then, if NOEPEER is enabled, drop it. If the packet meets our 1597338530Sdelphij * authenticty requirements and is the first he sent, mobilize 1598338530Sdelphij * a passive association. 1599338530Sdelphij * Otherwise, kiss the frog. 1600330106Sdelphij * 1601330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1602182007Sroberto */ 1603182007Sroberto case AM_NEWPASS: 160456749Sroberto 1605338530Sdelphij DEBUG_REQUIRE(MODE_ACTIVE == hismode); 1606338530Sdelphij 1607280849Scy#ifdef AUTOKEY 160856749Sroberto /* 1609280849Scy * Do not respond if not the same group. 161056749Sroberto */ 1611280849Scy if (group_test(groupname, sys_ident)) { 1612330106Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n")); 1613280849Scy sys_declined++; 1614280849Scy return; 1615280849Scy } 1616280849Scy#endif /* AUTOKEY */ 1617280849Scy if (!AUTH(sys_authenticate | (restrict_mask & 1618330106Sdelphij (RES_NOPEER | RES_DONTTRUST)), is_authentic) 1619330106Sdelphij ) { 1620338530Sdelphij /* 1621338530Sdelphij * If authenticated but cannot mobilize an 1622338530Sdelphij * association, send a symmetric passive 1623338530Sdelphij * response without mobilizing an association. 1624338530Sdelphij * This is for drat broken Windows clients. See 1625338530Sdelphij * Microsoft KB 875424 for preferred workaround. 1626338530Sdelphij */ 1627338530Sdelphij if (AUTH(restrict_mask & RES_DONTTRUST, 1628338530Sdelphij is_authentic)) { 1629338530Sdelphij fast_xmit(rbufp, MODE_PASSIVE, skeyid, 1630338530Sdelphij restrict_mask); 1631338530Sdelphij return; /* hooray */ 1632280849Scy } 1633338530Sdelphij /* HMS: Why is this next set of lines a feature? */ 1634338530Sdelphij if (is_authentic == AUTH_ERROR) { 1635338530Sdelphij fast_xmit(rbufp, MODE_PASSIVE, 0, 1636338530Sdelphij restrict_mask); 1637338530Sdelphij sys_restricted++; 1638338530Sdelphij return; 1639338530Sdelphij } 1640338530Sdelphij 1641338530Sdelphij if (restrict_mask & RES_NOEPEER) { 1642338530Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n")); 1643338530Sdelphij sys_declined++; 1644338530Sdelphij return; 1645338530Sdelphij } 1646338530Sdelphij 1647289764Sglebius /* [Bug 2941] 1648289764Sglebius * If we got here, the packet isn't part of an 1649330106Sdelphij * existing association, either isn't correctly 1650330106Sdelphij * authenticated or it is but we are refusing 1651330106Sdelphij * ephemeral peer requests, and it didn't meet 1652330106Sdelphij * either of the previous two special cases so we 1653330106Sdelphij * should just drop it on the floor. For example, 1654289764Sglebius * crypto-NAKs (is_authentic == AUTH_CRYPTO) 1655289764Sglebius * will make it this far. This is just 1656289764Sglebius * debug-printed and not logged to avoid log 1657289764Sglebius * flooding. 1658289764Sglebius */ 1659293423Sdelphij DPRINTF(2, ("receive: at %ld refusing to mobilize passive association" 1660293423Sdelphij " with unknown peer %s mode %d/%s:%s keyid %08x len %d auth %d\n", 1661289764Sglebius current_time, stoa(&rbufp->recv_srcadr), 1662293423Sdelphij hismode, hm_str, am_str, skeyid, 1663293423Sdelphij (authlen + has_mac), is_authentic)); 1664289764Sglebius sys_declined++; 1665289764Sglebius return; 1666182007Sroberto } 1667280849Scy 1668338530Sdelphij if (restrict_mask & RES_NOEPEER) { 1669338530Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n")); 1670338530Sdelphij sys_declined++; 1671338530Sdelphij return; 1672338530Sdelphij } 1673338530Sdelphij 1674280849Scy /* 1675280849Scy * Do not respond if synchronized and if stratum is 1676280849Scy * below the floor or at or above the ceiling. Note, 1677280849Scy * this allows an unsynchronized peer to synchronize to 1678280849Scy * us. It would be very strange if he did and then was 1679280849Scy * nipped, but that could only happen if we were 1680280849Scy * operating at the top end of the range. It also means 1681280849Scy * we will spin an ephemeral association in response to 1682280849Scy * MODE_ACTIVE KoDs, which will time out eventually. 1683280849Scy */ 1684289764Sglebius if ( hisleap != LEAP_NOTINSYNC 1685362716Scy && (hisstratum < sys_floor || hisstratum >= sys_ceiling)) { 1686362716Scy DPRINTF(2, ("receive: AM_NEWPASS drop: Remote stratum (%d) out of range\n", 1687362716Scy hisstratum)); 1688280849Scy sys_declined++; 1689280849Scy return; /* no help */ 1690182007Sroberto } 169154359Sroberto 1692182007Sroberto /* 1693280849Scy * The message is correctly authenticated and allowed. 1694330106Sdelphij * Mobilize a symmetric passive association, if we won't 1695330106Sdelphij * exceed the ippeerlimit. 1696182007Sroberto */ 1697330106Sdelphij if ((peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr, 1698330106Sdelphij r4a.ippeerlimit, MODE_PASSIVE, hisversion, 1699330106Sdelphij pkt->ppoll, NTP_MAXDPOLL, 0, MDF_UCAST, 0, 1700330106Sdelphij skeyid, sys_ident)) == NULL) { 1701330106Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: newpeer() failed\n")); 1702280849Scy sys_declined++; 1703280849Scy return; /* ignore duplicate */ 1704280849Scy } 1705182007Sroberto break; 1706182007Sroberto 1707280849Scy 170854359Sroberto /* 1709182007Sroberto * Process regular packet. Nothing special. 1710330106Sdelphij * 1711330106Sdelphij * There are cases here where we do not call record_raw_stats(). 171254359Sroberto */ 1713182007Sroberto case AM_PROCPKT: 1714280849Scy 1715280849Scy#ifdef AUTOKEY 1716280849Scy /* 1717280849Scy * Do not respond if not the same group. 1718280849Scy */ 1719280849Scy if (group_test(groupname, peer->ident)) { 1720330106Sdelphij DPRINTF(2, ("receive: AM_PROCPKT drop: Autokey group mismatch\n")); 1721280849Scy sys_declined++; 1722280849Scy return; 1723280849Scy } 1724280849Scy#endif /* AUTOKEY */ 1725294554Sdelphij 1726294554Sdelphij if (MODE_BROADCAST == hismode) { 1727298695Sdelphij int bail = 0; 1728298695Sdelphij l_fp tdiff; 1729298695Sdelphij u_long deadband; 1730294554Sdelphij 1731294554Sdelphij DPRINTF(2, ("receive: PROCPKT/BROADCAST: prev pkt %ld seconds ago, ppoll: %d, %d secs\n", 1732294554Sdelphij (current_time - peer->timelastrec), 1733294554Sdelphij peer->ppoll, (1 << peer->ppoll) 1734294554Sdelphij )); 1735294554Sdelphij /* Things we can check: 1736294554Sdelphij * 1737294554Sdelphij * Did the poll interval change? 1738294554Sdelphij * Is the poll interval in the packet in-range? 1739294554Sdelphij * Did this packet arrive too soon? 1740294554Sdelphij * Is the timestamp in this packet monotonic 1741294554Sdelphij * with respect to the previous packet? 1742294554Sdelphij */ 1743294554Sdelphij 1744294554Sdelphij /* This is noteworthy, not error-worthy */ 1745294554Sdelphij if (pkt->ppoll != peer->ppoll) { 1746330106Sdelphij msyslog(LOG_INFO, "receive: broadcast poll from %s changed from %u to %u", 1747294554Sdelphij stoa(&rbufp->recv_srcadr), 1748294554Sdelphij peer->ppoll, pkt->ppoll); 1749294554Sdelphij } 1750294554Sdelphij 1751294554Sdelphij /* This is error-worthy */ 1752338530Sdelphij if ( pkt->ppoll < peer->minpoll 1753338530Sdelphij || pkt->ppoll > peer->maxpoll) { 1754330106Sdelphij msyslog(LOG_INFO, "receive: broadcast poll of %u from %s is out-of-range (%d to %d)!", 1755294554Sdelphij pkt->ppoll, stoa(&rbufp->recv_srcadr), 1756294554Sdelphij peer->minpoll, peer->maxpoll); 1757294554Sdelphij ++bail; 1758294554Sdelphij } 1759294554Sdelphij 1760309007Sdelphij /* too early? worth an error, too! 1761309007Sdelphij * 1762309007Sdelphij * [Bug 3113] Ensure that at least one poll 1763309007Sdelphij * interval has elapsed since the last **clean** 1764309007Sdelphij * packet was received. We limit the check to 1765309007Sdelphij * **clean** packets to prevent replayed packets 1766309007Sdelphij * and incorrectly authenticated packets, which 1767309007Sdelphij * we'll discard, from being used to create a 1768309007Sdelphij * denial of service condition. 1769309007Sdelphij */ 1770298695Sdelphij deadband = (1u << pkt->ppoll); 1771298695Sdelphij if (FLAG_BC_VOL & peer->flags) 1772298695Sdelphij deadband -= 3; /* allow greater fuzz after volley */ 1773309007Sdelphij if ((current_time - peer->timereceived) < deadband) { 1774298695Sdelphij msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after %lu, not %lu seconds!", 1775294554Sdelphij stoa(&rbufp->recv_srcadr), 1776309007Sdelphij (current_time - peer->timereceived), 1777298695Sdelphij deadband); 1778294554Sdelphij ++bail; 1779294554Sdelphij } 1780294554Sdelphij 1781309007Sdelphij /* Alert if time from the server is non-monotonic. 1782309007Sdelphij * 1783309007Sdelphij * [Bug 3114] is about Broadcast mode replay DoS. 1784309007Sdelphij * 1785309007Sdelphij * Broadcast mode *assumes* a trusted network. 1786309007Sdelphij * Even so, it's nice to be robust in the face 1787309007Sdelphij * of attacks. 1788309007Sdelphij * 1789309007Sdelphij * If we get an authenticated broadcast packet 1790309007Sdelphij * with an "earlier" timestamp, it means one of 1791309007Sdelphij * two things: 1792309007Sdelphij * 1793309007Sdelphij * - the broadcast server had a backward step. 1794309007Sdelphij * 1795309007Sdelphij * - somebody is trying a replay attack. 1796309007Sdelphij * 1797309007Sdelphij * deadband: By default, we assume the broadcast 1798309007Sdelphij * network is trustable, so we take our accepted 1799309007Sdelphij * broadcast packets as we receive them. But 1800309007Sdelphij * some folks might want to take additional poll 1801338530Sdelphij * delays before believing a backward step. 1802309007Sdelphij */ 1803309007Sdelphij if (sys_bcpollbstep) { 1804309007Sdelphij /* pkt->ppoll or peer->ppoll ? */ 1805309007Sdelphij deadband = (1u << pkt->ppoll) 1806309007Sdelphij * sys_bcpollbstep + 2; 1807309007Sdelphij } else { 1808309007Sdelphij deadband = 0; 1809309007Sdelphij } 1810309007Sdelphij 1811309007Sdelphij if (L_ISZERO(&peer->bxmt)) { 1812309007Sdelphij tdiff.l_ui = tdiff.l_uf = 0; 1813309007Sdelphij } else { 1814309007Sdelphij tdiff = p_xmt; 1815309007Sdelphij L_SUB(&tdiff, &peer->bxmt); 1816309007Sdelphij } 1817338530Sdelphij if ( tdiff.l_i < 0 1818338530Sdelphij && (current_time - peer->timereceived) < deadband) 1819309007Sdelphij { 1820294554Sdelphij msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x", 1821294554Sdelphij stoa(&rbufp->recv_srcadr), 1822294554Sdelphij peer->bxmt.l_ui, peer->bxmt.l_uf, 1823294554Sdelphij p_xmt.l_ui, p_xmt.l_uf 1824294554Sdelphij ); 1825294554Sdelphij ++bail; 1826294554Sdelphij } 1827294554Sdelphij 1828294554Sdelphij if (bail) { 1829330106Sdelphij DPRINTF(2, ("receive: AM_PROCPKT drop: bail\n")); 1830294554Sdelphij peer->timelastrec = current_time; 1831294554Sdelphij sys_declined++; 1832294554Sdelphij return; 1833294554Sdelphij } 1834294554Sdelphij } 1835294554Sdelphij 1836182007Sroberto break; 183754359Sroberto 183854359Sroberto /* 1839182007Sroberto * A passive packet matches a passive association. This is 1840182007Sroberto * usually the result of reconfiguring a client on the fly. As 1841280849Scy * this association might be legitimate and this packet an 1842182007Sroberto * attempt to deny service, just ignore it. 184354359Sroberto */ 1844182007Sroberto case AM_ERR: 1845330106Sdelphij DPRINTF(2, ("receive: AM_ERR drop.\n")); 1846280849Scy sys_declined++; 1847182007Sroberto return; 1848132454Sroberto 1849132454Sroberto /* 1850182007Sroberto * For everything else there is the bit bucket. 1851132454Sroberto */ 1852182007Sroberto default: 1853330106Sdelphij DPRINTF(2, ("receive: default drop.\n")); 1854280849Scy sys_declined++; 1855182007Sroberto return; 1856182007Sroberto } 1857280849Scy 1858280849Scy#ifdef AUTOKEY 1859280849Scy /* 1860280849Scy * If the association is configured for Autokey, the packet must 1861280849Scy * have a public key ID; if not, the packet must have a 1862280849Scy * symmetric key ID. 1863280849Scy */ 1864289764Sglebius if ( is_authentic != AUTH_CRYPTO 1865289764Sglebius && ( ((peer->flags & FLAG_SKEY) && skeyid <= NTP_MAXKEY) 1866289764Sglebius || (!(peer->flags & FLAG_SKEY) && skeyid > NTP_MAXKEY))) { 1867330106Sdelphij DPRINTF(2, ("receive: drop: Autokey but wrong/bad auth\n")); 1868280849Scy sys_badauth++; 1869280849Scy return; 1870280849Scy } 1871280849Scy#endif /* AUTOKEY */ 1872298695Sdelphij 1873280849Scy peer->received++; 1874182007Sroberto peer->flash &= ~PKT_TEST_MASK; 1875280849Scy if (peer->flags & FLAG_XBOGUS) { 1876280849Scy peer->flags &= ~FLAG_XBOGUS; 1877280849Scy peer->flash |= TEST3; 1878280849Scy } 1879132454Sroberto 1880132454Sroberto /* 1881182007Sroberto * Next comes a rigorous schedule of timestamp checking. If the 1882280849Scy * transmit timestamp is zero, the server has not initialized in 1883280849Scy * interleaved modes or is horribly broken. 1884298695Sdelphij * 1885298695Sdelphij * A KoD packet we pay attention to cannot have a 0 transmit 1886298695Sdelphij * timestamp. 1887132454Sroberto */ 1888330106Sdelphij 1889330106Sdelphij kissCode = kiss_code_check(hisleap, hisstratum, hismode, pkt->refid); 1890330106Sdelphij 1891182007Sroberto if (L_ISZERO(&p_xmt)) { 1892280849Scy peer->flash |= TEST3; /* unsynch */ 1893330106Sdelphij if (kissCode != NOKISS) { /* KoD packet */ 1894298695Sdelphij peer->bogusorg++; /* for TEST2 or TEST3 */ 1895298695Sdelphij msyslog(LOG_INFO, 1896298695Sdelphij "receive: Unexpected zero transmit timestamp in KoD from %s", 1897298695Sdelphij ntoa(&peer->srcadr)); 1898298695Sdelphij return; 1899298695Sdelphij } 1900132454Sroberto 1901132454Sroberto /* 1902298695Sdelphij * If the transmit timestamp duplicates our previous one, the 1903182007Sroberto * packet is a replay. This prevents the bad guys from replaying 1904182007Sroberto * the most recent packet, authenticated or not. 1905132454Sroberto */ 1906358659Scy } else if ( ((FLAG_LOOPNONCE & peer->flags) && L_ISEQU(&peer->nonce, &p_xmt)) 1907358659Scy || (!(FLAG_LOOPNONCE & peer->flags) && L_ISEQU(&peer->xmt, &p_xmt)) 1908358659Scy ) { 1909330106Sdelphij DPRINTF(2, ("receive: drop: Duplicate xmit\n")); 1910280849Scy peer->flash |= TEST1; /* duplicate */ 1911182007Sroberto peer->oldpkt++; 1912280849Scy return; 1913132454Sroberto 1914132454Sroberto /* 1915301247Sdelphij * If this is a broadcast mode packet, make sure hisstratum 1916301247Sdelphij * is appropriate. Don't do anything else here - we wait to 1917301247Sdelphij * see if this is an interleave broadcast packet until after 1918301247Sdelphij * we've validated the MAC that SHOULD be provided. 1919301247Sdelphij * 1920330106Sdelphij * hisstratum cannot be 0 - see assertion above. 1921301247Sdelphij * If hisstratum is 15, then we'll advertise as UNSPEC but 1922301247Sdelphij * at least we'll be able to sync with the broadcast server. 1923132454Sroberto */ 1924280849Scy } else if (hismode == MODE_BROADCAST) { 1925330106Sdelphij /* 0 is unexpected too, and impossible */ 1926330106Sdelphij if (STRATUM_UNSPEC <= hisstratum) { 1927301247Sdelphij /* Is this a ++sys_declined or ??? */ 1928301247Sdelphij msyslog(LOG_INFO, 1929301247Sdelphij "receive: Unexpected stratum (%d) in broadcast from %s", 1930301247Sdelphij hisstratum, ntoa(&peer->srcadr)); 1931280849Scy return; 1932280849Scy } 1933132454Sroberto 1934132454Sroberto /* 1935298695Sdelphij * Basic KoD validation checking: 1936298695Sdelphij * 1937298695Sdelphij * KoD packets are a mixed-blessing. Forged KoD packets 1938298695Sdelphij * are DoS attacks. There are rare situations where we might 1939298695Sdelphij * get a valid KoD response, though. Since KoD packets are 1940298695Sdelphij * a special case that complicate the checks we do next, we 1941298695Sdelphij * handle the basic KoD checks here. 1942298695Sdelphij * 1943298695Sdelphij * Note that we expect the incoming KoD packet to have its 1944298695Sdelphij * (nonzero) org, rec, and xmt timestamps set to the xmt timestamp 1945298695Sdelphij * that we have previously sent out. Watch interleave mode. 1946298695Sdelphij */ 1947330106Sdelphij } else if (kissCode != NOKISS) { 1948298695Sdelphij DEBUG_INSIST(!L_ISZERO(&p_xmt)); 1949298695Sdelphij if ( L_ISZERO(&p_org) /* We checked p_xmt above */ 1950298695Sdelphij || L_ISZERO(&p_rec)) { 1951298695Sdelphij peer->bogusorg++; 1952298695Sdelphij msyslog(LOG_INFO, 1953298695Sdelphij "receive: KoD packet from %s has a zero org or rec timestamp. Ignoring.", 1954298695Sdelphij ntoa(&peer->srcadr)); 1955298695Sdelphij return; 1956298695Sdelphij } 1957298695Sdelphij 1958298695Sdelphij if ( !L_ISEQU(&p_xmt, &p_org) 1959298695Sdelphij || !L_ISEQU(&p_xmt, &p_rec)) { 1960298695Sdelphij peer->bogusorg++; 1961298695Sdelphij msyslog(LOG_INFO, 1962298695Sdelphij "receive: KoD packet from %s has inconsistent xmt/org/rec timestamps. Ignoring.", 1963298695Sdelphij ntoa(&peer->srcadr)); 1964298695Sdelphij return; 1965298695Sdelphij } 1966298695Sdelphij 1967298695Sdelphij /* Be conservative */ 1968298695Sdelphij if (peer->flip == 0 && !L_ISEQU(&p_org, &peer->aorg)) { 1969298695Sdelphij peer->bogusorg++; 1970298695Sdelphij msyslog(LOG_INFO, 1971298695Sdelphij "receive: flip 0 KoD origin timestamp %#010x.%08x from %s does not match %#010x.%08x - ignoring.", 1972298695Sdelphij p_org.l_ui, p_org.l_uf, 1973298695Sdelphij ntoa(&peer->srcadr), 1974298695Sdelphij peer->aorg.l_ui, peer->aorg.l_uf); 1975298695Sdelphij return; 1976298695Sdelphij } else if (peer->flip == 1 && !L_ISEQU(&p_org, &peer->borg)) { 1977298695Sdelphij peer->bogusorg++; 1978298695Sdelphij msyslog(LOG_INFO, 1979298695Sdelphij "receive: flip 1 KoD origin timestamp %#010x.%08x from %s does not match interleave %#010x.%08x - ignoring.", 1980298695Sdelphij p_org.l_ui, p_org.l_uf, 1981298695Sdelphij ntoa(&peer->srcadr), 1982298695Sdelphij peer->borg.l_ui, peer->borg.l_uf); 1983298695Sdelphij return; 1984298695Sdelphij } 1985309007Sdelphij 1986298695Sdelphij /* 1987293423Sdelphij * Basic mode checks: 1988289764Sglebius * 1989294554Sdelphij * If there is no origin timestamp, it's either an initial packet 1990294554Sdelphij * or we've already received a response to our query. Of course, 1991294554Sdelphij * should 'aorg' be all-zero because this really was the original 1992298695Sdelphij * transmit timestamp, we'll ignore this reply. There is a window 1993298695Sdelphij * of one nanosecond once every 136 years' time where this is 1994330106Sdelphij * possible. We currently ignore this situation, as a completely 1995330106Sdelphij * zero timestamp is (quietly?) disallowed. 1996293423Sdelphij * 1997293423Sdelphij * Otherwise, check for bogus packet in basic mode. 1998293423Sdelphij * If it is bogus, switch to interleaved mode and resynchronize, 1999293423Sdelphij * but only after confirming the packet is not bogus in 2000293423Sdelphij * symmetric interleaved mode. 2001293423Sdelphij * 2002289764Sglebius * This could also mean somebody is forging packets claiming to 2003289764Sglebius * be from us, attempting to cause our server to KoD us. 2004330106Sdelphij * 2005330106Sdelphij * We have earlier asserted that hisstratum cannot be 0. 2006330106Sdelphij * If hisstratum is STRATUM_UNSPEC, it means he's not sync'd. 2007132454Sroberto */ 2008358659Scy 2009358659Scy /* XXX: FLAG_LOOPNONCE */ 2010358659Scy DEBUG_INSIST(0 == (FLAG_LOOPNONCE & peer->flags)); 2011358659Scy 2012280849Scy } else if (peer->flip == 0) { 2013298695Sdelphij if (0) { 2014298695Sdelphij } else if (L_ISZERO(&p_org)) { 2015316068Sdelphij const char *action; 2016309007Sdelphij 2017316068Sdelphij#ifdef BUG3361 2018316068Sdelphij msyslog(LOG_INFO, 2019316068Sdelphij "receive: BUG 3361: Clearing peer->aorg "); 2020309007Sdelphij L_CLR(&peer->aorg); 2021358659Scy /* Clear peer->nonce, too? */ 2022316068Sdelphij#endif 2023309007Sdelphij /**/ 2024309007Sdelphij switch (hismode) { 2025309007Sdelphij /* We allow 0org for: */ 2026309007Sdelphij case UCHAR_MAX: 2027309007Sdelphij action = "Allow"; 2028309007Sdelphij break; 2029309007Sdelphij /* We disallow 0org for: */ 2030309007Sdelphij case MODE_UNSPEC: 2031309007Sdelphij case MODE_ACTIVE: 2032309007Sdelphij case MODE_PASSIVE: 2033309007Sdelphij case MODE_CLIENT: 2034309007Sdelphij case MODE_SERVER: 2035309007Sdelphij case MODE_BROADCAST: 2036309007Sdelphij action = "Drop"; 2037309007Sdelphij peer->bogusorg++; 2038309007Sdelphij peer->flash |= TEST2; /* bogus */ 2039309007Sdelphij break; 2040309007Sdelphij default: 2041316068Sdelphij action = ""; /* for cranky compilers / MSVC */ 2042309007Sdelphij INSIST(!"receive(): impossible hismode"); 2043309007Sdelphij break; 2044309007Sdelphij } 2045309007Sdelphij /**/ 2046298695Sdelphij msyslog(LOG_INFO, 2047309007Sdelphij "receive: %s 0 origin timestamp from %s@%s xmt %#010x.%08x", 2048309007Sdelphij action, hm_str, ntoa(&peer->srcadr), 2049298695Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)); 2050298695Sdelphij } else if (!L_ISEQU(&p_org, &peer->aorg)) { 2051298695Sdelphij /* are there cases here where we should bail? */ 2052298695Sdelphij /* Should we set TEST2 if we decide to try xleave? */ 2053280849Scy peer->bogusorg++; 2054280849Scy peer->flash |= TEST2; /* bogus */ 2055289764Sglebius msyslog(LOG_INFO, 2056298695Sdelphij "receive: Unexpected origin timestamp %#010x.%08x does not match aorg %#010x.%08x from %s@%s xmt %#010x.%08x", 2057293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 2058298695Sdelphij peer->aorg.l_ui, peer->aorg.l_uf, 2059298695Sdelphij hm_str, ntoa(&peer->srcadr), 2060293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)); 2061289764Sglebius if ( !L_ISZERO(&peer->dst) 2062289764Sglebius && L_ISEQU(&p_org, &peer->dst)) { 2063293423Sdelphij /* Might be the start of an interleave */ 2064298695Sdelphij if (dynamic_interleave) { 2065298695Sdelphij peer->flip = 1; 2066298695Sdelphij report_event(PEVNT_XLEAVE, peer, NULL); 2067298695Sdelphij } else { 2068298695Sdelphij msyslog(LOG_INFO, 2069298695Sdelphij "receive: Dynamic interleave from %s@%s denied", 2070298695Sdelphij hm_str, ntoa(&peer->srcadr)); 2071298695Sdelphij } 2072182007Sroberto } 2073280849Scy } else { 2074280849Scy L_CLR(&peer->aorg); 2075358659Scy /* XXX: FLAG_LOOPNONCE */ 2076182007Sroberto } 2077280849Scy 2078280849Scy /* 2079280849Scy * Check for valid nonzero timestamp fields. 2080280849Scy */ 2081301247Sdelphij } else if ( L_ISZERO(&p_org) 2082301247Sdelphij || L_ISZERO(&p_rec) 2083301247Sdelphij || L_ISZERO(&peer->dst)) { 2084280849Scy peer->flash |= TEST3; /* unsynch */ 2085280849Scy 2086280849Scy /* 2087280849Scy * Check for bogus packet in interleaved symmetric mode. This 2088280849Scy * can happen if a packet is lost, duplicated or crossed. If 2089280849Scy * found, flip and resynchronize. 2090280849Scy */ 2091289764Sglebius } else if ( !L_ISZERO(&peer->dst) 2092289764Sglebius && !L_ISEQU(&p_org, &peer->dst)) { 2093330106Sdelphij DPRINTF(2, ("receive: drop: Bogus packet in interleaved symmetric mode\n")); 2094280849Scy peer->bogusorg++; 2095280849Scy peer->flags |= FLAG_XBOGUS; 2096280849Scy peer->flash |= TEST2; /* bogus */ 2097330106Sdelphij#ifdef BUG3453 2098289764Sglebius return; /* Bogus packet, we are done */ 2099330106Sdelphij#endif 2100182007Sroberto } 2101132454Sroberto 2102301247Sdelphij /**/ 2103301247Sdelphij 2104132454Sroberto /* 2105280849Scy * If this is a crypto_NAK, the server cannot authenticate a 2106280849Scy * client packet. The server might have just changed keys. Clear 2107280849Scy * the association and restart the protocol. 2108280849Scy */ 2109298695Sdelphij if (crypto_nak_test == VALIDNAK) { 2110280849Scy report_event(PEVNT_AUTH, peer, "crypto_NAK"); 2111280849Scy peer->flash |= TEST5; /* bad auth */ 2112280849Scy peer->badauth++; 2113280849Scy if (peer->flags & FLAG_PREEMPT) { 2114294554Sdelphij if (unpeer_crypto_nak_early) { 2115294554Sdelphij unpeer(peer); 2116294554Sdelphij } 2117330106Sdelphij DPRINTF(2, ("receive: drop: PREEMPT crypto_NAK\n")); 2118280849Scy return; 2119280849Scy } 2120280849Scy#ifdef AUTOKEY 2121301247Sdelphij if (peer->crypto) { 2122280849Scy peer_clear(peer, "AUTH"); 2123301247Sdelphij } 2124280849Scy#endif /* AUTOKEY */ 2125330106Sdelphij DPRINTF(2, ("receive: drop: crypto_NAK\n")); 2126280849Scy return; 2127182007Sroberto 2128282408Scy /* 2129282408Scy * If the digest fails or it's missing for authenticated 2130282408Scy * associations, the client cannot authenticate a server 2131280849Scy * reply to a client packet previously sent. The loopback check 2132280849Scy * is designed to avoid a bait-and-switch attack, which was 2133280849Scy * possible in past versions. If symmetric modes, return a 2134280849Scy * crypto-NAK. The peer should restart the protocol. 2135182007Sroberto */ 2136282408Scy } else if (!AUTH(peer->keyid || has_mac || 2137282408Scy (restrict_mask & RES_DONTTRUST), is_authentic)) { 2138301247Sdelphij 2139301247Sdelphij if (peer->flash & PKT_TEST_MASK) { 2140301247Sdelphij msyslog(LOG_INFO, 2141301247Sdelphij "receive: Bad auth in packet with bad timestamps from %s denied - spoof?", 2142301247Sdelphij ntoa(&peer->srcadr)); 2143301247Sdelphij return; 2144301247Sdelphij } 2145301247Sdelphij 2146280849Scy report_event(PEVNT_AUTH, peer, "digest"); 2147280849Scy peer->flash |= TEST5; /* bad auth */ 2148280849Scy peer->badauth++; 2149289764Sglebius if ( has_mac 2150301247Sdelphij && ( hismode == MODE_ACTIVE 2151301247Sdelphij || hismode == MODE_PASSIVE)) 2152132454Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask); 2153280849Scy if (peer->flags & FLAG_PREEMPT) { 2154294554Sdelphij if (unpeer_digest_early) { 2155294554Sdelphij unpeer(peer); 2156294554Sdelphij } 2157280849Scy } 2158280849Scy#ifdef AUTOKEY 2159301247Sdelphij else if (peer_clear_digest_early && peer->crypto) { 2160280849Scy peer_clear(peer, "AUTH"); 2161301247Sdelphij } 2162280849Scy#endif /* AUTOKEY */ 2163330106Sdelphij DPRINTF(2, ("receive: drop: Bad or missing AUTH\n")); 2164280849Scy return; 216554359Sroberto } 216654359Sroberto 2167182007Sroberto /* 2168301247Sdelphij * For broadcast packets: 2169301247Sdelphij * 2170301247Sdelphij * HMS: This next line never made much sense to me, even 2171301247Sdelphij * when it was up higher: 2172301247Sdelphij * If an initial volley, bail out now and let the 2173301247Sdelphij * client do its stuff. 2174301247Sdelphij * 2175301247Sdelphij * If the packet has not failed authentication, then 2176301247Sdelphij * - if the origin timestamp is nonzero this is an 2177301247Sdelphij * interleaved broadcast, so restart the protocol. 2178301247Sdelphij * - else, this is not an interleaved broadcast packet. 2179282408Scy */ 2180301247Sdelphij if (hismode == MODE_BROADCAST) { 2181301247Sdelphij if ( is_authentic == AUTH_OK 2182301247Sdelphij || is_authentic == AUTH_NONE) { 2183301247Sdelphij if (!L_ISZERO(&p_org)) { 2184301247Sdelphij if (!(peer->flags & FLAG_XB)) { 2185301247Sdelphij msyslog(LOG_INFO, 2186301247Sdelphij "receive: Broadcast server at %s is in interleave mode", 2187301247Sdelphij ntoa(&peer->srcadr)); 2188301247Sdelphij peer->flags |= FLAG_XB; 2189301247Sdelphij peer->aorg = p_xmt; 2190301247Sdelphij peer->borg = rbufp->recv_time; 2191301247Sdelphij report_event(PEVNT_XLEAVE, peer, NULL); 2192301247Sdelphij return; 2193301247Sdelphij } 2194301247Sdelphij } else if (peer->flags & FLAG_XB) { 2195301247Sdelphij msyslog(LOG_INFO, 2196301247Sdelphij "receive: Broadcast server at %s is no longer in interleave mode", 2197301247Sdelphij ntoa(&peer->srcadr)); 2198301247Sdelphij peer->flags &= ~FLAG_XB; 2199301247Sdelphij } 2200301247Sdelphij } else { 2201301247Sdelphij msyslog(LOG_INFO, 2202301247Sdelphij "receive: Bad broadcast auth (%d) from %s", 2203301247Sdelphij is_authentic, ntoa(&peer->srcadr)); 2204301247Sdelphij } 2205309007Sdelphij 2206309007Sdelphij /* 2207309007Sdelphij * Now that we know the packet is correctly authenticated, 2208309007Sdelphij * update peer->bxmt. 2209309007Sdelphij */ 2210309007Sdelphij peer->bxmt = p_xmt; 2211301247Sdelphij } 2212301247Sdelphij 2213301247Sdelphij 2214301247Sdelphij /* 2215301247Sdelphij ** Update the state variables. 2216301247Sdelphij */ 2217282408Scy if (peer->flip == 0) { 2218282408Scy if (hismode != MODE_BROADCAST) 2219282408Scy peer->rec = p_xmt; 2220282408Scy peer->dst = rbufp->recv_time; 2221282408Scy } 2222282408Scy peer->xmt = p_xmt; 2223282408Scy 2224282408Scy /* 2225280849Scy * Set the peer ppoll to the maximum of the packet ppoll and the 2226280849Scy * peer minpoll. If a kiss-o'-death, set the peer minpoll to 2227280849Scy * this maximum and advance the headway to give the sender some 2228280849Scy * headroom. Very intricate. 2229280849Scy */ 2230289764Sglebius 2231289764Sglebius /* 2232289764Sglebius * Check for any kiss codes. Note this is only used when a server 2233330106Sdelphij * responds to a packet request. 2234289764Sglebius */ 2235289764Sglebius 2236289764Sglebius /* 2237289764Sglebius * Check to see if this is a RATE Kiss Code 2238289764Sglebius * Currently this kiss code will accept whatever poll 2239289764Sglebius * rate that the server sends 2240289764Sglebius */ 2241280849Scy peer->ppoll = max(peer->minpoll, pkt->ppoll); 2242289764Sglebius if (kissCode == RATEKISS) { 2243289764Sglebius peer->selbroken++; /* Increment the KoD count */ 2244280849Scy report_event(PEVNT_RATE, peer, NULL); 2245280849Scy if (pkt->ppoll > peer->minpoll) 2246280849Scy peer->minpoll = peer->ppoll; 2247280849Scy peer->burst = peer->retry = 0; 2248280849Scy peer->throttle = (NTP_SHIFT + 1) * (1 << peer->minpoll); 2249358659Scy poll_update(peer, pkt->ppoll, 0); 2250280849Scy return; /* kiss-o'-death */ 2251280849Scy } 2252289764Sglebius if (kissCode != NOKISS) { 2253289764Sglebius peer->selbroken++; /* Increment the KoD count */ 2254289764Sglebius return; /* Drop any other kiss code packets */ 2255289764Sglebius } 2256280849Scy 2257301247Sdelphij 2258294554Sdelphij /* 2259301247Sdelphij * XXX 2260301247Sdelphij */ 2261301247Sdelphij 2262301247Sdelphij 2263301247Sdelphij /* 2264294554Sdelphij * If: 2265294554Sdelphij * - this is a *cast (uni-, broad-, or m-) server packet 2266298695Sdelphij * - and it's symmetric-key authenticated 2267294554Sdelphij * then see if the sender's IP is trusted for this keyid. 2268294554Sdelphij * If it is, great - nothing special to do here. 2269294554Sdelphij * Otherwise, we should report and bail. 2270298695Sdelphij * 2271298695Sdelphij * Autokey-authenticated packets are accepted. 2272294554Sdelphij */ 2273289764Sglebius 2274294554Sdelphij switch (hismode) { 2275294554Sdelphij case MODE_SERVER: /* server mode */ 2276294554Sdelphij case MODE_BROADCAST: /* broadcast mode */ 2277294554Sdelphij case MODE_ACTIVE: /* symmetric active mode */ 2278298695Sdelphij case MODE_PASSIVE: /* symmetric passive mode */ 2279294554Sdelphij if ( is_authentic == AUTH_OK 2280298695Sdelphij && skeyid 2281298695Sdelphij && skeyid <= NTP_MAXKEY 2282294554Sdelphij && !authistrustedip(skeyid, &peer->srcadr)) { 2283294554Sdelphij report_event(PEVNT_AUTH, peer, "authIP"); 2284294554Sdelphij peer->badauth++; 2285294554Sdelphij return; 2286294554Sdelphij } 2287309007Sdelphij break; 2288294554Sdelphij 2289294554Sdelphij case MODE_CLIENT: /* client mode */ 2290294554Sdelphij#if 0 /* At this point, MODE_CONTROL is overloaded by MODE_BCLIENT */ 2291294554Sdelphij case MODE_CONTROL: /* control mode */ 2292294554Sdelphij#endif 2293294554Sdelphij case MODE_PRIVATE: /* private mode */ 2294294554Sdelphij case MODE_BCLIENT: /* broadcast client mode */ 2295309007Sdelphij break; 2296298695Sdelphij 2297298695Sdelphij case MODE_UNSPEC: /* unspecified (old version) */ 2298294554Sdelphij default: 2299298695Sdelphij msyslog(LOG_INFO, 2300298695Sdelphij "receive: Unexpected mode (%d) in packet from %s", 2301298695Sdelphij hismode, ntoa(&peer->srcadr)); 2302309007Sdelphij break; 2303294554Sdelphij } 2304294554Sdelphij 2305294554Sdelphij 2306280849Scy /* 2307182007Sroberto * That was hard and I am sweaty, but the packet is squeaky 2308182007Sroberto * clean. Get on with real work. 2309182007Sroberto */ 2310182007Sroberto peer->timereceived = current_time; 2311294554Sdelphij peer->timelastrec = current_time; 2312182007Sroberto if (is_authentic == AUTH_OK) 2313182007Sroberto peer->flags |= FLAG_AUTHENTIC; 2314182007Sroberto else 2315182007Sroberto peer->flags &= ~FLAG_AUTHENTIC; 2316280849Scy 2317280849Scy#ifdef AUTOKEY 231854359Sroberto /* 231982505Sroberto * More autokey dance. The rules of the cha-cha are as follows: 232082505Sroberto * 232182505Sroberto * 1. If there is no key or the key is not auto, do nothing. 232282505Sroberto * 2323132454Sroberto * 2. If this packet is in response to the one just previously 2324132454Sroberto * sent or from a broadcast server, do the extension fields. 2325132454Sroberto * Otherwise, assume bogosity and bail out. 2326132454Sroberto * 2327132454Sroberto * 3. If an extension field contains a verified signature, it is 232882505Sroberto * self-authenticated and we sit the dance. 232982505Sroberto * 2330132454Sroberto * 4. If this is a server reply, check only to see that the 233182505Sroberto * transmitted key ID matches the received key ID. 233282505Sroberto * 2333132454Sroberto * 5. Check to see that one or more hashes of the current key ID 233482505Sroberto * matches the previous key ID or ultimate original key ID 233582505Sroberto * obtained from the broadcaster or symmetric peer. If no 2336280849Scy * match, sit the dance and call for new autokey values. 2337182007Sroberto * 2338280849Scy * In case of crypto error, fire the orchestra, stop dancing and 2339280849Scy * restart the protocol. 234054359Sroberto */ 2341280849Scy if (peer->flags & FLAG_SKEY) { 2342280849Scy /* 2343280849Scy * Decrement remaining autokey hashes. This isn't 2344280849Scy * perfect if a packet is lost, but results in no harm. 2345280849Scy */ 2346280849Scy ap = (struct autokey *)peer->recval.ptr; 2347280849Scy if (ap != NULL) { 2348280849Scy if (ap->seq > 0) 2349280849Scy ap->seq--; 2350280849Scy } 2351182007Sroberto peer->flash |= TEST8; 2352132454Sroberto rval = crypto_recv(peer, rbufp); 2353280849Scy if (rval == XEVNT_OK) { 2354280849Scy peer->unreach = 0; 2355280849Scy } else { 2356280849Scy if (rval == XEVNT_ERR) { 2357280849Scy report_event(PEVNT_RESTART, peer, 2358280849Scy "crypto error"); 2359280849Scy peer_clear(peer, "CRYP"); 2360280849Scy peer->flash |= TEST9; /* bad crypt */ 2361294554Sdelphij if (peer->flags & FLAG_PREEMPT) { 2362294554Sdelphij if (unpeer_crypto_early) { 2363294554Sdelphij unpeer(peer); 2364294554Sdelphij } 2365294554Sdelphij } 2366280849Scy } 2367182007Sroberto return; 2368280849Scy } 2369132454Sroberto 2370280849Scy /* 2371280849Scy * If server mode, verify the receive key ID matches 2372280849Scy * the transmit key ID. 2373280849Scy */ 2374280849Scy if (hismode == MODE_SERVER) { 237582505Sroberto if (skeyid == peer->keyid) 2376182007Sroberto peer->flash &= ~TEST8; 2377280849Scy 2378280849Scy /* 2379280849Scy * If an extension field is present, verify only that it 2380280849Scy * has been correctly signed. We don't need a sequence 2381280849Scy * check here, but the sequence continues. 2382280849Scy */ 2383182007Sroberto } else if (!(peer->flash & TEST8)) { 238482505Sroberto peer->pkeyid = skeyid; 2385280849Scy 2386280849Scy /* 2387280849Scy * Now the fun part. Here, skeyid is the current ID in 2388280849Scy * the packet, pkeyid is the ID in the last packet and 2389280849Scy * tkeyid is the hash of skeyid. If the autokey values 2390280849Scy * have not been received, this is an automatic error. 2391280849Scy * If so, check that the tkeyid matches pkeyid. If not, 2392280849Scy * hash tkeyid and try again. If the number of hashes 2393280849Scy * exceeds the number remaining in the sequence, declare 2394280849Scy * a successful failure and refresh the autokey values. 2395280849Scy */ 2396280849Scy } else if (ap != NULL) { 239782505Sroberto int i; 239882505Sroberto 239982505Sroberto for (i = 0; ; i++) { 2400289764Sglebius if ( tkeyid == peer->pkeyid 2401289764Sglebius || tkeyid == ap->key) { 2402182007Sroberto peer->flash &= ~TEST8; 240382505Sroberto peer->pkeyid = skeyid; 2404280849Scy ap->seq -= i; 240582505Sroberto break; 240682505Sroberto } 2407280849Scy if (i > ap->seq) { 2408280849Scy peer->crypto &= 2409280849Scy ~CRYPTO_FLAG_AUTO; 241082505Sroberto break; 2411280849Scy } 241254359Sroberto tkeyid = session_key( 241382505Sroberto &rbufp->recv_srcadr, dstadr_sin, 241482505Sroberto tkeyid, pkeyid, 0); 241554359Sroberto } 2416280849Scy if (peer->flash & TEST8) 2417280849Scy report_event(PEVNT_AUTH, peer, "keylist"); 241854359Sroberto } 2419182007Sroberto if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */ 2420280849Scy peer->flash |= TEST8; /* bad autokey */ 242182505Sroberto 242282505Sroberto /* 2423280849Scy * The maximum lifetime of the protocol is about one 2424280849Scy * week before restarting the Autokey protocol to 2425280849Scy * refresh certificates and leapseconds values. 242682505Sroberto */ 2427280849Scy if (current_time > peer->refresh) { 2428280849Scy report_event(PEVNT_RESTART, peer, 2429280849Scy "crypto refresh"); 2430280849Scy peer_clear(peer, "TIME"); 2431280849Scy return; 2432132454Sroberto } 243354359Sroberto } 2434280849Scy#endif /* AUTOKEY */ 243554359Sroberto 243654359Sroberto /* 2437182007Sroberto * The dance is complete and the flash bits have been lit. Toss 2438182007Sroberto * the packet over the fence for processing, which may light up 2439358659Scy * more flashers. Leave if the packet is not good. 244054359Sroberto */ 2441280849Scy process_packet(peer, pkt, rbufp->recv_length); 2442358659Scy if (peer->flash & PKT_TEST_MASK) 2443358659Scy return; 2444182007Sroberto 2445358659Scy /* [bug 3592] Update poll. Ideally this should not happen in a 2446358659Scy * receive branch, but too much is going on here... at least we 2447358659Scy * do it only if the packet was good! 2448358659Scy */ 2449358659Scy poll_update(peer, peer->hpoll, (peer->hmode == MODE_CLIENT)); 2450358659Scy 2451182007Sroberto /* 2452280849Scy * In interleaved mode update the state variables. Also adjust the 2453280849Scy * transmit phase to avoid crossover. 2454182007Sroberto */ 2455280849Scy if (peer->flip != 0) { 2456280849Scy peer->rec = p_rec; 2457280849Scy peer->dst = rbufp->recv_time; 2458280849Scy if (peer->nextdate - current_time < (1U << min(peer->ppoll, 2459280849Scy peer->hpoll)) / 2) 2460280849Scy peer->nextdate++; 2461280849Scy else 2462280849Scy peer->nextdate--; 2463182007Sroberto } 246454359Sroberto} 246554359Sroberto 246654359Sroberto 246754359Sroberto/* 2468301247Sdelphij * process_packet - Packet Procedure, a la Section 3.4.4 of RFC-1305 2469301247Sdelphij * Or almost, at least. If we're in here we have a reasonable 2470301247Sdelphij * expectation that we will be having a long term 247154359Sroberto * relationship with this host. 247254359Sroberto */ 247382505Srobertovoid 247454359Srobertoprocess_packet( 247554359Sroberto register struct peer *peer, 2476280849Scy register struct pkt *pkt, 2477280849Scy u_int len 247854359Sroberto ) 247954359Sroberto{ 2480182007Sroberto double t34, t21; 2481132454Sroberto double p_offset, p_del, p_disp; 2482280849Scy l_fp p_rec, p_xmt, p_org, p_reftime, ci; 2483280849Scy u_char pmode, pleap, pversion, pstratum; 2484280849Scy char statstr[NTP_MAXSTRLEN]; 2485280849Scy#ifdef ASSYM 2486280849Scy int itemp; 2487280849Scy double etemp, ftemp, td; 2488280849Scy#endif /* ASSYM */ 248954359Sroberto 249054359Sroberto p_del = FPTOD(NTOHS_FP(pkt->rootdelay)); 2491280849Scy p_offset = 0; 2492280849Scy p_disp = FPTOD(NTOHS_FP(pkt->rootdisp)); 249354359Sroberto NTOHL_FP(&pkt->reftime, &p_reftime); 2494280849Scy NTOHL_FP(&pkt->org, &p_org); 249554359Sroberto NTOHL_FP(&pkt->rec, &p_rec); 249654359Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 2497132454Sroberto pmode = PKT_MODE(pkt->li_vn_mode); 2498132454Sroberto pleap = PKT_LEAP(pkt->li_vn_mode); 2499280849Scy pversion = PKT_VERSION(pkt->li_vn_mode); 2500132454Sroberto pstratum = PKT_TO_STRATUM(pkt->stratum); 250154359Sroberto 250254359Sroberto /* 2503301247Sdelphij * Verify the server is synchronized; that is, the leap bits, 2504301247Sdelphij * stratum and root distance are valid. 2505301247Sdelphij */ 2506301247Sdelphij if ( pleap == LEAP_NOTINSYNC /* test 6 */ 2507301247Sdelphij || pstratum < sys_floor || pstratum >= sys_ceiling) 2508301247Sdelphij peer->flash |= TEST6; /* bad synch or strat */ 2509301247Sdelphij if (p_del / 2 + p_disp >= MAXDISPERSE) /* test 7 */ 2510301247Sdelphij peer->flash |= TEST7; /* bad header */ 2511301247Sdelphij 2512301247Sdelphij /* 2513301247Sdelphij * If any tests fail at this point, the packet is discarded. 2514301247Sdelphij * Note that some flashers may have already been set in the 2515301247Sdelphij * receive() routine. 2516301247Sdelphij */ 2517301247Sdelphij if (peer->flash & PKT_TEST_MASK) { 2518301247Sdelphij peer->seldisptoolarge++; 2519301247Sdelphij DPRINTF(1, ("packet: flash header %04x\n", 2520301247Sdelphij peer->flash)); 2521362716Scy /* [Bug 3592] do *not* update poll on bad packets! */ 2522301247Sdelphij return; 2523301247Sdelphij } 2524301247Sdelphij 2525362716Scy /* 2526362716Scy * update stats, now that we really handle this packet: 2527362716Scy */ 2528301247Sdelphij sys_processed++; 2529301247Sdelphij peer->processed++; 2530301247Sdelphij 2531301247Sdelphij /* 2532280849Scy * Capture the header values in the client/peer association.. 253354359Sroberto */ 2534330106Sdelphij record_raw_stats(&peer->srcadr, 2535330106Sdelphij peer->dstadr ? &peer->dstadr->sin : NULL, 2536280849Scy &p_org, &p_rec, &p_xmt, &peer->dst, 2537280849Scy pleap, pversion, pmode, pstratum, pkt->ppoll, pkt->precision, 2538330106Sdelphij p_del, p_disp, pkt->refid, 2539330106Sdelphij len - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 2540132454Sroberto peer->leap = pleap; 2541182007Sroberto peer->stratum = min(pstratum, STRATUM_UNSPEC); 2542182007Sroberto peer->pmode = pmode; 2543182007Sroberto peer->precision = pkt->precision; 2544182007Sroberto peer->rootdelay = p_del; 2545280849Scy peer->rootdisp = p_disp; 2546182007Sroberto peer->refid = pkt->refid; /* network byte order */ 2547182007Sroberto peer->reftime = p_reftime; 254882505Sroberto 254982505Sroberto /* 2550280849Scy * First, if either burst mode is armed, enable the burst. 2551280849Scy * Compute the headway for the next packet and delay if 2552280849Scy * necessary to avoid exceeding the threshold. 255382505Sroberto */ 2554280849Scy if (peer->retry > 0) { 2555280849Scy peer->retry = 0; 2556280849Scy if (peer->reach) 2557280849Scy peer->burst = min(1 << (peer->hpoll - 2558280849Scy peer->minpoll), NTP_SHIFT) - 1; 2559280849Scy else 2560280849Scy peer->burst = NTP_IBURST - 1; 2561280849Scy if (peer->burst > 0) 2562280849Scy peer->nextdate = current_time; 2563280849Scy } 2564280849Scy 2565132454Sroberto /* 2566280849Scy * If the peer was previously unreachable, raise a trap. In any 2567280849Scy * case, mark it reachable. 2568282408Scy */ 2569280849Scy if (!peer->reach) { 2570280849Scy report_event(PEVNT_REACH, peer, NULL); 257154359Sroberto peer->timereachable = current_time; 257254359Sroberto } 257354359Sroberto peer->reach |= 1; 257454359Sroberto 257554359Sroberto /* 2576182007Sroberto * For a client/server association, calculate the clock offset, 2577182007Sroberto * roundtrip delay and dispersion. The equations are reordered 2578182007Sroberto * from the spec for more efficient use of temporaries. For a 2579182007Sroberto * broadcast association, offset the last measurement by the 2580280849Scy * computed delay during the client/server volley. Note the 2581182007Sroberto * computation of dispersion includes the system precision plus 2582182007Sroberto * that due to the frequency error since the origin time. 258354359Sroberto * 2584182007Sroberto * It is very important to respect the hazards of overflow. The 2585182007Sroberto * only permitted operation on raw timestamps is subtraction, 2586182007Sroberto * where the result is a signed quantity spanning from 68 years 2587182007Sroberto * in the past to 68 years in the future. To avoid loss of 2588182007Sroberto * precision, these calculations are done using 64-bit integer 2589182007Sroberto * arithmetic. However, the offset and delay calculations are 2590182007Sroberto * sums and differences of these first-order differences, which 2591182007Sroberto * if done using 64-bit integer arithmetic, would be valid over 2592182007Sroberto * only half that span. Since the typical first-order 2593182007Sroberto * differences are usually very small, they are converted to 64- 2594182007Sroberto * bit doubles and all remaining calculations done in floating- 2595280849Scy * double arithmetic. This preserves the accuracy while 2596280849Scy * retaining the 68-year span. 2597182007Sroberto * 2598280849Scy * There are three interleaving schemes, basic, interleaved 2599280849Scy * symmetric and interleaved broadcast. The timestamps are 2600280849Scy * idioscyncratically different. See the onwire briefing/white 2601280849Scy * paper at www.eecis.udel.edu/~mills for details. 2602280849Scy * 2603280849Scy * Interleaved symmetric mode 2604280849Scy * t1 = peer->aorg/borg, t2 = peer->rec, t3 = p_xmt, 2605280849Scy * t4 = peer->dst 260654359Sroberto */ 2607280849Scy if (peer->flip != 0) { 2608280849Scy ci = p_xmt; /* t3 - t4 */ 2609280849Scy L_SUB(&ci, &peer->dst); 2610280849Scy LFPTOD(&ci, t34); 2611280849Scy ci = p_rec; /* t2 - t1 */ 2612280849Scy if (peer->flip > 0) 2613280849Scy L_SUB(&ci, &peer->borg); 2614280849Scy else 2615280849Scy L_SUB(&ci, &peer->aorg); 2616280849Scy LFPTOD(&ci, t21); 2617280849Scy p_del = t21 - t34; 2618280849Scy p_offset = (t21 + t34) / 2.; 2619280849Scy if (p_del < 0 || p_del > 1.) { 2620280849Scy snprintf(statstr, sizeof(statstr), 2621280849Scy "t21 %.6f t34 %.6f", t21, t34); 2622280849Scy report_event(PEVNT_XERR, peer, statstr); 2623280849Scy return; 2624280849Scy } 262554359Sroberto 262654359Sroberto /* 2627280849Scy * Broadcast modes 262854359Sroberto */ 2629280849Scy } else if (peer->pmode == MODE_BROADCAST) { 2630280849Scy 2631280849Scy /* 2632280849Scy * Interleaved broadcast mode. Use interleaved timestamps. 2633280849Scy * t1 = peer->borg, t2 = p_org, t3 = p_org, t4 = aorg 2634280849Scy */ 2635282408Scy if (peer->flags & FLAG_XB) { 2636282408Scy ci = p_org; /* delay */ 2637280849Scy L_SUB(&ci, &peer->aorg); 2638280849Scy LFPTOD(&ci, t34); 2639280849Scy ci = p_org; /* t2 - t1 */ 2640280849Scy L_SUB(&ci, &peer->borg); 2641280849Scy LFPTOD(&ci, t21); 2642280849Scy peer->aorg = p_xmt; 2643280849Scy peer->borg = peer->dst; 2644280849Scy if (t34 < 0 || t34 > 1.) { 2645298695Sdelphij /* drop all if in the initial volley */ 2646298695Sdelphij if (FLAG_BC_VOL & peer->flags) 2647298695Sdelphij goto bcc_init_volley_fail; 2648280849Scy snprintf(statstr, sizeof(statstr), 2649280849Scy "offset %.6f delay %.6f", t21, t34); 2650280849Scy report_event(PEVNT_XERR, peer, statstr); 265182505Sroberto return; 2652280849Scy } 2653280849Scy p_offset = t21; 2654280849Scy peer->xleave = t34; 265554359Sroberto 2656280849Scy /* 2657280849Scy * Basic broadcast - use direct timestamps. 2658280849Scy * t3 = p_xmt, t4 = peer->dst 2659280849Scy */ 2660280849Scy } else { 2661280849Scy ci = p_xmt; /* t3 - t4 */ 2662280849Scy L_SUB(&ci, &peer->dst); 2663280849Scy LFPTOD(&ci, t34); 2664280849Scy p_offset = t34; 266554359Sroberto } 2666280849Scy 2667280849Scy /* 2668280849Scy * When calibration is complete and the clock is 2669280849Scy * synchronized, the bias is calculated as the difference 2670280849Scy * between the unicast timestamp and the broadcast 2671280849Scy * timestamp. This works for both basic and interleaved 2672280849Scy * modes. 2673338530Sdelphij * [Bug 3031] Don't keep this peer when the delay 2674298695Sdelphij * calculation gives reason to suspect clock steps. 2675298695Sdelphij * This is assumed for delays > 50ms. 2676280849Scy */ 2677280849Scy if (FLAG_BC_VOL & peer->flags) { 2678280849Scy peer->flags &= ~FLAG_BC_VOL; 2679280849Scy peer->delay = fabs(peer->offset - p_offset) * 2; 2680298695Sdelphij DPRINTF(2, ("broadcast volley: initial delay=%.6f\n", 2681298695Sdelphij peer->delay)); 2682298695Sdelphij if (peer->delay > fabs(sys_bdelay)) { 2683298695Sdelphij bcc_init_volley_fail: 2684298695Sdelphij DPRINTF(2, ("%s", "broadcast volley: initial delay exceeds limit\n")); 2685298695Sdelphij unpeer(peer); 2686298695Sdelphij return; 2687298695Sdelphij } 2688280849Scy } 2689298695Sdelphij peer->nextdate = current_time + (1u << peer->ppoll) - 2u; 269054359Sroberto p_del = peer->delay; 2691280849Scy p_offset += p_del / 2; 2692280849Scy 2693280849Scy 2694280849Scy /* 2695280849Scy * Basic mode, otherwise known as the old fashioned way. 2696280849Scy * 2697280849Scy * t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->dst 2698280849Scy */ 269954359Sroberto } else { 2700280849Scy ci = p_xmt; /* t3 - t4 */ 2701280849Scy L_SUB(&ci, &peer->dst); 2702280849Scy LFPTOD(&ci, t34); 2703280849Scy ci = p_rec; /* t2 - t1 */ 2704280849Scy L_SUB(&ci, &p_org); 2705280849Scy LFPTOD(&ci, t21); 2706280849Scy p_del = fabs(t21 - t34); 2707182007Sroberto p_offset = (t21 + t34) / 2.; 270854359Sroberto } 270982505Sroberto p_del = max(p_del, LOGTOD(sys_precision)); 2710280849Scy p_disp = LOGTOD(sys_precision) + LOGTOD(peer->precision) + 2711280849Scy clock_phi * p_del; 2712280849Scy 2713280849Scy#if ASSYM 2714280849Scy /* 2715280849Scy * This code calculates the outbound and inbound data rates by 2716280849Scy * measuring the differences between timestamps at different 2717280849Scy * packet lengths. This is helpful in cases of large asymmetric 2718280849Scy * delays commonly experienced on deep space communication 2719280849Scy * links. 2720280849Scy */ 2721280849Scy if (peer->t21_last > 0 && peer->t34_bytes > 0) { 2722280849Scy itemp = peer->t21_bytes - peer->t21_last; 2723280849Scy if (itemp > 25) { 2724280849Scy etemp = t21 - peer->t21; 2725280849Scy if (fabs(etemp) > 1e-6) { 2726280849Scy ftemp = itemp / etemp; 2727280849Scy if (ftemp > 1000.) 2728280849Scy peer->r21 = ftemp; 2729280849Scy } 2730280849Scy } 2731280849Scy itemp = len - peer->t34_bytes; 2732280849Scy if (itemp > 25) { 2733280849Scy etemp = -t34 - peer->t34; 2734280849Scy if (fabs(etemp) > 1e-6) { 2735280849Scy ftemp = itemp / etemp; 2736280849Scy if (ftemp > 1000.) 2737280849Scy peer->r34 = ftemp; 2738280849Scy } 2739280849Scy } 2740280849Scy } 2741280849Scy 2742280849Scy /* 2743280849Scy * The following section compensates for different data rates on 2744280849Scy * the outbound (d21) and inbound (t34) directions. To do this, 2745280849Scy * it finds t such that r21 * t - r34 * (d - t) = 0, where d is 2746280849Scy * the roundtrip delay. Then it calculates the correction as a 2747280849Scy * fraction of d. 2748280849Scy */ 2749293423Sdelphij peer->t21 = t21; 2750280849Scy peer->t21_last = peer->t21_bytes; 2751280849Scy peer->t34 = -t34; 2752280849Scy peer->t34_bytes = len; 2753293423Sdelphij DPRINTF(2, ("packet: t21 %.9lf %d t34 %.9lf %d\n", peer->t21, 2754293423Sdelphij peer->t21_bytes, peer->t34, peer->t34_bytes)); 2755280849Scy if (peer->r21 > 0 && peer->r34 > 0 && p_del > 0) { 2756280849Scy if (peer->pmode != MODE_BROADCAST) 2757280849Scy td = (peer->r34 / (peer->r21 + peer->r34) - 2758280849Scy .5) * p_del; 2759280849Scy else 2760280849Scy td = 0; 2761280849Scy 2762280849Scy /* 2763293423Sdelphij * Unfortunately, in many cases the errors are 2764280849Scy * unacceptable, so for the present the rates are not 2765280849Scy * used. In future, we might find conditions where the 2766280849Scy * calculations are useful, so this should be considered 2767280849Scy * a work in progress. 2768280849Scy */ 2769280849Scy t21 -= td; 2770280849Scy t34 -= td; 2771293423Sdelphij DPRINTF(2, ("packet: del %.6lf r21 %.1lf r34 %.1lf %.6lf\n", 2772280849Scy p_del, peer->r21 / 1e3, peer->r34 / 1e3, 2773293423Sdelphij td)); 2774282408Scy } 2775280849Scy#endif /* ASSYM */ 2776280849Scy 2777280849Scy /* 2778280849Scy * That was awesome. Now hand off to the clock filter. 2779280849Scy */ 2780280849Scy clock_filter(peer, p_offset + peer->bias, p_del, p_disp); 2781280849Scy 2782280849Scy /* 2783280849Scy * If we are in broadcast calibrate mode, return to broadcast 2784280849Scy * client mode when the client is fit and the autokey dance is 2785280849Scy * complete. 2786280849Scy */ 2787289764Sglebius if ( (FLAG_BC_VOL & peer->flags) 2788289764Sglebius && MODE_CLIENT == peer->hmode 2789289764Sglebius && !(TEST11 & peer_unfit(peer))) { /* distance exceeded */ 2790280849Scy#ifdef AUTOKEY 2791280849Scy if (peer->flags & FLAG_SKEY) { 2792280849Scy if (!(~peer->crypto & CRYPTO_FLAG_ALL)) 2793280849Scy peer->hmode = MODE_BCLIENT; 2794280849Scy } else { 2795280849Scy peer->hmode = MODE_BCLIENT; 2796280849Scy } 2797280849Scy#else /* !AUTOKEY follows */ 2798280849Scy peer->hmode = MODE_BCLIENT; 2799280849Scy#endif /* !AUTOKEY */ 2800280849Scy } 280154359Sroberto} 280254359Sroberto 280354359Sroberto 280454359Sroberto/* 280554359Sroberto * clock_update - Called at system process update intervals. 280654359Sroberto */ 280754359Srobertostatic void 2808280849Scyclock_update( 2809280849Scy struct peer *peer /* peer structure pointer */ 2810280849Scy ) 281154359Sroberto{ 2812182007Sroberto double dtemp; 2813280849Scy l_fp now; 2814280849Scy#ifdef HAVE_LIBSCF_H 2815280849Scy char *fmri; 2816280849Scy#endif /* HAVE_LIBSCF_H */ 281754359Sroberto 281854359Sroberto /* 2819280849Scy * Update the system state variables. We do this very carefully, 2820280849Scy * as the poll interval might need to be clamped differently. 282154359Sroberto */ 2822280849Scy sys_peer = peer; 2823280849Scy sys_epoch = peer->epoch; 2824280849Scy if (sys_poll < peer->minpoll) 2825280849Scy sys_poll = peer->minpoll; 2826280849Scy if (sys_poll > peer->maxpoll) 2827280849Scy sys_poll = peer->maxpoll; 2828358659Scy poll_update(peer, sys_poll, 0); 2829280849Scy sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC); 2830289764Sglebius if ( peer->stratum == STRATUM_REFCLOCK 2831289764Sglebius || peer->stratum == STRATUM_UNSPEC) 2832280849Scy sys_refid = peer->refid; 2833280849Scy else 2834280849Scy sys_refid = addr2refid(&peer->srcadr); 2835280849Scy /* 2836280849Scy * Root Dispersion (E) is defined (in RFC 5905) as: 2837280849Scy * 2838280849Scy * E = p.epsilon_r + p.epsilon + p.psi + PHI*(s.t - p.t) + |THETA| 2839280849Scy * 2840280849Scy * where: 2841280849Scy * p.epsilon_r is the PollProc's root dispersion 2842280849Scy * p.epsilon is the PollProc's dispersion 2843280849Scy * p.psi is the PollProc's jitter 2844280849Scy * THETA is the combined offset 2845280849Scy * 2846280849Scy * NB: Think Hard about where these numbers come from and 2847280849Scy * what they mean. When did peer->update happen? Has anything 2848280849Scy * interesting happened since then? What values are the most 2849280849Scy * defensible? Why? 2850280849Scy * 2851280849Scy * DLM thinks this equation is probably the best of all worse choices. 2852280849Scy */ 2853280849Scy dtemp = peer->rootdisp 2854280849Scy + peer->disp 2855280849Scy + sys_jitter 2856280849Scy + clock_phi * (current_time - peer->update) 2857280849Scy + fabs(sys_offset); 2858182007Sroberto 2859358659Scy p2_rootdisp = prev_rootdisp; 2860358659Scy prev_rootdisp = sys_rootdisp; 2861280849Scy if (dtemp > sys_mindisp) 2862280849Scy sys_rootdisp = dtemp; 2863280849Scy else 2864280849Scy sys_rootdisp = sys_mindisp; 2865358659Scy 2866280849Scy sys_rootdelay = peer->delay + peer->rootdelay; 2867358659Scy 2868358659Scy p2_reftime = prev_reftime; 2869358659Scy p2_time = prev_time; 2870358659Scy 2871358659Scy prev_reftime = sys_reftime; 2872358659Scy prev_time = current_time + 64 + (rand() & 0x3f); /* 64-127 s */ 2873358659Scy 2874280849Scy sys_reftime = peer->dst; 2875280849Scy 2876293423Sdelphij DPRINTF(1, ("clock_update: at %lu sample %lu associd %d\n", 2877293423Sdelphij current_time, peer->epoch, peer->associd)); 287854359Sroberto 287982505Sroberto /* 2880280849Scy * Comes now the moment of truth. Crank the clock discipline and 2881280849Scy * see what comes out. 2882280849Scy */ 2883280849Scy switch (local_clock(peer, sys_offset)) { 2884280849Scy 2885280849Scy /* 2886182007Sroberto * Clock exceeds panic threshold. Life as we know it ends. 288782505Sroberto */ 288882505Sroberto case -1: 2889280849Scy#ifdef HAVE_LIBSCF_H 2890280849Scy /* 2891280849Scy * For Solaris enter the maintenance mode. 2892280849Scy */ 2893280849Scy if ((fmri = getenv("SMF_FMRI")) != NULL) { 2894280849Scy if (smf_maintain_instance(fmri, 0) < 0) { 2895280849Scy printf("smf_maintain_instance: %s\n", 2896280849Scy scf_strerror(scf_error())); 2897280849Scy exit(1); 2898280849Scy } 2899280849Scy /* 2900280849Scy * Sleep until SMF kills us. 2901280849Scy */ 2902280849Scy for (;;) 2903280849Scy pause(); 2904280849Scy } 2905280849Scy#endif /* HAVE_LIBSCF_H */ 2906132454Sroberto exit (-1); 2907182007Sroberto /* not reached */ 290854359Sroberto 290982505Sroberto /* 291082505Sroberto * Clock was stepped. Flush all time values of all peers. 291182505Sroberto */ 2912182007Sroberto case 2: 291382505Sroberto clear_all(); 2914285169Scy set_sys_leap(LEAP_NOTINSYNC); 2915182007Sroberto sys_stratum = STRATUM_UNSPEC; 2916280849Scy memcpy(&sys_refid, "STEP", 4); 2917182007Sroberto sys_rootdelay = 0; 2918358659Scy p2_rootdisp = 0; 2919358659Scy prev_rootdisp = 0; 2920280849Scy sys_rootdisp = 0; 2921358659Scy L_CLR(&p2_reftime); /* Should we clear p2_reftime? */ 2922358659Scy L_CLR(&prev_reftime); /* Should we clear prev_reftime? */ 2923280849Scy L_CLR(&sys_reftime); 2924280849Scy sys_jitter = LOGTOD(sys_precision); 2925280849Scy leapsec_reset_frame(); 292654359Sroberto break; 292754359Sroberto 292882505Sroberto /* 2929280849Scy * Clock was slewed. Handle the leapsecond stuff. 293082505Sroberto */ 2931182007Sroberto case 1: 2932182007Sroberto 2933182007Sroberto /* 2934280849Scy * If this is the first time the clock is set, reset the 2935280849Scy * leap bits. If crypto, the timer will goose the setup 2936280849Scy * process. 2937182007Sroberto */ 2938280849Scy if (sys_leap == LEAP_NOTINSYNC) { 2939285169Scy set_sys_leap(LEAP_NOWARNING); 2940280849Scy#ifdef AUTOKEY 2941280849Scy if (crypto_flags) 2942280849Scy crypto_update(); 2943280849Scy#endif /* AUTOKEY */ 2944280849Scy /* 2945280849Scy * If our parent process is waiting for the 2946280849Scy * first clock sync, send them home satisfied. 2947280849Scy */ 2948280849Scy#ifdef HAVE_WORKING_FORK 2949358659Scy if (daemon_pipe[1] != -1) { 2950358659Scy write(daemon_pipe[1], "S\n", 2); 2951358659Scy close(daemon_pipe[1]); 2952358659Scy daemon_pipe[1] = -1; 2953280849Scy DPRINTF(1, ("notified parent --wait-sync is done\n")); 2954280849Scy } 2955280849Scy#endif /* HAVE_WORKING_FORK */ 2956280849Scy 2957182007Sroberto } 2958280849Scy 2959280849Scy /* 2960280849Scy * If there is no leap second pending and the number of 2961280849Scy * survivor leap bits is greater than half the number of 2962280849Scy * survivors, try to schedule a leap for the end of the 2963280849Scy * current month. (This only works if no leap second for 2964280849Scy * that range is in the table, so doing this more than 2965280849Scy * once is mostly harmless.) 2966280849Scy */ 2967280849Scy if (leapsec == LSPROX_NOWARN) { 2968289764Sglebius if ( leap_vote_ins > leap_vote_del 2969280849Scy && leap_vote_ins > sys_survivors / 2) { 2970280849Scy get_systime(&now); 2971280849Scy leapsec_add_dyn(TRUE, now.l_ui, NULL); 2972280849Scy } 2973289764Sglebius if ( leap_vote_del > leap_vote_ins 2974280849Scy && leap_vote_del > sys_survivors / 2) { 2975280849Scy get_systime(&now); 2976280849Scy leapsec_add_dyn(FALSE, now.l_ui, NULL); 2977280849Scy } 2978132454Sroberto } 2979182007Sroberto break; 2980280849Scy 2981182007Sroberto /* 2982182007Sroberto * Popcorn spike or step threshold exceeded. Pretend it never 2983182007Sroberto * happened. 2984182007Sroberto */ 2985182007Sroberto default: 2986182007Sroberto break; 298754359Sroberto } 298854359Sroberto} 298954359Sroberto 299054359Sroberto 299154359Sroberto/* 299282505Sroberto * poll_update - update peer poll interval 299354359Sroberto */ 299454359Srobertovoid 299554359Srobertopoll_update( 2996280849Scy struct peer *peer, /* peer structure pointer */ 2997358659Scy u_char mpoll, 2998358659Scy u_char skewpoll 299954359Sroberto ) 300054359Sroberto{ 3001358659Scy u_long next, utemp, limit; 3002280849Scy u_char hpoll; 300354359Sroberto 300454359Sroberto /* 3005182007Sroberto * This routine figures out when the next poll should be sent. 3006280849Scy * That turns out to be wickedly complicated. One problem is 3007280849Scy * that sometimes the time for the next poll is in the past when 3008280849Scy * the poll interval is reduced. We watch out for races here 3009280849Scy * between the receive process and the poll process. 3010182007Sroberto * 3011280849Scy * Clamp the poll interval between minpoll and maxpoll. 301254359Sroberto */ 3013280849Scy hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll); 3014182007Sroberto 3015280849Scy#ifdef AUTOKEY 3016182007Sroberto /* 3017280849Scy * If during the crypto protocol the poll interval has changed, 3018280849Scy * the lifetimes in the key list are probably bogus. Purge the 3019280849Scy * the key list and regenerate it later. 3020182007Sroberto */ 3021280849Scy if ((peer->flags & FLAG_SKEY) && hpoll != peer->hpoll) 3022182007Sroberto key_expire(peer); 3023280849Scy#endif /* AUTOKEY */ 3024182007Sroberto peer->hpoll = hpoll; 302582505Sroberto 302682505Sroberto /* 3027280849Scy * There are three variables important for poll scheduling, the 3028280849Scy * current time (current_time), next scheduled time (nextdate) 3029280849Scy * and the earliest time (utemp). The earliest time is 2 s 3030280849Scy * seconds, but could be more due to rate management. When 3031280849Scy * sending in a burst, use the earliest time. When not in a 3032280849Scy * burst but with a reply pending, send at the earliest time 3033280849Scy * unless the next scheduled time has not advanced. This can 3034280849Scy * only happen if multiple replies are pending in the same 3035280849Scy * response interval. Otherwise, send at the later of the next 3036280849Scy * scheduled time and the earliest time. 3037280849Scy * 3038280849Scy * Now we figure out if there is an override. If a burst is in 3039280849Scy * progress and we get called from the receive process, just 3040280849Scy * slink away. If called from the poll process, delay 1 s for a 3041280849Scy * reference clock, otherwise 2 s. 304282505Sroberto */ 3043280849Scy utemp = current_time + max(peer->throttle - (NTP_SHIFT - 1) * 3044280849Scy (1 << peer->minpoll), ntp_minpkt); 3045358659Scy 3046358659Scy /*[Bug 3592] avoid unlimited postpone of next poll */ 3047358659Scy limit = (2u << hpoll); 3048358659Scy if (limit > 64) 3049358659Scy limit -= (limit >> 2); 3050358659Scy limit += peer->outdate; 3051358659Scy if (limit < current_time) 3052358659Scy limit = current_time; 3053358659Scy 305454359Sroberto if (peer->burst > 0) { 3055280849Scy if (peer->nextdate > current_time) 305654359Sroberto return; 305782505Sroberto#ifdef REFCLOCK 305882505Sroberto else if (peer->flags & FLAG_REFCLOCK) 3059280849Scy peer->nextdate = current_time + RESP_DELAY; 3060182007Sroberto#endif /* REFCLOCK */ 306154359Sroberto else 3062280849Scy peer->nextdate = utemp; 3063280849Scy 3064280849Scy#ifdef AUTOKEY 3065182007Sroberto /* 3066280849Scy * If a burst is not in progress and a crypto response message 3067280849Scy * is pending, delay 2 s, but only if this is a new interval. 3068182007Sroberto */ 3069280849Scy } else if (peer->cmmd != NULL) { 3070280849Scy if (peer->nextdate > current_time) { 3071280849Scy if (peer->nextdate + ntp_minpkt != utemp) 3072280849Scy peer->nextdate = utemp; 3073280849Scy } else { 3074280849Scy peer->nextdate = utemp; 3075280849Scy } 3076280849Scy#endif /* AUTOKEY */ 3077182007Sroberto 307882505Sroberto /* 3079280849Scy * The ordinary case. If a retry, use minpoll; if unreachable, 3080280849Scy * use host poll; otherwise, use the minimum of host and peer 3081280849Scy * polls; In other words, oversampling is okay but 3082280849Scy * understampling is evil. Use the maximum of this value and the 3083280849Scy * headway. If the average headway is greater than the headway 3084280849Scy * threshold, increase the headway by the minimum interval. 308582505Sroberto */ 3086280849Scy } else { 3087280849Scy if (peer->retry > 0) 3088280849Scy hpoll = peer->minpoll; 3089280849Scy else 3090280849Scy hpoll = min(peer->ppoll, peer->hpoll); 3091280849Scy#ifdef REFCLOCK 3092280849Scy if (peer->flags & FLAG_REFCLOCK) 3093280849Scy next = 1 << hpoll; 3094280849Scy else 3095280849Scy#endif /* REFCLOCK */ 3096280849Scy next = ((0x1000UL | (ntp_random() & 0x0ff)) << 3097280849Scy hpoll) >> 12; 3098280849Scy next += peer->outdate; 3099358659Scy /* XXX: bug3596: Deal with poll skew list? */ 3100358659Scy if (skewpoll) { 3101358659Scy psl_item psi; 3102358659Scy 3103358659Scy if (0 == get_pollskew(hpoll, &psi)) { 3104358659Scy int sub = psi.sub; 3105358659Scy int qty = psi.qty; 3106358659Scy int msk = psi.msk; 3107358659Scy int val; 3108358659Scy 3109358659Scy if ( 0 != sub 3110358659Scy || 0 != qty) { 3111358659Scy do { 3112358659Scy val = ntp_random() & msk; 3113358659Scy } while (val > qty); 3114358659Scy 3115358659Scy next -= sub; 3116358659Scy next += val; 3117358659Scy } 3118358659Scy } else { 3119358659Scy /* get_pollskew() already logged this */ 3120358659Scy } 3121358659Scy } 3122280849Scy if (next > utemp) 3123280849Scy peer->nextdate = next; 3124280849Scy else 3125280849Scy peer->nextdate = utemp; 3126280849Scy if (peer->throttle > (1 << peer->minpoll)) 3127280849Scy peer->nextdate += ntp_minpkt; 3128280849Scy } 3129358659Scy 3130358659Scy /*[Bug 3592] avoid unlimited postpone of next poll */ 3131358659Scy if (peer->nextdate > limit) { 3132358659Scy DPRINTF(1, ("poll_update: clamp reached; limit %lu next %lu\n", 3133358659Scy limit, peer->nextdate)); 3134358659Scy peer->nextdate = limit; 3135358659Scy } 3136280849Scy DPRINTF(2, ("poll_update: at %lu %s poll %d burst %d retry %d head %d early %lu next %lu\n", 3137280849Scy current_time, ntoa(&peer->srcadr), peer->hpoll, 3138280849Scy peer->burst, peer->retry, peer->throttle, 3139280849Scy utemp - current_time, peer->nextdate - 3140280849Scy current_time)); 314154359Sroberto} 314254359Sroberto 3143280849Scy 314454359Sroberto/* 3145280849Scy * peer_clear - clear peer filter registers. See Section 3.4.8 of the 3146280849Scy * spec. 314754359Sroberto */ 314854359Srobertovoid 3149280849Scypeer_clear( 3150280849Scy struct peer *peer, /* peer structure */ 3151280849Scy const char *ident /* tally lights */ 3152280849Scy ) 315354359Sroberto{ 3154280849Scy u_char u; 3155309007Sdelphij l_fp bxmt = peer->bxmt; /* bcast clients retain this! */ 3156280849Scy 3157280849Scy#ifdef AUTOKEY 315882505Sroberto /* 315982505Sroberto * If cryptographic credentials have been acquired, toss them to 316082505Sroberto * Valhalla. Note that autokeys are ephemeral, in that they are 316182505Sroberto * tossed immediately upon use. Therefore, the keylist can be 316282505Sroberto * purged anytime without needing to preserve random keys. Note 316382505Sroberto * that, if the peer is purged, the cryptographic variables are 316482505Sroberto * purged, too. This makes it much harder to sneak in some 316582505Sroberto * unauthenticated data in the clock filter. 316682505Sroberto */ 3167280849Scy key_expire(peer); 3168132454Sroberto if (peer->iffval != NULL) 3169132454Sroberto BN_free(peer->iffval); 3170132454Sroberto value_free(&peer->cookval); 3171132454Sroberto value_free(&peer->recval); 3172280849Scy value_free(&peer->encrypt); 3173280849Scy value_free(&peer->sndval); 3174280849Scy if (peer->cmmd != NULL) 3175182007Sroberto free(peer->cmmd); 3176280849Scy if (peer->subject != NULL) 3177280849Scy free(peer->subject); 3178280849Scy if (peer->issuer != NULL) 3179280849Scy free(peer->issuer); 3180280849Scy#endif /* AUTOKEY */ 3181182007Sroberto 318282505Sroberto /* 3183280849Scy * Clear all values, including the optional crypto values above. 318482505Sroberto */ 3185280849Scy memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO(peer)); 318682505Sroberto peer->ppoll = peer->maxpoll; 3187182007Sroberto peer->hpoll = peer->minpoll; 3188182007Sroberto peer->disp = MAXDISPERSE; 3189280849Scy peer->flash = peer_unfit(peer); 3190182007Sroberto peer->jitter = LOGTOD(sys_precision); 3191280849Scy 3192309007Sdelphij /* Don't throw away our broadcast replay protection */ 3193309007Sdelphij if (peer->hmode == MODE_BCLIENT) 3194309007Sdelphij peer->bxmt = bxmt; 3195309007Sdelphij 3196280849Scy /* 3197280849Scy * If interleave mode, initialize the alternate origin switch. 3198280849Scy */ 3199280849Scy if (peer->flags & FLAG_XLEAVE) 3200280849Scy peer->flip = 1; 3201280849Scy for (u = 0; u < NTP_SHIFT; u++) { 3202280849Scy peer->filter_order[u] = u; 3203280849Scy peer->filter_disp[u] = MAXDISPERSE; 3204182007Sroberto } 320582505Sroberto#ifdef REFCLOCK 320682505Sroberto if (!(peer->flags & FLAG_REFCLOCK)) { 3207280849Scy#endif 320882505Sroberto peer->leap = LEAP_NOTINSYNC; 320982505Sroberto peer->stratum = STRATUM_UNSPEC; 3210132454Sroberto memcpy(&peer->refid, ident, 4); 3211280849Scy#ifdef REFCLOCK 3212338530Sdelphij } else { 3213338530Sdelphij /* Clear refclock sample filter */ 3214338530Sdelphij peer->procptr->codeproc = 0; 3215338530Sdelphij peer->procptr->coderecv = 0; 321682505Sroberto } 3217280849Scy#endif 321854359Sroberto 321954359Sroberto /* 3220182007Sroberto * During initialization use the association count to spread out 3221280849Scy * the polls at one-second intervals. Passive associations' 3222280849Scy * first poll is delayed by the "discard minimum" to avoid rate 3223280849Scy * limiting. Other post-startup new or cleared associations 3224280849Scy * randomize the first poll over the minimum poll interval to 3225280849Scy * avoid implosion. 322654359Sroberto */ 3227132454Sroberto peer->nextdate = peer->update = peer->outdate = current_time; 3228280849Scy if (initializing) { 3229182007Sroberto peer->nextdate += peer_associations; 3230280849Scy } else if (MODE_PASSIVE == peer->hmode) { 3231280849Scy peer->nextdate += ntp_minpkt; 3232280849Scy } else { 3233280849Scy peer->nextdate += ntp_random() % peer->minpoll; 3234280849Scy } 3235280849Scy#ifdef AUTOKEY 3236280849Scy peer->refresh = current_time + (1 << NTP_REFRESH); 3237280849Scy#endif /* AUTOKEY */ 3238293423Sdelphij DPRINTF(1, ("peer_clear: at %ld next %ld associd %d refid %s\n", 3239280849Scy current_time, peer->nextdate, peer->associd, 3240293423Sdelphij ident)); 324154359Sroberto} 324254359Sroberto 324354359Sroberto 324454359Sroberto/* 324554359Sroberto * clock_filter - add incoming clock sample to filter register and run 324654359Sroberto * the filter procedure to find the best sample. 324754359Sroberto */ 324854359Srobertovoid 324954359Srobertoclock_filter( 3250132454Sroberto struct peer *peer, /* peer structure pointer */ 3251132454Sroberto double sample_offset, /* clock offset */ 3252132454Sroberto double sample_delay, /* roundtrip delay */ 3253132454Sroberto double sample_disp /* dispersion */ 325454359Sroberto ) 325554359Sroberto{ 3256132454Sroberto double dst[NTP_SHIFT]; /* distance vector */ 3257132454Sroberto int ord[NTP_SHIFT]; /* index vector */ 3258132454Sroberto int i, j, k, m; 3259182007Sroberto double dtemp, etemp; 3260280849Scy char tbuf[80]; 326154359Sroberto 326254359Sroberto /* 3263280849Scy * A sample consists of the offset, delay, dispersion and epoch 3264280849Scy * of arrival. The offset and delay are determined by the on- 3265280849Scy * wire protocol. The dispersion grows from the last outbound 3266280849Scy * packet to the arrival of this one increased by the sum of the 3267280849Scy * peer precision and the system precision as required by the 3268280849Scy * error budget. First, shift the new arrival into the shift 3269280849Scy * register discarding the oldest one. 327054359Sroberto */ 327154359Sroberto j = peer->filter_nextpt; 327282505Sroberto peer->filter_offset[j] = sample_offset; 3273280849Scy peer->filter_delay[j] = sample_delay; 3274182007Sroberto peer->filter_disp[j] = sample_disp; 3275182007Sroberto peer->filter_epoch[j] = current_time; 3276182007Sroberto j = (j + 1) % NTP_SHIFT; 3277182007Sroberto peer->filter_nextpt = j; 327854359Sroberto 327954359Sroberto /* 328082505Sroberto * Update dispersions since the last update and at the same 3281280849Scy * time initialize the distance and index lists. Since samples 3282280849Scy * become increasingly uncorrelated beyond the Allan intercept, 3283280849Scy * only under exceptional cases will an older sample be used. 3284280849Scy * Therefore, the distance list uses a compound metric. If the 3285280849Scy * dispersion is greater than the maximum dispersion, clamp the 3286280849Scy * distance at that value. If the time since the last update is 3287280849Scy * less than the Allan intercept use the delay; otherwise, use 3288280849Scy * the sum of the delay and dispersion. 328954359Sroberto */ 329082505Sroberto dtemp = clock_phi * (current_time - peer->update); 329182505Sroberto peer->update = current_time; 329282505Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 3293132454Sroberto if (i != 0) 329482505Sroberto peer->filter_disp[j] += dtemp; 3295282408Scy if (peer->filter_disp[j] >= MAXDISPERSE) { 3296132454Sroberto peer->filter_disp[j] = MAXDISPERSE; 329782505Sroberto dst[i] = MAXDISPERSE; 3298280849Scy } else if (peer->update - peer->filter_epoch[j] > 3299280849Scy (u_long)ULOGTOD(allan_xpt)) { 3300280849Scy dst[i] = peer->filter_delay[j] + 3301280849Scy peer->filter_disp[j]; 3302280849Scy } else { 3303132454Sroberto dst[i] = peer->filter_delay[j]; 3304280849Scy } 330582505Sroberto ord[i] = j; 3306280849Scy j = (j + 1) % NTP_SHIFT; 330782505Sroberto } 330854359Sroberto 3309280849Scy /* 3310282408Scy * If the clock has stabilized, sort the samples by distance. 331154359Sroberto */ 3312280849Scy if (freq_cnt == 0) { 3313182007Sroberto for (i = 1; i < NTP_SHIFT; i++) { 3314182007Sroberto for (j = 0; j < i; j++) { 3315280849Scy if (dst[j] > dst[i]) { 3316182007Sroberto k = ord[j]; 3317182007Sroberto ord[j] = ord[i]; 3318182007Sroberto ord[i] = k; 3319182007Sroberto etemp = dst[j]; 3320182007Sroberto dst[j] = dst[i]; 3321182007Sroberto dst[i] = etemp; 3322182007Sroberto } 332354359Sroberto } 332454359Sroberto } 332582505Sroberto } 332682505Sroberto 332782505Sroberto /* 332882505Sroberto * Copy the index list to the association structure so ntpq 3329280849Scy * can see it later. Prune the distance list to leave only 3330280849Scy * samples less than the maximum dispersion, which disfavors 3331280849Scy * uncorrelated samples older than the Allan intercept. To 3332280849Scy * further improve the jitter estimate, of the remainder leave 3333280849Scy * only samples less than the maximum distance, but keep at 3334280849Scy * least two samples for jitter calculation. 333582505Sroberto */ 333682505Sroberto m = 0; 333782505Sroberto for (i = 0; i < NTP_SHIFT; i++) { 3338132454Sroberto peer->filter_order[i] = (u_char) ord[i]; 3339289764Sglebius if ( dst[i] >= MAXDISPERSE 3340289764Sglebius || (m >= 2 && dst[i] >= sys_maxdist)) 334182505Sroberto continue; 334282505Sroberto m++; 334382505Sroberto } 3344282408Scy 334554359Sroberto /* 3346182007Sroberto * Compute the dispersion and jitter. The dispersion is weighted 3347182007Sroberto * exponentially by NTP_FWEIGHT (0.5) so it is normalized close 3348182007Sroberto * to 1.0. The jitter is the RMS differences relative to the 3349280849Scy * lowest delay sample. 335054359Sroberto */ 3351182007Sroberto peer->disp = peer->jitter = 0; 335282505Sroberto k = ord[0]; 335354359Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 335482505Sroberto j = ord[i]; 335582505Sroberto peer->disp = NTP_FWEIGHT * (peer->disp + 335682505Sroberto peer->filter_disp[j]); 335782505Sroberto if (i < m) 3358182007Sroberto peer->jitter += DIFF(peer->filter_offset[j], 335982505Sroberto peer->filter_offset[k]); 336054359Sroberto } 336154359Sroberto 336254359Sroberto /* 336382505Sroberto * If no acceptable samples remain in the shift register, 336482505Sroberto * quietly tiptoe home leaving only the dispersion. Otherwise, 3365182007Sroberto * save the offset, delay and jitter. Note the jitter must not 3366182007Sroberto * be less than the precision. 336782505Sroberto */ 3368280849Scy if (m == 0) { 3369280849Scy clock_select(); 337082505Sroberto return; 3371280849Scy } 3372132454Sroberto etemp = fabs(peer->offset - peer->filter_offset[k]); 337382505Sroberto peer->offset = peer->filter_offset[k]; 337482505Sroberto peer->delay = peer->filter_delay[k]; 337582505Sroberto if (m > 1) 3376182007Sroberto peer->jitter /= m - 1; 3377182007Sroberto peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision)); 337882505Sroberto 337982505Sroberto /* 3380280849Scy * If the the new sample and the current sample are both valid 3381280849Scy * and the difference between their offsets exceeds CLOCK_SGATE 3382280849Scy * (3) times the jitter and the interval between them is less 3383280849Scy * than twice the host poll interval, consider the new sample 3384280849Scy * a popcorn spike and ignore it. 338554359Sroberto */ 3386289764Sglebius if ( peer->disp < sys_maxdist 3387289764Sglebius && peer->filter_disp[k] < sys_maxdist 3388289764Sglebius && etemp > CLOCK_SGATE * peer->jitter 3389289764Sglebius && peer->filter_epoch[k] - peer->epoch 3390289764Sglebius < 2. * ULOGTOD(peer->hpoll)) { 3391280849Scy snprintf(tbuf, sizeof(tbuf), "%.6f s", etemp); 3392280849Scy report_event(PEVNT_POPCORN, peer, tbuf); 339354359Sroberto return; 339454359Sroberto } 339554359Sroberto 339654359Sroberto /* 3397280849Scy * A new minimum sample is useful only if it is later than the 3398280849Scy * last one used. In this design the maximum lifetime of any 3399280849Scy * sample is not greater than eight times the poll interval, so 3400280849Scy * the maximum interval between minimum samples is eight 3401280849Scy * packets. 340254359Sroberto */ 3403280849Scy if (peer->filter_epoch[k] <= peer->epoch) { 3404293423Sdelphij DPRINTF(2, ("clock_filter: old sample %lu\n", current_time - 3405293423Sdelphij peer->filter_epoch[k])); 340654359Sroberto return; 340754359Sroberto } 3408280849Scy peer->epoch = peer->filter_epoch[k]; 340982505Sroberto 341082505Sroberto /* 341182505Sroberto * The mitigated sample statistics are saved for later 3412280849Scy * processing. If not synchronized or not in a burst, tickle the 3413280849Scy * clock select algorithm. 341482505Sroberto */ 3415280849Scy record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), 3416280849Scy peer->offset, peer->delay, peer->disp, peer->jitter); 3417293423Sdelphij DPRINTF(1, ("clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f\n", 341882505Sroberto m, peer->offset, peer->delay, peer->disp, 3419293423Sdelphij peer->jitter)); 3420182007Sroberto if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) 3421182007Sroberto clock_select(); 342254359Sroberto} 342354359Sroberto 342454359Sroberto 342554359Sroberto/* 342654359Sroberto * clock_select - find the pick-of-the-litter clock 3427132454Sroberto * 3428280849Scy * LOCKCLOCK: (1) If the local clock is the prefer peer, it will always 3429280849Scy * be enabled, even if declared falseticker, (2) only the prefer peer 3430280849Scy * can be selected as the system peer, (3) if the external source is 3431280849Scy * down, the system leap bits are set to 11 and the stratum set to 3432280849Scy * infinity. 343354359Sroberto */ 343454359Srobertovoid 343554359Srobertoclock_select(void) 343654359Sroberto{ 3437132454Sroberto struct peer *peer; 3438132454Sroberto int i, j, k, n; 3439280849Scy int nlist, nl2; 3440280849Scy int allow; 3441280849Scy int speer; 3442182007Sroberto double d, e, f, g; 3443132454Sroberto double high, low; 3444280849Scy double speermet; 3445362716Scy double lastresort_dist = MAXDISPERSE; 3446280849Scy double orphmet = 2.0 * U_INT32_MAX; /* 2x is greater than */ 3447280849Scy struct endpoint endp; 344854359Sroberto struct peer *osys_peer; 3449280849Scy struct peer *sys_prefer = NULL; /* prefer peer */ 3450280849Scy struct peer *typesystem = NULL; 3451362716Scy struct peer *typelastresort = NULL; 3452280849Scy struct peer *typeorphan = NULL; 3453280849Scy#ifdef REFCLOCK 345482505Sroberto struct peer *typeacts = NULL; 345582505Sroberto struct peer *typelocal = NULL; 3456280849Scy struct peer *typepps = NULL; 3457280849Scy#endif /* REFCLOCK */ 345854359Sroberto static struct endpoint *endpoint = NULL; 345982505Sroberto static int *indx = NULL; 3460280849Scy static peer_select *peers = NULL; 346154359Sroberto static u_int endpoint_size = 0; 3462280849Scy static u_int peers_size = 0; 346382505Sroberto static u_int indx_size = 0; 3464280849Scy size_t octets; 346554359Sroberto 346654359Sroberto /* 346782505Sroberto * Initialize and create endpoint, index and peer lists big 346882505Sroberto * enough to handle all associations. 346954359Sroberto */ 347082505Sroberto osys_peer = sys_peer; 3471132454Sroberto sys_survivors = 0; 3472132454Sroberto#ifdef LOCKCLOCK 3473285169Scy set_sys_leap(LEAP_NOTINSYNC); 3474132454Sroberto sys_stratum = STRATUM_UNSPEC; 3475132454Sroberto memcpy(&sys_refid, "DOWN", 4); 3476132454Sroberto#endif /* LOCKCLOCK */ 347754359Sroberto 347854359Sroberto /* 3479280849Scy * Allocate dynamic space depending on the number of 3480280849Scy * associations. 3481280849Scy */ 3482280849Scy nlist = 1; 3483280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3484280849Scy nlist++; 3485280849Scy endpoint_size = ALIGNED_SIZE(nlist * 2 * sizeof(*endpoint)); 3486280849Scy peers_size = ALIGNED_SIZE(nlist * sizeof(*peers)); 3487280849Scy indx_size = ALIGNED_SIZE(nlist * 2 * sizeof(*indx)); 3488280849Scy octets = endpoint_size + peers_size + indx_size; 3489280849Scy endpoint = erealloc(endpoint, octets); 3490280849Scy peers = INC_ALIGNED_PTR(endpoint, endpoint_size); 3491280849Scy indx = INC_ALIGNED_PTR(peers, peers_size); 3492280849Scy 3493280849Scy /* 349482505Sroberto * Initially, we populate the island with all the rifraff peers 349582505Sroberto * that happen to be lying around. Those with seriously 349682505Sroberto * defective clocks are immediately booted off the island. Then, 349782505Sroberto * the falsetickers are culled and put to sea. The truechimers 349882505Sroberto * remaining are subject to repeated rounds where the most 349982505Sroberto * unpopular at each round is kicked off. When the population 3500132454Sroberto * has dwindled to sys_minclock, the survivors split a million 3501132454Sroberto * bucks and collectively crank the chimes. 350254359Sroberto */ 3503280849Scy nlist = nl2 = 0; /* none yet */ 3504280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) { 3505280849Scy peer->new_status = CTL_PST_SEL_REJECT; 350654359Sroberto 3507280849Scy /* 3508280849Scy * Leave the island immediately if the peer is 3509280849Scy * unfit to synchronize. 3510280849Scy */ 3511309007Sdelphij if (peer_unfit(peer)) { 3512280849Scy continue; 3513309007Sdelphij } 351482505Sroberto 3515280849Scy /* 3516362716Scy * If we have never been synchronised, look for any peer 3517362716Scy * which has ever been synchronised and pick the one which 3518362716Scy * has the lowest root distance. This can be used as a last 3519362716Scy * resort if all else fails. Once we get an initial sync 3520362716Scy * with this peer, sys_reftime gets set and so this 3521362716Scy * function becomes disabled. 3522362716Scy */ 3523362716Scy if (L_ISZERO(&sys_reftime)) { 3524362716Scy d = root_distance(peer); 3525362716Scy if (!L_ISZERO(&peer->reftime) && d < lastresort_dist) { 3526362716Scy typelastresort = peer; 3527362716Scy lastresort_dist = d; 3528362716Scy } 3529362716Scy } 3530362716Scy 3531362716Scy /* 3532280849Scy * If this peer is an orphan parent, elect the 3533280849Scy * one with the lowest metric defined as the 3534280849Scy * IPv4 address or the first 64 bits of the 3535280849Scy * hashed IPv6 address. To ensure convergence 3536280849Scy * on the same selected orphan, consider as 3537280849Scy * well that this system may have the lowest 3538280849Scy * metric and be the orphan parent. If this 3539280849Scy * system wins, sys_peer will be NULL to trigger 3540280849Scy * orphan mode in timer(). 3541280849Scy */ 3542280849Scy if (peer->stratum == sys_orphan) { 3543280849Scy u_int32 localmet; 3544280849Scy u_int32 peermet; 354554359Sroberto 3546280849Scy if (peer->dstadr != NULL) 3547280849Scy localmet = ntohl(peer->dstadr->addr_refid); 3548280849Scy else 3549280849Scy localmet = U_INT32_MAX; 3550280849Scy peermet = ntohl(addr2refid(&peer->srcadr)); 3551280849Scy if (peermet < localmet && peermet < orphmet) { 3552280849Scy typeorphan = peer; 3553280849Scy orphmet = peermet; 355454359Sroberto } 3555280849Scy continue; 3556280849Scy } 355754359Sroberto 3558280849Scy /* 3559280849Scy * If this peer could have the orphan parent 3560280849Scy * as a synchronization ancestor, exclude it 3561282408Scy * from selection to avoid forming a 3562280849Scy * synchronization loop within the orphan mesh, 3563282408Scy * triggering stratum climb to infinity 3564280849Scy * instability. Peers at stratum higher than 3565280849Scy * the orphan stratum could have the orphan 3566280849Scy * parent in ancestry so are excluded. 3567280849Scy * See http://bugs.ntp.org/2050 3568280849Scy */ 3569309007Sdelphij if (peer->stratum > sys_orphan) { 3570280849Scy continue; 3571309007Sdelphij } 3572280849Scy#ifdef REFCLOCK 3573280849Scy /* 3574280849Scy * The following are special cases. We deal 3575280849Scy * with them later. 3576280849Scy */ 3577280849Scy if (!(peer->flags & FLAG_PREFER)) { 3578280849Scy switch (peer->refclktype) { 3579280849Scy case REFCLK_LOCALCLOCK: 3580289764Sglebius if ( current_time > orphwait 3581289764Sglebius && typelocal == NULL) 3582280849Scy typelocal = peer; 3583280849Scy continue; 3584182007Sroberto 3585280849Scy case REFCLK_ACTS: 3586289764Sglebius if ( current_time > orphwait 3587289764Sglebius && typeacts == NULL) 3588280849Scy typeacts = peer; 3589280849Scy continue; 359054359Sroberto } 3591280849Scy } 3592280849Scy#endif /* REFCLOCK */ 359354359Sroberto 3594280849Scy /* 3595280849Scy * If we get this far, the peer can stay on the 3596280849Scy * island, but does not yet have the immunity 3597280849Scy * idol. 3598280849Scy */ 3599280849Scy peer->new_status = CTL_PST_SEL_SANE; 3600280849Scy f = root_distance(peer); 3601280849Scy peers[nlist].peer = peer; 3602280849Scy peers[nlist].error = peer->jitter; 3603280849Scy peers[nlist].synch = f; 3604280849Scy nlist++; 3605182007Sroberto 3606280849Scy /* 3607280849Scy * Insert each interval endpoint on the unsorted 3608280849Scy * endpoint[] list. 3609280849Scy */ 3610280849Scy e = peer->offset; 3611280849Scy endpoint[nl2].type = -1; /* lower end */ 3612280849Scy endpoint[nl2].val = e - f; 3613280849Scy nl2++; 3614280849Scy endpoint[nl2].type = 1; /* upper end */ 3615280849Scy endpoint[nl2].val = e + f; 3616280849Scy nl2++; 3617280849Scy } 3618280849Scy /* 3619280849Scy * Construct sorted indx[] of endpoint[] indexes ordered by 3620280849Scy * offset. 3621280849Scy */ 3622280849Scy for (i = 0; i < nl2; i++) 3623280849Scy indx[i] = i; 3624280849Scy for (i = 0; i < nl2; i++) { 3625280849Scy endp = endpoint[indx[i]]; 3626280849Scy e = endp.val; 3627280849Scy k = i; 3628280849Scy for (j = i + 1; j < nl2; j++) { 3629280849Scy endp = endpoint[indx[j]]; 3630280849Scy if (endp.val < e) { 3631280849Scy e = endp.val; 3632280849Scy k = j; 363354359Sroberto } 363454359Sroberto } 3635280849Scy if (k != i) { 3636280849Scy j = indx[k]; 3637280849Scy indx[k] = indx[i]; 3638280849Scy indx[i] = j; 3639280849Scy } 364054359Sroberto } 3641280849Scy for (i = 0; i < nl2; i++) 3642280849Scy DPRINTF(3, ("select: endpoint %2d %.6f\n", 3643280849Scy endpoint[indx[i]].type, endpoint[indx[i]].val)); 3644280849Scy 3645132454Sroberto /* 3646132454Sroberto * This is the actual algorithm that cleaves the truechimers 3647132454Sroberto * from the falsetickers. The original algorithm was described 3648132454Sroberto * in Keith Marzullo's dissertation, but has been modified for 3649132454Sroberto * better accuracy. 3650132454Sroberto * 3651132454Sroberto * Briefly put, we first assume there are no falsetickers, then 3652132454Sroberto * scan the candidate list first from the low end upwards and 3653132454Sroberto * then from the high end downwards. The scans stop when the 3654132454Sroberto * number of intersections equals the number of candidates less 3655132454Sroberto * the number of falsetickers. If this doesn't happen for a 3656132454Sroberto * given number of falsetickers, we bump the number of 3657132454Sroberto * falsetickers and try again. If the number of falsetickers 3658132454Sroberto * becomes equal to or greater than half the number of 3659132454Sroberto * candidates, the Albanians have won the Byzantine wars and 3660132454Sroberto * correct synchronization is not possible. 3661132454Sroberto * 3662132454Sroberto * Here, nlist is the number of candidates and allow is the 3663182007Sroberto * number of falsetickers. Upon exit, the truechimers are the 3664280849Scy * survivors with offsets not less than low and not greater than 3665182007Sroberto * high. There may be none of them. 3666132454Sroberto */ 3667132454Sroberto low = 1e9; 3668132454Sroberto high = -1e9; 3669132454Sroberto for (allow = 0; 2 * allow < nlist; allow++) { 3670132454Sroberto 3671132454Sroberto /* 3672282408Scy * Bound the interval (low, high) as the smallest 3673280849Scy * interval containing points from the most sources. 3674132454Sroberto */ 3675132454Sroberto n = 0; 3676280849Scy for (i = 0; i < nl2; i++) { 3677132454Sroberto low = endpoint[indx[i]].val; 3678132454Sroberto n -= endpoint[indx[i]].type; 3679132454Sroberto if (n >= nlist - allow) 368054359Sroberto break; 368154359Sroberto } 3682132454Sroberto n = 0; 3683280849Scy for (j = nl2 - 1; j >= 0; j--) { 3684132454Sroberto high = endpoint[indx[j]].val; 368582505Sroberto n += endpoint[indx[j]].type; 3686132454Sroberto if (n >= nlist - allow) 368754359Sroberto break; 368854359Sroberto } 3689132454Sroberto 3690132454Sroberto /* 3691132454Sroberto * If an interval containing truechimers is found, stop. 3692132454Sroberto * If not, increase the number of falsetickers and go 3693132454Sroberto * around again. 3694132454Sroberto */ 3695132454Sroberto if (high > low) 369654359Sroberto break; 369754359Sroberto } 369854359Sroberto 369954359Sroberto /* 3700280849Scy * Clustering algorithm. Whittle candidate list of falsetickers, 3701280849Scy * who leave the island immediately. The TRUE peer is always a 3702182007Sroberto * truechimer. We must leave at least one peer to collect the 3703280849Scy * million bucks. 3704280849Scy * 3705280849Scy * We assert the correct time is contained in the interval, but 3706280849Scy * the best offset estimate for the interval might not be 3707280849Scy * contained in the interval. For this purpose, a truechimer is 3708282408Scy * defined as the midpoint of an interval that overlaps the 3709280849Scy * intersection interval. 3710182007Sroberto */ 3711182007Sroberto j = 0; 3712182007Sroberto for (i = 0; i < nlist; i++) { 3713280849Scy double h; 3714280849Scy 3715280849Scy peer = peers[i].peer; 3716280849Scy h = peers[i].synch; 3717289764Sglebius if (( high <= low 3718289764Sglebius || peer->offset + h < low 3719289764Sglebius || peer->offset - h > high 3720289764Sglebius ) && !(peer->flags & FLAG_TRUE)) 3721182007Sroberto continue; 3722182007Sroberto 3723280849Scy#ifdef REFCLOCK 3724182007Sroberto /* 3725280849Scy * Eligible PPS peers must survive the intersection 3726280849Scy * algorithm. Use the first one found, but don't 3727280849Scy * include any of them in the cluster population. 3728182007Sroberto */ 3729280849Scy if (peer->flags & FLAG_PPS) { 3730282408Scy if (typepps == NULL) 3731280849Scy typepps = peer; 3732282408Scy if (!(peer->flags & FLAG_TSTAMP_PPS)) 3733282408Scy continue; 3734182007Sroberto } 3735280849Scy#endif /* REFCLOCK */ 3736182007Sroberto 3737280849Scy if (j != i) 3738280849Scy peers[j] = peers[i]; 3739182007Sroberto j++; 3740182007Sroberto } 3741182007Sroberto nlist = j; 3742182007Sroberto 3743182007Sroberto /* 3744282408Scy * If no survivors remain at this point, check if the modem 3745280849Scy * driver, local driver or orphan parent in that order. If so, 3746280849Scy * nominate the first one found as the only survivor. 3747280849Scy * Otherwise, give up and leave the island to the rats. 374854359Sroberto */ 3749182007Sroberto if (nlist == 0) { 3750280849Scy peers[0].error = 0; 3751280849Scy peers[0].synch = sys_mindisp; 3752280849Scy#ifdef REFCLOCK 3753280849Scy if (typeacts != NULL) { 3754280849Scy peers[0].peer = typeacts; 375554359Sroberto nlist = 1; 3756280849Scy } else if (typelocal != NULL) { 3757280849Scy peers[0].peer = typelocal; 375854359Sroberto nlist = 1; 3759280849Scy } else 3760280849Scy#endif /* REFCLOCK */ 3761280849Scy if (typeorphan != NULL) { 3762280849Scy peers[0].peer = typeorphan; 3763280849Scy nlist = 1; 3764362716Scy } else if (typelastresort != NULL) { 3765362716Scy peers[0].peer = typelastresort; 3766362716Scy nlist = 1; 376754359Sroberto } 376854359Sroberto } 376954359Sroberto 377054359Sroberto /* 3771280849Scy * Mark the candidates at this point as truechimers. 3772132454Sroberto */ 3773280849Scy for (i = 0; i < nlist; i++) { 3774280849Scy peers[i].peer->new_status = CTL_PST_SEL_SELCAND; 3775280849Scy DPRINTF(2, ("select: survivor %s %f\n", 3776280849Scy stoa(&peers[i].peer->srcadr), peers[i].synch)); 3777280849Scy } 3778132454Sroberto 377954359Sroberto /* 3780289764Sglebius * Now, vote outliers off the island by select jitter weighted 3781182007Sroberto * by root distance. Continue voting as long as there are more 3782280849Scy * than sys_minclock survivors and the select jitter of the peer 3783280849Scy * with the worst metric is greater than the minimum peer 3784282408Scy * jitter. Stop if we are about to discard a TRUE or PREFER 3785280849Scy * peer, who of course have the immunity idol. 378654359Sroberto */ 378754359Sroberto while (1) { 378882505Sroberto d = 1e9; 378982505Sroberto e = -1e9; 3790280849Scy g = 0; 379182505Sroberto k = 0; 379282505Sroberto for (i = 0; i < nlist; i++) { 3793280849Scy if (peers[i].error < d) 3794280849Scy d = peers[i].error; 3795280849Scy peers[i].seljit = 0; 379682505Sroberto if (nlist > 1) { 3797280849Scy f = 0; 379882505Sroberto for (j = 0; j < nlist; j++) 3799280849Scy f += DIFF(peers[j].peer->offset, 3800280849Scy peers[i].peer->offset); 3801280849Scy peers[i].seljit = SQRT(f / (nlist - 1)); 380254359Sroberto } 3803280849Scy if (peers[i].seljit * peers[i].synch > e) { 3804280849Scy g = peers[i].seljit; 3805280849Scy e = peers[i].seljit * peers[i].synch; 380654359Sroberto k = i; 380754359Sroberto } 380854359Sroberto } 3809280849Scy g = max(g, LOGTOD(sys_precision)); 3810289764Sglebius if ( nlist <= max(1, sys_minclock) 3811289764Sglebius || g <= d 3812289764Sglebius || ((FLAG_TRUE | FLAG_PREFER) & peers[k].peer->flags)) 3813132454Sroberto break; 3814280849Scy 3815280849Scy DPRINTF(3, ("select: drop %s seljit %.6f jit %.6f\n", 3816280849Scy ntoa(&peers[k].peer->srcadr), g, d)); 3817280849Scy if (nlist > sys_maxclock) 3818280849Scy peers[k].peer->new_status = CTL_PST_SEL_EXCESS; 3819280849Scy for (j = k + 1; j < nlist; j++) 3820280849Scy peers[j - 1] = peers[j]; 382154359Sroberto nlist--; 382254359Sroberto } 382382505Sroberto 382482505Sroberto /* 3825132454Sroberto * What remains is a list usually not greater than sys_minclock 3826280849Scy * peers. Note that unsynchronized peers cannot survive this 3827280849Scy * far. Count and mark these survivors. 3828280849Scy * 3829280849Scy * While at it, count the number of leap warning bits found. 3830280849Scy * This will be used later to vote the system leap warning bit. 3831280849Scy * If a leap warning bit is found on a reference clock, the vote 3832280849Scy * is always won. 3833280849Scy * 3834280849Scy * Choose the system peer using a hybrid metric composed of the 3835280849Scy * selection jitter scaled by the root distance augmented by 3836280849Scy * stratum scaled by sys_mindisp (.001 by default). The goal of 3837280849Scy * the small stratum factor is to avoid clockhop between a 3838280849Scy * reference clock and a network peer which has a refclock and 3839280849Scy * is using an older ntpd, which does not floor sys_rootdisp at 3840280849Scy * sys_mindisp. 3841280849Scy * 3842280849Scy * In contrast, ntpd 4.2.6 and earlier used stratum primarily 3843280849Scy * in selecting the system peer, using a weight of 1 second of 3844280849Scy * additional root distance per stratum. This heavy bias is no 3845280849Scy * longer appropriate, as the scaled root distance provides a 3846280849Scy * more rational metric carrying the cumulative error budget. 384754359Sroberto */ 3848280849Scy e = 1e9; 3849280849Scy speer = 0; 3850280849Scy leap_vote_ins = 0; 3851280849Scy leap_vote_del = 0; 3852182007Sroberto for (i = 0; i < nlist; i++) { 3853280849Scy peer = peers[i].peer; 3854280849Scy peer->unreach = 0; 3855280849Scy peer->new_status = CTL_PST_SEL_SYNCCAND; 3856182007Sroberto sys_survivors++; 3857280849Scy if (peer->leap == LEAP_ADDSECOND) { 3858280849Scy if (peer->flags & FLAG_REFCLOCK) 3859280849Scy leap_vote_ins = nlist; 3860280849Scy else if (leap_vote_ins < nlist) 3861280849Scy leap_vote_ins++; 3862280849Scy } 3863280849Scy if (peer->leap == LEAP_DELSECOND) { 3864280849Scy if (peer->flags & FLAG_REFCLOCK) 3865280849Scy leap_vote_del = nlist; 3866280849Scy else if (leap_vote_del < nlist) 3867280849Scy leap_vote_del++; 3868280849Scy } 3869132454Sroberto if (peer->flags & FLAG_PREFER) 3870132454Sroberto sys_prefer = peer; 3871280849Scy speermet = peers[i].seljit * peers[i].synch + 3872280849Scy peer->stratum * sys_mindisp; 3873280849Scy if (speermet < e) { 3874280849Scy e = speermet; 3875280849Scy speer = i; 3876280849Scy } 387754359Sroberto } 387854359Sroberto 387954359Sroberto /* 3880280849Scy * Unless there are at least sys_misane survivors, leave the 3881280849Scy * building dark. Otherwise, do a clockhop dance. Ordinarily, 3882280849Scy * use the selected survivor speer. However, if the current 3883280849Scy * system peer is not speer, stay with the current system peer 3884280849Scy * as long as it doesn't get too old or too ugly. 3885132454Sroberto */ 3886280849Scy if (nlist > 0 && nlist >= sys_minsane) { 3887280849Scy double x; 3888280849Scy 3889280849Scy typesystem = peers[speer].peer; 3890280849Scy if (osys_peer == NULL || osys_peer == typesystem) { 3891282408Scy sys_clockhop = 0; 3892280849Scy } else if ((x = fabs(typesystem->offset - 3893280849Scy osys_peer->offset)) < sys_mindisp) { 3894280849Scy if (sys_clockhop == 0) 3895280849Scy sys_clockhop = sys_mindisp; 3896280849Scy else 3897280849Scy sys_clockhop *= .5; 3898280849Scy DPRINTF(1, ("select: clockhop %d %.6f %.6f\n", 3899280849Scy j, x, sys_clockhop)); 3900280849Scy if (fabs(x) < sys_clockhop) 3901280849Scy typesystem = osys_peer; 3902280849Scy else 3903280849Scy sys_clockhop = 0; 3904280849Scy } else { 3905280849Scy sys_clockhop = 0; 3906280849Scy } 3907182007Sroberto } 3908132454Sroberto 3909132454Sroberto /* 3910280849Scy * Mitigation rules of the game. We have the pick of the 3911280849Scy * litter in typesystem if any survivors are left. If 3912280849Scy * there is a prefer peer, use its offset and jitter. 3913280849Scy * Otherwise, use the combined offset and jitter of all kitters. 391454359Sroberto */ 3915280849Scy if (typesystem != NULL) { 3916280849Scy if (sys_prefer == NULL) { 3917280849Scy typesystem->new_status = CTL_PST_SEL_SYSPEER; 3918280849Scy clock_combine(peers, sys_survivors, speer); 3919182007Sroberto } else { 3920280849Scy typesystem = sys_prefer; 3921280849Scy sys_clockhop = 0; 3922280849Scy typesystem->new_status = CTL_PST_SEL_SYSPEER; 3923280849Scy sys_offset = typesystem->offset; 3924280849Scy sys_jitter = typesystem->jitter; 3925182007Sroberto } 3926280849Scy DPRINTF(1, ("select: combine offset %.9f jitter %.9f\n", 3927280849Scy sys_offset, sys_jitter)); 3928280849Scy } 3929280849Scy#ifdef REFCLOCK 3930280849Scy /* 3931280849Scy * If a PPS driver is lit and the combined offset is less than 3932280849Scy * 0.4 s, select the driver as the PPS peer and use its offset 3933280849Scy * and jitter. However, if this is the atom driver, use it only 3934280849Scy * if there is a prefer peer or there are no survivors and none 3935280849Scy * are required. 3936280849Scy */ 3937289764Sglebius if ( typepps != NULL 3938289764Sglebius && fabs(sys_offset) < 0.4 3939289764Sglebius && ( typepps->refclktype != REFCLK_ATOM_PPS 3940289764Sglebius || ( typepps->refclktype == REFCLK_ATOM_PPS 3941289764Sglebius && ( sys_prefer != NULL 3942289764Sglebius || (typesystem == NULL && sys_minsane == 0))))) { 3943280849Scy typesystem = typepps; 3944280849Scy sys_clockhop = 0; 3945280849Scy typesystem->new_status = CTL_PST_SEL_PPS; 3946293423Sdelphij sys_offset = typesystem->offset; 3947280849Scy sys_jitter = typesystem->jitter; 3948280849Scy DPRINTF(1, ("select: pps offset %.9f jitter %.9f\n", 3949280849Scy sys_offset, sys_jitter)); 3950280849Scy } 3951280849Scy#endif /* REFCLOCK */ 3952182007Sroberto 3953280849Scy /* 3954280849Scy * If there are no survivors at this point, there is no 3955280849Scy * system peer. If so and this is an old update, keep the 3956280849Scy * current statistics, but do not update the clock. 3957280849Scy */ 3958280849Scy if (typesystem == NULL) { 3959280849Scy if (osys_peer != NULL) { 3960362716Scy orphwait = current_time + sys_orphwait; 3961280849Scy report_event(EVNT_NOPEER, NULL, NULL); 3962182007Sroberto } 3963280849Scy sys_peer = NULL; 3964280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3965280849Scy peer->status = peer->new_status; 3966280849Scy return; 396754359Sroberto } 3968182007Sroberto 3969182007Sroberto /* 3970280849Scy * Do not use old data, as this may mess up the clock discipline 3971280849Scy * stability. 3972182007Sroberto */ 3973280849Scy if (typesystem->epoch <= sys_epoch) 3974280849Scy return; 3975132454Sroberto 3976280849Scy /* 3977280849Scy * We have found the alpha male. Wind the clock. 3978280849Scy */ 3979280849Scy if (osys_peer != typesystem) 3980280849Scy report_event(PEVNT_NEWPEER, typesystem, NULL); 3981280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3982280849Scy peer->status = peer->new_status; 3983280849Scy clock_update(typesystem); 398454359Sroberto} 398554359Sroberto 3986182007Sroberto 3987182007Srobertostatic void 398854359Srobertoclock_combine( 3989280849Scy peer_select * peers, /* survivor list */ 3990280849Scy int npeers, /* number of survivors */ 3991280849Scy int syspeer /* index of sys.peer */ 399254359Sroberto ) 399354359Sroberto{ 3994132454Sroberto int i; 3995182007Sroberto double x, y, z, w; 3996132454Sroberto 3997182007Sroberto y = z = w = 0; 399854359Sroberto for (i = 0; i < npeers; i++) { 3999280849Scy x = 1. / peers[i].synch; 4000280849Scy y += x; 4001280849Scy z += x * peers[i].peer->offset; 4002280849Scy w += x * DIFF(peers[i].peer->offset, 4003280849Scy peers[syspeer].peer->offset); 400454359Sroberto } 4005182007Sroberto sys_offset = z / y; 4006280849Scy sys_jitter = SQRT(w / y + SQUARE(peers[syspeer].seljit)); 400754359Sroberto} 400854359Sroberto 4009280849Scy 401054359Sroberto/* 401154359Sroberto * root_distance - compute synchronization distance from peer to root 401254359Sroberto */ 401354359Srobertostatic double 401454359Srobertoroot_distance( 4015280849Scy struct peer *peer /* peer structure pointer */ 401654359Sroberto ) 401754359Sroberto{ 4018280849Scy double dtemp; 4019182007Sroberto 402082505Sroberto /* 4021280849Scy * Root Distance (LAMBDA) is defined as: 4022309007Sdelphij * (delta + DELTA)/2 + epsilon + EPSILON + D 4023280849Scy * 4024280849Scy * where: 4025280849Scy * delta is the round-trip delay 4026280849Scy * DELTA is the root delay 4027309007Sdelphij * epsilon is the peer dispersion 4028280849Scy * + (15 usec each second) 4029280849Scy * EPSILON is the root dispersion 4030309007Sdelphij * D is sys_jitter 4031280849Scy * 4032280849Scy * NB: Think hard about why we are using these values, and what 4033280849Scy * the alternatives are, and the various pros/cons. 4034280849Scy * 4035280849Scy * DLM thinks these are probably the best choices from any of the 4036280849Scy * other worse choices. 4037280849Scy */ 4038280849Scy dtemp = (peer->delay + peer->rootdelay) / 2 4039309007Sdelphij + peer->disp 4040280849Scy + clock_phi * (current_time - peer->update) 4041280849Scy + peer->rootdisp 4042280849Scy + peer->jitter; 4043280849Scy /* 404482505Sroberto * Careful squeak here. The value returned must be greater than 4045182007Sroberto * the minimum root dispersion in order to avoid clockhop with 4046280849Scy * highly precise reference clocks. Note that the root distance 4047280849Scy * cannot exceed the sys_maxdist, as this is the cutoff by the 4048280849Scy * selection algorithm. 404982505Sroberto */ 4050280849Scy if (dtemp < sys_mindisp) 4051280849Scy dtemp = sys_mindisp; 4052280849Scy return (dtemp); 405354359Sroberto} 405454359Sroberto 4055280849Scy 405654359Sroberto/* 405754359Sroberto * peer_xmit - send packet for persistent association. 405854359Sroberto */ 405954359Srobertostatic void 406054359Srobertopeer_xmit( 406154359Sroberto struct peer *peer /* peer structure pointer */ 406254359Sroberto ) 406354359Sroberto{ 406482505Sroberto struct pkt xpkt; /* transmit packet */ 4065280849Scy size_t sendlen, authlen; 4066182007Sroberto keyid_t xkeyid = 0; /* transmit key ID */ 4067280849Scy l_fp xmt_tx, xmt_ty; 406854359Sroberto 4069280849Scy if (!peer->dstadr) /* drop peers without interface */ 4070182007Sroberto return; 4071182007Sroberto 4072280849Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version, 4073280849Scy peer->hmode); 4074280849Scy xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 407554359Sroberto xpkt.ppoll = peer->hpoll; 407654359Sroberto xpkt.precision = sys_precision; 4077280849Scy xpkt.refid = sys_refid; 4078280849Scy xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 4079280849Scy xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); 4080358659Scy /* Use sys_reftime for peer exchanges */ 408154359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 4082280849Scy HTONL_FP(&peer->rec, &xpkt.org); 4083280849Scy HTONL_FP(&peer->dst, &xpkt.rec); 408454359Sroberto 408554359Sroberto /* 408682505Sroberto * If the received packet contains a MAC, the transmitted packet 408782505Sroberto * is authenticated and contains a MAC. If not, the transmitted 408882505Sroberto * packet is not authenticated. 408982505Sroberto * 4090182007Sroberto * It is most important when autokey is in use that the local 4091182007Sroberto * interface IP address be known before the first packet is 4092182007Sroberto * sent. Otherwise, it is not possible to compute a correct MAC 4093182007Sroberto * the recipient will accept. Thus, the I/O semantics have to do 4094182007Sroberto * a little more work. In particular, the wildcard interface 4095182007Sroberto * might not be usable. 409654359Sroberto */ 409754359Sroberto sendlen = LEN_PKT_NOMAC; 4098293423Sdelphij if ( 4099280849Scy#ifdef AUTOKEY 4100293423Sdelphij !(peer->flags & FLAG_SKEY) && 4101280849Scy#endif /* !AUTOKEY */ 4102293423Sdelphij peer->keyid == 0) { 4103280849Scy 4104280849Scy /* 4105280849Scy * Transmit a-priori timestamps 4106280849Scy */ 4107280849Scy get_systime(&xmt_tx); 4108280849Scy if (peer->flip == 0) { /* basic mode */ 4109280849Scy peer->aorg = xmt_tx; 4110280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4111280849Scy } else { /* interleaved modes */ 4112280849Scy if (peer->hmode == MODE_BROADCAST) { /* bcst */ 4113280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4114280849Scy if (peer->flip > 0) 4115280849Scy HTONL_FP(&peer->borg, 4116280849Scy &xpkt.org); 4117280849Scy else 4118280849Scy HTONL_FP(&peer->aorg, 4119280849Scy &xpkt.org); 4120280849Scy } else { /* symmetric */ 4121280849Scy if (peer->flip > 0) 4122280849Scy HTONL_FP(&peer->borg, 4123280849Scy &xpkt.xmt); 4124280849Scy else 4125280849Scy HTONL_FP(&peer->aorg, 4126280849Scy &xpkt.xmt); 4127280849Scy } 4128280849Scy } 4129280849Scy peer->t21_bytes = sendlen; 4130316068Sdelphij sendpkt(&peer->srcadr, peer->dstadr, 4131316068Sdelphij sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl], 4132316068Sdelphij &xpkt, sendlen); 413382505Sroberto peer->sent++; 4134280849Scy peer->throttle += (1 << peer->minpoll) - 2; 4135280849Scy 4136280849Scy /* 4137280849Scy * Capture a-posteriori timestamps 4138280849Scy */ 4139280849Scy get_systime(&xmt_ty); 4140280849Scy if (peer->flip != 0) { /* interleaved modes */ 4141280849Scy if (peer->flip > 0) 4142280849Scy peer->aorg = xmt_ty; 4143280849Scy else 4144280849Scy peer->borg = xmt_ty; 4145280849Scy peer->flip = -peer->flip; 4146280849Scy } 4147280849Scy L_SUB(&xmt_ty, &xmt_tx); 4148280849Scy LFPTOD(&xmt_ty, peer->xleave); 4149293423Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d len %zu xmt %#010x.%08x\n", 4150293423Sdelphij current_time, 4151293423Sdelphij peer->dstadr ? stoa(&peer->dstadr->sin) : "-", 4152338530Sdelphij stoa(&peer->srcadr), peer->hmode, sendlen, 4153293423Sdelphij xmt_tx.l_ui, xmt_tx.l_uf)); 415482505Sroberto return; 415582505Sroberto } 415654359Sroberto 415782505Sroberto /* 4158280849Scy * Authentication is enabled, so the transmitted packet must be 4159280849Scy * authenticated. If autokey is enabled, fuss with the various 4160280849Scy * modes; otherwise, symmetric key cryptography is used. 416182505Sroberto */ 4162280849Scy#ifdef AUTOKEY 4163280849Scy if (peer->flags & FLAG_SKEY) { 4164132454Sroberto struct exten *exten; /* extension field */ 416582505Sroberto 416654359Sroberto /* 416782505Sroberto * The Public Key Dance (PKD): Cryptographic credentials 416882505Sroberto * are contained in extension fields, each including a 416982505Sroberto * 4-octet length/code word followed by a 4-octet 417082505Sroberto * association ID and optional additional data. Optional 417182505Sroberto * data includes a 4-octet data length field followed by 417282505Sroberto * the data itself. Request messages are sent from a 417382505Sroberto * configured association; response messages can be sent 417482505Sroberto * from a configured association or can take the fast 417582505Sroberto * path without ever matching an association. Response 417682505Sroberto * messages have the same code as the request, but have 417782505Sroberto * a response bit and possibly an error bit set. In this 417882505Sroberto * implementation, a message may contain no more than 4179280849Scy * one command and one or more responses. 418082505Sroberto * 418182505Sroberto * Cryptographic session keys include both a public and 418282505Sroberto * a private componet. Request and response messages 418382505Sroberto * using extension fields are always sent with the 418482505Sroberto * private component set to zero. Packets without 418582505Sroberto * extension fields indlude the private component when 418682505Sroberto * the session key is generated. 418754359Sroberto */ 418882505Sroberto while (1) { 4189282408Scy 419054359Sroberto /* 419182505Sroberto * Allocate and initialize a keylist if not 419282505Sroberto * already done. Then, use the list in inverse 419382505Sroberto * order, discarding keys once used. Keep the 419482505Sroberto * latest key around until the next one, so 419582505Sroberto * clients can use client/server packets to 419682505Sroberto * compute propagation delay. 419782505Sroberto * 419882505Sroberto * Note that once a key is used from the list, 419982505Sroberto * it is retained in the key cache until the 420082505Sroberto * next key is used. This is to allow a client 420182505Sroberto * to retrieve the encrypted session key 420282505Sroberto * identifier to verify authenticity. 420382505Sroberto * 420482505Sroberto * If for some reason a key is no longer in the 4205280849Scy * key cache, a birthday has happened or the key 4206280849Scy * has expired, so the pseudo-random sequence is 4207280849Scy * broken. In that case, purge the keylist and 4208280849Scy * regenerate it. 420954359Sroberto */ 421082505Sroberto if (peer->keynumber == 0) 421182505Sroberto make_keylist(peer, peer->dstadr); 421282505Sroberto else 421382505Sroberto peer->keynumber--; 421482505Sroberto xkeyid = peer->keylist[peer->keynumber]; 421582505Sroberto if (authistrusted(xkeyid)) 421682505Sroberto break; 421782505Sroberto else 421882505Sroberto key_expire(peer); 421954359Sroberto } 422082505Sroberto peer->keyid = xkeyid; 4221182007Sroberto exten = NULL; 422282505Sroberto switch (peer->hmode) { 422354359Sroberto 4224280849Scy /* 4225280849Scy * In broadcast server mode the autokey values are 4226280849Scy * required by the broadcast clients. Push them when a 4227280849Scy * new keylist is generated; otherwise, push the 4228280849Scy * association message so the client can request them at 4229280849Scy * other times. 4230280849Scy */ 423182505Sroberto case MODE_BROADCAST: 423282505Sroberto if (peer->flags & FLAG_ASSOC) 4233132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 4234280849Scy CRYPTO_RESP, peer->associd, NULL); 423582505Sroberto else 4236132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC | 4237280849Scy CRYPTO_RESP, peer->associd, NULL); 423882505Sroberto break; 423982505Sroberto 424054359Sroberto /* 4241282408Scy * In symmetric modes the parameter, certificate, 4242280849Scy * identity, cookie and autokey exchanges are 4243280849Scy * required. The leapsecond exchange is optional. But, a 4244280849Scy * peer will not believe the other peer until the other 4245280849Scy * peer has synchronized, so the certificate exchange 4246280849Scy * might loop until then. If a peer finds a broken 4247280849Scy * autokey sequence, it uses the autokey exchange to 4248280849Scy * retrieve the autokey values. In any case, if a new 4249280849Scy * keylist is generated, the autokey values are pushed. 425054359Sroberto */ 425182505Sroberto case MODE_ACTIVE: 425282505Sroberto case MODE_PASSIVE: 4253280849Scy 4254182007Sroberto /* 4255280849Scy * Parameter, certificate and identity. 4256182007Sroberto */ 425782505Sroberto if (!peer->crypto) 4258132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 4259280849Scy peer->associd, hostval.ptr); 4260280849Scy else if (!(peer->crypto & CRYPTO_FLAG_CERT)) 4261132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 4262280849Scy peer->associd, peer->issuer); 4263182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 4264182007Sroberto exten = crypto_args(peer, 4265280849Scy crypto_ident(peer), peer->associd, 4266280849Scy NULL); 4267132454Sroberto 4268132454Sroberto /* 4269280849Scy * Cookie and autokey. We request the cookie 4270280849Scy * only when the this peer and the other peer 4271280849Scy * are synchronized. But, this peer needs the 4272280849Scy * autokey values when the cookie is zero. Any 4273280849Scy * time we regenerate the key list, we offer the 4274280849Scy * autokey values without being asked. If for 4275280849Scy * some reason either peer finds a broken 4276280849Scy * autokey sequence, the autokey exchange is 4277280849Scy * used to retrieve the autokey values. 4278132454Sroberto */ 4279289764Sglebius else if ( sys_leap != LEAP_NOTINSYNC 4280289764Sglebius && peer->leap != LEAP_NOTINSYNC 4281289764Sglebius && !(peer->crypto & CRYPTO_FLAG_COOK)) 4282132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 4283280849Scy peer->associd, NULL); 4284132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 4285132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 4286280849Scy peer->associd, NULL); 4287289764Sglebius else if ( peer->flags & FLAG_ASSOC 4288289764Sglebius && peer->crypto & CRYPTO_FLAG_SIGN) 4289280849Scy exten = crypto_args(peer, CRYPTO_AUTO | 4290280849Scy CRYPTO_RESP, peer->assoc, NULL); 4291132454Sroberto 4292132454Sroberto /* 4293280849Scy * Wait for clock sync, then sign the 4294280849Scy * certificate and retrieve the leapsecond 4295280849Scy * values. 4296132454Sroberto */ 4297280849Scy else if (sys_leap == LEAP_NOTINSYNC) 4298280849Scy break; 4299280849Scy 4300280849Scy else if (!(peer->crypto & CRYPTO_FLAG_SIGN)) 4301280849Scy exten = crypto_args(peer, CRYPTO_SIGN, 4302280849Scy peer->associd, hostval.ptr); 4303280849Scy else if (!(peer->crypto & CRYPTO_FLAG_LEAP)) 4304280849Scy exten = crypto_args(peer, CRYPTO_LEAP, 4305280849Scy peer->associd, NULL); 430682505Sroberto break; 430782505Sroberto 430882505Sroberto /* 4309280849Scy * In client mode the parameter, certificate, identity, 4310280849Scy * cookie and sign exchanges are required. The 4311280849Scy * leapsecond exchange is optional. If broadcast client 4312280849Scy * mode the same exchanges are required, except that the 4313280849Scy * autokey exchange is substitutes for the cookie 4314280849Scy * exchange, since the cookie is always zero. If the 4315280849Scy * broadcast client finds a broken autokey sequence, it 4316280849Scy * uses the autokey exchange to retrieve the autokey 4317280849Scy * values. 431882505Sroberto */ 431982505Sroberto case MODE_CLIENT: 4320280849Scy 4321182007Sroberto /* 4322280849Scy * Parameter, certificate and identity. 4323182007Sroberto */ 432482505Sroberto if (!peer->crypto) 4325132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 4326280849Scy peer->associd, hostval.ptr); 4327280849Scy else if (!(peer->crypto & CRYPTO_FLAG_CERT)) 4328132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 4329280849Scy peer->associd, peer->issuer); 4330182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 4331182007Sroberto exten = crypto_args(peer, 4332280849Scy crypto_ident(peer), peer->associd, 4333280849Scy NULL); 4334132454Sroberto 4335132454Sroberto /* 4336280849Scy * Cookie and autokey. These are requests, but 4337280849Scy * we use the peer association ID with autokey 4338280849Scy * rather than our own. 4339132454Sroberto */ 4340280849Scy else if (!(peer->crypto & CRYPTO_FLAG_COOK)) 4341132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 4342280849Scy peer->associd, NULL); 4343280849Scy else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 4344132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 4345280849Scy peer->assoc, NULL); 4346132454Sroberto 4347132454Sroberto /* 4348280849Scy * Wait for clock sync, then sign the 4349280849Scy * certificate and retrieve the leapsecond 4350280849Scy * values. 4351132454Sroberto */ 4352280849Scy else if (sys_leap == LEAP_NOTINSYNC) 4353280849Scy break; 4354280849Scy 4355280849Scy else if (!(peer->crypto & CRYPTO_FLAG_SIGN)) 4356132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 4357280849Scy peer->associd, hostval.ptr); 4358280849Scy else if (!(peer->crypto & CRYPTO_FLAG_LEAP)) 4359280849Scy exten = crypto_args(peer, CRYPTO_LEAP, 4360280849Scy peer->associd, NULL); 436182505Sroberto break; 436282505Sroberto } 436382505Sroberto 436482505Sroberto /* 4365280849Scy * Add a queued extension field if present. This is 4366280849Scy * always a request message, so the reply ID is already 4367280849Scy * in the message. If an error occurs, the error bit is 4368280849Scy * lit in the response. 4369182007Sroberto */ 4370182007Sroberto if (peer->cmmd != NULL) { 4371280849Scy u_int32 temp32; 4372280849Scy 4373280849Scy temp32 = CRYPTO_RESP; 4374280849Scy peer->cmmd->opcode |= htonl(temp32); 4375280849Scy sendlen += crypto_xmit(peer, &xpkt, NULL, 4376280849Scy sendlen, peer->cmmd, 0); 4377182007Sroberto free(peer->cmmd); 4378182007Sroberto peer->cmmd = NULL; 4379182007Sroberto } 4380280849Scy 4381280849Scy /* 4382280849Scy * Add an extension field created above. All but the 4383280849Scy * autokey response message are request messages. 4384280849Scy */ 4385182007Sroberto if (exten != NULL) { 4386280849Scy if (exten->opcode != 0) 4387280849Scy sendlen += crypto_xmit(peer, &xpkt, 4388280849Scy NULL, sendlen, exten, 0); 4389182007Sroberto free(exten); 4390182007Sroberto } 4391182007Sroberto 4392182007Sroberto /* 4393280849Scy * Calculate the next session key. Since extension 4394280849Scy * fields are present, the cookie value is zero. 439582505Sroberto */ 4396280849Scy if (sendlen > (int)LEN_PKT_NOMAC) { 439782505Sroberto session_key(&peer->dstadr->sin, &peer->srcadr, 439882505Sroberto xkeyid, 0, 2); 4399182007Sroberto } 4400282408Scy } 4401280849Scy#endif /* AUTOKEY */ 4402182007Sroberto 4403182007Sroberto /* 4404280849Scy * Transmit a-priori timestamps 4405182007Sroberto */ 4406280849Scy get_systime(&xmt_tx); 4407280849Scy if (peer->flip == 0) { /* basic mode */ 4408280849Scy peer->aorg = xmt_tx; 4409280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4410280849Scy } else { /* interleaved modes */ 4411280849Scy if (peer->hmode == MODE_BROADCAST) { /* bcst */ 4412280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4413280849Scy if (peer->flip > 0) 4414280849Scy HTONL_FP(&peer->borg, &xpkt.org); 4415280849Scy else 4416280849Scy HTONL_FP(&peer->aorg, &xpkt.org); 4417280849Scy } else { /* symmetric */ 4418280849Scy if (peer->flip > 0) 4419280849Scy HTONL_FP(&peer->borg, &xpkt.xmt); 4420280849Scy else 4421280849Scy HTONL_FP(&peer->aorg, &xpkt.xmt); 4422280849Scy } 4423280849Scy } 442482505Sroberto xkeyid = peer->keyid; 442582505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 442682505Sroberto if (authlen == 0) { 4427280849Scy report_event(PEVNT_AUTH, peer, "no key"); 4428280849Scy peer->flash |= TEST5; /* auth error */ 4429280849Scy peer->badauth++; 443082505Sroberto return; 443182505Sroberto } 443282505Sroberto sendlen += authlen; 4433280849Scy#ifdef AUTOKEY 443482505Sroberto if (xkeyid > NTP_MAXKEY) 443582505Sroberto authtrust(xkeyid, 0); 4436280849Scy#endif /* AUTOKEY */ 443782505Sroberto if (sendlen > sizeof(xpkt)) { 4438293423Sdelphij msyslog(LOG_ERR, "peer_xmit: buffer overflow %zu", sendlen); 4439132454Sroberto exit (-1); 444082505Sroberto } 4441280849Scy peer->t21_bytes = sendlen; 4442316068Sdelphij sendpkt(&peer->srcadr, peer->dstadr, 4443316068Sdelphij sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl], 4444316068Sdelphij &xpkt, sendlen); 4445280849Scy peer->sent++; 4446280849Scy peer->throttle += (1 << peer->minpoll) - 2; 444782505Sroberto 444882505Sroberto /* 4449280849Scy * Capture a-posteriori timestamps 445082505Sroberto */ 4451280849Scy get_systime(&xmt_ty); 4452280849Scy if (peer->flip != 0) { /* interleaved modes */ 4453280849Scy if (peer->flip > 0) 4454280849Scy peer->aorg = xmt_ty; 4455280849Scy else 4456280849Scy peer->borg = xmt_ty; 4457280849Scy peer->flip = -peer->flip; 4458280849Scy } 4459280849Scy L_SUB(&xmt_ty, &xmt_tx); 4460280849Scy LFPTOD(&xmt_ty, peer->xleave); 4461280849Scy#ifdef AUTOKEY 4462293423Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n", 4463280849Scy current_time, latoa(peer->dstadr), 4464280849Scy ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen, 4465293423Sdelphij peer->keynumber)); 4466280849Scy#else /* !AUTOKEY follows */ 4467316068Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu\n", 4468280849Scy current_time, peer->dstadr ? 4469280849Scy ntoa(&peer->dstadr->sin) : "-", 4470293423Sdelphij ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen)); 4471280849Scy#endif /* !AUTOKEY */ 4472293423Sdelphij 4473293423Sdelphij return; 447454359Sroberto} 447554359Sroberto 447682505Sroberto 4477285169Scy#ifdef LEAP_SMEAR 4478285169Scy 4479285169Scystatic void 4480293423Sdelphijleap_smear_add_offs( 4481293423Sdelphij l_fp *t, 4482293423Sdelphij l_fp *t_recv 4483293423Sdelphij ) 4484293423Sdelphij{ 4485293423Sdelphij 4486285169Scy L_ADD(t, &leap_smear.offset); 4487293423Sdelphij 4488309007Sdelphij /* 4489309007Sdelphij ** XXX: Should the smear be added to the root dispersion? 4490309007Sdelphij */ 4491309007Sdelphij 4492293423Sdelphij return; 4493285169Scy} 4494285169Scy 4495338530Sdelphij#endif /* LEAP_SMEAR */ 4496285169Scy 4497285169Scy 449854359Sroberto/* 449982505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that 450082505Sroberto * neither the source or destination can be a broadcast address. 450154359Sroberto */ 450254359Srobertostatic void 450354359Srobertofast_xmit( 450454359Sroberto struct recvbuf *rbufp, /* receive packet pointer */ 4505358659Scy int xmode, /* receive mode */ /* XXX: HMS: really? */ 4506132454Sroberto keyid_t xkeyid, /* transmit key ID */ 4507280849Scy int flags /* restrict mask */ 450854359Sroberto ) 450954359Sroberto{ 4510280849Scy struct pkt xpkt; /* transmit packet structure */ 4511280849Scy struct pkt *rpkt; /* receive packet structure */ 4512280849Scy l_fp xmt_tx, xmt_ty; 4513293423Sdelphij size_t sendlen; 4514280849Scy#ifdef AUTOKEY 4515132454Sroberto u_int32 temp32; 4516132454Sroberto#endif 451754359Sroberto 451854359Sroberto /* 451982505Sroberto * Initialize transmit packet header fields from the receive 4520280849Scy * buffer provided. We leave the fields intact as received, but 4521280849Scy * set the peer poll at the maximum of the receive peer poll and 4522280849Scy * the system minimum poll (ntp_minpoll). This is for KoD rate 4523280849Scy * control and not strictly specification compliant, but doesn't 4524280849Scy * break anything. 4525182007Sroberto * 4526280849Scy * If the gazinta was from a multicast address, the gazoutta 4527280849Scy * must go out another way. 452854359Sroberto */ 452954359Sroberto rpkt = &rbufp->recv_pkt; 4530182007Sroberto if (rbufp->dstadr->flags & INT_MCASTOPEN) 453182505Sroberto rbufp->dstadr = findinterface(&rbufp->recv_srcadr); 453282505Sroberto 453382505Sroberto /* 4534280849Scy * If this is a kiss-o'-death (KoD) packet, show leap 4535182007Sroberto * unsynchronized, stratum zero, reference ID the four-character 4536358659Scy * kiss code and (???) system root delay. Note we don't reveal 4537358659Scy * the local time, so these packets can't be used for 4538280849Scy * synchronization. 4539182007Sroberto */ 4540280849Scy if (flags & RES_KOD) { 4541280849Scy sys_kodsent++; 4542132454Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 4543132454Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 4544280849Scy xpkt.stratum = STRATUM_PKT_UNSPEC; 4545280849Scy xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll); 4546280849Scy xpkt.precision = rpkt->precision; 4547182007Sroberto memcpy(&xpkt.refid, "RATE", 4); 4548280849Scy xpkt.rootdelay = rpkt->rootdelay; 4549280849Scy xpkt.rootdisp = rpkt->rootdisp; 4550280849Scy xpkt.reftime = rpkt->reftime; 4551280849Scy xpkt.org = rpkt->xmt; 4552280849Scy xpkt.rec = rpkt->xmt; 4553280849Scy xpkt.xmt = rpkt->xmt; 4554182007Sroberto 4555182007Sroberto /* 4556182007Sroberto * This is a normal packet. Use the system variables. 4557182007Sroberto */ 4558280849Scy } else { 4559358659Scy double this_rootdisp; 4560358659Scy l_fp this_ref_time; 4561358659Scy 4562285169Scy#ifdef LEAP_SMEAR 4563285169Scy /* 4564285169Scy * Make copies of the variables which can be affected by smearing. 4565285169Scy */ 4566285169Scy l_fp this_recv_time; 4567285169Scy#endif 4568285169Scy 4569285169Scy /* 4570358659Scy * If we are inside the leap smear interval we add 4571358659Scy * the current smear offset to: 4572358659Scy * - the packet receive time, 4573358659Scy * - the packet transmit time, 4574358659Scy * - and eventually to the reftime to make sure the 4575358659Scy * reftime isn't later than the transmit/receive times. 4576285169Scy */ 4577285169Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(xmt_leap, 457882505Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 4579285169Scy 458082505Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 4581280849Scy xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll); 4582280849Scy xpkt.precision = sys_precision; 458382505Sroberto xpkt.refid = sys_refid; 4584182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 4585285169Scy 4586358659Scy /* 4587358659Scy ** Server Response Fuzzing 4588358659Scy ** 4589358659Scy ** Which values do we want to use for reftime and rootdisp? 4590358659Scy */ 4591358659Scy 4592358659Scy if ( MODE_SERVER == xmode 4593358659Scy && RES_SRVRSPFUZ & flags) { 4594358659Scy if (current_time < p2_time) { 4595358659Scy this_ref_time = p2_reftime; 4596358659Scy this_rootdisp = p2_rootdisp; 4597358659Scy } else if (current_time < prev_time) { 4598358659Scy this_ref_time = prev_reftime; 4599358659Scy this_rootdisp = prev_rootdisp; 4600358659Scy } else { 4601358659Scy this_ref_time = sys_reftime; 4602358659Scy this_rootdisp = sys_rootdisp; 4603358659Scy } 4604358659Scy 4605358659Scy SRVRSP_FUZZ(this_ref_time); 4606358659Scy } else { 4607358659Scy this_ref_time = sys_reftime; 4608358659Scy this_rootdisp = sys_rootdisp; 4609358659Scy } 4610358659Scy 4611358659Scy /* 4612358659Scy ** ROOT DISPERSION 4613358659Scy */ 4614358659Scy 4615358659Scy xpkt.rootdisp = HTONS_FP(DTOUFP(this_rootdisp)); 4616358659Scy 4617358659Scy /* 4618358659Scy ** REFTIME 4619358659Scy */ 4620358659Scy 4621285169Scy#ifdef LEAP_SMEAR 4622285169Scy if (leap_smear.in_progress) { 4623358659Scy /* adjust the reftime by the same amount as the 4624358659Scy * leap smear, as we don't want to risk the 4625358659Scy * reftime being later than the transmit time. 4626358659Scy */ 4627285169Scy leap_smear_add_offs(&this_ref_time, NULL); 4628358659Scy } 4629358659Scy#endif 4630358659Scy 4631358659Scy HTONL_FP(&this_ref_time, &xpkt.reftime); 4632358659Scy 4633358659Scy /* 4634358659Scy ** REFID 4635358659Scy */ 4636358659Scy 4637358659Scy#ifdef LEAP_SMEAR 4638358659Scy if (leap_smear.in_progress) { 4639285169Scy xpkt.refid = convertLFPToRefID(leap_smear.offset); 4640285169Scy DPRINTF(2, ("fast_xmit: leap_smear.in_progress: refid %8x, smear %s\n", 4641285169Scy ntohl(xpkt.refid), 4642285169Scy lfptoa(&leap_smear.offset, 8) 4643285169Scy )); 4644285169Scy } 4645285169Scy#endif 4646285169Scy 4647358659Scy /* 4648358659Scy ** ORIGIN 4649358659Scy */ 4650358659Scy 4651280849Scy xpkt.org = rpkt->xmt; 4652285169Scy 4653358659Scy /* 4654358659Scy ** RECEIVE 4655358659Scy */ 4656285169Scy#ifdef LEAP_SMEAR 4657285169Scy this_recv_time = rbufp->recv_time; 4658285169Scy if (leap_smear.in_progress) 4659285169Scy leap_smear_add_offs(&this_recv_time, NULL); 4660285169Scy HTONL_FP(&this_recv_time, &xpkt.rec); 4661285169Scy#else 4662280849Scy HTONL_FP(&rbufp->recv_time, &xpkt.rec); 4663285169Scy#endif 4664285169Scy 4665358659Scy /* 4666358659Scy ** TRANSMIT 4667358659Scy */ 4668358659Scy 4669280849Scy get_systime(&xmt_tx); 4670285169Scy#ifdef LEAP_SMEAR 4671285169Scy if (leap_smear.in_progress) 4672285169Scy leap_smear_add_offs(&xmt_tx, &this_recv_time); 4673285169Scy#endif 4674280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4675280849Scy } 4676182007Sroberto 4677280849Scy#ifdef HAVE_NTP_SIGND 4678280849Scy if (flags & RES_MSSNTP) { 4679280849Scy send_via_ntp_signd(rbufp, xmode, xkeyid, flags, &xpkt); 4680280849Scy return; 468182505Sroberto } 4682280849Scy#endif /* HAVE_NTP_SIGND */ 468382505Sroberto 468482505Sroberto /* 468582505Sroberto * If the received packet contains a MAC, the transmitted packet 468682505Sroberto * is authenticated and contains a MAC. If not, the transmitted 468782505Sroberto * packet is not authenticated. 468882505Sroberto */ 468954359Sroberto sendlen = LEN_PKT_NOMAC; 469082505Sroberto if (rbufp->recv_length == sendlen) { 469182505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, 469256749Sroberto sendlen); 4693293423Sdelphij DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d len %lu\n", 4694132454Sroberto current_time, stoa(&rbufp->dstadr->sin), 4695293423Sdelphij stoa(&rbufp->recv_srcadr), xmode, 4696293423Sdelphij (u_long)sendlen)); 469782505Sroberto return; 469882505Sroberto } 469954359Sroberto 470082505Sroberto /* 470182505Sroberto * The received packet contains a MAC, so the transmitted packet 4702182007Sroberto * must be authenticated. For symmetric key cryptography, use 4703182007Sroberto * the predefined and trusted symmetric keys to generate the 4704182007Sroberto * cryptosum. For autokey cryptography, use the server private 4705182007Sroberto * value to generate the cookie, which is unique for every 4706182007Sroberto * source-destination-key ID combination. 470782505Sroberto */ 4708280849Scy#ifdef AUTOKEY 470982505Sroberto if (xkeyid > NTP_MAXKEY) { 471082505Sroberto keyid_t cookie; 471182505Sroberto 471254359Sroberto /* 471382505Sroberto * The only way to get here is a reply to a legitimate 471482505Sroberto * client request message, so the mode must be 471582505Sroberto * MODE_SERVER. If an extension field is present, there 471682505Sroberto * can be only one and that must be a command. Do what 471782505Sroberto * needs, but with private value of zero so the poor 471882505Sroberto * jerk can decode it. If no extension field is present, 471982505Sroberto * use the cookie to generate the session key. 472054359Sroberto */ 472182505Sroberto cookie = session_key(&rbufp->recv_srcadr, 472282505Sroberto &rbufp->dstadr->sin, 0, sys_private, 0); 4723293423Sdelphij if ((size_t)rbufp->recv_length > sendlen + MAX_MAC_LEN) { 472482505Sroberto session_key(&rbufp->dstadr->sin, 472582505Sroberto &rbufp->recv_srcadr, xkeyid, 0, 2); 4726132454Sroberto temp32 = CRYPTO_RESP; 4727132454Sroberto rpkt->exten[0] |= htonl(temp32); 4728280849Scy sendlen += crypto_xmit(NULL, &xpkt, rbufp, 4729280849Scy sendlen, (struct exten *)rpkt->exten, 4730280849Scy cookie); 473182505Sroberto } else { 473282505Sroberto session_key(&rbufp->dstadr->sin, 473382505Sroberto &rbufp->recv_srcadr, xkeyid, cookie, 2); 473482505Sroberto } 473582505Sroberto } 4736280849Scy#endif /* AUTOKEY */ 4737280849Scy get_systime(&xmt_tx); 4738280849Scy sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 4739280849Scy#ifdef AUTOKEY 474082505Sroberto if (xkeyid > NTP_MAXKEY) 474182505Sroberto authtrust(xkeyid, 0); 4742280849Scy#endif /* AUTOKEY */ 474382505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); 4744280849Scy get_systime(&xmt_ty); 4745280849Scy L_SUB(&xmt_ty, &xmt_tx); 4746280849Scy sys_authdelay = xmt_ty; 4747293423Sdelphij DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d keyid %08x len %lu\n", 474882505Sroberto current_time, ntoa(&rbufp->dstadr->sin), 4749293423Sdelphij ntoa(&rbufp->recv_srcadr), xmode, xkeyid, 4750293423Sdelphij (u_long)sendlen)); 475154359Sroberto} 475254359Sroberto 475382505Sroberto 475454359Sroberto/* 4755280849Scy * pool_xmit - resolve hostname or send unicast solicitation for pool. 4756280849Scy */ 4757280849Scystatic void 4758280849Scypool_xmit( 4759280849Scy struct peer *pool /* pool solicitor association */ 4760280849Scy ) 4761280849Scy{ 4762280849Scy#ifdef WORKER 4763280849Scy struct pkt xpkt; /* transmit packet structure */ 4764280849Scy struct addrinfo hints; 4765280849Scy int rc; 4766280849Scy struct interface * lcladr; 4767280849Scy sockaddr_u * rmtadr; 4768330106Sdelphij r4addr r4a; 4769358659Scy u_short restrict_mask; 4770280849Scy struct peer * p; 4771280849Scy l_fp xmt_tx; 4772280849Scy 4773358659Scy DEBUG_REQUIRE(pool); 4774280849Scy if (NULL == pool->ai) { 4775280849Scy if (pool->addrs != NULL) { 4776280849Scy /* free() is used with copy_addrinfo_list() */ 4777280849Scy free(pool->addrs); 4778280849Scy pool->addrs = NULL; 4779280849Scy } 4780280849Scy ZERO(hints); 4781280849Scy hints.ai_family = AF(&pool->srcadr); 4782280849Scy hints.ai_socktype = SOCK_DGRAM; 4783280849Scy hints.ai_protocol = IPPROTO_UDP; 4784280849Scy /* ignore getaddrinfo_sometime() errors, we will retry */ 4785280849Scy rc = getaddrinfo_sometime( 4786280849Scy pool->hostname, 4787280849Scy "ntp", 4788280849Scy &hints, 4789280849Scy 0, /* no retry */ 4790280849Scy &pool_name_resolved, 4791280849Scy (void *)(intptr_t)pool->associd); 4792280849Scy if (!rc) 4793280849Scy DPRINTF(1, ("pool DNS lookup %s started\n", 4794280849Scy pool->hostname)); 4795280849Scy else 4796280849Scy msyslog(LOG_ERR, 4797289764Sglebius "unable to start pool DNS %s: %m", 4798280849Scy pool->hostname); 4799280849Scy return; 4800280849Scy } 4801280849Scy 4802280849Scy do { 4803280849Scy /* copy_addrinfo_list ai_addr points to a sockaddr_u */ 4804280849Scy rmtadr = (sockaddr_u *)(void *)pool->ai->ai_addr; 4805280849Scy pool->ai = pool->ai->ai_next; 4806330106Sdelphij p = findexistingpeer(rmtadr, NULL, NULL, MODE_CLIENT, 0, NULL); 4807280849Scy } while (p != NULL && pool->ai != NULL); 4808280849Scy if (p != NULL) 4809280849Scy return; /* out of addresses, re-query DNS next poll */ 4810330106Sdelphij restrictions(rmtadr, &r4a); 4811330106Sdelphij restrict_mask = r4a.rflags; 4812280849Scy if (RES_FLAGS & restrict_mask) 4813282408Scy restrict_source(rmtadr, 0, 4814280849Scy current_time + POOL_SOLICIT_WINDOW + 1); 4815280849Scy lcladr = findinterface(rmtadr); 4816280849Scy memset(&xpkt, 0, sizeof(xpkt)); 4817280849Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, pool->version, 4818280849Scy MODE_CLIENT); 4819280849Scy xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 4820280849Scy xpkt.ppoll = pool->hpoll; 4821280849Scy xpkt.precision = sys_precision; 4822280849Scy xpkt.refid = sys_refid; 4823280849Scy xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 4824280849Scy xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); 4825358659Scy /* Bug 3596: What are the pros/cons of using sys_reftime here? */ 4826280849Scy HTONL_FP(&sys_reftime, &xpkt.reftime); 4827358659Scy 4828358659Scy /* HMS: the following is better done after the ntp_random() calls */ 4829280849Scy get_systime(&xmt_tx); 4830280849Scy pool->aorg = xmt_tx; 4831358659Scy 4832358659Scy if (FLAG_LOOPNONCE & pool->flags) { 4833358659Scy l_fp nonce; 4834358659Scy 4835358659Scy do { 4836358659Scy nonce.l_ui = ntp_random(); 4837358659Scy } while (0 == nonce.l_ui); 4838358659Scy do { 4839358659Scy nonce.l_uf = ntp_random(); 4840358659Scy } while (0 == nonce.l_uf); 4841358659Scy pool->nonce = nonce; 4842358659Scy HTONL_FP(&nonce, &xpkt.xmt); 4843358659Scy } else { 4844358659Scy L_CLR(&pool->nonce); 4845358659Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4846358659Scy } 4847316068Sdelphij sendpkt(rmtadr, lcladr, 4848316068Sdelphij sys_ttl[(pool->ttl >= sys_ttlmax) ? sys_ttlmax : pool->ttl], 4849316068Sdelphij &xpkt, LEN_PKT_NOMAC); 4850280849Scy pool->sent++; 4851280849Scy pool->throttle += (1 << pool->minpoll) - 2; 4852293423Sdelphij DPRINTF(1, ("pool_xmit: at %ld %s->%s pool\n", 4853293423Sdelphij current_time, latoa(lcladr), stoa(rmtadr))); 4854280849Scy msyslog(LOG_INFO, "Soliciting pool server %s", stoa(rmtadr)); 4855280849Scy#endif /* WORKER */ 4856280849Scy} 4857280849Scy 4858280849Scy 4859280849Scy#ifdef AUTOKEY 4860280849Scy /* 4861280849Scy * group_test - test if this is the same group 4862280849Scy * 4863280849Scy * host assoc return action 4864280849Scy * none none 0 mobilize * 4865280849Scy * none group 0 mobilize * 4866280849Scy * group none 0 mobilize * 4867280849Scy * group group 1 mobilize 4868280849Scy * group different 1 ignore 4869280849Scy * * ignore if notrust 4870280849Scy */ 4871293423Sdelphijint 4872293423Sdelphijgroup_test( 4873280849Scy char *grp, 4874280849Scy char *ident 4875280849Scy ) 4876280849Scy{ 4877280849Scy if (grp == NULL) 4878280849Scy return (0); 4879280849Scy 4880280849Scy if (strcmp(grp, sys_groupname) == 0) 4881280849Scy return (0); 4882280849Scy 4883280849Scy if (ident == NULL) 4884280849Scy return (1); 4885280849Scy 4886280849Scy if (strcmp(grp, ident) == 0) 4887280849Scy return (0); 4888280849Scy 4889280849Scy return (1); 4890280849Scy} 4891280849Scy#endif /* AUTOKEY */ 4892280849Scy 4893298695Sdelphij 4894280849Scy#ifdef WORKER 4895280849Scyvoid 4896280849Scypool_name_resolved( 4897280849Scy int rescode, 4898280849Scy int gai_errno, 4899280849Scy void * context, 4900280849Scy const char * name, 4901280849Scy const char * service, 4902280849Scy const struct addrinfo * hints, 4903280849Scy const struct addrinfo * res 4904280849Scy ) 4905280849Scy{ 4906280849Scy struct peer * pool; /* pool solicitor association */ 4907280849Scy associd_t assoc; 4908280849Scy 4909280849Scy if (rescode) { 4910280849Scy msyslog(LOG_ERR, 4911280849Scy "error resolving pool %s: %s (%d)", 4912280849Scy name, gai_strerror(rescode), rescode); 4913280849Scy return; 4914280849Scy } 4915280849Scy 4916280849Scy assoc = (associd_t)(intptr_t)context; 4917280849Scy pool = findpeerbyassoc(assoc); 4918280849Scy if (NULL == pool) { 4919280849Scy msyslog(LOG_ERR, 4920280849Scy "Could not find assoc %u for pool DNS %s", 4921280849Scy assoc, name); 4922280849Scy return; 4923280849Scy } 4924280849Scy DPRINTF(1, ("pool DNS %s completed\n", name)); 4925280849Scy pool->addrs = copy_addrinfo_list(res); 4926280849Scy pool->ai = pool->addrs; 4927280849Scy pool_xmit(pool); 4928280849Scy 4929280849Scy} 4930280849Scy#endif /* WORKER */ 4931280849Scy 4932280849Scy 4933280849Scy#ifdef AUTOKEY 4934280849Scy/* 493582505Sroberto * key_expire - purge the key list 493654359Sroberto */ 493782505Srobertovoid 493882505Srobertokey_expire( 493982505Sroberto struct peer *peer /* peer structure pointer */ 494054359Sroberto ) 494154359Sroberto{ 494254359Sroberto int i; 494354359Sroberto 4944132454Sroberto if (peer->keylist != NULL) { 494582505Sroberto for (i = 0; i <= peer->keynumber; i++) 494682505Sroberto authtrust(peer->keylist[i], 0); 494782505Sroberto free(peer->keylist); 494882505Sroberto peer->keylist = NULL; 494954359Sroberto } 4950132454Sroberto value_free(&peer->sndval); 4951132454Sroberto peer->keynumber = 0; 4952280849Scy peer->flags &= ~FLAG_ASSOC; 4953293423Sdelphij DPRINTF(1, ("key_expire: at %lu associd %d\n", current_time, 4954293423Sdelphij peer->associd)); 495554359Sroberto} 4956280849Scy#endif /* AUTOKEY */ 495754359Sroberto 4958132454Sroberto 495954359Sroberto/* 4960280849Scy * local_refid(peer) - check peer refid to avoid selecting peers 4961280849Scy * currently synced to this ntpd. 4962280849Scy */ 4963280849Scystatic int 4964280849Scylocal_refid( 4965280849Scy struct peer * p 4966280849Scy ) 4967280849Scy{ 4968280849Scy endpt * unicast_ep; 4969280849Scy 4970280849Scy if (p->dstadr != NULL && !(INT_MCASTIF & p->dstadr->flags)) 4971280849Scy unicast_ep = p->dstadr; 4972280849Scy else 4973280849Scy unicast_ep = findinterface(&p->srcadr); 4974280849Scy 4975280849Scy if (unicast_ep != NULL && p->refid == unicast_ep->addr_refid) 4976280849Scy return TRUE; 4977280849Scy else 4978280849Scy return FALSE; 4979280849Scy} 4980280849Scy 4981280849Scy 4982280849Scy/* 4983132454Sroberto * Determine if the peer is unfit for synchronization 4984132454Sroberto * 4985132454Sroberto * A peer is unfit for synchronization if 4986182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling 4987280849Scy * > TEST11 root distance exceeded for remote peer 4988182007Sroberto * > TEST12 a direct or indirect synchronization loop would form 4989182007Sroberto * > TEST13 unreachable or noselect 4990132454Sroberto */ 4991182007Srobertoint /* FALSE if fit, TRUE if unfit */ 4992132454Srobertopeer_unfit( 4993132454Sroberto struct peer *peer /* peer structure pointer */ 4994132454Sroberto ) 4995132454Sroberto{ 4996182007Sroberto int rval = 0; 4997182007Sroberto 4998182007Sroberto /* 4999182007Sroberto * A stratum error occurs if (1) the server has never been 5000182007Sroberto * synchronized, (2) the server stratum is below the floor or 5001280849Scy * greater than or equal to the ceiling. 5002182007Sroberto */ 5003289764Sglebius if ( peer->leap == LEAP_NOTINSYNC 5004289764Sglebius || peer->stratum < sys_floor 5005309007Sdelphij || peer->stratum >= sys_ceiling) { 5006280849Scy rval |= TEST10; /* bad synch or stratum */ 5007309007Sdelphij } 5008182007Sroberto 5009182007Sroberto /* 5010280849Scy * A distance error for a remote peer occurs if the root 5011280849Scy * distance is greater than or equal to the distance threshold 5012280849Scy * plus the increment due to one host poll interval. 5013182007Sroberto */ 5014289764Sglebius if ( !(peer->flags & FLAG_REFCLOCK) 5015289764Sglebius && root_distance(peer) >= sys_maxdist 5016309007Sdelphij + clock_phi * ULOGTOD(peer->hpoll)) { 5017182007Sroberto rval |= TEST11; /* distance exceeded */ 5018309007Sdelphij } 5019182007Sroberto 5020182007Sroberto /* 5021182007Sroberto * A loop error occurs if the remote peer is synchronized to the 5022280849Scy * local peer or if the remote peer is synchronized to the same 5023280849Scy * server as the local peer but only if the remote peer is 5024280849Scy * neither a reference clock nor an orphan. 5025182007Sroberto */ 5026309007Sdelphij if (peer->stratum > 1 && local_refid(peer)) { 5027280849Scy rval |= TEST12; /* synchronization loop */ 5028309007Sdelphij } 5029182007Sroberto 5030182007Sroberto /* 5031182007Sroberto * An unreachable error occurs if the server is unreachable or 5032182007Sroberto * the noselect bit is set. 5033182007Sroberto */ 5034309007Sdelphij if (!peer->reach || (peer->flags & FLAG_NOSELECT)) { 5035182007Sroberto rval |= TEST13; /* unreachable */ 5036309007Sdelphij } 5037182007Sroberto 5038182007Sroberto peer->flash &= ~PEER_TEST_MASK; 5039182007Sroberto peer->flash |= rval; 5040182007Sroberto return (rval); 5041132454Sroberto} 5042132454Sroberto 5043132454Sroberto 5044132454Sroberto/* 504554359Sroberto * Find the precision of this particular machine 504654359Sroberto */ 5047280849Scy#define MINSTEP 20e-9 /* minimum clock increment (s) */ 5048280849Scy#define MAXSTEP 1 /* maximum clock increment (s) */ 5049280849Scy#define MINCHANGES 12 /* minimum number of step samples */ 5050280849Scy#define MAXLOOPS ((int)(1. / MINSTEP)) /* avoid infinite loop */ 505154359Sroberto 505254359Sroberto/* 5053280849Scy * This routine measures the system precision defined as the minimum of 5054280849Scy * a sequence of differences between successive readings of the system 5055280849Scy * clock. However, if a difference is less than MINSTEP, the clock has 5056280849Scy * been read more than once during a clock tick and the difference is 5057280849Scy * ignored. We set MINSTEP greater than zero in case something happens 5058280849Scy * like a cache miss, and to tolerate underlying system clocks which 5059280849Scy * ensure each reading is strictly greater than prior readings while 5060280849Scy * using an underlying stepping (not interpolated) clock. 5061132454Sroberto * 5062280849Scy * sys_tick and sys_precision represent the time to read the clock for 5063280849Scy * systems with high-precision clocks, and the tick interval or step 5064280849Scy * size for lower-precision stepping clocks. 5065280849Scy * 5066280849Scy * This routine also measures the time to read the clock on stepping 5067280849Scy * system clocks by counting the number of readings between changes of 5068280849Scy * the underlying clock. With either type of clock, the minimum time 5069280849Scy * to read the clock is saved as sys_fuzz, and used to ensure the 5070280849Scy * get_systime() readings always increase and are fuzzed below sys_fuzz. 507154359Sroberto */ 5072280849Scyvoid 5073280849Scymeasure_precision(void) 507454359Sroberto{ 5075280849Scy /* 5076280849Scy * With sys_fuzz set to zero, get_systime() fuzzing of low bits 5077280849Scy * is effectively disabled. trunc_os_clock is FALSE to disable 5078280849Scy * get_ostime() simulation of a low-precision system clock. 5079280849Scy */ 5080280849Scy set_sys_fuzz(0.); 5081280849Scy trunc_os_clock = FALSE; 5082280849Scy measured_tick = measure_tick_fuzz(); 5083280849Scy set_sys_tick_precision(measured_tick); 5084280849Scy msyslog(LOG_INFO, "proto: precision = %.3f usec (%d)", 5085280849Scy sys_tick * 1e6, sys_precision); 5086280849Scy if (sys_fuzz < sys_tick) { 5087280849Scy msyslog(LOG_NOTICE, "proto: fuzz beneath %.3f usec", 5088280849Scy sys_fuzz * 1e6); 5089280849Scy } 5090280849Scy} 5091280849Scy 5092280849Scy 5093280849Scy/* 5094280849Scy * measure_tick_fuzz() 5095280849Scy * 5096280849Scy * measures the minimum time to read the clock (stored in sys_fuzz) 5097280849Scy * and returns the tick, the larger of the minimum increment observed 5098280849Scy * between successive clock readings and the time to read the clock. 5099280849Scy */ 5100280849Scydouble 5101280849Scymeasure_tick_fuzz(void) 5102280849Scy{ 5103280849Scy l_fp minstep; /* MINSTEP as l_fp */ 5104132454Sroberto l_fp val; /* current seconds fraction */ 5105132454Sroberto l_fp last; /* last seconds fraction */ 5106280849Scy l_fp ldiff; /* val - last */ 5107132454Sroberto double tick; /* computed tick value */ 5108280849Scy double diff; 5109280849Scy long repeats; 5110280849Scy long max_repeats; 5111280849Scy int changes; 5112132454Sroberto int i; /* log2 precision */ 511354359Sroberto 5114280849Scy tick = MAXSTEP; 5115280849Scy max_repeats = 0; 5116280849Scy repeats = 0; 5117280849Scy changes = 0; 5118280849Scy DTOLFP(MINSTEP, &minstep); 5119132454Sroberto get_systime(&last); 5120280849Scy for (i = 0; i < MAXLOOPS && changes < MINCHANGES; i++) { 5121132454Sroberto get_systime(&val); 5122280849Scy ldiff = val; 5123280849Scy L_SUB(&ldiff, &last); 5124132454Sroberto last = val; 5125280849Scy if (L_ISGT(&ldiff, &minstep)) { 5126280849Scy max_repeats = max(repeats, max_repeats); 5127280849Scy repeats = 0; 5128280849Scy changes++; 5129280849Scy LFPTOD(&ldiff, diff); 5130280849Scy tick = min(diff, tick); 5131280849Scy } else { 5132280849Scy repeats++; 5133280849Scy } 513454359Sroberto } 5135280849Scy if (changes < MINCHANGES) { 5136280849Scy msyslog(LOG_ERR, "Fatal error: precision could not be measured (MINSTEP too large?)"); 5137280849Scy exit(1); 5138280849Scy } 5139132454Sroberto 5140280849Scy if (0 == max_repeats) { 5141280849Scy set_sys_fuzz(tick); 5142280849Scy } else { 5143280849Scy set_sys_fuzz(tick / max_repeats); 5144280849Scy } 5145280849Scy 5146280849Scy return tick; 5147280849Scy} 5148280849Scy 5149280849Scy 5150280849Scyvoid 5151280849Scyset_sys_tick_precision( 5152280849Scy double tick 5153280849Scy ) 5154280849Scy{ 5155280849Scy int i; 5156280849Scy 5157280849Scy if (tick > 1.) { 5158280849Scy msyslog(LOG_ERR, 5159280849Scy "unsupported tick %.3f > 1s ignored", tick); 5160280849Scy return; 5161280849Scy } 5162280849Scy if (tick < measured_tick) { 5163280849Scy msyslog(LOG_ERR, 5164280849Scy "proto: tick %.3f less than measured tick %.3f, ignored", 5165280849Scy tick, measured_tick); 5166280849Scy return; 5167280849Scy } else if (tick > measured_tick) { 5168280849Scy trunc_os_clock = TRUE; 5169280849Scy msyslog(LOG_NOTICE, 5170280849Scy "proto: truncating system clock to multiples of %.9f", 5171280849Scy tick); 5172280849Scy } 5173280849Scy sys_tick = tick; 5174280849Scy 5175132454Sroberto /* 5176132454Sroberto * Find the nearest power of two. 5177132454Sroberto */ 5178280849Scy for (i = 0; tick <= 1; i--) 5179132454Sroberto tick *= 2; 5180280849Scy if (tick - 1 > 1 - tick / 2) 5181280849Scy i++; 518254359Sroberto 5183280849Scy sys_precision = (s_char)i; 5184132454Sroberto} 5185132454Sroberto 5186132454Sroberto 5187132454Sroberto/* 518854359Sroberto * init_proto - initialize the protocol module's data 518954359Sroberto */ 519054359Srobertovoid 519154359Srobertoinit_proto(void) 519254359Sroberto{ 5193132454Sroberto l_fp dummy; 5194132454Sroberto int i; 519554359Sroberto 519654359Sroberto /* 519754359Sroberto * Fill in the sys_* stuff. Default is don't listen to 5198280849Scy * broadcasting, require authentication. 519954359Sroberto */ 5200285169Scy set_sys_leap(LEAP_NOTINSYNC); 520154359Sroberto sys_stratum = STRATUM_UNSPEC; 5202132454Sroberto memcpy(&sys_refid, "INIT", 4); 5203280849Scy sys_peer = NULL; 520454359Sroberto sys_rootdelay = 0; 5205280849Scy sys_rootdisp = 0; 520654359Sroberto L_CLR(&sys_reftime); 5207280849Scy sys_jitter = 0; 5208280849Scy measure_precision(); 5209280849Scy get_systime(&dummy); 521082505Sroberto sys_survivors = 0; 5211132454Sroberto sys_manycastserver = 0; 521254359Sroberto sys_bclient = 0; 5213298695Sdelphij sys_bdelay = BDELAY_DEFAULT; /*[Bug 3031] delay cutoff */ 521454359Sroberto sys_authenticate = 1; 5215280849Scy sys_stattime = current_time; 5216280849Scy orphwait = current_time + sys_orphwait; 5217132454Sroberto proto_clr_stats(); 5218316068Sdelphij for (i = 0; i < MAX_TTL; ++i) 5219132454Sroberto sys_ttl[i] = (u_char)((i * 256) / MAX_TTL); 5220316068Sdelphij sys_ttlmax = (MAX_TTL - 1); 5221280849Scy hardpps_enable = 0; 522254359Sroberto stats_control = 1; 522354359Sroberto} 522454359Sroberto 522554359Sroberto 522654359Sroberto/* 522754359Sroberto * proto_config - configure the protocol module 522854359Sroberto */ 522954359Srobertovoid 523054359Srobertoproto_config( 5231132454Sroberto int item, 5232132454Sroberto u_long value, 5233132454Sroberto double dvalue, 5234280849Scy sockaddr_u *svalue 523554359Sroberto ) 523654359Sroberto{ 523754359Sroberto /* 523854359Sroberto * Figure out what he wants to change, then do it 523954359Sroberto */ 5240280849Scy DPRINTF(2, ("proto_config: code %d value %lu dvalue %lf\n", 5241280849Scy item, value, dvalue)); 5242280849Scy 524354359Sroberto switch (item) { 5244132454Sroberto 5245132454Sroberto /* 5246280849Scy * enable and disable commands - arguments are Boolean. 5247132454Sroberto */ 5248280849Scy case PROTO_AUTHENTICATE: /* authentication (auth) */ 5249280849Scy sys_authenticate = value; 525054359Sroberto break; 525154359Sroberto 5252280849Scy case PROTO_BROADCLIENT: /* broadcast client (bclient) */ 5253280849Scy sys_bclient = (int)value; 5254280849Scy if (sys_bclient == 0) 5255280849Scy io_unsetbclient(); 5256280849Scy else 5257280849Scy io_setbclient(); 525854359Sroberto break; 525954359Sroberto 5260280849Scy#ifdef REFCLOCK 5261280849Scy case PROTO_CAL: /* refclock calibrate (calibrate) */ 5262280849Scy cal_enable = value; 5263280849Scy break; 5264280849Scy#endif /* REFCLOCK */ 5265280849Scy 5266280849Scy case PROTO_KERNEL: /* kernel discipline (kernel) */ 5267280849Scy select_loop(value); 5268280849Scy break; 5269280849Scy 5270280849Scy case PROTO_MONITOR: /* monitoring (monitor) */ 527154359Sroberto if (value) 527254359Sroberto mon_start(MON_ON); 5273285169Scy else { 527454359Sroberto mon_stop(MON_ON); 5275285169Scy if (mon_enabled) 5276285169Scy msyslog(LOG_WARNING, 5277285169Scy "restrict: 'monitor' cannot be disabled while 'limited' is enabled"); 5278285169Scy } 527954359Sroberto break; 528054359Sroberto 5281280849Scy case PROTO_NTP: /* NTP discipline (ntp) */ 5282280849Scy ntp_enable = value; 528354359Sroberto break; 528454359Sroberto 5285280849Scy case PROTO_MODE7: /* mode7 management (ntpdc) */ 5286280849Scy ntp_mode7 = value; 528754359Sroberto break; 528854359Sroberto 5289280849Scy case PROTO_PPS: /* PPS discipline (pps) */ 5290280849Scy hardpps_enable = value; 5291182007Sroberto break; 5292182007Sroberto 5293280849Scy case PROTO_FILEGEN: /* statistics (stats) */ 5294280849Scy stats_control = value; 529554359Sroberto break; 529654359Sroberto 5297132454Sroberto /* 5298280849Scy * tos command - arguments are double, sometimes cast to int 5299132454Sroberto */ 5300309007Sdelphij 5301309007Sdelphij case PROTO_BCPOLLBSTEP: /* Broadcast Poll Backstep gate (bcpollbstep) */ 5302309007Sdelphij sys_bcpollbstep = (u_char)dvalue; 5303309007Sdelphij break; 5304309007Sdelphij 5305280849Scy case PROTO_BEACON: /* manycast beacon (beacon) */ 5306280849Scy sys_beacon = (int)dvalue; 530754359Sroberto break; 530854359Sroberto 5309280849Scy case PROTO_BROADDELAY: /* default broadcast delay (bdelay) */ 5310298695Sdelphij sys_bdelay = (dvalue ? dvalue : BDELAY_DEFAULT); 531154359Sroberto break; 531254359Sroberto 5313280849Scy case PROTO_CEILING: /* stratum ceiling (ceiling) */ 5314280849Scy sys_ceiling = (int)dvalue; 5315132454Sroberto break; 5316132454Sroberto 5317280849Scy case PROTO_COHORT: /* cohort switch (cohort) */ 5318280849Scy sys_cohort = (int)dvalue; 531954359Sroberto break; 532054359Sroberto 5321280849Scy case PROTO_FLOOR: /* stratum floor (floor) */ 5322280849Scy sys_floor = (int)dvalue; 532382505Sroberto break; 532482505Sroberto 5325280849Scy case PROTO_MAXCLOCK: /* maximum candidates (maxclock) */ 5326182007Sroberto sys_maxclock = (int)dvalue; 5327132454Sroberto break; 5328132454Sroberto 5329280849Scy case PROTO_MAXDIST: /* select threshold (maxdist) */ 5330280849Scy sys_maxdist = dvalue; 5331132454Sroberto break; 5332132454Sroberto 5333280849Scy case PROTO_CALLDELAY: /* modem call delay (mdelay) */ 5334280849Scy break; /* NOT USED */ 5335132454Sroberto 5336280849Scy case PROTO_MINCLOCK: /* minimum candidates (minclock) */ 5337280849Scy sys_minclock = (int)dvalue; 5338132454Sroberto break; 5339132454Sroberto 5340280849Scy case PROTO_MINDISP: /* minimum distance (mindist) */ 5341280849Scy sys_mindisp = dvalue; 5342182007Sroberto break; 5343182007Sroberto 5344280849Scy case PROTO_MINSANE: /* minimum survivors (minsane) */ 5345280849Scy sys_minsane = (int)dvalue; 5346132454Sroberto break; 5347182007Sroberto 5348280849Scy case PROTO_ORPHAN: /* orphan stratum (orphan) */ 5349280849Scy sys_orphan = (int)dvalue; 5350182007Sroberto break; 5351182007Sroberto 5352280849Scy case PROTO_ORPHWAIT: /* orphan wait (orphwait) */ 5353280849Scy orphwait -= sys_orphwait; 5354362716Scy sys_orphwait = (dvalue >= 1) ? (int)dvalue : NTP_ORPHWAIT; 5355280849Scy orphwait += sys_orphwait; 5356182007Sroberto break; 5357182007Sroberto 5358182007Sroberto /* 5359280849Scy * Miscellaneous commands 5360182007Sroberto */ 5361280849Scy case PROTO_MULTICAST_ADD: /* add group address */ 5362280849Scy if (svalue != NULL) 5363280849Scy io_multicast_add(svalue); 5364280849Scy sys_bclient = 1; 5365182007Sroberto break; 5366182007Sroberto 5367280849Scy case PROTO_MULTICAST_DEL: /* delete group address */ 5368280849Scy if (svalue != NULL) 5369280849Scy io_multicast_del(svalue); 5370132454Sroberto break; 5371132454Sroberto 5372294554Sdelphij /* 5373301247Sdelphij * Peer_clear Early policy choices 5374301247Sdelphij */ 5375301247Sdelphij 5376301247Sdelphij case PROTO_PCEDIGEST: /* Digest */ 5377301247Sdelphij peer_clear_digest_early = value; 5378301247Sdelphij break; 5379301247Sdelphij 5380301247Sdelphij /* 5381294554Sdelphij * Unpeer Early policy choices 5382294554Sdelphij */ 5383294554Sdelphij 5384294554Sdelphij case PROTO_UECRYPTO: /* Crypto */ 5385294554Sdelphij unpeer_crypto_early = value; 5386294554Sdelphij break; 5387294554Sdelphij 5388294554Sdelphij case PROTO_UECRYPTONAK: /* Crypto_NAK */ 5389294554Sdelphij unpeer_crypto_nak_early = value; 5390294554Sdelphij break; 5391294554Sdelphij 5392294554Sdelphij case PROTO_UEDIGEST: /* Digest */ 5393294554Sdelphij unpeer_digest_early = value; 5394294554Sdelphij break; 5395294554Sdelphij 539656749Sroberto default: 5397280849Scy msyslog(LOG_NOTICE, 5398280849Scy "proto: unsupported option %d", item); 539954359Sroberto } 540054359Sroberto} 540154359Sroberto 540254359Sroberto 540354359Sroberto/* 540454359Sroberto * proto_clr_stats - clear protocol stat counters 540554359Sroberto */ 540654359Srobertovoid 540754359Srobertoproto_clr_stats(void) 540854359Sroberto{ 5409132454Sroberto sys_stattime = current_time; 5410132454Sroberto sys_received = 0; 5411132454Sroberto sys_processed = 0; 5412280849Scy sys_newversion = 0; 5413280849Scy sys_oldversion = 0; 5414280849Scy sys_declined = 0; 5415132454Sroberto sys_restricted = 0; 541654359Sroberto sys_badlength = 0; 541754359Sroberto sys_badauth = 0; 541854359Sroberto sys_limitrejected = 0; 5419280849Scy sys_kodsent = 0; 5420330106Sdelphij sys_lamport = 0; 5421330106Sdelphij sys_tsrounding = 0; 542254359Sroberto} 5423