]> git.ipfire.org Git - thirdparty/chrony.git/blame - ntp_core.c
test: use env shebang in all bash scripts
[thirdparty/chrony.git] / ntp_core.c
CommitLineData
88840341 1/*
88840341
RC
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
6672f045 5 * Copyright (C) Richard P. Curnow 1997-2003
3916c336 6 * Copyright (C) Miroslav Lichvar 2009-2020
88840341
RC
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
8e23110a 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
88840341
RC
20 *
21 **********************************************************************
22
23 =======================================================================
24
25 Core NTP protocol engine
26 */
27
da2c8d90
ML
28#include "config.h"
29
88840341
RC
30#include "sysincl.h"
31
a78bf0c3 32#include "array.h"
ca28dbd2 33#include "ntp_auth.h"
88840341
RC
34#include "ntp_core.h"
35#include "ntp_io.h"
36#include "memory.h"
37#include "sched.h"
38#include "reference.h"
39#include "local.h"
189aafde 40#include "samplefilt.h"
7f45eb79 41#include "smooth.h"
88840341
RC
42#include "sources.h"
43#include "util.h"
44#include "conf.h"
45#include "logging.h"
88840341 46#include "addrfilt.h"
88840341
RC
47#include "clientlog.h"
48
49/* ================================================== */
88840341 50
e78e65ef 51static LOG_FileID logfileid;
0a0aff14 52static int log_raw_measurements;
88840341 53
88840341
RC
54/* ================================================== */
55/* Enumeration used for remembering the operating mode of one of the
56 sources */
57
58typedef enum {
59 MD_OFFLINE, /* No sampling at all */
60 MD_ONLINE, /* Normal sampling based on sampling interval */
61 MD_BURST_WAS_OFFLINE, /* Burst sampling, return to offline afterwards */
62 MD_BURST_WAS_ONLINE, /* Burst sampling, return to online afterwards */
63} OperatingMode;
64
65/* ================================================== */
66/* Structure used for holding a single peer/server's
67 protocol machine */
68
69struct NCR_Instance_Record {
70 NTP_Remote_Address remote_addr; /* Needed for routing transmit packets */
9a657cd4 71 NTP_Local_Address local_addr; /* Local address/socket used to send packets */
88840341
RC
72 NTP_Mode mode; /* The source's NTP mode
73 (client/server or symmetric active peer) */
90b25f5b 74 int interleaved; /* Boolean enabling interleaved NTP mode */
88840341
RC
75 OperatingMode opmode; /* Whether we are sampling this source
76 or not and in what way */
cbd77c97
ML
77 SCH_TimeoutID rx_timeout_id; /* Timeout ID for latest received response */
78 SCH_TimeoutID tx_timeout_id; /* Timeout ID for next transmission */
779e40ed 79 int tx_suspended; /* Boolean indicating we can't transmit yet */
88840341 80
b0fe4436 81 int auto_iburst; /* If 1, initiate a burst when going online */
d0eb9427 82 int auto_burst; /* If 1, initiate a burst on each poll */
7637faa0
ML
83 int auto_offline; /* If 1, automatically go offline when requests
84 cannot be sent */
88840341
RC
85
86 int local_poll; /* Log2 of polling interval at our end */
87 int remote_poll; /* Log2 of server/peer's polling interval (recovered
88 from received packets) */
cce7a5f1
ML
89 int remote_stratum; /* Stratum of the server/peer (recovered from
90 received packets) */
88840341
RC
91
92 int presend_minpoll; /* If the current polling interval is
cd5105b1
ML
93 at least this, an extra client packet
94 will be send some time before normal
88840341
RC
95 transmit. This ensures that both
96 us and the server/peer have an ARP
97 entry for each other ready, which
98 means our measurement is not
99 botched by an ARP round-trip on one
100 side or the other. */
101
102 int presend_done; /* The presend packet has been sent */
103
104 int minpoll; /* Log2 of minimum defined polling interval */
105 int maxpoll; /* Log2 of maximum defined polling interval */
106
c8fe69c9
BLA
107 int min_stratum; /* Increase stratum in received packets to the
108 minimum */
109
7a6ee1d7
ML
110 int poll_target; /* Target number of sourcestats samples */
111
1aecc51c
ML
112 int version; /* Version set in packets for server/peer */
113
7a6ee1d7
ML
114 double poll_score; /* Score of current local poll */
115
88840341
RC
116 double max_delay; /* Maximum round-trip delay to the
117 peer that we can tolerate and still
118 use the sample for generating
119 statistics from */
120
8fbfe55e 121 double max_delay_ratio; /* Largest ratio of delay /
88840341
RC
122 min_delay_in_register that we can
123 tolerate. */
124
b977c95b
ML
125 double max_delay_dev_ratio; /* Maximum ratio of increase in delay / stddev */
126
6cd55839
ML
127 double offset_correction; /* Correction applied to measured offset
128 (e.g. for asymmetry in network delay) */
129
ca28dbd2 130 NAU_Instance auth; /* Authentication */
88840341 131
30e65496
ML
132 /* Count of transmitted packets since last valid response */
133 unsigned int tx_count;
88840341 134
90b25f5b
ML
135 /* Flag indicating a valid response was received since last request */
136 int valid_rx;
137
138 /* Flag indicating the timestamps below are from a valid packet and may
139 be used for synchronisation */
140 int valid_timestamps;
141
f0f18a02 142 /* Receive and transmit timestamps from the last valid response */
90b25f5b
ML
143 NTP_int64 remote_ntp_rx;
144 NTP_int64 remote_ntp_tx;
88840341 145
f0f18a02 146 /* Local timestamp when the last valid response was received from the
88840341
RC
147 source. We have to be prepared to tinker with this if the local
148 clock has its frequency adjusted before we repond. The value we
149 store here is what our own local time was when the same arrived.
150 Before replying, we have to correct this to fit with the
151 parameters for the current reference. (It must be stored
152 relative to local time to permit frequency and offset adjustments
153 to be made when we trim the local clock). */
90b25f5b 154 NTP_int64 local_ntp_rx;
14c8f076 155 NTP_Local_Timestamp local_rx;
88840341
RC
156
157 /* Local timestamp when we last transmitted a packet to the source.
158 We store two versions. The first is in NTP format, and is used
159 to validate the next received packet from the source.
160 Additionally, this is corrected to bring it into line with the
d0dfa1de 161 current reference. The second is in timespec format, and is kept
88840341
RC
162 relative to the local clock. We modify this in accordance with
163 local clock frequency/offset changes, and use this for computing
164 statistics about the source when a return packet arrives. */
165 NTP_int64 local_ntp_tx;
14c8f076 166 NTP_Local_Timestamp local_tx;
88840341 167
2668a12e 168 /* Previous values of some variables needed in interleaved mode */
2e0870ee 169 NTP_Local_Timestamp prev_local_tx;
2668a12e 170 int prev_local_poll;
64c2fd98 171 unsigned int prev_tx_count;
2e0870ee 172
f0f18a02
ML
173 /* Flag indicating the two timestamps below were updated since the
174 last transmission */
175 int updated_init_timestamps;
176
177 /* Timestamps used for (re)starting the symmetric protocol, when we
178 need to respond to a packet which is not a valid response */
179 NTP_int64 init_remote_ntp_tx;
180 NTP_Local_Timestamp init_local_rx;
181
88840341
RC
182 /* The instance record in the main source management module. This
183 performs the statistical analysis on the samples we generate */
184
185 SRC_Instance source;
186
189aafde
ML
187 /* Optional median filter for NTP measurements */
188 SPF_Instance filter;
189
88840341
RC
190 int burst_good_samples_to_go;
191 int burst_total_samples_to_go;
192
535ca64b
ML
193 /* Report from last valid response */
194 RPT_NTPReport report;
88840341
RC
195};
196
a78bf0c3
ML
197typedef struct {
198 NTP_Remote_Address addr;
199 NTP_Local_Address local_addr;
ca28dbd2 200 NAU_Instance auth;
a78bf0c3
ML
201 int interval;
202} BroadcastDestination;
203
204/* Array of BroadcastDestination */
205static ARR_Instance broadcasts;
206
88840341
RC
207/* ================================================== */
208/* Initial delay period before first packet is transmitted (in seconds) */
d1b820e7 209#define INITIAL_DELAY 0.2
88840341
RC
210
211/* Spacing required between samples for any two servers/peers (to
212 minimise risk of network collisions) (in seconds) */
dcce79fd 213#define MIN_SAMPLING_SEPARATION 0.002
97d42033 214#define MAX_SAMPLING_SEPARATION 0.2
d1b820e7 215
833022b7
ML
216/* Randomness added to spacing between samples for one server/peer */
217#define SAMPLING_RANDOMNESS 0.02
218
cce7a5f1 219/* Adjustment of the peer polling interval */
992590e9 220#define PEER_SAMPLING_ADJ 1.1
cce7a5f1 221
5b75d4af
ML
222/* Maximum spacing between samples in the burst mode as an absolute
223 value and ratio to the normal polling interval */
224#define MAX_BURST_INTERVAL 2.0
225#define MAX_BURST_POLL_RATIO 0.25
88840341 226
70928dba
ML
227/* Number of samples in initial burst */
228#define IBURST_GOOD_SAMPLES 4
229#define IBURST_TOTAL_SAMPLES SOURCE_REACH_BITS
230
d0eb9427
ML
231/* Number of samples in automatic burst */
232#define BURST_GOOD_SAMPLES 1
233#define MAX_BURST_TOTAL_SAMPLES 4
234
cd5105b1 235/* Time to wait after sending packet to 'warm up' link */
d23c647e 236#define WARM_UP_DELAY 2.0
d1b820e7 237
8cc7ebff 238/* Compatible NTP protocol versions */
8fbfe55e 239#define NTP_MAX_COMPAT_VERSION NTP_VERSION
cf001799 240#define NTP_MIN_COMPAT_VERSION 1
8cc7ebff 241
8fbfe55e 242/* Maximum allowed dispersion - as defined in RFC 5905 (16 seconds) */
88840341
RC
243#define NTP_MAX_DISPERSION 16.0
244
df9b5d8c
ML
245/* Maximum allowed time for server to process client packet */
246#define MAX_SERVER_INTERVAL 4.0
247
8f6a1b53
ML
248/* Maximum acceptable delay in transmission for timestamp correction */
249#define MAX_TX_DELAY 1.0
250
f2f834e7 251/* Maximum allowed values of maxdelay parameters */
99147ed8
ML
252#define MAX_MAXDELAY 1.0e3
253#define MAX_MAXDELAYRATIO 1.0e6
254#define MAX_MAXDELAYDEVRATIO 1.0e6
f2f834e7 255
a79fbef2 256/* Minimum and maximum allowed poll interval */
dcce79fd 257#define MIN_POLL -6
a79fbef2 258#define MAX_POLL 24
0380cf0c 259
59d1b417
ML
260/* Enable sub-second polling intervals only when the peer delay is not
261 longer than 10 milliseconds to restrict them to local networks */
262#define MIN_NONLAN_POLL 0
263#define MAX_LAN_PEER_DELAY 0.01
264
8fbfe55e
ML
265/* Kiss-o'-Death codes */
266#define KOD_RATE 0x52415445UL /* RATE */
267
7aa4bbf6
ML
268/* Maximum poll interval set by KoD RATE */
269#define MAX_KOD_RATE_POLL SRC_DEFAULT_MAXPOLL
270
16afa8eb
ML
271/* Maximum number of missed responses to accept samples using old timestamps
272 in the interleaved client/server mode */
273#define MAX_CLIENT_INTERLEAVED_TX 4
274
0baa35ea
ML
275/* Maximum ratio of local intervals in the timestamp selection of the
276 interleaved mode to prefer a sample using previous timestamps */
277#define MAX_INTERLEAVED_L2L_RATIO 0.1
278
547272e6
ML
279/* Invalid socket, different from the one in ntp_io.c */
280#define INVALID_SOCK_FD -2
779e40ed 281
88840341
RC
282/* ================================================== */
283
5214d42c
ML
284/* Server IPv4/IPv6 sockets */
285static int server_sock_fd4;
286static int server_sock_fd6;
287
88840341
RC
288static ADF_AuthTable access_auth_table;
289
2c877fa1
ML
290/* Characters for printing synchronisation status and timestamping source */
291static const char leap_chars[4] = {'N', '+', '-', '?'};
292static const char tss_chars[3] = {'D', 'K', 'H'};
293
88840341
RC
294/* ================================================== */
295/* Forward prototypes */
296
297static void transmit_timeout(void *arg);
badf97d4 298static double get_transmit_delay(NCR_Instance inst, int on_tx, double last_tx);
97d42033 299static double get_separation(int poll);
cb8660e7 300static int parse_packet(NTP_Packet *packet, int length, NTP_PacketInfo *info);
b0fe4436 301static void set_connectivity(NCR_Instance inst, SRC_Connectivity connectivity);
88840341
RC
302
303/* ================================================== */
304
cb88cea3
ML
305static void
306do_size_checks(void)
307{
308 /* Assertions to check the sizes of certain data types
309 and the positions of certain record fields */
310
311 /* Check that certain invariants are true */
312 assert(sizeof(NTP_int32) == 4);
313 assert(sizeof(NTP_int64) == 8);
314
315 /* Check offsets of all fields in the NTP packet format */
316 assert(offsetof(NTP_Packet, lvm) == 0);
317 assert(offsetof(NTP_Packet, stratum) == 1);
318 assert(offsetof(NTP_Packet, poll) == 2);
319 assert(offsetof(NTP_Packet, precision) == 3);
320 assert(offsetof(NTP_Packet, root_delay) == 4);
321 assert(offsetof(NTP_Packet, root_dispersion) == 8);
322 assert(offsetof(NTP_Packet, reference_id) == 12);
323 assert(offsetof(NTP_Packet, reference_ts) == 16);
324 assert(offsetof(NTP_Packet, originate_ts) == 24);
325 assert(offsetof(NTP_Packet, receive_ts) == 32);
326 assert(offsetof(NTP_Packet, transmit_ts) == 40);
327}
328
329/* ================================================== */
330
474b2af1
ML
331static void
332do_time_checks(void)
333{
d0dfa1de 334 struct timespec now;
e1accce4
ML
335 time_t warning_advance = 3600 * 24 * 365 * 10; /* 10 years */
336
474b2af1
ML
337#ifdef HAVE_LONG_TIME_T
338 /* Check that time before NTP_ERA_SPLIT underflows correctly */
339
d0dfa1de
ML
340 struct timespec ts1 = {NTP_ERA_SPLIT, 1}, ts2 = {NTP_ERA_SPLIT - 1, 1};
341 NTP_int64 nts1, nts2;
474b2af1
ML
342 int r;
343
99cc9452
ML
344 UTI_TimespecToNtp64(&ts1, &nts1, NULL);
345 UTI_TimespecToNtp64(&ts2, &nts2, NULL);
346 UTI_Ntp64ToTimespec(&nts1, &ts1);
347 UTI_Ntp64ToTimespec(&nts2, &ts2);
474b2af1 348
d0dfa1de
ML
349 r = ts1.tv_sec == NTP_ERA_SPLIT &&
350 ts1.tv_sec + (1ULL << 32) - 1 == ts2.tv_sec;
474b2af1
ML
351
352 assert(r);
e1accce4
ML
353
354 LCL_ReadRawTime(&now);
d0dfa1de 355 if (ts2.tv_sec - now.tv_sec < warning_advance)
f282856c 356 LOG(LOGS_WARN, "Assumed NTP time ends at %s!", UTI_TimeToLogForm(ts2.tv_sec));
e1accce4
ML
357#else
358 LCL_ReadRawTime(&now);
359 if (now.tv_sec > 0x7fffffff - warning_advance)
f282856c 360 LOG(LOGS_WARN, "System time ends at %s!", UTI_TimeToLogForm(0x7fffffff));
474b2af1
ML
361#endif
362}
363
364/* ================================================== */
365
43cd119d
ML
366static void
367zero_local_timestamp(NTP_Local_Timestamp *ts)
368{
369 UTI_ZeroTimespec(&ts->ts);
370 ts->err = 0.0;
371 ts->source = NTP_TS_DAEMON;
372}
373
374/* ================================================== */
375
88840341
RC
376void
377NCR_Initialise(void)
378{
cb88cea3 379 do_size_checks();
474b2af1 380 do_time_checks();
cb88cea3 381
0a0aff14 382 logfileid = CNF_GetLogMeasurements(&log_raw_measurements) ? LOG_FileOpen("measurements",
2c877fa1 383 " Date (UTC) Time IP Address L St 123 567 ABCD LP RP Score Offset Peer del. Peer disp. Root del. Root disp. Refid MTxRx")
e78e65ef 384 : -1;
88840341
RC
385
386 access_auth_table = ADF_CreateTable();
a78bf0c3 387 broadcasts = ARR_CreateInstance(sizeof (BroadcastDestination));
5214d42c 388
52e12e42
ML
389 /* Server socket will be opened when access is allowed */
390 server_sock_fd4 = INVALID_SOCK_FD;
391 server_sock_fd6 = INVALID_SOCK_FD;
88840341
RC
392}
393
394/* ================================================== */
395
396void
397NCR_Finalise(void)
398{
5214d42c
ML
399 unsigned int i;
400
401 if (server_sock_fd4 != INVALID_SOCK_FD)
402 NIO_CloseServerSocket(server_sock_fd4);
403 if (server_sock_fd6 != INVALID_SOCK_FD)
404 NIO_CloseServerSocket(server_sock_fd6);
405
ca28dbd2 406 for (i = 0; i < ARR_GetSize(broadcasts); i++) {
5214d42c 407 NIO_CloseServerSocket(((BroadcastDestination *)ARR_GetElement(broadcasts, i))->local_addr.sock_fd);
ca28dbd2
ML
408 NAU_DestroyInstance(((BroadcastDestination *)ARR_GetElement(broadcasts, i))->auth);
409 }
5214d42c 410
a78bf0c3 411 ARR_DestroyInstance(broadcasts);
88840341 412 ADF_DestroyTable(access_auth_table);
88840341
RC
413}
414
415/* ================================================== */
416
417static void
ba283e6b 418restart_timeout(NCR_Instance inst, double delay)
88840341 419{
779e40ed
ML
420 /* Check if we can transmit */
421 if (inst->tx_suspended) {
cbd77c97 422 assert(!inst->tx_timeout_id);
779e40ed
ML
423 return;
424 }
425
cbd77c97
ML
426 /* Stop both rx and tx timers if running */
427 SCH_RemoveTimeout(inst->rx_timeout_id);
428 inst->rx_timeout_id = 0;
429 SCH_RemoveTimeout(inst->tx_timeout_id);
88840341 430
779e40ed 431 /* Start new timer for transmission */
97d42033 432 inst->tx_timeout_id = SCH_AddTimeoutInClass(delay, get_separation(inst->local_poll),
cbd77c97 433 SAMPLING_RANDOMNESS,
1c51feb3
ML
434 inst->mode == MODE_CLIENT ?
435 SCH_NtpClientClass : SCH_NtpPeerClass,
cbd77c97 436 transmit_timeout, (void *)inst);
ba283e6b
ML
437}
438
439/* ================================================== */
8671002b 440
ba283e6b
ML
441static void
442start_initial_timeout(NCR_Instance inst)
443{
045794df 444 double delay, last_tx;
d0dfa1de 445 struct timespec now;
045794df 446
cbd77c97 447 if (!inst->tx_timeout_id) {
779e40ed
ML
448 /* This will be the first transmission after mode change */
449
779e40ed
ML
450 /* Mark source active */
451 SRC_SetActive(inst->source);
a9b9e7be 452 }
ba283e6b 453
045794df
ML
454 /* In case the offline period was too short, adjust the delay to keep
455 the interval between packets at least as long as the current polling
456 interval */
457 SCH_GetLastEventTime(&now, NULL, NULL);
14c8f076 458 last_tx = UTI_DiffTimespecsToDouble(&now, &inst->local_tx.ts);
045794df
ML
459 if (last_tx < 0.0)
460 last_tx = 0.0;
461 delay = get_transmit_delay(inst, 0, 0.0) - last_tx;
462 if (delay < INITIAL_DELAY)
463 delay = INITIAL_DELAY;
464
465 restart_timeout(inst, delay);
a9b9e7be 466}
08faca03 467
a9b9e7be
ML
468/* ================================================== */
469
470static void
471close_client_socket(NCR_Instance inst)
472{
473 if (inst->mode == MODE_CLIENT && inst->local_addr.sock_fd != INVALID_SOCK_FD) {
474 NIO_CloseClientSocket(inst->local_addr.sock_fd);
475 inst->local_addr.sock_fd = INVALID_SOCK_FD;
779e40ed 476 }
cbd77c97
ML
477
478 SCH_RemoveTimeout(inst->rx_timeout_id);
479 inst->rx_timeout_id = 0;
88840341
RC
480}
481
482/* ================================================== */
483
60a25f6e
ML
484static void
485take_offline(NCR_Instance inst)
486{
487 inst->opmode = MD_OFFLINE;
0076458e 488
cbd77c97
ML
489 SCH_RemoveTimeout(inst->tx_timeout_id);
490 inst->tx_timeout_id = 0;
60a25f6e
ML
491
492 /* Mark source unreachable */
493 SRC_ResetReachability(inst->source);
8671002b
ML
494
495 /* And inactive */
496 SRC_UnsetActive(inst->source);
08faca03 497
a9b9e7be 498 close_client_socket(inst);
3ebebac6
ML
499
500 NCR_ResetInstance(inst);
60a25f6e
ML
501}
502
503/* ================================================== */
504
2458325c 505NCR_Instance
fa402a17
ML
506NCR_CreateInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
507 SourceParameters *params, const char *name)
88840341
RC
508{
509 NCR_Instance result;
510
511 result = MallocNew(struct NCR_Instance_Record);
512
513 result->remote_addr = *remote_addr;
308de812 514 result->local_addr.ip_addr.family = IPADDR_UNSPEC;
86acea5c 515 result->local_addr.if_index = INVALID_IF_INDEX;
308de812 516
2458325c
ML
517 switch (type) {
518 case NTP_SERVER:
a9b9e7be 519 /* Client socket will be obtained when sending request */
779e40ed 520 result->local_addr.sock_fd = INVALID_SOCK_FD;
2458325c
ML
521 result->mode = MODE_CLIENT;
522 break;
523 case NTP_PEER:
6d1dda0f 524 result->local_addr.sock_fd = NIO_OpenServerSocket(remote_addr);
2458325c
ML
525 result->mode = MODE_ACTIVE;
526 break;
527 default:
528 assert(0);
529 }
88840341 530
96d652e5
ML
531 result->interleaved = params->interleaved;
532
88840341 533 result->minpoll = params->minpoll;
2c47602c 534 if (result->minpoll < MIN_POLL)
0380cf0c 535 result->minpoll = SRC_DEFAULT_MINPOLL;
a79fbef2
ML
536 else if (result->minpoll > MAX_POLL)
537 result->minpoll = MAX_POLL;
2c47602c 538
88840341 539 result->maxpoll = params->maxpoll;
2c47602c 540 if (result->maxpoll < MIN_POLL)
0380cf0c 541 result->maxpoll = SRC_DEFAULT_MAXPOLL;
a79fbef2
ML
542 else if (result->maxpoll > MAX_POLL)
543 result->maxpoll = MAX_POLL;
4b5f4650
ML
544 if (result->maxpoll < result->minpoll)
545 result->maxpoll = result->minpoll;
88840341 546
3ebebac6 547 result->min_stratum = params->min_stratum;
740e8130
ML
548 if (result->min_stratum >= NTP_MAX_STRATUM)
549 result->min_stratum = NTP_MAX_STRATUM - 1;
86626521 550
2408bbcd 551 /* Presend doesn't work in symmetric mode */
88840341 552 result->presend_minpoll = params->presend_minpoll;
90229984
ML
553 if (result->presend_minpoll <= MAX_POLL && result->mode != MODE_CLIENT)
554 result->presend_minpoll = MAX_POLL + 1;
3ebebac6 555
99147ed8
ML
556 result->max_delay = CLAMP(0.0, params->max_delay, MAX_MAXDELAY);
557 result->max_delay_ratio = CLAMP(0.0, params->max_delay_ratio, MAX_MAXDELAYRATIO);
558 result->max_delay_dev_ratio = CLAMP(0.0, params->max_delay_dev_ratio, MAX_MAXDELAYDEVRATIO);
6cd55839 559 result->offset_correction = params->offset;
b0fe4436 560 result->auto_iburst = params->iburst;
d0eb9427 561 result->auto_burst = params->burst;
3ebebac6
ML
562 result->auto_offline = params->auto_offline;
563 result->poll_target = params->poll_target;
88840341 564
c4150872
ML
565 if (params->nts) {
566 IPSockAddr nts_address;
567
568 if (result->mode == MODE_ACTIVE)
569 LOG(LOGS_WARN, "NTS not supported with peers");
570
571 nts_address.ip_addr = remote_addr->ip_addr;
572 nts_address.port = params->nts_port;
573
cc77b0e9 574 result->auth = NAU_CreateNtsInstance(&nts_address, name, params->cert_set,
6615bb1b 575 result->remote_addr.port);
c4150872 576 } else if (params->authkey != INACTIVE_AUTHKEY) {
ca28dbd2 577 result->auth = NAU_CreateSymmetricInstance(params->authkey);
88840341 578 } else {
ca28dbd2 579 result->auth = NAU_CreateNoneInstance();
88840341
RC
580 }
581
ca28dbd2
ML
582 result->version = NAU_GetSuggestedNtpVersion(result->auth);
583
e6e9a472
ML
584 if (params->version)
585 result->version = CLAMP(NTP_MIN_COMPAT_VERSION, params->version, NTP_VERSION);
586
8671002b 587 /* Create a source instance for this NTP source */
6688f403 588 result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr),
dfe87714
ML
589 SRC_NTP, NAU_IsAuthEnabled(result->auth),
590 params->sel_options, &result->remote_addr.ip_addr,
d0964ffa 591 params->min_samples, params->max_samples,
8ccda538 592 params->min_delay, params->asymmetry);
8671002b 593
189aafde
ML
594 if (params->filter_length >= 1)
595 result->filter = SPF_CreateInstance(params->filter_length, params->filter_length,
596 NTP_MAX_DISPERSION, 0.0);
597 else
598 result->filter = NULL;
599
cbd77c97
ML
600 result->rx_timeout_id = 0;
601 result->tx_timeout_id = 0;
779e40ed 602 result->tx_suspended = 1;
b0fe4436 603 result->opmode = MD_OFFLINE;
badf97d4 604 result->local_poll = result->minpoll;
4d7eb2f7 605 result->poll_score = 0.0;
43cd119d 606 zero_local_timestamp(&result->local_tx);
9c760de6
ML
607 result->burst_good_samples_to_go = 0;
608 result->burst_total_samples_to_go = 0;
535ca64b 609 memset(&result->report, 0, sizeof (result->report));
88840341 610
3ebebac6
ML
611 NCR_ResetInstance(result);
612
b0fe4436 613 set_connectivity(result, params->connectivity);
93b5b08b 614
88840341 615 return result;
88840341
RC
616}
617
618/* ================================================== */
88840341
RC
619
620/* Destroy an instance */
621void
622NCR_DestroyInstance(NCR_Instance instance)
623{
08faca03
ML
624 if (instance->opmode != MD_OFFLINE)
625 take_offline(instance);
626
5214d42c
ML
627 if (instance->mode == MODE_ACTIVE)
628 NIO_CloseServerSocket(instance->local_addr.sock_fd);
629
189aafde
ML
630 if (instance->filter)
631 SPF_DestroyInstance(instance->filter);
632
ca28dbd2
ML
633 NAU_DestroyInstance(instance->auth);
634
88840341
RC
635 /* This will destroy the source instance inside the
636 structure, which will cause reselection if this was the
637 synchronising source etc. */
638 SRC_DestroyInstance(instance->source);
639
88840341
RC
640 /* Free the data structure */
641 Free(instance);
88840341
RC
642}
643
644/* ================================================== */
645
779e40ed
ML
646void
647NCR_StartInstance(NCR_Instance instance)
648{
649 instance->tx_suspended = 0;
650 if (instance->opmode != MD_OFFLINE)
651 start_initial_timeout(instance);
652}
653
654/* ================================================== */
655
3ebebac6
ML
656void
657NCR_ResetInstance(NCR_Instance instance)
658{
659 instance->tx_count = 0;
660 instance->presend_done = 0;
661
3ebebac6
ML
662 instance->remote_poll = 0;
663 instance->remote_stratum = 0;
664
90b25f5b
ML
665 instance->valid_rx = 0;
666 instance->valid_timestamps = 0;
6e9c0489
ML
667 UTI_ZeroNtp64(&instance->remote_ntp_rx);
668 UTI_ZeroNtp64(&instance->remote_ntp_tx);
669 UTI_ZeroNtp64(&instance->local_ntp_rx);
670 UTI_ZeroNtp64(&instance->local_ntp_tx);
43cd119d 671 zero_local_timestamp(&instance->local_rx);
64c2fd98 672
2e0870ee 673 zero_local_timestamp(&instance->prev_local_tx);
2668a12e 674 instance->prev_local_poll = 0;
64c2fd98 675 instance->prev_tx_count = 0;
f0f18a02
ML
676
677 instance->updated_init_timestamps = 0;
678 UTI_ZeroNtp64(&instance->init_remote_ntp_tx);
679 zero_local_timestamp(&instance->init_local_rx);
189aafde
ML
680
681 if (instance->filter)
682 SPF_DropSamples(instance->filter);
4d7eb2f7
ML
683}
684
685/* ================================================== */
badf97d4 686
4d7eb2f7
ML
687void
688NCR_ResetPoll(NCR_Instance instance)
689{
badf97d4
ML
690 if (instance->local_poll != instance->minpoll) {
691 instance->local_poll = instance->minpoll;
692
693 /* The timer was set with a longer poll interval, restart it */
cbd77c97 694 if (instance->tx_timeout_id)
badf97d4
ML
695 restart_timeout(instance, get_transmit_delay(instance, 0, 0.0));
696 }
3ebebac6
ML
697}
698
699/* ================================================== */
700
29c1df46 701void
e8062b7f 702NCR_ChangeRemoteAddress(NCR_Instance inst, NTP_Remote_Address *remote_addr, int ntp_only)
29c1df46 703{
dec0d3bf 704 memset(&inst->report, 0, sizeof (inst->report));
4d7eb2f7 705 NCR_ResetInstance(inst);
0b2e77ae 706
0b2e77ae
ML
707 if (!ntp_only)
708 NAU_ChangeAddress(inst->auth, &remote_addr->ip_addr);
709
29c1df46 710 inst->remote_addr = *remote_addr;
29c1df46
ML
711
712 if (inst->mode == MODE_CLIENT)
713 close_client_socket(inst);
5214d42c
ML
714 else {
715 NIO_CloseServerSocket(inst->local_addr.sock_fd);
eb75ce7d 716 inst->local_addr.ip_addr.family = IPADDR_UNSPEC;
86acea5c 717 inst->local_addr.if_index = INVALID_IF_INDEX;
6d1dda0f 718 inst->local_addr.sock_fd = NIO_OpenServerSocket(remote_addr);
5214d42c 719 }
29c1df46 720
42dd5caa
ML
721 /* Update the reference ID and reset the source/sourcestats instances */
722 SRC_SetRefid(inst->source, UTI_IPToRefid(&remote_addr->ip_addr),
723 &inst->remote_addr.ip_addr);
724 SRC_ResetInstance(inst->source);
29c1df46
ML
725}
726
727/* ================================================== */
728
88840341 729static void
7a6ee1d7 730adjust_poll(NCR_Instance inst, double adj)
88840341 731{
7a6ee1d7 732 inst->poll_score += adj;
88840341 733
7a6ee1d7
ML
734 if (inst->poll_score >= 1.0) {
735 inst->local_poll += (int)inst->poll_score;
736 inst->poll_score -= (int)inst->poll_score;
88840341 737 }
7a6ee1d7
ML
738
739 if (inst->poll_score < 0.0) {
740 inst->local_poll += (int)(inst->poll_score - 1.0);
741 inst->poll_score -= (int)(inst->poll_score - 1.0);
88840341
RC
742 }
743
744 /* Clamp polling interval to defined range */
745 if (inst->local_poll < inst->minpoll) {
746 inst->local_poll = inst->minpoll;
7a6ee1d7 747 inst->poll_score = 0;
88840341
RC
748 } else if (inst->local_poll > inst->maxpoll) {
749 inst->local_poll = inst->maxpoll;
7a6ee1d7 750 inst->poll_score = 1.0;
88840341 751 }
59d1b417
ML
752
753 /* Don't allow a sub-second polling interval if the source is not reachable
754 or it is not in a local network according to the measured delay */
755 if (inst->local_poll < MIN_NONLAN_POLL &&
756 (!SRC_IsReachable(inst->source) ||
757 SST_MinRoundTripDelay(SRC_GetSourcestats(inst->source)) > MAX_LAN_PEER_DELAY))
758 inst->local_poll = MIN_NONLAN_POLL;
88840341
RC
759}
760
761/* ================================================== */
762
030e3b2d
ML
763static double
764get_poll_adj(NCR_Instance inst, double error_in_estimate, double peer_distance)
765{
766 double poll_adj;
c2ab1426 767 int samples;
030e3b2d
ML
768
769 if (error_in_estimate > peer_distance) {
189aafde
ML
770 /* If the prediction is not even within +/- the peer distance of the peer,
771 we are clearly not tracking the peer at all well, so we back off the
772 sampling rate depending on just how bad the situation is */
c2ab1426 773 poll_adj = -log(error_in_estimate / peer_distance) / log(2.0);
030e3b2d 774 } else {
c2ab1426 775 samples = SST_Samples(SRC_GetSourcestats(inst->source));
030e3b2d
ML
776
777 /* Adjust polling interval so that the number of sourcestats samples
778 remains close to the target value */
779 poll_adj = ((double)samples / inst->poll_target - 1.0) / inst->poll_target;
780
781 /* Make interval shortening quicker */
782 if (samples < inst->poll_target) {
783 poll_adj *= 2.0;
784 }
785 }
786
787 return poll_adj;
788}
789
790/* ================================================== */
791
62cd319a
ML
792static int
793get_transmit_poll(NCR_Instance inst)
794{
795 int poll;
796
797 poll = inst->local_poll;
798
799 /* In symmetric mode, if the peer is responding, use shorter of the local
800 and remote poll interval, but not shorter than the minimum */
801 if (inst->mode == MODE_ACTIVE && poll > inst->remote_poll &&
7352e470 802 SRC_IsReachable(inst->source))
62cd319a
ML
803 poll = MAX(inst->remote_poll, inst->minpoll);
804
805 return poll;
806}
807
808/* ================================================== */
809
cf700a00 810static double
78ae4ebf 811get_transmit_delay(NCR_Instance inst, int on_tx, double last_tx)
cf700a00 812{
cce7a5f1 813 int poll_to_use, stratum_diff;
cf700a00
ML
814 double delay_time;
815
816 /* If we're in burst mode, queue for immediate dispatch.
817
818 If we're operating in client/server mode, queue the timeout for
819 the poll interval hence. The fact that a timeout has been queued
820 in the transmit handler is immaterial - that is only done so that
821 we at least send something, if no reply is heard.
822
823 If we're in symmetric mode, we have to take account of the peer's
824 wishes, otherwise his sampling regime will fall to pieces. If
825 we're in client/server mode, we don't care what poll interval the
826 server responded with last time. */
827
62cd319a
ML
828 poll_to_use = get_transmit_poll(inst);
829 delay_time = UTI_Log2ToDouble(poll_to_use);
830
cf700a00
ML
831 switch (inst->opmode) {
832 case MD_OFFLINE:
833 assert(0);
834 break;
835 case MD_ONLINE:
cf700a00
ML
836 switch(inst->mode) {
837 case MODE_CLIENT:
2408bbcd
ML
838 if (inst->presend_done)
839 delay_time = WARM_UP_DELAY;
cf700a00
ML
840 break;
841
842 case MODE_ACTIVE:
992590e9 843 /* If the remote stratum is higher than ours, wait a bit for the next
4a243687
ML
844 packet before responding in order to minimize the delay of the
845 measurement and its error for the peer which has higher stratum.
846 If the remote stratum is equal to ours, try to interleave packets
847 evenly with the peer. */
cce7a5f1 848 stratum_diff = inst->remote_stratum - REF_GetOurStratum();
992590e9 849 if ((stratum_diff > 0 && last_tx * PEER_SAMPLING_ADJ < delay_time) ||
cce7a5f1
ML
850 (!on_tx && !stratum_diff &&
851 last_tx / delay_time > PEER_SAMPLING_ADJ - 0.5))
852 delay_time *= PEER_SAMPLING_ADJ;
853
854 /* Substract the already spend time */
78ae4ebf
ML
855 if (last_tx > 0.0)
856 delay_time -= last_tx;
857 if (delay_time < 0.0)
858 delay_time = 0.0;
cf700a00
ML
859
860 break;
861 default:
862 assert(0);
863 break;
864 }
865 break;
866
867 case MD_BURST_WAS_ONLINE:
868 case MD_BURST_WAS_OFFLINE:
3f3ebd3b 869 /* Burst modes */
5b75d4af 870 delay_time = MIN(MAX_BURST_INTERVAL, MAX_BURST_POLL_RATIO * delay_time);
cf700a00
ML
871 break;
872 default:
873 assert(0);
874 break;
875 }
876
877 return delay_time;
878}
879
97d42033
ML
880/* ================================================== */
881/* Calculate sampling separation for given polling interval */
882
883static double
884get_separation(int poll)
885{
886 double separation;
887
8aa4ae02
ML
888 assert(poll >= MIN_POLL && poll <= MAX_POLL);
889
97d42033
ML
890 /* Allow up to 8 sources using the same short interval to not be limited
891 by the separation */
892 separation = UTI_Log2ToDouble(poll - 3);
893
894 return CLAMP(MIN_SAMPLING_SEPARATION, separation, MAX_SAMPLING_SEPARATION);
895}
896
cbd77c97
ML
897/* ================================================== */
898/* Timeout handler for closing the client socket when no acceptable
899 reply can be received from the server */
900
901static void
902receive_timeout(void *arg)
903{
904 NCR_Instance inst = (NCR_Instance)arg;
905
d7868091 906 DEBUG_LOG("Receive timeout for %s", UTI_IPSockAddrToString(&inst->remote_addr));
cbd77c97
ML
907
908 inst->rx_timeout_id = 0;
909 close_client_socket(inst);
910}
911
cf700a00
ML
912/* ================================================== */
913
e3c77f9b 914static int
88840341 915transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
90b25f5b 916 int interleaved, /* Flag enabling interleaved mode */
88840341 917 int my_poll, /* The log2 of the local poll interval */
73d4eaaf 918 int version, /* The NTP version to be set in the packet */
aca1daf7 919 uint32_t kod, /* KoD code - 0 disabled */
ca28dbd2 920 NAU_Instance auth, /* The authentication to be used for the packet */
90b25f5b
ML
921 NTP_int64 *remote_ntp_rx, /* The receive timestamp from received packet */
922 NTP_int64 *remote_ntp_tx, /* The transmit timestamp from received packet */
923 NTP_Local_Timestamp *local_rx, /* The RX time of the received packet */
924 NTP_Local_Timestamp *local_tx, /* The TX time of the previous packet
925 RESULT : TX time of this packet */
2c7ab983
ML
926 NTP_int64 *local_ntp_rx, /* The receive timestamp from the previous packet
927 RESULT : receive timestamp from this packet */
928 NTP_int64 *local_ntp_tx, /* The transmit timestamp from the previous packet
929 RESULT : transmit timestamp from this packet */
308de812 930 NTP_Remote_Address *where_to, /* Where to address the reponse to */
9ea1e4e4
ML
931 NTP_Local_Address *from, /* From what address to send it */
932 NTP_Packet *request, /* The received packet if responding */
933 NTP_PacketInfo *request_info /* and its info */
88840341
RC
934 )
935{
cb8660e7 936 NTP_PacketInfo info;
88840341 937 NTP_Packet message;
d0dfa1de 938 struct timespec local_receive, local_transmit;
859e0c23 939 double smooth_offset, local_transmit_err;
ca28dbd2 940 int ret, precision;
116c6972 941 NTP_int64 ts_fuzz;
88840341
RC
942
943 /* Parameters read from reference module */
7f45eb79 944 int are_we_synchronised, our_stratum, smooth_time;
88840341 945 NTP_Leap leap_status;
116c6972 946 uint32_t our_ref_id;
d0dfa1de 947 struct timespec our_ref_time;
859e0c23 948 double our_root_delay, our_root_dispersion;
88840341 949
ca28dbd2
ML
950 assert(auth || (request && request_info));
951
73d4eaaf
ML
952 /* Don't reply with version higher than ours */
953 if (version > NTP_VERSION) {
954 version = NTP_VERSION;
955 }
88840341 956
f0f18a02
ML
957 /* Check if the packet can be formed in the interleaved mode */
958 if (interleaved && (!remote_ntp_rx || !local_tx || UTI_IsZeroTimespec(&local_tx->ts)))
90b25f5b
ML
959 interleaved = 0;
960
8225bf01
ML
961 smooth_time = 0;
962 smooth_offset = 0.0;
963
ff03b813
ML
964 /* Get an initial transmit timestamp. A more accurate timestamp will be
965 taken later in this function. */
966 SCH_GetLastEventTime(&local_transmit, NULL, NULL);
967
8225bf01
ML
968 if (my_mode == MODE_CLIENT) {
969 /* Don't reveal local time or state of the clock in client packets */
970 precision = 32;
2aab6a85 971 leap_status = our_stratum = our_ref_id = 0;
8225bf01 972 our_root_delay = our_root_dispersion = 0.0;
d0dfa1de 973 UTI_ZeroTimespec(&our_ref_time);
7f45eb79 974 } else {
8225bf01
ML
975 REF_GetReferenceParams(&local_transmit,
976 &are_we_synchronised, &leap_status,
977 &our_stratum,
978 &our_ref_id, &our_ref_time,
979 &our_root_delay, &our_root_dispersion);
980
981 /* Get current smoothing offset when sending packet to a client */
982 if (SMT_IsEnabled() && (my_mode == MODE_SERVER || my_mode == MODE_BROADCAST)) {
983 smooth_offset = SMT_GetOffset(&local_transmit);
984 smooth_time = fabs(smooth_offset) > LCL_GetSysPrecisionAsQuantum();
985
986 /* Suppress leap second when smoothing and slew mode are enabled */
987 if (REF_GetLeapMode() == REF_LeapModeSlew &&
988 (leap_status == LEAP_InsertSecond || leap_status == LEAP_DeleteSecond))
989 leap_status = LEAP_Normal;
990 }
991
992 precision = LCL_GetSysPrecisionAsLog();
7f45eb79
ML
993 }
994
90b25f5b 995 if (smooth_time && !UTI_IsZeroTimespec(&local_rx->ts)) {
ab1f01ba 996 our_ref_id = NTP_REFID_SMOOTH;
d0dfa1de 997 UTI_AddDoubleToTimespec(&our_ref_time, smooth_offset, &our_ref_time);
14c8f076 998 UTI_AddDoubleToTimespec(&local_rx->ts, smooth_offset, &local_receive);
ab1f01ba 999 } else {
14c8f076 1000 local_receive = local_rx->ts;
ab1f01ba
ML
1001 }
1002
aca1daf7
ML
1003 if (kod != 0) {
1004 leap_status = LEAP_Unsynchronised;
1005 our_stratum = NTP_INVALID_STRATUM;
1006 our_ref_id = kod;
1007 }
1008
88840341 1009 /* Generate transmit packet */
2aab6a85 1010 message.lvm = NTP_LVM(leap_status, version, my_mode);
8fbfe55e
ML
1011 /* Stratum 16 and larger are invalid */
1012 if (our_stratum < NTP_MAX_STRATUM) {
4ba843f8
RC
1013 message.stratum = our_stratum;
1014 } else {
4ba843f8
RC
1015 message.stratum = NTP_INVALID_STRATUM;
1016 }
75a7af9e 1017
88840341 1018 message.poll = my_poll;
8225bf01 1019 message.precision = precision;
99cc9452
ML
1020 message.root_delay = UTI_DoubleToNtp32(our_root_delay);
1021 message.root_dispersion = UTI_DoubleToNtp32(our_root_dispersion);
b9b896d8 1022 message.reference_id = htonl(our_ref_id);
88840341
RC
1023
1024 /* Now fill in timestamps */
7f45eb79 1025
99cc9452 1026 UTI_TimespecToNtp64(&our_ref_time, &message.reference_ts, NULL);
88840341 1027
be8215e1 1028 /* Don't reveal timestamps which are not necessary for the protocol */
88840341 1029
be8215e1
ML
1030 if (my_mode != MODE_CLIENT || interleaved) {
1031 /* Originate - this comes from the last packet the source sent us */
1032 message.originate_ts = interleaved ? *remote_ntp_rx : *remote_ntp_tx;
8225bf01 1033
2c7ab983
ML
1034 do {
1035 /* Prepare random bits which will be added to the receive timestamp */
1036 UTI_GetNtp64Fuzz(&ts_fuzz, precision);
1037
1038 /* Receive - this is when we received the last packet from the source.
1039 This timestamp will have been adjusted so that it will now look to
1040 the source like we have been running on our latest estimate of
1041 frequency all along */
1042 UTI_TimespecToNtp64(&local_receive, &message.receive_ts, &ts_fuzz);
1043
1044 /* Do not send a packet with a non-zero receive timestamp equal to the
1045 originate timestamp or previous receive timestamp */
1046 } while (!UTI_IsZeroNtp64(&message.receive_ts) &&
1047 UTI_IsEqualAnyNtp64(&message.receive_ts, &message.originate_ts,
1048 local_ntp_rx, NULL));
be8215e1
ML
1049 } else {
1050 UTI_ZeroNtp64(&message.originate_ts);
1051 UTI_ZeroNtp64(&message.receive_ts);
1052 }
df6c2a43 1053
061579ec 1054 do {
cb8660e7
ML
1055 if (!parse_packet(&message, NTP_HEADER_LENGTH, &info))
1056 return 0;
1057
061579ec
ML
1058 /* Prepare random bits which will be added to the transmit timestamp */
1059 UTI_GetNtp64Fuzz(&ts_fuzz, precision);
1060
ff03b813
ML
1061 /* Get a more accurate transmit timestamp if it needs to be saved in the
1062 packet (i.e. in the server, symmetric, and broadcast basic modes) */
1063 if (!interleaved && precision < 32) {
1064 LCL_ReadCookedTime(&local_transmit, &local_transmit_err);
1065 if (smooth_time)
1066 UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
ff03b813 1067 }
061579ec 1068
ca28dbd2
ML
1069 UTI_TimespecToNtp64(interleaved ? &local_tx->ts : &local_transmit,
1070 &message.transmit_ts, &ts_fuzz);
1071
1072 /* Generate the authentication data */
1073 if (auth) {
1074 if (!NAU_GenerateRequestAuth(auth, &message, &info)) {
1075 DEBUG_LOG("Could not generate request auth");
1076 return 0;
577aed48 1077 }
061579ec 1078 } else {
aca1daf7
ML
1079 if (!NAU_GenerateResponseAuth(request, request_info, &message, &info,
1080 where_to, from, kod)) {
ca28dbd2
ML
1081 DEBUG_LOG("Could not generate response auth");
1082 return 0;
1083 }
777303f1 1084 }
061579ec 1085
2c7ab983
ML
1086 /* Do not send a packet with a non-zero transmit timestamp which is
1087 equal to any of the following timestamps:
1088 - receive (to allow reliable detection of the interleaved mode)
1089 - originate (to prevent the packet from being its own valid response
1090 in the symmetric mode)
1091 - previous transmit (to invalidate responses to the previous packet)
1092 (the precision must be at least -30 to prevent an infinite loop!) */
1093 } while (!UTI_IsZeroNtp64(&message.transmit_ts) &&
1094 UTI_IsEqualAnyNtp64(&message.transmit_ts, &message.receive_ts,
1095 &message.originate_ts, local_ntp_tx));
88840341 1096
b8ee6d6e
ML
1097 if (request_info && request_info->length < info.length) {
1098 DEBUG_LOG("Response longer than request req_len=%d res_len=%d",
1099 request_info->length, info.length);
1100 return 0;
1101 }
1102
ff03b813
ML
1103 /* If the transmit timestamp will be saved, get an even more
1104 accurate daemon timestamp closer to the transmission */
1105 if (local_tx)
1106 LCL_ReadCookedTime(&local_transmit, &local_transmit_err);
1107
cb8660e7 1108 ret = NIO_SendPacket(&message, where_to, from, info.length, local_tx != NULL);
8fbfe55e 1109
88840341 1110 if (local_tx) {
ff03b813
ML
1111 if (smooth_time)
1112 UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
14c8f076 1113 local_tx->ts = local_transmit;
859e0c23 1114 local_tx->err = local_transmit_err;
14c8f076 1115 local_tx->source = NTP_TS_DAEMON;
88840341
RC
1116 }
1117
90b25f5b
ML
1118 if (local_ntp_rx)
1119 *local_ntp_rx = message.receive_ts;
1120 if (local_ntp_tx)
88840341 1121 *local_ntp_tx = message.transmit_ts;
88840341 1122
e3c77f9b 1123 return ret;
88840341
RC
1124}
1125
88840341
RC
1126/* ================================================== */
1127/* Timeout handler for transmitting to a source. */
1128
1129static void
1130transmit_timeout(void *arg)
1131{
1132 NCR_Instance inst = (NCR_Instance) arg;
eb75ce7d 1133 NTP_Local_Address local_addr;
f0f18a02 1134 int interleaved, initial, sent;
88840341 1135
cbd77c97 1136 inst->tx_timeout_id = 0;
60a25f6e
ML
1137
1138 switch (inst->opmode) {
1139 case MD_BURST_WAS_ONLINE:
1140 /* With online burst switch to online before last packet */
1141 if (inst->burst_total_samples_to_go <= 1)
1142 inst->opmode = MD_ONLINE;
deaf0ffe 1143 break;
60a25f6e
ML
1144 case MD_BURST_WAS_OFFLINE:
1145 if (inst->burst_total_samples_to_go <= 0)
1146 take_offline(inst);
1147 break;
d0eb9427
ML
1148 case MD_ONLINE:
1149 /* Start a new burst if the burst option is enabled and the average
1150 polling interval including the burst will not fall below the
1151 minimum polling interval */
99e3045d 1152 if (inst->auto_burst && inst->local_poll > inst->minpoll)
d0eb9427
ML
1153 NCR_InitiateSampleBurst(inst, BURST_GOOD_SAMPLES,
1154 MIN(1 << (inst->local_poll - inst->minpoll),
1155 MAX_BURST_TOTAL_SAMPLES));
deaf0ffe 1156 break;
60a25f6e
ML
1157 default:
1158 break;
1159 }
1160
1161 if (inst->opmode == MD_OFFLINE) {
1162 return;
1163 }
1164
d7868091 1165 DEBUG_LOG("Transmit timeout for %s", UTI_IPSockAddrToString(&inst->remote_addr));
88840341 1166
ca28dbd2
ML
1167 /* Prepare authentication */
1168 if (!NAU_PrepareRequestAuth(inst->auth)) {
1169 if (inst->burst_total_samples_to_go > 0)
1170 inst->burst_total_samples_to_go--;
1171 adjust_poll(inst, 0.25);
1172 SRC_UpdateReachability(inst->source, 0);
1173 restart_timeout(inst, get_transmit_delay(inst, 1, 0.0));
1174 return;
1175 }
1176
a9b9e7be
ML
1177 /* Open new client socket */
1178 if (inst->mode == MODE_CLIENT) {
1179 close_client_socket(inst);
1180 assert(inst->local_addr.sock_fd == INVALID_SOCK_FD);
6d1dda0f 1181 inst->local_addr.sock_fd = NIO_OpenClientSocket(&inst->remote_addr);
a9b9e7be
ML
1182 }
1183
eb75ce7d
ML
1184 /* Don't require the packet to be sent from the same address as before */
1185 local_addr.ip_addr.family = IPADDR_UNSPEC;
86acea5c 1186 local_addr.if_index = INVALID_IF_INDEX;
eb75ce7d
ML
1187 local_addr.sock_fd = inst->local_addr.sock_fd;
1188
64c2fd98
ML
1189 /* In symmetric mode, don't send a packet in interleaved mode unless it
1190 is the first response to the last valid request received from the peer
1191 and there was just one response to the previous valid request. This
1192 prevents the peer from matching the transmit timestamp with an older
b896bb5a
ML
1193 response if it can't detect missed responses. In client mode, which has
1194 at most one response per request, check how many responses are missing to
1195 prevent the server from responding with a very old transmit timestamp. */
64c2fd98 1196 interleaved = inst->interleaved &&
b896bb5a
ML
1197 ((inst->mode == MODE_CLIENT &&
1198 inst->tx_count < MAX_CLIENT_INTERLEAVED_TX) ||
1199 (inst->mode == MODE_ACTIVE &&
1200 inst->prev_tx_count == 1 && inst->tx_count == 0));
64c2fd98 1201
f0f18a02
ML
1202 /* In symmetric mode, if no valid response was received since the previous
1203 transmission, respond to the last received packet even if it failed some
1204 specific NTP tests. This is necessary for starting and restarting the
1205 protocol, e.g. when a packet was lost. */
1206 initial = inst->mode == MODE_ACTIVE && !inst->valid_rx &&
1207 !UTI_IsZeroNtp64(&inst->init_remote_ntp_tx);
1208
1209 /* Prepare for the response */
1210 inst->valid_rx = 0;
1211 inst->updated_init_timestamps = 0;
1212 if (initial)
1213 inst->valid_timestamps = 0;
1214
88840341 1215 /* Check whether we need to 'warm up' the link to the other end by
cd5105b1 1216 sending an NTP exchange to ensure both ends' ARP caches are
2b3d64c3
ML
1217 primed or whether we need to send two packets first to ensure a
1218 server in the interleaved mode has a fresh timestamp for us. */
9c760de6
ML
1219 if (inst->presend_minpoll <= inst->local_poll && !inst->presend_done &&
1220 !inst->burst_total_samples_to_go) {
64c2fd98 1221 inst->presend_done = interleaved ? 2 : 1;
2b3d64c3
ML
1222 } else if (inst->presend_done > 0) {
1223 inst->presend_done--;
88840341
RC
1224 }
1225
f0f18a02 1226 /* Send the request (which may also be a response in the symmetric mode) */
aca1daf7 1227 sent = transmit_packet(inst->mode, interleaved, inst->local_poll, inst->version, 0,
ca28dbd2 1228 inst->auth,
f0f18a02
ML
1229 initial ? NULL : &inst->remote_ntp_rx,
1230 initial ? &inst->init_remote_ntp_tx : &inst->remote_ntp_tx,
1231 initial ? &inst->init_local_rx : &inst->local_rx,
1232 &inst->local_tx, &inst->local_ntp_rx, &inst->local_ntp_tx,
9ea1e4e4 1233 &inst->remote_addr, &local_addr, NULL, NULL);
d446950c 1234
88840341 1235 ++inst->tx_count;
535ca64b
ML
1236 if (sent)
1237 inst->report.total_tx_count++;
88840341 1238
d446950c
ML
1239 /* If the source loses connectivity and our packets are still being sent,
1240 back off the sampling rate to reduce the network traffic. If it's the
1241 source to which we are currently locked, back off slowly. */
8b93e1a7
ML
1242
1243 if (inst->tx_count >= 2) {
1244 /* Implies we have missed at least one transmission */
0c4968ec 1245
d446950c
ML
1246 if (sent) {
1247 adjust_poll(inst, SRC_IsSyncPeer(inst->source) ? 0.1 : 0.25);
1248 }
0c4968ec
ML
1249
1250 SRC_UpdateReachability(inst->source, 0);
88840341
RC
1251 }
1252
7637faa0
ML
1253 /* With auto_offline take the source offline if sending failed */
1254 if (!sent && inst->auto_offline)
1255 NCR_SetConnectivity(inst, SRC_OFFLINE);
1256
88840341 1257 switch (inst->opmode) {
88840341 1258 case MD_BURST_WAS_ONLINE:
4e66b5ce
ML
1259 /* When not reachable, don't stop online burst until sending succeeds */
1260 if (!sent && !SRC_IsReachable(inst->source))
1261 break;
1262 /* Fall through */
88840341 1263 case MD_BURST_WAS_OFFLINE:
60a25f6e 1264 --inst->burst_total_samples_to_go;
78ae4ebf 1265 break;
7637faa0
ML
1266 case MD_OFFLINE:
1267 return;
78ae4ebf 1268 default:
88840341
RC
1269 break;
1270 }
1271
78ae4ebf 1272 /* Restart timer for this message */
ba283e6b 1273 restart_timeout(inst, get_transmit_delay(inst, 1, 0.0));
88840341 1274
cbd77c97
ML
1275 /* If a client packet was just sent, schedule a timeout to close the socket
1276 at the time when all server replies would fail the delay test, so the
1277 socket is not open for longer than necessary */
1278 if (inst->mode == MODE_CLIENT)
1279 inst->rx_timeout_id = SCH_AddTimeoutByDelay(inst->max_delay + MAX_SERVER_INTERVAL,
1280 receive_timeout, (void *)inst);
1281}
88840341 1282
8fbfe55e
ML
1283/* ================================================== */
1284
8fbfe55e 1285static int
588785e1 1286parse_packet(NTP_Packet *packet, int length, NTP_PacketInfo *info)
8fbfe55e 1287{
588785e1
ML
1288 if (length < NTP_HEADER_LENGTH || length % 4U != 0) {
1289 DEBUG_LOG("NTP packet has invalid length %d", length);
1290 return 0;
1291 }
1292
1293 info->length = length;
1294 info->version = NTP_LVM_TO_VERSION(packet->lvm);
1295 info->mode = NTP_LVM_TO_MODE(packet->lvm);
1296 info->ext_fields = 0;
46cac4e2 1297 info->auth.mode = NTP_AUTH_NONE;
588785e1
ML
1298
1299 if (info->version < NTP_MIN_COMPAT_VERSION || info->version > NTP_MAX_COMPAT_VERSION) {
1300 DEBUG_LOG("NTP packet has invalid version %d", info->version);
1301 return 0;
1302 }
1303
56a102ed
ML
1304 /* Parse authentication extension fields or MAC */
1305 if (!NAU_ParsePacket(packet, info))
1306 return 0;
8fbfe55e 1307
56a102ed 1308 return 1;
8fbfe55e
ML
1309}
1310
88840341
RC
1311/* ================================================== */
1312
c68ca40c
ML
1313static int
1314check_delay_ratio(NCR_Instance inst, SST_Stats stats,
1315 struct timespec *sample_time, double delay)
1316{
1317 double last_sample_ago, predicted_offset, min_delay, skew, std_dev;
1318 double max_delay;
1319
1320 if (inst->max_delay_ratio < 1.0 ||
1321 !SST_GetDelayTestData(stats, sample_time, &last_sample_ago,
1322 &predicted_offset, &min_delay, &skew, &std_dev))
1323 return 1;
1324
1325 max_delay = min_delay * inst->max_delay_ratio +
1326 last_sample_ago * (skew + LCL_GetMaxClockError());
1327
1328 if (delay <= max_delay)
1329 return 1;
1330
1331 DEBUG_LOG("maxdelayratio: delay=%e max_delay=%e", delay, max_delay);
1332 return 0;
1333}
1334
1335/* ================================================== */
1336
51fe80ad
ML
1337static int
1338check_delay_dev_ratio(NCR_Instance inst, SST_Stats stats,
1339 struct timespec *sample_time, double offset, double delay)
1340{
1341 double last_sample_ago, predicted_offset, min_delay, skew, std_dev;
1342 double delta, max_delta, error_in_estimate;
1343
1344 if (!SST_GetDelayTestData(stats, sample_time, &last_sample_ago,
1345 &predicted_offset, &min_delay, &skew, &std_dev))
1346 return 1;
1347
1348 /* Require that the ratio of the increase in delay from the minimum to the
1349 standard deviation is less than max_delay_dev_ratio. In the allowed
1350 increase in delay include also dispersion. */
1351
1352 max_delta = std_dev * inst->max_delay_dev_ratio +
1353 last_sample_ago * (skew + LCL_GetMaxClockError());
1354 delta = (delay - min_delay) / 2.0;
1355
1356 if (delta <= max_delta)
1357 return 1;
1358
1359 error_in_estimate = offset + predicted_offset;
1360
1361 /* Before we decide to drop the sample, make sure the difference between
1362 measured offset and predicted offset is not significantly larger than
1363 the increase in delay */
1364 if (fabs(error_in_estimate) - delta > max_delta)
1365 return 1;
1366
1367 DEBUG_LOG("maxdelaydevratio: error=%e delay=%e delta=%e max_delta=%e",
1368 error_in_estimate, delay, delta, max_delta);
1369 return 0;
1370}
1371
1372/* ================================================== */
1373
7a88e0a8
ML
1374static int
1375check_sync_loop(NCR_Instance inst, NTP_Packet *message, NTP_Local_Address *local_addr,
1376 struct timespec *local_ts)
1377{
1378 double our_root_delay, our_root_dispersion;
1379 int are_we_synchronised, our_stratum;
1380 struct timespec our_ref_time;
1381 NTP_Leap leap_status;
1382 uint32_t our_ref_id;
1383
00498631 1384 /* Check if a server socket is open, i.e. a client or peer can actually
7a88e0a8 1385 be synchronised to us */
00498631 1386 if (!NIO_IsServerSocketOpen())
7a88e0a8
ML
1387 return 1;
1388
1389 /* Check if the source indicates that it is synchronised to our address
1390 (assuming it uses the same address as the one from which we send requests
1391 to the source) */
1392 if (message->stratum > 1 &&
1393 message->reference_id == htonl(UTI_IPToRefid(&local_addr->ip_addr)))
1394 return 0;
1395
1396 /* Compare our reference data with the source to make sure it is not us
1397 (e.g. due to a misconfiguration) */
1398
1399 REF_GetReferenceParams(local_ts, &are_we_synchronised, &leap_status, &our_stratum,
1400 &our_ref_id, &our_ref_time, &our_root_delay, &our_root_dispersion);
1401
1402 if (message->stratum == our_stratum &&
1403 message->reference_id == htonl(our_ref_id) &&
1404 message->root_delay == UTI_DoubleToNtp32(our_root_delay) &&
1405 !UTI_IsZeroNtp64(&message->reference_ts)) {
1406 NTP_int64 ntp_ref_time;
1407
1408 UTI_TimespecToNtp64(&our_ref_time, &ntp_ref_time, NULL);
1409 if (UTI_CompareNtp64(&message->reference_ts, &ntp_ref_time) == 0) {
1410 DEBUG_LOG("Source %s is me", UTI_IPToString(&inst->remote_addr.ip_addr));
1411 return 0;
1412 }
1413 }
1414
1415 return 1;
1416}
1417
1418/* ================================================== */
1419
189aafde
ML
1420static void
1421process_sample(NCR_Instance inst, NTP_Sample *sample)
1422{
1423 double estimated_offset, error_in_estimate, filtered_sample_ago;
1424 NTP_Sample filtered_sample;
1425 int filtered_samples;
1426
1427 /* Accumulate the sample to the median filter if it is enabled. When the
1428 filter produces a result, check if it is not too old, i.e. the filter did
1429 not miss too many samples due to missing responses or failing tests. */
1430 if (inst->filter) {
1431 SPF_AccumulateSample(inst->filter, sample);
1432
1433 filtered_samples = SPF_GetNumberOfSamples(inst->filter);
1434
1435 if (!SPF_GetFilteredSample(inst->filter, &filtered_sample))
1436 return;
1437
1438 filtered_sample_ago = UTI_DiffTimespecsToDouble(&sample->time, &filtered_sample.time);
1439
1440 if (filtered_sample_ago > SOURCE_REACH_BITS / 2 * filtered_samples *
1441 UTI_Log2ToDouble(inst->local_poll)) {
1442 DEBUG_LOG("filtered sample dropped ago=%f poll=%d", filtered_sample_ago,
1443 inst->local_poll);
1444 return;
1445 }
1446
1447 sample = &filtered_sample;
1448 }
1449
1450 /* Get the estimated offset predicted from previous samples. The
1451 convention here is that positive means local clock FAST of
1452 reference, i.e. backwards to the way that 'offset' is defined. */
1453 estimated_offset = SST_PredictOffset(SRC_GetSourcestats(inst->source), &sample->time);
1454
1455 error_in_estimate = fabs(-sample->offset - estimated_offset);
1456
1457 SRC_AccumulateSample(inst->source, sample);
1458 SRC_SelectSource(inst->source);
1459
1460 adjust_poll(inst, get_poll_adj(inst, error_in_estimate,
1461 sample->peer_dispersion + 0.5 * sample->peer_delay));
1462}
1463
1464/* ================================================== */
1465
aaf744df 1466static int
2d492eac
ML
1467process_response(NCR_Instance inst, NTP_Local_Address *local_addr,
1468 NTP_Local_Timestamp *rx_ts, NTP_Packet *message, NTP_PacketInfo *info)
88840341 1469{
6bef8aa0 1470 NTP_Sample sample;
1045adaa
ML
1471 SST_Stats stats;
1472
89b127bf 1473 int pkt_leap, pkt_version;
ca28dbd2 1474 uint32_t pkt_refid;
88840341
RC
1475 double pkt_root_delay;
1476 double pkt_root_dispersion;
1477
8fbfe55e
ML
1478 /* The skew and estimated frequency offset relative to the remote source */
1479 double skew, source_freq_lo, source_freq_hi;
88840341 1480
8fbfe55e 1481 /* RFC 5905 packet tests */
90b25f5b
ML
1482 int test1, test2n, test2i, test2, test3, test5, test6, test7;
1483 int interleaved_packet, valid_packet, synced_packet;
88840341 1484
8fbfe55e
ML
1485 /* Additional tests */
1486 int testA, testB, testC, testD;
1487 int good_packet;
88840341 1488
8fbfe55e
ML
1489 /* Kiss-o'-Death codes */
1490 int kod_rate;
88840341 1491
2e0870ee
ML
1492 NTP_Local_Timestamp local_receive, local_transmit;
1493 double remote_interval, local_interval, response_time;
8fbfe55e 1494 double delay_time, precision;
f0f18a02 1495 int updated_timestamps;
9f9dd794 1496
8fbfe55e 1497 /* ==================== */
88840341 1498
1045adaa
ML
1499 stats = SRC_GetSourcestats(inst->source);
1500
8fbfe55e 1501 pkt_leap = NTP_LVM_TO_LEAP(message->lvm);
89b127bf 1502 pkt_version = NTP_LVM_TO_VERSION(message->lvm);
8fbfe55e 1503 pkt_refid = ntohl(message->reference_id);
99cc9452
ML
1504 pkt_root_delay = UTI_Ntp32ToDouble(message->root_delay);
1505 pkt_root_dispersion = UTI_Ntp32ToDouble(message->root_dispersion);
88840341 1506
8fbfe55e
ML
1507 /* Check if the packet is valid per RFC 5905, section 8.
1508 The test values are 1 when passed and 0 when failed. */
1509
1510 /* Test 1 checks for duplicate packet */
666ece12
ML
1511 test1 = UTI_CompareNtp64(&message->receive_ts, &inst->remote_ntp_rx) ||
1512 UTI_CompareNtp64(&message->transmit_ts, &inst->remote_ntp_tx);
90b25f5b
ML
1513
1514 /* Test 2 checks for bogus packet in the basic and interleaved modes. This
1515 ensures the source is responding to the latest packet we sent to it. */
6e9c0489 1516 test2n = !UTI_CompareNtp64(&message->originate_ts, &inst->local_ntp_tx);
90b25f5b 1517 test2i = inst->interleaved &&
6e9c0489 1518 !UTI_CompareNtp64(&message->originate_ts, &inst->local_ntp_rx);
90b25f5b
ML
1519 test2 = test2n || test2i;
1520 interleaved_packet = !test2n && test2i;
8fbfe55e
ML
1521
1522 /* Test 3 checks for invalid timestamps. This can happen when the
1523 association if not properly 'up'. */
6e9c0489
ML
1524 test3 = !UTI_IsZeroNtp64(&message->originate_ts) &&
1525 !UTI_IsZeroNtp64(&message->receive_ts) &&
1526 !UTI_IsZeroNtp64(&message->transmit_ts);
8fbfe55e
ML
1527
1528 /* Test 4 would check for denied access. It would always pass as this
1529 function is called only for known sources. */
1530
ca28dbd2
ML
1531 /* Test 5 checks for authentication failure */
1532 test5 = NAU_CheckResponseAuth(inst->auth, message, info);
8fbfe55e
ML
1533
1534 /* Test 6 checks for unsynchronised server */
1535 test6 = pkt_leap != LEAP_Unsynchronised &&
1536 message->stratum < NTP_MAX_STRATUM &&
1537 message->stratum != NTP_INVALID_STRATUM;
1538
1539 /* Test 7 checks for bad data. The root distance must be smaller than a
37e6357c
ML
1540 defined maximum. */
1541 test7 = pkt_root_delay / 2.0 + pkt_root_dispersion < NTP_MAX_DISPERSION;
8fbfe55e 1542
cea21adb
ML
1543 /* The packet is considered valid if the tests 1-5 passed. The timestamps
1544 can be used for synchronisation if the tests 6 and 7 passed too. */
1545 valid_packet = test1 && test2 && test3 && test5;
1546 synced_packet = valid_packet && test6 && test7;
8fbfe55e
ML
1547
1548 /* Check for Kiss-o'-Death codes */
1549 kod_rate = 0;
1550 if (test1 && test2 && test5 && pkt_leap == LEAP_Unsynchronised &&
1551 message->stratum == NTP_INVALID_STRATUM) {
1552 if (pkt_refid == KOD_RATE)
1553 kod_rate = 1;
88840341
RC
1554 }
1555
90b25f5b
ML
1556 if (synced_packet && (!interleaved_packet || inst->valid_timestamps)) {
1557 /* These are the timespec equivalents of the remote and local epochs */
2e0870ee 1558 struct timespec remote_receive, remote_transmit, remote_request_receive;
2668a12e
ML
1559 struct timespec local_average, remote_average, prev_remote_transmit;
1560 double prev_remote_poll_interval;
90b25f5b 1561
2e0870ee 1562 /* Select remote and local timestamps for the new sample */
90b25f5b 1563 if (interleaved_packet) {
0baa35ea
ML
1564 /* Prefer previous local TX and remote RX timestamps if it will make
1565 the intervals significantly shorter in order to improve the accuracy
1566 of the measured delay */
1567 if (!UTI_IsZeroTimespec(&inst->prev_local_tx.ts) &&
1568 MAX_INTERLEAVED_L2L_RATIO *
1569 UTI_DiffTimespecsToDouble(&inst->local_tx.ts, &inst->local_rx.ts) >
1570 UTI_DiffTimespecsToDouble(&inst->local_rx.ts, &inst->prev_local_tx.ts)) {
1571 UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_receive);
1572 remote_request_receive = remote_receive;
1573 local_transmit = inst->prev_local_tx;
1574 } else {
1575 UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
1576 UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_request_receive);
1577 local_transmit = inst->local_tx;
1578 }
2e0870ee 1579 UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
2668a12e 1580 UTI_Ntp64ToTimespec(&inst->remote_ntp_tx, &prev_remote_transmit);
2e0870ee 1581 local_receive = inst->local_rx;
90b25f5b 1582 } else {
2e0870ee
ML
1583 UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
1584 UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
2668a12e 1585 UTI_ZeroTimespec(&prev_remote_transmit);
2e0870ee
ML
1586 remote_request_receive = remote_receive;
1587 local_receive = *rx_ts;
1588 local_transmit = inst->local_tx;
90b25f5b 1589 }
88840341 1590
2e0870ee
ML
1591 /* Calculate intervals between remote and local timestamps */
1592 UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
1593 &remote_average, &remote_interval);
1594 UTI_AverageDiffTimespecs(&local_transmit.ts, &local_receive.ts,
1595 &local_average, &local_interval);
1596 response_time = fabs(UTI_DiffTimespecsToDouble(&remote_transmit,
1597 &remote_request_receive));
1598
1599 precision = LCL_GetSysPrecisionAsQuantum() + UTI_Log2ToDouble(message->precision);
1600
14bb9f29 1601 /* Calculate delay */
6bef8aa0
ML
1602 sample.peer_delay = fabs(local_interval - remote_interval);
1603 if (sample.peer_delay < precision)
1604 sample.peer_delay = precision;
88840341 1605
8fbfe55e 1606 /* Calculate offset. Following the NTP definition, this is negative
88840341 1607 if we are fast of the remote source. */
6bef8aa0 1608 sample.offset = UTI_DiffTimespecsToDouble(&remote_average, &local_average);
6cd55839
ML
1609
1610 /* Apply configured correction */
6bef8aa0 1611 sample.offset += inst->offset_correction;
6cd55839 1612
88840341
RC
1613 /* We treat the time of the sample as being midway through the local
1614 measurement period. An analysis assuming constant relative
1615 frequency and zero network delay shows this is the only possible
1616 choice to estimate the frequency difference correctly for every
1617 sample pair. */
6bef8aa0 1618 sample.time = local_average;
88840341 1619
2e0870ee
ML
1620 SST_GetFrequencyRange(stats, &source_freq_lo, &source_freq_hi);
1621
88840341 1622 /* Calculate skew */
1d72d22b 1623 skew = (source_freq_hi - source_freq_lo) / 2.0;
88840341
RC
1624
1625 /* and then calculate peer dispersion */
6bef8aa0
ML
1626 sample.peer_dispersion = MAX(precision, MAX(local_transmit.err, local_receive.err)) +
1627 skew * fabs(local_interval);
88840341 1628
2668a12e
ML
1629 /* If the source is an active peer, this is the minimum assumed interval
1630 between previous two transmissions (if not constrained by minpoll) */
1631 prev_remote_poll_interval = UTI_Log2ToDouble(MIN(inst->remote_poll,
1632 inst->prev_local_poll));
1633
8fbfe55e
ML
1634 /* Additional tests required to pass before accumulating the sample */
1635
23a4e8b3 1636 /* Test A requires that the minimum estimate of the peer delay is not
2668a12e 1637 larger than the configured maximum, in both client modes that the server
b896bb5a
ML
1638 processing time is sane, and in interleaved symmetric mode that the
1639 measured delay and intervals between remote timestamps don't indicate
1640 a missed response */
6bef8aa0
ML
1641 testA = sample.peer_delay - sample.peer_dispersion <= inst->max_delay &&
1642 precision <= inst->max_delay &&
b896bb5a 1643 !(inst->mode == MODE_CLIENT && response_time > MAX_SERVER_INTERVAL) &&
90b25f5b 1644 !(inst->mode == MODE_ACTIVE && interleaved_packet &&
6bef8aa0 1645 (sample.peer_delay > 0.5 * prev_remote_poll_interval ||
2668a12e
ML
1646 UTI_CompareNtp64(&message->receive_ts, &message->transmit_ts) <= 0 ||
1647 (inst->remote_poll <= inst->prev_local_poll &&
1648 UTI_DiffTimespecsToDouble(&remote_transmit, &prev_remote_transmit) >
1649 1.5 * prev_remote_poll_interval)));
8fbfe55e 1650
e1645966
ML
1651 /* Test B requires in client mode that the ratio of the round trip delay
1652 to the minimum one currently in the stats data register is less than an
1653 administrator-defined value */
6bef8aa0 1654 testB = check_delay_ratio(inst, stats, &sample.time, sample.peer_delay);
8fbfe55e
ML
1655
1656 /* Test C requires that the ratio of the increase in delay from the minimum
1657 one in the stats data register to the standard deviation of the offsets
1658 in the register is less than an administrator-defined value or the
1659 difference between measured offset and predicted offset is larger than
1660 the increase in delay */
6bef8aa0 1661 testC = check_delay_dev_ratio(inst, stats, &sample.time, sample.offset, sample.peer_delay);
8fbfe55e 1662
7a88e0a8
ML
1663 /* Test D requires that the source is not synchronised to us and is not us
1664 to prevent a synchronisation loop */
1665 testD = check_sync_loop(inst, message, local_addr, &rx_ts->ts);
88840341 1666 } else {
2e0870ee 1667 remote_interval = local_interval = response_time = 0.0;
6bef8aa0
ML
1668 sample.offset = sample.peer_delay = sample.peer_dispersion = 0.0;
1669 sample.time = rx_ts->ts;
2e0870ee
ML
1670 local_receive = *rx_ts;
1671 local_transmit = inst->local_tx;
8fbfe55e 1672 testA = testB = testC = testD = 0;
88840341
RC
1673 }
1674
8fbfe55e
ML
1675 /* The packet is considered good for synchronisation if
1676 the additional tests passed */
1677 good_packet = testA && testB && testC && testD;
1678
6bef8aa0
ML
1679 sample.root_delay = pkt_root_delay + sample.peer_delay;
1680 sample.root_dispersion = pkt_root_dispersion + sample.peer_dispersion;
8fbfe55e 1681
90b25f5b
ML
1682 /* Update the NTP timestamps. If it's a valid packet from a synchronised
1683 source, the timestamps may be used later when processing a packet in the
96d652e5 1684 interleaved mode. Protect the timestamps against replay attacks in client
33053a5e
ML
1685 mode, and also in symmetric mode as long as the peers use the same polling
1686 interval and never start with clocks in future or very distant past.
1687 The authentication test (test5) is required to prevent DoS attacks using
1688 unauthenticated packets on authenticated symmetric associations. */
96d652e5 1689 if ((inst->mode == MODE_CLIENT && valid_packet && !inst->valid_rx) ||
f0f18a02
ML
1690 (inst->mode == MODE_ACTIVE && valid_packet &&
1691 (!inst->valid_rx ||
33053a5e 1692 UTI_CompareNtp64(&inst->remote_ntp_tx, &message->transmit_ts) < 0))) {
90b25f5b
ML
1693 inst->remote_ntp_rx = message->receive_ts;
1694 inst->remote_ntp_tx = message->transmit_ts;
1695 inst->local_rx = *rx_ts;
1696 inst->valid_timestamps = synced_packet;
f0f18a02
ML
1697
1698 UTI_ZeroNtp64(&inst->init_remote_ntp_tx);
1699 zero_local_timestamp(&inst->init_local_rx);
1700 inst->updated_init_timestamps = 0;
1701 updated_timestamps = 2;
0baa35ea
ML
1702
1703 /* Don't use the same set of timestamps for the next sample */
1704 if (interleaved_packet)
1705 inst->prev_local_tx = inst->local_tx;
1706 else
1707 zero_local_timestamp(&inst->prev_local_tx);
f0f18a02
ML
1708 } else if (inst->mode == MODE_ACTIVE &&
1709 test1 && !UTI_IsZeroNtp64(&message->transmit_ts) && test5 &&
1710 (!inst->updated_init_timestamps ||
1711 UTI_CompareNtp64(&inst->init_remote_ntp_tx, &message->transmit_ts) < 0)) {
1712 inst->init_remote_ntp_tx = message->transmit_ts;
1713 inst->init_local_rx = *rx_ts;
1714 inst->updated_init_timestamps = 1;
1715 updated_timestamps = 1;
1716 } else {
1717 updated_timestamps = 0;
90b25f5b
ML
1718 }
1719
1720 /* Accept at most one response per request. The NTP specification recommends
1721 resetting local_ntp_tx to make the following packets fail test2 or test3,
33053a5e 1722 but that would not allow the code above to make multiple updates of the
2408bbcd 1723 timestamps in symmetric mode. Also, ignore presend responses. */
90b25f5b
ML
1724 if (inst->valid_rx) {
1725 test2 = test3 = 0;
1726 valid_packet = synced_packet = good_packet = 0;
1727 } else if (valid_packet) {
2408bbcd
ML
1728 if (inst->presend_done) {
1729 testA = 0;
1730 good_packet = 0;
1731 }
90b25f5b
ML
1732 inst->valid_rx = 1;
1733 }
1734
2e0870ee
ML
1735 if ((unsigned int)local_receive.source >= sizeof (tss_chars) ||
1736 (unsigned int)local_transmit.source >= sizeof (tss_chars))
9f9dd794
ML
1737 assert(0);
1738
f282856c 1739 DEBUG_LOG("NTP packet lvm=%o stratum=%d poll=%d prec=%d root_delay=%f root_disp=%f refid=%"PRIx32" [%s]",
8fbfe55e
ML
1740 message->lvm, message->stratum, message->poll, message->precision,
1741 pkt_root_delay, pkt_root_dispersion, pkt_refid,
1742 message->stratum == NTP_INVALID_STRATUM ? UTI_RefidToString(pkt_refid) : "");
f282856c 1743 DEBUG_LOG("reference=%s origin=%s receive=%s transmit=%s",
99cc9452
ML
1744 UTI_Ntp64ToString(&message->reference_ts),
1745 UTI_Ntp64ToString(&message->originate_ts),
1746 UTI_Ntp64ToString(&message->receive_ts),
1747 UTI_Ntp64ToString(&message->transmit_ts));
f282856c 1748 DEBUG_LOG("offset=%.9f delay=%.9f dispersion=%f root_delay=%f root_dispersion=%f",
6bef8aa0
ML
1749 sample.offset, sample.peer_delay, sample.peer_dispersion,
1750 sample.root_delay, sample.root_dispersion);
2e0870ee
ML
1751 DEBUG_LOG("remote_interval=%.9f local_interval=%.9f response_time=%.9f txs=%c rxs=%c",
1752 remote_interval, local_interval, response_time,
1753 tss_chars[local_transmit.source], tss_chars[local_receive.source]);
f0f18a02
ML
1754 DEBUG_LOG("test123=%d%d%d test567=%d%d%d testABCD=%d%d%d%d kod_rate=%d interleaved=%d"
1755 " presend=%d valid=%d good=%d updated=%d",
8fbfe55e 1756 test1, test2, test3, test5, test6, test7, testA, testB, testC, testD,
2408bbcd 1757 kod_rate, interleaved_packet, inst->presend_done, valid_packet, good_packet,
f0f18a02 1758 updated_timestamps);
8fbfe55e 1759
8fbfe55e 1760 if (valid_packet) {
577290c5
ML
1761 inst->remote_poll = message->poll;
1762 inst->remote_stratum = message->stratum != NTP_INVALID_STRATUM ?
1763 message->stratum : NTP_MAX_STRATUM;
1764
2668a12e 1765 inst->prev_local_poll = inst->local_poll;
64c2fd98 1766 inst->prev_tx_count = inst->tx_count;
30e65496 1767 inst->tx_count = 0;
2668a12e 1768
30e65496 1769 SRC_UpdateReachability(inst->source, synced_packet);
1a8dcce8 1770 SRC_UpdateStatus(inst->source, MAX(message->stratum, inst->min_stratum), pkt_leap);
88840341 1771
8fbfe55e 1772 if (good_packet) {
189aafde
ML
1773 /* Adjust the polling interval, accumulate the sample, etc. */
1774 process_sample(inst, &sample);
030e3b2d
ML
1775
1776 /* If we're in burst mode, check whether the burst is completed and
1777 revert to the previous mode */
1778 switch (inst->opmode) {
1779 case MD_BURST_WAS_ONLINE:
1780 case MD_BURST_WAS_OFFLINE:
1781 --inst->burst_good_samples_to_go;
030e3b2d 1782 if (inst->burst_good_samples_to_go <= 0) {
60a25f6e 1783 if (inst->opmode == MD_BURST_WAS_ONLINE)
030e3b2d 1784 inst->opmode = MD_ONLINE;
60a25f6e
ML
1785 else
1786 take_offline(inst);
030e3b2d
ML
1787 }
1788 break;
1789 default:
1790 break;
88840341 1791 }
30e65496 1792 } else {
feef0dd9
ML
1793 /* Slowly increase the polling interval if we can't get a good response */
1794 adjust_poll(inst, testD ? 0.02 : 0.1);
030e3b2d 1795 }
88840341 1796
a9b9e7be
ML
1797 /* If in client mode, no more packets are expected to be coming from the
1798 server and the socket can be closed */
1799 close_client_socket(inst);
1800
86acea5c 1801 /* Update the local address and interface */
eb75ce7d 1802 inst->local_addr.ip_addr = local_addr->ip_addr;
86acea5c 1803 inst->local_addr.if_index = local_addr->if_index;
eb75ce7d 1804
cea21adb
ML
1805 /* And now, requeue the timer */
1806 if (inst->opmode != MD_OFFLINE) {
2577e20f 1807 delay_time = get_transmit_delay(inst, 0,
14c8f076 1808 UTI_DiffTimespecsToDouble(&inst->local_rx.ts, &inst->local_tx.ts));
88840341 1809
cea21adb 1810 if (kod_rate) {
f282856c 1811 LOG(LOGS_WARN, "Received KoD RATE from %s",
b76ea642
ML
1812 UTI_IPToString(&inst->remote_addr.ip_addr));
1813
cea21adb 1814 /* Back off for a while and stop ongoing burst */
beaaaad1 1815 delay_time += 4 * UTI_Log2ToDouble(inst->local_poll);
cf700a00 1816
cea21adb
ML
1817 if (inst->opmode == MD_BURST_WAS_OFFLINE || inst->opmode == MD_BURST_WAS_ONLINE) {
1818 inst->burst_good_samples_to_go = 0;
cea21adb
ML
1819 }
1820 }
88840341 1821
cea21adb
ML
1822 /* Get rid of old timeout and start a new one */
1823 assert(inst->tx_timeout_id);
1824 restart_timeout(inst, delay_time);
1825 }
535ca64b
ML
1826
1827 /* Update the NTP report */
1828 inst->report.remote_addr = inst->remote_addr.ip_addr;
1829 inst->report.local_addr = inst->local_addr.ip_addr;
1830 inst->report.remote_port = inst->remote_addr.port;
89b127bf
ML
1831 inst->report.leap = pkt_leap;
1832 inst->report.version = pkt_version;
535ca64b
ML
1833 inst->report.mode = NTP_LVM_TO_MODE(message->lvm);
1834 inst->report.stratum = message->stratum;
1835 inst->report.poll = message->poll;
1836 inst->report.precision = message->precision;
1837 inst->report.root_delay = pkt_root_delay;
1838 inst->report.root_dispersion = pkt_root_dispersion;
1839 inst->report.ref_id = pkt_refid;
1840 UTI_Ntp64ToTimespec(&message->reference_ts, &inst->report.ref_time);
6bef8aa0
ML
1841 inst->report.offset = sample.offset;
1842 inst->report.peer_delay = sample.peer_delay;
1843 inst->report.peer_dispersion = sample.peer_dispersion;
2e0870ee 1844 inst->report.response_time = response_time;
535ca64b
ML
1845 inst->report.jitter_asymmetry = SST_GetJitterAsymmetry(stats);
1846 inst->report.tests = ((((((((test1 << 1 | test2) << 1 | test3) << 1 |
1847 test5) << 1 | test6) << 1 | test7) << 1 |
1848 testA) << 1 | testB) << 1 | testC) << 1 | testD;
1849 inst->report.interleaved = interleaved_packet;
ca28dbd2 1850 inst->report.authenticated = NAU_IsAuthEnabled(inst->auth);
2e0870ee
ML
1851 inst->report.tx_tss_char = tss_chars[local_transmit.source];
1852 inst->report.rx_tss_char = tss_chars[local_receive.source];
535ca64b
ML
1853
1854 inst->report.total_valid_count++;
88840341
RC
1855 }
1856
1857 /* Do measurement logging */
0a0aff14 1858 if (logfileid != -1 && (log_raw_measurements || synced_packet)) {
756c2e9a 1859 LOG_FileWrite(logfileid, "%s %-15s %1c %2d %1d%1d%1d %1d%1d%1d %1d%1d%1d%d %2d %2d %4.2f %10.3e %10.3e %10.3e %10.3e %10.3e %08"PRIX32" %1d%1c %1c %1c",
6bef8aa0 1860 UTI_TimeToLogForm(sample.time.tv_sec),
8265ff28 1861 UTI_IPToString(&inst->remote_addr.ip_addr),
2c877fa1 1862 leap_chars[pkt_leap],
88840341 1863 message->stratum,
8fbfe55e 1864 test1, test2, test3, test5, test6, test7, testA, testB, testC, testD,
5c691a54 1865 inst->local_poll, message->poll,
7a6ee1d7 1866 inst->poll_score,
6bef8aa0 1867 sample.offset, sample.peer_delay, sample.peer_dispersion,
2c877fa1
ML
1868 pkt_root_delay, pkt_root_dispersion, pkt_refid,
1869 NTP_LVM_TO_MODE(message->lvm), interleaved_packet ? 'I' : 'B',
2e0870ee
ML
1870 tss_chars[local_transmit.source],
1871 tss_chars[local_receive.source]);
88840341 1872 }
aaf744df 1873
b0838280 1874 return good_packet;
88840341
RC
1875}
1876
1877/* ================================================== */
8fbfe55e 1878/* From RFC 5905, the standard handling of received packets, depending
88840341
RC
1879 on the mode of the packet and of the source, is :
1880
8fbfe55e
ML
1881 +------------------+---------------------------------------+
1882 | | Packet Mode |
1883 +------------------+-------+-------+-------+-------+-------+
1884 | Association Mode | 1 | 2 | 3 | 4 | 5 |
1885 +------------------+-------+-------+-------+-------+-------+
1886 | No Association 0 | NEWPS | DSCRD | FXMIT | MANY | NEWBC |
1887 | Symm. Active 1 | PROC | PROC | DSCRD | DSCRD | DSCRD |
1888 | Symm. Passive 2 | PROC | ERR | DSCRD | DSCRD | DSCRD |
1889 | Client 3 | DSCRD | DSCRD | DSCRD | PROC | DSCRD |
1890 | Server 4 | DSCRD | DSCRD | DSCRD | DSCRD | DSCRD |
1891 | Broadcast 5 | DSCRD | DSCRD | DSCRD | DSCRD | DSCRD |
1892 | Bcast Client 6 | DSCRD | DSCRD | DSCRD | DSCRD | PROC |
1893 +------------------+-------+-------+-------+-------+-------+
1894
8f6a1b53
ML
1895 Association mode 0 is implemented in NCR_ProcessRxUnknown(), other modes
1896 in NCR_ProcessRxKnown().
8fbfe55e
ML
1897
1898 Broadcast, manycast and ephemeral symmetric passive associations are not
1899 supported yet.
88840341
RC
1900 */
1901
1902/* ================================================== */
cc3f5962
ML
1903/* This routine is called when a new packet arrives off the network,
1904 and it relates to a source we have an ongoing protocol exchange with */
88840341 1905
aaf744df 1906int
14c8f076
ML
1907NCR_ProcessRxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
1908 NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
88840341 1909{
cb8660e7
ML
1910 int proc_packet, proc_as_unknown;
1911 NTP_PacketInfo info;
88840341 1912
567e66a0
ML
1913 inst->report.total_rx_count++;
1914
cb8660e7 1915 if (!parse_packet(message, length, &info))
aaf744df 1916 return 0;
88840341 1917
8fbfe55e
ML
1918 proc_packet = 0;
1919 proc_as_unknown = 0;
777303f1 1920
88840341 1921 /* Now, depending on the mode we decide what to do */
cb8660e7 1922 switch (info.mode) {
88840341 1923 case MODE_ACTIVE:
8fbfe55e 1924 switch (inst->mode) {
88840341
RC
1925 case MODE_ACTIVE:
1926 /* Ordinary symmetric peering */
8fbfe55e 1927 proc_packet = 1;
88840341
RC
1928 break;
1929 case MODE_PASSIVE:
1930 /* In this software this case should not arise, we don't
1931 support unconfigured peers */
1932 break;
1933 case MODE_CLIENT:
1934 /* This is where we have the remote configured as a server and he has
8fbfe55e
ML
1935 us configured as a peer, process as from an unknown source */
1936 proc_as_unknown = 1;
88840341
RC
1937 break;
1938 default:
8fbfe55e 1939 /* Discard */
88840341
RC
1940 break;
1941 }
88840341
RC
1942 break;
1943
8fbfe55e
ML
1944 case MODE_PASSIVE:
1945 switch (inst->mode) {
88840341 1946 case MODE_ACTIVE:
8fbfe55e
ML
1947 /* This would arise if we have the remote configured as a peer and
1948 he does not have us configured */
8fbfe55e 1949 proc_packet = 1;
88840341
RC
1950 break;
1951 case MODE_PASSIVE:
8fbfe55e 1952 /* Error condition in RFC 5905 */
88840341
RC
1953 break;
1954 default:
8fbfe55e 1955 /* Discard */
88840341
RC
1956 break;
1957 }
1958 break;
1959
8fbfe55e
ML
1960 case MODE_CLIENT:
1961 /* If message is client mode, we just respond with a server mode
1962 packet, regardless of what we think the remote machine is
1963 supposed to be. However, even though this is a configured
1964 peer or server, we still implement access restrictions on
1965 client mode operation.
88840341 1966
8fbfe55e
ML
1967 This copes with the case for an isolated network where one
1968 machine is set by eye and is used as the master, with the
1969 other machines pointed at it. If the master goes down, we
1970 want to be able to reset its time at startup by relying on
1971 one of the secondaries to flywheel it. The behaviour coded here
1972 is required in the secondaries to make this possible. */
1973
1974 proc_as_unknown = 1;
1975 break;
1976
1977 case MODE_SERVER:
8fbfe55e 1978 switch (inst->mode) {
88840341 1979 case MODE_CLIENT:
8fbfe55e
ML
1980 /* Standard case where he's a server and we're the client */
1981 proc_packet = 1;
88840341
RC
1982 break;
1983 default:
8fbfe55e 1984 /* Discard */
88840341
RC
1985 break;
1986 }
1987 break;
1988
1989 case MODE_BROADCAST:
8fbfe55e 1990 /* Just ignore these */
88840341
RC
1991 break;
1992
1993 default:
1994 /* Obviously ignore */
1995 break;
8fbfe55e
ML
1996 }
1997
8fbfe55e 1998 if (proc_packet) {
dccd6196
ML
1999 /* Check if the reply was received by the socket that sent the request */
2000 if (local_addr->sock_fd != inst->local_addr.sock_fd) {
f282856c 2001 DEBUG_LOG("Packet received by wrong socket %d (expected %d)",
dccd6196 2002 local_addr->sock_fd, inst->local_addr.sock_fd);
aaf744df 2003 return 0;
dccd6196
ML
2004 }
2005
2006 /* Ignore packets from offline sources */
2007 if (inst->opmode == MD_OFFLINE || inst->tx_suspended) {
f282856c 2008 DEBUG_LOG("Packet from offline source");
aaf744df 2009 return 0;
dccd6196
ML
2010 }
2011
2d492eac 2012 return process_response(inst, local_addr, rx_ts, message, &info);
8fbfe55e 2013 } else if (proc_as_unknown) {
14c8f076 2014 NCR_ProcessRxUnknown(&inst->remote_addr, local_addr, rx_ts, message, length);
aaf744df
ML
2015 /* It's not a reply to our request, don't return success */
2016 return 0;
8fbfe55e 2017 } else {
cb8660e7 2018 DEBUG_LOG("NTP packet discarded mode=%d our_mode=%u", (int)info.mode, inst->mode);
aaf744df 2019 return 0;
88840341 2020 }
88840341
RC
2021}
2022
2023/* ================================================== */
2024/* This routine is called when a new packet arrives off the network,
73e49868 2025 and it relates to a source we don't know (not our server or peer) */
88840341
RC
2026
2027void
14c8f076
ML
2028NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
2029 NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
88840341 2030{
cb8660e7
ML
2031 NTP_PacketInfo info;
2032 NTP_Mode my_mode;
96d652e5
ML
2033 NTP_int64 *local_ntp_rx, *local_ntp_tx;
2034 NTP_Local_Timestamp local_tx, *tx_ts;
ca28dbd2 2035 int log_index, interleaved, poll, version;
aca1daf7 2036 uint32_t kod;
88840341 2037
91e74c70
ML
2038 /* Ignore the packet if it wasn't received by server socket */
2039 if (!NIO_IsServerSocket(local_addr->sock_fd)) {
f282856c 2040 DEBUG_LOG("NTP request packet received by client socket %d", local_addr->sock_fd);
91e74c70
ML
2041 return;
2042 }
2043
cb8660e7 2044 if (!parse_packet(message, length, &info))
8cc7ebff 2045 return;
8cc7ebff 2046
8fbfe55e 2047 if (!ADF_IsAllowed(access_auth_table, &remote_addr->ip_addr)) {
d7868091
ML
2048 DEBUG_LOG("NTP packet received from unauthorised host %s",
2049 UTI_IPToString(&remote_addr->ip_addr));
8fbfe55e
ML
2050 return;
2051 }
88840341 2052
cb8660e7 2053 switch (info.mode) {
8fbfe55e 2054 case MODE_ACTIVE:
88840341
RC
2055 /* We are symmetric passive, even though we don't ever lock to him */
2056 my_mode = MODE_PASSIVE;
8fbfe55e
ML
2057 break;
2058 case MODE_CLIENT:
2059 /* Reply with server packet */
2060 my_mode = MODE_SERVER;
8fbfe55e 2061 break;
fbca570d
ML
2062 case MODE_UNDEFINED:
2063 /* Check if it is an NTPv1 client request (NTPv1 packets have a reserved
2064 field instead of the mode field and the actual mode is determined from
2065 the port numbers). Don't ever respond with a mode 0 packet! */
cb8660e7 2066 if (info.version == 1 && remote_addr->port != NTP_PORT) {
fbca570d
ML
2067 my_mode = MODE_SERVER;
2068 break;
2069 }
2070 /* Fall through */
8fbfe55e
ML
2071 default:
2072 /* Discard */
cb8660e7 2073 DEBUG_LOG("NTP packet discarded mode=%d", (int)info.mode);
8fbfe55e 2074 return;
88840341 2075 }
8fbfe55e 2076
aca1daf7 2077 kod = 0;
3a2d33d5 2078 log_index = CLG_LogServiceAccess(CLG_NTP, &remote_addr->ip_addr, &rx_ts->ts);
b506594c
ML
2079
2080 /* Don't reply to all requests if the rate is excessive */
3a2d33d5 2081 if (log_index >= 0 && CLG_LimitServiceRate(CLG_NTP, log_index)) {
f282856c 2082 DEBUG_LOG("NTP packet discarded to limit response rate");
b506594c
ML
2083 return;
2084 }
086e886d 2085
ca28dbd2 2086 /* Check authentication */
aca1daf7
ML
2087 if (!NAU_CheckRequestAuth(message, &info, &kod)) {
2088 DEBUG_LOG("NTP packet failed auth mode=%d kod=%"PRIx32, (int)info.auth.mode, kod);
2089
2090 /* Don't respond unless a non-zero KoD was returned */
2091 if (kod == 0)
2092 return;
f8df4789
ML
2093 } else if (info.auth.mode != NTP_AUTH_NONE && info.auth.mode != NTP_AUTH_MSSNTP) {
2094 CLG_LogAuthNtpRequest();
61dd4e0c 2095 }
8fbfe55e 2096
96d652e5
ML
2097 local_ntp_rx = local_ntp_tx = NULL;
2098 tx_ts = NULL;
2099 interleaved = 0;
2100
2101 /* Check if the client is using the interleaved mode. If it is, save the
2102 new transmit timestamp and if the old transmit timestamp is valid, respond
2103 in the interleaved mode. This means the third reply to a new client is
2104 the earliest one that can be interleaved. We don't want to waste time
2105 on clients that are not using the interleaved mode. */
aca1daf7 2106 if (kod == 0 && log_index >= 0) {
96d652e5 2107 CLG_GetNtpTimestamps(log_index, &local_ntp_rx, &local_ntp_tx);
6e9c0489 2108 interleaved = !UTI_IsZeroNtp64(local_ntp_rx) &&
c6dd7496
ML
2109 !UTI_CompareNtp64(&message->originate_ts, local_ntp_rx) &&
2110 UTI_CompareNtp64(&message->receive_ts, &message->transmit_ts);
96d652e5
ML
2111
2112 if (interleaved) {
4b98dada 2113 UTI_Ntp64ToTimespec(local_ntp_tx, &local_tx.ts);
96d652e5
ML
2114 tx_ts = &local_tx;
2115 } else {
6e9c0489 2116 UTI_ZeroNtp64(local_ntp_tx);
96d652e5
ML
2117 local_ntp_tx = NULL;
2118 }
2119 }
2120
018a1c42
ML
2121 /* Suggest the client to increase its polling interval if it indicates
2122 the interval is shorter than the rate limiting interval */
2123 poll = CLG_GetNtpMinPoll();
2124 poll = MAX(poll, message->poll);
2125
fdfcabd7
ML
2126 /* Respond with the same version */
2127 version = info.version;
2128
96d652e5 2129 /* Send a reply */
aca1daf7 2130 transmit_packet(my_mode, interleaved, poll, version, kod, NULL,
ca28dbd2 2131 &message->receive_ts, &message->transmit_ts,
9ea1e4e4
ML
2132 rx_ts, tx_ts, local_ntp_rx, NULL, remote_addr, local_addr,
2133 message, &info);
96d652e5
ML
2134
2135 /* Save the transmit timestamp */
2136 if (tx_ts)
2137 UTI_TimespecToNtp64(&tx_ts->ts, local_ntp_tx, NULL);
88840341
RC
2138}
2139
2140/* ================================================== */
2141
8f6a1b53 2142static void
14c8f076 2143update_tx_timestamp(NTP_Local_Timestamp *tx_ts, NTP_Local_Timestamp *new_tx_ts,
bd736f92 2144 NTP_int64 *local_ntp_rx, NTP_int64 *local_ntp_tx, NTP_Packet *message)
8f6a1b53
ML
2145{
2146 double delay;
2147
14c8f076 2148 if (UTI_IsZeroTimespec(&tx_ts->ts)) {
f282856c 2149 DEBUG_LOG("Unexpected TX update");
8f6a1b53
ML
2150 return;
2151 }
2152
2153 /* Check if this is the last packet that was sent */
6e9c0489
ML
2154 if ((local_ntp_rx && UTI_CompareNtp64(&message->receive_ts, local_ntp_rx)) ||
2155 (local_ntp_tx && UTI_CompareNtp64(&message->transmit_ts, local_ntp_tx))) {
f282856c 2156 DEBUG_LOG("RX/TX timestamp mismatch");
8f6a1b53
ML
2157 return;
2158 }
2159
14c8f076 2160 delay = UTI_DiffTimespecsToDouble(&new_tx_ts->ts, &tx_ts->ts);
8f6a1b53
ML
2161
2162 if (delay < 0.0 || delay > MAX_TX_DELAY) {
f282856c 2163 DEBUG_LOG("Unacceptable TX delay %.9f", delay);
8f6a1b53
ML
2164 return;
2165 }
2166
2167 *tx_ts = *new_tx_ts;
2168
f282856c 2169 DEBUG_LOG("Updated TX timestamp delay=%.9f", delay);
8f6a1b53
ML
2170}
2171
2172/* ================================================== */
2173
2174void
14c8f076
ML
2175NCR_ProcessTxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
2176 NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
8f6a1b53 2177{
cb8660e7 2178 NTP_PacketInfo info;
8f6a1b53 2179
cb8660e7 2180 if (!parse_packet(message, length, &info))
8f6a1b53
ML
2181 return;
2182
8f6a1b53 2183 /* Server and passive mode packets are responses to unknown sources */
cb8660e7 2184 if (info.mode != MODE_CLIENT && info.mode != MODE_ACTIVE) {
14c8f076 2185 NCR_ProcessTxUnknown(&inst->remote_addr, local_addr, tx_ts, message, length);
8f6a1b53
ML
2186 return;
2187 }
2188
bd736f92
ML
2189 update_tx_timestamp(&inst->local_tx, tx_ts, &inst->local_ntp_rx, &inst->local_ntp_tx,
2190 message);
8f6a1b53
ML
2191}
2192
2193/* ================================================== */
2194
2195void
14c8f076
ML
2196NCR_ProcessTxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
2197 NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
8f6a1b53 2198{
96d652e5
ML
2199 NTP_int64 *local_ntp_rx, *local_ntp_tx;
2200 NTP_Local_Timestamp local_tx;
cb8660e7 2201 NTP_PacketInfo info;
96d652e5
ML
2202 int log_index;
2203
cb8660e7 2204 if (!parse_packet(message, length, &info))
96d652e5
ML
2205 return;
2206
cb8660e7 2207 if (info.mode == MODE_BROADCAST)
2d67871b
ML
2208 return;
2209
96d652e5
ML
2210 log_index = CLG_GetClientIndex(&remote_addr->ip_addr);
2211 if (log_index < 0)
2212 return;
2213
cb8660e7 2214 if (SMT_IsEnabled() && info.mode == MODE_SERVER)
da2d33e9
ML
2215 UTI_AddDoubleToTimespec(&tx_ts->ts, SMT_GetOffset(&tx_ts->ts), &tx_ts->ts);
2216
96d652e5
ML
2217 CLG_GetNtpTimestamps(log_index, &local_ntp_rx, &local_ntp_tx);
2218
2219 UTI_Ntp64ToTimespec(local_ntp_tx, &local_tx.ts);
2220 update_tx_timestamp(&local_tx, tx_ts, local_ntp_rx, NULL, message);
2221 UTI_TimespecToNtp64(&local_tx.ts, local_ntp_tx, NULL);
8f6a1b53
ML
2222}
2223
2224/* ================================================== */
2225
88840341 2226void
d0dfa1de 2227NCR_SlewTimes(NCR_Instance inst, struct timespec *when, double dfreq, double doffset)
88840341 2228{
40d82675 2229 double delta;
7958b176 2230
14c8f076
ML
2231 if (!UTI_IsZeroTimespec(&inst->local_rx.ts))
2232 UTI_AdjustTimespec(&inst->local_rx.ts, when, &inst->local_rx.ts, &delta, dfreq, doffset);
2233 if (!UTI_IsZeroTimespec(&inst->local_tx.ts))
2234 UTI_AdjustTimespec(&inst->local_tx.ts, when, &inst->local_tx.ts, &delta, dfreq, doffset);
0baa35ea
ML
2235 if (!UTI_IsZeroTimespec(&inst->prev_local_tx.ts))
2236 UTI_AdjustTimespec(&inst->prev_local_tx.ts, when, &inst->prev_local_tx.ts, &delta, dfreq,
2237 doffset);
f0f18a02 2238 if (!UTI_IsZeroTimespec(&inst->init_local_rx.ts))
b2964417 2239 UTI_AdjustTimespec(&inst->init_local_rx.ts, when, &inst->init_local_rx.ts, &delta, dfreq,
f0f18a02 2240 doffset);
189aafde
ML
2241
2242 if (inst->filter)
2243 SPF_SlewSamples(inst->filter, when, dfreq, doffset);
88840341
RC
2244}
2245
2246/* ================================================== */
2247
b0fe4436
ML
2248static void
2249set_connectivity(NCR_Instance inst, SRC_Connectivity connectivity)
88840341 2250{
8b9021bf
ML
2251 if (connectivity == SRC_MAYBE_ONLINE)
2252 connectivity = NIO_IsServerConnectable(&inst->remote_addr) ? SRC_ONLINE : SRC_OFFLINE;
2253
ce6b8969
ML
2254 switch (connectivity) {
2255 case SRC_ONLINE:
2256 switch (inst->opmode) {
2257 case MD_ONLINE:
2258 /* Nothing to do */
2259 break;
2260 case MD_OFFLINE:
ce6b8969
ML
2261 inst->opmode = MD_ONLINE;
2262 NCR_ResetInstance(inst);
2263 start_initial_timeout(inst);
b0fe4436
ML
2264 if (inst->auto_iburst)
2265 NCR_InitiateSampleBurst(inst, IBURST_GOOD_SAMPLES, IBURST_TOTAL_SAMPLES);
ce6b8969
ML
2266 break;
2267 case MD_BURST_WAS_ONLINE:
2268 /* Will revert */
2269 break;
2270 case MD_BURST_WAS_OFFLINE:
2271 inst->opmode = MD_BURST_WAS_ONLINE;
ce6b8969
ML
2272 break;
2273 default:
2274 assert(0);
2275 }
88840341 2276 break;
ce6b8969
ML
2277 case SRC_OFFLINE:
2278 switch (inst->opmode) {
2279 case MD_ONLINE:
ce6b8969
ML
2280 take_offline(inst);
2281 break;
2282 case MD_OFFLINE:
2283 break;
2284 case MD_BURST_WAS_ONLINE:
2285 inst->opmode = MD_BURST_WAS_OFFLINE;
ce6b8969
ML
2286 break;
2287 case MD_BURST_WAS_OFFLINE:
2288 break;
2289 default:
2290 assert(0);
2291 }
88840341 2292 break;
ce6b8969
ML
2293 default:
2294 assert(0);
88840341 2295 }
88840341
RC
2296}
2297
2298/* ================================================== */
2299
b0fe4436
ML
2300void
2301NCR_SetConnectivity(NCR_Instance inst, SRC_Connectivity connectivity)
2302{
2303 OperatingMode prev_opmode;
2304 int was_online, is_online;
2305
2306 prev_opmode = inst->opmode;
2307
2308 set_connectivity(inst, connectivity);
2309
2310 /* Report an important change */
2311 was_online = prev_opmode == MD_ONLINE || prev_opmode == MD_BURST_WAS_ONLINE;
2312 is_online = inst->opmode == MD_ONLINE || inst->opmode == MD_BURST_WAS_ONLINE;
2313 if (was_online != is_online)
2314 LOG(LOGS_INFO, "Source %s %s",
2315 UTI_IPToString(&inst->remote_addr.ip_addr), is_online ? "online" : "offline");
2316}
2317
2318/* ================================================== */
2319
88840341
RC
2320void
2321NCR_ModifyMinpoll(NCR_Instance inst, int new_minpoll)
2322{
2c47602c 2323 if (new_minpoll < MIN_POLL || new_minpoll > MAX_POLL)
0380cf0c 2324 return;
88840341 2325 inst->minpoll = new_minpoll;
f282856c 2326 LOG(LOGS_INFO, "Source %s new minpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_minpoll);
4b5f4650
ML
2327 if (inst->maxpoll < inst->minpoll)
2328 NCR_ModifyMaxpoll(inst, inst->minpoll);
88840341
RC
2329}
2330
2331/* ================================================== */
2332
2333void
2334NCR_ModifyMaxpoll(NCR_Instance inst, int new_maxpoll)
2335{
2c47602c 2336 if (new_maxpoll < MIN_POLL || new_maxpoll > MAX_POLL)
0380cf0c 2337 return;
88840341 2338 inst->maxpoll = new_maxpoll;
f282856c 2339 LOG(LOGS_INFO, "Source %s new maxpoll %d", UTI_IPToString(&inst->remote_addr.ip_addr), new_maxpoll);
4b5f4650
ML
2340 if (inst->minpoll > inst->maxpoll)
2341 NCR_ModifyMinpoll(inst, inst->maxpoll);
88840341
RC
2342}
2343
2344/* ================================================== */
2345
2346void
2347NCR_ModifyMaxdelay(NCR_Instance inst, double new_max_delay)
2348{
99147ed8 2349 inst->max_delay = CLAMP(0.0, new_max_delay, MAX_MAXDELAY);
74f0c092 2350 LOG(LOGS_INFO, "Source %s new maxdelay %f",
f2f834e7 2351 UTI_IPToString(&inst->remote_addr.ip_addr), inst->max_delay);
88840341
RC
2352}
2353
2354/* ================================================== */
2355
2356void
2357NCR_ModifyMaxdelayratio(NCR_Instance inst, double new_max_delay_ratio)
2358{
99147ed8 2359 inst->max_delay_ratio = CLAMP(0.0, new_max_delay_ratio, MAX_MAXDELAYRATIO);
74f0c092 2360 LOG(LOGS_INFO, "Source %s new maxdelayratio %f",
f2f834e7 2361 UTI_IPToString(&inst->remote_addr.ip_addr), inst->max_delay_ratio);
88840341
RC
2362}
2363
2364/* ================================================== */
2365
6ed5a650
ML
2366void
2367NCR_ModifyMaxdelaydevratio(NCR_Instance inst, double new_max_delay_dev_ratio)
2368{
99147ed8 2369 inst->max_delay_dev_ratio = CLAMP(0.0, new_max_delay_dev_ratio, MAX_MAXDELAYDEVRATIO);
74f0c092 2370 LOG(LOGS_INFO, "Source %s new maxdelaydevratio %f",
f2f834e7 2371 UTI_IPToString(&inst->remote_addr.ip_addr), inst->max_delay_dev_ratio);
6ed5a650
ML
2372}
2373
2374/* ================================================== */
2375
78300d01
ML
2376void
2377NCR_ModifyMinstratum(NCR_Instance inst, int new_min_stratum)
2378{
2379 inst->min_stratum = new_min_stratum;
f282856c 2380 LOG(LOGS_INFO, "Source %s new minstratum %d",
78300d01
ML
2381 UTI_IPToString(&inst->remote_addr.ip_addr), new_min_stratum);
2382}
2383
2384/* ================================================== */
2385
bed5b72c
ML
2386void
2387NCR_ModifyPolltarget(NCR_Instance inst, int new_poll_target)
2388{
2389 inst->poll_target = new_poll_target;
f282856c 2390 LOG(LOGS_INFO, "Source %s new polltarget %d",
bed5b72c
ML
2391 UTI_IPToString(&inst->remote_addr.ip_addr), new_poll_target);
2392}
2393
2394/* ================================================== */
2395
88840341
RC
2396void
2397NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples)
2398{
2399
2400 if (inst->mode == MODE_CLIENT) {
2401
2402 /* We want to prevent burst mode being used on symmetric active
2403 associations - it will play havoc with the peer's sampling
2404 strategy. (This obviously relies on us having the peer
2405 configured that way if he has us configured symmetric active -
2406 but there's not much else we can do.) */
2407
2408 switch (inst->opmode) {
2409 case MD_BURST_WAS_OFFLINE:
2410 case MD_BURST_WAS_ONLINE:
2411 /* If already burst sampling, don't start again */
2412 break;
2413
2414 case MD_ONLINE:
8671002b 2415 case MD_OFFLINE:
779e40ed
ML
2416 inst->opmode = inst->opmode == MD_ONLINE ?
2417 MD_BURST_WAS_ONLINE : MD_BURST_WAS_OFFLINE;
8671002b
ML
2418 inst->burst_good_samples_to_go = n_good_samples;
2419 inst->burst_total_samples_to_go = n_total_samples;
2420 start_initial_timeout(inst);
2421 break;
88840341 2422 default:
6b0198c2 2423 assert(0);
88840341
RC
2424 break;
2425 }
2426 }
2427
2428}
2429
2430/* ================================================== */
2431
2432void
d0dfa1de 2433NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timespec *now)
88840341 2434{
62cd319a 2435 report->poll = get_transmit_poll(inst);
88840341
RC
2436
2437 switch (inst->mode) {
2438 case MODE_CLIENT:
2439 report->mode = RPT_NTP_CLIENT;
2440 break;
2441 case MODE_ACTIVE:
2442 report->mode = RPT_NTP_PEER;
2443 break;
2444 default:
6b0198c2 2445 assert(0);
88840341 2446 }
88840341
RC
2447}
2448
2449/* ================================================== */
2450
79c7384e
ML
2451void
2452NCR_GetAuthReport(NCR_Instance inst, RPT_AuthReport *report)
2453{
2454 NAU_GetReport(inst->auth, report);
2455}
2456
2457/* ================================================== */
2458
535ca64b
ML
2459void
2460NCR_GetNTPReport(NCR_Instance inst, RPT_NTPReport *report)
2461{
2462 *report = inst->report;
2463}
2464
2465/* ================================================== */
2466
88840341 2467int
8265ff28 2468NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
88840341
RC
2469 {
2470 ADF_Status status;
2471
2472 if (allow) {
2473 if (all) {
2474 status = ADF_AllowAll(access_auth_table, ip_addr, subnet_bits);
2475 } else {
2476 status = ADF_Allow(access_auth_table, ip_addr, subnet_bits);
2477 }
2478 } else {
2479 if (all) {
2480 status = ADF_DenyAll(access_auth_table, ip_addr, subnet_bits);
2481 } else {
2482 status = ADF_Deny(access_auth_table, ip_addr, subnet_bits);
2483 }
2484 }
2485
52e12e42 2486 if (status != ADF_SUCCESS)
88840341 2487 return 0;
52e12e42
ML
2488
2489 /* Keep server sockets open only when an address allowed */
2490 if (allow) {
2491 NTP_Remote_Address remote_addr;
2492
2493 if (server_sock_fd4 == INVALID_SOCK_FD &&
2494 ADF_IsAnyAllowed(access_auth_table, IPADDR_INET4)) {
2495 remote_addr.ip_addr.family = IPADDR_INET4;
2496 server_sock_fd4 = NIO_OpenServerSocket(&remote_addr);
2497 }
2498 if (server_sock_fd6 == INVALID_SOCK_FD &&
2499 ADF_IsAnyAllowed(access_auth_table, IPADDR_INET6)) {
2500 remote_addr.ip_addr.family = IPADDR_INET6;
2501 server_sock_fd6 = NIO_OpenServerSocket(&remote_addr);
2502 }
88840341 2503 } else {
52e12e42
ML
2504 if (server_sock_fd4 != INVALID_SOCK_FD &&
2505 !ADF_IsAnyAllowed(access_auth_table, IPADDR_INET4)) {
2506 NIO_CloseServerSocket(server_sock_fd4);
2507 server_sock_fd4 = INVALID_SOCK_FD;
2508 }
2509 if (server_sock_fd6 != INVALID_SOCK_FD &&
2510 !ADF_IsAnyAllowed(access_auth_table, IPADDR_INET6)) {
2511 NIO_CloseServerSocket(server_sock_fd6);
2512 server_sock_fd6 = INVALID_SOCK_FD;
2513 }
88840341 2514 }
52e12e42
ML
2515
2516 return 1;
88840341
RC
2517}
2518
2519/* ================================================== */
2520
2521int
8265ff28 2522NCR_CheckAccessRestriction(IPAddr *ip_addr)
88840341
RC
2523{
2524 return ADF_IsAllowed(access_auth_table, ip_addr);
2525}
2526
2527/* ================================================== */
2528
88840341
RC
2529void
2530NCR_IncrementActivityCounters(NCR_Instance inst, int *online, int *offline,
2531 int *burst_online, int *burst_offline)
2532{
2533 switch (inst->opmode) {
2534 case MD_BURST_WAS_OFFLINE:
2535 ++*burst_offline;
2536 break;
2537 case MD_BURST_WAS_ONLINE:
2538 ++*burst_online;
2539 break;
2540 case MD_ONLINE:
2541 ++*online;
2542 break;
2543 case MD_OFFLINE:
2544 ++*offline;
2545 break;
2546 default:
6b0198c2 2547 assert(0);
88840341
RC
2548 break;
2549 }
2550}
2551
2552/* ================================================== */
48b6c2aa
ML
2553
2554NTP_Remote_Address *
2555NCR_GetRemoteAddress(NCR_Instance inst)
2556{
2557 return &inst->remote_addr;
2558}
2559
2560/* ================================================== */
2ea87490 2561
eb75ce7d
ML
2562uint32_t
2563NCR_GetLocalRefid(NCR_Instance inst)
2564{
2565 return UTI_IPToRefid(&inst->local_addr.ip_addr);
2566}
2567
2568/* ================================================== */
2569
2ea87490
ML
2570int NCR_IsSyncPeer(NCR_Instance inst)
2571{
2572 return SRC_IsSyncPeer(inst->source);
2573}
2574
2575/* ================================================== */
a78bf0c3 2576
d690faeb
ML
2577void
2578NCR_DumpAuthData(NCR_Instance inst)
2579{
2580 NAU_DumpData(inst->auth);
2581}
2582
2583/* ================================================== */
2584
a78bf0c3
ML
2585static void
2586broadcast_timeout(void *arg)
2587{
2588 BroadcastDestination *destination;
2589 NTP_int64 orig_ts;
14c8f076 2590 NTP_Local_Timestamp recv_ts;
97d42033 2591 int poll;
a78bf0c3
ML
2592
2593 destination = ARR_GetElement(broadcasts, (long)arg);
97d42033 2594 poll = log(destination->interval) / log(2.0) + 0.5;
a78bf0c3 2595
6e9c0489 2596 UTI_ZeroNtp64(&orig_ts);
43cd119d 2597 zero_local_timestamp(&recv_ts);
a78bf0c3 2598
aca1daf7 2599 transmit_packet(MODE_BROADCAST, 0, poll, NTP_VERSION, 0, destination->auth,
ca28dbd2
ML
2600 &orig_ts, &orig_ts, &recv_ts, NULL, NULL, NULL,
2601 &destination->addr, &destination->local_addr, NULL, NULL);
a78bf0c3
ML
2602
2603 /* Requeue timeout. We don't care if interval drifts gradually. */
97d42033 2604 SCH_AddTimeoutInClass(destination->interval, get_separation(poll), SAMPLING_RANDOMNESS,
a78bf0c3
ML
2605 SCH_NtpBroadcastClass, broadcast_timeout, arg);
2606}
2607
2608/* ================================================== */
2609
2610void
500c9cbf 2611NCR_AddBroadcastDestination(NTP_Remote_Address *addr, int interval)
a78bf0c3
ML
2612{
2613 BroadcastDestination *destination;
2614
2615 destination = (BroadcastDestination *)ARR_GetNewElement(broadcasts);
2616
500c9cbf 2617 destination->addr = *addr;
a78bf0c3 2618 destination->local_addr.ip_addr.family = IPADDR_UNSPEC;
86acea5c 2619 destination->local_addr.if_index = INVALID_IF_INDEX;
6d1dda0f 2620 destination->local_addr.sock_fd = NIO_OpenServerSocket(&destination->addr);
ca28dbd2 2621 destination->auth = NAU_CreateNoneInstance();
beaaaad1 2622 destination->interval = CLAMP(1, interval, 1 << MAX_POLL);
a78bf0c3 2623
97d42033 2624 SCH_AddTimeoutInClass(destination->interval, MAX_SAMPLING_SEPARATION, SAMPLING_RANDOMNESS,
a78bf0c3
ML
2625 SCH_NtpBroadcastClass, broadcast_timeout,
2626 (void *)(long)(ARR_GetSize(broadcasts) - 1));
2627}