summaryrefslogtreecommitdiffstats
path: root/ntp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntp_core.c')
-rw-r--r--ntp_core.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/ntp_core.c b/ntp_core.c
index 023e60b..2965413 100644
--- a/ntp_core.c
+++ b/ntp_core.c
@@ -3,7 +3,7 @@
**********************************************************************
* Copyright (C) Richard P. Curnow 1997-2003
- * Copyright (C) Miroslav Lichvar 2009-2023
+ * Copyright (C) Miroslav Lichvar 2009-2024
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -221,7 +221,7 @@ struct NCR_Instance_Record {
int burst_good_samples_to_go;
int burst_total_samples_to_go;
- /* Report from last valid response */
+ /* Report from last valid response and packet/timestamp statistics */
RPT_NTPReport report;
};
@@ -2211,7 +2211,8 @@ process_response(NCR_Instance inst, int saved, NTP_Local_Address *local_addr,
/* Test A combines multiple tests to avoid changing the measurements log
format and ntpdata report. It requires that the minimum estimate of the
peer delay is not larger than the configured maximum, it is not a
- response in the 'warm up' exchange, in both client modes that the server
+ response in the 'warm up' exchange, the configured offset correction is
+ within the supported NTP interval, both client modes that the server
processing time is sane, in interleaved client/server mode that the
previous response was not in basic mode (which prevents using timestamps
that minimise delay error), and in interleaved symmetric mode that the
@@ -2220,6 +2221,7 @@ process_response(NCR_Instance inst, int saved, NTP_Local_Address *local_addr,
testA = sample.peer_delay - sample.peer_dispersion <= inst->max_delay &&
precision <= inst->max_delay &&
inst->presend_done <= 0 &&
+ UTI_IsTimeOffsetSane(&sample.time, sample.offset) &&
!(inst->mode == MODE_CLIENT && response_time > MAX_SERVER_INTERVAL) &&
!(inst->mode == MODE_CLIENT && interleaved_packet &&
UTI_IsZeroTimespec(&inst->prev_local_tx.ts) &&
@@ -2372,13 +2374,17 @@ process_response(NCR_Instance inst, int saved, NTP_Local_Address *local_addr,
SRC_UpdateReachability(inst->source, synced_packet);
- if (synced_packet) {
- if (inst->copy && inst->remote_stratum > 0) {
- /* Assume the reference ID and stratum of the server */
+ if (inst->copy) {
+ /* Assume the reference ID and stratum of the server */
+ if (synced_packet && inst->remote_stratum > 0) {
inst->remote_stratum--;
SRC_SetRefid(inst->source, ntohl(message->reference_id), &inst->remote_addr.ip_addr);
+ } else {
+ SRC_ResetInstance(inst->source);
}
+ }
+ if (synced_packet) {
SRC_UpdateStatus(inst->source, MAX(inst->remote_stratum, inst->min_stratum), pkt_leap);
if (inst->delay_quant)
@@ -2530,6 +2536,10 @@ NCR_ProcessRxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
NTP_PacketInfo info;
inst->report.total_rx_count++;
+ if (rx_ts->source == NTP_TS_KERNEL)
+ inst->report.total_kernel_rx_ts++;
+ else if (rx_ts->source == NTP_TS_HARDWARE)
+ inst->report.total_hw_rx_ts++;
if (!parse_packet(message, length, &info))
return 0;
@@ -2652,6 +2662,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
NTP_Local_Timestamp local_tx, *tx_ts;
NTP_int64 ntp_rx, *local_ntp_rx;
int log_index, interleaved, poll, version;
+ CLG_Limit limit;
uint32_t kod;
/* Ignore the packet if it wasn't received by server socket */
@@ -2697,7 +2708,8 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
log_index = CLG_LogServiceAccess(CLG_NTP, &remote_addr->ip_addr, &rx_ts->ts);
/* Don't reply to all requests if the rate is excessive */
- if (log_index >= 0 && CLG_LimitServiceRate(CLG_NTP, log_index)) {
+ limit = log_index >= 0 ? CLG_LimitServiceRate(CLG_NTP, log_index) : CLG_PASS;
+ if (limit == CLG_DROP) {
DEBUG_LOG("NTP packet discarded to limit response rate");
return;
}
@@ -2711,6 +2723,13 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
return;
}
+ if (limit == CLG_KOD) {
+ /* Don't respond if there is a conflict with the NTS NAK */
+ if (kod != 0)
+ return;
+ kod = KOD_RATE;
+ }
+
local_ntp_rx = NULL;
tx_ts = NULL;
interleaved = 0;
@@ -2736,7 +2755,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
CLG_DisableNtpTimestamps(&ntp_rx);
}
- CLG_UpdateNtpStats(kod != 0 && info.auth.mode != NTP_AUTH_NONE &&
+ CLG_UpdateNtpStats(kod == 0 && info.auth.mode != NTP_AUTH_NONE &&
info.auth.mode != NTP_AUTH_MSSNTP,
rx_ts->source, interleaved ? tx_ts->source : NTP_TS_DAEMON);
@@ -2812,8 +2831,11 @@ NCR_ProcessTxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
message);
if (tx_ts->source == NTP_TS_HARDWARE) {
+ inst->report.total_hw_tx_ts++;
if (has_saved_response(inst))
process_saved_response(inst);
+ } else if (tx_ts->source == NTP_TS_KERNEL) {
+ inst->report.total_kernel_tx_ts++;
}
}
@@ -3018,6 +3040,16 @@ NCR_ModifyMinstratum(NCR_Instance inst, int new_min_stratum)
/* ================================================== */
void
+NCR_ModifyOffset(NCR_Instance inst, double new_offset)
+{
+ inst->offset_correction = new_offset;
+ LOG(LOGS_INFO, "Source %s new offset %f",
+ UTI_IPToString(&inst->remote_addr.ip_addr), new_offset);
+}
+
+/* ================================================== */
+
+void
NCR_ModifyPolltarget(NCR_Instance inst, int new_poll_target)
{
inst->poll_target = MAX(1, new_poll_target);