from received packets) */
int remote_stratum; /* Stratum of the server/peer (recovered from
received packets) */
+ double remote_root_delay; /* Root delay from last valid packet */
+ double remote_root_dispersion;/* Root dispersion from last valid packet */
int presend_minpoll; /* If the current polling interval is
at least this, an extra client packet
instance->remote_poll = 0;
instance->remote_stratum = 0;
+ instance->remote_root_delay = 0.0;
+ instance->remote_root_dispersion = 0.0;
instance->valid_rx = 0;
instance->valid_timestamps = 0;
/* These are the timespec equivalents of the remote and local epochs */
struct timespec remote_receive, remote_transmit, remote_request_receive;
struct timespec local_average, remote_average, prev_remote_transmit;
- double prev_remote_poll_interval;
+ double prev_remote_poll_interval, root_delay, root_dispersion;
/* Select remote and local timestamps for the new sample */
if (interleaved_packet) {
UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_receive);
remote_request_receive = remote_receive;
local_transmit = inst->prev_local_tx;
+ root_delay = inst->remote_root_delay;
+ root_dispersion = inst->remote_root_dispersion;
} else {
UTI_Ntp64ToTimespec(&message->receive_ts, &remote_receive);
UTI_Ntp64ToTimespec(&inst->remote_ntp_rx, &remote_request_receive);
local_transmit = inst->local_tx;
+ root_delay = MAX(pkt_root_delay, inst->remote_root_delay);
+ root_dispersion = MAX(pkt_root_dispersion, inst->remote_root_dispersion);
}
UTI_Ntp64ToTimespec(&message->transmit_ts, &remote_transmit);
UTI_Ntp64ToTimespec(&inst->remote_ntp_tx, &prev_remote_transmit);
remote_request_receive = remote_receive;
local_receive = *rx_ts;
local_transmit = inst->local_tx;
+ root_delay = pkt_root_delay;
+ root_dispersion = pkt_root_dispersion;
}
/* Calculate intervals between remote and local timestamps */
/* Calculate skew */
skew = (source_freq_hi - source_freq_lo) / 2.0;
- /* and then calculate peer dispersion */
+ /* and then calculate peer dispersion and the rest of the sample */
sample.peer_dispersion = MAX(precision, MAX(local_transmit.err, local_receive.err)) +
skew * fabs(local_interval);
+ sample.root_delay = root_delay + sample.peer_delay;
+ sample.root_dispersion = root_dispersion + sample.peer_dispersion;
/* If the source is an active peer, this is the minimum assumed interval
between previous two transmissions (if not constrained by minpoll) */
} else {
remote_interval = local_interval = response_time = 0.0;
sample.offset = sample.peer_delay = sample.peer_dispersion = 0.0;
+ sample.root_delay = sample.root_dispersion = 0.0;
sample.time = rx_ts->ts;
local_receive = *rx_ts;
local_transmit = inst->local_tx;
the additional tests passed */
good_packet = testA && testB && testC && testD;
- sample.root_delay = pkt_root_delay + sample.peer_delay;
- sample.root_dispersion = pkt_root_dispersion + sample.peer_dispersion;
-
/* Update the NTP timestamps. If it's a valid packet from a synchronised
source, the timestamps may be used later when processing a packet in the
interleaved mode. Protect the timestamps against replay attacks in client
inst->remote_poll = message->poll;
inst->remote_stratum = message->stratum != NTP_INVALID_STRATUM ?
MIN(message->stratum, NTP_MAX_STRATUM) : NTP_MAX_STRATUM;
+ inst->remote_root_delay = pkt_root_delay;
+ inst->remote_root_dispersion = pkt_root_dispersion;
inst->prev_local_poll = inst->local_poll;
inst->prev_tx_count = inst->tx_count;