From 123cb497b9df0a06861c76c22258235d880644aa Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 14 Jun 2023 14:52:10 +0200 Subject: [PATCH] sources: replace reachable sources in selection Instead of waiting for the next update of reachability, trigger replacement of falsetickers, jittery and distant sources as soon as the selection status is updated in their SRC_SelectSource() call. --- sources.c | 43 ++++++++++++++++++++++++++++++---------- test/simulation/137-pool | 2 +- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/sources.c b/sources.c index daea2f7..4f6b41d 100644 --- a/sources.c +++ b/sources.c @@ -184,6 +184,8 @@ static double reselect_distance; static double stratum_weight; static double combine_limit; +static SRC_Instance last_updated_inst; + static LOG_FileID logfileid; /* Identifier of the dump file */ @@ -218,6 +220,8 @@ void SRC_Initialise(void) { LCL_AddParameterChangeHandler(slew_sources, NULL); LCL_AddDispersionNotifyHandler(add_dispersion, NULL); + last_updated_inst = NULL; + logfileid = CNF_GetLogSelection() ? LOG_FileOpen("selection", " Date (UTC) Time IP Address S EOpts Reach Score Last sample Low end High end") : -1; @@ -301,6 +305,9 @@ void SRC_DestroyInstance(SRC_Instance instance) { int dead_index, i; + if (last_updated_inst == instance) + last_updated_inst = NULL; + assert(initialised); if (instance->index < 0 || instance->index >= n_sources || instance != sources[instance->index]) @@ -478,6 +485,19 @@ special_mode_end(void) return 1; } +/* ================================================== */ + +static void +handle_bad_source(SRC_Instance inst) +{ + if (inst->type == SRC_NTP) { + DEBUG_LOG("Bad source status=%c", get_status_char(inst->status)); + NSR_HandleBadSource(inst->ip_addr); + } +} + +/* ================================================== */ + void SRC_UpdateReachability(SRC_Instance inst, int reachable) { @@ -498,15 +518,9 @@ SRC_UpdateReachability(SRC_Instance inst, int reachable) REF_SetUnsynchronised(); } - /* Try to replace NTP sources that are unreachable, falsetickers, or - have root distance or jitter larger than the allowed maximums */ - if (inst->type == SRC_NTP && - ((!inst->reachability && inst->reachability_size == SOURCE_REACH_BITS) || - inst->status == SRC_BAD_DISTANCE || inst->status == SRC_JITTERY || - inst->status == SRC_FALSETICKER)) { - DEBUG_LOG("Bad source status=%c", get_status_char(inst->status)); - NSR_HandleBadSource(inst->ip_addr); - } + /* Try to replace unreachable NTP sources */ + if (inst->reachability == 0 && inst->reachability_size == SOURCE_REACH_BITS) + handle_bad_source(inst); } /* ================================================== */ @@ -662,6 +676,13 @@ mark_source(SRC_Instance inst, SRC_Status status) inst->status = status; + /* Try to replace NTP sources that are falsetickers, or have a root + distance or jitter larger than the allowed maximums */ + if (inst == last_updated_inst) { + if (status == SRC_FALSETICKER || status == SRC_BAD_DISTANCE || status == SRC_JITTERY) + handle_bad_source(inst); + } + DEBUG_LOG("%s status=%c options=%x reach=%o/%d updates=%d distant=%d leap=%d vote=%d lo=%f hi=%f", source_to_string(inst), get_status_char(inst->status), (unsigned int)inst->sel_options, (unsigned int)inst->reachability, @@ -812,8 +833,10 @@ SRC_SelectSource(SRC_Instance updated_inst) double first_sample_ago, max_reach_sample_ago; NTP_Leap leap_status; - if (updated_inst) + if (updated_inst) { updated_inst->updates++; + last_updated_inst = updated_inst; + } if (n_sources == 0) { /* In this case, we clearly cannot synchronise to anything */ diff --git a/test/simulation/137-pool b/test/simulation/137-pool index 41c65d2..2e9564e 100755 --- a/test/simulation/137-pool +++ b/test/simulation/137-pool @@ -62,7 +62,7 @@ check_sync || test_fail check_log_messages "Detected falseticker" 2 10 || test_fail check_log_messages "Source 192.168.123.. replaced with" 1 1 || test_fail check_file_messages "20.*192.168.123.* 11.1 6 6 " 15 17 measurements.log || test_fail -check_file_messages "20.*00:01:.. 192.168.123.* 11.1 6 6 " 1 1 measurements.log || test_fail +check_file_messages "20.*00:\(00:07\|01:..\) 192.168.123.* 11.1 6 6 " 1 1 measurements.log || test_fail rm -f tmp/measurements.log test_pass