chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
sd-dhcp: avoid checksum calculation if possible
[elogind.git]
/
src
/
timedate
/
timedate-sntp.c
diff --git
a/src/timedate/timedate-sntp.c
b/src/timedate/timedate-sntp.c
index fff02c79e5b3f241c050b04d19e9251585756cf9..e47a0865673185143efb5f3fab4c8abfab7c29cc 100644
(file)
--- a/
src/timedate/timedate-sntp.c
+++ b/
src/timedate/timedate-sntp.c
@@
-118,6
+118,8
@@
struct ntp_msg {
} _packed_;
struct SNTPContext {
} _packed_;
struct SNTPContext {
+ void (*report)(usec_t poll, double offset, double delay, double jitter, bool spike);
+
/* peer */
sd_event_source *event_receive;
char *server;
/* peer */
sd_event_source *event_receive;
char *server;
@@
-203,7
+205,7
@@
static int sntp_send_request(SNTPContext *sntp) {
* matching answer to our request.
*
* The actual value does not matter, We do not care about the correct
* matching answer to our request.
*
* The actual value does not matter, We do not care about the correct
- * NTP UINT_MAX fraction
,
we just pass the plain nanosecond value.
+ * NTP UINT_MAX fraction
;
we just pass the plain nanosecond value.
*/
clock_gettime(CLOCK_MONOTONIC, &sntp->trans_time_mon);
clock_gettime(CLOCK_REALTIME, &sntp->trans_time);
*/
clock_gettime(CLOCK_MONOTONIC, &sntp->trans_time_mon);
clock_gettime(CLOCK_REALTIME, &sntp->trans_time);
@@
-218,7
+220,7
@@
static int sntp_send_request(SNTPContext *sntp) {
sntp->pending = true;
log_debug("Sent NTP request to: %s", sntp->server);
} else
sntp->pending = true;
log_debug("Sent NTP request to: %s", sntp->server);
} else
- log_
info
("Sending NTP request to %s failed: %m", sntp->server);
+ log_
debug
("Sending NTP request to %s failed: %m", sntp->server);
/* re-arm timer with incresing timeout, in case the packets never arrive back */
if (sntp->retry_interval > 0) {
/* re-arm timer with incresing timeout, in case the packets never arrive back */
if (sntp->retry_interval > 0) {
@@
-263,7
+265,12
@@
static int sntp_arm_timer(SNTPContext *sntp, usec_t next) {
}
e = sd_event_source_get_event(sntp->event_receive);
}
e = sd_event_source_get_event(sntp->event_receive);
- r = sd_event_add_monotonic(e, &sntp->event_timer, now(CLOCK_MONOTONIC) + next, 0, sntp_timer, sntp);
+ r = sd_event_add_time(
+ e,
+ &sntp->event_timer,
+ CLOCK_MONOTONIC,
+ now(CLOCK_MONOTONIC) + next, 0,
+ sntp_timer, sntp);
if (r < 0)
return r;
if (r < 0)
return r;
@@
-286,7
+293,7
@@
static int sntp_clock_watch(sd_event_source *source, int fd, uint32_t revents, v
}
/* resync */
}
/* resync */
- log_info("System time changed
, r
esyncing.");
+ log_info("System time changed
. R
esyncing.");
sntp->poll_resync = true;
sntp_send_request(sntp);
sntp->poll_resync = true;
sntp_send_request(sntp);
@@
-345,14
+352,12
@@
static int sntp_adjust_clock(SNTPContext *sntp, double offset, int leap_sec) {
* syncs the system time periodically to the hardware clock.
*/
if (offset < NTP_MAX_ADJUST && offset > -NTP_MAX_ADJUST) {
* syncs the system time periodically to the hardware clock.
*/
if (offset < NTP_MAX_ADJUST && offset > -NTP_MAX_ADJUST) {
- int constant;
-
- constant = log2i(sntp->poll_interval_usec / USEC_PER_SEC) - 6;
-
- tmx.modes |= ADJ_STATUS | ADJ_OFFSET | ADJ_TIMECONST;
+ tmx.modes |= ADJ_STATUS | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
tmx.status = STA_PLL;
tmx.offset = offset * 1000 * 1000;
tmx.status = STA_PLL;
tmx.offset = offset * 1000 * 1000;
- tmx.constant = constant;
+ tmx.constant = log2i(sntp->poll_interval_usec / USEC_PER_SEC) - 6;
+ tmx.maxerror = 0;
+ tmx.esterror = 0;
log_debug(" adjust (slew): %+f sec\n", (double)tmx.offset / USEC_PER_SEC);
} else {
tmx.modes = ADJ_SETOFFSET;
log_debug(" adjust (slew): %+f sec\n", (double)tmx.offset / USEC_PER_SEC);
} else {
tmx.modes = ADJ_SETOFFSET;
@@
-404,18
+409,6
@@
static bool sntp_sample_spike_detection(SNTPContext *sntp, double offset, double
sntp->packet_count++;
jitter = sntp->samples_jitter;
sntp->packet_count++;
jitter = sntp->samples_jitter;
- /* ignore samples when resyncing */
- if (sntp->poll_resync)
- return false;
-
- /* we need a few samples before we calculate anything */
- if (sntp->packet_count < 3)
- return false;
-
- /* always accept sample if we are farther off than the round trip delay */
- if (fabs(offset) > delay)
- return false;
-
/* calculate new jitter value from the RMS differences relative to the lowest delay sample */
for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(sntp->samples); i++)
if (sntp->samples[i].delay > 0 && sntp->samples[i].delay < sntp->samples[idx_min].delay)
/* calculate new jitter value from the RMS differences relative to the lowest delay sample */
for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(sntp->samples); i++)
if (sntp->samples[i].delay > 0 && sntp->samples[i].delay < sntp->samples[idx_min].delay)
@@
-426,8
+419,20
@@
static bool sntp_sample_spike_detection(SNTPContext *sntp, double offset, double
j += square(sntp->samples[i].offset - sntp->samples[idx_min].offset);
sntp->samples_jitter = sqrt(j / (ELEMENTSOF(sntp->samples) - 1));
j += square(sntp->samples[i].offset - sntp->samples[idx_min].offset);
sntp->samples_jitter = sqrt(j / (ELEMENTSOF(sntp->samples) - 1));
+ /* ignore samples when resyncing */
+ if (sntp->poll_resync)
+ return false;
+
+ /* always accept offset if we are farther off than the round-trip delay */
+ if (fabs(offset) > delay)
+ return false;
+
+ /* we need a few samples before looking at them */
+ if (sntp->packet_count < 4)
+ return false;
+
/* do not accept anything worse than the maximum possible error of the best sample */
/* do not accept anything worse than the maximum possible error of the best sample */
- if (abs(offset) > sntp->samples[idx_min].delay)
+ if (
f
abs(offset) > sntp->samples[idx_min].delay)
return true;
/* compare the difference between the current offset to the previous offset and jitter */
return true;
/* compare the difference between the current offset to the previous offset and jitter */
@@
-442,7
+447,7
@@
static void sntp_adjust_poll(SNTPContext *sntp, double offset, bool spike) {
}
/* set to minimal poll interval */
}
/* set to minimal poll interval */
- if (fabs(offset) > NTP_ACCURACY_SEC) {
+ if (
!spike &&
fabs(offset) > NTP_ACCURACY_SEC) {
sntp->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
return;
}
sntp->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
return;
}
@@
-494,24
+499,24
@@
static int sntp_receive_response(sd_event_source *source, int fd, uint32_t reven
int r;
if (revents & (EPOLLHUP|EPOLLERR)) {
int r;
if (revents & (EPOLLHUP|EPOLLERR)) {
- log_debug("Server connection returned error
, c
losing.");
+ log_debug("Server connection returned error
. C
losing.");
sntp_server_disconnect(sntp);
return -ENOTCONN;
}
len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
if (len < 0) {
sntp_server_disconnect(sntp);
return -ENOTCONN;
}
len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
if (len < 0) {
- log_debug("Error receiving message
, disconnecting
");
+ log_debug("Error receiving message
. Disconnecting.
");
return -EINVAL;
}
if (iov.iov_len < sizeof(struct ntp_msg)) {
return -EINVAL;
}
if (iov.iov_len < sizeof(struct ntp_msg)) {
- log_debug("Invalid response from server
, disconnecting
");
+ log_debug("Invalid response from server
. Disconnecting.
");
return -EINVAL;
}
if (sntp->server_addr.sin_addr.s_addr != server_addr.sin_addr.s_addr) {
return -EINVAL;
}
if (sntp->server_addr.sin_addr.s_addr != server_addr.sin_addr.s_addr) {
- log_debug("Response from unknown server
, disconnecting
");
+ log_debug("Response from unknown server
. Disconnecting.
");
return -EINVAL;
}
return -EINVAL;
}
@@
-527,35
+532,35
@@
static int sntp_receive_response(sd_event_source *source, int fd, uint32_t reven
}
}
if (!recv_time) {
}
}
if (!recv_time) {
- log_debug("Invalid packet timestamp
, disconnecting
");
+ log_debug("Invalid packet timestamp
. Disconnecting.
");
return -EINVAL;
}
ntpmsg = iov.iov_base;
if (!sntp->pending) {
return -EINVAL;
}
ntpmsg = iov.iov_base;
if (!sntp->pending) {
- log_debug("Unexpected reply
, ignoring
");
+ log_debug("Unexpected reply
. Ignoring.
");
return 0;
}
/* check our "time cookie" (we just stored nanoseconds in the fraction field) */
return 0;
}
/* check our "time cookie" (we just stored nanoseconds in the fraction field) */
- if (be32toh(ntpmsg->origin_time.sec) != sntp->trans_time.tv_sec + OFFSET_1900_1970||
+ if (be32toh(ntpmsg->origin_time.sec) != sntp->trans_time.tv_sec + OFFSET_1900_1970
||
be32toh(ntpmsg->origin_time.frac) != sntp->trans_time.tv_nsec) {
be32toh(ntpmsg->origin_time.frac) != sntp->trans_time.tv_nsec) {
- log_debug("Invalid reply
, not our transmit time, ignoring
");
+ log_debug("Invalid reply
; not our transmit time. Ignoring.
");
return 0;
}
if (NTP_FIELD_LEAP(ntpmsg->field) == NTP_LEAP_NOTINSYNC) {
return 0;
}
if (NTP_FIELD_LEAP(ntpmsg->field) == NTP_LEAP_NOTINSYNC) {
- log_debug("Server is not synchronized
, disconnecting
");
+ log_debug("Server is not synchronized
. Disconnecting.
");
return -EINVAL;
}
if (NTP_FIELD_VERSION(ntpmsg->field) != 4) {
return -EINVAL;
}
if (NTP_FIELD_VERSION(ntpmsg->field) != 4) {
- log_debug("Response NTPv%d
, disconnecting
", NTP_FIELD_VERSION(ntpmsg->field));
+ log_debug("Response NTPv%d
. Disconnecting.
", NTP_FIELD_VERSION(ntpmsg->field));
return -EINVAL;
}
if (NTP_FIELD_MODE(ntpmsg->field) != NTP_MODE_SERVER) {
return -EINVAL;
}
if (NTP_FIELD_MODE(ntpmsg->field) != NTP_MODE_SERVER) {
- log_debug("Unsupported mode %d
, disconnecting
", NTP_FIELD_MODE(ntpmsg->field));
+ log_debug("Unsupported mode %d
. Disconnecting.
", NTP_FIELD_MODE(ntpmsg->field));
return -EINVAL;
}
return -EINVAL;
}
@@
-579,7
+584,7
@@
static int sntp_receive_response(sd_event_source *source, int fd, uint32_t reven
* Transmit Timestamp T3 time reply sent by server
* Destination Timestamp T4 time reply received by client
*
* Transmit Timestamp T3 time reply sent by server
* Destination Timestamp T4 time reply received by client
*
- * The round
trip delay d and system clock offset t
are defined as:
+ * The round
-trip delay, d, and system clock offset, t,
are defined as:
* d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
*/
clock_gettime(CLOCK_MONOTONIC, &now_ts);
* d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
*/
clock_gettime(CLOCK_MONOTONIC, &now_ts);
@@
-626,9
+631,8
@@
static int sntp_receive_response(sd_event_source *source, int fd, uint32_t reven
sntp->samples_jitter, spike ? " spike" : "",
sntp->poll_interval_usec / USEC_PER_SEC);
sntp->samples_jitter, spike ? " spike" : "",
sntp->poll_interval_usec / USEC_PER_SEC);
- log_info("%4llu %+10f %10f %10f%s",
- sntp->poll_interval_usec / USEC_PER_SEC, offset, delay,
- sntp->samples_jitter, spike ? " spike" : "");
+ if (sntp->report)
+ sntp->report(sntp->poll_interval_usec, offset, delay, sntp->samples_jitter, spike);
if (!spike) {
r = sntp_adjust_clock(sntp, offset, leap_sec);
if (!spike) {
r = sntp_adjust_clock(sntp, offset, leap_sec);
@@
-723,6
+727,10
@@
static int sntp_listen_setup(SNTPContext *sntp, sd_event *e) {
return 0;
}
return 0;
}
+void sntp_report_register(SNTPContext *sntp, void (*report)(usec_t poll_usec, double offset, double delay, double jitter, bool spike)) {
+ sntp->report = report;
+}
+
int sntp_new(SNTPContext **sntp, sd_event *e) {
_cleanup_free_ SNTPContext *c;
int r;
int sntp_new(SNTPContext **sntp, sd_event *e) {
_cleanup_free_ SNTPContext *c;
int r;