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>
38 #include "sparse-endian.h"
40 #include "socket-util.h"
42 #include "ratelimit.h"
44 #include "sd-resolve.h"
45 #include "sd-daemon.h"
47 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
50 #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
53 /* expected accuracy of time synchronization; used to adjust the poll interval */
54 #define NTP_ACCURACY_SEC 0.2
57 * "A client MUST NOT under any conditions use a poll interval less
60 #define NTP_POLL_INTERVAL_MIN_SEC 32
61 #define NTP_POLL_INTERVAL_MAX_SEC 2048
64 * Maximum delta in seconds which the system clock is gradually adjusted
65 * (slew) to approach the network time. Deltas larger that this are set by
66 * letting the system time jump. The kernel's limit for adjtime is 0.5s.
68 #define NTP_MAX_ADJUST 0.4
70 /* NTP protocol, packet header */
71 #define NTP_LEAP_PLUSSEC 1
72 #define NTP_LEAP_MINUSSEC 2
73 #define NTP_LEAP_NOTINSYNC 3
74 #define NTP_MODE_CLIENT 3
75 #define NTP_MODE_SERVER 4
76 #define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
77 #define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
78 #define NTP_FIELD_MODE(f) ((f) & 7)
79 #define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
82 * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
83 * in seconds relative to 0h on 1 January 1900."
85 #define OFFSET_1900_1970 2208988800UL
87 #define RETRY_USEC (30*USEC_PER_SEC)
88 #define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
89 #define RATELIMIT_BURST 10
106 struct ntp_ts_short root_delay;
107 struct ntp_ts_short root_dispersion;
109 struct ntp_ts reference_time;
110 struct ntp_ts origin_time;
111 struct ntp_ts recv_time;
112 struct ntp_ts trans_time;
115 typedef struct Manager Manager;
116 typedef struct ServerAddress ServerAddress;
117 typedef struct ServerName ServerName;
119 struct ServerAddress {
120 union sockaddr_union sockaddr;
122 LIST_FIELDS(ServerAddress, addresses);
127 LIST_HEAD(ServerAddress, addresses);
128 LIST_FIELDS(ServerName, names);
135 LIST_HEAD(ServerName, servers);
140 sd_resolve_query *resolve_query;
141 sd_event_source *event_receive;
142 ServerName *current_server_name;
143 ServerAddress *current_server_address;
145 uint64_t packet_count;
147 /* last sent packet */
148 struct timespec trans_time_mon;
149 struct timespec trans_time;
150 usec_t retry_interval;
154 sd_event_source *event_timer;
155 usec_t poll_interval_usec;
163 unsigned int samples_idx;
164 double samples_jitter;
170 /* watch for time changes */
171 sd_event_source *event_clock_watch;
174 /* Retry connections */
175 sd_event_source *event_retry;
177 /* Handle SIGINT/SIGTERM */
178 sd_event_source *sigterm, *sigint;
181 static void manager_free(Manager *m);
182 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
183 #define _cleanup_manager_free_ _cleanup_(manager_freep)
185 static int manager_arm_timer(Manager *m, usec_t next);
186 static int manager_clock_watch_setup(Manager *m);
187 static int manager_connect(Manager *m);
188 static void manager_disconnect(Manager *m);
190 static double ntp_ts_to_d(const struct ntp_ts *ts) {
191 return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
194 static double ts_to_d(const struct timespec *ts) {
195 return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
198 static double tv_to_d(const struct timeval *tv) {
199 return tv->tv_sec + (1.0e-6 * tv->tv_usec);
202 static double square(double d) {
206 static int manager_send_request(Manager *m) {
207 _cleanup_free_ char *pretty = NULL;
208 struct ntp_msg ntpmsg = {
210 * "The client initializes the NTP message header, sends the request
211 * to the server, and strips the time of day from the Transmit
212 * Timestamp field of the reply. For this purpose, all the NTP
213 * header fields are set to 0, except the Mode, VN, and optional
214 * Transmit Timestamp fields."
216 .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
222 assert(m->current_server_name);
223 assert(m->current_server_address);
226 * Set transmit timestamp, remember it; the server will send that back
227 * as the origin timestamp and we have an indication that this is the
228 * matching answer to our request.
230 * The actual value does not matter, We do not care about the correct
231 * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
233 assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
234 assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
235 ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
236 ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
238 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
240 log_error("Failed to format sockaddr: %s", strerror(-r));
244 len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
245 if (len == sizeof(ntpmsg)) {
247 log_debug("Sent NTP request to %s (%s)", pretty, m->current_server_name->string);
249 log_debug("Sending NTP request to %s (%s) failed: %m", pretty, m->current_server_name->string);
250 return manager_connect(m);
253 /* re-arm timer with incresing timeout, in case the packets never arrive back */
254 if (m->retry_interval > 0) {
255 if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
256 m->retry_interval *= 2;
258 m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
260 r = manager_arm_timer(m, m->retry_interval);
262 log_error("Failed to rearm timer: %s", strerror(-r));
269 static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
270 Manager *m = userdata;
274 return manager_send_request(m);
277 static int manager_arm_timer(Manager *m, usec_t next) {
281 assert(m->event_receive);
284 m->event_timer = sd_event_source_unref(m->event_timer);
288 if (m->event_timer) {
289 r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
293 return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
296 return sd_event_add_time(
300 now(CLOCK_MONOTONIC) + next, 0,
304 static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
305 Manager *m = userdata;
310 manager_clock_watch_setup(m);
312 /* skip our own jumps */
319 log_info("System time changed. Resyncing.");
320 m->poll_resync = true;
321 return manager_send_request(m);
324 /* wake up when the system time changes underneath us */
325 static int manager_clock_watch_setup(Manager *m) {
327 struct itimerspec its = {
328 .it_value.tv_sec = TIME_T_MAX
335 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
336 m->clock_watch_fd = safe_close(m->clock_watch_fd);
338 m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
339 if (m->clock_watch_fd < 0) {
340 log_error("Failed to create timerfd: %m");
344 if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
345 log_error("Failed to set up timerfd: %m");
349 r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
351 log_error("Failed to create clock watch event source: %s", strerror(-r));
358 static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
359 struct timex tmx = {};
365 * For small deltas, tell the kernel to gradually adjust the system
366 * clock to the NTP time, larger deltas are just directly set.
368 * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
369 * syncs the system time periodically to the hardware clock.
371 if (fabs(offset) < NTP_MAX_ADJUST) {
372 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
373 tmx.status = STA_PLL;
374 tmx.offset = offset * NSEC_PER_SEC;
375 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
378 log_debug(" adjust (slew): %+.3f sec\n", offset);
380 tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
382 /* ADJ_NANO uses nanoseconds in the microseconds field */
383 tmx.time.tv_sec = (long)offset;
384 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
386 /* the kernel expects -0.3s as {-1, 7000.000.000} */
387 if (tmx.time.tv_usec < 0) {
388 tmx.time.tv_sec -= 1;
389 tmx.time.tv_usec += NSEC_PER_SEC;
393 log_debug(" adjust (jump): %+.3f sec\n", offset);
398 tmx.status |= STA_INS;
401 tmx.status |= STA_DEL;
405 r = clock_adjtime(CLOCK_REALTIME, &tmx);
409 m->drift_ppm = tmx.freq / 65536;
411 log_debug(" status : %04i %s\n"
412 " time now : %li.%03lli\n"
414 " offset : %+.3f sec\n"
415 " freq offset : %+li (%i ppm)\n",
416 tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
417 tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
419 (double)tmx.offset / NSEC_PER_SEC,
420 tmx.freq, m->drift_ppm);
425 static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
426 unsigned int i, idx_cur, idx_new, idx_min;
434 /* ignore initial sample */
435 if (m->packet_count == 1)
438 /* store the current data in our samples array */
439 idx_cur = m->samples_idx;
440 idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
441 m->samples_idx = idx_new;
442 m->samples[idx_new].offset = offset;
443 m->samples[idx_new].delay = delay;
445 /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
446 jitter = m->samples_jitter;
447 for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
448 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
452 for (i = 0; i < ELEMENTSOF(m->samples); i++)
453 j += square(m->samples[i].offset - m->samples[idx_min].offset);
454 m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
456 /* ignore samples when resyncing */
460 /* always accept offset if we are farther off than the round-trip delay */
461 if (fabs(offset) > delay)
464 /* we need a few samples before looking at them */
465 if (m->packet_count < 4)
468 /* do not accept anything worse than the maximum possible error of the best sample */
469 if (fabs(offset) > m->samples[idx_min].delay)
472 /* compare the difference between the current offset to the previous offset and jitter */
473 return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
476 static void manager_adjust_poll(Manager *m, double offset, bool spike) {
479 if (m->poll_resync) {
480 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
481 m->poll_resync = false;
485 /* set to minimal poll interval */
486 if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
487 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
491 /* increase polling interval */
492 if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
493 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
494 m->poll_interval_usec *= 2;
498 /* decrease polling interval */
499 if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
500 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
501 m->poll_interval_usec /= 2;
506 static bool sockaddr_equal(union sockaddr_union *a, union sockaddr_union *b) {
510 if (a->sa.sa_family != b->sa.sa_family)
513 if (a->sa.sa_family == AF_INET)
514 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
516 if (a->sa.sa_family == AF_INET6)
517 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
522 static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
523 _cleanup_free_ char *pretty = NULL;
524 Manager *m = userdata;
525 struct ntp_msg ntpmsg;
529 .iov_len = sizeof(ntpmsg),
532 struct cmsghdr cmsghdr;
533 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
535 union sockaddr_union server_addr;
536 struct msghdr msghdr = {
539 .msg_control = &control,
540 .msg_controllen = sizeof(control),
541 .msg_name = &server_addr,
542 .msg_namelen = sizeof(server_addr),
544 struct cmsghdr *cmsg;
545 struct timespec now_ts;
546 struct timeval *recv_time;
548 double origin, receive, trans, dest;
549 double delay, offset;
557 if (revents & (EPOLLHUP|EPOLLERR)) {
558 log_warning("Server connection returned error.");
559 return manager_connect(m);
562 len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
567 log_warning("Error receiving message. Disconnecting.");
568 return manager_connect(m);
571 if (iov.iov_len < sizeof(struct ntp_msg)) {
572 log_warning("Invalid response from server. Disconnecting.");
573 return manager_connect(m);
576 if (!m->current_server_name ||
577 !m->current_server_address ||
578 !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
579 log_debug("Response from unknown server.");
584 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
585 if (cmsg->cmsg_level != SOL_SOCKET)
588 switch (cmsg->cmsg_type) {
590 recv_time = (struct timeval *) CMSG_DATA(cmsg);
595 log_error("Invalid packet timestamp.");
600 log_debug("Unexpected reply. Ignoring.");
604 /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
605 if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
606 be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
607 log_debug("Invalid reply; not our transmit time. Ignoring.");
611 if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
612 log_debug("Server is not synchronized. Disconnecting.");
613 return manager_connect(m);
616 if (NTP_FIELD_VERSION(ntpmsg.field) != 4) {
617 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
618 return manager_connect(m);
621 if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
622 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
623 return manager_connect(m);
628 m->retry_interval = 0;
630 /* announce leap seconds */
631 if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
633 else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
639 * "Timestamp Name ID When Generated
640 * ------------------------------------------------------------
641 * Originate Timestamp T1 time request sent by client
642 * Receive Timestamp T2 time request received by server
643 * Transmit Timestamp T3 time reply sent by server
644 * Destination Timestamp T4 time reply received by client
646 * The round-trip delay, d, and system clock offset, t, are defined as:
647 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
649 assert_se(clock_gettime(CLOCK_MONOTONIC, &now_ts) >= 0);
650 origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
651 receive = ntp_ts_to_d(&ntpmsg.recv_time);
652 trans = ntp_ts_to_d(&ntpmsg.trans_time);
653 dest = tv_to_d(recv_time) + OFFSET_1900_1970;
655 offset = ((receive - origin) + (trans - dest)) / 2;
656 delay = (dest - origin) - (trans - receive);
658 spike = manager_sample_spike_detection(m, offset, delay);
660 manager_adjust_poll(m, offset, spike);
662 log_debug("NTP response:\n"
667 " precision : %.6f sec (%d)\n"
668 " reference : %.4s\n"
673 " offset : %+.3f sec\n"
674 " delay : %+.3f sec\n"
675 " packet count : %"PRIu64"\n"
677 " poll interval: %llu\n",
678 NTP_FIELD_LEAP(ntpmsg.field),
679 NTP_FIELD_VERSION(ntpmsg.field),
680 NTP_FIELD_MODE(ntpmsg.field),
682 exp2(ntpmsg.precision), ntpmsg.precision,
683 ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
684 origin - OFFSET_1900_1970,
685 receive - OFFSET_1900_1970,
686 trans - OFFSET_1900_1970,
687 dest - OFFSET_1900_1970,
690 m->samples_jitter, spike ? " spike" : "",
691 m->poll_interval_usec / USEC_PER_SEC);
694 r = manager_adjust_clock(m, offset, leap_sec);
696 log_error("Failed to call clock_adjtime(): %m");
699 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
701 log_error("Failed to format socket address: %s", strerror(-r));
705 log_info("%s (%s): interval/delta/delay/jitter/drift %llus/%+.3fs/%.3fs/%.3fs/%+ippm%s",
706 pretty, m->current_server_name->string, m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
707 spike ? " (ignored)" : "");
709 r = manager_arm_timer(m, m->poll_interval_usec);
711 log_error("Failed to rearm timer: %s", strerror(-r));
718 static int manager_listen_setup(Manager *m) {
719 union sockaddr_union addr = {};
720 static const int tos = IPTOS_LOWDELAY;
721 static const int on = 1;
726 assert(m->server_socket < 0);
727 assert(!m->event_receive);
728 assert(m->current_server_address);
730 addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
732 m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
733 if (m->server_socket < 0)
736 r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
740 r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
744 setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
746 return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
749 static int manager_begin(Manager *m) {
750 _cleanup_free_ char *pretty = NULL;
754 assert_return(m->current_server_name, -EHOSTUNREACH);
755 assert_return(m->current_server_address, -EHOSTUNREACH);
757 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
759 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
761 log_warning("Failed to decode address of %s: %s", m->current_server_name->string, strerror(-r));
765 log_debug("Connecting to NTP server %s (%s).", pretty, m->current_server_name->string);
766 sd_notifyf(false, "STATUS=Using Time Server %s (%s)", pretty, m->current_server_name->string);
768 r = manager_listen_setup(m);
770 log_warning("Failed to setup connection socket: %s", strerror(-r));
774 r = manager_clock_watch_setup(m);
778 return manager_send_request(m);
781 static void server_name_flush_addresses(ServerName *n) {
786 while ((a = n->addresses)) {
787 LIST_REMOVE(addresses, n->addresses, a);
792 static void manager_flush_names(Manager *m) {
797 while ((n = m->servers)) {
798 LIST_REMOVE(names, m->servers, n);
800 server_name_flush_addresses(n);
805 static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
806 Manager *m = userdata;
807 ServerAddress *a, *last = NULL;
811 assert(m->current_server_name);
813 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
816 log_error("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
819 return manager_connect(m);
822 server_name_flush_addresses(m->current_server_name);
824 for (; ai; ai = ai->ai_next) {
825 _cleanup_free_ char *pretty = NULL;
828 assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
829 assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
831 if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
832 log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
836 a = new0(ServerAddress, 1);
840 memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
841 a->socklen = ai->ai_addrlen;
843 LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
846 sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
847 log_debug("Found address %s for %s.", pretty, m->current_server_name->string);
850 if (!m->current_server_name->addresses) {
851 log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
854 return manager_connect(m);
857 m->current_server_address = m->current_server_name->addresses;
859 return manager_begin(m);
862 static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
863 Manager *m = userdata;
867 return manager_connect(m);
870 static int manager_connect(Manager *m) {
872 struct addrinfo hints = {
873 .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
874 .ai_socktype = SOCK_DGRAM,
880 manager_disconnect(m);
882 m->event_retry = sd_event_source_unref(m->event_retry);
883 if (!ratelimit_test(&m->ratelimit)) {
884 log_debug("Slowing down attempts to contact servers.");
886 r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
888 log_error("Failed to create retry timer: %s", strerror(-r));
895 /* If we already are operating on some address, switch to the
897 if (m->current_server_address && m->current_server_address->addresses_next)
898 m->current_server_address = m->current_server_address->addresses_next;
900 /* Hmm, we are through all addresses, let's look for the next host instead */
901 m->current_server_address = NULL;
903 if (m->current_server_name && m->current_server_name->names_next)
904 m->current_server_name = m->current_server_name->names_next;
907 m->current_server_name = NULL;
908 log_debug("No server found.");
912 m->current_server_name = m->servers;
915 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
917 log_error("Failed to create resolver: %s", strerror(-r));
924 r = manager_begin(m);
931 static int manager_add_server(Manager *m, const char *server) {
937 n = new0(ServerName, 1);
941 n->string = strdup(server);
947 LIST_PREPEND(names, m->servers, n);
951 static void manager_disconnect(Manager *m) {
954 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
956 m->event_timer = sd_event_source_unref(m->event_timer);
958 m->event_receive = sd_event_source_unref(m->event_receive);
959 m->server_socket = safe_close(m->server_socket);
961 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
962 m->clock_watch_fd = safe_close(m->clock_watch_fd);
965 static int manager_new(Manager **ret) {
966 _cleanup_manager_free_ Manager *m = NULL;
969 m = new0(Manager, 1);
973 m->server_socket = m->clock_watch_fd = -1;
975 RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
977 r = sd_event_default(&m->event);
981 sd_event_add_signal(m->event, &m->sigterm, SIGTERM, NULL, NULL);
982 sd_event_add_signal(m->event, &m->sigint, SIGINT, NULL, NULL);
984 r = sd_resolve_default(&m->resolve);
988 r = sd_resolve_attach_event(m->resolve, m->event, 0);
992 r = manager_clock_watch_setup(m);
1002 static void manager_free(Manager *m) {
1006 manager_disconnect(m);
1007 manager_flush_names(m);
1009 sd_event_source_unref(m->sigint);
1010 sd_event_source_unref(m->sigterm);
1012 sd_event_source_unref(m->event_retry);
1014 sd_resolve_unref(m->resolve);
1015 sd_event_unref(m->event);
1020 int main(int argc, char *argv[]) {
1021 _cleanup_manager_free_ Manager *m = NULL;
1024 log_set_target(LOG_TARGET_AUTO);
1025 log_parse_environment();
1028 assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
1030 r = manager_new(&m);
1032 log_error("Failed to allocate manager: %s", strerror(-r));
1036 sd_notify(false, "READY=1");
1038 r = manager_add_server(m, "time1.google.com");
1040 log_error("Failed to add server: %s", strerror(-r));
1044 r = manager_connect(m);
1048 r = sd_event_loop(m->event);
1050 log_error("Failed to run event loop: %s", strerror(-r));
1054 sd_event_get_exit_code(m->event, &r);
1057 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;