- return r;
-
- m->drift_ppm = tmx.freq / 65536;
-
- log_debug(" status : %04i %s\n"
- " time now : %li.%03lli\n"
- " constant : %li\n"
- " offset : %+.3f sec\n"
- " freq offset : %+li (%i ppm)\n",
- tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
- tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
- tmx.constant,
- (double)tmx.offset / NSEC_PER_SEC,
- tmx.freq, m->drift_ppm);
-
- return 0;
-}
-
-static bool sntp_sample_spike_detection(Manager *m, double offset, double delay) {
- unsigned int i, idx_cur, idx_new, idx_min;
- double jitter;
- double j;
-
- m->packet_count++;
-
- /* ignore initial sample */
- if (m->packet_count == 1)
- return false;
-
- /* store the current data in our samples array */
- idx_cur = m->samples_idx;
- idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
- m->samples_idx = idx_new;
- m->samples[idx_new].offset = offset;
- m->samples[idx_new].delay = delay;
-
- /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
- jitter = m->samples_jitter;
- for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
- if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
- idx_min = i;
-
- j = 0;
- for (i = 0; i < ELEMENTSOF(m->samples); i++)
- j += square(m->samples[i].offset - m->samples[idx_min].offset);
- m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
-
- /* ignore samples when resyncing */
- if (m->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 (m->packet_count < 4)
- return false;
-
- /* do not accept anything worse than the maximum possible error of the best sample */
- if (fabs(offset) > m->samples[idx_min].delay)
- return true;
-
- /* compare the difference between the current offset to the previous offset and jitter */
- return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
-}
-
-static void sntp_adjust_poll(Manager *m, double offset, bool spike) {
- if (m->poll_resync) {
- m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
- m->poll_resync = false;
- return;
- }
-
- /* set to minimal poll interval */
- if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
- m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
- return;
- }
-
- /* increase polling interval */
- if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
- if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
- m->poll_interval_usec *= 2;
- return;
- }
-
- /* decrease polling interval */
- if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
- if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
- m->poll_interval_usec /= 2;
- return;
- }
-}
-
-static int sntp_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
- Manager *m = userdata;
- unsigned char buf[sizeof(struct ntp_msg)];
- struct iovec iov = {
- .iov_base = buf,
- .iov_len = sizeof(buf),
- };
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
- } control;
- union sockaddr_union server_addr;
- struct msghdr msghdr = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- .msg_name = &server_addr,
- .msg_namelen = sizeof(server_addr),
- };
- struct cmsghdr *cmsg;
- struct timespec now_ts;
- struct timeval *recv_time;
- ssize_t len;
- struct ntp_msg *ntpmsg;
- double origin, receive, trans, dest;
- double delay, offset;
- bool spike;
- int leap_sec;
- int r;
-
- if (revents & (EPOLLHUP|EPOLLERR)) {
- log_debug("Server connection returned error. Closing.");
- sntp_server_disconnect(m);
- return -ENOTCONN;
- }
-
- len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
- if (len < 0) {
- log_debug("Error receiving message. Disconnecting.");
- return -EINVAL;
- }
-
- if (iov.iov_len < sizeof(struct ntp_msg)) {
- log_debug("Invalid response from server. Disconnecting.");
- return -EINVAL;
- }
-
- if (m->server_addr.in.sin_addr.s_addr != server_addr.in.sin_addr.s_addr) {
- log_debug("Response from unknown server. Disconnecting.");
- return -EINVAL;
- }