chiark / gitweb /
7e34e93ca62ab8503d9ee5d595090afe5f81f765
[elogind.git] / src / timedate / timedate-sntp.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 /*
23  * "Simple Network Time Protocol Version 4 (SNTPv4) is a subset of the
24  * Network Time Protocol (NTP) used to synchronize computer clocks in
25  * the Internet. SNTPv4 can be used when the ultimate performance of
26  * a full NTP implementation based on RFC 1305 is neither needed nor
27  * justified."
28  *
29  * "Unlike most NTP clients, SNTP clients normally operate with only a
30  * single server at a time."
31  *
32  * http://tools.ietf.org/html/rfc4330
33  */
34
35 #include <stdlib.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <string.h>
40 #include <time.h>
41 #include <math.h>
42 #include <arpa/inet.h>
43 #include <netinet/in.h>
44 #include <netinet/ip.h>
45 #include <sys/timerfd.h>
46 #include <sys/timex.h>
47 #include <sys/socket.h>
48
49 #include "missing.h"
50 #include "util.h"
51 #include "sparse-endian.h"
52 #include "log.h"
53 #include "sd-event.h"
54 #include "timedate-sntp.h"
55
56 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
57
58 #ifndef ADJ_SETOFFSET
59 #define ADJ_SETOFFSET                   0x0100  /* add 'time' to current time */
60 #endif
61
62 /* Maximum delta in seconds which the system clock is gradually adjusted
63  * to approach the network time. Deltas larger that this are set by letting
64  * the system time jump. The maximum for adjtime is 500ms.
65  */
66 #define NTP_MAX_ADJUST                  0.2
67
68 /*
69  * "Define the required accuracy of the system clock, then calculate the
70  * maximum timeout. Use the longest maximum timeout possible given the system
71  * constraints to minimize time server aggregate load."
72  *
73  * "A client MUST NOT under any conditions use a poll interval less
74  * than 15 seconds."
75  */
76 #define NTP_POLL_INTERVAL_MIN_SEC       16
77 #define NTP_POLL_INTERVAL_MAX_SEC       2048
78 #define NTP_ACCURACY_SEC                0.1
79
80 #define NTP_LEAP_PLUSSEC                1
81 #define NTP_LEAP_MINUSSEC               2
82 #define NTP_LEAP_NOTINSYNC              3
83 #define NTP_MODE_CLIENT                 3
84 #define NTP_MODE_SERVER                 4
85 #define NTP_FIELD_LEAP(f)               (((f) >> 6) & 3)
86 #define NTP_FIELD_VERSION(f)            (((f) >> 3) & 7)
87 #define NTP_FIELD_MODE(f)               ((f) & 7)
88 #define NTP_FIELD(l, v, m)              (((l) << 6) | ((v) << 3) | (m))
89
90 /*
91  * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
92  * in seconds relative to 0h on 1 January 1900."
93  */
94 #define OFFSET_1900_1970        2208988800UL
95
96 struct ntp_ts {
97         be32_t sec;
98         be32_t frac;
99 } _packed_;
100
101 struct ntp_ts_short {
102         be16_t sec;
103         be16_t frac;
104 } _packed_;
105
106 struct ntp_msg {
107         uint8_t field;
108         uint8_t stratum;
109         int8_t poll;
110         int8_t precision;
111         struct ntp_ts_short root_delay;
112         struct ntp_ts_short root_dispersion;
113         char refid[4];
114         struct ntp_ts reference_time;
115         struct ntp_ts origin_time;
116         struct ntp_ts recv_time;
117         struct ntp_ts trans_time;
118 } _packed_;
119
120 struct SNTPContext {
121         /* peer */
122         sd_event_source *event_receive;
123         char *server;
124         struct sockaddr_in server_addr;
125         int server_socket;
126         uint64_t packet_count;
127
128         /* last sent packet */
129         struct timespec trans_time_mon;
130         struct timespec trans_time;
131         usec_t retry_interval;
132         bool pending;
133
134         /* poll timer */
135         sd_event_source *event_timer;
136         usec_t poll_interval_usec;
137         bool poll_resync;
138
139         /* history data */
140         struct {
141                 double offset;
142                 double delay;
143         } samples[8];
144         unsigned int samples_idx;
145         double samples_jitter;
146
147         /* last change */
148         bool jumped;
149
150         /* watch for time changes */
151         sd_event_source *event_clock_watch;
152         int clock_watch_fd;
153 };
154
155 static int sntp_arm_timer(SNTPContext *sntp, usec_t next);
156 static int sntp_clock_watch_setup(SNTPContext *sntp);
157
158 static double ntp_ts_to_d(const struct ntp_ts *ts) {
159         return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
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 ts_to_d(const struct timespec *ts) {
167         return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
168 }
169
170 static void d_to_tv(double d, struct timeval *tv) {
171         tv->tv_sec = (long)d;
172         tv->tv_usec = (d - tv->tv_sec) * 1000 * 1000;
173
174         /* the kernel expects -0.3s as {-1, 7000.000} */
175         if (tv->tv_usec < 0) {
176                 tv->tv_sec  -= 1;
177                 tv->tv_usec += 1000 * 1000;
178         }
179 }
180
181 static double square(double d) {
182         return d * d;
183 }
184
185 static int sntp_send_request(SNTPContext *sntp) {
186         struct ntp_msg ntpmsg = {};
187         struct sockaddr_in addr = {};
188         ssize_t len;
189         int r;
190
191         /*
192          * "The client initializes the NTP message header, sends the request
193          * to the server, and strips the time of day from the Transmit
194          * Timestamp field of the reply.  For this purpose, all the NTP
195          * header fields are set to 0, except the Mode, VN, and optional
196          * Transmit Timestamp fields."
197          */
198         ntpmsg.field = NTP_FIELD(0, 4, NTP_MODE_CLIENT);
199
200         /*
201          * Set transmit timestamp, remember it; the server will send that back
202          * as the origin timestamp and we have an indication that this is the
203          * matching answer to our request.
204          *
205          * The actual value does not matter, We do not care about the correct
206          * NTP UINT_MAX fraction, we just pass the plain nanosecond value.
207          */
208         clock_gettime(CLOCK_MONOTONIC, &sntp->trans_time_mon);
209         clock_gettime(CLOCK_REALTIME, &sntp->trans_time);
210         ntpmsg.trans_time.sec = htobe32(sntp->trans_time.tv_sec + OFFSET_1900_1970);
211         ntpmsg.trans_time.frac = htobe32(sntp->trans_time.tv_nsec);
212
213         addr.sin_family = AF_INET;
214         addr.sin_port = htobe16(123);
215         addr.sin_addr.s_addr = inet_addr(sntp->server);
216         len = sendto(sntp->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &addr, sizeof(addr));
217         if (len == sizeof(ntpmsg)) {
218                 sntp->pending = true;
219                 log_debug("Sent NTP request to: %s", sntp->server);
220         } else
221                 log_info("Sending NTP request to %s failed: %m", sntp->server);
222
223         /* re-arm timer with incresing timeout, in case the packets never arrive back */
224         if (sntp->retry_interval > 0) {
225                 if (sntp->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
226                         sntp->retry_interval *= 2;
227         } else
228                 sntp->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
229         r = sntp_arm_timer(sntp, sntp->retry_interval);
230         if (r < 0)
231                 return r;
232
233         return 0;
234 }
235
236 static int sntp_timer(sd_event_source *source, usec_t usec, void *userdata) {
237         SNTPContext *sntp = userdata;
238
239         assert(sntp);
240
241         sntp_send_request(sntp);
242         return 0;
243 }
244
245 static int sntp_arm_timer(SNTPContext *sntp, usec_t next) {
246         sd_event *e;
247         int r;
248
249         assert(sntp);
250         assert(sntp->event_receive);
251
252         if (next == 0) {
253                 sntp->event_timer = sd_event_source_unref(sntp->event_timer);
254                 return 0;
255         }
256
257         if (sntp->event_timer) {
258                 r = sd_event_source_set_time(sntp->event_timer, now(CLOCK_MONOTONIC) + next);
259                 if (r < 0)
260                         return r;
261
262                 return sd_event_source_set_enabled(sntp->event_timer, SD_EVENT_ONESHOT);
263         }
264
265         e = sd_event_source_get_event(sntp->event_receive);
266         r = sd_event_add_monotonic(e, &sntp->event_timer, now(CLOCK_MONOTONIC) + next, 0, sntp_timer, sntp);
267         if (r < 0)
268                 return r;
269
270         return 0;
271 }
272
273 static int sntp_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
274         SNTPContext *sntp = userdata;
275
276         assert(sntp);
277         assert(sntp->event_receive);
278
279         /* rearm timer */
280         sntp_clock_watch_setup(sntp);
281
282         /* skip our own jumps */
283         if (sntp->jumped) {
284                 sntp->jumped = false;
285                 return 0;
286         }
287
288         /* resync */
289         log_info("System time changed, resyncing.");
290         sntp->poll_resync = true;
291         sntp_send_request(sntp);
292
293         return 0;
294 }
295
296 /* wake up when the system time changes underneath us */
297 static int sntp_clock_watch_setup(SNTPContext *sntp) {
298         struct itimerspec its = { .it_value.tv_sec = TIME_T_MAX };
299         _cleanup_close_ int fd = -1;
300         sd_event *e;
301         sd_event_source *source;
302         int r;
303
304         assert(sntp);
305         assert(sntp->event_receive);
306
307         fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
308         if (fd < 0) {
309                 log_error("Failed to create timerfd: %m");
310                 return -errno;
311         }
312
313         if (timerfd_settime(fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
314                 log_error("Failed to set up timerfd: %m");
315                 return -errno;
316         }
317
318         e = sd_event_source_get_event(sntp->event_receive);
319         r = sd_event_add_io(e, &source, fd, EPOLLIN, sntp_clock_watch, sntp);
320         if (r < 0) {
321                 log_error("Failed to create clock watch event source: %s", strerror(-r));
322                 return r;
323         }
324
325         sd_event_source_unref(sntp->event_clock_watch);
326         sntp->event_clock_watch = source;
327
328         if (sntp->clock_watch_fd >= 0)
329                 close(sntp->clock_watch_fd);
330         sntp->clock_watch_fd = fd;
331         fd = -1;
332
333         return 0;
334 }
335
336 static int sntp_adjust_clock(SNTPContext *sntp, double offset, int leap_sec) {
337         struct timex tmx = {};
338         int r;
339
340         /*
341          * For small deltas, tell the kernel to gradually adjust the system
342          * clock to the NTP time, larger deltas are just directly set.
343          *
344          * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
345          * syncs the system time periodically to the hardware clock.
346          */
347         if (offset < NTP_MAX_ADJUST && offset > -NTP_MAX_ADJUST) {
348                 int constant;
349
350                 constant = log2i(sntp->poll_interval_usec / USEC_PER_SEC) - 6;
351
352                 tmx.modes |= ADJ_STATUS | ADJ_OFFSET | ADJ_TIMECONST;
353                 tmx.status = STA_PLL;
354                 tmx.offset = offset * 1000 * 1000;
355                 tmx.constant = constant;
356                 log_debug("  adjust (slew): %+f sec\n", (double)tmx.offset / USEC_PER_SEC);
357         } else {
358                 tmx.modes = ADJ_SETOFFSET;
359                 d_to_tv(offset, &tmx.time);
360
361                 sntp->jumped = true;
362                 log_debug("  adjust (jump): %+f sec\n", tv_to_d(&tmx.time));
363         }
364
365         switch (leap_sec) {
366         case 1:
367                 tmx.status |= STA_INS;
368                 break;
369         case -1:
370                 tmx.status |= STA_DEL;
371                 break;
372         }
373
374         r = clock_adjtime(CLOCK_REALTIME, &tmx);
375         if (r < 0)
376                 return r;
377
378         log_debug("  status       : %04i %s\n"
379                   "  time now     : %li.%06li\n"
380                   "  constant     : %li\n"
381                   "  offset       : %+f sec\n"
382                   "  freq offset  : %+li (%+.3f ppm)\n",
383                   tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
384                   tmx.time.tv_sec, tmx.time.tv_usec,
385                   tmx.constant,
386                   (double)tmx.offset / USEC_PER_SEC,
387                   tmx.freq, (double)tmx.freq / 65536);
388
389         return 0;
390 }
391
392 static bool sntp_sample_spike_detection(SNTPContext *sntp, double offset, double delay) {
393         unsigned int i, idx_cur, idx_new, idx_min;
394         double jitter;
395         double j;
396
397         /* store the current data in our samples array */
398         idx_cur = sntp->samples_idx;
399         idx_new = (idx_cur + 1) % ELEMENTSOF(sntp->samples);
400         sntp->samples_idx = idx_new;
401         sntp->samples[idx_new].offset = offset;
402         sntp->samples[idx_new].delay = delay;
403
404         sntp->packet_count++;
405         jitter = sntp->samples_jitter;
406
407         /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
408         for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(sntp->samples); i++)
409                 if (sntp->samples[i].delay > 0 && sntp->samples[i].delay < sntp->samples[idx_min].delay)
410                         idx_min = i;
411
412         j = 0;
413         for (i = 0; i < ELEMENTSOF(sntp->samples); i++)
414                 j += square(sntp->samples[i].offset - sntp->samples[idx_min].offset);
415         sntp->samples_jitter = sqrt(j / (ELEMENTSOF(sntp->samples) - 1));
416
417         /* ignore samples when resyncing */
418         if (sntp->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 (sntp->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) > sntp->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 - sntp->samples[idx_cur].offset) > 3 * jitter;
435 }
436
437 static void sntp_adjust_poll(SNTPContext *sntp, double offset, bool spike) {
438         if (sntp->poll_resync) {
439                 sntp->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
440                 sntp->poll_resync = false;
441                 return;
442         }
443
444         /* set to minimal poll interval */
445         if (fabs(offset) > NTP_ACCURACY_SEC) {
446                 sntp->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 (sntp->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
453                         sntp->poll_interval_usec *= 2;
454                 return;
455         }
456
457         /* decrease polling interval */
458         if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
459                 if (sntp->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
460                         sntp->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         SNTPContext *sntp = 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(sntp);
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 (sntp->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 (!sntp->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) != sntp->trans_time.tv_sec + OFFSET_1900_1970||
542             be32toh(ntpmsg->origin_time.frac) != sntp->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         sntp->pending = false;
564         sntp->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 roundtrip 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(&sntp->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(sntp, offset, delay);
595
596         sntp_adjust_poll(sntp, 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    : %f sec (%d)\n"
604                   "  reference    : %.4s\n"
605                   "  origin       : %f\n"
606                   "  receive      : %f\n"
607                   "  transmit     : %f\n"
608                   "  dest         : %f\n"
609                   "  offset       : %+f sec\n"
610                   "  delay        : %+f sec\n"
611                   "  packet count : %"PRIu64"\n"
612                   "  jitter       : %f%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                   sntp->packet_count,
626                   sntp->samples_jitter, spike ? " spike" : "",
627                   sntp->poll_interval_usec / USEC_PER_SEC);
628
629         log_info("%4llu %+10f %10f %10f%s",
630                  sntp->poll_interval_usec / USEC_PER_SEC, offset, delay,
631                  sntp->samples_jitter, spike ? " spike" : "");
632
633         if (!spike) {
634                 r = sntp_adjust_clock(sntp, offset, leap_sec);
635                 if (r < 0)
636                         log_error("Failed to call clock_adjtime(): %m");
637         }
638
639         r = sntp_arm_timer(sntp, sntp->poll_interval_usec);
640         if (r < 0)
641                 return r;
642
643         return 0;
644 }
645
646 int sntp_server_connect(SNTPContext *sntp, const char *server) {
647         _cleanup_free_ char *s = NULL;
648
649         assert(sntp);
650         assert(server);
651         assert(sntp->server_socket >= 0);
652
653         s = strdup(server);
654         if (!s)
655                 return -ENOMEM;
656
657         free(sntp->server);
658         sntp->server = s;
659         s = NULL;
660
661         zero(sntp->server_addr);
662         sntp->server_addr.sin_family = AF_INET;
663         sntp->server_addr.sin_addr.s_addr = inet_addr(server);
664
665         sntp->poll_interval_usec = 2 * NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
666
667         return sntp_send_request(sntp);
668 }
669
670 void sntp_server_disconnect(SNTPContext *sntp) {
671         if (!sntp->server)
672                 return;
673
674         sntp->event_timer = sd_event_source_unref(sntp->event_timer);
675
676         sntp->event_clock_watch = sd_event_source_unref(sntp->event_clock_watch);
677         if (sntp->clock_watch_fd > 0)
678                 close(sntp->clock_watch_fd);
679         sntp->clock_watch_fd = -1;
680
681         sntp->event_receive = sd_event_source_unref(sntp->event_receive);
682         if (sntp->server_socket > 0)
683                 close(sntp->server_socket);
684         sntp->server_socket = -1;
685
686         zero(sntp->server_addr);
687         free(sntp->server);
688         sntp->server = NULL;
689 }
690
691 static int sntp_listen_setup(SNTPContext *sntp, sd_event *e) {
692         _cleanup_close_ int fd = -1;
693         struct sockaddr_in addr;
694         const int on = 1;
695         const int tos = IPTOS_LOWDELAY;
696         int r;
697
698         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
699         if (fd < 0)
700                 return -errno;
701
702         zero(addr);
703         addr.sin_family = AF_INET;
704         r = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
705         if (r < 0)
706                 return -errno;
707
708         r = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
709         if (r < 0)
710                 return -errno;
711
712         r = setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
713         if (r < 0)
714                 return -errno;
715
716         r = sd_event_add_io(e, &sntp->event_receive, fd, EPOLLIN, sntp_receive_response, sntp);
717         if (r < 0)
718                 return r;
719
720         sntp->server_socket = fd;
721         fd = -1;
722
723         return 0;
724 }
725
726 int sntp_new(SNTPContext **sntp, sd_event *e) {
727         _cleanup_free_ SNTPContext *c;
728         int r;
729
730         c = new0(SNTPContext, 1);
731         if (!c)
732                 return -ENOMEM;
733
734         r = sntp_listen_setup(c, e);
735         if (r < 0)
736                 return r;
737
738         r = sntp_clock_watch_setup(c);
739         if (r < 0)
740                 return r;
741
742         *sntp = c;
743         c = NULL;
744
745         return 0;
746 }
747
748 SNTPContext *sntp_unref(SNTPContext *sntp) {
749         sntp_server_disconnect(sntp);
750         free(sntp);
751         return NULL;
752 }