sources: add require option
Require that at least one of the sources specified with this option is selectable (i.e. recently reachable and not a falseticker) before updating the clock. Together with the trust option this may be useful to allow a trusted, but not very precise, reference clock or a trusted authenticated NTP source to be safely combined with unauthenticated NTP sources in order to improve the accuracy of the clock. They can be selected and used for synchronization only if they agree with the trusted and required source.
This commit is contained in:
parent
936f5cb0f1
commit
e98f76e084
8 changed files with 44 additions and 6 deletions
2
candm.h
2
candm.h
|
@ -244,6 +244,7 @@ typedef struct {
|
|||
#define REQ_ADDSRC_PREFER 0x8
|
||||
#define REQ_ADDSRC_NOSELECT 0x10
|
||||
#define REQ_ADDSRC_TRUST 0x20
|
||||
#define REQ_ADDSRC_REQUIRE 0x40
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr;
|
||||
|
@ -480,6 +481,7 @@ typedef struct {
|
|||
#define RPY_SD_FLAG_NOSELECT 0x1
|
||||
#define RPY_SD_FLAG_PREFER 0x2
|
||||
#define RPY_SD_FLAG_TRUST 0x4
|
||||
#define RPY_SD_FLAG_REQUIRE 0x8
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr;
|
||||
|
|
|
@ -2724,6 +2724,14 @@ which are not very accurate, but are locked with a PPS refclock.
|
|||
Assume time from this source is always true. It can't be rejected as a
|
||||
falseticker in the source selection if sources that are specified without this
|
||||
option don't agree with it.
|
||||
@item require
|
||||
Require that at least one of the sources specified with this option is
|
||||
selectable (i.e. recently reachable and not a falseticker) before updating the
|
||||
clock. Together with the @code{trust} option this may be useful to allow a
|
||||
trusted, but not very precise, reference clock to be safely combined with
|
||||
unauthenticated NTP sources in order to improve the accuracy of the clock.
|
||||
They can be selected and used for synchronisation only if they agree with
|
||||
the trusted and required source.
|
||||
@item minsamples
|
||||
Set the minimum number of samples kept for this source. This overrides the
|
||||
@code{minsamples} directive (@pxref{minsamples directive}).
|
||||
|
@ -3033,6 +3041,14 @@ Assume time from this source is always true. It can't be rejected as a
|
|||
falseticker in the source selection if sources that are specified without this
|
||||
option don't agree with it.
|
||||
|
||||
@item require
|
||||
Require that at least one of the sources specified with this option is
|
||||
selectable (i.e. recently reachable and not a falseticker) before updating the
|
||||
clock. Together with the @code{trust} option this may be useful to allow a
|
||||
trusted authenticated source to be safely combined with unauthenticated sources
|
||||
in order to improve the accuracy of the clock. They can be selected and used
|
||||
for synchronisation only if they agree with the trusted and required source.
|
||||
|
||||
@item minsamples
|
||||
Set the minimum number of samples kept for this source. This overrides the
|
||||
@code{minsamples} directive (@pxref{minsamples directive}).
|
||||
|
|
3
client.c
3
client.c
|
@ -1119,7 +1119,8 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
|
|||
(data.params.iburst ? REQ_ADDSRC_IBURST : 0) |
|
||||
(data.params.sel_options & SRC_SELECT_PREFER ? REQ_ADDSRC_PREFER : 0) |
|
||||
(data.params.sel_options & SRC_SELECT_NOSELECT ? REQ_ADDSRC_NOSELECT : 0) |
|
||||
(data.params.sel_options & SRC_SELECT_TRUST ? REQ_ADDSRC_TRUST : 0));
|
||||
(data.params.sel_options & SRC_SELECT_TRUST ? REQ_ADDSRC_TRUST : 0) |
|
||||
(data.params.sel_options & SRC_SELECT_REQUIRE ? REQ_ADDSRC_REQUIRE : 0));
|
||||
result = 1;
|
||||
|
||||
break;
|
||||
|
|
6
cmdmon.c
6
cmdmon.c
|
@ -664,7 +664,8 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
|||
tx_message->data.source_data.flags =
|
||||
htons((report.sel_options & SRC_SELECT_PREFER ? RPY_SD_FLAG_PREFER : 0) |
|
||||
(report.sel_options & SRC_SELECT_NOSELECT ? RPY_SD_FLAG_NOSELECT : 0) |
|
||||
(report.sel_options & SRC_SELECT_TRUST ? RPY_SD_FLAG_TRUST : 0));
|
||||
(report.sel_options & SRC_SELECT_TRUST ? RPY_SD_FLAG_TRUST : 0) |
|
||||
(report.sel_options & SRC_SELECT_REQUIRE ? RPY_SD_FLAG_REQUIRE : 0));
|
||||
tx_message->data.source_data.reachability = htons(report.reachability);
|
||||
tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
|
||||
tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
|
||||
|
@ -760,7 +761,8 @@ handle_add_source(NTP_Source_Type type, CMD_Request *rx_message, CMD_Reply *tx_m
|
|||
params.sel_options =
|
||||
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_PREFER ? SRC_SELECT_PREFER : 0) |
|
||||
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
|
||||
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0);
|
||||
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0) |
|
||||
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_REQUIRE ? SRC_SELECT_REQUIRE : 0);
|
||||
params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
|
||||
params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
|
||||
|
||||
|
|
|
@ -173,6 +173,9 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
|
|||
} else if (!strcasecmp(cmd, "trust")) {
|
||||
src->params.sel_options |= SRC_SELECT_TRUST;
|
||||
|
||||
} else if (!strcasecmp(cmd, "require")) {
|
||||
src->params.sel_options |= SRC_SELECT_REQUIRE;
|
||||
|
||||
} else if (!strcasecmp(cmd, "version")) {
|
||||
if (sscanf(line, "%d%n", &src->params.version, &n) != 1) {
|
||||
result = CPS_BadVersion;
|
||||
|
|
3
conf.c
3
conf.c
|
@ -746,6 +746,9 @@ parse_refclock(char *line)
|
|||
} else if (!strcasecmp(cmd, "trust")) {
|
||||
n = 0;
|
||||
sel_options |= SRC_SELECT_TRUST;
|
||||
} else if (!strcasecmp(cmd, "require")) {
|
||||
n = 0;
|
||||
sel_options |= SRC_SELECT_REQUIRE;
|
||||
} else {
|
||||
other_parse_error("Invalid refclock option");
|
||||
return;
|
||||
|
|
16
sources.c
16
sources.c
|
@ -602,7 +602,7 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||
struct SelectInfo *si;
|
||||
struct timeval now, ref_time;
|
||||
int i, j, j1, j2, index, sel_prefer, n_endpoints, n_sel_sources;
|
||||
int n_badstats_sources, max_sel_reach, max_badstat_reach;
|
||||
int n_badstats_sources, max_sel_reach, max_badstat_reach, sel_req_source;
|
||||
int depth, best_depth, trust_depth, best_trust_depth;
|
||||
int combined, stratum, min_stratum, max_score_index;
|
||||
double src_offset, src_offset_sd, src_frequency, src_skew;
|
||||
|
@ -631,12 +631,18 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||
n_endpoints = 0;
|
||||
n_sel_sources = 0;
|
||||
n_badstats_sources = 0;
|
||||
sel_req_source = 0;
|
||||
max_sel_reach = max_badstat_reach = 0;
|
||||
max_reach_sample_ago = 0.0;
|
||||
|
||||
for (i = 0; i < n_sources; i++) {
|
||||
assert(sources[i]->status != SRC_OK);
|
||||
|
||||
/* If some sources are specified with the require option, at least one
|
||||
of them will have to be selectable in order to update the clock */
|
||||
if (sources[i]->sel_options & SRC_SELECT_REQUIRE)
|
||||
sel_req_source = 1;
|
||||
|
||||
/* Ignore sources which were added with the noselect option */
|
||||
if (sources[i]->sel_options & SRC_SELECT_NOSELECT) {
|
||||
sources[i]->status = SRC_UNSELECTABLE;
|
||||
|
@ -825,15 +831,19 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
|||
sources[i]->sel_info.hi_limit <= best_hi)) {
|
||||
|
||||
sel_sources[n_sel_sources++] = i;
|
||||
|
||||
if (sources[i]->sel_options & SRC_SELECT_REQUIRE)
|
||||
sel_req_source = 0;
|
||||
} else {
|
||||
sources[i]->status = SRC_FALSETICKER;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_sel_sources == 0 || n_sel_sources < CNF_GetMinSources()) {
|
||||
if (!n_sel_sources || sel_req_source || n_sel_sources < CNF_GetMinSources()) {
|
||||
if (selected_source_index != INVALID_SOURCE) {
|
||||
log_selection_message("Can't synchronise: %s selectable sources",
|
||||
n_sel_sources ? "not enough" : "no");
|
||||
!n_sel_sources ? "no" :
|
||||
sel_req_source ? "no required source in" : "not enough");
|
||||
selected_source_index = INVALID_SOURCE;
|
||||
}
|
||||
mark_ok_sources(SRC_WAITS_SOURCES);
|
||||
|
|
|
@ -67,5 +67,6 @@ typedef struct {
|
|||
#define SRC_SELECT_NOSELECT 0x1
|
||||
#define SRC_SELECT_PREFER 0x2
|
||||
#define SRC_SELECT_TRUST 0x4
|
||||
#define SRC_SELECT_REQUIRE 0x8
|
||||
|
||||
#endif /* GOT_SRCPARAMS_H */
|
||||
|
|
Loading…
Reference in a new issue