1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Kay Sievers
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
31 #include <netinet/ip.h>
32 #include <sys/timerfd.h>
33 #include <sys/timex.h>
34 #include <sys/socket.h>
39 #include "sparse-endian.h"
41 #include "socket-util.h"
43 #include "ratelimit.h"
46 #include "sd-resolve.h"
47 #include "sd-daemon.h"
49 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
52 #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
55 /* expected accuracy of time synchronization; used to adjust the poll interval */
56 #define NTP_ACCURACY_SEC 0.2
59 * "A client MUST NOT under any conditions use a poll interval less
62 #define NTP_POLL_INTERVAL_MIN_SEC 32
63 #define NTP_POLL_INTERVAL_MAX_SEC 2048
66 * Maximum delta in seconds which the system clock is gradually adjusted
67 * (slew) to approach the network time. Deltas larger that this are set by
68 * letting the system time jump. The kernel's limit for adjtime is 0.5s.
70 #define NTP_MAX_ADJUST 0.4
72 /* NTP protocol, packet header */
73 #define NTP_LEAP_PLUSSEC 1
74 #define NTP_LEAP_MINUSSEC 2
75 #define NTP_LEAP_NOTINSYNC 3
76 #define NTP_MODE_CLIENT 3
77 #define NTP_MODE_SERVER 4
78 #define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
79 #define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
80 #define NTP_FIELD_MODE(f) ((f) & 7)
81 #define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
84 * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
85 * in seconds relative to 0h on 1 January 1900."
87 #define OFFSET_1900_1970 2208988800UL
89 #define RETRY_USEC (30*USEC_PER_SEC)
90 #define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
91 #define RATELIMIT_BURST 10
108 struct ntp_ts_short root_delay;
109 struct ntp_ts_short root_dispersion;
111 struct ntp_ts reference_time;
112 struct ntp_ts origin_time;
113 struct ntp_ts recv_time;
114 struct ntp_ts trans_time;
117 typedef struct Manager Manager;
118 typedef struct ServerAddress ServerAddress;
119 typedef struct ServerName ServerName;
121 struct ServerAddress {
122 union sockaddr_union sockaddr;
124 LIST_FIELDS(ServerAddress, addresses);
129 LIST_HEAD(ServerAddress, addresses);
130 LIST_FIELDS(ServerName, names);
137 LIST_HEAD(ServerName, servers);
142 sd_resolve_query *resolve_query;
143 sd_event_source *event_receive;
144 ServerName *current_server_name;
145 ServerAddress *current_server_address;
147 uint64_t packet_count;
149 /* last sent packet */
150 struct timespec trans_time_mon;
151 struct timespec trans_time;
152 usec_t retry_interval;
156 sd_event_source *event_timer;
157 usec_t poll_interval_usec;
165 unsigned int samples_idx;
166 double samples_jitter;
172 /* watch for time changes */
173 sd_event_source *event_clock_watch;
176 /* Retry connections */
177 sd_event_source *event_retry;
179 /* Handle SIGINT/SIGTERM */
180 sd_event_source *sigterm, *sigint;
183 static void manager_free(Manager *m);
184 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
185 #define _cleanup_manager_free_ _cleanup_(manager_freep)
187 static int manager_arm_timer(Manager *m, usec_t next);
188 static int manager_clock_watch_setup(Manager *m);
189 static int manager_connect(Manager *m);
190 static void manager_disconnect(Manager *m);
192 static double ntp_ts_to_d(const struct ntp_ts *ts) {
193 return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
196 static double ts_to_d(const struct timespec *ts) {
197 return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
200 static double tv_to_d(const struct timeval *tv) {
201 return tv->tv_sec + (1.0e-6 * tv->tv_usec);
204 static double square(double d) {
208 static int manager_send_request(Manager *m) {
209 _cleanup_free_ char *pretty = NULL;
210 struct ntp_msg ntpmsg = {
212 * "The client initializes the NTP message header, sends the request
213 * to the server, and strips the time of day from the Transmit
214 * Timestamp field of the reply. For this purpose, all the NTP
215 * header fields are set to 0, except the Mode, VN, and optional
216 * Transmit Timestamp fields."
218 .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
224 assert(m->current_server_name);
225 assert(m->current_server_address);
228 * Set transmit timestamp, remember it; the server will send that back
229 * as the origin timestamp and we have an indication that this is the
230 * matching answer to our request.
232 * The actual value does not matter, We do not care about the correct
233 * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
235 assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
236 assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
237 ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
238 ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
240 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
242 log_error("Failed to format sockaddr: %s", strerror(-r));
246 len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
247 if (len == sizeof(ntpmsg)) {
249 log_debug("Sent NTP request to %s (%s)", pretty, m->current_server_name->string);
251 log_debug("Sending NTP request to %s (%s) failed: %m", pretty, m->current_server_name->string);
252 return manager_connect(m);
255 /* re-arm timer with incresing timeout, in case the packets never arrive back */
256 if (m->retry_interval > 0) {
257 if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
258 m->retry_interval *= 2;
260 m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
262 r = manager_arm_timer(m, m->retry_interval);
264 log_error("Failed to rearm timer: %s", strerror(-r));
271 static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
272 Manager *m = userdata;
276 return manager_send_request(m);
279 static int manager_arm_timer(Manager *m, usec_t next) {
283 assert(m->event_receive);
286 m->event_timer = sd_event_source_unref(m->event_timer);
290 if (m->event_timer) {
291 r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
295 return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
298 return sd_event_add_time(
302 now(CLOCK_MONOTONIC) + next, 0,
306 static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
307 Manager *m = userdata;
312 manager_clock_watch_setup(m);
314 /* skip our own jumps */
321 log_info("System time changed. Resyncing.");
322 m->poll_resync = true;
323 return manager_send_request(m);
326 /* wake up when the system time changes underneath us */
327 static int manager_clock_watch_setup(Manager *m) {
329 struct itimerspec its = {
330 .it_value.tv_sec = TIME_T_MAX
337 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
338 m->clock_watch_fd = safe_close(m->clock_watch_fd);
340 m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
341 if (m->clock_watch_fd < 0) {
342 log_error("Failed to create timerfd: %m");
346 if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
347 log_error("Failed to set up timerfd: %m");
351 r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
353 log_error("Failed to create clock watch event source: %s", strerror(-r));
360 static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
361 struct timex tmx = {};
367 * For small deltas, tell the kernel to gradually adjust the system
368 * clock to the NTP time, larger deltas are just directly set.
370 * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
371 * syncs the system time periodically to the hardware clock.
373 if (fabs(offset) < NTP_MAX_ADJUST) {
374 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
375 tmx.status = STA_PLL;
376 tmx.offset = offset * NSEC_PER_SEC;
377 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
380 log_debug(" adjust (slew): %+.3f sec\n", offset);
382 tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
384 /* ADJ_NANO uses nanoseconds in the microseconds field */
385 tmx.time.tv_sec = (long)offset;
386 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
388 /* the kernel expects -0.3s as {-1, 7000.000.000} */
389 if (tmx.time.tv_usec < 0) {
390 tmx.time.tv_sec -= 1;
391 tmx.time.tv_usec += NSEC_PER_SEC;
395 log_debug(" adjust (jump): %+.3f sec\n", offset);
400 tmx.status |= STA_INS;
403 tmx.status |= STA_DEL;
407 r = clock_adjtime(CLOCK_REALTIME, &tmx);
411 m->drift_ppm = tmx.freq / 65536;
413 log_debug(" status : %04i %s\n"
414 " time now : %li.%03lli\n"
416 " offset : %+.3f sec\n"
417 " freq offset : %+li (%i ppm)\n",
418 tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
419 tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
421 (double)tmx.offset / NSEC_PER_SEC,
422 tmx.freq, m->drift_ppm);
427 static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
428 unsigned int i, idx_cur, idx_new, idx_min;
436 /* ignore initial sample */
437 if (m->packet_count == 1)
440 /* store the current data in our samples array */
441 idx_cur = m->samples_idx;
442 idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
443 m->samples_idx = idx_new;
444 m->samples[idx_new].offset = offset;
445 m->samples[idx_new].delay = delay;
447 /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
448 jitter = m->samples_jitter;
449 for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
450 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
454 for (i = 0; i < ELEMENTSOF(m->samples); i++)
455 j += square(m->samples[i].offset - m->samples[idx_min].offset);
456 m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
458 /* ignore samples when resyncing */
462 /* always accept offset if we are farther off than the round-trip delay */
463 if (fabs(offset) > delay)
466 /* we need a few samples before looking at them */
467 if (m->packet_count < 4)
470 /* do not accept anything worse than the maximum possible error of the best sample */
471 if (fabs(offset) > m->samples[idx_min].delay)
474 /* compare the difference between the current offset to the previous offset and jitter */
475 return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
478 static void manager_adjust_poll(Manager *m, double offset, bool spike) {
481 if (m->poll_resync) {
482 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
483 m->poll_resync = false;
487 /* set to minimal poll interval */
488 if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
489 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
493 /* increase polling interval */
494 if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
495 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
496 m->poll_interval_usec *= 2;
500 /* decrease polling interval */
501 if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
502 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
503 m->poll_interval_usec /= 2;
508 static bool sockaddr_equal(union sockaddr_union *a, union sockaddr_union *b) {
512 if (a->sa.sa_family != b->sa.sa_family)
515 if (a->sa.sa_family == AF_INET)
516 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
518 if (a->sa.sa_family == AF_INET6)
519 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
524 static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
525 _cleanup_free_ char *pretty = NULL;
526 Manager *m = userdata;
527 struct ntp_msg ntpmsg;
531 .iov_len = sizeof(ntpmsg),
534 struct cmsghdr cmsghdr;
535 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
537 union sockaddr_union server_addr;
538 struct msghdr msghdr = {
541 .msg_control = &control,
542 .msg_controllen = sizeof(control),
543 .msg_name = &server_addr,
544 .msg_namelen = sizeof(server_addr),
546 struct cmsghdr *cmsg;
547 struct timespec now_ts;
548 struct timeval *recv_time;
550 double origin, receive, trans, dest;
551 double delay, offset;
559 if (revents & (EPOLLHUP|EPOLLERR)) {
560 log_warning("Server connection returned error.");
561 return manager_connect(m);
564 len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
569 log_warning("Error receiving message. Disconnecting.");
570 return manager_connect(m);
573 if (iov.iov_len < sizeof(struct ntp_msg)) {
574 log_warning("Invalid response from server. Disconnecting.");
575 return manager_connect(m);
578 if (!m->current_server_name ||
579 !m->current_server_address ||
580 !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
581 log_debug("Response from unknown server.");
586 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
587 if (cmsg->cmsg_level != SOL_SOCKET)
590 switch (cmsg->cmsg_type) {
592 recv_time = (struct timeval *) CMSG_DATA(cmsg);
597 log_error("Invalid packet timestamp.");
602 log_debug("Unexpected reply. Ignoring.");
606 /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
607 if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
608 be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
609 log_debug("Invalid reply; not our transmit time. Ignoring.");
613 if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
614 log_debug("Server is not synchronized. Disconnecting.");
615 return manager_connect(m);
618 if (NTP_FIELD_VERSION(ntpmsg.field) != 4 && NTP_FIELD_VERSION(ntpmsg.field) != 3) {
619 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
620 return manager_connect(m);
623 if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
624 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
625 return manager_connect(m);
630 m->retry_interval = 0;
632 /* announce leap seconds */
633 if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
635 else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
641 * "Timestamp Name ID When Generated
642 * ------------------------------------------------------------
643 * Originate Timestamp T1 time request sent by client
644 * Receive Timestamp T2 time request received by server
645 * Transmit Timestamp T3 time reply sent by server
646 * Destination Timestamp T4 time reply received by client
648 * The round-trip delay, d, and system clock offset, t, are defined as:
649 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
651 assert_se(clock_gettime(CLOCK_MONOTONIC, &now_ts) >= 0);
652 origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
653 receive = ntp_ts_to_d(&ntpmsg.recv_time);
654 trans = ntp_ts_to_d(&ntpmsg.trans_time);
655 dest = tv_to_d(recv_time) + OFFSET_1900_1970;
657 offset = ((receive - origin) + (trans - dest)) / 2;
658 delay = (dest - origin) - (trans - receive);
660 spike = manager_sample_spike_detection(m, offset, delay);
662 manager_adjust_poll(m, offset, spike);
664 log_debug("NTP response:\n"
669 " precision : %.6f sec (%d)\n"
670 " reference : %.4s\n"
675 " offset : %+.3f sec\n"
676 " delay : %+.3f sec\n"
677 " packet count : %"PRIu64"\n"
679 " poll interval: %llu\n",
680 NTP_FIELD_LEAP(ntpmsg.field),
681 NTP_FIELD_VERSION(ntpmsg.field),
682 NTP_FIELD_MODE(ntpmsg.field),
684 exp2(ntpmsg.precision), ntpmsg.precision,
685 ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
686 origin - OFFSET_1900_1970,
687 receive - OFFSET_1900_1970,
688 trans - OFFSET_1900_1970,
689 dest - OFFSET_1900_1970,
692 m->samples_jitter, spike ? " spike" : "",
693 m->poll_interval_usec / USEC_PER_SEC);
696 r = manager_adjust_clock(m, offset, leap_sec);
698 log_error("Failed to call clock_adjtime(): %m");
701 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
703 log_error("Failed to format socket address: %s", strerror(-r));
707 log_info("%s (%s): interval/delta/delay/jitter/drift %llus/%+.3fs/%.3fs/%.3fs/%+ippm%s",
708 pretty, m->current_server_name->string, m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
709 spike ? " (ignored)" : "");
711 r = manager_arm_timer(m, m->poll_interval_usec);
713 log_error("Failed to rearm timer: %s", strerror(-r));
720 static int manager_listen_setup(Manager *m) {
721 union sockaddr_union addr = {};
722 static const int tos = IPTOS_LOWDELAY;
723 static const int on = 1;
728 assert(m->server_socket < 0);
729 assert(!m->event_receive);
730 assert(m->current_server_address);
732 addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
734 m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
735 if (m->server_socket < 0)
738 r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
742 r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
746 setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
748 return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
751 static int manager_begin(Manager *m) {
752 _cleanup_free_ char *pretty = NULL;
756 assert_return(m->current_server_name, -EHOSTUNREACH);
757 assert_return(m->current_server_address, -EHOSTUNREACH);
759 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
761 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
763 log_warning("Failed to decode address of %s: %s", m->current_server_name->string, strerror(-r));
767 log_debug("Connecting to NTP server %s (%s).", pretty, m->current_server_name->string);
768 sd_notifyf(false, "STATUS=Using Time Server %s (%s)", pretty, m->current_server_name->string);
770 r = manager_listen_setup(m);
772 log_warning("Failed to setup connection socket: %s", strerror(-r));
776 r = manager_clock_watch_setup(m);
780 return manager_send_request(m);
783 static void server_name_flush_addresses(ServerName *n) {
788 while ((a = n->addresses)) {
789 LIST_REMOVE(addresses, n->addresses, a);
794 static void manager_flush_names(Manager *m) {
799 while ((n = m->servers)) {
800 LIST_REMOVE(names, m->servers, n);
802 server_name_flush_addresses(n);
807 static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
808 Manager *m = userdata;
809 ServerAddress *a, *last = NULL;
813 assert(m->current_server_name);
815 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
818 log_error("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
821 return manager_connect(m);
824 server_name_flush_addresses(m->current_server_name);
826 for (; ai; ai = ai->ai_next) {
827 _cleanup_free_ char *pretty = NULL;
830 assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
831 assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
833 if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
834 log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
838 a = new0(ServerAddress, 1);
842 memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
843 a->socklen = ai->ai_addrlen;
845 LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
848 sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
849 log_debug("Found address %s for %s.", pretty, m->current_server_name->string);
852 if (!m->current_server_name->addresses) {
853 log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
856 return manager_connect(m);
859 m->current_server_address = m->current_server_name->addresses;
861 return manager_begin(m);
864 static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
865 Manager *m = userdata;
869 return manager_connect(m);
872 static int manager_connect(Manager *m) {
874 struct addrinfo hints = {
875 .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
876 .ai_socktype = SOCK_DGRAM,
882 manager_disconnect(m);
884 m->event_retry = sd_event_source_unref(m->event_retry);
885 if (!ratelimit_test(&m->ratelimit)) {
886 log_debug("Slowing down attempts to contact servers.");
888 r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
890 log_error("Failed to create retry timer: %s", strerror(-r));
897 /* If we already are operating on some address, switch to the
899 if (m->current_server_address && m->current_server_address->addresses_next)
900 m->current_server_address = m->current_server_address->addresses_next;
902 /* Hmm, we are through all addresses, let's look for the next host instead */
903 m->current_server_address = NULL;
905 if (m->current_server_name && m->current_server_name->names_next)
906 m->current_server_name = m->current_server_name->names_next;
909 m->current_server_name = NULL;
910 log_debug("No server found.");
914 m->current_server_name = m->servers;
917 /* Tell the resolver to reread /etc/resolv.conf, in
918 * case it changed. */
921 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
923 log_error("Failed to create resolver: %s", strerror(-r));
930 r = manager_begin(m);
937 static int manager_add_server(Manager *m, const char *server) {
943 n = new0(ServerName, 1);
947 n->string = strdup(server);
953 LIST_PREPEND(names, m->servers, n);
957 static void manager_disconnect(Manager *m) {
960 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
962 m->event_timer = sd_event_source_unref(m->event_timer);
964 m->event_receive = sd_event_source_unref(m->event_receive);
965 m->server_socket = safe_close(m->server_socket);
967 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
968 m->clock_watch_fd = safe_close(m->clock_watch_fd);
971 static int manager_new(Manager **ret) {
972 _cleanup_manager_free_ Manager *m = NULL;
975 m = new0(Manager, 1);
979 m->server_socket = m->clock_watch_fd = -1;
981 RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
983 r = sd_event_default(&m->event);
987 sd_event_add_signal(m->event, &m->sigterm, SIGTERM, NULL, NULL);
988 sd_event_add_signal(m->event, &m->sigint, SIGINT, NULL, NULL);
990 r = sd_resolve_default(&m->resolve);
994 r = sd_resolve_attach_event(m->resolve, m->event, 0);
998 r = manager_clock_watch_setup(m);
1008 static void manager_free(Manager *m) {
1012 manager_disconnect(m);
1013 manager_flush_names(m);
1015 sd_event_source_unref(m->sigint);
1016 sd_event_source_unref(m->sigterm);
1018 sd_event_source_unref(m->event_retry);
1020 sd_resolve_unref(m->resolve);
1021 sd_event_unref(m->event);
1026 int main(int argc, char *argv[]) {
1027 _cleanup_manager_free_ Manager *m = NULL;
1031 log_set_target(LOG_TARGET_AUTO);
1032 log_parse_environment();
1035 assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
1037 r = manager_new(&m);
1039 log_error("Failed to allocate manager: %s", strerror(-r));
1043 sd_notify(false, "READY=1");
1045 FOREACH_STRING(x, "time1.google.com", "time2.google.com", "time3.google.com", "time4.google.com", "0.fedora.pool.ntp.org") {
1046 r = manager_add_server(m, x);
1048 log_error("Failed to add server %s: %s", x, strerror(-r));
1053 r = manager_connect(m);
1057 r = sd_event_loop(m->event);
1059 log_error("Failed to run event loop: %s", strerror(-r));
1063 sd_event_get_exit_code(m->event, &r);
1066 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;