ntp_proto.c revision 330106
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" 18285169Scy#include "refidsmear.h" 19293423Sdelphij#include "lib_strbuf.h" 2054359Sroberto 2182505Sroberto#include <stdio.h> 22280849Scy#ifdef HAVE_LIBSCF_H 23280849Scy#include <libscf.h> 2454359Sroberto#endif 25280849Scy#ifdef HAVE_UNISTD_H 26280849Scy#include <unistd.h> 2754359Sroberto#endif 2854359Sroberto 29298695Sdelphij/* [Bug 3031] define automatic broadcastdelay cutoff preset */ 30298695Sdelphij#ifndef BDELAY_DEFAULT 31298695Sdelphij# define BDELAY_DEFAULT (-0.050) 32298695Sdelphij#endif 33298695Sdelphij 3454359Sroberto/* 35182007Sroberto * This macro defines the authentication state. If x is 1 authentication 36182007Sroberto * is required; othewise it is optional. 37182007Sroberto */ 38289764Sglebius#define AUTH(x, y) ((x) ? (y) == AUTH_OK \ 39289764Sglebius : (y) == AUTH_OK || (y) == AUTH_NONE) 40182007Sroberto 41330106Sdelphijtypedef enum 42330106Sdelphijauth_state { 43330106Sdelphij AUTH_UNKNOWN = -1, /* Unknown */ 44330106Sdelphij AUTH_NONE, /* authentication not required */ 45330106Sdelphij AUTH_OK, /* authentication OK */ 46330106Sdelphij AUTH_ERROR, /* authentication error */ 47330106Sdelphij AUTH_CRYPTO /* crypto_NAK */ 48330106Sdelphij} auth_code; 49280849Scy 50182007Sroberto/* 51289764Sglebius * Set up Kiss Code values 52289764Sglebius */ 53289764Sglebius 54330106Sdelphijtypedef enum 55330106Sdelphijkiss_codes { 56289764Sglebius NOKISS, /* No Kiss Code */ 57289764Sglebius RATEKISS, /* Rate limit Kiss Code */ 58289764Sglebius DENYKISS, /* Deny Kiss */ 59289764Sglebius RSTRKISS, /* Restricted Kiss */ 60330106Sdelphij XKISS /* Experimental Kiss */ 61330106Sdelphij} kiss_code; 62289764Sglebius 63330106Sdelphijtypedef enum 64330106Sdelphijnak_error_codes { 65298695Sdelphij NONAK, /* No NAK seen */ 66298695Sdelphij INVALIDNAK, /* NAK cannot be used */ 67298695Sdelphij VALIDNAK /* NAK is valid */ 68330106Sdelphij} nak_code; 69298695Sdelphij 70289764Sglebius/* 71280849Scy * traffic shaping parameters 7254359Sroberto */ 73280849Scy#define NTP_IBURST 6 /* packets in iburst */ 74280849Scy#define RESP_DELAY 1 /* refclock burst delay (s) */ 75280849Scy 76280849Scy/* 77280849Scy * pool soliciting restriction duration (s) 78280849Scy */ 79280849Scy#define POOL_SOLICIT_WINDOW 8 80280849Scy 81280849Scy/* 82280849Scy * peer_select groups statistics for a peer used by clock_select() and 83280849Scy * clock_cluster(). 84280849Scy */ 85280849Scytypedef struct peer_select_tag { 86280849Scy struct peer * peer; 87280849Scy double synch; /* sync distance */ 88280849Scy double error; /* jitter */ 89280849Scy double seljit; /* selection jitter */ 90280849Scy} peer_select; 91280849Scy 92280849Scy/* 93280849Scy * System variables are declared here. Unless specified otherwise, all 94280849Scy * times are in seconds. 95280849Scy */ 96285169Scyu_char sys_leap; /* system leap indicator, use set_sys_leap() to change this */ 97285169Scyu_char xmt_leap; /* leap indicator sent in client requests, set up by set_sys_leap() */ 98280849Scyu_char sys_stratum; /* system stratum */ 99182007Srobertos_char sys_precision; /* local clock precision (log2 s) */ 10082505Srobertodouble sys_rootdelay; /* roundtrip delay to primary source */ 101280849Scydouble sys_rootdisp; /* dispersion to primary source */ 102280849Scyu_int32 sys_refid; /* reference id (network byte order) */ 103280849Scyl_fp sys_reftime; /* last update time */ 104280849Scystruct peer *sys_peer; /* current peer */ 10554359Sroberto 106285169Scy#ifdef LEAP_SMEAR 107285169Scystruct leap_smear_info leap_smear; 108285169Scy#endif 109285169Scyint leap_sec_in_progress; 110285169Scy 11154359Sroberto/* 112280849Scy * Rate controls. Leaky buckets are used to throttle the packet 113280849Scy * transmission rates in order to protect busy servers such as at NIST 114280849Scy * and USNO. There is a counter for each association and another for KoD 115280849Scy * packets. The association counter decrements each second, but not 116280849Scy * below zero. Each time a packet is sent the counter is incremented by 117280849Scy * a configurable value representing the average interval between 118280849Scy * packets. A packet is delayed as long as the counter is greater than 119280849Scy * zero. Note this does not affect the time value computations. 12054359Sroberto */ 121280849Scy/* 122280849Scy * Nonspecified system state variables 123280849Scy */ 124132454Srobertoint sys_bclient; /* broadcast client enable */ 125132454Srobertodouble sys_bdelay; /* broadcast client default delay */ 12654359Srobertoint sys_authenticate; /* requre authentication for config */ 12754359Srobertol_fp sys_authdelay; /* authentication delay */ 128280849Scydouble sys_offset; /* current local clock offset */ 129280849Scydouble sys_mindisp = MINDISPERSE; /* minimum distance (s) */ 130280849Scydouble sys_maxdist = MAXDISTANCE; /* selection threshold */ 131280849Scydouble sys_jitter; /* system jitter */ 132280849Scyu_long sys_epoch; /* last clock update time */ 133280849Scystatic double sys_clockhop; /* clockhop threshold */ 134280849Scystatic int leap_vote_ins; /* leap consensus for insert */ 135280849Scystatic int leap_vote_del; /* leap consensus for delete */ 13682505Srobertokeyid_t sys_private; /* private value for session seed */ 13782505Srobertoint sys_manycastserver; /* respond to manycast client pkts */ 138280849Scyint ntp_mode7; /* respond to ntpdc (mode7) */ 13982505Srobertoint peer_ntpdate; /* active peers in ntpdate mode */ 140132454Srobertoint sys_survivors; /* truest of the truechimers */ 141280849Scychar *sys_ident = NULL; /* identity scheme */ 14254359Sroberto 14354359Sroberto/* 144132454Sroberto * TOS and multicast mapping stuff 145132454Sroberto */ 146182007Srobertoint sys_floor = 0; /* cluster stratum floor */ 147309007Sdelphiju_char sys_bcpollbstep = 0; /* Broadcast Poll backstep gate */ 148280849Scyint sys_ceiling = STRATUM_UNSPEC - 1; /* cluster stratum ceiling */ 149132454Srobertoint sys_minsane = 1; /* minimum candidates */ 150280849Scyint sys_minclock = NTP_MINCLOCK; /* minimum candidates */ 151182007Srobertoint sys_maxclock = NTP_MAXCLOCK; /* maximum candidates */ 152132454Srobertoint sys_cohort = 0; /* cohort switch */ 153182007Srobertoint sys_orphan = STRATUM_UNSPEC + 1; /* orphan stratum */ 154280849Scyint sys_orphwait = NTP_ORPHWAIT; /* orphan wait */ 155182007Srobertoint sys_beacon = BEACON; /* manycast beacon interval */ 156316068Sdelphiju_int sys_ttlmax; /* max ttl mapping vector index */ 157132454Srobertou_char sys_ttl[MAX_TTL]; /* ttl mapping vector */ 158132454Sroberto 159132454Sroberto/* 160280849Scy * Statistics counters - first the good, then the bad 16154359Sroberto */ 162280849Scyu_long sys_stattime; /* elapsed time */ 163132454Srobertou_long sys_received; /* packets received */ 164280849Scyu_long sys_processed; /* packets for this host */ 165280849Scyu_long sys_newversion; /* current version */ 166280849Scyu_long sys_oldversion; /* old version */ 167132454Srobertou_long sys_restricted; /* access denied */ 168132454Srobertou_long sys_badlength; /* bad length or format */ 169132454Srobertou_long sys_badauth; /* bad authentication */ 170280849Scyu_long sys_declined; /* declined */ 171132454Srobertou_long sys_limitrejected; /* rate exceeded */ 172280849Scyu_long sys_kodsent; /* KoD sent */ 17354359Sroberto 174294554Sdelphij/* 175301247Sdelphij * Mechanism knobs: how soon do we peer_clear() or unpeer()? 176294554Sdelphij * 177294554Sdelphij * The default way is "on-receipt". If this was a packet from a 178294554Sdelphij * well-behaved source, on-receipt will offer the fastest recovery. 179294554Sdelphij * If this was from a DoS attack, the default way makes it easier 180294554Sdelphij * for a bad-guy to DoS us. So look and see what bites you harder 181294554Sdelphij * and choose according to your environment. 182294554Sdelphij */ 183301247Sdelphijint peer_clear_digest_early = 1; /* bad digest (TEST5) and Autokey */ 184294554Sdelphijint unpeer_crypto_early = 1; /* bad crypto (TEST9) */ 185294554Sdelphijint unpeer_crypto_nak_early = 1; /* crypto_NAK (TEST5) */ 186294554Sdelphijint unpeer_digest_early = 1; /* bad digest (TEST5) */ 187294554Sdelphij 188298695Sdelphijint dynamic_interleave = DYNAMIC_INTERLEAVE; /* Bug 2978 mitigation */ 189298695Sdelphij 190298695Sdelphijint kiss_code_check(u_char hisleap, u_char hisstratum, u_char hismode, u_int32 refid); 191330106Sdelphijnak_code valid_NAK (struct peer *peer, struct recvbuf *rbufp, u_char hismode); 192280849Scystatic double root_distance (struct peer *); 193280849Scystatic void clock_combine (peer_select *, int, int); 194280849Scystatic void peer_xmit (struct peer *); 195280849Scystatic void fast_xmit (struct recvbuf *, int, keyid_t, int); 196280849Scystatic void pool_xmit (struct peer *); 197280849Scystatic void clock_update (struct peer *); 198280849Scystatic void measure_precision(void); 199280849Scystatic double measure_tick_fuzz(void); 200280849Scystatic int local_refid (struct peer *); 201280849Scystatic int peer_unfit (struct peer *); 202280849Scy#ifdef AUTOKEY 203280849Scystatic int group_test (char *, char *); 204280849Scy#endif /* AUTOKEY */ 205280849Scy#ifdef WORKER 206280849Scyvoid pool_name_resolved (int, int, void *, const char *, 207280849Scy const char *, const struct addrinfo *, 208280849Scy const struct addrinfo *); 209280849Scy#endif /* WORKER */ 21054359Sroberto 211293423Sdelphijconst char * amtoa (int am); 212293423Sdelphij 213293423Sdelphij 214285169Scyvoid 215293423Sdelphijset_sys_leap( 216293423Sdelphij u_char new_sys_leap 217293423Sdelphij ) 218293423Sdelphij{ 219285169Scy sys_leap = new_sys_leap; 220285169Scy xmt_leap = sys_leap; 221182007Sroberto 222285169Scy /* 223285169Scy * Under certain conditions we send faked leap bits to clients, so 224285169Scy * eventually change xmt_leap below, but never change LEAP_NOTINSYNC. 225285169Scy */ 226285169Scy if (xmt_leap != LEAP_NOTINSYNC) { 227285169Scy if (leap_sec_in_progress) { 228285169Scy /* always send "not sync" */ 229285169Scy xmt_leap = LEAP_NOTINSYNC; 230285169Scy } 231285169Scy#ifdef LEAP_SMEAR 232285169Scy else { 233285169Scy /* 234293423Sdelphij * If leap smear is enabled in general we must 235293423Sdelphij * never send a leap second warning to clients, 236293423Sdelphij * so make sure we only send "in sync". 237285169Scy */ 238285169Scy if (leap_smear.enabled) 239285169Scy xmt_leap = LEAP_NOWARNING; 240285169Scy } 241285169Scy#endif /* LEAP_SMEAR */ 242285169Scy } 243285169Scy} 244285169Scy 245293423Sdelphij 246289764Sglebius/* 247289764Sglebius * Kiss Code check 248289764Sglebius */ 249293423Sdelphijint 250293423Sdelphijkiss_code_check( 251293423Sdelphij u_char hisleap, 252293423Sdelphij u_char hisstratum, 253293423Sdelphij u_char hismode, 254293423Sdelphij u_int32 refid 255293423Sdelphij ) 256293423Sdelphij{ 257285169Scy 258293423Sdelphij if ( hismode == MODE_SERVER 259293423Sdelphij && hisleap == LEAP_NOTINSYNC 260293423Sdelphij && hisstratum == STRATUM_UNSPEC) { 261293423Sdelphij if(memcmp(&refid,"RATE", 4) == 0) { 262293423Sdelphij return (RATEKISS); 263293423Sdelphij } else if(memcmp(&refid,"DENY", 4) == 0) { 264293423Sdelphij return (DENYKISS); 265293423Sdelphij } else if(memcmp(&refid,"RSTR", 4) == 0) { 266293423Sdelphij return (RSTRKISS); 267293423Sdelphij } else if(memcmp(&refid,"X", 1) == 0) { 268293423Sdelphij return (XKISS); 269289764Sglebius } 270293423Sdelphij } 271330106Sdelphij return (NOKISS); 272289764Sglebius} 273293423Sdelphij 274293423Sdelphij 275298695Sdelphij/* 276298695Sdelphij * Check that NAK is valid 277298695Sdelphij */ 278330106Sdelphijnak_code 279298695Sdelphijvalid_NAK( 280298695Sdelphij struct peer *peer, 281298695Sdelphij struct recvbuf *rbufp, 282298695Sdelphij u_char hismode 283298695Sdelphij ) 284298695Sdelphij{ 285309007Sdelphij int base_packet_length = MIN_V4_PKT_LEN; 286301247Sdelphij int remainder_size; 287301247Sdelphij struct pkt * rpkt; 288301247Sdelphij int keyid; 289301247Sdelphij l_fp p_org; /* origin timestamp */ 290301247Sdelphij const l_fp * myorg; /* selected peer origin */ 291298695Sdelphij 292298695Sdelphij /* 293298695Sdelphij * Check to see if there is something beyond the basic packet 294298695Sdelphij */ 295298695Sdelphij if (rbufp->recv_length == base_packet_length) { 296298695Sdelphij return NONAK; 297298695Sdelphij } 298298695Sdelphij 299298695Sdelphij remainder_size = rbufp->recv_length - base_packet_length; 300298695Sdelphij /* 301298695Sdelphij * Is this a potential NAK? 302298695Sdelphij */ 303298695Sdelphij if (remainder_size != 4) { 304298695Sdelphij return NONAK; 305298695Sdelphij } 306298695Sdelphij 307298695Sdelphij /* 308298695Sdelphij * Only server responses can contain NAK's 309298695Sdelphij */ 310298695Sdelphij 311298695Sdelphij if (hismode != MODE_SERVER && 312298695Sdelphij hismode != MODE_ACTIVE && 313298695Sdelphij hismode != MODE_PASSIVE 314298695Sdelphij ) { 315301247Sdelphij return INVALIDNAK; 316298695Sdelphij } 317298695Sdelphij 318298695Sdelphij /* 319298695Sdelphij * Make sure that the extra field in the packet is all zeros 320298695Sdelphij */ 321298695Sdelphij rpkt = &rbufp->recv_pkt; 322298695Sdelphij keyid = ntohl(((u_int32 *)rpkt)[base_packet_length / 4]); 323298695Sdelphij if (keyid != 0) { 324301247Sdelphij return INVALIDNAK; 325298695Sdelphij } 326298695Sdelphij 327298695Sdelphij /* 328298695Sdelphij * Only valid if peer uses a key 329298695Sdelphij */ 330301247Sdelphij if (!peer || !peer->keyid || !(peer->flags & FLAG_SKEY)) { 331301247Sdelphij return INVALIDNAK; 332298695Sdelphij } 333301247Sdelphij 334301247Sdelphij /* 335301247Sdelphij * The ORIGIN must match, or this cannot be a valid NAK, either. 336301247Sdelphij */ 337301247Sdelphij NTOHL_FP(&rpkt->org, &p_org); 338301247Sdelphij if (peer->flip > 0) 339301247Sdelphij myorg = &peer->borg; 340301247Sdelphij else 341301247Sdelphij myorg = &peer->aorg; 342309007Sdelphij 343301247Sdelphij if (L_ISZERO(&p_org) || 344301247Sdelphij L_ISZERO( myorg) || 345301247Sdelphij !L_ISEQU(&p_org, myorg)) { 346301247Sdelphij return INVALIDNAK; 347298695Sdelphij } 348301247Sdelphij 349301247Sdelphij /* If we ever passed all that checks, we should be safe. Well, 350301247Sdelphij * as safe as we can ever be with an unauthenticated crypto-nak. 351301247Sdelphij */ 352301247Sdelphij return VALIDNAK; 353298695Sdelphij} 354298695Sdelphij 355298695Sdelphij 35654359Sroberto/* 357280849Scy * transmit - transmit procedure called by poll timeout 35854359Sroberto */ 35954359Srobertovoid 36054359Srobertotransmit( 36154359Sroberto struct peer *peer /* peer structure pointer */ 36254359Sroberto ) 36354359Sroberto{ 364280849Scy u_char hpoll; 36554359Sroberto 366132454Sroberto /* 367132454Sroberto * The polling state machine. There are two kinds of machines, 368132454Sroberto * those that never expect a reply (broadcast and manycast 369132454Sroberto * server modes) and those that do (all other modes). The dance 370132454Sroberto * is intricate... 371132454Sroberto */ 37254359Sroberto hpoll = peer->hpoll; 373182007Sroberto 374182007Sroberto /* 375182007Sroberto * In broadcast mode the poll interval is never changed from 376182007Sroberto * minpoll. 377182007Sroberto */ 378132454Sroberto if (peer->cast_flags & (MDF_BCAST | MDF_MCAST)) { 379182007Sroberto peer->outdate = current_time; 380280849Scy if (sys_leap != LEAP_NOTINSYNC) 381280849Scy peer_xmit(peer); 382182007Sroberto poll_update(peer, hpoll); 383182007Sroberto return; 384182007Sroberto } 38554359Sroberto 386182007Sroberto /* 387182007Sroberto * In manycast mode we start with unity ttl. The ttl is 388182007Sroberto * increased by one for each poll until either sys_maxclock 389182007Sroberto * servers have been found or the maximum ttl is reached. When 390182007Sroberto * sys_maxclock servers are found we stop polling until one or 391280849Scy * more servers have timed out or until less than sys_minclock 392182007Sroberto * associations turn up. In this case additional better servers 393280849Scy * are dragged in and preempt the existing ones. Once every 394280849Scy * sys_beacon seconds we are to transmit unconditionally, but 395280849Scy * this code is not quite right -- peer->unreach counts polls 396280849Scy * and is being compared with sys_beacon, so the beacons happen 397280849Scy * every sys_beacon polls. 398182007Sroberto */ 399182007Sroberto if (peer->cast_flags & MDF_ACAST) { 400182007Sroberto peer->outdate = current_time; 401182007Sroberto if (peer->unreach > sys_beacon) { 402182007Sroberto peer->unreach = 0; 403182007Sroberto peer->ttl = 0; 404182007Sroberto peer_xmit(peer); 405289764Sglebius } else if ( sys_survivors < sys_minclock 406289764Sglebius || peer_associations < sys_maxclock) { 407316068Sdelphij if (peer->ttl < sys_ttlmax) 408182007Sroberto peer->ttl++; 409182007Sroberto peer_xmit(peer); 410182007Sroberto } 411182007Sroberto peer->unreach++; 412182007Sroberto poll_update(peer, hpoll); 413182007Sroberto return; 414182007Sroberto } 41582505Sroberto 416182007Sroberto /* 417280849Scy * Pool associations transmit unicast solicitations when there 418280849Scy * are less than a hard limit of 2 * sys_maxclock associations, 419280849Scy * and either less than sys_minclock survivors or less than 420280849Scy * sys_maxclock associations. The hard limit prevents unbounded 421280849Scy * growth in associations if the system clock or network quality 422280849Scy * result in survivor count dipping below sys_minclock often. 423280849Scy * This was observed testing with pool, where sys_maxclock == 12 424280849Scy * resulted in 60 associations without the hard limit. A 425280849Scy * similar hard limit on manycastclient ephemeral associations 426280849Scy * may be appropriate. 427280849Scy */ 428280849Scy if (peer->cast_flags & MDF_POOL) { 429280849Scy peer->outdate = current_time; 430289764Sglebius if ( (peer_associations <= 2 * sys_maxclock) 431289764Sglebius && ( peer_associations < sys_maxclock 432293423Sdelphij || sys_survivors < sys_minclock)) 433280849Scy pool_xmit(peer); 434280849Scy poll_update(peer, hpoll); 435280849Scy return; 436280849Scy } 437280849Scy 438280849Scy /* 439182007Sroberto * In unicast modes the dance is much more intricate. It is 440280849Scy * designed to back off whenever possible to minimize network 441182007Sroberto * traffic. 442182007Sroberto */ 443182007Sroberto if (peer->burst == 0) { 444182007Sroberto u_char oreach; 445182007Sroberto 446132454Sroberto /* 447182007Sroberto * Update the reachability status. If not heard for 448182007Sroberto * three consecutive polls, stuff infinity in the clock 449282408Scy * filter. 450132454Sroberto */ 451182007Sroberto oreach = peer->reach; 452182007Sroberto peer->outdate = current_time; 453280849Scy peer->unreach++; 454182007Sroberto peer->reach <<= 1; 455182007Sroberto if (!peer->reach) { 45682505Sroberto 457182007Sroberto /* 458182007Sroberto * Here the peer is unreachable. If it was 459280849Scy * previously reachable raise a trap. Send a 460280849Scy * burst if enabled. 461182007Sroberto */ 462280849Scy clock_filter(peer, 0., 0., MAXDISPERSE); 463182007Sroberto if (oreach) { 464280849Scy peer_unfit(peer); 465280849Scy report_event(PEVNT_UNREACH, peer, NULL); 466182007Sroberto } 467289764Sglebius if ( (peer->flags & FLAG_IBURST) 468289764Sglebius && peer->retry == 0) 469280849Scy peer->retry = NTP_RETRY; 470182007Sroberto } else { 471182007Sroberto 472182007Sroberto /* 473280849Scy * Here the peer is reachable. Send a burst if 474280849Scy * enabled and the peer is fit. Reset unreach 475280849Scy * for persistent and ephemeral associations. 476280849Scy * Unreach is also reset for survivors in 477280849Scy * clock_select(). 478182007Sroberto */ 479280849Scy hpoll = sys_poll; 480280849Scy if (!(peer->flags & FLAG_PREEMPT)) 481182007Sroberto peer->unreach = 0; 482289764Sglebius if ( (peer->flags & FLAG_BURST) 483289764Sglebius && peer->retry == 0 484289764Sglebius && !peer_unfit(peer)) 485280849Scy peer->retry = NTP_RETRY; 486182007Sroberto } 487182007Sroberto 488132454Sroberto /* 489280849Scy * Watch for timeout. If ephemeral, toss the rascal; 490280849Scy * otherwise, bump the poll interval. Note the 491280849Scy * poll_update() routine will clamp it to maxpoll. 492280849Scy * If preemptible and we have more peers than maxclock, 493280849Scy * and this peer has the minimum score of preemptibles, 494280849Scy * demobilize. 495282408Scy */ 496132454Sroberto if (peer->unreach >= NTP_UNREACH) { 497280849Scy hpoll++; 498280849Scy /* ephemeral: no FLAG_CONFIG nor FLAG_PREEMPT */ 499280849Scy if (!(peer->flags & (FLAG_CONFIG | FLAG_PREEMPT))) { 500280849Scy report_event(PEVNT_RESTART, peer, "timeout"); 501182007Sroberto peer_clear(peer, "TIME"); 50282505Sroberto unpeer(peer); 50382505Sroberto return; 50482505Sroberto } 505289764Sglebius if ( (peer->flags & FLAG_PREEMPT) 506289764Sglebius && (peer_associations > sys_maxclock) 507289764Sglebius && score_all(peer)) { 508280849Scy report_event(PEVNT_RESTART, peer, "timeout"); 509280849Scy peer_clear(peer, "TIME"); 510280849Scy unpeer(peer); 511280849Scy return; 512280849Scy } 51382505Sroberto } 514182007Sroberto } else { 515182007Sroberto peer->burst--; 516132454Sroberto if (peer->burst == 0) { 51754359Sroberto 51854359Sroberto /* 519182007Sroberto * If ntpdate mode and the clock has not been 520182007Sroberto * set and all peers have completed the burst, 521182007Sroberto * we declare a successful failure. 52254359Sroberto */ 523182007Sroberto if (mode_ntpdate) { 524182007Sroberto peer_ntpdate--; 525182007Sroberto if (peer_ntpdate == 0) { 526132454Sroberto msyslog(LOG_NOTICE, 527280849Scy "ntpd: no servers found"); 528280849Scy if (!msyslog_term) 529280849Scy printf( 530280849Scy "ntpd: no servers found\n"); 531132454Sroberto exit (0); 532132454Sroberto } 53354359Sroberto } 53454359Sroberto } 53554359Sroberto } 536280849Scy if (peer->retry > 0) 537280849Scy peer->retry--; 53854359Sroberto 53954359Sroberto /* 540282408Scy * Do not transmit if in broadcast client mode. 54154359Sroberto */ 542182007Sroberto if (peer->hmode != MODE_BCLIENT) 543182007Sroberto peer_xmit(peer); 544132454Sroberto poll_update(peer, hpoll); 545293423Sdelphij 546293423Sdelphij return; 54754359Sroberto} 54854359Sroberto 549182007Sroberto 550293423Sdelphijconst char * 551293423Sdelphijamtoa( 552293423Sdelphij int am 553293423Sdelphij ) 554293423Sdelphij{ 555293423Sdelphij char *bp; 556293423Sdelphij 557293423Sdelphij switch(am) { 558293423Sdelphij case AM_ERR: return "AM_ERR"; 559293423Sdelphij case AM_NOMATCH: return "AM_NOMATCH"; 560293423Sdelphij case AM_PROCPKT: return "AM_PROCPKT"; 561293423Sdelphij case AM_BCST: return "AM_BCST"; 562293423Sdelphij case AM_FXMIT: return "AM_FXMIT"; 563293423Sdelphij case AM_MANYCAST: return "AM_MANYCAST"; 564293423Sdelphij case AM_NEWPASS: return "AM_NEWPASS"; 565293423Sdelphij case AM_NEWBCL: return "AM_NEWBCL"; 566293423Sdelphij case AM_POSSBCL: return "AM_POSSBCL"; 567293423Sdelphij default: 568293423Sdelphij LIB_GETBUF(bp); 569293423Sdelphij snprintf(bp, LIB_BUFLENGTH, "AM_#%d", am); 570293423Sdelphij return bp; 571293423Sdelphij } 572293423Sdelphij} 573293423Sdelphij 574293423Sdelphij 57554359Sroberto/* 576280849Scy * receive - receive procedure called for each packet received 57754359Sroberto */ 57854359Srobertovoid 57954359Srobertoreceive( 58054359Sroberto struct recvbuf *rbufp 58154359Sroberto ) 58254359Sroberto{ 583132454Sroberto register struct peer *peer; /* peer structure pointer */ 584132454Sroberto register struct pkt *pkt; /* receive packet pointer */ 585280849Scy u_char hisversion; /* packet version */ 586280849Scy u_char hisleap; /* packet leap indicator */ 587280849Scy u_char hismode; /* packet mode */ 588280849Scy u_char hisstratum; /* packet stratum */ 589330106Sdelphij r4addr r4a; /* address restrictions */ 590280849Scy u_short restrict_mask; /* restrict bits */ 591293423Sdelphij const char *hm_str; /* hismode string */ 592293423Sdelphij const char *am_str; /* association match string */ 593293423Sdelphij int kissCode = NOKISS; /* Kiss Code */ 594132454Sroberto int has_mac; /* length of MAC field */ 595132454Sroberto int authlen; /* offset of MAC field */ 596330106Sdelphij auth_code is_authentic = AUTH_UNKNOWN; /* Was AUTH_NONE */ 597330106Sdelphij nak_code crypto_nak_test; /* result of crypto-NAK check */ 598280849Scy int retcode = AM_NOMATCH; /* match code */ 599280849Scy keyid_t skeyid = 0; /* key IDs */ 600280849Scy u_int32 opcode = 0; /* extension field opcode */ 601293423Sdelphij sockaddr_u *dstadr_sin; /* active runway */ 602132454Sroberto struct peer *peer2; /* aux peer structure pointer */ 603293423Sdelphij endpt *match_ep; /* newpeer() local address */ 604182007Sroberto l_fp p_org; /* origin timestamp */ 605182007Sroberto l_fp p_rec; /* receive timestamp */ 606132454Sroberto l_fp p_xmt; /* transmit timestamp */ 607280849Scy#ifdef AUTOKEY 608280849Scy char hostname[NTP_MAXSTRLEN + 1]; 609280849Scy char *groupname = NULL; 610132454Sroberto struct autokey *ap; /* autokey structure pointer */ 611132454Sroberto int rval; /* cookie snatcher */ 612280849Scy keyid_t pkeyid = 0, tkeyid = 0; /* key IDs */ 613280849Scy#endif /* AUTOKEY */ 614280849Scy#ifdef HAVE_NTP_SIGND 615280849Scy static unsigned char zero_key[16]; 616280849Scy#endif /* HAVE_NTP_SIGND */ 61754359Sroberto 61854359Sroberto /* 619330106Sdelphij * Note that there are many places we do not call record_raw_stats(). 620330106Sdelphij * 621330106Sdelphij * We only want to call it *after* we've sent a response, or perhaps 622330106Sdelphij * when we've decided to drop a packet. 623330106Sdelphij */ 624330106Sdelphij 625330106Sdelphij /* 62682505Sroberto * Monitor the packet and get restrictions. Note that the packet 62782505Sroberto * length for control and private mode packets must be checked 628280849Scy * by the service routines. Some restrictions have to be handled 629280849Scy * later in order to generate a kiss-o'-death packet. 63054359Sroberto */ 631132454Sroberto /* 632132454Sroberto * Bogus port check is before anything, since it probably 633132454Sroberto * reveals a clogging attack. 634132454Sroberto */ 635132454Sroberto sys_received++; 636280849Scy if (0 == SRCPORT(&rbufp->recv_srcadr)) { 637132454Sroberto sys_badlength++; 638132454Sroberto return; /* bogus port */ 639132454Sroberto } 640330106Sdelphij restrictions(&rbufp->recv_srcadr, &r4a); 641330106Sdelphij restrict_mask = r4a.rflags; 642330106Sdelphij 643293423Sdelphij pkt = &rbufp->recv_pkt; 644182007Sroberto hisversion = PKT_VERSION(pkt->li_vn_mode); 645182007Sroberto hisleap = PKT_LEAP(pkt->li_vn_mode); 646132454Sroberto hismode = (int)PKT_MODE(pkt->li_vn_mode); 647182007Sroberto hisstratum = PKT_TO_STRATUM(pkt->stratum); 648330106Sdelphij DPRINTF(2, ("receive: at %ld %s<-%s ippeerlimit %d mode %d iflags %s restrict %s org %#010x.%08x xmt %#010x.%08x\n", 649330106Sdelphij current_time, stoa(&rbufp->dstadr->sin), 650330106Sdelphij stoa(&rbufp->recv_srcadr), r4a.ippeerlimit, hismode, 651330106Sdelphij build_iflags(rbufp->dstadr->flags), 652330106Sdelphij build_rflags(restrict_mask), 653330106Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 654330106Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 655330106Sdelphij 656330106Sdelphij /* See basic mode and broadcast checks, below */ 657301247Sdelphij INSIST(0 != hisstratum); 658301247Sdelphij 659280849Scy if (restrict_mask & RES_IGNORE) { 660330106Sdelphij DPRINTF(2, ("receive: drop: RES_IGNORE\n")); 661280849Scy sys_restricted++; 662280849Scy return; /* ignore everything */ 663280849Scy } 664132454Sroberto if (hismode == MODE_PRIVATE) { 665280849Scy if (!ntp_mode7 || (restrict_mask & RES_NOQUERY)) { 666330106Sdelphij DPRINTF(2, ("receive: drop: RES_NOQUERY\n")); 667132454Sroberto sys_restricted++; 66882505Sroberto return; /* no query private */ 669132454Sroberto } 67056749Sroberto process_private(rbufp, ((restrict_mask & 67156749Sroberto RES_NOMODIFY) == 0)); 67254359Sroberto return; 67354359Sroberto } 674132454Sroberto if (hismode == MODE_CONTROL) { 675132454Sroberto if (restrict_mask & RES_NOQUERY) { 676330106Sdelphij DPRINTF(2, ("receive: drop: RES_NOQUERY\n")); 677132454Sroberto sys_restricted++; 67882505Sroberto return; /* no query control */ 679132454Sroberto } 68054359Sroberto process_control(rbufp, restrict_mask); 68154359Sroberto return; 68254359Sroberto } 683132454Sroberto if (restrict_mask & RES_DONTSERVE) { 684330106Sdelphij DPRINTF(2, ("receive: drop: RES_DONTSERVE\n")); 685132454Sroberto sys_restricted++; 686280849Scy return; /* no time serve */ 687132454Sroberto } 688280849Scy 689280849Scy /* 690280849Scy * This is for testing. If restricted drop ten percent of 691280849Scy * surviving packets. 692280849Scy */ 693280849Scy if (restrict_mask & RES_FLAKE) { 694280849Scy if ((double)ntp_random() / 0x7fffffff < .1) { 695330106Sdelphij DPRINTF(2, ("receive: drop: RES_FLAKE\n")); 696280849Scy sys_restricted++; 697280849Scy return; /* no flakeway */ 698280849Scy } 69982505Sroberto } 700282408Scy 701132454Sroberto /* 702330106Sdelphij ** Format Layer Checks 703330106Sdelphij ** 704330106Sdelphij ** Validate the packet format. The packet size, packet header, 705330106Sdelphij ** and any extension field lengths are checked. We identify 706330106Sdelphij ** the beginning of the MAC, to identify the upper limit of 707330106Sdelphij ** of the hash computation. 708330106Sdelphij ** 709330106Sdelphij ** In case of a format layer check violation, the packet is 710330106Sdelphij ** discarded with no further processing. 711330106Sdelphij */ 712330106Sdelphij 713330106Sdelphij /* 714132454Sroberto * Version check must be after the query packets, since they 715280849Scy * intentionally use an early version. 716132454Sroberto */ 717182007Sroberto if (hisversion == NTP_VERSION) { 718280849Scy sys_newversion++; /* new version */ 719289764Sglebius } else if ( !(restrict_mask & RES_VERSION) 720289764Sglebius && hisversion >= NTP_OLDVERSION) { 721280849Scy sys_oldversion++; /* previous version */ 722132454Sroberto } else { 723330106Sdelphij DPRINTF(2, ("receive: drop: RES_VERSION\n")); 724280849Scy sys_badlength++; 725132454Sroberto return; /* old version */ 726132454Sroberto } 72754359Sroberto 72854359Sroberto /* 729132454Sroberto * Figure out his mode and validate the packet. This has some 730132454Sroberto * legacy raunch that probably should be removed. In very early 731132454Sroberto * NTP versions mode 0 was equivalent to what later versions 732132454Sroberto * would interpret as client mode. 73354359Sroberto */ 73482505Sroberto if (hismode == MODE_UNSPEC) { 735182007Sroberto if (hisversion == NTP_OLDVERSION) { 736132454Sroberto hismode = MODE_CLIENT; 737132454Sroberto } else { 738330106Sdelphij DPRINTF(2, ("receive: drop: MODE_UNSPEC\n")); 739132454Sroberto sys_badlength++; 740132454Sroberto return; /* invalid mode */ 741132454Sroberto } 74282505Sroberto } 74354359Sroberto 74454359Sroberto /* 74582505Sroberto * Parse the extension field if present. We figure out whether 74682505Sroberto * an extension field is present by measuring the MAC size. If 747182007Sroberto * the number of words following the packet header is 0, no MAC 748182007Sroberto * is present and the packet is not authenticated. If 1, the 749182007Sroberto * packet is a crypto-NAK; if 3, the packet is authenticated 750280849Scy * with DES; if 5, the packet is authenticated with MD5; if 6, 751280849Scy * the packet is authenticated with SHA. If 2 or * 4, the packet 752280849Scy * is a runt and discarded forthwith. If greater than 6, an 753280849Scy * extension field is present, so we subtract the length of the 754280849Scy * field and go around again. 755330106Sdelphij * 756330106Sdelphij * Note the above description is lame. We should/could also check 757330106Sdelphij * the two bytes that make up the EF type and subtype, and then 758330106Sdelphij * check the two bytes that tell us the EF length. A legacy MAC 759330106Sdelphij * has a 4 byte keyID, and for conforming symmetric keys its value 760330106Sdelphij * must be <= 64k, meaning the top two bytes will always be zero. 761330106Sdelphij * Since the EF Type of 0 is reserved/unused, there's no way a 762330106Sdelphij * conforming legacy MAC could ever be misinterpreted as an EF. 763330106Sdelphij * 764330106Sdelphij * There is more, but this isn't the place to document it. 76554359Sroberto */ 766298695Sdelphij 76754359Sroberto authlen = LEN_PKT_NOMAC; 768132454Sroberto has_mac = rbufp->recv_length - authlen; 769132454Sroberto while (has_mac > 0) { 770280849Scy u_int32 len; 771280849Scy#ifdef AUTOKEY 772280849Scy u_int32 hostlen; 773280849Scy struct exten *ep; 774280849Scy#endif /*AUTOKEY */ 77582505Sroberto 776280849Scy if (has_mac % 4 != 0 || has_mac < (int)MIN_MAC_LEN) { 777330106Sdelphij DPRINTF(2, ("receive: drop: bad post-packet length\n")); 77854359Sroberto sys_badlength++; 779280849Scy return; /* bad length */ 78054359Sroberto } 781330106Sdelphij /* 782330106Sdelphij * This next test is clearly wrong - it needlessly 783330106Sdelphij * prohibits short EFs (which don't yet exist) 784330106Sdelphij */ 785280849Scy if (has_mac <= (int)MAX_MAC_LEN) { 78682505Sroberto skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]); 78782505Sroberto break; 78854359Sroberto 789280849Scy } else { 790280849Scy opcode = ntohl(((u_int32 *)pkt)[authlen / 4]); 791280849Scy len = opcode & 0xffff; 792289764Sglebius if ( len % 4 != 0 793289764Sglebius || len < 4 794289764Sglebius || (int)len + authlen > rbufp->recv_length) { 795330106Sdelphij DPRINTF(2, ("receive: drop: bad EF length\n")); 79682505Sroberto sys_badlength++; 797280849Scy return; /* bad length */ 79882505Sroberto } 799280849Scy#ifdef AUTOKEY 800280849Scy /* 801280849Scy * Extract calling group name for later. If 802280849Scy * sys_groupname is non-NULL, there must be 803280849Scy * a group name provided to elicit a response. 804280849Scy */ 805289764Sglebius if ( (opcode & 0x3fff0000) == CRYPTO_ASSOC 806289764Sglebius && sys_groupname != NULL) { 807280849Scy ep = (struct exten *)&((u_int32 *)pkt)[authlen / 4]; 808280849Scy hostlen = ntohl(ep->vallen); 809289764Sglebius if ( hostlen >= sizeof(hostname) 810289764Sglebius || hostlen > len - 811289764Sglebius offsetof(struct exten, pkt)) { 812330106Sdelphij DPRINTF(2, ("receive: drop: bad autokey hostname length\n")); 813280849Scy sys_badlength++; 814280849Scy return; /* bad length */ 815280849Scy } 816280849Scy memcpy(hostname, &ep->pkt, hostlen); 817280849Scy hostname[hostlen] = '\0'; 818280849Scy groupname = strchr(hostname, '@'); 819280849Scy if (groupname == NULL) { 820330106Sdelphij DPRINTF(2, ("receive: drop: empty autokey groupname\n")); 821280849Scy sys_declined++; 822280849Scy return; 823280849Scy } 824280849Scy groupname++; 825280849Scy } 826280849Scy#endif /* AUTOKEY */ 827280849Scy authlen += len; 828280849Scy has_mac -= len; 82982505Sroberto } 83054359Sroberto } 83154359Sroberto 83254359Sroberto /* 833280849Scy * If has_mac is < 0 we had a malformed packet. 834280849Scy */ 835280849Scy if (has_mac < 0) { 836330106Sdelphij DPRINTF(2, ("receive: drop: post-packet under-read\n")); 837280849Scy sys_badlength++; 838280849Scy return; /* bad length */ 839280849Scy } 840280849Scy 841280849Scy /* 842330106Sdelphij ** Packet Data Verification Layer 843330106Sdelphij ** 844330106Sdelphij ** This layer verifies the packet data content. If 845330106Sdelphij ** authentication is required, a MAC must be present. 846330106Sdelphij ** If a MAC is present, it must validate. 847330106Sdelphij ** Crypto-NAK? Look - a shiny thing! 848330106Sdelphij ** 849330106Sdelphij ** If authentication fails, we're done. 850330106Sdelphij */ 851330106Sdelphij 852330106Sdelphij /* 853330106Sdelphij * If authentication is explicitly required, a MAC must be present. 854280849Scy */ 855280849Scy if (restrict_mask & RES_DONTTRUST && has_mac == 0) { 856330106Sdelphij DPRINTF(2, ("receive: drop: RES_DONTTRUST\n")); 857280849Scy sys_restricted++; 858280849Scy return; /* access denied */ 859280849Scy } 860280849Scy 861280849Scy /* 862280849Scy * Update the MRU list and finger the cloggers. It can be a 863280849Scy * little expensive, so turn it off for production use. 864280849Scy * RES_LIMITED and RES_KOD will be cleared in the returned 865280849Scy * restrict_mask unless one or both actions are warranted. 866280849Scy */ 867280849Scy restrict_mask = ntp_monitor(rbufp, restrict_mask); 868280849Scy if (restrict_mask & RES_LIMITED) { 869280849Scy sys_limitrejected++; 870289764Sglebius if ( !(restrict_mask & RES_KOD) 871289764Sglebius || MODE_BROADCAST == hismode 872289764Sglebius || MODE_SERVER == hismode) { 873330106Sdelphij if (MODE_SERVER == hismode) { 874280849Scy DPRINTF(1, ("Possibly self-induced rate limiting of MODE_SERVER from %s\n", 875280849Scy stoa(&rbufp->recv_srcadr))); 876330106Sdelphij } else { 877330106Sdelphij DPRINTF(2, ("receive: drop: RES_KOD\n")); 878330106Sdelphij } 879280849Scy return; /* rate exceeded */ 880280849Scy } 881280849Scy if (hismode == MODE_CLIENT) 882280849Scy fast_xmit(rbufp, MODE_SERVER, skeyid, 883280849Scy restrict_mask); 884280849Scy else 885280849Scy fast_xmit(rbufp, MODE_ACTIVE, skeyid, 886280849Scy restrict_mask); 887280849Scy return; /* rate exceeded */ 888280849Scy } 889280849Scy restrict_mask &= ~RES_KOD; 890280849Scy 891280849Scy /* 89282505Sroberto * We have tossed out as many buggy packets as possible early in 89382505Sroberto * the game to reduce the exposure to a clogging attack. Now we 89482505Sroberto * have to burn some cycles to find the association and 89582505Sroberto * authenticate the packet if required. Note that we burn only 896280849Scy * digest cycles, again to reduce exposure. There may be no 89782505Sroberto * matching association and that's okay. 89882505Sroberto * 89982505Sroberto * More on the autokey mambo. Normally the local interface is 90082505Sroberto * found when the association was mobilized with respect to a 90182505Sroberto * designated remote address. We assume packets arriving from 90282505Sroberto * the remote address arrive via this interface and the local 90382505Sroberto * address used to construct the autokey is the unicast address 90482505Sroberto * of the interface. However, if the sender is a broadcaster, 90582505Sroberto * the interface broadcast address is used instead. 906280849Scy * Notwithstanding this technobabble, if the sender is a 90782505Sroberto * multicaster, the broadcast address is null, so we use the 90882505Sroberto * unicast address anyway. Don't ask. 90954359Sroberto */ 910330106Sdelphij 911280849Scy peer = findpeer(rbufp, hismode, &retcode); 91282505Sroberto dstadr_sin = &rbufp->dstadr->sin; 913182007Sroberto NTOHL_FP(&pkt->org, &p_org); 914182007Sroberto NTOHL_FP(&pkt->rec, &p_rec); 915182007Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 916293423Sdelphij hm_str = modetoa(hismode); 917293423Sdelphij am_str = amtoa(retcode); 918182007Sroberto 919182007Sroberto /* 920182007Sroberto * Authentication is conditioned by three switches: 921182007Sroberto * 922182007Sroberto * NOPEER (RES_NOPEER) do not mobilize an association unless 923182007Sroberto * authenticated 924182007Sroberto * NOTRUST (RES_DONTTRUST) do not allow access unless 925182007Sroberto * authenticated (implies NOPEER) 926182007Sroberto * enable (sys_authenticate) master NOPEER switch, by default 927182007Sroberto * on 928182007Sroberto * 929182007Sroberto * The NOPEER and NOTRUST can be specified on a per-client basis 930182007Sroberto * using the restrict command. The enable switch if on implies 931182007Sroberto * NOPEER for all clients. There are four outcomes: 932182007Sroberto * 933182007Sroberto * NONE The packet has no MAC. 934182007Sroberto * OK the packet has a MAC and authentication succeeds 935182007Sroberto * ERROR the packet has a MAC and authentication fails 936182007Sroberto * CRYPTO crypto-NAK. The MAC has four octets only. 937182007Sroberto * 938182007Sroberto * Note: The AUTH(x, y) macro is used to filter outcomes. If x 939182007Sroberto * is zero, acceptable outcomes of y are NONE and OK. If x is 940182007Sroberto * one, the only acceptable outcome of y is OK. 941182007Sroberto */ 942298695Sdelphij crypto_nak_test = valid_NAK(peer, rbufp, hismode); 943280849Scy 944298695Sdelphij /* 945298695Sdelphij * Drop any invalid crypto-NAKs 946298695Sdelphij */ 947298695Sdelphij if (crypto_nak_test == INVALIDNAK) { 948298695Sdelphij report_event(PEVNT_AUTH, peer, "Invalid_NAK"); 949298695Sdelphij if (0 != peer) { 950298695Sdelphij peer->badNAK++; 951298695Sdelphij } 952298695Sdelphij msyslog(LOG_ERR, "Invalid-NAK error at %ld %s<-%s", 953298695Sdelphij current_time, stoa(dstadr_sin), stoa(&rbufp->recv_srcadr)); 954298695Sdelphij return; 955298695Sdelphij } 956298695Sdelphij 95754359Sroberto if (has_mac == 0) { 958280849Scy restrict_mask &= ~RES_MSSNTP; 959182007Sroberto is_authentic = AUTH_NONE; /* not required */ 960293423Sdelphij DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n", 961182007Sroberto current_time, stoa(dstadr_sin), 962293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 963293423Sdelphij authlen, 964293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 965293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 966298695Sdelphij } else if (crypto_nak_test == VALIDNAK) { 967280849Scy restrict_mask &= ~RES_MSSNTP; 968280849Scy is_authentic = AUTH_CRYPTO; /* crypto-NAK */ 969293423Sdelphij DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC4\n", 970182007Sroberto current_time, stoa(dstadr_sin), 971293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 972293423Sdelphij skeyid, authlen + has_mac, is_authentic, 973293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 974293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 975280849Scy 976280849Scy#ifdef HAVE_NTP_SIGND 977280849Scy /* 978280849Scy * If the signature is 20 bytes long, the last 16 of 979280849Scy * which are zero, then this is a Microsoft client 980280849Scy * wanting AD-style authentication of the server's 981282408Scy * reply. 982280849Scy * 983280849Scy * This is described in Microsoft's WSPP docs, in MS-SNTP: 984280849Scy * http://msdn.microsoft.com/en-us/library/cc212930.aspx 985280849Scy */ 986289764Sglebius } else if ( has_mac == MAX_MD5_LEN 987289764Sglebius && (restrict_mask & RES_MSSNTP) 988289764Sglebius && (retcode == AM_FXMIT || retcode == AM_NEWPASS) 989289764Sglebius && (memcmp(zero_key, (char *)pkt + authlen + 4, 990293423Sdelphij MAX_MD5_LEN - 4) == 0)) { 991280849Scy is_authentic = AUTH_NONE; 992280849Scy#endif /* HAVE_NTP_SIGND */ 993280849Scy 99454359Sroberto } else { 995330106Sdelphij /* 996330106Sdelphij * has_mac is not 0 997330106Sdelphij * Not a VALID_NAK 998330106Sdelphij * Not an MS-SNTP SIGND packet 999330106Sdelphij * 1000330106Sdelphij * So there is a MAC here. 1001330106Sdelphij */ 1002330106Sdelphij 1003280849Scy restrict_mask &= ~RES_MSSNTP; 1004280849Scy#ifdef AUTOKEY 100582505Sroberto /* 100682505Sroberto * For autokey modes, generate the session key 100782505Sroberto * and install in the key cache. Use the socket 100882505Sroberto * broadcast or unicast address as appropriate. 100982505Sroberto */ 1010280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) { 1011282408Scy 101282505Sroberto /* 101382505Sroberto * More on the autokey dance (AKD). A cookie is 101482505Sroberto * constructed from public and private values. 101582505Sroberto * For broadcast packets, the cookie is public 101682505Sroberto * (zero). For packets that match no 101782505Sroberto * association, the cookie is hashed from the 101882505Sroberto * addresses and private value. For server 101982505Sroberto * packets, the cookie was previously obtained 102082505Sroberto * from the server. For symmetric modes, the 102182505Sroberto * cookie was previously constructed using an 102282505Sroberto * agreement protocol; however, should PKI be 102382505Sroberto * unavailable, we construct a fake agreement as 102482505Sroberto * the EXOR of the peer and host cookies. 102582505Sroberto * 102682505Sroberto * hismode ephemeral persistent 102782505Sroberto * ======================================= 102882505Sroberto * active 0 cookie# 102982505Sroberto * passive 0% cookie# 103082505Sroberto * client sys cookie 0% 103182505Sroberto * server 0% sys cookie 103282505Sroberto * broadcast 0 0 103382505Sroberto * 103482505Sroberto * # if unsync, 0 103582505Sroberto * % can't happen 103682505Sroberto */ 1037280849Scy if (has_mac < (int)MAX_MD5_LEN) { 1038330106Sdelphij DPRINTF(2, ("receive: drop: MD5 digest too short\n")); 1039280849Scy sys_badauth++; 1040280849Scy return; 1041280849Scy } 104282505Sroberto if (hismode == MODE_BROADCAST) { 104354359Sroberto 104482505Sroberto /* 104582505Sroberto * For broadcaster, use the interface 104682505Sroberto * broadcast address when available; 104782505Sroberto * otherwise, use the unicast address 104882505Sroberto * found when the association was 1049182007Sroberto * mobilized. However, if this is from 1050182007Sroberto * the wildcard interface, game over. 105182505Sroberto */ 1052289764Sglebius if ( crypto_flags 1053289764Sglebius && rbufp->dstadr == 1054289764Sglebius ANY_INTERFACE_CHOOSE(&rbufp->recv_srcadr)) { 1055330106Sdelphij DPRINTF(2, ("receive: drop: BCAST from wildcard\n")); 1056182007Sroberto sys_restricted++; 1057182007Sroberto return; /* no wildcard */ 1058182007Sroberto } 105982505Sroberto pkeyid = 0; 1060280849Scy if (!SOCK_UNSPEC(&rbufp->dstadr->bcast)) 106182505Sroberto dstadr_sin = 106282505Sroberto &rbufp->dstadr->bcast; 106382505Sroberto } else if (peer == NULL) { 106482505Sroberto pkeyid = session_key( 106582505Sroberto &rbufp->recv_srcadr, dstadr_sin, 0, 106682505Sroberto sys_private, 0); 106782505Sroberto } else { 1068132454Sroberto pkeyid = peer->pcookie; 106982505Sroberto } 107082505Sroberto 107154359Sroberto /* 107282505Sroberto * The session key includes both the public 107382505Sroberto * values and cookie. In case of an extension 107482505Sroberto * field, the cookie used for authentication 107582505Sroberto * purposes is zero. Note the hash is saved for 107682505Sroberto * use later in the autokey mambo. 107754359Sroberto */ 1078280849Scy if (authlen > (int)LEN_PKT_NOMAC && pkeyid != 0) { 107982505Sroberto session_key(&rbufp->recv_srcadr, 108082505Sroberto dstadr_sin, skeyid, 0, 2); 108154359Sroberto tkeyid = session_key( 108282505Sroberto &rbufp->recv_srcadr, dstadr_sin, 108382505Sroberto skeyid, pkeyid, 0); 108482505Sroberto } else { 108554359Sroberto tkeyid = session_key( 108682505Sroberto &rbufp->recv_srcadr, dstadr_sin, 108782505Sroberto skeyid, pkeyid, 2); 108854359Sroberto } 108954359Sroberto 109054359Sroberto } 1091280849Scy#endif /* AUTOKEY */ 109254359Sroberto 109354359Sroberto /* 109454359Sroberto * Compute the cryptosum. Note a clogging attack may 109582505Sroberto * succeed in bloating the key cache. If an autokey, 109682505Sroberto * purge it immediately, since we won't be needing it 1097182007Sroberto * again. If the packet is authentic, it can mobilize an 1098182007Sroberto * association. Note that there is no key zero. 109954359Sroberto */ 1100182007Sroberto if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, 1101280849Scy has_mac)) 1102182007Sroberto is_authentic = AUTH_ERROR; 1103280849Scy else 1104182007Sroberto is_authentic = AUTH_OK; 1105280849Scy#ifdef AUTOKEY 1106280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) 110782505Sroberto authtrust(skeyid, 0); 1108280849Scy#endif /* AUTOKEY */ 1109293423Sdelphij DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x\n", 1110132454Sroberto current_time, stoa(dstadr_sin), 1111293423Sdelphij stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, 1112293423Sdelphij skeyid, authlen + has_mac, is_authentic, 1113293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1114293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); 111554359Sroberto } 111654359Sroberto 1117330106Sdelphij 111854359Sroberto /* 1119330106Sdelphij * Bug 3454: 1120330106Sdelphij * 1121330106Sdelphij * Now come at this from a different perspective: 1122330106Sdelphij * - If we expect a MAC and it's not there, we drop it. 1123330106Sdelphij * - If we expect one keyID and get another, we drop it. 1124330106Sdelphij * - If we have a MAC ahd it hasn't been validated yet, try. 1125330106Sdelphij * - if the provided MAC doesn't validate, we drop it. 1126330106Sdelphij * 1127330106Sdelphij * There might be more to this. 1128330106Sdelphij */ 1129330106Sdelphij if (0 != peer && 0 != peer->keyid) { 1130330106Sdelphij /* Should we msyslog() any of these? */ 1131330106Sdelphij 1132330106Sdelphij /* 1133330106Sdelphij * This should catch: 1134330106Sdelphij * - no keyID where one is expected, 1135330106Sdelphij * - different keyID than what we expect. 1136330106Sdelphij */ 1137330106Sdelphij if (peer->keyid != skeyid) { 1138330106Sdelphij DPRINTF(2, ("receive: drop: Wanted keyID %d, got %d from %s\n", 1139330106Sdelphij peer->keyid, skeyid, 1140330106Sdelphij stoa(&rbufp->recv_srcadr))); 1141330106Sdelphij sys_restricted++; 1142330106Sdelphij return; /* drop: access denied */ 1143330106Sdelphij } 1144330106Sdelphij 1145330106Sdelphij /* 1146330106Sdelphij * if has_mac != 0 ... 1147330106Sdelphij * - If it has not yet been validated, do so. 1148330106Sdelphij * (under what circumstances might that happen?) 1149330106Sdelphij * - if missing or bad MAC, log and drop. 1150330106Sdelphij */ 1151330106Sdelphij if (0 != has_mac) { 1152330106Sdelphij if (is_authentic == AUTH_UNKNOWN) { 1153330106Sdelphij /* How can this happen? */ 1154330106Sdelphij DPRINTF(2, ("receive: 3454 check: AUTH_UNKNOWN from %s\n", 1155330106Sdelphij stoa(&rbufp->recv_srcadr))); 1156330106Sdelphij if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, 1157330106Sdelphij has_mac)) { 1158330106Sdelphij /* MAC invalid or not found */ 1159330106Sdelphij is_authentic = AUTH_ERROR; 1160330106Sdelphij } else { 1161330106Sdelphij is_authentic = AUTH_OK; 1162330106Sdelphij } 1163330106Sdelphij } 1164330106Sdelphij if (is_authentic != AUTH_OK) { 1165330106Sdelphij DPRINTF(2, ("receive: drop: missing or bad MAC from %s\n", 1166330106Sdelphij stoa(&rbufp->recv_srcadr))); 1167330106Sdelphij sys_restricted++; 1168330106Sdelphij return; /* drop: access denied */ 1169330106Sdelphij } 1170330106Sdelphij } 1171330106Sdelphij } 1172330106Sdelphij /**/ 1173330106Sdelphij 1174330106Sdelphij /* 1175330106Sdelphij ** On-Wire Protocol Layer 1176330106Sdelphij ** 1177330106Sdelphij ** Verify protocol operations consistent with the on-wire protocol. 1178330106Sdelphij ** The protocol discards bogus and duplicate packets as well as 1179330106Sdelphij ** minimizes disruptions doe to protocol restarts and dropped 1180330106Sdelphij ** packets. The operations are controlled by two timestamps: 1181330106Sdelphij ** the transmit timestamp saved in the client state variables, 1182330106Sdelphij ** and the origin timestamp in the server packet header. The 1183330106Sdelphij ** comparison of these two timestamps is called the loopback test. 1184330106Sdelphij ** The transmit timestamp functions as a nonce to verify that the 1185330106Sdelphij ** response corresponds to the original request. The transmit 1186330106Sdelphij ** timestamp also serves to discard replays of the most recent 1187330106Sdelphij ** packet. Upon failure of either test, the packet is discarded 1188330106Sdelphij ** with no further action. 1189330106Sdelphij */ 1190330106Sdelphij 1191330106Sdelphij /* 119282505Sroberto * The association matching rules are implemented by a set of 1193182007Sroberto * routines and an association table. A packet matching an 1194182007Sroberto * association is processed by the peer process for that 1195182007Sroberto * association. If there are no errors, an ephemeral association 1196182007Sroberto * is mobilized: a broadcast packet mobilizes a broadcast client 1197132454Sroberto * aassociation; a manycast server packet mobilizes a manycast 1198132454Sroberto * client association; a symmetric active packet mobilizes a 1199182007Sroberto * symmetric passive association. 120054359Sroberto */ 120154359Sroberto switch (retcode) { 1202182007Sroberto 1203182007Sroberto /* 1204182007Sroberto * This is a client mode packet not matching any association. If 1205182007Sroberto * an ordinary client, simply toss a server mode packet back 1206182007Sroberto * over the fence. If a manycast client, we have to work a 1207182007Sroberto * little harder. 1208330106Sdelphij * 1209330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1210182007Sroberto */ 121154359Sroberto case AM_FXMIT: 121254359Sroberto 121356749Sroberto /* 1214280849Scy * If authentication OK, send a server reply; otherwise, 1215280849Scy * send a crypto-NAK. 121656749Sroberto */ 1217182007Sroberto if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) { 1218330106Sdelphij /* HMS: would be nice to log FAST_XMIT|BADAUTH|RESTRICTED */ 1219330106Sdelphij record_raw_stats(&rbufp->recv_srcadr, 1220330106Sdelphij &rbufp->dstadr->sin, 1221330106Sdelphij &p_org, &p_rec, &p_xmt, &rbufp->recv_time, 1222330106Sdelphij PKT_LEAP(pkt->li_vn_mode), 1223330106Sdelphij PKT_VERSION(pkt->li_vn_mode), 1224330106Sdelphij PKT_MODE(pkt->li_vn_mode), 1225330106Sdelphij PKT_TO_STRATUM(pkt->stratum), 1226330106Sdelphij pkt->ppoll, 1227330106Sdelphij pkt->precision, 1228330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdelay)), 1229330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdisp)), 1230330106Sdelphij pkt->refid, 1231330106Sdelphij rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 1232330106Sdelphij 1233182007Sroberto if (AUTH(restrict_mask & RES_DONTTRUST, 1234280849Scy is_authentic)) { 1235182007Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 1236182007Sroberto restrict_mask); 1237280849Scy } else if (is_authentic == AUTH_ERROR) { 1238182007Sroberto fast_xmit(rbufp, MODE_SERVER, 0, 1239182007Sroberto restrict_mask); 1240280849Scy sys_badauth++; 1241280849Scy } else { 1242330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: !mcast restricted\n")); 1243280849Scy sys_restricted++; 1244280849Scy } 1245330106Sdelphij 1246182007Sroberto return; /* hooray */ 124756749Sroberto } 124854359Sroberto 124956749Sroberto /* 1250182007Sroberto * This must be manycast. Do not respond if not 1251182007Sroberto * configured as a manycast server. 125256749Sroberto */ 1253182007Sroberto if (!sys_manycastserver) { 1254330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: Not manycastserver\n")); 1255182007Sroberto sys_restricted++; 1256182007Sroberto return; /* not enabled */ 1257182007Sroberto } 1258182007Sroberto 1259280849Scy#ifdef AUTOKEY 1260182007Sroberto /* 1261280849Scy * Do not respond if not the same group. 1262182007Sroberto */ 1263280849Scy if (group_test(groupname, NULL)) { 1264330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: empty groupname\n")); 1265280849Scy sys_declined++; 1266280849Scy return; 1267280849Scy } 1268280849Scy#endif /* AUTOKEY */ 1269182007Sroberto 1270182007Sroberto /* 1271280849Scy * Do not respond if we are not synchronized or our 1272280849Scy * stratum is greater than the manycaster or the 1273280849Scy * manycaster has already synchronized to us. 1274182007Sroberto */ 1275289764Sglebius if ( sys_leap == LEAP_NOTINSYNC 1276289764Sglebius || sys_stratum >= hisstratum 1277289764Sglebius || (!sys_cohort && sys_stratum == hisstratum + 1) 1278289764Sglebius || rbufp->dstadr->addr_refid == pkt->refid) { 1279330106Sdelphij DPRINTF(2, ("receive: AM_FXMIT drop: LEAP_NOTINSYNC || stratum || loop\n")); 1280280849Scy sys_declined++; 1281182007Sroberto return; /* no help */ 1282280849Scy } 1283182007Sroberto 1284182007Sroberto /* 1285182007Sroberto * Respond only if authentication succeeds. Don't do a 1286182007Sroberto * crypto-NAK, as that would not be useful. 1287182007Sroberto */ 1288330106Sdelphij if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) { 1289330106Sdelphij record_raw_stats(&rbufp->recv_srcadr, 1290330106Sdelphij &rbufp->dstadr->sin, 1291330106Sdelphij &p_org, &p_rec, &p_xmt, &rbufp->recv_time, 1292330106Sdelphij PKT_LEAP(pkt->li_vn_mode), 1293330106Sdelphij PKT_VERSION(pkt->li_vn_mode), 1294330106Sdelphij PKT_MODE(pkt->li_vn_mode), 1295330106Sdelphij PKT_TO_STRATUM(pkt->stratum), 1296330106Sdelphij pkt->ppoll, 1297330106Sdelphij pkt->precision, 1298330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdelay)), 1299330106Sdelphij FPTOD(NTOHS_FP(pkt->rootdisp)), 1300330106Sdelphij pkt->refid, 1301330106Sdelphij rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 1302330106Sdelphij 130382505Sroberto fast_xmit(rbufp, MODE_SERVER, skeyid, 130482505Sroberto restrict_mask); 1305330106Sdelphij } 1306182007Sroberto return; /* hooray */ 1307182007Sroberto 1308182007Sroberto /* 1309182007Sroberto * This is a server mode packet returned in response to a client 1310280849Scy * mode packet sent to a multicast group address (for 1311280849Scy * manycastclient) or to a unicast address (for pool). The 1312280849Scy * origin timestamp is a good nonce to reliably associate the 1313280849Scy * reply with what was sent. If there is no match, that's 1314280849Scy * curious and could be an intruder attempting to clog, so we 1315280849Scy * just ignore it. 1316182007Sroberto * 1317282408Scy * If the packet is authentic and the manycastclient or pool 1318280849Scy * association is found, we mobilize a client association and 1319280849Scy * copy pertinent variables from the manycastclient or pool 1320280849Scy * association to the new client association. If not, just 1321280849Scy * ignore the packet. 1322182007Sroberto * 1323182007Sroberto * There is an implosion hazard at the manycast client, since 1324182007Sroberto * the manycast servers send the server packet immediately. If 1325182007Sroberto * the guy is already here, don't fire up a duplicate. 1326330106Sdelphij * 1327330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1328182007Sroberto */ 132954359Sroberto case AM_MANYCAST: 133054359Sroberto 1331280849Scy#ifdef AUTOKEY 1332280849Scy /* 1333280849Scy * Do not respond if not the same group. 1334280849Scy */ 1335280849Scy if (group_test(groupname, NULL)) { 1336330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: empty groupname\n")); 1337280849Scy sys_declined++; 1338280849Scy return; 1339280849Scy } 1340280849Scy#endif /* AUTOKEY */ 1341182007Sroberto if ((peer2 = findmanycastpeer(rbufp)) == NULL) { 1342330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: No manycast peer\n")); 1343132454Sroberto sys_restricted++; 1344182007Sroberto return; /* not enabled */ 1345132454Sroberto } 1346289764Sglebius if (!AUTH( (!(peer2->cast_flags & MDF_POOL) 1347289764Sglebius && sys_authenticate) 1348289764Sglebius || (restrict_mask & (RES_NOPEER | 1349330106Sdelphij RES_DONTTRUST)), is_authentic) 1350330106Sdelphij /* MC: RES_NOEPEER? */ 1351330106Sdelphij ) { 1352330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: bad auth || (NOPEER|DONTTRUST)\n")); 1353280849Scy sys_restricted++; 1354280849Scy return; /* access denied */ 1355280849Scy } 1356132454Sroberto 1357132454Sroberto /* 1358280849Scy * Do not respond if unsynchronized or stratum is below 1359280849Scy * the floor or at or above the ceiling. 1360132454Sroberto */ 1361289764Sglebius if ( hisleap == LEAP_NOTINSYNC 1362289764Sglebius || hisstratum < sys_floor 1363289764Sglebius || hisstratum >= sys_ceiling) { 1364330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: unsync/stratum\n")); 1365280849Scy sys_declined++; 1366280849Scy return; /* no help */ 1367280849Scy } 1368280849Scy peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr, 1369330106Sdelphij r4a.ippeerlimit, MODE_CLIENT, hisversion, 1370330106Sdelphij peer2->minpoll, peer2->maxpoll, 1371330106Sdelphij FLAG_PREEMPT | (FLAG_IBURST & peer2->flags), 1372330106Sdelphij MDF_UCAST | MDF_UCLNT, 0, skeyid, sys_ident); 1373280849Scy if (NULL == peer) { 1374330106Sdelphij DPRINTF(2, ("receive: AM_MANYCAST drop: duplicate\n")); 1375280849Scy sys_declined++; 1376280849Scy return; /* ignore duplicate */ 1377280849Scy } 137856749Sroberto 1379280849Scy /* 1380280849Scy * After each ephemeral pool association is spun, 1381280849Scy * accelerate the next poll for the pool solicitor so 1382280849Scy * the pool will fill promptly. 1383280849Scy */ 1384280849Scy if (peer2->cast_flags & MDF_POOL) 1385280849Scy peer2->nextdate = current_time + 1; 1386280849Scy 1387280849Scy /* 1388280849Scy * Further processing of the solicitation response would 1389280849Scy * simply detect its origin timestamp as bogus for the 1390280849Scy * brand-new association (it matches the prototype 1391280849Scy * association) and tinker with peer->nextdate delaying 1392280849Scy * first sync. 1393280849Scy */ 1394280849Scy return; /* solicitation response handled */ 1395280849Scy 1396182007Sroberto /* 1397182007Sroberto * This is the first packet received from a broadcast server. If 1398182007Sroberto * the packet is authentic and we are enabled as broadcast 1399182007Sroberto * client, mobilize a broadcast client association. We don't 1400182007Sroberto * kiss any frogs here. 1401330106Sdelphij * 1402330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1403182007Sroberto */ 1404182007Sroberto case AM_NEWBCL: 1405280849Scy 1406280849Scy#ifdef AUTOKEY 1407280849Scy /* 1408280849Scy * Do not respond if not the same group. 1409280849Scy */ 1410280849Scy if (group_test(groupname, sys_ident)) { 1411330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: groupname mismatch\n")); 1412280849Scy sys_declined++; 1413280849Scy return; 1414280849Scy } 1415280849Scy#endif /* AUTOKEY */ 1416280849Scy if (sys_bclient == 0) { 1417330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: not a bclient\n")); 1418280849Scy sys_restricted++; 1419280849Scy return; /* not enabled */ 1420280849Scy } 1421182007Sroberto if (!AUTH(sys_authenticate | (restrict_mask & 1422330106Sdelphij (RES_NOPEER | RES_DONTTRUST)), is_authentic) 1423330106Sdelphij /* NEWBCL: RES_NOEPEER? */ 1424330106Sdelphij ) { 1425330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: AUTH failed\n")); 1426280849Scy sys_restricted++; 1427280849Scy return; /* access denied */ 1428280849Scy } 142954359Sroberto 143056749Sroberto /* 1431182007Sroberto * Do not respond if unsynchronized or stratum is below 1432182007Sroberto * the floor or at or above the ceiling. 143356749Sroberto */ 1434289764Sglebius if ( hisleap == LEAP_NOTINSYNC 1435289764Sglebius || hisstratum < sys_floor 1436289764Sglebius || hisstratum >= sys_ceiling) { 1437330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Unsync or bad stratum\n")); 1438280849Scy sys_declined++; 1439280849Scy return; /* no help */ 1440280849Scy } 1441132454Sroberto 1442280849Scy#ifdef AUTOKEY 144356749Sroberto /* 1444280849Scy * Do not respond if Autokey and the opcode is not a 1445280849Scy * CRYPTO_ASSOC response with association ID. 144656749Sroberto */ 1447289764Sglebius if ( crypto_flags && skeyid > NTP_MAXKEY 1448289764Sglebius && (opcode & 0xffff0000) != (CRYPTO_ASSOC | CRYPTO_RESP)) { 1449330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not CRYPTO_ASSOC\n")); 1450280849Scy sys_declined++; 1451280849Scy return; /* protocol error */ 1452280849Scy } 1453280849Scy#endif /* AUTOKEY */ 145482505Sroberto 1455132454Sroberto /* 1456280849Scy * Broadcasts received via a multicast address may 1457280849Scy * arrive after a unicast volley has begun 1458280849Scy * with the same remote address. newpeer() will not 1459280849Scy * find duplicate associations on other local endpoints 1460280849Scy * if a non-NULL endpoint is supplied. multicastclient 1461280849Scy * ephemeral associations are unique across all local 1462280849Scy * endpoints. 1463132454Sroberto */ 1464280849Scy if (!(INT_MCASTOPEN & rbufp->dstadr->flags)) 1465280849Scy match_ep = rbufp->dstadr; 1466280849Scy else 1467280849Scy match_ep = NULL; 146856749Sroberto 1469132454Sroberto /* 1470280849Scy * Determine whether to execute the initial volley. 147156749Sroberto */ 1472298695Sdelphij if (sys_bdelay > 0.0) { 1473280849Scy#ifdef AUTOKEY 1474182007Sroberto /* 1475182007Sroberto * If a two-way exchange is not possible, 1476182007Sroberto * neither is Autokey. 1477182007Sroberto */ 1478280849Scy if (crypto_flags && skeyid > NTP_MAXKEY) { 1479280849Scy sys_restricted++; 1480330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not 2-way\n")); 1481182007Sroberto return; /* no autokey */ 1482182007Sroberto } 1483280849Scy#endif /* AUTOKEY */ 1484280849Scy 1485280849Scy /* 1486280849Scy * Do not execute the volley. Start out in 1487280849Scy * broadcast client mode. 1488280849Scy */ 1489330106Sdelphij peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, 1490330106Sdelphij r4a.ippeerlimit, MODE_BCLIENT, hisversion, 1491330106Sdelphij pkt->ppoll, pkt->ppoll, 1492330106Sdelphij FLAG_PREEMPT, MDF_BCLNT, 0, skeyid, sys_ident); 1493280849Scy if (NULL == peer) { 1494330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: duplicate\n")); 1495280849Scy sys_restricted++; 1496280849Scy return; /* ignore duplicate */ 1497280849Scy 1498280849Scy } else { 1499280849Scy peer->delay = sys_bdelay; 1500294554Sdelphij peer->bxmt = p_xmt; 1501280849Scy } 1502280849Scy break; 1503132454Sroberto } 150456749Sroberto 1505280849Scy /* 1506280849Scy * Execute the initial volley in order to calibrate the 1507280849Scy * propagation delay and run the Autokey protocol. 1508280849Scy * 1509280849Scy * Note that the minpoll is taken from the broadcast 1510280849Scy * packet, normally 6 (64 s) and that the poll interval 1511280849Scy * is fixed at this value. 1512280849Scy */ 1513280849Scy peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep, 1514330106Sdelphij r4a.ippeerlimit, MODE_CLIENT, hisversion, 1515330106Sdelphij pkt->ppoll, pkt->ppoll, 1516280849Scy FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT, 1517280849Scy 0, skeyid, sys_ident); 1518280849Scy if (NULL == peer) { 1519330106Sdelphij DPRINTF(2, ("receive: AM_NEWBCL drop: empty newpeer() failed\n")); 1520280849Scy sys_restricted++; 1521280849Scy return; /* ignore duplicate */ 1522280849Scy } 1523294554Sdelphij peer->bxmt = p_xmt; 1524280849Scy#ifdef AUTOKEY 1525280849Scy if (skeyid > NTP_MAXKEY) 1526280849Scy crypto_recv(peer, rbufp); 1527280849Scy#endif /* AUTOKEY */ 1528280849Scy 1529280849Scy return; /* hooray */ 1530280849Scy 1531182007Sroberto /* 1532182007Sroberto * This is the first packet received from a symmetric active 1533330106Sdelphij * peer. If the packet is authentic, the first he sent, and 1534330106Sdelphij * RES_NOEPEER is not enabled, mobilize a passive association 1535330106Sdelphij * If not, kiss the frog. 1536330106Sdelphij * 1537330106Sdelphij * There are cases here where we do not call record_raw_stats(). 1538182007Sroberto */ 1539182007Sroberto case AM_NEWPASS: 154056749Sroberto 1541280849Scy#ifdef AUTOKEY 154256749Sroberto /* 1543280849Scy * Do not respond if not the same group. 154456749Sroberto */ 1545280849Scy if (group_test(groupname, sys_ident)) { 1546330106Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n")); 1547280849Scy sys_declined++; 1548280849Scy return; 1549280849Scy } 1550280849Scy#endif /* AUTOKEY */ 1551280849Scy if (!AUTH(sys_authenticate | (restrict_mask & 1552330106Sdelphij (RES_NOPEER | RES_DONTTRUST)), is_authentic) 1553330106Sdelphij ) { 1554330106Sdelphij if (0 == (restrict_mask & RES_NOEPEER)) { 1555330106Sdelphij /* 1556330106Sdelphij * If authenticated but cannot mobilize an 1557330106Sdelphij * association, send a symmetric passive 1558330106Sdelphij * response without mobilizing an association. 1559330106Sdelphij * This is for drat broken Windows clients. See 1560330106Sdelphij * Microsoft KB 875424 for preferred workaround. 1561330106Sdelphij */ 1562330106Sdelphij if (AUTH(restrict_mask & RES_DONTTRUST, 1563330106Sdelphij is_authentic)) { 1564330106Sdelphij fast_xmit(rbufp, MODE_PASSIVE, skeyid, 1565330106Sdelphij restrict_mask); 1566330106Sdelphij return; /* hooray */ 1567330106Sdelphij } 1568330106Sdelphij if (is_authentic == AUTH_ERROR) { 1569330106Sdelphij fast_xmit(rbufp, MODE_ACTIVE, 0, 1570330106Sdelphij restrict_mask); 1571330106Sdelphij sys_restricted++; 1572330106Sdelphij return; 1573330106Sdelphij } 1574280849Scy } 1575289764Sglebius /* [Bug 2941] 1576289764Sglebius * If we got here, the packet isn't part of an 1577330106Sdelphij * existing association, either isn't correctly 1578330106Sdelphij * authenticated or it is but we are refusing 1579330106Sdelphij * ephemeral peer requests, and it didn't meet 1580330106Sdelphij * either of the previous two special cases so we 1581330106Sdelphij * should just drop it on the floor. For example, 1582289764Sglebius * crypto-NAKs (is_authentic == AUTH_CRYPTO) 1583289764Sglebius * will make it this far. This is just 1584289764Sglebius * debug-printed and not logged to avoid log 1585289764Sglebius * flooding. 1586289764Sglebius */ 1587293423Sdelphij DPRINTF(2, ("receive: at %ld refusing to mobilize passive association" 1588293423Sdelphij " with unknown peer %s mode %d/%s:%s keyid %08x len %d auth %d\n", 1589289764Sglebius current_time, stoa(&rbufp->recv_srcadr), 1590293423Sdelphij hismode, hm_str, am_str, skeyid, 1591293423Sdelphij (authlen + has_mac), is_authentic)); 1592289764Sglebius sys_declined++; 1593289764Sglebius return; 1594182007Sroberto } 1595280849Scy 1596280849Scy /* 1597280849Scy * Do not respond if synchronized and if stratum is 1598280849Scy * below the floor or at or above the ceiling. Note, 1599280849Scy * this allows an unsynchronized peer to synchronize to 1600280849Scy * us. It would be very strange if he did and then was 1601280849Scy * nipped, but that could only happen if we were 1602280849Scy * operating at the top end of the range. It also means 1603280849Scy * we will spin an ephemeral association in response to 1604280849Scy * MODE_ACTIVE KoDs, which will time out eventually. 1605280849Scy */ 1606289764Sglebius if ( hisleap != LEAP_NOTINSYNC 1607289764Sglebius && (hisstratum < sys_floor || hisstratum >= sys_ceiling)) { 1608330106Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n")); 1609280849Scy sys_declined++; 1610280849Scy return; /* no help */ 1611182007Sroberto } 161254359Sroberto 1613182007Sroberto /* 1614280849Scy * The message is correctly authenticated and allowed. 1615330106Sdelphij * Mobilize a symmetric passive association, if we won't 1616330106Sdelphij * exceed the ippeerlimit. 1617182007Sroberto */ 1618330106Sdelphij if ((peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr, 1619330106Sdelphij r4a.ippeerlimit, MODE_PASSIVE, hisversion, 1620330106Sdelphij pkt->ppoll, NTP_MAXDPOLL, 0, MDF_UCAST, 0, 1621330106Sdelphij skeyid, sys_ident)) == NULL) { 1622330106Sdelphij DPRINTF(2, ("receive: AM_NEWPASS drop: newpeer() failed\n")); 1623280849Scy sys_declined++; 1624280849Scy return; /* ignore duplicate */ 1625280849Scy } 1626182007Sroberto break; 1627182007Sroberto 1628280849Scy 162954359Sroberto /* 1630182007Sroberto * Process regular packet. Nothing special. 1631330106Sdelphij * 1632330106Sdelphij * There are cases here where we do not call record_raw_stats(). 163354359Sroberto */ 1634182007Sroberto case AM_PROCPKT: 1635280849Scy 1636280849Scy#ifdef AUTOKEY 1637280849Scy /* 1638280849Scy * Do not respond if not the same group. 1639280849Scy */ 1640280849Scy if (group_test(groupname, peer->ident)) { 1641330106Sdelphij DPRINTF(2, ("receive: AM_PROCPKT drop: Autokey group mismatch\n")); 1642280849Scy sys_declined++; 1643280849Scy return; 1644280849Scy } 1645280849Scy#endif /* AUTOKEY */ 1646294554Sdelphij 1647294554Sdelphij if (MODE_BROADCAST == hismode) { 1648298695Sdelphij int bail = 0; 1649298695Sdelphij l_fp tdiff; 1650298695Sdelphij u_long deadband; 1651294554Sdelphij 1652294554Sdelphij DPRINTF(2, ("receive: PROCPKT/BROADCAST: prev pkt %ld seconds ago, ppoll: %d, %d secs\n", 1653294554Sdelphij (current_time - peer->timelastrec), 1654294554Sdelphij peer->ppoll, (1 << peer->ppoll) 1655294554Sdelphij )); 1656294554Sdelphij /* Things we can check: 1657294554Sdelphij * 1658294554Sdelphij * Did the poll interval change? 1659294554Sdelphij * Is the poll interval in the packet in-range? 1660294554Sdelphij * Did this packet arrive too soon? 1661294554Sdelphij * Is the timestamp in this packet monotonic 1662294554Sdelphij * with respect to the previous packet? 1663294554Sdelphij */ 1664294554Sdelphij 1665294554Sdelphij /* This is noteworthy, not error-worthy */ 1666294554Sdelphij if (pkt->ppoll != peer->ppoll) { 1667330106Sdelphij msyslog(LOG_INFO, "receive: broadcast poll from %s changed from %u to %u", 1668294554Sdelphij stoa(&rbufp->recv_srcadr), 1669294554Sdelphij peer->ppoll, pkt->ppoll); 1670294554Sdelphij } 1671294554Sdelphij 1672294554Sdelphij /* This is error-worthy */ 1673298695Sdelphij if (pkt->ppoll < peer->minpoll || 1674298695Sdelphij pkt->ppoll > peer->maxpoll ) { 1675330106Sdelphij msyslog(LOG_INFO, "receive: broadcast poll of %u from %s is out-of-range (%d to %d)!", 1676294554Sdelphij pkt->ppoll, stoa(&rbufp->recv_srcadr), 1677294554Sdelphij peer->minpoll, peer->maxpoll); 1678294554Sdelphij ++bail; 1679294554Sdelphij } 1680294554Sdelphij 1681309007Sdelphij /* too early? worth an error, too! 1682309007Sdelphij * 1683309007Sdelphij * [Bug 3113] Ensure that at least one poll 1684309007Sdelphij * interval has elapsed since the last **clean** 1685309007Sdelphij * packet was received. We limit the check to 1686309007Sdelphij * **clean** packets to prevent replayed packets 1687309007Sdelphij * and incorrectly authenticated packets, which 1688309007Sdelphij * we'll discard, from being used to create a 1689309007Sdelphij * denial of service condition. 1690309007Sdelphij */ 1691298695Sdelphij deadband = (1u << pkt->ppoll); 1692298695Sdelphij if (FLAG_BC_VOL & peer->flags) 1693298695Sdelphij deadband -= 3; /* allow greater fuzz after volley */ 1694309007Sdelphij if ((current_time - peer->timereceived) < deadband) { 1695298695Sdelphij msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after %lu, not %lu seconds!", 1696294554Sdelphij stoa(&rbufp->recv_srcadr), 1697309007Sdelphij (current_time - peer->timereceived), 1698298695Sdelphij deadband); 1699294554Sdelphij ++bail; 1700294554Sdelphij } 1701294554Sdelphij 1702309007Sdelphij /* Alert if time from the server is non-monotonic. 1703309007Sdelphij * 1704309007Sdelphij * [Bug 3114] is about Broadcast mode replay DoS. 1705309007Sdelphij * 1706309007Sdelphij * Broadcast mode *assumes* a trusted network. 1707309007Sdelphij * Even so, it's nice to be robust in the face 1708309007Sdelphij * of attacks. 1709309007Sdelphij * 1710309007Sdelphij * If we get an authenticated broadcast packet 1711309007Sdelphij * with an "earlier" timestamp, it means one of 1712309007Sdelphij * two things: 1713309007Sdelphij * 1714309007Sdelphij * - the broadcast server had a backward step. 1715309007Sdelphij * 1716309007Sdelphij * - somebody is trying a replay attack. 1717309007Sdelphij * 1718309007Sdelphij * deadband: By default, we assume the broadcast 1719309007Sdelphij * network is trustable, so we take our accepted 1720309007Sdelphij * broadcast packets as we receive them. But 1721309007Sdelphij * some folks might want to take additional poll 1722309007Sdelphij * delays before believing a backward step. 1723309007Sdelphij */ 1724309007Sdelphij if (sys_bcpollbstep) { 1725309007Sdelphij /* pkt->ppoll or peer->ppoll ? */ 1726309007Sdelphij deadband = (1u << pkt->ppoll) 1727309007Sdelphij * sys_bcpollbstep + 2; 1728309007Sdelphij } else { 1729309007Sdelphij deadband = 0; 1730309007Sdelphij } 1731309007Sdelphij 1732309007Sdelphij if (L_ISZERO(&peer->bxmt)) { 1733309007Sdelphij tdiff.l_ui = tdiff.l_uf = 0; 1734309007Sdelphij } else { 1735309007Sdelphij tdiff = p_xmt; 1736309007Sdelphij L_SUB(&tdiff, &peer->bxmt); 1737309007Sdelphij } 1738309007Sdelphij if (tdiff.l_i < 0 && 1739309007Sdelphij (current_time - peer->timereceived) < deadband) 1740309007Sdelphij { 1741294554Sdelphij msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x", 1742294554Sdelphij stoa(&rbufp->recv_srcadr), 1743294554Sdelphij peer->bxmt.l_ui, peer->bxmt.l_uf, 1744294554Sdelphij p_xmt.l_ui, p_xmt.l_uf 1745294554Sdelphij ); 1746294554Sdelphij ++bail; 1747294554Sdelphij } 1748294554Sdelphij 1749294554Sdelphij if (bail) { 1750330106Sdelphij DPRINTF(2, ("receive: AM_PROCPKT drop: bail\n")); 1751294554Sdelphij peer->timelastrec = current_time; 1752294554Sdelphij sys_declined++; 1753294554Sdelphij return; 1754294554Sdelphij } 1755294554Sdelphij } 1756294554Sdelphij 1757182007Sroberto break; 175854359Sroberto 175954359Sroberto /* 1760182007Sroberto * A passive packet matches a passive association. This is 1761182007Sroberto * usually the result of reconfiguring a client on the fly. As 1762280849Scy * this association might be legitimate and this packet an 1763182007Sroberto * attempt to deny service, just ignore it. 176454359Sroberto */ 1765182007Sroberto case AM_ERR: 1766330106Sdelphij DPRINTF(2, ("receive: AM_ERR drop.\n")); 1767280849Scy sys_declined++; 1768182007Sroberto return; 1769132454Sroberto 1770132454Sroberto /* 1771182007Sroberto * For everything else there is the bit bucket. 1772132454Sroberto */ 1773182007Sroberto default: 1774330106Sdelphij DPRINTF(2, ("receive: default drop.\n")); 1775280849Scy sys_declined++; 1776182007Sroberto return; 1777182007Sroberto } 1778280849Scy 1779280849Scy#ifdef AUTOKEY 1780280849Scy /* 1781280849Scy * If the association is configured for Autokey, the packet must 1782280849Scy * have a public key ID; if not, the packet must have a 1783280849Scy * symmetric key ID. 1784280849Scy */ 1785289764Sglebius if ( is_authentic != AUTH_CRYPTO 1786289764Sglebius && ( ((peer->flags & FLAG_SKEY) && skeyid <= NTP_MAXKEY) 1787289764Sglebius || (!(peer->flags & FLAG_SKEY) && skeyid > NTP_MAXKEY))) { 1788330106Sdelphij DPRINTF(2, ("receive: drop: Autokey but wrong/bad auth\n")); 1789280849Scy sys_badauth++; 1790280849Scy return; 1791280849Scy } 1792280849Scy#endif /* AUTOKEY */ 1793298695Sdelphij 1794280849Scy peer->received++; 1795182007Sroberto peer->flash &= ~PKT_TEST_MASK; 1796280849Scy if (peer->flags & FLAG_XBOGUS) { 1797280849Scy peer->flags &= ~FLAG_XBOGUS; 1798280849Scy peer->flash |= TEST3; 1799280849Scy } 1800132454Sroberto 1801132454Sroberto /* 1802182007Sroberto * Next comes a rigorous schedule of timestamp checking. If the 1803280849Scy * transmit timestamp is zero, the server has not initialized in 1804280849Scy * interleaved modes or is horribly broken. 1805298695Sdelphij * 1806298695Sdelphij * A KoD packet we pay attention to cannot have a 0 transmit 1807298695Sdelphij * timestamp. 1808132454Sroberto */ 1809330106Sdelphij 1810330106Sdelphij kissCode = kiss_code_check(hisleap, hisstratum, hismode, pkt->refid); 1811330106Sdelphij 1812182007Sroberto if (L_ISZERO(&p_xmt)) { 1813280849Scy peer->flash |= TEST3; /* unsynch */ 1814330106Sdelphij if (kissCode != NOKISS) { /* KoD packet */ 1815298695Sdelphij peer->bogusorg++; /* for TEST2 or TEST3 */ 1816298695Sdelphij msyslog(LOG_INFO, 1817298695Sdelphij "receive: Unexpected zero transmit timestamp in KoD from %s", 1818298695Sdelphij ntoa(&peer->srcadr)); 1819298695Sdelphij return; 1820298695Sdelphij } 1821132454Sroberto 1822132454Sroberto /* 1823298695Sdelphij * If the transmit timestamp duplicates our previous one, the 1824182007Sroberto * packet is a replay. This prevents the bad guys from replaying 1825182007Sroberto * the most recent packet, authenticated or not. 1826132454Sroberto */ 1827280849Scy } else if (L_ISEQU(&peer->xmt, &p_xmt)) { 1828330106Sdelphij DPRINTF(2, ("receive: drop: Duplicate xmit\n")); 1829280849Scy peer->flash |= TEST1; /* duplicate */ 1830182007Sroberto peer->oldpkt++; 1831280849Scy return; 1832132454Sroberto 1833132454Sroberto /* 1834301247Sdelphij * If this is a broadcast mode packet, make sure hisstratum 1835301247Sdelphij * is appropriate. Don't do anything else here - we wait to 1836301247Sdelphij * see if this is an interleave broadcast packet until after 1837301247Sdelphij * we've validated the MAC that SHOULD be provided. 1838301247Sdelphij * 1839330106Sdelphij * hisstratum cannot be 0 - see assertion above. 1840301247Sdelphij * If hisstratum is 15, then we'll advertise as UNSPEC but 1841301247Sdelphij * at least we'll be able to sync with the broadcast server. 1842132454Sroberto */ 1843280849Scy } else if (hismode == MODE_BROADCAST) { 1844330106Sdelphij /* 0 is unexpected too, and impossible */ 1845330106Sdelphij if (STRATUM_UNSPEC <= hisstratum) { 1846301247Sdelphij /* Is this a ++sys_declined or ??? */ 1847301247Sdelphij msyslog(LOG_INFO, 1848301247Sdelphij "receive: Unexpected stratum (%d) in broadcast from %s", 1849301247Sdelphij hisstratum, ntoa(&peer->srcadr)); 1850280849Scy return; 1851280849Scy } 1852132454Sroberto 1853132454Sroberto /* 1854298695Sdelphij * Basic KoD validation checking: 1855298695Sdelphij * 1856298695Sdelphij * KoD packets are a mixed-blessing. Forged KoD packets 1857298695Sdelphij * are DoS attacks. There are rare situations where we might 1858298695Sdelphij * get a valid KoD response, though. Since KoD packets are 1859298695Sdelphij * a special case that complicate the checks we do next, we 1860298695Sdelphij * handle the basic KoD checks here. 1861298695Sdelphij * 1862298695Sdelphij * Note that we expect the incoming KoD packet to have its 1863298695Sdelphij * (nonzero) org, rec, and xmt timestamps set to the xmt timestamp 1864298695Sdelphij * that we have previously sent out. Watch interleave mode. 1865298695Sdelphij */ 1866330106Sdelphij } else if (kissCode != NOKISS) { 1867298695Sdelphij DEBUG_INSIST(!L_ISZERO(&p_xmt)); 1868298695Sdelphij if ( L_ISZERO(&p_org) /* We checked p_xmt above */ 1869298695Sdelphij || L_ISZERO(&p_rec)) { 1870298695Sdelphij peer->bogusorg++; 1871298695Sdelphij msyslog(LOG_INFO, 1872298695Sdelphij "receive: KoD packet from %s has a zero org or rec timestamp. Ignoring.", 1873298695Sdelphij ntoa(&peer->srcadr)); 1874298695Sdelphij return; 1875298695Sdelphij } 1876298695Sdelphij 1877298695Sdelphij if ( !L_ISEQU(&p_xmt, &p_org) 1878298695Sdelphij || !L_ISEQU(&p_xmt, &p_rec)) { 1879298695Sdelphij peer->bogusorg++; 1880298695Sdelphij msyslog(LOG_INFO, 1881298695Sdelphij "receive: KoD packet from %s has inconsistent xmt/org/rec timestamps. Ignoring.", 1882298695Sdelphij ntoa(&peer->srcadr)); 1883298695Sdelphij return; 1884298695Sdelphij } 1885298695Sdelphij 1886298695Sdelphij /* Be conservative */ 1887298695Sdelphij if (peer->flip == 0 && !L_ISEQU(&p_org, &peer->aorg)) { 1888298695Sdelphij peer->bogusorg++; 1889298695Sdelphij msyslog(LOG_INFO, 1890298695Sdelphij "receive: flip 0 KoD origin timestamp %#010x.%08x from %s does not match %#010x.%08x - ignoring.", 1891298695Sdelphij p_org.l_ui, p_org.l_uf, 1892298695Sdelphij ntoa(&peer->srcadr), 1893298695Sdelphij peer->aorg.l_ui, peer->aorg.l_uf); 1894298695Sdelphij return; 1895298695Sdelphij } else if (peer->flip == 1 && !L_ISEQU(&p_org, &peer->borg)) { 1896298695Sdelphij peer->bogusorg++; 1897298695Sdelphij msyslog(LOG_INFO, 1898298695Sdelphij "receive: flip 1 KoD origin timestamp %#010x.%08x from %s does not match interleave %#010x.%08x - ignoring.", 1899298695Sdelphij p_org.l_ui, p_org.l_uf, 1900298695Sdelphij ntoa(&peer->srcadr), 1901298695Sdelphij peer->borg.l_ui, peer->borg.l_uf); 1902298695Sdelphij return; 1903298695Sdelphij } 1904309007Sdelphij 1905298695Sdelphij /* 1906293423Sdelphij * Basic mode checks: 1907289764Sglebius * 1908294554Sdelphij * If there is no origin timestamp, it's either an initial packet 1909294554Sdelphij * or we've already received a response to our query. Of course, 1910294554Sdelphij * should 'aorg' be all-zero because this really was the original 1911298695Sdelphij * transmit timestamp, we'll ignore this reply. There is a window 1912298695Sdelphij * of one nanosecond once every 136 years' time where this is 1913330106Sdelphij * possible. We currently ignore this situation, as a completely 1914330106Sdelphij * zero timestamp is (quietly?) disallowed. 1915293423Sdelphij * 1916293423Sdelphij * Otherwise, check for bogus packet in basic mode. 1917293423Sdelphij * If it is bogus, switch to interleaved mode and resynchronize, 1918293423Sdelphij * but only after confirming the packet is not bogus in 1919293423Sdelphij * symmetric interleaved mode. 1920293423Sdelphij * 1921289764Sglebius * This could also mean somebody is forging packets claiming to 1922289764Sglebius * be from us, attempting to cause our server to KoD us. 1923330106Sdelphij * 1924330106Sdelphij * We have earlier asserted that hisstratum cannot be 0. 1925330106Sdelphij * If hisstratum is STRATUM_UNSPEC, it means he's not sync'd. 1926132454Sroberto */ 1927280849Scy } else if (peer->flip == 0) { 1928298695Sdelphij if (0) { 1929298695Sdelphij } else if (L_ISZERO(&p_org)) { 1930316068Sdelphij const char *action; 1931309007Sdelphij 1932316068Sdelphij#ifdef BUG3361 1933316068Sdelphij msyslog(LOG_INFO, 1934316068Sdelphij "receive: BUG 3361: Clearing peer->aorg "); 1935309007Sdelphij L_CLR(&peer->aorg); 1936316068Sdelphij#endif 1937309007Sdelphij /**/ 1938309007Sdelphij switch (hismode) { 1939309007Sdelphij /* We allow 0org for: */ 1940309007Sdelphij case UCHAR_MAX: 1941309007Sdelphij action = "Allow"; 1942309007Sdelphij break; 1943309007Sdelphij /* We disallow 0org for: */ 1944309007Sdelphij case MODE_UNSPEC: 1945309007Sdelphij case MODE_ACTIVE: 1946309007Sdelphij case MODE_PASSIVE: 1947309007Sdelphij case MODE_CLIENT: 1948309007Sdelphij case MODE_SERVER: 1949309007Sdelphij case MODE_BROADCAST: 1950309007Sdelphij action = "Drop"; 1951309007Sdelphij peer->bogusorg++; 1952309007Sdelphij peer->flash |= TEST2; /* bogus */ 1953309007Sdelphij break; 1954309007Sdelphij default: 1955316068Sdelphij action = ""; /* for cranky compilers / MSVC */ 1956309007Sdelphij INSIST(!"receive(): impossible hismode"); 1957309007Sdelphij break; 1958309007Sdelphij } 1959309007Sdelphij /**/ 1960298695Sdelphij msyslog(LOG_INFO, 1961309007Sdelphij "receive: %s 0 origin timestamp from %s@%s xmt %#010x.%08x", 1962309007Sdelphij action, hm_str, ntoa(&peer->srcadr), 1963298695Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)); 1964298695Sdelphij } else if (!L_ISEQU(&p_org, &peer->aorg)) { 1965298695Sdelphij /* are there cases here where we should bail? */ 1966298695Sdelphij /* Should we set TEST2 if we decide to try xleave? */ 1967280849Scy peer->bogusorg++; 1968280849Scy peer->flash |= TEST2; /* bogus */ 1969289764Sglebius msyslog(LOG_INFO, 1970298695Sdelphij "receive: Unexpected origin timestamp %#010x.%08x does not match aorg %#010x.%08x from %s@%s xmt %#010x.%08x", 1971293423Sdelphij ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), 1972298695Sdelphij peer->aorg.l_ui, peer->aorg.l_uf, 1973298695Sdelphij hm_str, ntoa(&peer->srcadr), 1974293423Sdelphij ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)); 1975289764Sglebius if ( !L_ISZERO(&peer->dst) 1976289764Sglebius && L_ISEQU(&p_org, &peer->dst)) { 1977293423Sdelphij /* Might be the start of an interleave */ 1978298695Sdelphij if (dynamic_interleave) { 1979298695Sdelphij peer->flip = 1; 1980298695Sdelphij report_event(PEVNT_XLEAVE, peer, NULL); 1981298695Sdelphij } else { 1982298695Sdelphij msyslog(LOG_INFO, 1983298695Sdelphij "receive: Dynamic interleave from %s@%s denied", 1984298695Sdelphij hm_str, ntoa(&peer->srcadr)); 1985298695Sdelphij } 1986182007Sroberto } 1987280849Scy } else { 1988280849Scy L_CLR(&peer->aorg); 1989182007Sroberto } 1990280849Scy 1991280849Scy /* 1992280849Scy * Check for valid nonzero timestamp fields. 1993280849Scy */ 1994301247Sdelphij } else if ( L_ISZERO(&p_org) 1995301247Sdelphij || L_ISZERO(&p_rec) 1996301247Sdelphij || L_ISZERO(&peer->dst)) { 1997280849Scy peer->flash |= TEST3; /* unsynch */ 1998280849Scy 1999280849Scy /* 2000280849Scy * Check for bogus packet in interleaved symmetric mode. This 2001280849Scy * can happen if a packet is lost, duplicated or crossed. If 2002280849Scy * found, flip and resynchronize. 2003280849Scy */ 2004289764Sglebius } else if ( !L_ISZERO(&peer->dst) 2005289764Sglebius && !L_ISEQU(&p_org, &peer->dst)) { 2006330106Sdelphij DPRINTF(2, ("receive: drop: Bogus packet in interleaved symmetric mode\n")); 2007280849Scy peer->bogusorg++; 2008280849Scy peer->flags |= FLAG_XBOGUS; 2009280849Scy peer->flash |= TEST2; /* bogus */ 2010330106Sdelphij#ifdef BUG3453 2011289764Sglebius return; /* Bogus packet, we are done */ 2012330106Sdelphij#endif 2013182007Sroberto } 2014132454Sroberto 2015301247Sdelphij /**/ 2016301247Sdelphij 2017132454Sroberto /* 2018280849Scy * If this is a crypto_NAK, the server cannot authenticate a 2019280849Scy * client packet. The server might have just changed keys. Clear 2020280849Scy * the association and restart the protocol. 2021280849Scy */ 2022298695Sdelphij if (crypto_nak_test == VALIDNAK) { 2023280849Scy report_event(PEVNT_AUTH, peer, "crypto_NAK"); 2024280849Scy peer->flash |= TEST5; /* bad auth */ 2025280849Scy peer->badauth++; 2026280849Scy if (peer->flags & FLAG_PREEMPT) { 2027294554Sdelphij if (unpeer_crypto_nak_early) { 2028294554Sdelphij unpeer(peer); 2029294554Sdelphij } 2030330106Sdelphij DPRINTF(2, ("receive: drop: PREEMPT crypto_NAK\n")); 2031280849Scy return; 2032280849Scy } 2033280849Scy#ifdef AUTOKEY 2034301247Sdelphij if (peer->crypto) { 2035280849Scy peer_clear(peer, "AUTH"); 2036301247Sdelphij } 2037280849Scy#endif /* AUTOKEY */ 2038330106Sdelphij DPRINTF(2, ("receive: drop: crypto_NAK\n")); 2039280849Scy return; 2040182007Sroberto 2041282408Scy /* 2042282408Scy * If the digest fails or it's missing for authenticated 2043282408Scy * associations, the client cannot authenticate a server 2044280849Scy * reply to a client packet previously sent. The loopback check 2045280849Scy * is designed to avoid a bait-and-switch attack, which was 2046280849Scy * possible in past versions. If symmetric modes, return a 2047280849Scy * crypto-NAK. The peer should restart the protocol. 2048182007Sroberto */ 2049282408Scy } else if (!AUTH(peer->keyid || has_mac || 2050282408Scy (restrict_mask & RES_DONTTRUST), is_authentic)) { 2051301247Sdelphij 2052301247Sdelphij if (peer->flash & PKT_TEST_MASK) { 2053301247Sdelphij msyslog(LOG_INFO, 2054301247Sdelphij "receive: Bad auth in packet with bad timestamps from %s denied - spoof?", 2055301247Sdelphij ntoa(&peer->srcadr)); 2056301247Sdelphij return; 2057301247Sdelphij } 2058301247Sdelphij 2059280849Scy report_event(PEVNT_AUTH, peer, "digest"); 2060280849Scy peer->flash |= TEST5; /* bad auth */ 2061280849Scy peer->badauth++; 2062289764Sglebius if ( has_mac 2063301247Sdelphij && ( hismode == MODE_ACTIVE 2064301247Sdelphij || hismode == MODE_PASSIVE)) 2065132454Sroberto fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask); 2066280849Scy if (peer->flags & FLAG_PREEMPT) { 2067294554Sdelphij if (unpeer_digest_early) { 2068294554Sdelphij unpeer(peer); 2069294554Sdelphij } 2070280849Scy } 2071280849Scy#ifdef AUTOKEY 2072301247Sdelphij else if (peer_clear_digest_early && peer->crypto) { 2073280849Scy peer_clear(peer, "AUTH"); 2074301247Sdelphij } 2075280849Scy#endif /* AUTOKEY */ 2076330106Sdelphij DPRINTF(2, ("receive: drop: Bad or missing AUTH\n")); 2077280849Scy return; 207854359Sroberto } 207954359Sroberto 2080182007Sroberto /* 2081301247Sdelphij * For broadcast packets: 2082301247Sdelphij * 2083301247Sdelphij * HMS: This next line never made much sense to me, even 2084301247Sdelphij * when it was up higher: 2085301247Sdelphij * If an initial volley, bail out now and let the 2086301247Sdelphij * client do its stuff. 2087301247Sdelphij * 2088301247Sdelphij * If the packet has not failed authentication, then 2089301247Sdelphij * - if the origin timestamp is nonzero this is an 2090301247Sdelphij * interleaved broadcast, so restart the protocol. 2091301247Sdelphij * - else, this is not an interleaved broadcast packet. 2092282408Scy */ 2093301247Sdelphij if (hismode == MODE_BROADCAST) { 2094301247Sdelphij if ( is_authentic == AUTH_OK 2095301247Sdelphij || is_authentic == AUTH_NONE) { 2096301247Sdelphij if (!L_ISZERO(&p_org)) { 2097301247Sdelphij if (!(peer->flags & FLAG_XB)) { 2098301247Sdelphij msyslog(LOG_INFO, 2099301247Sdelphij "receive: Broadcast server at %s is in interleave mode", 2100301247Sdelphij ntoa(&peer->srcadr)); 2101301247Sdelphij peer->flags |= FLAG_XB; 2102301247Sdelphij peer->aorg = p_xmt; 2103301247Sdelphij peer->borg = rbufp->recv_time; 2104301247Sdelphij report_event(PEVNT_XLEAVE, peer, NULL); 2105301247Sdelphij return; 2106301247Sdelphij } 2107301247Sdelphij } else if (peer->flags & FLAG_XB) { 2108301247Sdelphij msyslog(LOG_INFO, 2109301247Sdelphij "receive: Broadcast server at %s is no longer in interleave mode", 2110301247Sdelphij ntoa(&peer->srcadr)); 2111301247Sdelphij peer->flags &= ~FLAG_XB; 2112301247Sdelphij } 2113301247Sdelphij } else { 2114301247Sdelphij msyslog(LOG_INFO, 2115301247Sdelphij "receive: Bad broadcast auth (%d) from %s", 2116301247Sdelphij is_authentic, ntoa(&peer->srcadr)); 2117301247Sdelphij } 2118309007Sdelphij 2119309007Sdelphij /* 2120309007Sdelphij * Now that we know the packet is correctly authenticated, 2121309007Sdelphij * update peer->bxmt. 2122309007Sdelphij */ 2123309007Sdelphij peer->bxmt = p_xmt; 2124301247Sdelphij } 2125301247Sdelphij 2126301247Sdelphij 2127301247Sdelphij /* 2128301247Sdelphij ** Update the state variables. 2129301247Sdelphij */ 2130282408Scy if (peer->flip == 0) { 2131282408Scy if (hismode != MODE_BROADCAST) 2132282408Scy peer->rec = p_xmt; 2133282408Scy peer->dst = rbufp->recv_time; 2134282408Scy } 2135282408Scy peer->xmt = p_xmt; 2136282408Scy 2137282408Scy /* 2138280849Scy * Set the peer ppoll to the maximum of the packet ppoll and the 2139280849Scy * peer minpoll. If a kiss-o'-death, set the peer minpoll to 2140280849Scy * this maximum and advance the headway to give the sender some 2141280849Scy * headroom. Very intricate. 2142280849Scy */ 2143289764Sglebius 2144289764Sglebius /* 2145289764Sglebius * Check for any kiss codes. Note this is only used when a server 2146330106Sdelphij * responds to a packet request. 2147289764Sglebius */ 2148289764Sglebius 2149289764Sglebius /* 2150289764Sglebius * Check to see if this is a RATE Kiss Code 2151289764Sglebius * Currently this kiss code will accept whatever poll 2152289764Sglebius * rate that the server sends 2153289764Sglebius */ 2154280849Scy peer->ppoll = max(peer->minpoll, pkt->ppoll); 2155289764Sglebius if (kissCode == RATEKISS) { 2156289764Sglebius peer->selbroken++; /* Increment the KoD count */ 2157280849Scy report_event(PEVNT_RATE, peer, NULL); 2158280849Scy if (pkt->ppoll > peer->minpoll) 2159280849Scy peer->minpoll = peer->ppoll; 2160280849Scy peer->burst = peer->retry = 0; 2161280849Scy peer->throttle = (NTP_SHIFT + 1) * (1 << peer->minpoll); 2162280849Scy poll_update(peer, pkt->ppoll); 2163280849Scy return; /* kiss-o'-death */ 2164280849Scy } 2165289764Sglebius if (kissCode != NOKISS) { 2166289764Sglebius peer->selbroken++; /* Increment the KoD count */ 2167289764Sglebius return; /* Drop any other kiss code packets */ 2168289764Sglebius } 2169280849Scy 2170301247Sdelphij 2171294554Sdelphij /* 2172301247Sdelphij * XXX 2173301247Sdelphij */ 2174301247Sdelphij 2175301247Sdelphij 2176301247Sdelphij /* 2177294554Sdelphij * If: 2178294554Sdelphij * - this is a *cast (uni-, broad-, or m-) server packet 2179298695Sdelphij * - and it's symmetric-key authenticated 2180294554Sdelphij * then see if the sender's IP is trusted for this keyid. 2181294554Sdelphij * If it is, great - nothing special to do here. 2182294554Sdelphij * Otherwise, we should report and bail. 2183298695Sdelphij * 2184298695Sdelphij * Autokey-authenticated packets are accepted. 2185294554Sdelphij */ 2186289764Sglebius 2187294554Sdelphij switch (hismode) { 2188294554Sdelphij case MODE_SERVER: /* server mode */ 2189294554Sdelphij case MODE_BROADCAST: /* broadcast mode */ 2190294554Sdelphij case MODE_ACTIVE: /* symmetric active mode */ 2191298695Sdelphij case MODE_PASSIVE: /* symmetric passive mode */ 2192294554Sdelphij if ( is_authentic == AUTH_OK 2193298695Sdelphij && skeyid 2194298695Sdelphij && skeyid <= NTP_MAXKEY 2195294554Sdelphij && !authistrustedip(skeyid, &peer->srcadr)) { 2196294554Sdelphij report_event(PEVNT_AUTH, peer, "authIP"); 2197294554Sdelphij peer->badauth++; 2198294554Sdelphij return; 2199294554Sdelphij } 2200309007Sdelphij break; 2201294554Sdelphij 2202294554Sdelphij case MODE_CLIENT: /* client mode */ 2203294554Sdelphij#if 0 /* At this point, MODE_CONTROL is overloaded by MODE_BCLIENT */ 2204294554Sdelphij case MODE_CONTROL: /* control mode */ 2205294554Sdelphij#endif 2206294554Sdelphij case MODE_PRIVATE: /* private mode */ 2207294554Sdelphij case MODE_BCLIENT: /* broadcast client mode */ 2208309007Sdelphij break; 2209298695Sdelphij 2210298695Sdelphij case MODE_UNSPEC: /* unspecified (old version) */ 2211294554Sdelphij default: 2212298695Sdelphij msyslog(LOG_INFO, 2213298695Sdelphij "receive: Unexpected mode (%d) in packet from %s", 2214298695Sdelphij hismode, ntoa(&peer->srcadr)); 2215309007Sdelphij break; 2216294554Sdelphij } 2217294554Sdelphij 2218294554Sdelphij 2219280849Scy /* 2220182007Sroberto * That was hard and I am sweaty, but the packet is squeaky 2221182007Sroberto * clean. Get on with real work. 2222182007Sroberto */ 2223182007Sroberto peer->timereceived = current_time; 2224294554Sdelphij peer->timelastrec = current_time; 2225182007Sroberto if (is_authentic == AUTH_OK) 2226182007Sroberto peer->flags |= FLAG_AUTHENTIC; 2227182007Sroberto else 2228182007Sroberto peer->flags &= ~FLAG_AUTHENTIC; 2229280849Scy 2230280849Scy#ifdef AUTOKEY 223154359Sroberto /* 223282505Sroberto * More autokey dance. The rules of the cha-cha are as follows: 223382505Sroberto * 223482505Sroberto * 1. If there is no key or the key is not auto, do nothing. 223582505Sroberto * 2236132454Sroberto * 2. If this packet is in response to the one just previously 2237132454Sroberto * sent or from a broadcast server, do the extension fields. 2238132454Sroberto * Otherwise, assume bogosity and bail out. 2239132454Sroberto * 2240132454Sroberto * 3. If an extension field contains a verified signature, it is 224182505Sroberto * self-authenticated and we sit the dance. 224282505Sroberto * 2243132454Sroberto * 4. If this is a server reply, check only to see that the 224482505Sroberto * transmitted key ID matches the received key ID. 224582505Sroberto * 2246132454Sroberto * 5. Check to see that one or more hashes of the current key ID 224782505Sroberto * matches the previous key ID or ultimate original key ID 224882505Sroberto * obtained from the broadcaster or symmetric peer. If no 2249280849Scy * match, sit the dance and call for new autokey values. 2250182007Sroberto * 2251280849Scy * In case of crypto error, fire the orchestra, stop dancing and 2252280849Scy * restart the protocol. 225354359Sroberto */ 2254280849Scy if (peer->flags & FLAG_SKEY) { 2255280849Scy /* 2256280849Scy * Decrement remaining autokey hashes. This isn't 2257280849Scy * perfect if a packet is lost, but results in no harm. 2258280849Scy */ 2259280849Scy ap = (struct autokey *)peer->recval.ptr; 2260280849Scy if (ap != NULL) { 2261280849Scy if (ap->seq > 0) 2262280849Scy ap->seq--; 2263280849Scy } 2264182007Sroberto peer->flash |= TEST8; 2265132454Sroberto rval = crypto_recv(peer, rbufp); 2266280849Scy if (rval == XEVNT_OK) { 2267280849Scy peer->unreach = 0; 2268280849Scy } else { 2269280849Scy if (rval == XEVNT_ERR) { 2270280849Scy report_event(PEVNT_RESTART, peer, 2271280849Scy "crypto error"); 2272280849Scy peer_clear(peer, "CRYP"); 2273280849Scy peer->flash |= TEST9; /* bad crypt */ 2274294554Sdelphij if (peer->flags & FLAG_PREEMPT) { 2275294554Sdelphij if (unpeer_crypto_early) { 2276294554Sdelphij unpeer(peer); 2277294554Sdelphij } 2278294554Sdelphij } 2279280849Scy } 2280182007Sroberto return; 2281280849Scy } 2282132454Sroberto 2283280849Scy /* 2284280849Scy * If server mode, verify the receive key ID matches 2285280849Scy * the transmit key ID. 2286280849Scy */ 2287280849Scy if (hismode == MODE_SERVER) { 228882505Sroberto if (skeyid == peer->keyid) 2289182007Sroberto peer->flash &= ~TEST8; 2290280849Scy 2291280849Scy /* 2292280849Scy * If an extension field is present, verify only that it 2293280849Scy * has been correctly signed. We don't need a sequence 2294280849Scy * check here, but the sequence continues. 2295280849Scy */ 2296182007Sroberto } else if (!(peer->flash & TEST8)) { 229782505Sroberto peer->pkeyid = skeyid; 2298280849Scy 2299280849Scy /* 2300280849Scy * Now the fun part. Here, skeyid is the current ID in 2301280849Scy * the packet, pkeyid is the ID in the last packet and 2302280849Scy * tkeyid is the hash of skeyid. If the autokey values 2303280849Scy * have not been received, this is an automatic error. 2304280849Scy * If so, check that the tkeyid matches pkeyid. If not, 2305280849Scy * hash tkeyid and try again. If the number of hashes 2306280849Scy * exceeds the number remaining in the sequence, declare 2307280849Scy * a successful failure and refresh the autokey values. 2308280849Scy */ 2309280849Scy } else if (ap != NULL) { 231082505Sroberto int i; 231182505Sroberto 231282505Sroberto for (i = 0; ; i++) { 2313289764Sglebius if ( tkeyid == peer->pkeyid 2314289764Sglebius || tkeyid == ap->key) { 2315182007Sroberto peer->flash &= ~TEST8; 231682505Sroberto peer->pkeyid = skeyid; 2317280849Scy ap->seq -= i; 231882505Sroberto break; 231982505Sroberto } 2320280849Scy if (i > ap->seq) { 2321280849Scy peer->crypto &= 2322280849Scy ~CRYPTO_FLAG_AUTO; 232382505Sroberto break; 2324280849Scy } 232554359Sroberto tkeyid = session_key( 232682505Sroberto &rbufp->recv_srcadr, dstadr_sin, 232782505Sroberto tkeyid, pkeyid, 0); 232854359Sroberto } 2329280849Scy if (peer->flash & TEST8) 2330280849Scy report_event(PEVNT_AUTH, peer, "keylist"); 233154359Sroberto } 2332182007Sroberto if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */ 2333280849Scy peer->flash |= TEST8; /* bad autokey */ 233482505Sroberto 233582505Sroberto /* 2336280849Scy * The maximum lifetime of the protocol is about one 2337280849Scy * week before restarting the Autokey protocol to 2338280849Scy * refresh certificates and leapseconds values. 233982505Sroberto */ 2340280849Scy if (current_time > peer->refresh) { 2341280849Scy report_event(PEVNT_RESTART, peer, 2342280849Scy "crypto refresh"); 2343280849Scy peer_clear(peer, "TIME"); 2344280849Scy return; 2345132454Sroberto } 234654359Sroberto } 2347280849Scy#endif /* AUTOKEY */ 234854359Sroberto 234954359Sroberto /* 2350182007Sroberto * The dance is complete and the flash bits have been lit. Toss 2351182007Sroberto * the packet over the fence for processing, which may light up 2352182007Sroberto * more flashers. 235354359Sroberto */ 2354280849Scy process_packet(peer, pkt, rbufp->recv_length); 2355182007Sroberto 2356182007Sroberto /* 2357280849Scy * In interleaved mode update the state variables. Also adjust the 2358280849Scy * transmit phase to avoid crossover. 2359182007Sroberto */ 2360280849Scy if (peer->flip != 0) { 2361280849Scy peer->rec = p_rec; 2362280849Scy peer->dst = rbufp->recv_time; 2363280849Scy if (peer->nextdate - current_time < (1U << min(peer->ppoll, 2364280849Scy peer->hpoll)) / 2) 2365280849Scy peer->nextdate++; 2366280849Scy else 2367280849Scy peer->nextdate--; 2368182007Sroberto } 236954359Sroberto} 237054359Sroberto 237154359Sroberto 237254359Sroberto/* 2373301247Sdelphij * process_packet - Packet Procedure, a la Section 3.4.4 of RFC-1305 2374301247Sdelphij * Or almost, at least. If we're in here we have a reasonable 2375301247Sdelphij * expectation that we will be having a long term 237654359Sroberto * relationship with this host. 237754359Sroberto */ 237882505Srobertovoid 237954359Srobertoprocess_packet( 238054359Sroberto register struct peer *peer, 2381280849Scy register struct pkt *pkt, 2382280849Scy u_int len 238354359Sroberto ) 238454359Sroberto{ 2385182007Sroberto double t34, t21; 2386132454Sroberto double p_offset, p_del, p_disp; 2387280849Scy l_fp p_rec, p_xmt, p_org, p_reftime, ci; 2388280849Scy u_char pmode, pleap, pversion, pstratum; 2389280849Scy char statstr[NTP_MAXSTRLEN]; 2390280849Scy#ifdef ASSYM 2391280849Scy int itemp; 2392280849Scy double etemp, ftemp, td; 2393280849Scy#endif /* ASSYM */ 239454359Sroberto 2395301247Sdelphij#if 0 239654359Sroberto sys_processed++; 239754359Sroberto peer->processed++; 2398301247Sdelphij#endif 239954359Sroberto p_del = FPTOD(NTOHS_FP(pkt->rootdelay)); 2400280849Scy p_offset = 0; 2401280849Scy p_disp = FPTOD(NTOHS_FP(pkt->rootdisp)); 240254359Sroberto NTOHL_FP(&pkt->reftime, &p_reftime); 2403280849Scy NTOHL_FP(&pkt->org, &p_org); 240454359Sroberto NTOHL_FP(&pkt->rec, &p_rec); 240554359Sroberto NTOHL_FP(&pkt->xmt, &p_xmt); 2406132454Sroberto pmode = PKT_MODE(pkt->li_vn_mode); 2407132454Sroberto pleap = PKT_LEAP(pkt->li_vn_mode); 2408280849Scy pversion = PKT_VERSION(pkt->li_vn_mode); 2409132454Sroberto pstratum = PKT_TO_STRATUM(pkt->stratum); 241054359Sroberto 2411301247Sdelphij /**/ 2412301247Sdelphij 2413301247Sdelphij /**/ 2414301247Sdelphij 241554359Sroberto /* 2416301247Sdelphij * Verify the server is synchronized; that is, the leap bits, 2417301247Sdelphij * stratum and root distance are valid. 2418301247Sdelphij */ 2419301247Sdelphij if ( pleap == LEAP_NOTINSYNC /* test 6 */ 2420301247Sdelphij || pstratum < sys_floor || pstratum >= sys_ceiling) 2421301247Sdelphij peer->flash |= TEST6; /* bad synch or strat */ 2422301247Sdelphij if (p_del / 2 + p_disp >= MAXDISPERSE) /* test 7 */ 2423301247Sdelphij peer->flash |= TEST7; /* bad header */ 2424301247Sdelphij 2425301247Sdelphij /* 2426301247Sdelphij * If any tests fail at this point, the packet is discarded. 2427301247Sdelphij * Note that some flashers may have already been set in the 2428301247Sdelphij * receive() routine. 2429301247Sdelphij */ 2430301247Sdelphij if (peer->flash & PKT_TEST_MASK) { 2431301247Sdelphij peer->seldisptoolarge++; 2432301247Sdelphij DPRINTF(1, ("packet: flash header %04x\n", 2433301247Sdelphij peer->flash)); 2434301247Sdelphij return; 2435301247Sdelphij } 2436301247Sdelphij 2437301247Sdelphij /**/ 2438301247Sdelphij 2439301247Sdelphij#if 1 2440301247Sdelphij sys_processed++; 2441301247Sdelphij peer->processed++; 2442301247Sdelphij#endif 2443301247Sdelphij 2444301247Sdelphij /* 2445280849Scy * Capture the header values in the client/peer association.. 244654359Sroberto */ 2447330106Sdelphij record_raw_stats(&peer->srcadr, 2448330106Sdelphij peer->dstadr ? &peer->dstadr->sin : NULL, 2449280849Scy &p_org, &p_rec, &p_xmt, &peer->dst, 2450280849Scy pleap, pversion, pmode, pstratum, pkt->ppoll, pkt->precision, 2451330106Sdelphij p_del, p_disp, pkt->refid, 2452330106Sdelphij len - MIN_V4_PKT_LEN, (u_char *)&pkt->exten); 2453132454Sroberto peer->leap = pleap; 2454182007Sroberto peer->stratum = min(pstratum, STRATUM_UNSPEC); 2455182007Sroberto peer->pmode = pmode; 2456182007Sroberto peer->precision = pkt->precision; 2457182007Sroberto peer->rootdelay = p_del; 2458280849Scy peer->rootdisp = p_disp; 2459182007Sroberto peer->refid = pkt->refid; /* network byte order */ 2460182007Sroberto peer->reftime = p_reftime; 246182505Sroberto 246282505Sroberto /* 2463280849Scy * First, if either burst mode is armed, enable the burst. 2464280849Scy * Compute the headway for the next packet and delay if 2465280849Scy * necessary to avoid exceeding the threshold. 246682505Sroberto */ 2467280849Scy if (peer->retry > 0) { 2468280849Scy peer->retry = 0; 2469280849Scy if (peer->reach) 2470280849Scy peer->burst = min(1 << (peer->hpoll - 2471280849Scy peer->minpoll), NTP_SHIFT) - 1; 2472280849Scy else 2473280849Scy peer->burst = NTP_IBURST - 1; 2474280849Scy if (peer->burst > 0) 2475280849Scy peer->nextdate = current_time; 2476280849Scy } 2477280849Scy poll_update(peer, peer->hpoll); 2478280849Scy 2479301247Sdelphij /**/ 2480132454Sroberto 2481132454Sroberto /* 2482280849Scy * If the peer was previously unreachable, raise a trap. In any 2483280849Scy * case, mark it reachable. 2484282408Scy */ 2485280849Scy if (!peer->reach) { 2486280849Scy report_event(PEVNT_REACH, peer, NULL); 248754359Sroberto peer->timereachable = current_time; 248854359Sroberto } 248954359Sroberto peer->reach |= 1; 249054359Sroberto 249154359Sroberto /* 2492182007Sroberto * For a client/server association, calculate the clock offset, 2493182007Sroberto * roundtrip delay and dispersion. The equations are reordered 2494182007Sroberto * from the spec for more efficient use of temporaries. For a 2495182007Sroberto * broadcast association, offset the last measurement by the 2496280849Scy * computed delay during the client/server volley. Note the 2497182007Sroberto * computation of dispersion includes the system precision plus 2498182007Sroberto * that due to the frequency error since the origin time. 249954359Sroberto * 2500182007Sroberto * It is very important to respect the hazards of overflow. The 2501182007Sroberto * only permitted operation on raw timestamps is subtraction, 2502182007Sroberto * where the result is a signed quantity spanning from 68 years 2503182007Sroberto * in the past to 68 years in the future. To avoid loss of 2504182007Sroberto * precision, these calculations are done using 64-bit integer 2505182007Sroberto * arithmetic. However, the offset and delay calculations are 2506182007Sroberto * sums and differences of these first-order differences, which 2507182007Sroberto * if done using 64-bit integer arithmetic, would be valid over 2508182007Sroberto * only half that span. Since the typical first-order 2509182007Sroberto * differences are usually very small, they are converted to 64- 2510182007Sroberto * bit doubles and all remaining calculations done in floating- 2511280849Scy * double arithmetic. This preserves the accuracy while 2512280849Scy * retaining the 68-year span. 2513182007Sroberto * 2514280849Scy * There are three interleaving schemes, basic, interleaved 2515280849Scy * symmetric and interleaved broadcast. The timestamps are 2516280849Scy * idioscyncratically different. See the onwire briefing/white 2517280849Scy * paper at www.eecis.udel.edu/~mills for details. 2518280849Scy * 2519280849Scy * Interleaved symmetric mode 2520280849Scy * t1 = peer->aorg/borg, t2 = peer->rec, t3 = p_xmt, 2521280849Scy * t4 = peer->dst 252254359Sroberto */ 2523280849Scy if (peer->flip != 0) { 2524280849Scy ci = p_xmt; /* t3 - t4 */ 2525280849Scy L_SUB(&ci, &peer->dst); 2526280849Scy LFPTOD(&ci, t34); 2527280849Scy ci = p_rec; /* t2 - t1 */ 2528280849Scy if (peer->flip > 0) 2529280849Scy L_SUB(&ci, &peer->borg); 2530280849Scy else 2531280849Scy L_SUB(&ci, &peer->aorg); 2532280849Scy LFPTOD(&ci, t21); 2533280849Scy p_del = t21 - t34; 2534280849Scy p_offset = (t21 + t34) / 2.; 2535280849Scy if (p_del < 0 || p_del > 1.) { 2536280849Scy snprintf(statstr, sizeof(statstr), 2537280849Scy "t21 %.6f t34 %.6f", t21, t34); 2538280849Scy report_event(PEVNT_XERR, peer, statstr); 2539280849Scy return; 2540280849Scy } 254154359Sroberto 254254359Sroberto /* 2543280849Scy * Broadcast modes 254454359Sroberto */ 2545280849Scy } else if (peer->pmode == MODE_BROADCAST) { 2546280849Scy 2547280849Scy /* 2548280849Scy * Interleaved broadcast mode. Use interleaved timestamps. 2549280849Scy * t1 = peer->borg, t2 = p_org, t3 = p_org, t4 = aorg 2550280849Scy */ 2551282408Scy if (peer->flags & FLAG_XB) { 2552282408Scy ci = p_org; /* delay */ 2553280849Scy L_SUB(&ci, &peer->aorg); 2554280849Scy LFPTOD(&ci, t34); 2555280849Scy ci = p_org; /* t2 - t1 */ 2556280849Scy L_SUB(&ci, &peer->borg); 2557280849Scy LFPTOD(&ci, t21); 2558280849Scy peer->aorg = p_xmt; 2559280849Scy peer->borg = peer->dst; 2560280849Scy if (t34 < 0 || t34 > 1.) { 2561298695Sdelphij /* drop all if in the initial volley */ 2562298695Sdelphij if (FLAG_BC_VOL & peer->flags) 2563298695Sdelphij goto bcc_init_volley_fail; 2564280849Scy snprintf(statstr, sizeof(statstr), 2565280849Scy "offset %.6f delay %.6f", t21, t34); 2566280849Scy report_event(PEVNT_XERR, peer, statstr); 256782505Sroberto return; 2568280849Scy } 2569280849Scy p_offset = t21; 2570280849Scy peer->xleave = t34; 257154359Sroberto 2572280849Scy /* 2573280849Scy * Basic broadcast - use direct timestamps. 2574280849Scy * t3 = p_xmt, t4 = peer->dst 2575280849Scy */ 2576280849Scy } else { 2577280849Scy ci = p_xmt; /* t3 - t4 */ 2578280849Scy L_SUB(&ci, &peer->dst); 2579280849Scy LFPTOD(&ci, t34); 2580280849Scy p_offset = t34; 258154359Sroberto } 2582280849Scy 2583280849Scy /* 2584280849Scy * When calibration is complete and the clock is 2585280849Scy * synchronized, the bias is calculated as the difference 2586280849Scy * between the unicast timestamp and the broadcast 2587280849Scy * timestamp. This works for both basic and interleaved 2588280849Scy * modes. 2589298695Sdelphij * [Bug 3031] Don't keep this peer when the delay 2590298695Sdelphij * calculation gives reason to suspect clock steps. 2591298695Sdelphij * This is assumed for delays > 50ms. 2592280849Scy */ 2593280849Scy if (FLAG_BC_VOL & peer->flags) { 2594280849Scy peer->flags &= ~FLAG_BC_VOL; 2595280849Scy peer->delay = fabs(peer->offset - p_offset) * 2; 2596298695Sdelphij DPRINTF(2, ("broadcast volley: initial delay=%.6f\n", 2597298695Sdelphij peer->delay)); 2598298695Sdelphij if (peer->delay > fabs(sys_bdelay)) { 2599298695Sdelphij bcc_init_volley_fail: 2600298695Sdelphij DPRINTF(2, ("%s", "broadcast volley: initial delay exceeds limit\n")); 2601298695Sdelphij unpeer(peer); 2602298695Sdelphij return; 2603298695Sdelphij } 2604280849Scy } 2605298695Sdelphij peer->nextdate = current_time + (1u << peer->ppoll) - 2u; 260654359Sroberto p_del = peer->delay; 2607280849Scy p_offset += p_del / 2; 2608280849Scy 2609280849Scy 2610280849Scy /* 2611280849Scy * Basic mode, otherwise known as the old fashioned way. 2612280849Scy * 2613280849Scy * t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->dst 2614280849Scy */ 261554359Sroberto } else { 2616280849Scy ci = p_xmt; /* t3 - t4 */ 2617280849Scy L_SUB(&ci, &peer->dst); 2618280849Scy LFPTOD(&ci, t34); 2619280849Scy ci = p_rec; /* t2 - t1 */ 2620280849Scy L_SUB(&ci, &p_org); 2621280849Scy LFPTOD(&ci, t21); 2622280849Scy p_del = fabs(t21 - t34); 2623182007Sroberto p_offset = (t21 + t34) / 2.; 262454359Sroberto } 262582505Sroberto p_del = max(p_del, LOGTOD(sys_precision)); 2626280849Scy p_disp = LOGTOD(sys_precision) + LOGTOD(peer->precision) + 2627280849Scy clock_phi * p_del; 2628280849Scy 2629280849Scy#if ASSYM 2630280849Scy /* 2631280849Scy * This code calculates the outbound and inbound data rates by 2632280849Scy * measuring the differences between timestamps at different 2633280849Scy * packet lengths. This is helpful in cases of large asymmetric 2634280849Scy * delays commonly experienced on deep space communication 2635280849Scy * links. 2636280849Scy */ 2637280849Scy if (peer->t21_last > 0 && peer->t34_bytes > 0) { 2638280849Scy itemp = peer->t21_bytes - peer->t21_last; 2639280849Scy if (itemp > 25) { 2640280849Scy etemp = t21 - peer->t21; 2641280849Scy if (fabs(etemp) > 1e-6) { 2642280849Scy ftemp = itemp / etemp; 2643280849Scy if (ftemp > 1000.) 2644280849Scy peer->r21 = ftemp; 2645280849Scy } 2646280849Scy } 2647280849Scy itemp = len - peer->t34_bytes; 2648280849Scy if (itemp > 25) { 2649280849Scy etemp = -t34 - peer->t34; 2650280849Scy if (fabs(etemp) > 1e-6) { 2651280849Scy ftemp = itemp / etemp; 2652280849Scy if (ftemp > 1000.) 2653280849Scy peer->r34 = ftemp; 2654280849Scy } 2655280849Scy } 2656280849Scy } 2657280849Scy 2658280849Scy /* 2659280849Scy * The following section compensates for different data rates on 2660280849Scy * the outbound (d21) and inbound (t34) directions. To do this, 2661280849Scy * it finds t such that r21 * t - r34 * (d - t) = 0, where d is 2662280849Scy * the roundtrip delay. Then it calculates the correction as a 2663280849Scy * fraction of d. 2664280849Scy */ 2665293423Sdelphij peer->t21 = t21; 2666280849Scy peer->t21_last = peer->t21_bytes; 2667280849Scy peer->t34 = -t34; 2668280849Scy peer->t34_bytes = len; 2669293423Sdelphij DPRINTF(2, ("packet: t21 %.9lf %d t34 %.9lf %d\n", peer->t21, 2670293423Sdelphij peer->t21_bytes, peer->t34, peer->t34_bytes)); 2671280849Scy if (peer->r21 > 0 && peer->r34 > 0 && p_del > 0) { 2672280849Scy if (peer->pmode != MODE_BROADCAST) 2673280849Scy td = (peer->r34 / (peer->r21 + peer->r34) - 2674280849Scy .5) * p_del; 2675280849Scy else 2676280849Scy td = 0; 2677280849Scy 2678280849Scy /* 2679293423Sdelphij * Unfortunately, in many cases the errors are 2680280849Scy * unacceptable, so for the present the rates are not 2681280849Scy * used. In future, we might find conditions where the 2682280849Scy * calculations are useful, so this should be considered 2683280849Scy * a work in progress. 2684280849Scy */ 2685280849Scy t21 -= td; 2686280849Scy t34 -= td; 2687293423Sdelphij DPRINTF(2, ("packet: del %.6lf r21 %.1lf r34 %.1lf %.6lf\n", 2688280849Scy p_del, peer->r21 / 1e3, peer->r34 / 1e3, 2689293423Sdelphij td)); 2690282408Scy } 2691280849Scy#endif /* ASSYM */ 2692280849Scy 2693280849Scy /* 2694280849Scy * That was awesome. Now hand off to the clock filter. 2695280849Scy */ 2696280849Scy clock_filter(peer, p_offset + peer->bias, p_del, p_disp); 2697280849Scy 2698280849Scy /* 2699280849Scy * If we are in broadcast calibrate mode, return to broadcast 2700280849Scy * client mode when the client is fit and the autokey dance is 2701280849Scy * complete. 2702280849Scy */ 2703289764Sglebius if ( (FLAG_BC_VOL & peer->flags) 2704289764Sglebius && MODE_CLIENT == peer->hmode 2705289764Sglebius && !(TEST11 & peer_unfit(peer))) { /* distance exceeded */ 2706280849Scy#ifdef AUTOKEY 2707280849Scy if (peer->flags & FLAG_SKEY) { 2708280849Scy if (!(~peer->crypto & CRYPTO_FLAG_ALL)) 2709280849Scy peer->hmode = MODE_BCLIENT; 2710280849Scy } else { 2711280849Scy peer->hmode = MODE_BCLIENT; 2712280849Scy } 2713280849Scy#else /* !AUTOKEY follows */ 2714280849Scy peer->hmode = MODE_BCLIENT; 2715280849Scy#endif /* !AUTOKEY */ 2716280849Scy } 271754359Sroberto} 271854359Sroberto 271954359Sroberto 272054359Sroberto/* 272154359Sroberto * clock_update - Called at system process update intervals. 272254359Sroberto */ 272354359Srobertostatic void 2724280849Scyclock_update( 2725280849Scy struct peer *peer /* peer structure pointer */ 2726280849Scy ) 272754359Sroberto{ 2728182007Sroberto double dtemp; 2729280849Scy l_fp now; 2730280849Scy#ifdef HAVE_LIBSCF_H 2731280849Scy char *fmri; 2732280849Scy#endif /* HAVE_LIBSCF_H */ 273354359Sroberto 273454359Sroberto /* 2735280849Scy * Update the system state variables. We do this very carefully, 2736280849Scy * as the poll interval might need to be clamped differently. 273754359Sroberto */ 2738280849Scy sys_peer = peer; 2739280849Scy sys_epoch = peer->epoch; 2740280849Scy if (sys_poll < peer->minpoll) 2741280849Scy sys_poll = peer->minpoll; 2742280849Scy if (sys_poll > peer->maxpoll) 2743280849Scy sys_poll = peer->maxpoll; 2744280849Scy poll_update(peer, sys_poll); 2745280849Scy sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC); 2746289764Sglebius if ( peer->stratum == STRATUM_REFCLOCK 2747289764Sglebius || peer->stratum == STRATUM_UNSPEC) 2748280849Scy sys_refid = peer->refid; 2749280849Scy else 2750280849Scy sys_refid = addr2refid(&peer->srcadr); 2751280849Scy /* 2752280849Scy * Root Dispersion (E) is defined (in RFC 5905) as: 2753280849Scy * 2754280849Scy * E = p.epsilon_r + p.epsilon + p.psi + PHI*(s.t - p.t) + |THETA| 2755280849Scy * 2756280849Scy * where: 2757280849Scy * p.epsilon_r is the PollProc's root dispersion 2758280849Scy * p.epsilon is the PollProc's dispersion 2759280849Scy * p.psi is the PollProc's jitter 2760280849Scy * THETA is the combined offset 2761280849Scy * 2762280849Scy * NB: Think Hard about where these numbers come from and 2763280849Scy * what they mean. When did peer->update happen? Has anything 2764280849Scy * interesting happened since then? What values are the most 2765280849Scy * defensible? Why? 2766280849Scy * 2767280849Scy * DLM thinks this equation is probably the best of all worse choices. 2768280849Scy */ 2769280849Scy dtemp = peer->rootdisp 2770280849Scy + peer->disp 2771280849Scy + sys_jitter 2772280849Scy + clock_phi * (current_time - peer->update) 2773280849Scy + fabs(sys_offset); 2774182007Sroberto 2775280849Scy if (dtemp > sys_mindisp) 2776280849Scy sys_rootdisp = dtemp; 2777280849Scy else 2778280849Scy sys_rootdisp = sys_mindisp; 2779280849Scy sys_rootdelay = peer->delay + peer->rootdelay; 2780280849Scy sys_reftime = peer->dst; 2781280849Scy 2782293423Sdelphij DPRINTF(1, ("clock_update: at %lu sample %lu associd %d\n", 2783293423Sdelphij current_time, peer->epoch, peer->associd)); 278454359Sroberto 278582505Sroberto /* 2786280849Scy * Comes now the moment of truth. Crank the clock discipline and 2787280849Scy * see what comes out. 2788280849Scy */ 2789280849Scy switch (local_clock(peer, sys_offset)) { 2790280849Scy 2791280849Scy /* 2792182007Sroberto * Clock exceeds panic threshold. Life as we know it ends. 279382505Sroberto */ 279482505Sroberto case -1: 2795280849Scy#ifdef HAVE_LIBSCF_H 2796280849Scy /* 2797280849Scy * For Solaris enter the maintenance mode. 2798280849Scy */ 2799280849Scy if ((fmri = getenv("SMF_FMRI")) != NULL) { 2800280849Scy if (smf_maintain_instance(fmri, 0) < 0) { 2801280849Scy printf("smf_maintain_instance: %s\n", 2802280849Scy scf_strerror(scf_error())); 2803280849Scy exit(1); 2804280849Scy } 2805280849Scy /* 2806280849Scy * Sleep until SMF kills us. 2807280849Scy */ 2808280849Scy for (;;) 2809280849Scy pause(); 2810280849Scy } 2811280849Scy#endif /* HAVE_LIBSCF_H */ 2812132454Sroberto exit (-1); 2813182007Sroberto /* not reached */ 281454359Sroberto 281582505Sroberto /* 281682505Sroberto * Clock was stepped. Flush all time values of all peers. 281782505Sroberto */ 2818182007Sroberto case 2: 281982505Sroberto clear_all(); 2820285169Scy set_sys_leap(LEAP_NOTINSYNC); 2821182007Sroberto sys_stratum = STRATUM_UNSPEC; 2822280849Scy memcpy(&sys_refid, "STEP", 4); 2823182007Sroberto sys_rootdelay = 0; 2824280849Scy sys_rootdisp = 0; 2825280849Scy L_CLR(&sys_reftime); 2826280849Scy sys_jitter = LOGTOD(sys_precision); 2827280849Scy leapsec_reset_frame(); 282854359Sroberto break; 282954359Sroberto 283082505Sroberto /* 2831280849Scy * Clock was slewed. Handle the leapsecond stuff. 283282505Sroberto */ 2833182007Sroberto case 1: 2834182007Sroberto 2835182007Sroberto /* 2836280849Scy * If this is the first time the clock is set, reset the 2837280849Scy * leap bits. If crypto, the timer will goose the setup 2838280849Scy * process. 2839182007Sroberto */ 2840280849Scy if (sys_leap == LEAP_NOTINSYNC) { 2841285169Scy set_sys_leap(LEAP_NOWARNING); 2842280849Scy#ifdef AUTOKEY 2843280849Scy if (crypto_flags) 2844280849Scy crypto_update(); 2845280849Scy#endif /* AUTOKEY */ 2846280849Scy /* 2847280849Scy * If our parent process is waiting for the 2848280849Scy * first clock sync, send them home satisfied. 2849280849Scy */ 2850280849Scy#ifdef HAVE_WORKING_FORK 2851280849Scy if (waitsync_fd_to_close != -1) { 2852280849Scy close(waitsync_fd_to_close); 2853280849Scy waitsync_fd_to_close = -1; 2854280849Scy DPRINTF(1, ("notified parent --wait-sync is done\n")); 2855280849Scy } 2856280849Scy#endif /* HAVE_WORKING_FORK */ 2857280849Scy 2858182007Sroberto } 2859280849Scy 2860280849Scy /* 2861280849Scy * If there is no leap second pending and the number of 2862280849Scy * survivor leap bits is greater than half the number of 2863280849Scy * survivors, try to schedule a leap for the end of the 2864280849Scy * current month. (This only works if no leap second for 2865280849Scy * that range is in the table, so doing this more than 2866280849Scy * once is mostly harmless.) 2867280849Scy */ 2868280849Scy if (leapsec == LSPROX_NOWARN) { 2869289764Sglebius if ( leap_vote_ins > leap_vote_del 2870280849Scy && leap_vote_ins > sys_survivors / 2) { 2871280849Scy get_systime(&now); 2872280849Scy leapsec_add_dyn(TRUE, now.l_ui, NULL); 2873280849Scy } 2874289764Sglebius if ( leap_vote_del > leap_vote_ins 2875280849Scy && leap_vote_del > sys_survivors / 2) { 2876280849Scy get_systime(&now); 2877280849Scy leapsec_add_dyn(FALSE, now.l_ui, NULL); 2878280849Scy } 2879132454Sroberto } 2880182007Sroberto break; 2881280849Scy 2882182007Sroberto /* 2883182007Sroberto * Popcorn spike or step threshold exceeded. Pretend it never 2884182007Sroberto * happened. 2885182007Sroberto */ 2886182007Sroberto default: 2887182007Sroberto break; 288854359Sroberto } 288954359Sroberto} 289054359Sroberto 289154359Sroberto 289254359Sroberto/* 289382505Sroberto * poll_update - update peer poll interval 289454359Sroberto */ 289554359Srobertovoid 289654359Srobertopoll_update( 2897280849Scy struct peer *peer, /* peer structure pointer */ 2898280849Scy u_char mpoll 289954359Sroberto ) 290054359Sroberto{ 2901280849Scy u_long next, utemp; 2902280849Scy u_char hpoll; 290354359Sroberto 290454359Sroberto /* 2905182007Sroberto * This routine figures out when the next poll should be sent. 2906280849Scy * That turns out to be wickedly complicated. One problem is 2907280849Scy * that sometimes the time for the next poll is in the past when 2908280849Scy * the poll interval is reduced. We watch out for races here 2909280849Scy * between the receive process and the poll process. 2910182007Sroberto * 2911280849Scy * Clamp the poll interval between minpoll and maxpoll. 291254359Sroberto */ 2913280849Scy hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll); 2914182007Sroberto 2915280849Scy#ifdef AUTOKEY 2916182007Sroberto /* 2917280849Scy * If during the crypto protocol the poll interval has changed, 2918280849Scy * the lifetimes in the key list are probably bogus. Purge the 2919280849Scy * the key list and regenerate it later. 2920182007Sroberto */ 2921280849Scy if ((peer->flags & FLAG_SKEY) && hpoll != peer->hpoll) 2922182007Sroberto key_expire(peer); 2923280849Scy#endif /* AUTOKEY */ 2924182007Sroberto peer->hpoll = hpoll; 292582505Sroberto 292682505Sroberto /* 2927280849Scy * There are three variables important for poll scheduling, the 2928280849Scy * current time (current_time), next scheduled time (nextdate) 2929280849Scy * and the earliest time (utemp). The earliest time is 2 s 2930280849Scy * seconds, but could be more due to rate management. When 2931280849Scy * sending in a burst, use the earliest time. When not in a 2932280849Scy * burst but with a reply pending, send at the earliest time 2933280849Scy * unless the next scheduled time has not advanced. This can 2934280849Scy * only happen if multiple replies are pending in the same 2935280849Scy * response interval. Otherwise, send at the later of the next 2936280849Scy * scheduled time and the earliest time. 2937280849Scy * 2938280849Scy * Now we figure out if there is an override. If a burst is in 2939280849Scy * progress and we get called from the receive process, just 2940280849Scy * slink away. If called from the poll process, delay 1 s for a 2941280849Scy * reference clock, otherwise 2 s. 294282505Sroberto */ 2943280849Scy utemp = current_time + max(peer->throttle - (NTP_SHIFT - 1) * 2944280849Scy (1 << peer->minpoll), ntp_minpkt); 294554359Sroberto if (peer->burst > 0) { 2946280849Scy if (peer->nextdate > current_time) 294754359Sroberto return; 294882505Sroberto#ifdef REFCLOCK 294982505Sroberto else if (peer->flags & FLAG_REFCLOCK) 2950280849Scy peer->nextdate = current_time + RESP_DELAY; 2951182007Sroberto#endif /* REFCLOCK */ 295254359Sroberto else 2953280849Scy peer->nextdate = utemp; 2954280849Scy 2955280849Scy#ifdef AUTOKEY 2956182007Sroberto /* 2957280849Scy * If a burst is not in progress and a crypto response message 2958280849Scy * is pending, delay 2 s, but only if this is a new interval. 2959182007Sroberto */ 2960280849Scy } else if (peer->cmmd != NULL) { 2961280849Scy if (peer->nextdate > current_time) { 2962280849Scy if (peer->nextdate + ntp_minpkt != utemp) 2963280849Scy peer->nextdate = utemp; 2964280849Scy } else { 2965280849Scy peer->nextdate = utemp; 2966280849Scy } 2967280849Scy#endif /* AUTOKEY */ 2968182007Sroberto 296982505Sroberto /* 2970280849Scy * The ordinary case. If a retry, use minpoll; if unreachable, 2971280849Scy * use host poll; otherwise, use the minimum of host and peer 2972280849Scy * polls; In other words, oversampling is okay but 2973280849Scy * understampling is evil. Use the maximum of this value and the 2974280849Scy * headway. If the average headway is greater than the headway 2975280849Scy * threshold, increase the headway by the minimum interval. 297682505Sroberto */ 2977280849Scy } else { 2978280849Scy if (peer->retry > 0) 2979280849Scy hpoll = peer->minpoll; 2980280849Scy else if (!(peer->reach)) 2981280849Scy hpoll = peer->hpoll; 2982280849Scy else 2983280849Scy hpoll = min(peer->ppoll, peer->hpoll); 2984280849Scy#ifdef REFCLOCK 2985280849Scy if (peer->flags & FLAG_REFCLOCK) 2986280849Scy next = 1 << hpoll; 2987280849Scy else 2988280849Scy#endif /* REFCLOCK */ 2989280849Scy next = ((0x1000UL | (ntp_random() & 0x0ff)) << 2990280849Scy hpoll) >> 12; 2991280849Scy next += peer->outdate; 2992280849Scy if (next > utemp) 2993280849Scy peer->nextdate = next; 2994280849Scy else 2995280849Scy peer->nextdate = utemp; 2996280849Scy if (peer->throttle > (1 << peer->minpoll)) 2997280849Scy peer->nextdate += ntp_minpkt; 2998280849Scy } 2999280849Scy DPRINTF(2, ("poll_update: at %lu %s poll %d burst %d retry %d head %d early %lu next %lu\n", 3000280849Scy current_time, ntoa(&peer->srcadr), peer->hpoll, 3001280849Scy peer->burst, peer->retry, peer->throttle, 3002280849Scy utemp - current_time, peer->nextdate - 3003280849Scy current_time)); 300454359Sroberto} 300554359Sroberto 3006280849Scy 300754359Sroberto/* 3008280849Scy * peer_clear - clear peer filter registers. See Section 3.4.8 of the 3009280849Scy * spec. 301054359Sroberto */ 301154359Srobertovoid 3012280849Scypeer_clear( 3013280849Scy struct peer *peer, /* peer structure */ 3014280849Scy const char *ident /* tally lights */ 3015280849Scy ) 301654359Sroberto{ 3017280849Scy u_char u; 3018309007Sdelphij l_fp bxmt = peer->bxmt; /* bcast clients retain this! */ 3019280849Scy 3020280849Scy#ifdef AUTOKEY 302182505Sroberto /* 302282505Sroberto * If cryptographic credentials have been acquired, toss them to 302382505Sroberto * Valhalla. Note that autokeys are ephemeral, in that they are 302482505Sroberto * tossed immediately upon use. Therefore, the keylist can be 302582505Sroberto * purged anytime without needing to preserve random keys. Note 302682505Sroberto * that, if the peer is purged, the cryptographic variables are 302782505Sroberto * purged, too. This makes it much harder to sneak in some 302882505Sroberto * unauthenticated data in the clock filter. 302982505Sroberto */ 3030280849Scy key_expire(peer); 3031132454Sroberto if (peer->iffval != NULL) 3032132454Sroberto BN_free(peer->iffval); 3033132454Sroberto value_free(&peer->cookval); 3034132454Sroberto value_free(&peer->recval); 3035280849Scy value_free(&peer->encrypt); 3036280849Scy value_free(&peer->sndval); 3037280849Scy if (peer->cmmd != NULL) 3038182007Sroberto free(peer->cmmd); 3039280849Scy if (peer->subject != NULL) 3040280849Scy free(peer->subject); 3041280849Scy if (peer->issuer != NULL) 3042280849Scy free(peer->issuer); 3043280849Scy#endif /* AUTOKEY */ 3044182007Sroberto 304582505Sroberto /* 3046280849Scy * Clear all values, including the optional crypto values above. 304782505Sroberto */ 3048280849Scy memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO(peer)); 304982505Sroberto peer->ppoll = peer->maxpoll; 3050182007Sroberto peer->hpoll = peer->minpoll; 3051182007Sroberto peer->disp = MAXDISPERSE; 3052280849Scy peer->flash = peer_unfit(peer); 3053182007Sroberto peer->jitter = LOGTOD(sys_precision); 3054280849Scy 3055309007Sdelphij /* Don't throw away our broadcast replay protection */ 3056309007Sdelphij if (peer->hmode == MODE_BCLIENT) 3057309007Sdelphij peer->bxmt = bxmt; 3058309007Sdelphij 3059280849Scy /* 3060280849Scy * If interleave mode, initialize the alternate origin switch. 3061280849Scy */ 3062280849Scy if (peer->flags & FLAG_XLEAVE) 3063280849Scy peer->flip = 1; 3064280849Scy for (u = 0; u < NTP_SHIFT; u++) { 3065280849Scy peer->filter_order[u] = u; 3066280849Scy peer->filter_disp[u] = MAXDISPERSE; 3067182007Sroberto } 306882505Sroberto#ifdef REFCLOCK 306982505Sroberto if (!(peer->flags & FLAG_REFCLOCK)) { 3070280849Scy#endif 307182505Sroberto peer->leap = LEAP_NOTINSYNC; 307282505Sroberto peer->stratum = STRATUM_UNSPEC; 3073132454Sroberto memcpy(&peer->refid, ident, 4); 3074280849Scy#ifdef REFCLOCK 307582505Sroberto } 3076280849Scy#endif 307754359Sroberto 307854359Sroberto /* 3079182007Sroberto * During initialization use the association count to spread out 3080280849Scy * the polls at one-second intervals. Passive associations' 3081280849Scy * first poll is delayed by the "discard minimum" to avoid rate 3082280849Scy * limiting. Other post-startup new or cleared associations 3083280849Scy * randomize the first poll over the minimum poll interval to 3084280849Scy * avoid implosion. 308554359Sroberto */ 3086132454Sroberto peer->nextdate = peer->update = peer->outdate = current_time; 3087280849Scy if (initializing) { 3088182007Sroberto peer->nextdate += peer_associations; 3089280849Scy } else if (MODE_PASSIVE == peer->hmode) { 3090280849Scy peer->nextdate += ntp_minpkt; 3091280849Scy } else { 3092280849Scy peer->nextdate += ntp_random() % peer->minpoll; 3093280849Scy } 3094280849Scy#ifdef AUTOKEY 3095280849Scy peer->refresh = current_time + (1 << NTP_REFRESH); 3096280849Scy#endif /* AUTOKEY */ 3097293423Sdelphij DPRINTF(1, ("peer_clear: at %ld next %ld associd %d refid %s\n", 3098280849Scy current_time, peer->nextdate, peer->associd, 3099293423Sdelphij ident)); 310054359Sroberto} 310154359Sroberto 310254359Sroberto 310354359Sroberto/* 310454359Sroberto * clock_filter - add incoming clock sample to filter register and run 310554359Sroberto * the filter procedure to find the best sample. 310654359Sroberto */ 310754359Srobertovoid 310854359Srobertoclock_filter( 3109132454Sroberto struct peer *peer, /* peer structure pointer */ 3110132454Sroberto double sample_offset, /* clock offset */ 3111132454Sroberto double sample_delay, /* roundtrip delay */ 3112132454Sroberto double sample_disp /* dispersion */ 311354359Sroberto ) 311454359Sroberto{ 3115132454Sroberto double dst[NTP_SHIFT]; /* distance vector */ 3116132454Sroberto int ord[NTP_SHIFT]; /* index vector */ 3117132454Sroberto int i, j, k, m; 3118182007Sroberto double dtemp, etemp; 3119280849Scy char tbuf[80]; 312054359Sroberto 312154359Sroberto /* 3122280849Scy * A sample consists of the offset, delay, dispersion and epoch 3123280849Scy * of arrival. The offset and delay are determined by the on- 3124280849Scy * wire protocol. The dispersion grows from the last outbound 3125280849Scy * packet to the arrival of this one increased by the sum of the 3126280849Scy * peer precision and the system precision as required by the 3127280849Scy * error budget. First, shift the new arrival into the shift 3128280849Scy * register discarding the oldest one. 312954359Sroberto */ 313054359Sroberto j = peer->filter_nextpt; 313182505Sroberto peer->filter_offset[j] = sample_offset; 3132280849Scy peer->filter_delay[j] = sample_delay; 3133182007Sroberto peer->filter_disp[j] = sample_disp; 3134182007Sroberto peer->filter_epoch[j] = current_time; 3135182007Sroberto j = (j + 1) % NTP_SHIFT; 3136182007Sroberto peer->filter_nextpt = j; 313754359Sroberto 313854359Sroberto /* 313982505Sroberto * Update dispersions since the last update and at the same 3140280849Scy * time initialize the distance and index lists. Since samples 3141280849Scy * become increasingly uncorrelated beyond the Allan intercept, 3142280849Scy * only under exceptional cases will an older sample be used. 3143280849Scy * Therefore, the distance list uses a compound metric. If the 3144280849Scy * dispersion is greater than the maximum dispersion, clamp the 3145280849Scy * distance at that value. If the time since the last update is 3146280849Scy * less than the Allan intercept use the delay; otherwise, use 3147280849Scy * the sum of the delay and dispersion. 314854359Sroberto */ 314982505Sroberto dtemp = clock_phi * (current_time - peer->update); 315082505Sroberto peer->update = current_time; 315182505Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 3152132454Sroberto if (i != 0) 315382505Sroberto peer->filter_disp[j] += dtemp; 3154282408Scy if (peer->filter_disp[j] >= MAXDISPERSE) { 3155132454Sroberto peer->filter_disp[j] = MAXDISPERSE; 315682505Sroberto dst[i] = MAXDISPERSE; 3157280849Scy } else if (peer->update - peer->filter_epoch[j] > 3158280849Scy (u_long)ULOGTOD(allan_xpt)) { 3159280849Scy dst[i] = peer->filter_delay[j] + 3160280849Scy peer->filter_disp[j]; 3161280849Scy } else { 3162132454Sroberto dst[i] = peer->filter_delay[j]; 3163280849Scy } 316482505Sroberto ord[i] = j; 3165280849Scy j = (j + 1) % NTP_SHIFT; 316682505Sroberto } 316754359Sroberto 3168280849Scy /* 3169282408Scy * If the clock has stabilized, sort the samples by distance. 317054359Sroberto */ 3171280849Scy if (freq_cnt == 0) { 3172182007Sroberto for (i = 1; i < NTP_SHIFT; i++) { 3173182007Sroberto for (j = 0; j < i; j++) { 3174280849Scy if (dst[j] > dst[i]) { 3175182007Sroberto k = ord[j]; 3176182007Sroberto ord[j] = ord[i]; 3177182007Sroberto ord[i] = k; 3178182007Sroberto etemp = dst[j]; 3179182007Sroberto dst[j] = dst[i]; 3180182007Sroberto dst[i] = etemp; 3181182007Sroberto } 318254359Sroberto } 318354359Sroberto } 318482505Sroberto } 318582505Sroberto 318682505Sroberto /* 318782505Sroberto * Copy the index list to the association structure so ntpq 3188280849Scy * can see it later. Prune the distance list to leave only 3189280849Scy * samples less than the maximum dispersion, which disfavors 3190280849Scy * uncorrelated samples older than the Allan intercept. To 3191280849Scy * further improve the jitter estimate, of the remainder leave 3192280849Scy * only samples less than the maximum distance, but keep at 3193280849Scy * least two samples for jitter calculation. 319482505Sroberto */ 319582505Sroberto m = 0; 319682505Sroberto for (i = 0; i < NTP_SHIFT; i++) { 3197132454Sroberto peer->filter_order[i] = (u_char) ord[i]; 3198289764Sglebius if ( dst[i] >= MAXDISPERSE 3199289764Sglebius || (m >= 2 && dst[i] >= sys_maxdist)) 320082505Sroberto continue; 320182505Sroberto m++; 320282505Sroberto } 3203282408Scy 320454359Sroberto /* 3205182007Sroberto * Compute the dispersion and jitter. The dispersion is weighted 3206182007Sroberto * exponentially by NTP_FWEIGHT (0.5) so it is normalized close 3207182007Sroberto * to 1.0. The jitter is the RMS differences relative to the 3208280849Scy * lowest delay sample. 320954359Sroberto */ 3210182007Sroberto peer->disp = peer->jitter = 0; 321182505Sroberto k = ord[0]; 321254359Sroberto for (i = NTP_SHIFT - 1; i >= 0; i--) { 321382505Sroberto j = ord[i]; 321482505Sroberto peer->disp = NTP_FWEIGHT * (peer->disp + 321582505Sroberto peer->filter_disp[j]); 321682505Sroberto if (i < m) 3217182007Sroberto peer->jitter += DIFF(peer->filter_offset[j], 321882505Sroberto peer->filter_offset[k]); 321954359Sroberto } 322054359Sroberto 322154359Sroberto /* 322282505Sroberto * If no acceptable samples remain in the shift register, 322382505Sroberto * quietly tiptoe home leaving only the dispersion. Otherwise, 3224182007Sroberto * save the offset, delay and jitter. Note the jitter must not 3225182007Sroberto * be less than the precision. 322682505Sroberto */ 3227280849Scy if (m == 0) { 3228280849Scy clock_select(); 322982505Sroberto return; 3230280849Scy } 3231132454Sroberto etemp = fabs(peer->offset - peer->filter_offset[k]); 323282505Sroberto peer->offset = peer->filter_offset[k]; 323382505Sroberto peer->delay = peer->filter_delay[k]; 323482505Sroberto if (m > 1) 3235182007Sroberto peer->jitter /= m - 1; 3236182007Sroberto peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision)); 323782505Sroberto 323882505Sroberto /* 3239280849Scy * If the the new sample and the current sample are both valid 3240280849Scy * and the difference between their offsets exceeds CLOCK_SGATE 3241280849Scy * (3) times the jitter and the interval between them is less 3242280849Scy * than twice the host poll interval, consider the new sample 3243280849Scy * a popcorn spike and ignore it. 324454359Sroberto */ 3245289764Sglebius if ( peer->disp < sys_maxdist 3246289764Sglebius && peer->filter_disp[k] < sys_maxdist 3247289764Sglebius && etemp > CLOCK_SGATE * peer->jitter 3248289764Sglebius && peer->filter_epoch[k] - peer->epoch 3249289764Sglebius < 2. * ULOGTOD(peer->hpoll)) { 3250280849Scy snprintf(tbuf, sizeof(tbuf), "%.6f s", etemp); 3251280849Scy report_event(PEVNT_POPCORN, peer, tbuf); 325254359Sroberto return; 325354359Sroberto } 325454359Sroberto 325554359Sroberto /* 3256280849Scy * A new minimum sample is useful only if it is later than the 3257280849Scy * last one used. In this design the maximum lifetime of any 3258280849Scy * sample is not greater than eight times the poll interval, so 3259280849Scy * the maximum interval between minimum samples is eight 3260280849Scy * packets. 326154359Sroberto */ 3262280849Scy if (peer->filter_epoch[k] <= peer->epoch) { 3263293423Sdelphij DPRINTF(2, ("clock_filter: old sample %lu\n", current_time - 3264293423Sdelphij peer->filter_epoch[k])); 326554359Sroberto return; 326654359Sroberto } 3267280849Scy peer->epoch = peer->filter_epoch[k]; 326882505Sroberto 326982505Sroberto /* 327082505Sroberto * The mitigated sample statistics are saved for later 3271280849Scy * processing. If not synchronized or not in a burst, tickle the 3272280849Scy * clock select algorithm. 327382505Sroberto */ 3274280849Scy record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), 3275280849Scy peer->offset, peer->delay, peer->disp, peer->jitter); 3276293423Sdelphij DPRINTF(1, ("clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f\n", 327782505Sroberto m, peer->offset, peer->delay, peer->disp, 3278293423Sdelphij peer->jitter)); 3279182007Sroberto if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) 3280182007Sroberto clock_select(); 328154359Sroberto} 328254359Sroberto 328354359Sroberto 328454359Sroberto/* 328554359Sroberto * clock_select - find the pick-of-the-litter clock 3286132454Sroberto * 3287280849Scy * LOCKCLOCK: (1) If the local clock is the prefer peer, it will always 3288280849Scy * be enabled, even if declared falseticker, (2) only the prefer peer 3289280849Scy * can be selected as the system peer, (3) if the external source is 3290280849Scy * down, the system leap bits are set to 11 and the stratum set to 3291280849Scy * infinity. 329254359Sroberto */ 329354359Srobertovoid 329454359Srobertoclock_select(void) 329554359Sroberto{ 3296132454Sroberto struct peer *peer; 3297132454Sroberto int i, j, k, n; 3298280849Scy int nlist, nl2; 3299280849Scy int allow; 3300280849Scy int speer; 3301182007Sroberto double d, e, f, g; 3302132454Sroberto double high, low; 3303280849Scy double speermet; 3304280849Scy double orphmet = 2.0 * U_INT32_MAX; /* 2x is greater than */ 3305280849Scy struct endpoint endp; 330654359Sroberto struct peer *osys_peer; 3307280849Scy struct peer *sys_prefer = NULL; /* prefer peer */ 3308280849Scy struct peer *typesystem = NULL; 3309280849Scy struct peer *typeorphan = NULL; 3310280849Scy#ifdef REFCLOCK 331182505Sroberto struct peer *typeacts = NULL; 331282505Sroberto struct peer *typelocal = NULL; 3313280849Scy struct peer *typepps = NULL; 3314280849Scy#endif /* REFCLOCK */ 331554359Sroberto static struct endpoint *endpoint = NULL; 331682505Sroberto static int *indx = NULL; 3317280849Scy static peer_select *peers = NULL; 331854359Sroberto static u_int endpoint_size = 0; 3319280849Scy static u_int peers_size = 0; 332082505Sroberto static u_int indx_size = 0; 3321280849Scy size_t octets; 332254359Sroberto 332354359Sroberto /* 332482505Sroberto * Initialize and create endpoint, index and peer lists big 332582505Sroberto * enough to handle all associations. 332654359Sroberto */ 332782505Sroberto osys_peer = sys_peer; 3328132454Sroberto sys_survivors = 0; 3329132454Sroberto#ifdef LOCKCLOCK 3330285169Scy set_sys_leap(LEAP_NOTINSYNC); 3331132454Sroberto sys_stratum = STRATUM_UNSPEC; 3332132454Sroberto memcpy(&sys_refid, "DOWN", 4); 3333132454Sroberto#endif /* LOCKCLOCK */ 333454359Sroberto 333554359Sroberto /* 3336280849Scy * Allocate dynamic space depending on the number of 3337280849Scy * associations. 3338280849Scy */ 3339280849Scy nlist = 1; 3340280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3341280849Scy nlist++; 3342280849Scy endpoint_size = ALIGNED_SIZE(nlist * 2 * sizeof(*endpoint)); 3343280849Scy peers_size = ALIGNED_SIZE(nlist * sizeof(*peers)); 3344280849Scy indx_size = ALIGNED_SIZE(nlist * 2 * sizeof(*indx)); 3345280849Scy octets = endpoint_size + peers_size + indx_size; 3346280849Scy endpoint = erealloc(endpoint, octets); 3347280849Scy peers = INC_ALIGNED_PTR(endpoint, endpoint_size); 3348280849Scy indx = INC_ALIGNED_PTR(peers, peers_size); 3349280849Scy 3350280849Scy /* 335182505Sroberto * Initially, we populate the island with all the rifraff peers 335282505Sroberto * that happen to be lying around. Those with seriously 335382505Sroberto * defective clocks are immediately booted off the island. Then, 335482505Sroberto * the falsetickers are culled and put to sea. The truechimers 335582505Sroberto * remaining are subject to repeated rounds where the most 335682505Sroberto * unpopular at each round is kicked off. When the population 3357132454Sroberto * has dwindled to sys_minclock, the survivors split a million 3358132454Sroberto * bucks and collectively crank the chimes. 335954359Sroberto */ 3360280849Scy nlist = nl2 = 0; /* none yet */ 3361280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) { 3362280849Scy peer->new_status = CTL_PST_SEL_REJECT; 336354359Sroberto 3364280849Scy /* 3365280849Scy * Leave the island immediately if the peer is 3366280849Scy * unfit to synchronize. 3367280849Scy */ 3368309007Sdelphij if (peer_unfit(peer)) { 3369280849Scy continue; 3370309007Sdelphij } 337182505Sroberto 3372280849Scy /* 3373280849Scy * If this peer is an orphan parent, elect the 3374280849Scy * one with the lowest metric defined as the 3375280849Scy * IPv4 address or the first 64 bits of the 3376280849Scy * hashed IPv6 address. To ensure convergence 3377280849Scy * on the same selected orphan, consider as 3378280849Scy * well that this system may have the lowest 3379280849Scy * metric and be the orphan parent. If this 3380280849Scy * system wins, sys_peer will be NULL to trigger 3381280849Scy * orphan mode in timer(). 3382280849Scy */ 3383280849Scy if (peer->stratum == sys_orphan) { 3384280849Scy u_int32 localmet; 3385280849Scy u_int32 peermet; 338654359Sroberto 3387280849Scy if (peer->dstadr != NULL) 3388280849Scy localmet = ntohl(peer->dstadr->addr_refid); 3389280849Scy else 3390280849Scy localmet = U_INT32_MAX; 3391280849Scy peermet = ntohl(addr2refid(&peer->srcadr)); 3392280849Scy if (peermet < localmet && peermet < orphmet) { 3393280849Scy typeorphan = peer; 3394280849Scy orphmet = peermet; 339554359Sroberto } 3396280849Scy continue; 3397280849Scy } 339854359Sroberto 3399280849Scy /* 3400280849Scy * If this peer could have the orphan parent 3401280849Scy * as a synchronization ancestor, exclude it 3402282408Scy * from selection to avoid forming a 3403280849Scy * synchronization loop within the orphan mesh, 3404282408Scy * triggering stratum climb to infinity 3405280849Scy * instability. Peers at stratum higher than 3406280849Scy * the orphan stratum could have the orphan 3407280849Scy * parent in ancestry so are excluded. 3408280849Scy * See http://bugs.ntp.org/2050 3409280849Scy */ 3410309007Sdelphij if (peer->stratum > sys_orphan) { 3411280849Scy continue; 3412309007Sdelphij } 3413280849Scy#ifdef REFCLOCK 3414280849Scy /* 3415280849Scy * The following are special cases. We deal 3416280849Scy * with them later. 3417280849Scy */ 3418280849Scy if (!(peer->flags & FLAG_PREFER)) { 3419280849Scy switch (peer->refclktype) { 3420280849Scy case REFCLK_LOCALCLOCK: 3421289764Sglebius if ( current_time > orphwait 3422289764Sglebius && typelocal == NULL) 3423280849Scy typelocal = peer; 3424280849Scy continue; 3425182007Sroberto 3426280849Scy case REFCLK_ACTS: 3427289764Sglebius if ( current_time > orphwait 3428289764Sglebius && typeacts == NULL) 3429280849Scy typeacts = peer; 3430280849Scy continue; 343154359Sroberto } 3432280849Scy } 3433280849Scy#endif /* REFCLOCK */ 343454359Sroberto 3435280849Scy /* 3436280849Scy * If we get this far, the peer can stay on the 3437280849Scy * island, but does not yet have the immunity 3438280849Scy * idol. 3439280849Scy */ 3440280849Scy peer->new_status = CTL_PST_SEL_SANE; 3441280849Scy f = root_distance(peer); 3442280849Scy peers[nlist].peer = peer; 3443280849Scy peers[nlist].error = peer->jitter; 3444280849Scy peers[nlist].synch = f; 3445280849Scy nlist++; 3446182007Sroberto 3447280849Scy /* 3448280849Scy * Insert each interval endpoint on the unsorted 3449280849Scy * endpoint[] list. 3450280849Scy */ 3451280849Scy e = peer->offset; 3452280849Scy endpoint[nl2].type = -1; /* lower end */ 3453280849Scy endpoint[nl2].val = e - f; 3454280849Scy nl2++; 3455280849Scy endpoint[nl2].type = 1; /* upper end */ 3456280849Scy endpoint[nl2].val = e + f; 3457280849Scy nl2++; 3458280849Scy } 3459280849Scy /* 3460280849Scy * Construct sorted indx[] of endpoint[] indexes ordered by 3461280849Scy * offset. 3462280849Scy */ 3463280849Scy for (i = 0; i < nl2; i++) 3464280849Scy indx[i] = i; 3465280849Scy for (i = 0; i < nl2; i++) { 3466280849Scy endp = endpoint[indx[i]]; 3467280849Scy e = endp.val; 3468280849Scy k = i; 3469280849Scy for (j = i + 1; j < nl2; j++) { 3470280849Scy endp = endpoint[indx[j]]; 3471280849Scy if (endp.val < e) { 3472280849Scy e = endp.val; 3473280849Scy k = j; 347454359Sroberto } 347554359Sroberto } 3476280849Scy if (k != i) { 3477280849Scy j = indx[k]; 3478280849Scy indx[k] = indx[i]; 3479280849Scy indx[i] = j; 3480280849Scy } 348154359Sroberto } 3482280849Scy for (i = 0; i < nl2; i++) 3483280849Scy DPRINTF(3, ("select: endpoint %2d %.6f\n", 3484280849Scy endpoint[indx[i]].type, endpoint[indx[i]].val)); 3485280849Scy 3486132454Sroberto /* 3487132454Sroberto * This is the actual algorithm that cleaves the truechimers 3488132454Sroberto * from the falsetickers. The original algorithm was described 3489132454Sroberto * in Keith Marzullo's dissertation, but has been modified for 3490132454Sroberto * better accuracy. 3491132454Sroberto * 3492132454Sroberto * Briefly put, we first assume there are no falsetickers, then 3493132454Sroberto * scan the candidate list first from the low end upwards and 3494132454Sroberto * then from the high end downwards. The scans stop when the 3495132454Sroberto * number of intersections equals the number of candidates less 3496132454Sroberto * the number of falsetickers. If this doesn't happen for a 3497132454Sroberto * given number of falsetickers, we bump the number of 3498132454Sroberto * falsetickers and try again. If the number of falsetickers 3499132454Sroberto * becomes equal to or greater than half the number of 3500132454Sroberto * candidates, the Albanians have won the Byzantine wars and 3501132454Sroberto * correct synchronization is not possible. 3502132454Sroberto * 3503132454Sroberto * Here, nlist is the number of candidates and allow is the 3504182007Sroberto * number of falsetickers. Upon exit, the truechimers are the 3505280849Scy * survivors with offsets not less than low and not greater than 3506182007Sroberto * high. There may be none of them. 3507132454Sroberto */ 3508132454Sroberto low = 1e9; 3509132454Sroberto high = -1e9; 3510132454Sroberto for (allow = 0; 2 * allow < nlist; allow++) { 3511132454Sroberto 3512132454Sroberto /* 3513282408Scy * Bound the interval (low, high) as the smallest 3514280849Scy * interval containing points from the most sources. 3515132454Sroberto */ 3516132454Sroberto n = 0; 3517280849Scy for (i = 0; i < nl2; i++) { 3518132454Sroberto low = endpoint[indx[i]].val; 3519132454Sroberto n -= endpoint[indx[i]].type; 3520132454Sroberto if (n >= nlist - allow) 352154359Sroberto break; 352254359Sroberto } 3523132454Sroberto n = 0; 3524280849Scy for (j = nl2 - 1; j >= 0; j--) { 3525132454Sroberto high = endpoint[indx[j]].val; 352682505Sroberto n += endpoint[indx[j]].type; 3527132454Sroberto if (n >= nlist - allow) 352854359Sroberto break; 352954359Sroberto } 3530132454Sroberto 3531132454Sroberto /* 3532132454Sroberto * If an interval containing truechimers is found, stop. 3533132454Sroberto * If not, increase the number of falsetickers and go 3534132454Sroberto * around again. 3535132454Sroberto */ 3536132454Sroberto if (high > low) 353754359Sroberto break; 353854359Sroberto } 353954359Sroberto 354054359Sroberto /* 3541280849Scy * Clustering algorithm. Whittle candidate list of falsetickers, 3542280849Scy * who leave the island immediately. The TRUE peer is always a 3543182007Sroberto * truechimer. We must leave at least one peer to collect the 3544280849Scy * million bucks. 3545280849Scy * 3546280849Scy * We assert the correct time is contained in the interval, but 3547280849Scy * the best offset estimate for the interval might not be 3548280849Scy * contained in the interval. For this purpose, a truechimer is 3549282408Scy * defined as the midpoint of an interval that overlaps the 3550280849Scy * intersection interval. 3551182007Sroberto */ 3552182007Sroberto j = 0; 3553182007Sroberto for (i = 0; i < nlist; i++) { 3554280849Scy double h; 3555280849Scy 3556280849Scy peer = peers[i].peer; 3557280849Scy h = peers[i].synch; 3558289764Sglebius if (( high <= low 3559289764Sglebius || peer->offset + h < low 3560289764Sglebius || peer->offset - h > high 3561289764Sglebius ) && !(peer->flags & FLAG_TRUE)) 3562182007Sroberto continue; 3563182007Sroberto 3564280849Scy#ifdef REFCLOCK 3565182007Sroberto /* 3566280849Scy * Eligible PPS peers must survive the intersection 3567280849Scy * algorithm. Use the first one found, but don't 3568280849Scy * include any of them in the cluster population. 3569182007Sroberto */ 3570280849Scy if (peer->flags & FLAG_PPS) { 3571282408Scy if (typepps == NULL) 3572280849Scy typepps = peer; 3573282408Scy if (!(peer->flags & FLAG_TSTAMP_PPS)) 3574282408Scy continue; 3575182007Sroberto } 3576280849Scy#endif /* REFCLOCK */ 3577182007Sroberto 3578280849Scy if (j != i) 3579280849Scy peers[j] = peers[i]; 3580182007Sroberto j++; 3581182007Sroberto } 3582182007Sroberto nlist = j; 3583182007Sroberto 3584182007Sroberto /* 3585282408Scy * If no survivors remain at this point, check if the modem 3586280849Scy * driver, local driver or orphan parent in that order. If so, 3587280849Scy * nominate the first one found as the only survivor. 3588280849Scy * Otherwise, give up and leave the island to the rats. 358954359Sroberto */ 3590182007Sroberto if (nlist == 0) { 3591280849Scy peers[0].error = 0; 3592280849Scy peers[0].synch = sys_mindisp; 3593280849Scy#ifdef REFCLOCK 3594280849Scy if (typeacts != NULL) { 3595280849Scy peers[0].peer = typeacts; 359654359Sroberto nlist = 1; 3597280849Scy } else if (typelocal != NULL) { 3598280849Scy peers[0].peer = typelocal; 359954359Sroberto nlist = 1; 3600280849Scy } else 3601280849Scy#endif /* REFCLOCK */ 3602280849Scy if (typeorphan != NULL) { 3603280849Scy peers[0].peer = typeorphan; 3604280849Scy nlist = 1; 360554359Sroberto } 360654359Sroberto } 360754359Sroberto 360854359Sroberto /* 3609280849Scy * Mark the candidates at this point as truechimers. 3610132454Sroberto */ 3611280849Scy for (i = 0; i < nlist; i++) { 3612280849Scy peers[i].peer->new_status = CTL_PST_SEL_SELCAND; 3613280849Scy DPRINTF(2, ("select: survivor %s %f\n", 3614280849Scy stoa(&peers[i].peer->srcadr), peers[i].synch)); 3615280849Scy } 3616132454Sroberto 361754359Sroberto /* 3618289764Sglebius * Now, vote outliers off the island by select jitter weighted 3619182007Sroberto * by root distance. Continue voting as long as there are more 3620280849Scy * than sys_minclock survivors and the select jitter of the peer 3621280849Scy * with the worst metric is greater than the minimum peer 3622282408Scy * jitter. Stop if we are about to discard a TRUE or PREFER 3623280849Scy * peer, who of course have the immunity idol. 362454359Sroberto */ 362554359Sroberto while (1) { 362682505Sroberto d = 1e9; 362782505Sroberto e = -1e9; 3628280849Scy g = 0; 362982505Sroberto k = 0; 363082505Sroberto for (i = 0; i < nlist; i++) { 3631280849Scy if (peers[i].error < d) 3632280849Scy d = peers[i].error; 3633280849Scy peers[i].seljit = 0; 363482505Sroberto if (nlist > 1) { 3635280849Scy f = 0; 363682505Sroberto for (j = 0; j < nlist; j++) 3637280849Scy f += DIFF(peers[j].peer->offset, 3638280849Scy peers[i].peer->offset); 3639280849Scy peers[i].seljit = SQRT(f / (nlist - 1)); 364054359Sroberto } 3641280849Scy if (peers[i].seljit * peers[i].synch > e) { 3642280849Scy g = peers[i].seljit; 3643280849Scy e = peers[i].seljit * peers[i].synch; 364454359Sroberto k = i; 364554359Sroberto } 364654359Sroberto } 3647280849Scy g = max(g, LOGTOD(sys_precision)); 3648289764Sglebius if ( nlist <= max(1, sys_minclock) 3649289764Sglebius || g <= d 3650289764Sglebius || ((FLAG_TRUE | FLAG_PREFER) & peers[k].peer->flags)) 3651132454Sroberto break; 3652280849Scy 3653280849Scy DPRINTF(3, ("select: drop %s seljit %.6f jit %.6f\n", 3654280849Scy ntoa(&peers[k].peer->srcadr), g, d)); 3655280849Scy if (nlist > sys_maxclock) 3656280849Scy peers[k].peer->new_status = CTL_PST_SEL_EXCESS; 3657280849Scy for (j = k + 1; j < nlist; j++) 3658280849Scy peers[j - 1] = peers[j]; 365954359Sroberto nlist--; 366054359Sroberto } 366182505Sroberto 366282505Sroberto /* 3663132454Sroberto * What remains is a list usually not greater than sys_minclock 3664280849Scy * peers. Note that unsynchronized peers cannot survive this 3665280849Scy * far. Count and mark these survivors. 3666280849Scy * 3667280849Scy * While at it, count the number of leap warning bits found. 3668280849Scy * This will be used later to vote the system leap warning bit. 3669280849Scy * If a leap warning bit is found on a reference clock, the vote 3670280849Scy * is always won. 3671280849Scy * 3672280849Scy * Choose the system peer using a hybrid metric composed of the 3673280849Scy * selection jitter scaled by the root distance augmented by 3674280849Scy * stratum scaled by sys_mindisp (.001 by default). The goal of 3675280849Scy * the small stratum factor is to avoid clockhop between a 3676280849Scy * reference clock and a network peer which has a refclock and 3677280849Scy * is using an older ntpd, which does not floor sys_rootdisp at 3678280849Scy * sys_mindisp. 3679280849Scy * 3680280849Scy * In contrast, ntpd 4.2.6 and earlier used stratum primarily 3681280849Scy * in selecting the system peer, using a weight of 1 second of 3682280849Scy * additional root distance per stratum. This heavy bias is no 3683280849Scy * longer appropriate, as the scaled root distance provides a 3684280849Scy * more rational metric carrying the cumulative error budget. 368554359Sroberto */ 3686280849Scy e = 1e9; 3687280849Scy speer = 0; 3688280849Scy leap_vote_ins = 0; 3689280849Scy leap_vote_del = 0; 3690182007Sroberto for (i = 0; i < nlist; i++) { 3691280849Scy peer = peers[i].peer; 3692280849Scy peer->unreach = 0; 3693280849Scy peer->new_status = CTL_PST_SEL_SYNCCAND; 3694182007Sroberto sys_survivors++; 3695280849Scy if (peer->leap == LEAP_ADDSECOND) { 3696280849Scy if (peer->flags & FLAG_REFCLOCK) 3697280849Scy leap_vote_ins = nlist; 3698280849Scy else if (leap_vote_ins < nlist) 3699280849Scy leap_vote_ins++; 3700280849Scy } 3701280849Scy if (peer->leap == LEAP_DELSECOND) { 3702280849Scy if (peer->flags & FLAG_REFCLOCK) 3703280849Scy leap_vote_del = nlist; 3704280849Scy else if (leap_vote_del < nlist) 3705280849Scy leap_vote_del++; 3706280849Scy } 3707132454Sroberto if (peer->flags & FLAG_PREFER) 3708132454Sroberto sys_prefer = peer; 3709280849Scy speermet = peers[i].seljit * peers[i].synch + 3710280849Scy peer->stratum * sys_mindisp; 3711280849Scy if (speermet < e) { 3712280849Scy e = speermet; 3713280849Scy speer = i; 3714280849Scy } 371554359Sroberto } 371654359Sroberto 371754359Sroberto /* 3718280849Scy * Unless there are at least sys_misane survivors, leave the 3719280849Scy * building dark. Otherwise, do a clockhop dance. Ordinarily, 3720280849Scy * use the selected survivor speer. However, if the current 3721280849Scy * system peer is not speer, stay with the current system peer 3722280849Scy * as long as it doesn't get too old or too ugly. 3723132454Sroberto */ 3724280849Scy if (nlist > 0 && nlist >= sys_minsane) { 3725280849Scy double x; 3726280849Scy 3727280849Scy typesystem = peers[speer].peer; 3728280849Scy if (osys_peer == NULL || osys_peer == typesystem) { 3729282408Scy sys_clockhop = 0; 3730280849Scy } else if ((x = fabs(typesystem->offset - 3731280849Scy osys_peer->offset)) < sys_mindisp) { 3732280849Scy if (sys_clockhop == 0) 3733280849Scy sys_clockhop = sys_mindisp; 3734280849Scy else 3735280849Scy sys_clockhop *= .5; 3736280849Scy DPRINTF(1, ("select: clockhop %d %.6f %.6f\n", 3737280849Scy j, x, sys_clockhop)); 3738280849Scy if (fabs(x) < sys_clockhop) 3739280849Scy typesystem = osys_peer; 3740280849Scy else 3741280849Scy sys_clockhop = 0; 3742280849Scy } else { 3743280849Scy sys_clockhop = 0; 3744280849Scy } 3745182007Sroberto } 3746132454Sroberto 3747132454Sroberto /* 3748280849Scy * Mitigation rules of the game. We have the pick of the 3749280849Scy * litter in typesystem if any survivors are left. If 3750280849Scy * there is a prefer peer, use its offset and jitter. 3751280849Scy * Otherwise, use the combined offset and jitter of all kitters. 375254359Sroberto */ 3753280849Scy if (typesystem != NULL) { 3754280849Scy if (sys_prefer == NULL) { 3755280849Scy typesystem->new_status = CTL_PST_SEL_SYSPEER; 3756280849Scy clock_combine(peers, sys_survivors, speer); 3757182007Sroberto } else { 3758280849Scy typesystem = sys_prefer; 3759280849Scy sys_clockhop = 0; 3760280849Scy typesystem->new_status = CTL_PST_SEL_SYSPEER; 3761280849Scy sys_offset = typesystem->offset; 3762280849Scy sys_jitter = typesystem->jitter; 3763182007Sroberto } 3764280849Scy DPRINTF(1, ("select: combine offset %.9f jitter %.9f\n", 3765280849Scy sys_offset, sys_jitter)); 3766280849Scy } 3767280849Scy#ifdef REFCLOCK 3768280849Scy /* 3769280849Scy * If a PPS driver is lit and the combined offset is less than 3770280849Scy * 0.4 s, select the driver as the PPS peer and use its offset 3771280849Scy * and jitter. However, if this is the atom driver, use it only 3772280849Scy * if there is a prefer peer or there are no survivors and none 3773280849Scy * are required. 3774280849Scy */ 3775289764Sglebius if ( typepps != NULL 3776289764Sglebius && fabs(sys_offset) < 0.4 3777289764Sglebius && ( typepps->refclktype != REFCLK_ATOM_PPS 3778289764Sglebius || ( typepps->refclktype == REFCLK_ATOM_PPS 3779289764Sglebius && ( sys_prefer != NULL 3780289764Sglebius || (typesystem == NULL && sys_minsane == 0))))) { 3781280849Scy typesystem = typepps; 3782280849Scy sys_clockhop = 0; 3783280849Scy typesystem->new_status = CTL_PST_SEL_PPS; 3784293423Sdelphij sys_offset = typesystem->offset; 3785280849Scy sys_jitter = typesystem->jitter; 3786280849Scy DPRINTF(1, ("select: pps offset %.9f jitter %.9f\n", 3787280849Scy sys_offset, sys_jitter)); 3788280849Scy } 3789280849Scy#endif /* REFCLOCK */ 3790182007Sroberto 3791280849Scy /* 3792280849Scy * If there are no survivors at this point, there is no 3793280849Scy * system peer. If so and this is an old update, keep the 3794280849Scy * current statistics, but do not update the clock. 3795280849Scy */ 3796280849Scy if (typesystem == NULL) { 3797280849Scy if (osys_peer != NULL) { 3798280849Scy if (sys_orphwait > 0) 3799280849Scy orphwait = current_time + sys_orphwait; 3800280849Scy report_event(EVNT_NOPEER, NULL, NULL); 3801182007Sroberto } 3802280849Scy sys_peer = NULL; 3803280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3804280849Scy peer->status = peer->new_status; 3805280849Scy return; 380654359Sroberto } 3807182007Sroberto 3808182007Sroberto /* 3809280849Scy * Do not use old data, as this may mess up the clock discipline 3810280849Scy * stability. 3811182007Sroberto */ 3812280849Scy if (typesystem->epoch <= sys_epoch) 3813280849Scy return; 3814132454Sroberto 3815280849Scy /* 3816280849Scy * We have found the alpha male. Wind the clock. 3817280849Scy */ 3818280849Scy if (osys_peer != typesystem) 3819280849Scy report_event(PEVNT_NEWPEER, typesystem, NULL); 3820280849Scy for (peer = peer_list; peer != NULL; peer = peer->p_link) 3821280849Scy peer->status = peer->new_status; 3822280849Scy clock_update(typesystem); 382354359Sroberto} 382454359Sroberto 3825182007Sroberto 3826182007Srobertostatic void 382754359Srobertoclock_combine( 3828280849Scy peer_select * peers, /* survivor list */ 3829280849Scy int npeers, /* number of survivors */ 3830280849Scy int syspeer /* index of sys.peer */ 383154359Sroberto ) 383254359Sroberto{ 3833132454Sroberto int i; 3834182007Sroberto double x, y, z, w; 3835132454Sroberto 3836182007Sroberto y = z = w = 0; 383754359Sroberto for (i = 0; i < npeers; i++) { 3838280849Scy x = 1. / peers[i].synch; 3839280849Scy y += x; 3840280849Scy z += x * peers[i].peer->offset; 3841280849Scy w += x * DIFF(peers[i].peer->offset, 3842280849Scy peers[syspeer].peer->offset); 384354359Sroberto } 3844182007Sroberto sys_offset = z / y; 3845280849Scy sys_jitter = SQRT(w / y + SQUARE(peers[syspeer].seljit)); 384654359Sroberto} 384754359Sroberto 3848280849Scy 384954359Sroberto/* 385054359Sroberto * root_distance - compute synchronization distance from peer to root 385154359Sroberto */ 385254359Srobertostatic double 385354359Srobertoroot_distance( 3854280849Scy struct peer *peer /* peer structure pointer */ 385554359Sroberto ) 385654359Sroberto{ 3857280849Scy double dtemp; 3858182007Sroberto 385982505Sroberto /* 3860280849Scy * Root Distance (LAMBDA) is defined as: 3861309007Sdelphij * (delta + DELTA)/2 + epsilon + EPSILON + D 3862280849Scy * 3863280849Scy * where: 3864280849Scy * delta is the round-trip delay 3865280849Scy * DELTA is the root delay 3866309007Sdelphij * epsilon is the peer dispersion 3867280849Scy * + (15 usec each second) 3868280849Scy * EPSILON is the root dispersion 3869309007Sdelphij * D is sys_jitter 3870280849Scy * 3871280849Scy * NB: Think hard about why we are using these values, and what 3872280849Scy * the alternatives are, and the various pros/cons. 3873280849Scy * 3874280849Scy * DLM thinks these are probably the best choices from any of the 3875280849Scy * other worse choices. 3876280849Scy */ 3877280849Scy dtemp = (peer->delay + peer->rootdelay) / 2 3878309007Sdelphij + peer->disp 3879280849Scy + clock_phi * (current_time - peer->update) 3880280849Scy + peer->rootdisp 3881280849Scy + peer->jitter; 3882280849Scy /* 388382505Sroberto * Careful squeak here. The value returned must be greater than 3884182007Sroberto * the minimum root dispersion in order to avoid clockhop with 3885280849Scy * highly precise reference clocks. Note that the root distance 3886280849Scy * cannot exceed the sys_maxdist, as this is the cutoff by the 3887280849Scy * selection algorithm. 388882505Sroberto */ 3889280849Scy if (dtemp < sys_mindisp) 3890280849Scy dtemp = sys_mindisp; 3891280849Scy return (dtemp); 389254359Sroberto} 389354359Sroberto 3894280849Scy 389554359Sroberto/* 389654359Sroberto * peer_xmit - send packet for persistent association. 389754359Sroberto */ 389854359Srobertostatic void 389954359Srobertopeer_xmit( 390054359Sroberto struct peer *peer /* peer structure pointer */ 390154359Sroberto ) 390254359Sroberto{ 390382505Sroberto struct pkt xpkt; /* transmit packet */ 3904280849Scy size_t sendlen, authlen; 3905182007Sroberto keyid_t xkeyid = 0; /* transmit key ID */ 3906280849Scy l_fp xmt_tx, xmt_ty; 390754359Sroberto 3908280849Scy if (!peer->dstadr) /* drop peers without interface */ 3909182007Sroberto return; 3910182007Sroberto 3911280849Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version, 3912280849Scy peer->hmode); 3913280849Scy xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 391454359Sroberto xpkt.ppoll = peer->hpoll; 391554359Sroberto xpkt.precision = sys_precision; 3916280849Scy xpkt.refid = sys_refid; 3917280849Scy xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 3918280849Scy xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); 391954359Sroberto HTONL_FP(&sys_reftime, &xpkt.reftime); 3920280849Scy HTONL_FP(&peer->rec, &xpkt.org); 3921280849Scy HTONL_FP(&peer->dst, &xpkt.rec); 392254359Sroberto 392354359Sroberto /* 392482505Sroberto * If the received packet contains a MAC, the transmitted packet 392582505Sroberto * is authenticated and contains a MAC. If not, the transmitted 392682505Sroberto * packet is not authenticated. 392782505Sroberto * 3928182007Sroberto * It is most important when autokey is in use that the local 3929182007Sroberto * interface IP address be known before the first packet is 3930182007Sroberto * sent. Otherwise, it is not possible to compute a correct MAC 3931182007Sroberto * the recipient will accept. Thus, the I/O semantics have to do 3932182007Sroberto * a little more work. In particular, the wildcard interface 3933182007Sroberto * might not be usable. 393454359Sroberto */ 393554359Sroberto sendlen = LEN_PKT_NOMAC; 3936293423Sdelphij if ( 3937280849Scy#ifdef AUTOKEY 3938293423Sdelphij !(peer->flags & FLAG_SKEY) && 3939280849Scy#endif /* !AUTOKEY */ 3940293423Sdelphij peer->keyid == 0) { 3941280849Scy 3942280849Scy /* 3943280849Scy * Transmit a-priori timestamps 3944280849Scy */ 3945280849Scy get_systime(&xmt_tx); 3946280849Scy if (peer->flip == 0) { /* basic mode */ 3947280849Scy peer->aorg = xmt_tx; 3948280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 3949280849Scy } else { /* interleaved modes */ 3950280849Scy if (peer->hmode == MODE_BROADCAST) { /* bcst */ 3951280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 3952280849Scy if (peer->flip > 0) 3953280849Scy HTONL_FP(&peer->borg, 3954280849Scy &xpkt.org); 3955280849Scy else 3956280849Scy HTONL_FP(&peer->aorg, 3957280849Scy &xpkt.org); 3958280849Scy } else { /* symmetric */ 3959280849Scy if (peer->flip > 0) 3960280849Scy HTONL_FP(&peer->borg, 3961280849Scy &xpkt.xmt); 3962280849Scy else 3963280849Scy HTONL_FP(&peer->aorg, 3964280849Scy &xpkt.xmt); 3965280849Scy } 3966280849Scy } 3967280849Scy peer->t21_bytes = sendlen; 3968316068Sdelphij sendpkt(&peer->srcadr, peer->dstadr, 3969316068Sdelphij sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl], 3970316068Sdelphij &xpkt, sendlen); 397182505Sroberto peer->sent++; 3972280849Scy peer->throttle += (1 << peer->minpoll) - 2; 3973280849Scy 3974280849Scy /* 3975280849Scy * Capture a-posteriori timestamps 3976280849Scy */ 3977280849Scy get_systime(&xmt_ty); 3978280849Scy if (peer->flip != 0) { /* interleaved modes */ 3979280849Scy if (peer->flip > 0) 3980280849Scy peer->aorg = xmt_ty; 3981280849Scy else 3982280849Scy peer->borg = xmt_ty; 3983280849Scy peer->flip = -peer->flip; 3984280849Scy } 3985280849Scy L_SUB(&xmt_ty, &xmt_tx); 3986280849Scy LFPTOD(&xmt_ty, peer->xleave); 3987293423Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d len %zu xmt %#010x.%08x\n", 3988293423Sdelphij current_time, 3989293423Sdelphij peer->dstadr ? stoa(&peer->dstadr->sin) : "-", 3990293423Sdelphij stoa(&peer->srcadr), peer->hmode, sendlen, 3991293423Sdelphij xmt_tx.l_ui, xmt_tx.l_uf)); 399282505Sroberto return; 399382505Sroberto } 399454359Sroberto 399582505Sroberto /* 3996280849Scy * Authentication is enabled, so the transmitted packet must be 3997280849Scy * authenticated. If autokey is enabled, fuss with the various 3998280849Scy * modes; otherwise, symmetric key cryptography is used. 399982505Sroberto */ 4000280849Scy#ifdef AUTOKEY 4001280849Scy if (peer->flags & FLAG_SKEY) { 4002132454Sroberto struct exten *exten; /* extension field */ 400382505Sroberto 400454359Sroberto /* 400582505Sroberto * The Public Key Dance (PKD): Cryptographic credentials 400682505Sroberto * are contained in extension fields, each including a 400782505Sroberto * 4-octet length/code word followed by a 4-octet 400882505Sroberto * association ID and optional additional data. Optional 400982505Sroberto * data includes a 4-octet data length field followed by 401082505Sroberto * the data itself. Request messages are sent from a 401182505Sroberto * configured association; response messages can be sent 401282505Sroberto * from a configured association or can take the fast 401382505Sroberto * path without ever matching an association. Response 401482505Sroberto * messages have the same code as the request, but have 401582505Sroberto * a response bit and possibly an error bit set. In this 401682505Sroberto * implementation, a message may contain no more than 4017280849Scy * one command and one or more responses. 401882505Sroberto * 401982505Sroberto * Cryptographic session keys include both a public and 402082505Sroberto * a private componet. Request and response messages 402182505Sroberto * using extension fields are always sent with the 402282505Sroberto * private component set to zero. Packets without 402382505Sroberto * extension fields indlude the private component when 402482505Sroberto * the session key is generated. 402554359Sroberto */ 402682505Sroberto while (1) { 4027282408Scy 402854359Sroberto /* 402982505Sroberto * Allocate and initialize a keylist if not 403082505Sroberto * already done. Then, use the list in inverse 403182505Sroberto * order, discarding keys once used. Keep the 403282505Sroberto * latest key around until the next one, so 403382505Sroberto * clients can use client/server packets to 403482505Sroberto * compute propagation delay. 403582505Sroberto * 403682505Sroberto * Note that once a key is used from the list, 403782505Sroberto * it is retained in the key cache until the 403882505Sroberto * next key is used. This is to allow a client 403982505Sroberto * to retrieve the encrypted session key 404082505Sroberto * identifier to verify authenticity. 404182505Sroberto * 404282505Sroberto * If for some reason a key is no longer in the 4043280849Scy * key cache, a birthday has happened or the key 4044280849Scy * has expired, so the pseudo-random sequence is 4045280849Scy * broken. In that case, purge the keylist and 4046280849Scy * regenerate it. 404754359Sroberto */ 404882505Sroberto if (peer->keynumber == 0) 404982505Sroberto make_keylist(peer, peer->dstadr); 405082505Sroberto else 405182505Sroberto peer->keynumber--; 405282505Sroberto xkeyid = peer->keylist[peer->keynumber]; 405382505Sroberto if (authistrusted(xkeyid)) 405482505Sroberto break; 405582505Sroberto else 405682505Sroberto key_expire(peer); 405754359Sroberto } 405882505Sroberto peer->keyid = xkeyid; 4059182007Sroberto exten = NULL; 406082505Sroberto switch (peer->hmode) { 406154359Sroberto 4062280849Scy /* 4063280849Scy * In broadcast server mode the autokey values are 4064280849Scy * required by the broadcast clients. Push them when a 4065280849Scy * new keylist is generated; otherwise, push the 4066280849Scy * association message so the client can request them at 4067280849Scy * other times. 4068280849Scy */ 406982505Sroberto case MODE_BROADCAST: 407082505Sroberto if (peer->flags & FLAG_ASSOC) 4071132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO | 4072280849Scy CRYPTO_RESP, peer->associd, NULL); 407382505Sroberto else 4074132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC | 4075280849Scy CRYPTO_RESP, peer->associd, NULL); 407682505Sroberto break; 407782505Sroberto 407854359Sroberto /* 4079282408Scy * In symmetric modes the parameter, certificate, 4080280849Scy * identity, cookie and autokey exchanges are 4081280849Scy * required. The leapsecond exchange is optional. But, a 4082280849Scy * peer will not believe the other peer until the other 4083280849Scy * peer has synchronized, so the certificate exchange 4084280849Scy * might loop until then. If a peer finds a broken 4085280849Scy * autokey sequence, it uses the autokey exchange to 4086280849Scy * retrieve the autokey values. In any case, if a new 4087280849Scy * keylist is generated, the autokey values are pushed. 408854359Sroberto */ 408982505Sroberto case MODE_ACTIVE: 409082505Sroberto case MODE_PASSIVE: 4091280849Scy 4092182007Sroberto /* 4093280849Scy * Parameter, certificate and identity. 4094182007Sroberto */ 409582505Sroberto if (!peer->crypto) 4096132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 4097280849Scy peer->associd, hostval.ptr); 4098280849Scy else if (!(peer->crypto & CRYPTO_FLAG_CERT)) 4099132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 4100280849Scy peer->associd, peer->issuer); 4101182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 4102182007Sroberto exten = crypto_args(peer, 4103280849Scy crypto_ident(peer), peer->associd, 4104280849Scy NULL); 4105132454Sroberto 4106132454Sroberto /* 4107280849Scy * Cookie and autokey. We request the cookie 4108280849Scy * only when the this peer and the other peer 4109280849Scy * are synchronized. But, this peer needs the 4110280849Scy * autokey values when the cookie is zero. Any 4111280849Scy * time we regenerate the key list, we offer the 4112280849Scy * autokey values without being asked. If for 4113280849Scy * some reason either peer finds a broken 4114280849Scy * autokey sequence, the autokey exchange is 4115280849Scy * used to retrieve the autokey values. 4116132454Sroberto */ 4117289764Sglebius else if ( sys_leap != LEAP_NOTINSYNC 4118289764Sglebius && peer->leap != LEAP_NOTINSYNC 4119289764Sglebius && !(peer->crypto & CRYPTO_FLAG_COOK)) 4120132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 4121280849Scy peer->associd, NULL); 4122132454Sroberto else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 4123132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 4124280849Scy peer->associd, NULL); 4125289764Sglebius else if ( peer->flags & FLAG_ASSOC 4126289764Sglebius && peer->crypto & CRYPTO_FLAG_SIGN) 4127280849Scy exten = crypto_args(peer, CRYPTO_AUTO | 4128280849Scy CRYPTO_RESP, peer->assoc, NULL); 4129132454Sroberto 4130132454Sroberto /* 4131280849Scy * Wait for clock sync, then sign the 4132280849Scy * certificate and retrieve the leapsecond 4133280849Scy * values. 4134132454Sroberto */ 4135280849Scy else if (sys_leap == LEAP_NOTINSYNC) 4136280849Scy break; 4137280849Scy 4138280849Scy else if (!(peer->crypto & CRYPTO_FLAG_SIGN)) 4139280849Scy exten = crypto_args(peer, CRYPTO_SIGN, 4140280849Scy peer->associd, hostval.ptr); 4141280849Scy else if (!(peer->crypto & CRYPTO_FLAG_LEAP)) 4142280849Scy exten = crypto_args(peer, CRYPTO_LEAP, 4143280849Scy peer->associd, NULL); 414482505Sroberto break; 414582505Sroberto 414682505Sroberto /* 4147280849Scy * In client mode the parameter, certificate, identity, 4148280849Scy * cookie and sign exchanges are required. The 4149280849Scy * leapsecond exchange is optional. If broadcast client 4150280849Scy * mode the same exchanges are required, except that the 4151280849Scy * autokey exchange is substitutes for the cookie 4152280849Scy * exchange, since the cookie is always zero. If the 4153280849Scy * broadcast client finds a broken autokey sequence, it 4154280849Scy * uses the autokey exchange to retrieve the autokey 4155280849Scy * values. 415682505Sroberto */ 415782505Sroberto case MODE_CLIENT: 4158280849Scy 4159182007Sroberto /* 4160280849Scy * Parameter, certificate and identity. 4161182007Sroberto */ 416282505Sroberto if (!peer->crypto) 4163132454Sroberto exten = crypto_args(peer, CRYPTO_ASSOC, 4164280849Scy peer->associd, hostval.ptr); 4165280849Scy else if (!(peer->crypto & CRYPTO_FLAG_CERT)) 4166132454Sroberto exten = crypto_args(peer, CRYPTO_CERT, 4167280849Scy peer->associd, peer->issuer); 4168182007Sroberto else if (!(peer->crypto & CRYPTO_FLAG_VRFY)) 4169182007Sroberto exten = crypto_args(peer, 4170280849Scy crypto_ident(peer), peer->associd, 4171280849Scy NULL); 4172132454Sroberto 4173132454Sroberto /* 4174280849Scy * Cookie and autokey. These are requests, but 4175280849Scy * we use the peer association ID with autokey 4176280849Scy * rather than our own. 4177132454Sroberto */ 4178280849Scy else if (!(peer->crypto & CRYPTO_FLAG_COOK)) 4179132454Sroberto exten = crypto_args(peer, CRYPTO_COOK, 4180280849Scy peer->associd, NULL); 4181280849Scy else if (!(peer->crypto & CRYPTO_FLAG_AUTO)) 4182132454Sroberto exten = crypto_args(peer, CRYPTO_AUTO, 4183280849Scy peer->assoc, NULL); 4184132454Sroberto 4185132454Sroberto /* 4186280849Scy * Wait for clock sync, then sign the 4187280849Scy * certificate and retrieve the leapsecond 4188280849Scy * values. 4189132454Sroberto */ 4190280849Scy else if (sys_leap == LEAP_NOTINSYNC) 4191280849Scy break; 4192280849Scy 4193280849Scy else if (!(peer->crypto & CRYPTO_FLAG_SIGN)) 4194132454Sroberto exten = crypto_args(peer, CRYPTO_SIGN, 4195280849Scy peer->associd, hostval.ptr); 4196280849Scy else if (!(peer->crypto & CRYPTO_FLAG_LEAP)) 4197280849Scy exten = crypto_args(peer, CRYPTO_LEAP, 4198280849Scy peer->associd, NULL); 419982505Sroberto break; 420082505Sroberto } 420182505Sroberto 420282505Sroberto /* 4203280849Scy * Add a queued extension field if present. This is 4204280849Scy * always a request message, so the reply ID is already 4205280849Scy * in the message. If an error occurs, the error bit is 4206280849Scy * lit in the response. 4207182007Sroberto */ 4208182007Sroberto if (peer->cmmd != NULL) { 4209280849Scy u_int32 temp32; 4210280849Scy 4211280849Scy temp32 = CRYPTO_RESP; 4212280849Scy peer->cmmd->opcode |= htonl(temp32); 4213280849Scy sendlen += crypto_xmit(peer, &xpkt, NULL, 4214280849Scy sendlen, peer->cmmd, 0); 4215182007Sroberto free(peer->cmmd); 4216182007Sroberto peer->cmmd = NULL; 4217182007Sroberto } 4218280849Scy 4219280849Scy /* 4220280849Scy * Add an extension field created above. All but the 4221280849Scy * autokey response message are request messages. 4222280849Scy */ 4223182007Sroberto if (exten != NULL) { 4224280849Scy if (exten->opcode != 0) 4225280849Scy sendlen += crypto_xmit(peer, &xpkt, 4226280849Scy NULL, sendlen, exten, 0); 4227182007Sroberto free(exten); 4228182007Sroberto } 4229182007Sroberto 4230182007Sroberto /* 4231280849Scy * Calculate the next session key. Since extension 4232280849Scy * fields are present, the cookie value is zero. 423382505Sroberto */ 4234280849Scy if (sendlen > (int)LEN_PKT_NOMAC) { 423582505Sroberto session_key(&peer->dstadr->sin, &peer->srcadr, 423682505Sroberto xkeyid, 0, 2); 4237182007Sroberto } 4238282408Scy } 4239280849Scy#endif /* AUTOKEY */ 4240182007Sroberto 4241182007Sroberto /* 4242280849Scy * Transmit a-priori timestamps 4243182007Sroberto */ 4244280849Scy get_systime(&xmt_tx); 4245280849Scy if (peer->flip == 0) { /* basic mode */ 4246280849Scy peer->aorg = xmt_tx; 4247280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4248280849Scy } else { /* interleaved modes */ 4249280849Scy if (peer->hmode == MODE_BROADCAST) { /* bcst */ 4250280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4251280849Scy if (peer->flip > 0) 4252280849Scy HTONL_FP(&peer->borg, &xpkt.org); 4253280849Scy else 4254280849Scy HTONL_FP(&peer->aorg, &xpkt.org); 4255280849Scy } else { /* symmetric */ 4256280849Scy if (peer->flip > 0) 4257280849Scy HTONL_FP(&peer->borg, &xpkt.xmt); 4258280849Scy else 4259280849Scy HTONL_FP(&peer->aorg, &xpkt.xmt); 4260280849Scy } 4261280849Scy } 426282505Sroberto xkeyid = peer->keyid; 426382505Sroberto authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 426482505Sroberto if (authlen == 0) { 4265280849Scy report_event(PEVNT_AUTH, peer, "no key"); 4266280849Scy peer->flash |= TEST5; /* auth error */ 4267280849Scy peer->badauth++; 426882505Sroberto return; 426982505Sroberto } 427082505Sroberto sendlen += authlen; 4271280849Scy#ifdef AUTOKEY 427282505Sroberto if (xkeyid > NTP_MAXKEY) 427382505Sroberto authtrust(xkeyid, 0); 4274280849Scy#endif /* AUTOKEY */ 427582505Sroberto if (sendlen > sizeof(xpkt)) { 4276293423Sdelphij msyslog(LOG_ERR, "peer_xmit: buffer overflow %zu", sendlen); 4277132454Sroberto exit (-1); 427882505Sroberto } 4279280849Scy peer->t21_bytes = sendlen; 4280316068Sdelphij sendpkt(&peer->srcadr, peer->dstadr, 4281316068Sdelphij sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl], 4282316068Sdelphij &xpkt, sendlen); 4283280849Scy peer->sent++; 4284280849Scy peer->throttle += (1 << peer->minpoll) - 2; 428582505Sroberto 428682505Sroberto /* 4287280849Scy * Capture a-posteriori timestamps 428882505Sroberto */ 4289280849Scy get_systime(&xmt_ty); 4290280849Scy if (peer->flip != 0) { /* interleaved modes */ 4291280849Scy if (peer->flip > 0) 4292280849Scy peer->aorg = xmt_ty; 4293280849Scy else 4294280849Scy peer->borg = xmt_ty; 4295280849Scy peer->flip = -peer->flip; 4296280849Scy } 4297280849Scy L_SUB(&xmt_ty, &xmt_tx); 4298280849Scy LFPTOD(&xmt_ty, peer->xleave); 4299280849Scy#ifdef AUTOKEY 4300293423Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n", 4301280849Scy current_time, latoa(peer->dstadr), 4302280849Scy ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen, 4303293423Sdelphij peer->keynumber)); 4304280849Scy#else /* !AUTOKEY follows */ 4305316068Sdelphij DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu\n", 4306280849Scy current_time, peer->dstadr ? 4307280849Scy ntoa(&peer->dstadr->sin) : "-", 4308293423Sdelphij ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen)); 4309280849Scy#endif /* !AUTOKEY */ 4310293423Sdelphij 4311293423Sdelphij return; 431254359Sroberto} 431354359Sroberto 431482505Sroberto 4315285169Scy#ifdef LEAP_SMEAR 4316285169Scy 4317285169Scystatic void 4318293423Sdelphijleap_smear_add_offs( 4319293423Sdelphij l_fp *t, 4320293423Sdelphij l_fp *t_recv 4321293423Sdelphij ) 4322293423Sdelphij{ 4323293423Sdelphij 4324285169Scy L_ADD(t, &leap_smear.offset); 4325293423Sdelphij 4326309007Sdelphij /* 4327309007Sdelphij ** XXX: Should the smear be added to the root dispersion? 4328309007Sdelphij */ 4329309007Sdelphij 4330293423Sdelphij return; 4331285169Scy} 4332285169Scy 4333285169Scy#endif /* LEAP_SMEAR */ 4334285169Scy 4335285169Scy 433654359Sroberto/* 433782505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that 433882505Sroberto * neither the source or destination can be a broadcast address. 433954359Sroberto */ 434054359Srobertostatic void 434154359Srobertofast_xmit( 434254359Sroberto struct recvbuf *rbufp, /* receive packet pointer */ 4343280849Scy int xmode, /* receive mode */ 4344132454Sroberto keyid_t xkeyid, /* transmit key ID */ 4345280849Scy int flags /* restrict mask */ 434654359Sroberto ) 434754359Sroberto{ 4348280849Scy struct pkt xpkt; /* transmit packet structure */ 4349280849Scy struct pkt *rpkt; /* receive packet structure */ 4350280849Scy l_fp xmt_tx, xmt_ty; 4351293423Sdelphij size_t sendlen; 4352280849Scy#ifdef AUTOKEY 4353132454Sroberto u_int32 temp32; 4354132454Sroberto#endif 435554359Sroberto 435654359Sroberto /* 435782505Sroberto * Initialize transmit packet header fields from the receive 4358280849Scy * buffer provided. We leave the fields intact as received, but 4359280849Scy * set the peer poll at the maximum of the receive peer poll and 4360280849Scy * the system minimum poll (ntp_minpoll). This is for KoD rate 4361280849Scy * control and not strictly specification compliant, but doesn't 4362280849Scy * break anything. 4363182007Sroberto * 4364280849Scy * If the gazinta was from a multicast address, the gazoutta 4365280849Scy * must go out another way. 436654359Sroberto */ 436754359Sroberto rpkt = &rbufp->recv_pkt; 4368182007Sroberto if (rbufp->dstadr->flags & INT_MCASTOPEN) 436982505Sroberto rbufp->dstadr = findinterface(&rbufp->recv_srcadr); 437082505Sroberto 437182505Sroberto /* 4372280849Scy * If this is a kiss-o'-death (KoD) packet, show leap 4373182007Sroberto * unsynchronized, stratum zero, reference ID the four-character 4374280849Scy * kiss code and system root delay. Note we don't reveal the 4375280849Scy * local time, so these packets can't be used for 4376280849Scy * synchronization. 4377182007Sroberto */ 4378280849Scy if (flags & RES_KOD) { 4379280849Scy sys_kodsent++; 4380132454Sroberto xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 4381132454Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 4382280849Scy xpkt.stratum = STRATUM_PKT_UNSPEC; 4383280849Scy xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll); 4384280849Scy xpkt.precision = rpkt->precision; 4385182007Sroberto memcpy(&xpkt.refid, "RATE", 4); 4386280849Scy xpkt.rootdelay = rpkt->rootdelay; 4387280849Scy xpkt.rootdisp = rpkt->rootdisp; 4388280849Scy xpkt.reftime = rpkt->reftime; 4389280849Scy xpkt.org = rpkt->xmt; 4390280849Scy xpkt.rec = rpkt->xmt; 4391280849Scy xpkt.xmt = rpkt->xmt; 4392182007Sroberto 4393182007Sroberto /* 4394182007Sroberto * This is a normal packet. Use the system variables. 4395182007Sroberto */ 4396280849Scy } else { 4397285169Scy#ifdef LEAP_SMEAR 4398285169Scy /* 4399285169Scy * Make copies of the variables which can be affected by smearing. 4400285169Scy */ 4401285169Scy l_fp this_ref_time; 4402285169Scy l_fp this_recv_time; 4403285169Scy#endif 4404285169Scy 4405285169Scy /* 4406285169Scy * If we are inside the leap smear interval we add the current smear offset to 4407285169Scy * the packet receive time, to the packet transmit time, and eventually to the 4408285169Scy * reftime to make sure the reftime isn't later than the transmit/receive times. 4409285169Scy */ 4410285169Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(xmt_leap, 441182505Sroberto PKT_VERSION(rpkt->li_vn_mode), xmode); 4412285169Scy 441382505Sroberto xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 4414280849Scy xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll); 4415280849Scy xpkt.precision = sys_precision; 441682505Sroberto xpkt.refid = sys_refid; 4417182007Sroberto xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 4418280849Scy xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); 4419285169Scy 4420285169Scy#ifdef LEAP_SMEAR 4421285169Scy this_ref_time = sys_reftime; 4422285169Scy if (leap_smear.in_progress) { 4423285169Scy leap_smear_add_offs(&this_ref_time, NULL); 4424285169Scy xpkt.refid = convertLFPToRefID(leap_smear.offset); 4425285169Scy DPRINTF(2, ("fast_xmit: leap_smear.in_progress: refid %8x, smear %s\n", 4426285169Scy ntohl(xpkt.refid), 4427285169Scy lfptoa(&leap_smear.offset, 8) 4428285169Scy )); 4429285169Scy } 4430285169Scy HTONL_FP(&this_ref_time, &xpkt.reftime); 4431285169Scy#else 4432280849Scy HTONL_FP(&sys_reftime, &xpkt.reftime); 4433285169Scy#endif 4434285169Scy 4435280849Scy xpkt.org = rpkt->xmt; 4436285169Scy 4437285169Scy#ifdef LEAP_SMEAR 4438285169Scy this_recv_time = rbufp->recv_time; 4439285169Scy if (leap_smear.in_progress) 4440285169Scy leap_smear_add_offs(&this_recv_time, NULL); 4441285169Scy HTONL_FP(&this_recv_time, &xpkt.rec); 4442285169Scy#else 4443280849Scy HTONL_FP(&rbufp->recv_time, &xpkt.rec); 4444285169Scy#endif 4445285169Scy 4446280849Scy get_systime(&xmt_tx); 4447285169Scy#ifdef LEAP_SMEAR 4448285169Scy if (leap_smear.in_progress) 4449285169Scy leap_smear_add_offs(&xmt_tx, &this_recv_time); 4450285169Scy#endif 4451280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4452280849Scy } 4453182007Sroberto 4454280849Scy#ifdef HAVE_NTP_SIGND 4455280849Scy if (flags & RES_MSSNTP) { 4456280849Scy send_via_ntp_signd(rbufp, xmode, xkeyid, flags, &xpkt); 4457280849Scy return; 445882505Sroberto } 4459280849Scy#endif /* HAVE_NTP_SIGND */ 446082505Sroberto 446182505Sroberto /* 446282505Sroberto * If the received packet contains a MAC, the transmitted packet 446382505Sroberto * is authenticated and contains a MAC. If not, the transmitted 446482505Sroberto * packet is not authenticated. 446582505Sroberto */ 446654359Sroberto sendlen = LEN_PKT_NOMAC; 446782505Sroberto if (rbufp->recv_length == sendlen) { 446882505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, 446956749Sroberto sendlen); 4470293423Sdelphij DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d len %lu\n", 4471132454Sroberto current_time, stoa(&rbufp->dstadr->sin), 4472293423Sdelphij stoa(&rbufp->recv_srcadr), xmode, 4473293423Sdelphij (u_long)sendlen)); 447482505Sroberto return; 447582505Sroberto } 447654359Sroberto 447782505Sroberto /* 447882505Sroberto * The received packet contains a MAC, so the transmitted packet 4479182007Sroberto * must be authenticated. For symmetric key cryptography, use 4480182007Sroberto * the predefined and trusted symmetric keys to generate the 4481182007Sroberto * cryptosum. For autokey cryptography, use the server private 4482182007Sroberto * value to generate the cookie, which is unique for every 4483182007Sroberto * source-destination-key ID combination. 448482505Sroberto */ 4485280849Scy#ifdef AUTOKEY 448682505Sroberto if (xkeyid > NTP_MAXKEY) { 448782505Sroberto keyid_t cookie; 448882505Sroberto 448954359Sroberto /* 449082505Sroberto * The only way to get here is a reply to a legitimate 449182505Sroberto * client request message, so the mode must be 449282505Sroberto * MODE_SERVER. If an extension field is present, there 449382505Sroberto * can be only one and that must be a command. Do what 449482505Sroberto * needs, but with private value of zero so the poor 449582505Sroberto * jerk can decode it. If no extension field is present, 449682505Sroberto * use the cookie to generate the session key. 449754359Sroberto */ 449882505Sroberto cookie = session_key(&rbufp->recv_srcadr, 449982505Sroberto &rbufp->dstadr->sin, 0, sys_private, 0); 4500293423Sdelphij if ((size_t)rbufp->recv_length > sendlen + MAX_MAC_LEN) { 450182505Sroberto session_key(&rbufp->dstadr->sin, 450282505Sroberto &rbufp->recv_srcadr, xkeyid, 0, 2); 4503132454Sroberto temp32 = CRYPTO_RESP; 4504132454Sroberto rpkt->exten[0] |= htonl(temp32); 4505280849Scy sendlen += crypto_xmit(NULL, &xpkt, rbufp, 4506280849Scy sendlen, (struct exten *)rpkt->exten, 4507280849Scy cookie); 450882505Sroberto } else { 450982505Sroberto session_key(&rbufp->dstadr->sin, 451082505Sroberto &rbufp->recv_srcadr, xkeyid, cookie, 2); 451182505Sroberto } 451282505Sroberto } 4513280849Scy#endif /* AUTOKEY */ 4514280849Scy get_systime(&xmt_tx); 4515280849Scy sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); 4516280849Scy#ifdef AUTOKEY 451782505Sroberto if (xkeyid > NTP_MAXKEY) 451882505Sroberto authtrust(xkeyid, 0); 4519280849Scy#endif /* AUTOKEY */ 452082505Sroberto sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); 4521280849Scy get_systime(&xmt_ty); 4522280849Scy L_SUB(&xmt_ty, &xmt_tx); 4523280849Scy sys_authdelay = xmt_ty; 4524293423Sdelphij DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d keyid %08x len %lu\n", 452582505Sroberto current_time, ntoa(&rbufp->dstadr->sin), 4526293423Sdelphij ntoa(&rbufp->recv_srcadr), xmode, xkeyid, 4527293423Sdelphij (u_long)sendlen)); 452854359Sroberto} 452954359Sroberto 453082505Sroberto 453154359Sroberto/* 4532280849Scy * pool_xmit - resolve hostname or send unicast solicitation for pool. 4533280849Scy */ 4534280849Scystatic void 4535280849Scypool_xmit( 4536280849Scy struct peer *pool /* pool solicitor association */ 4537280849Scy ) 4538280849Scy{ 4539280849Scy#ifdef WORKER 4540280849Scy struct pkt xpkt; /* transmit packet structure */ 4541280849Scy struct addrinfo hints; 4542280849Scy int rc; 4543280849Scy struct interface * lcladr; 4544280849Scy sockaddr_u * rmtadr; 4545330106Sdelphij r4addr r4a; 4546280849Scy int restrict_mask; 4547280849Scy struct peer * p; 4548280849Scy l_fp xmt_tx; 4549280849Scy 4550280849Scy if (NULL == pool->ai) { 4551280849Scy if (pool->addrs != NULL) { 4552280849Scy /* free() is used with copy_addrinfo_list() */ 4553280849Scy free(pool->addrs); 4554280849Scy pool->addrs = NULL; 4555280849Scy } 4556280849Scy ZERO(hints); 4557280849Scy hints.ai_family = AF(&pool->srcadr); 4558280849Scy hints.ai_socktype = SOCK_DGRAM; 4559280849Scy hints.ai_protocol = IPPROTO_UDP; 4560280849Scy /* ignore getaddrinfo_sometime() errors, we will retry */ 4561280849Scy rc = getaddrinfo_sometime( 4562280849Scy pool->hostname, 4563280849Scy "ntp", 4564280849Scy &hints, 4565280849Scy 0, /* no retry */ 4566280849Scy &pool_name_resolved, 4567280849Scy (void *)(intptr_t)pool->associd); 4568280849Scy if (!rc) 4569280849Scy DPRINTF(1, ("pool DNS lookup %s started\n", 4570280849Scy pool->hostname)); 4571280849Scy else 4572280849Scy msyslog(LOG_ERR, 4573289764Sglebius "unable to start pool DNS %s: %m", 4574280849Scy pool->hostname); 4575280849Scy return; 4576280849Scy } 4577280849Scy 4578280849Scy do { 4579280849Scy /* copy_addrinfo_list ai_addr points to a sockaddr_u */ 4580280849Scy rmtadr = (sockaddr_u *)(void *)pool->ai->ai_addr; 4581280849Scy pool->ai = pool->ai->ai_next; 4582330106Sdelphij p = findexistingpeer(rmtadr, NULL, NULL, MODE_CLIENT, 0, NULL); 4583280849Scy } while (p != NULL && pool->ai != NULL); 4584280849Scy if (p != NULL) 4585280849Scy return; /* out of addresses, re-query DNS next poll */ 4586330106Sdelphij restrictions(rmtadr, &r4a); 4587330106Sdelphij restrict_mask = r4a.rflags; 4588280849Scy if (RES_FLAGS & restrict_mask) 4589282408Scy restrict_source(rmtadr, 0, 4590280849Scy current_time + POOL_SOLICIT_WINDOW + 1); 4591280849Scy lcladr = findinterface(rmtadr); 4592280849Scy memset(&xpkt, 0, sizeof(xpkt)); 4593280849Scy xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, pool->version, 4594280849Scy MODE_CLIENT); 4595280849Scy xpkt.stratum = STRATUM_TO_PKT(sys_stratum); 4596280849Scy xpkt.ppoll = pool->hpoll; 4597280849Scy xpkt.precision = sys_precision; 4598280849Scy xpkt.refid = sys_refid; 4599280849Scy xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay)); 4600280849Scy xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp)); 4601280849Scy HTONL_FP(&sys_reftime, &xpkt.reftime); 4602280849Scy get_systime(&xmt_tx); 4603280849Scy pool->aorg = xmt_tx; 4604280849Scy HTONL_FP(&xmt_tx, &xpkt.xmt); 4605316068Sdelphij sendpkt(rmtadr, lcladr, 4606316068Sdelphij sys_ttl[(pool->ttl >= sys_ttlmax) ? sys_ttlmax : pool->ttl], 4607316068Sdelphij &xpkt, LEN_PKT_NOMAC); 4608280849Scy pool->sent++; 4609280849Scy pool->throttle += (1 << pool->minpoll) - 2; 4610293423Sdelphij DPRINTF(1, ("pool_xmit: at %ld %s->%s pool\n", 4611293423Sdelphij current_time, latoa(lcladr), stoa(rmtadr))); 4612280849Scy msyslog(LOG_INFO, "Soliciting pool server %s", stoa(rmtadr)); 4613280849Scy#endif /* WORKER */ 4614280849Scy} 4615280849Scy 4616280849Scy 4617280849Scy#ifdef AUTOKEY 4618280849Scy /* 4619280849Scy * group_test - test if this is the same group 4620280849Scy * 4621280849Scy * host assoc return action 4622280849Scy * none none 0 mobilize * 4623280849Scy * none group 0 mobilize * 4624280849Scy * group none 0 mobilize * 4625280849Scy * group group 1 mobilize 4626280849Scy * group different 1 ignore 4627280849Scy * * ignore if notrust 4628280849Scy */ 4629293423Sdelphijint 4630293423Sdelphijgroup_test( 4631280849Scy char *grp, 4632280849Scy char *ident 4633280849Scy ) 4634280849Scy{ 4635280849Scy if (grp == NULL) 4636280849Scy return (0); 4637280849Scy 4638280849Scy if (strcmp(grp, sys_groupname) == 0) 4639280849Scy return (0); 4640280849Scy 4641280849Scy if (ident == NULL) 4642280849Scy return (1); 4643280849Scy 4644280849Scy if (strcmp(grp, ident) == 0) 4645280849Scy return (0); 4646280849Scy 4647280849Scy return (1); 4648280849Scy} 4649280849Scy#endif /* AUTOKEY */ 4650280849Scy 4651298695Sdelphij 4652280849Scy#ifdef WORKER 4653280849Scyvoid 4654280849Scypool_name_resolved( 4655280849Scy int rescode, 4656280849Scy int gai_errno, 4657280849Scy void * context, 4658280849Scy const char * name, 4659280849Scy const char * service, 4660280849Scy const struct addrinfo * hints, 4661280849Scy const struct addrinfo * res 4662280849Scy ) 4663280849Scy{ 4664280849Scy struct peer * pool; /* pool solicitor association */ 4665280849Scy associd_t assoc; 4666280849Scy 4667280849Scy if (rescode) { 4668280849Scy msyslog(LOG_ERR, 4669280849Scy "error resolving pool %s: %s (%d)", 4670280849Scy name, gai_strerror(rescode), rescode); 4671280849Scy return; 4672280849Scy } 4673280849Scy 4674280849Scy assoc = (associd_t)(intptr_t)context; 4675280849Scy pool = findpeerbyassoc(assoc); 4676280849Scy if (NULL == pool) { 4677280849Scy msyslog(LOG_ERR, 4678280849Scy "Could not find assoc %u for pool DNS %s", 4679280849Scy assoc, name); 4680280849Scy return; 4681280849Scy } 4682280849Scy DPRINTF(1, ("pool DNS %s completed\n", name)); 4683280849Scy pool->addrs = copy_addrinfo_list(res); 4684280849Scy pool->ai = pool->addrs; 4685280849Scy pool_xmit(pool); 4686280849Scy 4687280849Scy} 4688280849Scy#endif /* WORKER */ 4689280849Scy 4690280849Scy 4691280849Scy#ifdef AUTOKEY 4692280849Scy/* 469382505Sroberto * key_expire - purge the key list 469454359Sroberto */ 469582505Srobertovoid 469682505Srobertokey_expire( 469782505Sroberto struct peer *peer /* peer structure pointer */ 469854359Sroberto ) 469954359Sroberto{ 470054359Sroberto int i; 470154359Sroberto 4702132454Sroberto if (peer->keylist != NULL) { 470382505Sroberto for (i = 0; i <= peer->keynumber; i++) 470482505Sroberto authtrust(peer->keylist[i], 0); 470582505Sroberto free(peer->keylist); 470682505Sroberto peer->keylist = NULL; 470754359Sroberto } 4708132454Sroberto value_free(&peer->sndval); 4709132454Sroberto peer->keynumber = 0; 4710280849Scy peer->flags &= ~FLAG_ASSOC; 4711293423Sdelphij DPRINTF(1, ("key_expire: at %lu associd %d\n", current_time, 4712293423Sdelphij peer->associd)); 471354359Sroberto} 4714280849Scy#endif /* AUTOKEY */ 471554359Sroberto 4716132454Sroberto 471754359Sroberto/* 4718280849Scy * local_refid(peer) - check peer refid to avoid selecting peers 4719280849Scy * currently synced to this ntpd. 4720280849Scy */ 4721280849Scystatic int 4722280849Scylocal_refid( 4723280849Scy struct peer * p 4724280849Scy ) 4725280849Scy{ 4726280849Scy endpt * unicast_ep; 4727280849Scy 4728280849Scy if (p->dstadr != NULL && !(INT_MCASTIF & p->dstadr->flags)) 4729280849Scy unicast_ep = p->dstadr; 4730280849Scy else 4731280849Scy unicast_ep = findinterface(&p->srcadr); 4732280849Scy 4733280849Scy if (unicast_ep != NULL && p->refid == unicast_ep->addr_refid) 4734280849Scy return TRUE; 4735280849Scy else 4736280849Scy return FALSE; 4737280849Scy} 4738280849Scy 4739280849Scy 4740280849Scy/* 4741132454Sroberto * Determine if the peer is unfit for synchronization 4742132454Sroberto * 4743132454Sroberto * A peer is unfit for synchronization if 4744182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling 4745280849Scy * > TEST11 root distance exceeded for remote peer 4746182007Sroberto * > TEST12 a direct or indirect synchronization loop would form 4747182007Sroberto * > TEST13 unreachable or noselect 4748132454Sroberto */ 4749182007Srobertoint /* FALSE if fit, TRUE if unfit */ 4750132454Srobertopeer_unfit( 4751132454Sroberto struct peer *peer /* peer structure pointer */ 4752132454Sroberto ) 4753132454Sroberto{ 4754182007Sroberto int rval = 0; 4755182007Sroberto 4756182007Sroberto /* 4757182007Sroberto * A stratum error occurs if (1) the server has never been 4758182007Sroberto * synchronized, (2) the server stratum is below the floor or 4759280849Scy * greater than or equal to the ceiling. 4760182007Sroberto */ 4761289764Sglebius if ( peer->leap == LEAP_NOTINSYNC 4762289764Sglebius || peer->stratum < sys_floor 4763309007Sdelphij || peer->stratum >= sys_ceiling) { 4764280849Scy rval |= TEST10; /* bad synch or stratum */ 4765309007Sdelphij } 4766182007Sroberto 4767182007Sroberto /* 4768280849Scy * A distance error for a remote peer occurs if the root 4769280849Scy * distance is greater than or equal to the distance threshold 4770280849Scy * plus the increment due to one host poll interval. 4771182007Sroberto */ 4772289764Sglebius if ( !(peer->flags & FLAG_REFCLOCK) 4773289764Sglebius && root_distance(peer) >= sys_maxdist 4774309007Sdelphij + clock_phi * ULOGTOD(peer->hpoll)) { 4775182007Sroberto rval |= TEST11; /* distance exceeded */ 4776309007Sdelphij } 4777182007Sroberto 4778182007Sroberto /* 4779182007Sroberto * A loop error occurs if the remote peer is synchronized to the 4780280849Scy * local peer or if the remote peer is synchronized to the same 4781280849Scy * server as the local peer but only if the remote peer is 4782280849Scy * neither a reference clock nor an orphan. 4783182007Sroberto */ 4784309007Sdelphij if (peer->stratum > 1 && local_refid(peer)) { 4785280849Scy rval |= TEST12; /* synchronization loop */ 4786309007Sdelphij } 4787182007Sroberto 4788182007Sroberto /* 4789182007Sroberto * An unreachable error occurs if the server is unreachable or 4790182007Sroberto * the noselect bit is set. 4791182007Sroberto */ 4792309007Sdelphij if (!peer->reach || (peer->flags & FLAG_NOSELECT)) { 4793182007Sroberto rval |= TEST13; /* unreachable */ 4794309007Sdelphij } 4795182007Sroberto 4796182007Sroberto peer->flash &= ~PEER_TEST_MASK; 4797182007Sroberto peer->flash |= rval; 4798182007Sroberto return (rval); 4799132454Sroberto} 4800132454Sroberto 4801132454Sroberto 4802132454Sroberto/* 480354359Sroberto * Find the precision of this particular machine 480454359Sroberto */ 4805280849Scy#define MINSTEP 20e-9 /* minimum clock increment (s) */ 4806280849Scy#define MAXSTEP 1 /* maximum clock increment (s) */ 4807280849Scy#define MINCHANGES 12 /* minimum number of step samples */ 4808280849Scy#define MAXLOOPS ((int)(1. / MINSTEP)) /* avoid infinite loop */ 480954359Sroberto 481054359Sroberto/* 4811280849Scy * This routine measures the system precision defined as the minimum of 4812280849Scy * a sequence of differences between successive readings of the system 4813280849Scy * clock. However, if a difference is less than MINSTEP, the clock has 4814280849Scy * been read more than once during a clock tick and the difference is 4815280849Scy * ignored. We set MINSTEP greater than zero in case something happens 4816280849Scy * like a cache miss, and to tolerate underlying system clocks which 4817280849Scy * ensure each reading is strictly greater than prior readings while 4818280849Scy * using an underlying stepping (not interpolated) clock. 4819132454Sroberto * 4820280849Scy * sys_tick and sys_precision represent the time to read the clock for 4821280849Scy * systems with high-precision clocks, and the tick interval or step 4822280849Scy * size for lower-precision stepping clocks. 4823280849Scy * 4824280849Scy * This routine also measures the time to read the clock on stepping 4825280849Scy * system clocks by counting the number of readings between changes of 4826280849Scy * the underlying clock. With either type of clock, the minimum time 4827280849Scy * to read the clock is saved as sys_fuzz, and used to ensure the 4828280849Scy * get_systime() readings always increase and are fuzzed below sys_fuzz. 482954359Sroberto */ 4830280849Scyvoid 4831280849Scymeasure_precision(void) 483254359Sroberto{ 4833280849Scy /* 4834280849Scy * With sys_fuzz set to zero, get_systime() fuzzing of low bits 4835280849Scy * is effectively disabled. trunc_os_clock is FALSE to disable 4836280849Scy * get_ostime() simulation of a low-precision system clock. 4837280849Scy */ 4838280849Scy set_sys_fuzz(0.); 4839280849Scy trunc_os_clock = FALSE; 4840280849Scy measured_tick = measure_tick_fuzz(); 4841280849Scy set_sys_tick_precision(measured_tick); 4842280849Scy msyslog(LOG_INFO, "proto: precision = %.3f usec (%d)", 4843280849Scy sys_tick * 1e6, sys_precision); 4844280849Scy if (sys_fuzz < sys_tick) { 4845280849Scy msyslog(LOG_NOTICE, "proto: fuzz beneath %.3f usec", 4846280849Scy sys_fuzz * 1e6); 4847280849Scy } 4848280849Scy} 4849280849Scy 4850280849Scy 4851280849Scy/* 4852280849Scy * measure_tick_fuzz() 4853280849Scy * 4854280849Scy * measures the minimum time to read the clock (stored in sys_fuzz) 4855280849Scy * and returns the tick, the larger of the minimum increment observed 4856280849Scy * between successive clock readings and the time to read the clock. 4857280849Scy */ 4858280849Scydouble 4859280849Scymeasure_tick_fuzz(void) 4860280849Scy{ 4861280849Scy l_fp minstep; /* MINSTEP as l_fp */ 4862132454Sroberto l_fp val; /* current seconds fraction */ 4863132454Sroberto l_fp last; /* last seconds fraction */ 4864280849Scy l_fp ldiff; /* val - last */ 4865132454Sroberto double tick; /* computed tick value */ 4866280849Scy double diff; 4867280849Scy long repeats; 4868280849Scy long max_repeats; 4869280849Scy int changes; 4870132454Sroberto int i; /* log2 precision */ 487154359Sroberto 4872280849Scy tick = MAXSTEP; 4873280849Scy max_repeats = 0; 4874280849Scy repeats = 0; 4875280849Scy changes = 0; 4876280849Scy DTOLFP(MINSTEP, &minstep); 4877132454Sroberto get_systime(&last); 4878280849Scy for (i = 0; i < MAXLOOPS && changes < MINCHANGES; i++) { 4879132454Sroberto get_systime(&val); 4880280849Scy ldiff = val; 4881280849Scy L_SUB(&ldiff, &last); 4882132454Sroberto last = val; 4883280849Scy if (L_ISGT(&ldiff, &minstep)) { 4884280849Scy max_repeats = max(repeats, max_repeats); 4885280849Scy repeats = 0; 4886280849Scy changes++; 4887280849Scy LFPTOD(&ldiff, diff); 4888280849Scy tick = min(diff, tick); 4889280849Scy } else { 4890280849Scy repeats++; 4891280849Scy } 489254359Sroberto } 4893280849Scy if (changes < MINCHANGES) { 4894280849Scy msyslog(LOG_ERR, "Fatal error: precision could not be measured (MINSTEP too large?)"); 4895280849Scy exit(1); 4896280849Scy } 4897132454Sroberto 4898280849Scy if (0 == max_repeats) { 4899280849Scy set_sys_fuzz(tick); 4900280849Scy } else { 4901280849Scy set_sys_fuzz(tick / max_repeats); 4902280849Scy } 4903280849Scy 4904280849Scy return tick; 4905280849Scy} 4906280849Scy 4907280849Scy 4908280849Scyvoid 4909280849Scyset_sys_tick_precision( 4910280849Scy double tick 4911280849Scy ) 4912280849Scy{ 4913280849Scy int i; 4914280849Scy 4915280849Scy if (tick > 1.) { 4916280849Scy msyslog(LOG_ERR, 4917280849Scy "unsupported tick %.3f > 1s ignored", tick); 4918280849Scy return; 4919280849Scy } 4920280849Scy if (tick < measured_tick) { 4921280849Scy msyslog(LOG_ERR, 4922280849Scy "proto: tick %.3f less than measured tick %.3f, ignored", 4923280849Scy tick, measured_tick); 4924280849Scy return; 4925280849Scy } else if (tick > measured_tick) { 4926280849Scy trunc_os_clock = TRUE; 4927280849Scy msyslog(LOG_NOTICE, 4928280849Scy "proto: truncating system clock to multiples of %.9f", 4929280849Scy tick); 4930280849Scy } 4931280849Scy sys_tick = tick; 4932280849Scy 4933132454Sroberto /* 4934132454Sroberto * Find the nearest power of two. 4935132454Sroberto */ 4936280849Scy for (i = 0; tick <= 1; i--) 4937132454Sroberto tick *= 2; 4938280849Scy if (tick - 1 > 1 - tick / 2) 4939280849Scy i++; 494054359Sroberto 4941280849Scy sys_precision = (s_char)i; 4942132454Sroberto} 4943132454Sroberto 4944132454Sroberto 4945132454Sroberto/* 494654359Sroberto * init_proto - initialize the protocol module's data 494754359Sroberto */ 494854359Srobertovoid 494954359Srobertoinit_proto(void) 495054359Sroberto{ 4951132454Sroberto l_fp dummy; 4952132454Sroberto int i; 495354359Sroberto 495454359Sroberto /* 495554359Sroberto * Fill in the sys_* stuff. Default is don't listen to 4956280849Scy * broadcasting, require authentication. 495754359Sroberto */ 4958285169Scy set_sys_leap(LEAP_NOTINSYNC); 495954359Sroberto sys_stratum = STRATUM_UNSPEC; 4960132454Sroberto memcpy(&sys_refid, "INIT", 4); 4961280849Scy sys_peer = NULL; 496254359Sroberto sys_rootdelay = 0; 4963280849Scy sys_rootdisp = 0; 496454359Sroberto L_CLR(&sys_reftime); 4965280849Scy sys_jitter = 0; 4966280849Scy measure_precision(); 4967280849Scy get_systime(&dummy); 496882505Sroberto sys_survivors = 0; 4969132454Sroberto sys_manycastserver = 0; 497054359Sroberto sys_bclient = 0; 4971298695Sdelphij sys_bdelay = BDELAY_DEFAULT; /*[Bug 3031] delay cutoff */ 497254359Sroberto sys_authenticate = 1; 4973280849Scy sys_stattime = current_time; 4974280849Scy orphwait = current_time + sys_orphwait; 4975132454Sroberto proto_clr_stats(); 4976316068Sdelphij for (i = 0; i < MAX_TTL; ++i) 4977132454Sroberto sys_ttl[i] = (u_char)((i * 256) / MAX_TTL); 4978316068Sdelphij sys_ttlmax = (MAX_TTL - 1); 4979280849Scy hardpps_enable = 0; 498054359Sroberto stats_control = 1; 498154359Sroberto} 498254359Sroberto 498354359Sroberto 498454359Sroberto/* 498554359Sroberto * proto_config - configure the protocol module 498654359Sroberto */ 498754359Srobertovoid 498854359Srobertoproto_config( 4989132454Sroberto int item, 4990132454Sroberto u_long value, 4991132454Sroberto double dvalue, 4992280849Scy sockaddr_u *svalue 499354359Sroberto ) 499454359Sroberto{ 499554359Sroberto /* 499654359Sroberto * Figure out what he wants to change, then do it 499754359Sroberto */ 4998280849Scy DPRINTF(2, ("proto_config: code %d value %lu dvalue %lf\n", 4999280849Scy item, value, dvalue)); 5000280849Scy 500154359Sroberto switch (item) { 5002132454Sroberto 5003132454Sroberto /* 5004280849Scy * enable and disable commands - arguments are Boolean. 5005132454Sroberto */ 5006280849Scy case PROTO_AUTHENTICATE: /* authentication (auth) */ 5007280849Scy sys_authenticate = value; 500854359Sroberto break; 500954359Sroberto 5010280849Scy case PROTO_BROADCLIENT: /* broadcast client (bclient) */ 5011280849Scy sys_bclient = (int)value; 5012280849Scy if (sys_bclient == 0) 5013280849Scy io_unsetbclient(); 5014280849Scy else 5015280849Scy io_setbclient(); 501654359Sroberto break; 501754359Sroberto 5018280849Scy#ifdef REFCLOCK 5019280849Scy case PROTO_CAL: /* refclock calibrate (calibrate) */ 5020280849Scy cal_enable = value; 5021280849Scy break; 5022280849Scy#endif /* REFCLOCK */ 5023280849Scy 5024280849Scy case PROTO_KERNEL: /* kernel discipline (kernel) */ 5025280849Scy select_loop(value); 5026280849Scy break; 5027280849Scy 5028280849Scy case PROTO_MONITOR: /* monitoring (monitor) */ 502954359Sroberto if (value) 503054359Sroberto mon_start(MON_ON); 5031285169Scy else { 503254359Sroberto mon_stop(MON_ON); 5033285169Scy if (mon_enabled) 5034285169Scy msyslog(LOG_WARNING, 5035285169Scy "restrict: 'monitor' cannot be disabled while 'limited' is enabled"); 5036285169Scy } 503754359Sroberto break; 503854359Sroberto 5039280849Scy case PROTO_NTP: /* NTP discipline (ntp) */ 5040280849Scy ntp_enable = value; 504154359Sroberto break; 504254359Sroberto 5043280849Scy case PROTO_MODE7: /* mode7 management (ntpdc) */ 5044280849Scy ntp_mode7 = value; 504554359Sroberto break; 504654359Sroberto 5047280849Scy case PROTO_PPS: /* PPS discipline (pps) */ 5048280849Scy hardpps_enable = value; 5049182007Sroberto break; 5050182007Sroberto 5051280849Scy case PROTO_FILEGEN: /* statistics (stats) */ 5052280849Scy stats_control = value; 505354359Sroberto break; 505454359Sroberto 5055132454Sroberto /* 5056280849Scy * tos command - arguments are double, sometimes cast to int 5057132454Sroberto */ 5058309007Sdelphij 5059309007Sdelphij case PROTO_BCPOLLBSTEP: /* Broadcast Poll Backstep gate (bcpollbstep) */ 5060309007Sdelphij sys_bcpollbstep = (u_char)dvalue; 5061309007Sdelphij break; 5062309007Sdelphij 5063280849Scy case PROTO_BEACON: /* manycast beacon (beacon) */ 5064280849Scy sys_beacon = (int)dvalue; 506554359Sroberto break; 506654359Sroberto 5067280849Scy case PROTO_BROADDELAY: /* default broadcast delay (bdelay) */ 5068298695Sdelphij sys_bdelay = (dvalue ? dvalue : BDELAY_DEFAULT); 506954359Sroberto break; 507054359Sroberto 5071280849Scy case PROTO_CEILING: /* stratum ceiling (ceiling) */ 5072280849Scy sys_ceiling = (int)dvalue; 5073132454Sroberto break; 5074132454Sroberto 5075280849Scy case PROTO_COHORT: /* cohort switch (cohort) */ 5076280849Scy sys_cohort = (int)dvalue; 507754359Sroberto break; 507854359Sroberto 5079280849Scy case PROTO_FLOOR: /* stratum floor (floor) */ 5080280849Scy sys_floor = (int)dvalue; 508182505Sroberto break; 508282505Sroberto 5083280849Scy case PROTO_MAXCLOCK: /* maximum candidates (maxclock) */ 5084182007Sroberto sys_maxclock = (int)dvalue; 5085132454Sroberto break; 5086132454Sroberto 5087280849Scy case PROTO_MAXDIST: /* select threshold (maxdist) */ 5088280849Scy sys_maxdist = dvalue; 5089132454Sroberto break; 5090132454Sroberto 5091280849Scy case PROTO_CALLDELAY: /* modem call delay (mdelay) */ 5092280849Scy break; /* NOT USED */ 5093132454Sroberto 5094280849Scy case PROTO_MINCLOCK: /* minimum candidates (minclock) */ 5095280849Scy sys_minclock = (int)dvalue; 5096132454Sroberto break; 5097132454Sroberto 5098280849Scy case PROTO_MINDISP: /* minimum distance (mindist) */ 5099280849Scy sys_mindisp = dvalue; 5100182007Sroberto break; 5101182007Sroberto 5102280849Scy case PROTO_MINSANE: /* minimum survivors (minsane) */ 5103280849Scy sys_minsane = (int)dvalue; 5104132454Sroberto break; 5105182007Sroberto 5106280849Scy case PROTO_ORPHAN: /* orphan stratum (orphan) */ 5107280849Scy sys_orphan = (int)dvalue; 5108182007Sroberto break; 5109182007Sroberto 5110280849Scy case PROTO_ORPHWAIT: /* orphan wait (orphwait) */ 5111280849Scy orphwait -= sys_orphwait; 5112280849Scy sys_orphwait = (int)dvalue; 5113280849Scy orphwait += sys_orphwait; 5114182007Sroberto break; 5115182007Sroberto 5116182007Sroberto /* 5117280849Scy * Miscellaneous commands 5118182007Sroberto */ 5119280849Scy case PROTO_MULTICAST_ADD: /* add group address */ 5120280849Scy if (svalue != NULL) 5121280849Scy io_multicast_add(svalue); 5122280849Scy sys_bclient = 1; 5123182007Sroberto break; 5124182007Sroberto 5125280849Scy case PROTO_MULTICAST_DEL: /* delete group address */ 5126280849Scy if (svalue != NULL) 5127280849Scy io_multicast_del(svalue); 5128132454Sroberto break; 5129132454Sroberto 5130294554Sdelphij /* 5131301247Sdelphij * Peer_clear Early policy choices 5132301247Sdelphij */ 5133301247Sdelphij 5134301247Sdelphij case PROTO_PCEDIGEST: /* Digest */ 5135301247Sdelphij peer_clear_digest_early = value; 5136301247Sdelphij break; 5137301247Sdelphij 5138301247Sdelphij /* 5139294554Sdelphij * Unpeer Early policy choices 5140294554Sdelphij */ 5141294554Sdelphij 5142294554Sdelphij case PROTO_UECRYPTO: /* Crypto */ 5143294554Sdelphij unpeer_crypto_early = value; 5144294554Sdelphij break; 5145294554Sdelphij 5146294554Sdelphij case PROTO_UECRYPTONAK: /* Crypto_NAK */ 5147294554Sdelphij unpeer_crypto_nak_early = value; 5148294554Sdelphij break; 5149294554Sdelphij 5150294554Sdelphij case PROTO_UEDIGEST: /* Digest */ 5151294554Sdelphij unpeer_digest_early = value; 5152294554Sdelphij break; 5153294554Sdelphij 515456749Sroberto default: 5155280849Scy msyslog(LOG_NOTICE, 5156280849Scy "proto: unsupported option %d", item); 515754359Sroberto } 515854359Sroberto} 515954359Sroberto 516054359Sroberto 516154359Sroberto/* 516254359Sroberto * proto_clr_stats - clear protocol stat counters 516354359Sroberto */ 516454359Srobertovoid 516554359Srobertoproto_clr_stats(void) 516654359Sroberto{ 5167132454Sroberto sys_stattime = current_time; 5168132454Sroberto sys_received = 0; 5169132454Sroberto sys_processed = 0; 5170280849Scy sys_newversion = 0; 5171280849Scy sys_oldversion = 0; 5172280849Scy sys_declined = 0; 5173132454Sroberto sys_restricted = 0; 517454359Sroberto sys_badlength = 0; 517554359Sroberto sys_badauth = 0; 517654359Sroberto sys_limitrejected = 0; 5177280849Scy sys_kodsent = 0; 5178330106Sdelphij sys_lamport = 0; 5179330106Sdelphij sys_tsrounding = 0; 518054359Sroberto} 5181