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