@item noselect
Never select this source. This is useful for monitoring or with sources
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
Set the minimum number of samples kept for this source. This overrides the
@code{minsamples} directive (@pxref{minsamples directive}).
@item noselect
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
Set the minimum number of samples kept for this source. This overrides the
@code{minsamples} directive (@pxref{minsamples directive}).
}
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_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.since_sample = htonl(report.latest_meas_ago);
tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
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_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_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
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 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_root_delay, src_root_dispersion;
double best_lo, best_hi, distance, sel_src_distance, max_score;
The first case is just bad luck - we need extra sources to
detect the falseticker, so just make an arbitrary choice based
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;
best_lo = best_hi = 0.0;
switch (sort_list[i].tag) {
case LOW:
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_lo = sort_list[i].offset;
}
break;
case HIGH:
- if (depth == best_depth)
+ if (trust_depth == best_trust_depth && depth == best_depth)
best_hi = sort_list[i].offset;
+ if (sources[sort_list[i].index]->sel_options & SRC_SELECT_TRUST)
+ trust_depth--;
depth--;
break;
default:
}
}
- if (best_depth <= n_sel_sources / 2) {
- /* Could not even get half the reachable sources to agree -
- clearly we can't synchronise. */
+ 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 (selected_source_index != INVALID_SOURCE) {
log_selection_message("Can't synchronise: no majority", NULL);
n_sel_sources = 0;
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)
continue;
- /* This should be the same condition to get into the endpoint
- list */
- /* Check if source's interval contains the best interval, or
- is wholly contained within it */
- if ((sources[i]->sel_info.lo_limit <= best_lo &&
+ /* Check if source's interval contains the best interval, or is wholly
+ contained within it. If there are any trusted sources the first
+ condition is applied only to them to not allow non-trusted sources to
+ move the final offset outside the interval. */
+ 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.lo_limit >= best_lo &&
sources[i]->sel_info.hi_limit <= best_hi)) {