From faff931a76ed5316670c3c4231d24337cce16d14 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 2 Jun 2020 18:54:41 +0200 Subject: [PATCH] sources: require majority for trusted sources Handle trusted sources as a separate set of sources which is required to have a majority for the selection to proceed. This should improve the selection with multiple trusted sources (e.g. due to the auth selection mode). --- sources.c | 13 ++++++++----- test/unit/sources.c | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sources.c b/sources.c index e272743..e625c68 100644 --- a/sources.c +++ b/sources.c @@ -755,7 +755,7 @@ SRC_SelectSource(SRC_Instance updated_inst) struct timespec now, ref_time; int i, j, j1, j2, index, sel_prefer, n_endpoints, n_sel_sources, sel_req_source; int n_badstats_sources, max_sel_reach, max_sel_reach_size, max_badstat_reach; - int depth, best_depth, trust_depth, best_trust_depth; + int depth, best_depth, trust_depth, best_trust_depth, n_sel_trust_sources; int combined, stratum, min_stratum, max_score_index; int orphan_stratum, orphan_source; double src_offset, src_offset_sd, src_frequency, src_frequency_sd, src_skew; @@ -783,7 +783,7 @@ SRC_SelectSource(SRC_Instance updated_inst) /* Step 1 - build intervals about each source */ n_endpoints = 0; - n_sel_sources = 0; + n_sel_sources = n_sel_trust_sources = 0; n_badstats_sources = 0; sel_req_source = 0; max_sel_reach = max_badstat_reach = 0; @@ -918,6 +918,9 @@ SRC_SelectSource(SRC_Instance updated_inst) if (sources[i]->status != SRC_OK) continue; + if (sources[i]->sel_options & SRC_SELECT_TRUST) + n_sel_trust_sources++; + si = &sources[i]->sel_info; j1 = n_endpoints; @@ -1023,9 +1026,9 @@ SRC_SelectSource(SRC_Instance updated_inst) } } - if (best_depth <= n_sel_sources / 2 && !best_trust_depth) { - /* Could not even get half the reachable sources to agree and there - are no trusted sources - clearly we can't synchronise */ + if ((best_trust_depth == 0 && best_depth <= n_sel_sources / 2) || + (best_trust_depth > 0 && best_trust_depth <= n_sel_trust_sources / 2)) { + /* Could not even get half the reachable (trusted) sources to agree */ if (selected_source_index != INVALID_SOURCE) { log_selection_message("Can't synchronise: no majority", NULL); diff --git a/test/unit/sources.c b/test/unit/sources.c index a314a2e..606fcab 100644 --- a/test/unit/sources.c +++ b/test/unit/sources.c @@ -131,7 +131,7 @@ test_unit(void) trusted_passed, trusted, required_passed, required); TEST_CHECK(!trusted || !passed || (passed_lo >= trusted_lo && passed_hi <= trusted_hi)); - TEST_CHECK(!passed || trusted != 1 || (trusted == 1 && trusted_passed == 1)); + TEST_CHECK(!passed || !trusted || trusted_passed >= 1); TEST_CHECK(!passed || !required || required_passed > 0); } }