parameters for the current reference. (It must be stored
relative to local time to permit frequency and offset adjustments
to be made when we trim the local clock). */
- struct timespec local_rx;
+ NTP_Local_Timestamp local_rx;
/* Local timestamp when we last transmitted a packet to the source.
We store two versions. The first is in NTP format, and is used
local clock frequency/offset changes, and use this for computing
statistics about the source when a return packet arrives. */
NTP_int64 local_ntp_tx;
- struct timespec local_tx;
+ NTP_Local_Timestamp local_tx;
/* The instance record in the main source management module. This
performs the statistical analysis on the samples we generate */
the interval between packets at least as long as the current polling
interval */
SCH_GetLastEventTime(&now, NULL, NULL);
- last_tx = UTI_DiffTimespecsToDouble(&now, &inst->local_tx);
+ last_tx = UTI_DiffTimespecsToDouble(&now, &inst->local_tx.ts);
if (last_tx < 0.0)
last_tx = 0.0;
delay = get_transmit_delay(inst, 0, 0.0) - last_tx;
result->tx_suspended = 1;
result->opmode = params->online ? MD_ONLINE : MD_OFFLINE;
result->local_poll = result->minpoll;
- UTI_ZeroTimespec(&result->local_tx);
+ UTI_ZeroTimespec(&result->local_tx.ts);
+ result->local_tx.err = 0.0;
+ result->local_tx.source = NTP_TS_DAEMON;
NCR_ResetInstance(result);
instance->remote_orig.lo = 0;
instance->local_ntp_tx.hi = 0;
instance->local_ntp_tx.lo = 0;
- UTI_ZeroTimespec(&instance->local_rx);
+ UTI_ZeroTimespec(&instance->local_rx.ts);
+ instance->local_rx.err = 0.0;
+ instance->local_rx.source = NTP_TS_DAEMON;
if (instance->local_poll != instance->minpoll) {
instance->local_poll = instance->minpoll;
int auth_mode, /* The authentication mode */
uint32_t key_id, /* The authentication key ID */
NTP_int64 *orig_ts, /* Originate timestamp (from received packet) */
- struct timespec *local_rx, /* Local time request packet was received */
- struct timespec *local_tx, /* RESULT : Time this reply
- is sent as local time, or
- NULL if don't want to
- know */
+ NTP_Local_Timestamp *local_rx, /* Local time request packet was received */
+ NTP_Local_Timestamp *local_tx, /* RESULT : Time this reply is sent as
+ local time, or NULL if don't want to
+ know */
NTP_int64 *local_ntp_tx, /* RESULT : Time reply sent
as NTP timestamp
(including adjustment to
if (smooth_time) {
our_ref_id = NTP_REFID_SMOOTH;
UTI_AddDoubleToTimespec(&our_ref_time, smooth_offset, &our_ref_time);
- UTI_AddDoubleToTimespec(local_rx, smooth_offset, &local_receive);
+ UTI_AddDoubleToTimespec(&local_rx->ts, smooth_offset, &local_receive);
} else {
- local_receive = *local_rx;
+ local_receive = local_rx->ts;
}
/* Generate transmit packet */
ret = NIO_SendPacket(&message, where_to, from, length, local_tx != NULL);
if (local_tx) {
- *local_tx = local_transmit;
+ local_tx->ts = local_transmit;
+ local_tx->err = 0.0;
+ local_tx->source = NTP_TS_DAEMON;
}
if (local_ntp_tx) {
/* ================================================== */
static int
-receive_packet(NTP_Packet *message, struct timespec *rx_ts, double rx_ts_err,
- NCR_Instance inst, NTP_Local_Address *local_addr, int length)
+receive_packet(NCR_Instance inst, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
{
int pkt_leap;
uint32_t pkt_refid, pkt_key_id;
UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
&remote_average, &remote_interval);
- UTI_AverageDiffTimespecs(&inst->local_tx, rx_ts,
+ UTI_AverageDiffTimespecs(&inst->local_tx.ts, &rx_ts->ts,
&local_average, &local_interval);
/* In our case, we work out 'delay' as the worst case delay,
skew = (source_freq_hi - source_freq_lo) / 2.0;
/* and then calculate peer dispersion */
- dispersion = precision + rx_ts_err + skew * fabs(local_interval);
+ dispersion = precision + rx_ts->err + skew * fabs(local_interval);
/* Additional tests required to pass before accumulating the sample */
pkt_refid != UTI_IPToRefid(&local_addr->ip_addr);
} else {
offset = delay = dispersion = 0.0;
- sample_time = *rx_ts;
+ sample_time = rx_ts->ts;
testA = testB = testC = testD = 0;
}
/* And now, requeue the timer */
if (inst->opmode != MD_OFFLINE) {
delay_time = get_transmit_delay(inst, 0,
- UTI_DiffTimespecsToDouble(&inst->local_rx, &inst->local_tx));
+ UTI_DiffTimespecsToDouble(&inst->local_rx.ts, &inst->local_tx.ts));
if (kod_rate) {
/* Back off for a while and stop ongoing burst */
and it relates to a source we have an ongoing protocol exchange with */
int
-NCR_ProcessRxKnown
-(NTP_Packet *message, /* the received message */
- struct timespec *rx_ts, /* timestamp at time of receipt */
- double rx_ts_err,
- NCR_Instance inst, /* the instance record for this peer/server */
- NTP_Local_Address *local_addr, /* the receiving address */
- int length /* the length of the received packet */
- )
+NCR_ProcessRxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
{
int pkt_mode, proc_packet, proc_as_unknown;
return 0;
}
- return receive_packet(message, rx_ts, rx_ts_err, inst, local_addr, length);
+ return receive_packet(inst, local_addr, rx_ts, message, length);
} else if (proc_as_unknown) {
- NCR_ProcessRxUnknown(message, rx_ts, rx_ts_err, &inst->remote_addr,
- local_addr, length);
+ NCR_ProcessRxUnknown(&inst->remote_addr, local_addr, rx_ts, message, length);
/* It's not a reply to our request, don't return success */
return 0;
} else {
and it relates to a source we don't know (not our server or peer) */
void
-NCR_ProcessRxUnknown
-(NTP_Packet *message, /* the received message */
- struct timespec *rx_ts, /* timestamp at time of receipt */
- double rx_ts_err, /* assumed error in the timestamp */
- NTP_Remote_Address *remote_addr,
- NTP_Local_Address *local_addr,
- int length /* the length of the received packet */
- )
+NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
{
NTP_Mode pkt_mode, my_mode;
int valid_auth, log_index;
return;
}
- log_index = CLG_LogNTPAccess(&remote_addr->ip_addr, rx_ts);
+ log_index = CLG_LogNTPAccess(&remote_addr->ip_addr, &rx_ts->ts);
/* Don't reply to all requests if the rate is excessive */
if (log_index >= 0 && CLG_LimitNTPResponseRate(log_index)) {
/* ================================================== */
static void
-update_tx_timestamp(struct timespec *tx_ts, struct timespec *new_tx_ts,
+update_tx_timestamp(NTP_Local_Timestamp *tx_ts, NTP_Local_Timestamp *new_tx_ts,
NTP_int64 *local_ntp_tx, NTP_Packet *message)
{
double delay;
- if (UTI_IsZeroTimespec(tx_ts)) {
+ if (UTI_IsZeroTimespec(&tx_ts->ts)) {
DEBUG_LOG(LOGF_NtpCore, "Unexpected TX update");
return;
}
return;
}
- delay = UTI_DiffTimespecsToDouble(new_tx_ts, tx_ts);
+ delay = UTI_DiffTimespecsToDouble(&new_tx_ts->ts, &tx_ts->ts);
if (delay < 0.0 || delay > MAX_TX_DELAY) {
DEBUG_LOG(LOGF_NtpCore, "Unacceptable TX delay %.9f", delay);
/* ================================================== */
void
-NCR_ProcessTxKnown(NTP_Packet *message, struct timespec *tx_ts, double tx_ts_err,
- NCR_Instance inst, NTP_Local_Address *local_addr, int length)
+NCR_ProcessTxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
{
NTP_Mode pkt_mode;
/* Server and passive mode packets are responses to unknown sources */
if (pkt_mode != MODE_CLIENT && pkt_mode != MODE_ACTIVE) {
- NCR_ProcessTxUnknown(message, tx_ts, tx_ts_err, &inst->remote_addr,
- local_addr, length);
+ NCR_ProcessTxUnknown(&inst->remote_addr, local_addr, tx_ts, message, length);
return;
}
/* ================================================== */
void
-NCR_ProcessTxUnknown(NTP_Packet *message, struct timespec *tx_ts, double tx_ts_err,
- NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
+NCR_ProcessTxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
{
/* Nothing to do yet */
DEBUG_LOG(LOGF_NtpCore, "Process TX unknown");
{
double delta;
- if (!UTI_IsZeroTimespec(&inst->local_rx))
- UTI_AdjustTimespec(&inst->local_rx, when, &inst->local_rx, &delta, dfreq, doffset);
- if (!UTI_IsZeroTimespec(&inst->local_tx))
- UTI_AdjustTimespec(&inst->local_tx, when, &inst->local_tx, &delta, dfreq, doffset);
+ if (!UTI_IsZeroTimespec(&inst->local_rx.ts))
+ UTI_AdjustTimespec(&inst->local_rx.ts, when, &inst->local_rx.ts, &delta, dfreq, doffset);
+ if (!UTI_IsZeroTimespec(&inst->local_tx.ts))
+ UTI_AdjustTimespec(&inst->local_tx.ts, when, &inst->local_tx.ts, &delta, dfreq, doffset);
}
/* ================================================== */
{
BroadcastDestination *destination;
NTP_int64 orig_ts;
- struct timespec recv_ts;
+ NTP_Local_Timestamp recv_ts;
destination = ARR_GetElement(broadcasts, (long)arg);
orig_ts.hi = 0;
orig_ts.lo = 0;
- UTI_ZeroTimespec(&recv_ts);
+ UTI_ZeroTimespec(&recv_ts.ts);
+ recv_ts.source = NTP_TS_DAEMON;
+ recv_ts.err = 0.0;
transmit_packet(MODE_BROADCAST, 6 /* FIXME: should this be log2(interval)? */,
NTP_VERSION, 0, 0, &orig_ts, &recv_ts, NULL, NULL,
NTP_SERVER, NTP_PEER
} NTP_Source_Type;
+typedef enum {
+ NTP_TS_DAEMON = 0,
+ NTP_TS_KERNEL,
+ NTP_TS_HARDWARE
+} NTP_Timestamp_Source;
+
+typedef struct {
+ struct timespec ts;
+ double err;
+ NTP_Timestamp_Source source;
+} NTP_Local_Timestamp;
+
/* This is a private data type used for storing the instance record for
each source that we are chiming with */
typedef struct NCR_Instance_Record *NCR_Instance;
/* This routine is called when a new packet arrives off the network,
and it relates to a source we have an ongoing protocol exchange with */
-extern int NCR_ProcessRxKnown(NTP_Packet *message, struct timespec *rx_ts, double rx_ts_err,
- NCR_Instance inst, NTP_Local_Address *local_addr, int length);
+extern int NCR_ProcessRxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length);
/* This routine is called when a new packet arrives off the network,
and we do not recognize its source */
-extern void NCR_ProcessRxUnknown(NTP_Packet *message, struct timespec *rx_ts, double rx_ts_err,
- NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
- int length);
+extern void NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length);
/* This routine is called when a packet is sent to a source we have
an ongoing protocol exchange with */
-extern void NCR_ProcessTxKnown(NTP_Packet *message, struct timespec *tx_ts, double tx_ts_err,
- NCR_Instance inst, NTP_Local_Address *local_addr, int length);
+extern void NCR_ProcessTxKnown(NCR_Instance inst, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length);
/* This routine is called when a packet is sent to a destination we
do not recognize */
-extern void NCR_ProcessTxUnknown(NTP_Packet *message, struct timespec *tx_ts, double tx_ts_err,
- NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
- int length);
+extern void NCR_ProcessTxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length);
/* Slew receive and transmit times in instance records */
extern void NCR_SlewTimes(NCR_Instance inst, struct timespec *when, double dfreq, double doffset);
{
NTP_Remote_Address remote_addr;
NTP_Local_Address local_addr;
+ NTP_Local_Timestamp local_ts;
+ struct timespec sched_ts;
struct cmsghdr *cmsg;
- struct timespec local_ts, sched_ts;
- double local_ts_err;
- SCH_GetLastEventTime(&local_ts, &local_ts_err, NULL);
- sched_ts = local_ts;
+ SCH_GetLastEventTime(&local_ts.ts, &local_ts.err, NULL);
+ local_ts.source = NTP_TS_DAEMON;
+ sched_ts = local_ts.ts;
if (hdr->msg_namelen > sizeof (union sockaddr_in46)) {
DEBUG_LOG(LOGF_NtpIO, "Truncated source address");
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
UTI_TimevalToTimespec(&tv, &ts);
- LCL_CookTime(&ts, &local_ts, &local_ts_err);
+ LCL_CookTime(&ts, &local_ts.ts, &local_ts.err);
+ local_ts.source = NTP_TS_KERNEL;
}
#endif
struct timespec ts;
memcpy(&ts, CMSG_DATA(cmsg), sizeof (ts));
- LCL_CookTime(&ts, &local_ts, &local_ts_err);
+ LCL_CookTime(&ts, &local_ts.ts, &local_ts.err);
+ local_ts.source = NTP_TS_KERNEL;
}
#endif
}
- DEBUG_LOG(LOGF_NtpIO, "Received %d bytes from %s:%d to %s fd=%d delay=%.9f",
+ DEBUG_LOG(LOGF_NtpIO, "Received %d bytes from %s:%d to %s fd=%d tss=%d delay=%.9f",
length, UTI_IPToString(&remote_addr.ip_addr), remote_addr.port,
- UTI_IPToString(&local_addr.ip_addr), local_addr.sock_fd,
- UTI_DiffTimespecsToDouble(&sched_ts, &local_ts));
+ UTI_IPToString(&local_addr.ip_addr), local_addr.sock_fd, local_ts.source,
+ UTI_DiffTimespecsToDouble(&sched_ts, &local_ts.ts));
/* Just ignore the packet if it's not of a recognized length */
if (length < NTP_NORMAL_PACKET_LENGTH || length > sizeof (NTP_Receive_Buffer))
return;
- NSR_ProcessRx((NTP_Packet *)hdr->msg_iov[0].iov_base, &local_ts, local_ts_err,
- &remote_addr, &local_addr, length);
+ NSR_ProcessRx(&remote_addr, &local_addr, &local_ts,
+ (NTP_Packet *)hdr->msg_iov[0].iov_base, length);
}
/* ================================================== */
/* This routine is called by ntp_io when a new packet arrives off the network,
possibly with an authentication tail */
void
-NSR_ProcessRx(NTP_Packet *message, struct timespec *rx_ts, double rx_ts_err,
- NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
+NSR_ProcessRx(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length)
{
SourceRecord *record;
struct SourcePool *pool;
if (found == 2) { /* Must match IP address AND port number */
record = get_record(slot);
- if (!NCR_ProcessRxKnown(message, rx_ts, rx_ts_err, record->data, local_addr, length))
+ if (!NCR_ProcessRxKnown(record->data, local_addr, rx_ts, message, length))
return;
if (record->tentative) {
}
}
} else {
- NCR_ProcessRxUnknown(message, rx_ts, rx_ts_err, remote_addr, local_addr, length);
+ NCR_ProcessRxUnknown(remote_addr, local_addr, rx_ts, message, length);
}
}
/* ================================================== */
void
-NSR_ProcessTx(NTP_Packet *message, struct timespec *tx_ts, double tx_ts_err,
- NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
+NSR_ProcessTx(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+ NTP_Local_Timestamp *tx_ts, NTP_Packet *message, int length)
{
SourceRecord *record;
int slot, found;
if (found == 2) { /* Must match IP address AND port number */
record = get_record(slot);
- NCR_ProcessTxKnown(message, tx_ts, tx_ts_err, record->data, local_addr, length);
+ NCR_ProcessTxKnown(record->data, local_addr, tx_ts, message, length);
} else {
- NCR_ProcessTxUnknown(message, tx_ts, tx_ts_err, remote_addr, local_addr, length);
+ NCR_ProcessTxUnknown(remote_addr, local_addr, tx_ts, message, length);
}
}