sources: add trust option
Assume time from a source that is specified with the trust option is always true. It can't be rejected as falseticker in the source selection if sources that are specified without this option don't agree with it.
This commit is contained in:
parent
fa15fb3d53
commit
936f5cb0f1
8 changed files with 49 additions and 14 deletions
2
candm.h
2
candm.h
|
@ -243,6 +243,7 @@ typedef struct {
|
||||||
#define REQ_ADDSRC_IBURST 0x4
|
#define REQ_ADDSRC_IBURST 0x4
|
||||||
#define REQ_ADDSRC_PREFER 0x8
|
#define REQ_ADDSRC_PREFER 0x8
|
||||||
#define REQ_ADDSRC_NOSELECT 0x10
|
#define REQ_ADDSRC_NOSELECT 0x10
|
||||||
|
#define REQ_ADDSRC_TRUST 0x20
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IPAddr ip_addr;
|
IPAddr ip_addr;
|
||||||
|
@ -478,6 +479,7 @@ typedef struct {
|
||||||
|
|
||||||
#define RPY_SD_FLAG_NOSELECT 0x1
|
#define RPY_SD_FLAG_NOSELECT 0x1
|
||||||
#define RPY_SD_FLAG_PREFER 0x2
|
#define RPY_SD_FLAG_PREFER 0x2
|
||||||
|
#define RPY_SD_FLAG_TRUST 0x4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IPAddr ip_addr;
|
IPAddr ip_addr;
|
||||||
|
|
|
@ -2720,6 +2720,10 @@ Prefer this source over sources without prefer option.
|
||||||
@item noselect
|
@item noselect
|
||||||
Never select this source. This is useful for monitoring or with sources
|
Never select this source. This is useful for monitoring or with sources
|
||||||
which are not very accurate, but are locked with a PPS refclock.
|
which are not very accurate, but are locked with a PPS refclock.
|
||||||
|
@item trust
|
||||||
|
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 minsamples
|
@item minsamples
|
||||||
Set the minimum number of samples kept for this source. This overrides the
|
Set the minimum number of samples kept for this source. This overrides the
|
||||||
@code{minsamples} directive (@pxref{minsamples directive}).
|
@code{minsamples} directive (@pxref{minsamples directive}).
|
||||||
|
@ -3024,6 +3028,11 @@ Prefer this source over sources without prefer option.
|
||||||
@item noselect
|
@item noselect
|
||||||
Never select this source. This is particularly useful for monitoring.
|
Never select this source. This is particularly useful for monitoring.
|
||||||
|
|
||||||
|
@item trust
|
||||||
|
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 minsamples
|
@item minsamples
|
||||||
Set the minimum number of samples kept for this source. This overrides the
|
Set the minimum number of samples kept for this source. This overrides the
|
||||||
@code{minsamples} directive (@pxref{minsamples directive}).
|
@code{minsamples} directive (@pxref{minsamples directive}).
|
||||||
|
|
3
client.c
3
client.c
|
@ -1118,7 +1118,8 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
|
||||||
(data.params.auto_offline ? REQ_ADDSRC_AUTOOFFLINE : 0) |
|
(data.params.auto_offline ? REQ_ADDSRC_AUTOOFFLINE : 0) |
|
||||||
(data.params.iburst ? REQ_ADDSRC_IBURST : 0) |
|
(data.params.iburst ? REQ_ADDSRC_IBURST : 0) |
|
||||||
(data.params.sel_options & SRC_SELECT_PREFER ? REQ_ADDSRC_PREFER : 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_NOSELECT ? REQ_ADDSRC_NOSELECT : 0) |
|
||||||
|
(data.params.sel_options & SRC_SELECT_TRUST ? REQ_ADDSRC_TRUST : 0));
|
||||||
result = 1;
|
result = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
6
cmdmon.c
6
cmdmon.c
|
@ -663,7 +663,8 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
}
|
}
|
||||||
tx_message->data.source_data.flags =
|
tx_message->data.source_data.flags =
|
||||||
htons((report.sel_options & SRC_SELECT_PREFER ? RPY_SD_FLAG_PREFER : 0) |
|
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_NOSELECT ? RPY_SD_FLAG_NOSELECT : 0) |
|
||||||
|
(report.sel_options & SRC_SELECT_TRUST ? RPY_SD_FLAG_TRUST : 0));
|
||||||
tx_message->data.source_data.reachability = htons(report.reachability);
|
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.since_sample = htonl(report.latest_meas_ago);
|
||||||
tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
|
tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
|
||||||
|
@ -758,7 +759,8 @@ handle_add_source(NTP_Source_Type type, CMD_Request *rx_message, CMD_Reply *tx_m
|
||||||
params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
|
params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
|
||||||
params.sel_options =
|
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_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_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
|
||||||
|
(ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0);
|
||||||
params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
|
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);
|
params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,9 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
|
||||||
} else if (!strcasecmp(cmd, "prefer")) {
|
} else if (!strcasecmp(cmd, "prefer")) {
|
||||||
src->params.sel_options |= SRC_SELECT_PREFER;
|
src->params.sel_options |= SRC_SELECT_PREFER;
|
||||||
|
|
||||||
|
} else if (!strcasecmp(cmd, "trust")) {
|
||||||
|
src->params.sel_options |= SRC_SELECT_TRUST;
|
||||||
|
|
||||||
} else if (!strcasecmp(cmd, "version")) {
|
} else if (!strcasecmp(cmd, "version")) {
|
||||||
if (sscanf(line, "%d%n", &src->params.version, &n) != 1) {
|
if (sscanf(line, "%d%n", &src->params.version, &n) != 1) {
|
||||||
result = CPS_BadVersion;
|
result = CPS_BadVersion;
|
||||||
|
|
3
conf.c
3
conf.c
|
@ -743,6 +743,9 @@ parse_refclock(char *line)
|
||||||
} else if (!strcasecmp(cmd, "prefer")) {
|
} else if (!strcasecmp(cmd, "prefer")) {
|
||||||
n = 0;
|
n = 0;
|
||||||
sel_options |= SRC_SELECT_PREFER;
|
sel_options |= SRC_SELECT_PREFER;
|
||||||
|
} else if (!strcasecmp(cmd, "trust")) {
|
||||||
|
n = 0;
|
||||||
|
sel_options |= SRC_SELECT_TRUST;
|
||||||
} else {
|
} else {
|
||||||
other_parse_error("Invalid refclock option");
|
other_parse_error("Invalid refclock option");
|
||||||
return;
|
return;
|
||||||
|
|
36
sources.c
36
sources.c
|
@ -603,7 +603,8 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
struct timeval now, ref_time;
|
struct timeval now, ref_time;
|
||||||
int i, j, j1, j2, index, sel_prefer, n_endpoints, n_sel_sources;
|
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;
|
||||||
int depth, best_depth, combined, stratum, min_stratum, max_score_index;
|
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;
|
double src_offset, src_offset_sd, src_frequency, src_skew;
|
||||||
double src_root_delay, src_root_dispersion;
|
double src_root_delay, src_root_dispersion;
|
||||||
double best_lo, best_hi, distance, sel_src_distance, max_score;
|
double best_lo, best_hi, distance, sel_src_distance, max_score;
|
||||||
|
@ -751,8 +752,12 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
The first case is just bad luck - we need extra sources to
|
The first case is just bad luck - we need extra sources to
|
||||||
detect the falseticker, so just make an arbitrary choice based
|
detect the falseticker, so just make an arbitrary choice based
|
||||||
on stratum & stability etc.
|
on stratum & stability etc.
|
||||||
|
|
||||||
|
Intervals from sources specified with the trust option have higher
|
||||||
|
priority in the search.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
trust_depth = best_trust_depth = 0;
|
||||||
depth = best_depth = 0;
|
depth = best_depth = 0;
|
||||||
best_lo = best_hi = 0.0;
|
best_lo = best_hi = 0.0;
|
||||||
|
|
||||||
|
@ -760,14 +765,20 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
switch (sort_list[i].tag) {
|
switch (sort_list[i].tag) {
|
||||||
case LOW:
|
case LOW:
|
||||||
depth++;
|
depth++;
|
||||||
if (depth > best_depth) {
|
if (sources[sort_list[i].index]->sel_options & SRC_SELECT_TRUST)
|
||||||
|
trust_depth++;
|
||||||
|
if (trust_depth > best_trust_depth ||
|
||||||
|
(trust_depth == best_trust_depth && depth > best_depth)) {
|
||||||
|
best_trust_depth = trust_depth;
|
||||||
best_depth = depth;
|
best_depth = depth;
|
||||||
best_lo = sort_list[i].offset;
|
best_lo = sort_list[i].offset;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIGH:
|
case HIGH:
|
||||||
if (depth == best_depth)
|
if (trust_depth == best_trust_depth && depth == best_depth)
|
||||||
best_hi = sort_list[i].offset;
|
best_hi = sort_list[i].offset;
|
||||||
|
if (sources[sort_list[i].index]->sel_options & SRC_SELECT_TRUST)
|
||||||
|
trust_depth--;
|
||||||
depth--;
|
depth--;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -775,9 +786,9 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_depth <= n_sel_sources / 2) {
|
if (best_depth <= n_sel_sources / 2 && !best_trust_depth) {
|
||||||
/* Could not even get half the reachable sources to agree -
|
/* Could not even get half the reachable sources to agree and there
|
||||||
clearly we can't synchronise. */
|
are no trusted sources - clearly we can't synchronise */
|
||||||
|
|
||||||
if (selected_source_index != INVALID_SOURCE) {
|
if (selected_source_index != INVALID_SOURCE) {
|
||||||
log_selection_message("Can't synchronise: no majority", NULL);
|
log_selection_message("Can't synchronise: no majority", NULL);
|
||||||
|
@ -798,14 +809,17 @@ SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
n_sel_sources = 0;
|
n_sel_sources = 0;
|
||||||
|
|
||||||
for (i = 0; i < n_sources; i++) {
|
for (i = 0; i < n_sources; i++) {
|
||||||
|
/* This should be the same condition to get into the endpoint
|
||||||
|
list */
|
||||||
if (sources[i]->status != SRC_OK)
|
if (sources[i]->status != SRC_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* This should be the same condition to get into the endpoint
|
/* Check if source's interval contains the best interval, or is wholly
|
||||||
list */
|
contained within it. If there are any trusted sources the first
|
||||||
/* Check if source's interval contains the best interval, or
|
condition is applied only to them to not allow non-trusted sources to
|
||||||
is wholly contained within it */
|
move the final offset outside the interval. */
|
||||||
if ((sources[i]->sel_info.lo_limit <= best_lo &&
|
if (((!best_trust_depth || sources[i]->sel_options & SRC_SELECT_TRUST) &&
|
||||||
|
sources[i]->sel_info.lo_limit <= best_lo &&
|
||||||
sources[i]->sel_info.hi_limit >= best_hi) ||
|
sources[i]->sel_info.hi_limit >= best_hi) ||
|
||||||
(sources[i]->sel_info.lo_limit >= best_lo &&
|
(sources[i]->sel_info.lo_limit >= best_lo &&
|
||||||
sources[i]->sel_info.hi_limit <= best_hi)) {
|
sources[i]->sel_info.hi_limit <= best_hi)) {
|
||||||
|
|
|
@ -66,5 +66,6 @@ typedef struct {
|
||||||
/* Flags for source selection */
|
/* Flags for source selection */
|
||||||
#define SRC_SELECT_NOSELECT 0x1
|
#define SRC_SELECT_NOSELECT 0x1
|
||||||
#define SRC_SELECT_PREFER 0x2
|
#define SRC_SELECT_PREFER 0x2
|
||||||
|
#define SRC_SELECT_TRUST 0x4
|
||||||
|
|
||||||
#endif /* GOT_SRCPARAMS_H */
|
#endif /* GOT_SRCPARAMS_H */
|
||||||
|
|
Loading…
Reference in a new issue