diff --git a/ntp_core.c b/ntp_core.c index a198545..af47516 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -1325,6 +1325,43 @@ check_packet_auth(NTP_Packet *pkt, int length, /* ================================================== */ +static int +check_delay_dev_ratio(NCR_Instance inst, SST_Stats stats, + struct timespec *sample_time, double offset, double delay) +{ + double last_sample_ago, predicted_offset, min_delay, skew, std_dev; + double delta, max_delta, error_in_estimate; + + if (!SST_GetDelayTestData(stats, sample_time, &last_sample_ago, + &predicted_offset, &min_delay, &skew, &std_dev)) + return 1; + + /* Require that the ratio of the increase in delay from the minimum to the + standard deviation is less than max_delay_dev_ratio. In the allowed + increase in delay include also dispersion. */ + + max_delta = std_dev * inst->max_delay_dev_ratio + + last_sample_ago * (skew + LCL_GetMaxClockError()); + delta = (delay - min_delay) / 2.0; + + if (delta <= max_delta) + return 1; + + error_in_estimate = offset + predicted_offset; + + /* Before we decide to drop the sample, make sure the difference between + measured offset and predicted offset is not significantly larger than + the increase in delay */ + if (fabs(error_in_estimate) - delta > max_delta) + return 1; + + DEBUG_LOG("maxdelaydevratio: error=%e delay=%e delta=%e max_delta=%e", + error_in_estimate, delay, delta, max_delta); + return 0; +} + +/* ================================================== */ + static int receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr, NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length) @@ -1554,8 +1591,7 @@ receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr, in the register is less than an administrator-defined value or the difference between measured offset and predicted offset is larger than the increase in delay */ - testC = SST_IsGoodSample(stats, -offset, delay, inst->max_delay_dev_ratio, - LCL_GetMaxClockError(), &sample_time); + testC = check_delay_dev_ratio(inst, stats, &sample_time, offset, delay); /* Test D requires that the remote peer is not synchronised to us to prevent a synchronisation loop */ diff --git a/sourcestats.c b/sourcestats.c index a4a9802..cf3d813 100644 --- a/sourcestats.c +++ b/sourcestats.c @@ -813,39 +813,21 @@ SST_MinRoundTripDelay(SST_Stats inst) /* ================================================== */ int -SST_IsGoodSample(SST_Stats inst, double offset, double delay, - double max_delay_dev_ratio, double clock_error, struct timespec *when) +SST_GetDelayTestData(SST_Stats inst, struct timespec *sample_time, + double *last_sample_ago, double *predicted_offset, + double *min_delay, double *skew, double *std_dev) { - double elapsed, allowed_increase, delay_increase; - if (inst->n_samples < 6) - return 1; + return 0; - elapsed = UTI_DiffTimespecsToDouble(when, &inst->offset_time); + *last_sample_ago = UTI_DiffTimespecsToDouble(sample_time, &inst->offset_time); + *predicted_offset = inst->estimated_offset + + *last_sample_ago * inst->estimated_frequency; + *min_delay = SST_MinRoundTripDelay(inst); + *skew = inst->skew; + *std_dev = inst->std_dev; - /* Require that the ratio of the increase in delay from the minimum to the - standard deviation is less than max_delay_dev_ratio. In the allowed - increase in delay include also skew and clock_error. */ - - allowed_increase = inst->std_dev * max_delay_dev_ratio + - elapsed * (inst->skew + clock_error); - delay_increase = (delay - SST_MinRoundTripDelay(inst)) / 2.0; - - if (delay_increase < allowed_increase) - return 1; - - offset -= inst->estimated_offset + elapsed * inst->estimated_frequency; - - /* Before we decide to drop the sample, make sure the difference between - measured offset and predicted offset is not significantly larger than - the increase in delay */ - if (fabs(offset) - delay_increase > allowed_increase) - return 1; - - DEBUG_LOG("Bad sample: offset=%f delay=%f incr_delay=%f allowed=%f", - offset, delay, delay_increase, allowed_increase); - - return 0; + return 1; } /* ================================================== */ diff --git a/sourcestats.h b/sourcestats.h index 9b34cc6..f0a5ca9 100644 --- a/sourcestats.h +++ b/sourcestats.h @@ -126,10 +126,10 @@ extern double SST_PredictOffset(SST_Stats inst, struct timespec *when); /* Find the minimum round trip delay in the register */ extern double SST_MinRoundTripDelay(SST_Stats inst); -/* This routine determines if a new sample is good enough that it should be - accumulated */ -extern int SST_IsGoodSample(SST_Stats inst, double offset, double delay, - double max_delay_dev_ratio, double clock_error, struct timespec *when); +/* Get data needed for testing NTP delay */ +extern int SST_GetDelayTestData(SST_Stats inst, struct timespec *sample_time, + double *last_sample_ago, double *predicted_offset, + double *min_delay, double *skew, double *std_dev); extern void SST_SaveToFile(SST_Stats inst, FILE *out);