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"
43 #include "sd-resolve.h"
44 #include "sd-daemon.h"
46 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
49 #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
52 /* expected accuracy of time synchronization; used to adjust the poll interval */
53 #define NTP_ACCURACY_SEC 0.2
56 * "A client MUST NOT under any conditions use a poll interval less
59 #define NTP_POLL_INTERVAL_MIN_SEC 32
60 #define NTP_POLL_INTERVAL_MAX_SEC 2048
63 * Maximum delta in seconds which the system clock is gradually adjusted
64 * (slew) to approach the network time. Deltas larger that this are set by
65 * letting the system time jump. The kernel's limit for adjtime is 0.5s.
67 #define NTP_MAX_ADJUST 0.4
69 /* NTP protocol, packet header */
70 #define NTP_LEAP_PLUSSEC 1
71 #define NTP_LEAP_MINUSSEC 2
72 #define NTP_LEAP_NOTINSYNC 3
73 #define NTP_MODE_CLIENT 3
74 #define NTP_MODE_SERVER 4
75 #define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
76 #define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
77 #define NTP_FIELD_MODE(f) ((f) & 7)
78 #define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
81 * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
82 * in seconds relative to 0h on 1 January 1900."
84 #define OFFSET_1900_1970 2208988800UL
101 struct ntp_ts_short root_delay;
102 struct ntp_ts_short root_dispersion;
104 struct ntp_ts reference_time;
105 struct ntp_ts origin_time;
106 struct ntp_ts recv_time;
107 struct ntp_ts trans_time;
110 typedef struct Manager Manager;
111 typedef struct ServerAddress ServerAddress;
112 typedef struct ServerName ServerName;
114 struct ServerAddress {
115 union sockaddr_union sockaddr;
117 LIST_FIELDS(ServerAddress, addresses);
122 LIST_HEAD(ServerAddress, addresses);
123 LIST_FIELDS(ServerName, names);
130 LIST_HEAD(ServerName, servers);
133 sd_resolve_query *resolve_query;
134 sd_event_source *event_receive;
135 ServerName *current_server_name;
136 ServerAddress *current_server_address;
138 uint64_t packet_count;
140 /* last sent packet */
141 struct timespec trans_time_mon;
142 struct timespec trans_time;
143 usec_t retry_interval;
147 sd_event_source *event_timer;
148 usec_t poll_interval_usec;
156 unsigned int samples_idx;
157 double samples_jitter;
163 /* watch for time changes */
164 sd_event_source *event_clock_watch;
167 /* Handle SIGINT/SIGTERM */
168 sd_event_source *sigterm, *sigint;
171 static void manager_free(Manager *m);
172 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
173 #define _cleanup_manager_free_ _cleanup_(manager_freep)
175 static int manager_arm_timer(Manager *m, usec_t next);
176 static int manager_clock_watch_setup(Manager *m);
177 static int manager_connect(Manager *m);
178 static void manager_disconnect(Manager *m);
180 static double ntp_ts_to_d(const struct ntp_ts *ts) {
181 return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
184 static double ts_to_d(const struct timespec *ts) {
185 return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
188 static double tv_to_d(const struct timeval *tv) {
189 return tv->tv_sec + (1.0e-6 * tv->tv_usec);
192 static double square(double d) {
196 static int manager_send_request(Manager *m) {
197 _cleanup_free_ char *pretty = NULL;
198 struct ntp_msg ntpmsg = {
200 * "The client initializes the NTP message header, sends the request
201 * to the server, and strips the time of day from the Transmit
202 * Timestamp field of the reply. For this purpose, all the NTP
203 * header fields are set to 0, except the Mode, VN, and optional
204 * Transmit Timestamp fields."
206 .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
212 assert(m->current_server_name);
213 assert(m->current_server_address);
216 * Set transmit timestamp, remember it; the server will send that back
217 * as the origin timestamp and we have an indication that this is the
218 * matching answer to our request.
220 * The actual value does not matter, We do not care about the correct
221 * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
223 assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
224 assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
225 ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
226 ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
228 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
230 log_error("Failed to format sockaddr: %s", strerror(-r));
234 len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
235 if (len == sizeof(ntpmsg)) {
237 log_debug("Sent NTP request to %s (%s)", pretty, m->current_server_name->string);
239 log_debug("Sending NTP request to %s (%s) failed: %m", pretty, m->current_server_name->string);
241 /* re-arm timer with incresing timeout, in case the packets never arrive back */
242 if (m->retry_interval > 0) {
243 if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
244 m->retry_interval *= 2;
246 m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
248 r = manager_arm_timer(m, m->retry_interval);
250 log_error("Failed to rearm timer: %s", strerror(-r));
257 static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
258 Manager *m = userdata;
262 return manager_send_request(m);
265 static int manager_arm_timer(Manager *m, usec_t next) {
269 assert(m->event_receive);
272 m->event_timer = sd_event_source_unref(m->event_timer);
276 if (m->event_timer) {
277 r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
281 return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
284 return sd_event_add_time(
288 now(CLOCK_MONOTONIC) + next, 0,
292 static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
293 Manager *m = userdata;
298 manager_clock_watch_setup(m);
300 /* skip our own jumps */
307 log_info("System time changed. Resyncing.");
308 m->poll_resync = true;
309 return manager_send_request(m);
312 /* wake up when the system time changes underneath us */
313 static int manager_clock_watch_setup(Manager *m) {
315 struct itimerspec its = {
316 .it_value.tv_sec = TIME_T_MAX
323 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
324 m->clock_watch_fd = safe_close(m->clock_watch_fd);
326 m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
327 if (m->clock_watch_fd < 0) {
328 log_error("Failed to create timerfd: %m");
332 if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
333 log_error("Failed to set up timerfd: %m");
337 r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
339 log_error("Failed to create clock watch event source: %s", strerror(-r));
346 static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
347 struct timex tmx = {};
353 * For small deltas, tell the kernel to gradually adjust the system
354 * clock to the NTP time, larger deltas are just directly set.
356 * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
357 * syncs the system time periodically to the hardware clock.
359 if (fabs(offset) < NTP_MAX_ADJUST) {
360 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
361 tmx.status = STA_PLL;
362 tmx.offset = offset * NSEC_PER_SEC;
363 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
366 log_debug(" adjust (slew): %+.3f sec\n", offset);
368 tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
370 /* ADJ_NANO uses nanoseconds in the microseconds field */
371 tmx.time.tv_sec = (long)offset;
372 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
374 /* the kernel expects -0.3s as {-1, 7000.000.000} */
375 if (tmx.time.tv_usec < 0) {
376 tmx.time.tv_sec -= 1;
377 tmx.time.tv_usec += NSEC_PER_SEC;
381 log_debug(" adjust (jump): %+.3f sec\n", offset);
386 tmx.status |= STA_INS;
389 tmx.status |= STA_DEL;
393 r = clock_adjtime(CLOCK_REALTIME, &tmx);
397 m->drift_ppm = tmx.freq / 65536;
399 log_debug(" status : %04i %s\n"
400 " time now : %li.%03lli\n"
402 " offset : %+.3f sec\n"
403 " freq offset : %+li (%i ppm)\n",
404 tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
405 tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
407 (double)tmx.offset / NSEC_PER_SEC,
408 tmx.freq, m->drift_ppm);
413 static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
414 unsigned int i, idx_cur, idx_new, idx_min;
422 /* ignore initial sample */
423 if (m->packet_count == 1)
426 /* store the current data in our samples array */
427 idx_cur = m->samples_idx;
428 idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
429 m->samples_idx = idx_new;
430 m->samples[idx_new].offset = offset;
431 m->samples[idx_new].delay = delay;
433 /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
434 jitter = m->samples_jitter;
435 for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
436 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
440 for (i = 0; i < ELEMENTSOF(m->samples); i++)
441 j += square(m->samples[i].offset - m->samples[idx_min].offset);
442 m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
444 /* ignore samples when resyncing */
448 /* always accept offset if we are farther off than the round-trip delay */
449 if (fabs(offset) > delay)
452 /* we need a few samples before looking at them */
453 if (m->packet_count < 4)
456 /* do not accept anything worse than the maximum possible error of the best sample */
457 if (fabs(offset) > m->samples[idx_min].delay)
460 /* compare the difference between the current offset to the previous offset and jitter */
461 return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
464 static void manager_adjust_poll(Manager *m, double offset, bool spike) {
467 if (m->poll_resync) {
468 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
469 m->poll_resync = false;
473 /* set to minimal poll interval */
474 if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
475 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
479 /* increase polling interval */
480 if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
481 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
482 m->poll_interval_usec *= 2;
486 /* decrease polling interval */
487 if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
488 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
489 m->poll_interval_usec /= 2;
494 static bool sockaddr_equal(union sockaddr_union *a, union sockaddr_union *b) {
498 if (a->sa.sa_family != b->sa.sa_family)
501 if (a->sa.sa_family == AF_INET)
502 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
504 if (a->sa.sa_family == AF_INET6)
505 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
510 static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
511 _cleanup_free_ char *pretty = NULL;
512 Manager *m = userdata;
513 struct ntp_msg ntpmsg;
517 .iov_len = sizeof(ntpmsg),
520 struct cmsghdr cmsghdr;
521 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
523 union sockaddr_union server_addr;
524 struct msghdr msghdr = {
527 .msg_control = &control,
528 .msg_controllen = sizeof(control),
529 .msg_name = &server_addr,
530 .msg_namelen = sizeof(server_addr),
532 struct cmsghdr *cmsg;
533 struct timespec now_ts;
534 struct timeval *recv_time;
536 double origin, receive, trans, dest;
537 double delay, offset;
545 if (revents & (EPOLLHUP|EPOLLERR)) {
546 log_warning("Server connection returned error.");
547 return manager_connect(m);
550 len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
555 log_warning("Error receiving message. Disconnecting.");
556 return manager_connect(m);
559 if (iov.iov_len < sizeof(struct ntp_msg)) {
560 log_warning("Invalid response from server. Disconnecting.");
561 return manager_connect(m);
564 if (!m->current_server_name ||
565 !m->current_server_address ||
566 !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
567 log_debug("Response from unknown server.");
572 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
573 if (cmsg->cmsg_level != SOL_SOCKET)
576 switch (cmsg->cmsg_type) {
578 recv_time = (struct timeval *) CMSG_DATA(cmsg);
583 log_error("Invalid packet timestamp.");
588 log_debug("Unexpected reply. Ignoring.");
592 /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
593 if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
594 be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
595 log_debug("Invalid reply; not our transmit time. Ignoring.");
599 if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
600 log_debug("Server is not synchronized. Disconnecting.");
601 return manager_connect(m);
604 if (NTP_FIELD_VERSION(ntpmsg.field) != 4) {
605 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
606 return manager_connect(m);
609 if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
610 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
611 return manager_connect(m);
616 m->retry_interval = 0;
618 /* announce leap seconds */
619 if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
621 else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
627 * "Timestamp Name ID When Generated
628 * ------------------------------------------------------------
629 * Originate Timestamp T1 time request sent by client
630 * Receive Timestamp T2 time request received by server
631 * Transmit Timestamp T3 time reply sent by server
632 * Destination Timestamp T4 time reply received by client
634 * The round-trip delay, d, and system clock offset, t, are defined as:
635 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
637 assert_se(clock_gettime(CLOCK_MONOTONIC, &now_ts) >= 0);
638 origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
639 receive = ntp_ts_to_d(&ntpmsg.recv_time);
640 trans = ntp_ts_to_d(&ntpmsg.trans_time);
641 dest = tv_to_d(recv_time) + OFFSET_1900_1970;
643 offset = ((receive - origin) + (trans - dest)) / 2;
644 delay = (dest - origin) - (trans - receive);
646 spike = manager_sample_spike_detection(m, offset, delay);
648 manager_adjust_poll(m, offset, spike);
650 log_debug("NTP response:\n"
655 " precision : %.6f sec (%d)\n"
656 " reference : %.4s\n"
661 " offset : %+.3f sec\n"
662 " delay : %+.3f sec\n"
663 " packet count : %"PRIu64"\n"
665 " poll interval: %llu\n",
666 NTP_FIELD_LEAP(ntpmsg.field),
667 NTP_FIELD_VERSION(ntpmsg.field),
668 NTP_FIELD_MODE(ntpmsg.field),
670 exp2(ntpmsg.precision), ntpmsg.precision,
671 ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
672 origin - OFFSET_1900_1970,
673 receive - OFFSET_1900_1970,
674 trans - OFFSET_1900_1970,
675 dest - OFFSET_1900_1970,
678 m->samples_jitter, spike ? " spike" : "",
679 m->poll_interval_usec / USEC_PER_SEC);
682 r = manager_adjust_clock(m, offset, leap_sec);
684 log_error("Failed to call clock_adjtime(): %m");
687 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
689 log_error("Failed to format socket address: %s", strerror(-r));
693 log_info("%s (%s): interval/delta/delay/jitter/drift %llus/%+.3fs/%.3fs/%.3fs/%+ippm%s",
694 pretty, m->current_server_name->string, m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
695 spike ? " (ignored)" : "");
697 r = manager_arm_timer(m, m->poll_interval_usec);
699 log_error("Failed to rearm timer: %s", strerror(-r));
706 static int manager_listen_setup(Manager *m) {
707 union sockaddr_union addr = {};
708 static const int tos = IPTOS_LOWDELAY;
709 static const int on = 1;
714 assert(m->server_socket < 0);
715 assert(!m->event_receive);
716 assert(m->current_server_address);
718 addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
720 m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
721 if (m->server_socket < 0)
724 r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
728 r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
732 setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
734 return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
737 static int manager_begin(Manager *m) {
738 _cleanup_free_ char *pretty = NULL;
742 assert_return(m->current_server_name, -EHOSTUNREACH);
743 assert_return(m->current_server_address, -EHOSTUNREACH);
745 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
747 r = sockaddr_pretty(&m->current_server_address->sockaddr.sa, m->current_server_address->socklen, true, &pretty);
749 log_warning("Failed to decode address of %s: %s", m->current_server_name->string, strerror(-r));
753 log_debug("Connecting to NTP server %s (%s).", pretty, m->current_server_name->string);
754 sd_notifyf(false, "STATUS=Using Time Server %s (%s)", pretty, m->current_server_name->string);
756 r = manager_listen_setup(m);
758 log_warning("Failed to setup connection socket: %s", strerror(-r));
762 r = manager_clock_watch_setup(m);
766 return manager_send_request(m);
769 static void server_name_flush_addresses(ServerName *n) {
774 while ((a = n->addresses)) {
775 LIST_REMOVE(addresses, n->addresses, a);
780 static void manager_flush_names(Manager *m) {
785 while ((n = m->servers)) {
786 LIST_REMOVE(names, m->servers, n);
788 server_name_flush_addresses(n);
793 static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
794 Manager *m = userdata;
795 ServerAddress *a, *last = NULL;
799 assert(m->current_server_name);
801 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
804 log_error("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
807 return manager_connect(m);
810 server_name_flush_addresses(m->current_server_name);
812 for (; ai; ai = ai->ai_next) {
813 _cleanup_free_ char *pretty = NULL;
816 assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
817 assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
819 if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
820 log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
824 a = new0(ServerAddress, 1);
828 memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
829 a->socklen = ai->ai_addrlen;
831 LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
834 sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
835 log_debug("Found address %s for %s.", pretty, m->current_server_name->string);
838 if (!m->current_server_name->addresses) {
839 log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
842 return manager_connect(m);
845 m->current_server_address = m->current_server_name->addresses;
847 return manager_begin(m);
850 static int manager_connect(Manager *m) {
852 struct addrinfo hints = {
853 .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
854 .ai_socktype = SOCK_DGRAM,
860 manager_disconnect(m);
862 /* If we already are operating on some address, switch to the
864 if (m->current_server_address && m->current_server_address->addresses_next)
865 m->current_server_address = m->current_server_address->addresses_next;
867 /* Hmm, we are through all addresses, let's look for the next host instead */
868 m->current_server_address = NULL;
870 if (m->current_server_name && m->current_server_name->names_next)
871 m->current_server_name = m->current_server_name->names_next;
874 m->current_server_name = NULL;
875 log_debug("No server found.");
879 m->current_server_name = m->servers;
882 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
884 log_error("Failed to create resolver: %s", strerror(-r));
891 r = manager_begin(m);
898 static int manager_add_server(Manager *m, const char *server) {
904 n = new0(ServerName, 1);
908 n->string = strdup(server);
914 LIST_PREPEND(names, m->servers, n);
918 static void manager_disconnect(Manager *m) {
921 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
923 m->event_timer = sd_event_source_unref(m->event_timer);
925 m->event_receive = sd_event_source_unref(m->event_receive);
926 m->server_socket = safe_close(m->server_socket);
928 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
929 m->clock_watch_fd = safe_close(m->clock_watch_fd);
932 static int manager_new(Manager **ret) {
933 _cleanup_manager_free_ Manager *m = NULL;
936 m = new0(Manager, 1);
940 m->server_socket = m->clock_watch_fd = -1;
942 r = sd_event_default(&m->event);
946 sd_event_add_signal(m->event, &m->sigterm, SIGTERM, NULL, NULL);
947 sd_event_add_signal(m->event, &m->sigint, SIGINT, NULL, NULL);
949 r = sd_resolve_default(&m->resolve);
953 r = sd_resolve_attach_event(m->resolve, m->event, 0);
957 r = manager_clock_watch_setup(m);
967 static void manager_free(Manager *m) {
971 manager_disconnect(m);
972 manager_flush_names(m);
974 sd_event_source_unref(m->sigint);
975 sd_event_source_unref(m->sigterm);
977 sd_resolve_unref(m->resolve);
978 sd_event_unref(m->event);
983 int main(int argc, char *argv[]) {
984 _cleanup_manager_free_ Manager *m = NULL;
987 log_set_target(LOG_TARGET_AUTO);
988 log_parse_environment();
991 assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
995 log_error("Failed to allocate manager: %s", strerror(-r));
999 sd_notify(false, "READY=1");
1001 r = manager_add_server(m, "time1.google.com");
1003 log_error("Failed to add server: %s", strerror(-r));
1007 r = manager_connect(m);
1011 r = sd_event_loop(m->event);
1013 log_error("Failed to run event loop: %s", strerror(-r));
1017 sd_event_get_exit_code(m->event, &r);
1020 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;