chiark / gitweb /
timesync: always initialize structs when declaring them as far as possible with conts...
[elogind.git] / src / timesync / timesyncd.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 Kay Sievers
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <time.h>
28 #include <math.h>
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>
35
36 #include "missing.h"
37 #include "util.h"
38 #include "sparse-endian.h"
39 #include "log.h"
40 #include "socket-util.h"
41 #include "sd-event.h"
42 #include "sd-daemon.h"
43
44 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
45
46 #ifndef ADJ_SETOFFSET
47 #define ADJ_SETOFFSET                   0x0100  /* add 'time' to current time */
48 #endif
49
50 /* expected accuracy of time synchronization; used to adjust the poll interval */
51 #define NTP_ACCURACY_SEC                0.2
52
53 /*
54  * "A client MUST NOT under any conditions use a poll interval less
55  * than 15 seconds."
56  */
57 #define NTP_POLL_INTERVAL_MIN_SEC       32
58 #define NTP_POLL_INTERVAL_MAX_SEC       2048
59
60 /*
61  * Maximum delta in seconds which the system clock is gradually adjusted
62  * (slew) to approach the network time. Deltas larger that this are set by
63  * letting the system time jump. The kernel's limit for adjtime is 0.5s.
64  */
65 #define NTP_MAX_ADJUST                  0.4
66
67 /* NTP protocol, packet header */
68 #define NTP_LEAP_PLUSSEC                1
69 #define NTP_LEAP_MINUSSEC               2
70 #define NTP_LEAP_NOTINSYNC              3
71 #define NTP_MODE_CLIENT                 3
72 #define NTP_MODE_SERVER                 4
73 #define NTP_FIELD_LEAP(f)               (((f) >> 6) & 3)
74 #define NTP_FIELD_VERSION(f)            (((f) >> 3) & 7)
75 #define NTP_FIELD_MODE(f)               ((f) & 7)
76 #define NTP_FIELD(l, v, m)              (((l) << 6) | ((v) << 3) | (m))
77
78 /*
79  * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
80  * in seconds relative to 0h on 1 January 1900."
81  */
82 #define OFFSET_1900_1970        2208988800UL
83
84 struct ntp_ts {
85         be32_t sec;
86         be32_t frac;
87 } _packed_;
88
89 struct ntp_ts_short {
90         be16_t sec;
91         be16_t frac;
92 } _packed_;
93
94 struct ntp_msg {
95         uint8_t field;
96         uint8_t stratum;
97         int8_t poll;
98         int8_t precision;
99         struct ntp_ts_short root_delay;
100         struct ntp_ts_short root_dispersion;
101         char refid[4];
102         struct ntp_ts reference_time;
103         struct ntp_ts origin_time;
104         struct ntp_ts recv_time;
105         struct ntp_ts trans_time;
106 } _packed_;
107
108 typedef struct Manager Manager;
109 struct Manager {
110         sd_event *event;
111
112         /* peer */
113         sd_event_source *event_receive;
114         char *server;
115         union sockaddr_union server_addr;
116         int server_socket;
117         uint64_t packet_count;
118
119         /* last sent packet */
120         struct timespec trans_time_mon;
121         struct timespec trans_time;
122         usec_t retry_interval;
123         bool pending;
124
125         /* poll timer */
126         sd_event_source *event_timer;
127         usec_t poll_interval_usec;
128         bool poll_resync;
129
130         /* history data */
131         struct {
132                 double offset;
133                 double delay;
134         } samples[8];
135         unsigned int samples_idx;
136         double samples_jitter;
137
138         /* last change */
139         bool jumped;
140         int drift_ppm;
141
142         /* watch for time changes */
143         sd_event_source *event_clock_watch;
144         int clock_watch_fd;
145 };
146
147 static void manager_free(Manager *m);
148 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
149 #define _cleanup_manager_free_ _cleanup_(manager_freep)
150
151 static int sntp_arm_timer(Manager *m, usec_t next);
152 static int sntp_clock_watch_setup(Manager *m);
153 static void sntp_server_disconnect(Manager *m);
154
155 static double ntp_ts_to_d(const struct ntp_ts *ts) {
156         return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
157 }
158
159 static double ts_to_d(const struct timespec *ts) {
160         return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
161 }
162
163 static double tv_to_d(const struct timeval *tv) {
164         return tv->tv_sec + (1.0e-6 * tv->tv_usec);
165 }
166
167 static double square(double d) {
168         return d * d;
169 }
170
171 static int sntp_send_request(Manager *m) {
172         struct ntp_msg ntpmsg = {
173                 /*
174                  * "The client initializes the NTP message header, sends the request
175                  * to the server, and strips the time of day from the Transmit
176                  * Timestamp field of the reply.  For this purpose, all the NTP
177                  * header fields are set to 0, except the Mode, VN, and optional
178                  * Transmit Timestamp fields."
179                  */
180                 .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
181         };
182
183         union sockaddr_union addr = {
184                 .in.sin_family = AF_INET,
185                 .in.sin_port = htobe16(123),
186         };
187         ssize_t len;
188         int r;
189
190
191         /*
192          * Set transmit timestamp, remember it; the server will send that back
193          * as the origin timestamp and we have an indication that this is the
194          * matching answer to our request.
195          *
196          * The actual value does not matter, We do not care about the correct
197          * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
198          */
199         clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon);
200         clock_gettime(CLOCK_REALTIME, &m->trans_time);
201         ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
202         ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
203
204         addr.in.sin_addr.s_addr = inet_addr(m->server);
205         len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &addr.sa, sizeof(addr.in));
206         if (len == sizeof(ntpmsg)) {
207                 m->pending = true;
208                 log_debug("Sent NTP request to: %s", m->server);
209         } else
210                 log_debug("Sending NTP request to %s failed: %m", m->server);
211
212         /* re-arm timer with incresing timeout, in case the packets never arrive back */
213         if (m->retry_interval > 0) {
214                 if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
215                         m->retry_interval *= 2;
216         } else
217                 m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
218         r = sntp_arm_timer(m, m->retry_interval);
219         if (r < 0)
220                 return r;
221
222         return 0;
223 }
224
225 static int sntp_timer(sd_event_source *source, usec_t usec, void *userdata) {
226         Manager *m = userdata;
227
228         assert(m);
229
230         sntp_send_request(m);
231         return 0;
232 }
233
234 static int sntp_arm_timer(Manager *m, usec_t next) {
235         int r;
236
237         assert(m);
238         assert(m->event_receive);
239
240         if (next == 0) {
241                 m->event_timer = sd_event_source_unref(m->event_timer);
242                 return 0;
243         }
244
245         if (m->event_timer) {
246                 r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
247                 if (r < 0)
248                         return r;
249
250                 return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
251         }
252
253         r = sd_event_add_time(
254                         m->event,
255                         &m->event_timer,
256                         CLOCK_MONOTONIC,
257                         now(CLOCK_MONOTONIC) + next, 0,
258                         sntp_timer, m);
259         if (r < 0)
260                 return r;
261
262         return 0;
263 }
264
265 static int sntp_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
266         Manager *m = userdata;
267
268         assert(m);
269         assert(m->event_receive);
270
271         /* rearm timer */
272         sntp_clock_watch_setup(m);
273
274         /* skip our own jumps */
275         if (m->jumped) {
276                 m->jumped = false;
277                 return 0;
278         }
279
280         /* resync */
281         log_info("System time changed. Resyncing.");
282         m->poll_resync = true;
283         sntp_send_request(m);
284
285         return 0;
286 }
287
288 /* wake up when the system time changes underneath us */
289 static int sntp_clock_watch_setup(Manager *m) {
290
291         struct itimerspec its = {
292                 .it_value.tv_sec = TIME_T_MAX
293         };
294
295         _cleanup_close_ int fd = -1;
296         sd_event_source *source;
297         int r;
298
299         assert(m);
300         assert(m->event_receive);
301
302         fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
303         if (fd < 0) {
304                 log_error("Failed to create timerfd: %m");
305                 return -errno;
306         }
307
308         if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
309                 log_error("Failed to set up timerfd: %m");
310                 return -errno;
311         }
312
313         r = sd_event_add_io(m->event, &source, fd, EPOLLIN, sntp_clock_watch, m);
314         if (r < 0) {
315                 log_error("Failed to create clock watch event source: %s", strerror(-r));
316                 return r;
317         }
318
319         sd_event_source_unref(m->event_clock_watch);
320         m->event_clock_watch = source;
321
322         if (m->clock_watch_fd >= 0)
323                 close(m->clock_watch_fd);
324         m->clock_watch_fd = fd;
325         fd = -1;
326
327         return 0;
328 }
329
330 static int sntp_adjust_clock(Manager *m, double offset, int leap_sec) {
331         struct timex tmx = {};
332         int r;
333
334         /*
335          * For small deltas, tell the kernel to gradually adjust the system
336          * clock to the NTP time, larger deltas are just directly set.
337          *
338          * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
339          * syncs the system time periodically to the hardware clock.
340          */
341         if (fabs(offset) < NTP_MAX_ADJUST) {
342                 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
343                 tmx.status = STA_PLL;
344                 tmx.offset = offset * NSEC_PER_SEC;
345                 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
346                 tmx.maxerror = 0;
347                 tmx.esterror = 0;
348                 log_debug("  adjust (slew): %+.3f sec\n", offset);
349         } else {
350                 tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
351
352                 /* ADJ_NANO uses nanoseconds in the microseconds field */
353                 tmx.time.tv_sec = (long)offset;
354                 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
355
356                 /* the kernel expects -0.3s as {-1, 7000.000.000} */
357                 if (tmx.time.tv_usec < 0) {
358                         tmx.time.tv_sec  -= 1;
359                         tmx.time.tv_usec += NSEC_PER_SEC;
360                 }
361
362                 m->jumped = true;
363                 log_debug("  adjust (jump): %+.3f sec\n", offset);
364         }
365
366         switch (leap_sec) {
367         case 1:
368                 tmx.status |= STA_INS;
369                 break;
370         case -1:
371                 tmx.status |= STA_DEL;
372                 break;
373         }
374
375         r = clock_adjtime(CLOCK_REALTIME, &tmx);
376         if (r < 0)
377                 return r;
378
379         m->drift_ppm = tmx.freq / 65536;
380
381         log_debug("  status       : %04i %s\n"
382                   "  time now     : %li.%03lli\n"
383                   "  constant     : %li\n"
384                   "  offset       : %+.3f sec\n"
385                   "  freq offset  : %+li (%i ppm)\n",
386                   tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
387                   tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
388                   tmx.constant,
389                   (double)tmx.offset / NSEC_PER_SEC,
390                   tmx.freq, m->drift_ppm);
391
392         return 0;
393 }
394
395 static bool sntp_sample_spike_detection(Manager *m, double offset, double delay) {
396         unsigned int i, idx_cur, idx_new, idx_min;
397         double jitter;
398         double j;
399
400         m->packet_count++;
401
402         /* ignore initial sample */
403         if (m->packet_count == 1)
404                 return false;
405
406         /* store the current data in our samples array */
407         idx_cur = m->samples_idx;
408         idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
409         m->samples_idx = idx_new;
410         m->samples[idx_new].offset = offset;
411         m->samples[idx_new].delay = delay;
412
413         /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
414         jitter = m->samples_jitter;
415         for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
416                 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
417                         idx_min = i;
418
419         j = 0;
420         for (i = 0; i < ELEMENTSOF(m->samples); i++)
421                 j += square(m->samples[i].offset - m->samples[idx_min].offset);
422         m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
423
424         /* ignore samples when resyncing */
425         if (m->poll_resync)
426                 return false;
427
428         /* always accept offset if we are farther off than the round-trip delay */
429         if (fabs(offset) > delay)
430                 return false;
431
432         /* we need a few samples before looking at them */
433         if (m->packet_count < 4)
434                 return false;
435
436         /* do not accept anything worse than the maximum possible error of the best sample */
437         if (fabs(offset) > m->samples[idx_min].delay)
438                 return true;
439
440         /* compare the difference between the current offset to the previous offset and jitter */
441         return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
442 }
443
444 static void sntp_adjust_poll(Manager *m, double offset, bool spike) {
445         if (m->poll_resync) {
446                 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
447                 m->poll_resync = false;
448                 return;
449         }
450
451         /* set to minimal poll interval */
452         if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
453                 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
454                 return;
455         }
456
457         /* increase polling interval */
458         if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
459                 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
460                         m->poll_interval_usec *= 2;
461                 return;
462         }
463
464         /* decrease polling interval */
465         if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
466                 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
467                         m->poll_interval_usec /= 2;
468                 return;
469         }
470 }
471
472 static int sntp_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
473         Manager *m = userdata;
474         unsigned char buf[sizeof(struct ntp_msg)];
475         struct iovec iov = {
476                 .iov_base = buf,
477                 .iov_len = sizeof(buf),
478         };
479         union {
480                 struct cmsghdr cmsghdr;
481                 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
482         } control;
483         union sockaddr_union server_addr;
484         struct msghdr msghdr = {
485                 .msg_iov = &iov,
486                 .msg_iovlen = 1,
487                 .msg_control = &control,
488                 .msg_controllen = sizeof(control),
489                 .msg_name = &server_addr,
490                 .msg_namelen = sizeof(server_addr),
491         };
492         struct cmsghdr *cmsg;
493         struct timespec now_ts;
494         struct timeval *recv_time;
495         ssize_t len;
496         struct ntp_msg *ntpmsg;
497         double origin, receive, trans, dest;
498         double delay, offset;
499         bool spike;
500         int leap_sec;
501         int r;
502
503         if (revents & (EPOLLHUP|EPOLLERR)) {
504                 log_debug("Server connection returned error. Closing.");
505                 sntp_server_disconnect(m);
506                 return -ENOTCONN;
507         }
508
509         len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
510         if (len < 0) {
511                 log_debug("Error receiving message. Disconnecting.");
512                 return -EINVAL;
513         }
514
515         if (iov.iov_len < sizeof(struct ntp_msg)) {
516                 log_debug("Invalid response from server. Disconnecting.");
517                 return -EINVAL;
518         }
519
520         if (m->server_addr.in.sin_addr.s_addr != server_addr.in.sin_addr.s_addr) {
521                 log_debug("Response from unknown server. Disconnecting.");
522                 return -EINVAL;
523         }
524
525         recv_time = NULL;
526         for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
527                 if (cmsg->cmsg_level != SOL_SOCKET)
528                         continue;
529
530                 switch (cmsg->cmsg_type) {
531                 case SCM_TIMESTAMP:
532                         recv_time = (struct timeval *) CMSG_DATA(cmsg);
533                         break;
534                 }
535         }
536         if (!recv_time) {
537                 log_debug("Invalid packet timestamp. Disconnecting.");
538                 return -EINVAL;
539         }
540
541         ntpmsg = iov.iov_base;
542         if (!m->pending) {
543                 log_debug("Unexpected reply. Ignoring.");
544                 return 0;
545         }
546
547         /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
548         if (be32toh(ntpmsg->origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
549             be32toh(ntpmsg->origin_time.frac) != m->trans_time.tv_nsec) {
550                 log_debug("Invalid reply; not our transmit time. Ignoring.");
551                 return 0;
552         }
553
554         if (NTP_FIELD_LEAP(ntpmsg->field) == NTP_LEAP_NOTINSYNC) {
555                 log_debug("Server is not synchronized. Disconnecting.");
556                 return -EINVAL;
557         }
558
559         if (NTP_FIELD_VERSION(ntpmsg->field) != 4) {
560                 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg->field));
561                 return -EINVAL;
562         }
563
564         if (NTP_FIELD_MODE(ntpmsg->field) != NTP_MODE_SERVER) {
565                 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg->field));
566                 return -EINVAL;
567         }
568
569         /* valid packet */
570         m->pending = false;
571         m->retry_interval = 0;
572
573         /* announce leap seconds */
574         if (NTP_FIELD_LEAP(ntpmsg->field) & NTP_LEAP_PLUSSEC)
575                 leap_sec = 1;
576         else if (NTP_FIELD_LEAP(ntpmsg->field) & NTP_LEAP_MINUSSEC)
577                 leap_sec = -1;
578         else
579                 leap_sec = 0;
580
581         /*
582          * "Timestamp Name          ID   When Generated
583          *  ------------------------------------------------------------
584          *  Originate Timestamp     T1   time request sent by client
585          *  Receive Timestamp       T2   time request received by server
586          *  Transmit Timestamp      T3   time reply sent by server
587          *  Destination Timestamp   T4   time reply received by client
588          *
589          *  The round-trip delay, d, and system clock offset, t, are defined as:
590          *  d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2"
591          */
592         clock_gettime(CLOCK_MONOTONIC, &now_ts);
593         origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
594         receive = ntp_ts_to_d(&ntpmsg->recv_time);
595         trans = ntp_ts_to_d(&ntpmsg->trans_time);
596         dest = tv_to_d(recv_time) + OFFSET_1900_1970;
597
598         offset = ((receive - origin) + (trans - dest)) / 2;
599         delay = (dest - origin) - (trans - receive);
600
601         spike = sntp_sample_spike_detection(m, offset, delay);
602
603         sntp_adjust_poll(m, offset, spike);
604
605         log_debug("NTP response:\n"
606                   "  leap         : %u\n"
607                   "  version      : %u\n"
608                   "  mode         : %u\n"
609                   "  stratum      : %u\n"
610                   "  precision    : %.6f sec (%d)\n"
611                   "  reference    : %.4s\n"
612                   "  origin       : %.3f\n"
613                   "  receive      : %.3f\n"
614                   "  transmit     : %.3f\n"
615                   "  dest         : %.3f\n"
616                   "  offset       : %+.3f sec\n"
617                   "  delay        : %+.3f sec\n"
618                   "  packet count : %"PRIu64"\n"
619                   "  jitter       : %.3f%s\n"
620                   "  poll interval: %llu\n",
621                   NTP_FIELD_LEAP(ntpmsg->field),
622                   NTP_FIELD_VERSION(ntpmsg->field),
623                   NTP_FIELD_MODE(ntpmsg->field),
624                   ntpmsg->stratum,
625                   exp2(ntpmsg->precision), ntpmsg->precision,
626                   ntpmsg->stratum == 1 ? ntpmsg->refid : "n/a",
627                   origin - OFFSET_1900_1970,
628                   receive - OFFSET_1900_1970,
629                   trans - OFFSET_1900_1970,
630                   dest - OFFSET_1900_1970,
631                   offset, delay,
632                   m->packet_count,
633                   m->samples_jitter, spike ? " spike" : "",
634                   m->poll_interval_usec / USEC_PER_SEC);
635
636         if (!spike) {
637                 r = sntp_adjust_clock(m, offset, leap_sec);
638                 if (r < 0)
639                         log_error("Failed to call clock_adjtime(): %m");
640         }
641
642         log_info("%s: interval/delta/delay/jitter/drift %llus/%+.3fs/%.3fs/%.3fs/%+ippm%s",
643                  m->server, m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
644                  spike ? " (ignored)" : "");
645         r = sntp_arm_timer(m, m->poll_interval_usec);
646         if (r < 0)
647                 return r;
648
649         return 0;
650 }
651
652 static int sntp_server_connect(Manager *m, const char *server) {
653         _cleanup_free_ char *s = NULL;
654
655         assert(m);
656         assert(server);
657         assert(m->server_socket >= 0);
658
659         s = strdup(server);
660         if (!s)
661                 return -ENOMEM;
662
663         free(m->server);
664         m->server = s;
665         s = NULL;
666
667         zero(m->server_addr);
668         m->server_addr.in.sin_family = AF_INET;
669         m->server_addr.in.sin_addr.s_addr = inet_addr(server);
670
671         m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
672
673         return sntp_send_request(m);
674 }
675
676 static void sntp_server_disconnect(Manager *m) {
677         if (!m->server)
678                 return;
679
680         m->event_timer = sd_event_source_unref(m->event_timer);
681
682         m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
683         if (m->clock_watch_fd > 0)
684                 close(m->clock_watch_fd);
685         m->clock_watch_fd = -1;
686
687         m->event_receive = sd_event_source_unref(m->event_receive);
688         if (m->server_socket > 0)
689                 close(m->server_socket);
690         m->server_socket = -1;
691
692         zero(m->server_addr);
693         free(m->server);
694         m->server = NULL;
695 }
696
697 static int sntp_listen_setup(Manager *m) {
698
699         union sockaddr_union addr = {
700                 .in.sin_family = AF_INET,
701         };
702
703         _cleanup_close_ int fd = -1;
704         const int on = 1;
705         const int tos = IPTOS_LOWDELAY;
706         int r;
707
708         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
709         if (fd < 0)
710                 return -errno;
711
712         r = bind(fd, &addr.sa, sizeof(addr.in));
713         if (r < 0)
714                 return -errno;
715
716         r = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
717         if (r < 0)
718                 return -errno;
719
720         r = setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
721         if (r < 0)
722                 return -errno;
723
724         r = sd_event_add_io(m->event, &m->event_receive, fd, EPOLLIN, sntp_receive_response, m);
725         if (r < 0)
726                 return r;
727
728         m->server_socket = fd;
729         fd = -1;
730
731         return 0;
732 }
733
734 static int manager_new(Manager **ret) {
735         _cleanup_manager_free_ Manager *m = NULL;
736         int r;
737
738         m = new0(Manager, 1);
739         if (!m)
740                 return -ENOMEM;
741
742         r = sd_event_default(&m->event);
743         if (r < 0)
744                 return r;
745
746         r = sntp_listen_setup(m);
747         if (r < 0)
748                 return r;
749
750         r = sntp_clock_watch_setup(m);
751         if (r < 0)
752                 return r;
753
754         *ret = m;
755         m = NULL;
756
757         return 0;
758 }
759
760 static void manager_free(Manager *m) {
761
762         if (!m)
763                 return;
764
765         sd_event_unref(m->event);
766         free(m);
767 }
768
769 int main(int argc, char *argv[]) {
770         _cleanup_manager_free_ Manager *m = NULL;
771         const char *server;
772         int r;
773
774         log_set_target(LOG_TARGET_AUTO);
775         log_parse_environment();
776         log_open();
777
778         r = manager_new(&m);
779         if (r < 0)
780                 goto out;
781
782         server = "216.239.32.15";       /* time1.google.com */
783
784         sd_notify(false, "READY=1");
785
786         r = sntp_server_connect(m, server);
787         if (r < 0)
788                 goto out;
789
790         sd_notifyf(false, "STATUS=Using Time Server: %s", server);
791
792         r = sd_event_loop(m->event);
793         if (r < 0)
794                 goto out;
795
796 out:
797         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
798 }