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