]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/timesync/timesyncd.c
build-sys: add missing makefile symlinks
[thirdparty/systemd.git] / src / timesync / timesyncd.c
CommitLineData
bcdbbd7e
KS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
e8af6973 6 Copyright 2014 Kay Sievers, Lennart Poettering
bcdbbd7e
KS
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
bcdbbd7e
KS
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>
7b415867 32#include <sys/timerfd.h>
bcdbbd7e
KS
33#include <sys/timex.h>
34#include <sys/socket.h>
05f7fc0f 35#include <resolv.h>
a349eb10
LP
36#include <sys/prctl.h>
37#include <sys/types.h>
38#include <grp.h>
bcdbbd7e 39
7b415867 40#include "missing.h"
bcdbbd7e
KS
41#include "util.h"
42#include "sparse-endian.h"
43#include "log.h"
5f8cfaee 44#include "socket-util.h"
678522cf 45#include "list.h"
7a183c4c 46#include "ratelimit.h"
881c7420 47#include "strv.h"
e8af6973 48#include "conf-parser.h"
bcdbbd7e 49#include "sd-event.h"
856a5a7d 50#include "sd-resolve.h"
687ed123 51#include "sd-daemon.h"
e0e5ce23
TG
52#include "sd-network.h"
53#include "event-util.h"
54#include "network-util.h"
d636d376 55#include "clock-util.h"
a349eb10 56#include "capability.h"
ece6e766 57#include "mkdir.h"
e8af6973 58#include "timesyncd.h"
bcdbbd7e 59
7b415867
KS
60#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
61
bcdbbd7e
KS
62#ifndef ADJ_SETOFFSET
63#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
64#endif
65
42742bf1
KS
66/* expected accuracy of time synchronization; used to adjust the poll interval */
67#define NTP_ACCURACY_SEC 0.2
bcdbbd7e
KS
68
69/*
bcdbbd7e
KS
70 * "A client MUST NOT under any conditions use a poll interval less
71 * than 15 seconds."
72 */
42742bf1 73#define NTP_POLL_INTERVAL_MIN_SEC 32
bcdbbd7e 74#define NTP_POLL_INTERVAL_MAX_SEC 2048
bcdbbd7e 75
42742bf1
KS
76/*
77 * Maximum delta in seconds which the system clock is gradually adjusted
78 * (slew) to approach the network time. Deltas larger that this are set by
79 * letting the system time jump. The kernel's limit for adjtime is 0.5s.
80 */
81#define NTP_MAX_ADJUST 0.4
82
83/* NTP protocol, packet header */
bcdbbd7e
KS
84#define NTP_LEAP_PLUSSEC 1
85#define NTP_LEAP_MINUSSEC 2
86#define NTP_LEAP_NOTINSYNC 3
87#define NTP_MODE_CLIENT 3
88#define NTP_MODE_SERVER 4
89#define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
90#define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
91#define NTP_FIELD_MODE(f) ((f) & 7)
92#define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
93
94/*
95 * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
96 * in seconds relative to 0h on 1 January 1900."
97 */
98#define OFFSET_1900_1970 2208988800UL
99
7a183c4c
LP
100#define RETRY_USEC (30*USEC_PER_SEC)
101#define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
becad8f1 102#define RATELIMIT_BURST 10
7a183c4c 103
16c058ba
LP
104#define TIMEOUT_USEC (10*USEC_PER_SEC)
105
bcdbbd7e
KS
106struct ntp_ts {
107 be32_t sec;
108 be32_t frac;
109} _packed_;
110
111struct ntp_ts_short {
112 be16_t sec;
113 be16_t frac;
114} _packed_;
115
116struct ntp_msg {
117 uint8_t field;
118 uint8_t stratum;
119 int8_t poll;
120 int8_t precision;
121 struct ntp_ts_short root_delay;
122 struct ntp_ts_short root_dispersion;
123 char refid[4];
124 struct ntp_ts reference_time;
125 struct ntp_ts origin_time;
126 struct ntp_ts recv_time;
127 struct ntp_ts trans_time;
128} _packed_;
129
687ed123
KS
130static void manager_free(Manager *m);
131DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
132#define _cleanup_manager_free_ _cleanup_(manager_freep)
133
856a5a7d
LP
134static int manager_arm_timer(Manager *m, usec_t next);
135static int manager_clock_watch_setup(Manager *m);
678522cf
LP
136static int manager_connect(Manager *m);
137static void manager_disconnect(Manager *m);
bcdbbd7e 138
d636d376
KS
139static double ntp_ts_to_d(const struct ntp_ts *ts) {
140 return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
141}
142
143static double ts_to_d(const struct timespec *ts) {
144 return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
145}
146
147static double tv_to_d(const struct timeval *tv) {
148 return tv->tv_sec + (1.0e-6 * tv->tv_usec);
149}
150
151static double square(double d) {
152 return d * d;
153}
154
155static int load_clock_timestamp(uid_t uid, gid_t gid) {
ece6e766 156 _cleanup_close_ int fd = -1;
d636d376
KS
157 usec_t min = TIME_EPOCH * USEC_PER_SEC;
158 usec_t ct;
159 int r;
ece6e766
LP
160
161 /* Let's try to make sure that the clock is always
162 * monotonically increasing, by saving the clock whenever we
163 * have a new NTP time, or when we shut down, and restoring it
164 * when we start again. This is particularly helpful on
165 * systems lacking a battery backed RTC. We also will adjust
166 * the time to at least the build time of systemd. */
167
d636d376
KS
168 fd = open("/var/lib/systemd/clock", O_RDWR|O_CLOEXEC, 0644);
169 if (fd >= 0) {
ece6e766 170 struct stat st;
d636d376
KS
171 usec_t stamp;
172
173 /* check if the recorded time is later than the compiled-in one */
174 r = fstat(fd, &st);
175 if (r >= 0) {
176 stamp = timespec_load(&st.st_mtim);
177 if (stamp > min)
178 min = stamp;
ece6e766
LP
179 }
180
d636d376
KS
181 /* Try to fix the access mode, so that we can still
182 touch the file after dropping priviliges */
183 fchmod(fd, 0644);
184 fchown(fd, uid, gid);
185
186 } else
187 /* create stamp file with the compiled-in date */
188 touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644);
ece6e766
LP
189
190 ct = now(CLOCK_REALTIME);
d636d376 191 if (ct < min) {
ece6e766 192 struct timespec ts;
d636d376 193 char date[FORMAT_TIMESTAMP_MAX];
ece6e766 194
d636d376
KS
195 log_info("System clock time unset or jumped backwards, restoring from recorded timestamp: %s",
196 format_timestamp(date, sizeof(date), min));
ece6e766 197
d636d376
KS
198 if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, min)) < 0)
199 log_error("Failed to restore system clock: %m");
ece6e766
LP
200 }
201
202 return 0;
203}
204
16c058ba
LP
205static int manager_timeout(sd_event_source *source, usec_t usec, void *userdata) {
206 _cleanup_free_ char *pretty = NULL;
207 Manager *m = userdata;
208
209 assert(m);
210 assert(m->current_server_name);
211 assert(m->current_server_address);
212
ae2db4e7 213 server_address_pretty(m->current_server_address, &pretty);
16c058ba
LP
214 log_info("Timed out waiting for reply from %s (%s).", strna(pretty), m->current_server_name->string);
215
216 return manager_connect(m);
217}
218
856a5a7d 219static int manager_send_request(Manager *m) {
678522cf 220 _cleanup_free_ char *pretty = NULL;
5f8cfaee
LP
221 struct ntp_msg ntpmsg = {
222 /*
223 * "The client initializes the NTP message header, sends the request
224 * to the server, and strips the time of day from the Transmit
225 * Timestamp field of the reply. For this purpose, all the NTP
226 * header fields are set to 0, except the Mode, VN, and optional
227 * Transmit Timestamp fields."
228 */
229 .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
230 };
bcdbbd7e 231 ssize_t len;
678522cf
LP
232 int r;
233
234 assert(m);
235 assert(m->current_server_name);
236 assert(m->current_server_address);
bcdbbd7e 237
16c058ba
LP
238 m->event_timeout = sd_event_source_unref(m->event_timeout);
239
bcdbbd7e
KS
240 /*
241 * Set transmit timestamp, remember it; the server will send that back
242 * as the origin timestamp and we have an indication that this is the
243 * matching answer to our request.
244 *
245 * The actual value does not matter, We do not care about the correct
07a062a7 246 * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
bcdbbd7e 247 */
6a5c7b7e 248 assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0);
856a5a7d 249 assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
687ed123
KS
250 ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
251 ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
bcdbbd7e 252
ae2db4e7 253 server_address_pretty(m->current_server_address, &pretty);
678522cf
LP
254
255 len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
7b415867 256 if (len == sizeof(ntpmsg)) {
687ed123 257 m->pending = true;
16c058ba 258 log_debug("Sent NTP request to %s (%s).", strna(pretty), m->current_server_name->string);
becad8f1 259 } else {
16c058ba 260 log_debug("Sending NTP request to %s (%s) failed: %m", strna(pretty), m->current_server_name->string);
becad8f1
LP
261 return manager_connect(m);
262 }
7b415867 263
15a224e0 264 /* re-arm timer with increasing timeout, in case the packets never arrive back */
687ed123
KS
265 if (m->retry_interval > 0) {
266 if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
267 m->retry_interval *= 2;
7b415867 268 } else
687ed123 269 m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
bcdbbd7e 270
678522cf
LP
271 r = manager_arm_timer(m, m->retry_interval);
272 if (r < 0) {
273 log_error("Failed to rearm timer: %s", strerror(-r));
274 return r;
275 }
276
16c058ba
LP
277 r = sd_event_add_time(
278 m->event,
279 &m->event_timeout,
6a5c7b7e
LP
280 clock_boottime_or_monotonic(),
281 now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
16c058ba
LP
282 manager_timeout, m);
283 if (r < 0) {
284 log_error("Failed to arm timeout timer: %s", strerror(-r));
285 return r;
286 }
287
678522cf 288 return 0;
bcdbbd7e
KS
289}
290
856a5a7d 291static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
687ed123 292 Manager *m = userdata;
bcdbbd7e 293
687ed123 294 assert(m);
bcdbbd7e 295
856a5a7d 296 return manager_send_request(m);
bcdbbd7e
KS
297}
298
856a5a7d 299static int manager_arm_timer(Manager *m, usec_t next) {
bcdbbd7e
KS
300 int r;
301
687ed123
KS
302 assert(m);
303 assert(m->event_receive);
bcdbbd7e 304
7b415867 305 if (next == 0) {
687ed123 306 m->event_timer = sd_event_source_unref(m->event_timer);
bcdbbd7e
KS
307 return 0;
308 }
309
687ed123 310 if (m->event_timer) {
6a5c7b7e 311 r = sd_event_source_set_time(m->event_timer, now(clock_boottime_or_monotonic()) + next);
bcdbbd7e
KS
312 if (r < 0)
313 return r;
314
687ed123 315 return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
bcdbbd7e
KS
316 }
317
856a5a7d 318 return sd_event_add_time(
687ed123
KS
319 m->event,
320 &m->event_timer,
6a5c7b7e
LP
321 clock_boottime_or_monotonic(),
322 now(clock_boottime_or_monotonic()) + next, 0,
856a5a7d 323 manager_timer, m);
bcdbbd7e
KS
324}
325
856a5a7d 326static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
687ed123 327 Manager *m = userdata;
7b415867 328
687ed123 329 assert(m);
7b415867
KS
330
331 /* rearm timer */
856a5a7d 332 manager_clock_watch_setup(m);
7b415867
KS
333
334 /* skip our own jumps */
687ed123
KS
335 if (m->jumped) {
336 m->jumped = false;
7b415867
KS
337 return 0;
338 }
339
340 /* resync */
07a062a7 341 log_info("System time changed. Resyncing.");
687ed123 342 m->poll_resync = true;
856a5a7d 343 return manager_send_request(m);
7b415867
KS
344}
345
346/* wake up when the system time changes underneath us */
856a5a7d 347static int manager_clock_watch_setup(Manager *m) {
5f8cfaee
LP
348
349 struct itimerspec its = {
350 .it_value.tv_sec = TIME_T_MAX
351 };
352
7b415867
KS
353 int r;
354
687ed123 355 assert(m);
7b415867 356
856a5a7d 357 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
376cd3b8 358 safe_close(m->clock_watch_fd);
856a5a7d
LP
359
360 m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
361 if (m->clock_watch_fd < 0) {
7b415867
KS
362 log_error("Failed to create timerfd: %m");
363 return -errno;
364 }
365
856a5a7d 366 if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
7b415867
KS
367 log_error("Failed to set up timerfd: %m");
368 return -errno;
369 }
370
856a5a7d 371 r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
7b415867
KS
372 if (r < 0) {
373 log_error("Failed to create clock watch event source: %s", strerror(-r));
374 return r;
375 }
376
7b415867
KS
377 return 0;
378}
379
856a5a7d 380static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
bcdbbd7e
KS
381 struct timex tmx = {};
382 int r;
383
856a5a7d
LP
384 assert(m);
385
bcdbbd7e
KS
386 /*
387 * For small deltas, tell the kernel to gradually adjust the system
388 * clock to the NTP time, larger deltas are just directly set.
bcdbbd7e 389 */
687ed123 390 if (fabs(offset) < NTP_MAX_ADJUST) {
d67006fe 391 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
bcdbbd7e 392 tmx.status = STA_PLL;
d67006fe
KS
393 tmx.offset = offset * NSEC_PER_SEC;
394 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
12c0d47c
KS
395 tmx.maxerror = 0;
396 tmx.esterror = 0;
d67006fe 397 log_debug(" adjust (slew): %+.3f sec\n", offset);
bcdbbd7e 398 } else {
c264aeab 399 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET;
d67006fe
KS
400
401 /* ADJ_NANO uses nanoseconds in the microseconds field */
402 tmx.time.tv_sec = (long)offset;
403 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
404
405 /* the kernel expects -0.3s as {-1, 7000.000.000} */
406 if (tmx.time.tv_usec < 0) {
ef619194 407 tmx.time.tv_sec -= 1;
d67006fe
KS
408 tmx.time.tv_usec += NSEC_PER_SEC;
409 }
7b415867 410
687ed123 411 m->jumped = true;
d67006fe 412 log_debug(" adjust (jump): %+.3f sec\n", offset);
bcdbbd7e
KS
413 }
414
c264aeab
KS
415 /*
416 * An unset STA_UNSYNC will enable the kernel's 11-minute mode,
417 * which syncs the system time periodically to the RTC.
418 *
419 * In case the RTC runs in local time, never touch the RTC,
420 * we have no way to properly handle daylight saving changes and
421 * mobile devices moving between time zones.
422 */
423 if (m->rtc_local_time)
424 tmx.status |= STA_UNSYNC;
425
bcdbbd7e
KS
426 switch (leap_sec) {
427 case 1:
428 tmx.status |= STA_INS;
429 break;
430 case -1:
431 tmx.status |= STA_DEL;
432 break;
433 }
434
81c36b3f 435 r = clock_adjtime(CLOCK_REALTIME, &tmx);
bcdbbd7e
KS
436 if (r < 0)
437 return r;
438
d636d376
KS
439 touch("/var/lib/systemd/clock");
440
ef619194
KS
441 m->drift_ppm = tmx.freq / 65536;
442
bcdbbd7e 443 log_debug(" status : %04i %s\n"
609e002e 444 " time now : %li.%03llu\n"
bcdbbd7e 445 " constant : %li\n"
ba9f11dc 446 " offset : %+.3f sec\n"
d67006fe 447 " freq offset : %+li (%i ppm)\n",
c264aeab 448 tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
609e002e 449 tmx.time.tv_sec, (unsigned long long) (tmx.time.tv_usec / NSEC_PER_MSEC),
bcdbbd7e 450 tmx.constant,
d67006fe 451 (double)tmx.offset / NSEC_PER_SEC,
ef619194 452 tmx.freq, m->drift_ppm);
bcdbbd7e
KS
453
454 return 0;
455}
456
856a5a7d 457static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
bcdbbd7e
KS
458 unsigned int i, idx_cur, idx_new, idx_min;
459 double jitter;
3dbc7620 460 double j;
bcdbbd7e 461
856a5a7d
LP
462 assert(m);
463
687ed123 464 m->packet_count++;
d8c21348
KS
465
466 /* ignore initial sample */
687ed123 467 if (m->packet_count == 1)
d8c21348
KS
468 return false;
469
bcdbbd7e 470 /* store the current data in our samples array */
687ed123
KS
471 idx_cur = m->samples_idx;
472 idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
473 m->samples_idx = idx_new;
474 m->samples[idx_new].offset = offset;
475 m->samples[idx_new].delay = delay;
bcdbbd7e 476
bcdbbd7e 477 /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
687ed123
KS
478 jitter = m->samples_jitter;
479 for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
480 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
bcdbbd7e
KS
481 idx_min = i;
482
3dbc7620 483 j = 0;
687ed123
KS
484 for (i = 0; i < ELEMENTSOF(m->samples); i++)
485 j += square(m->samples[i].offset - m->samples[idx_min].offset);
486 m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
bcdbbd7e 487
a47b9e62 488 /* ignore samples when resyncing */
687ed123 489 if (m->poll_resync)
a47b9e62
KS
490 return false;
491
492 /* always accept offset if we are farther off than the round-trip delay */
493 if (fabs(offset) > delay)
494 return false;
495
496 /* we need a few samples before looking at them */
687ed123 497 if (m->packet_count < 4)
a47b9e62
KS
498 return false;
499
3dbc7620 500 /* do not accept anything worse than the maximum possible error of the best sample */
687ed123 501 if (fabs(offset) > m->samples[idx_min].delay)
3dbc7620
KS
502 return true;
503
504 /* compare the difference between the current offset to the previous offset and jitter */
687ed123 505 return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
bcdbbd7e
KS
506}
507
856a5a7d
LP
508static void manager_adjust_poll(Manager *m, double offset, bool spike) {
509 assert(m);
510
687ed123
KS
511 if (m->poll_resync) {
512 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
513 m->poll_resync = false;
7b415867
KS
514 return;
515 }
516
bcdbbd7e 517 /* set to minimal poll interval */
18bb8adb 518 if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
687ed123 519 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
bcdbbd7e
KS
520 return;
521 }
522
523 /* increase polling interval */
3dbc7620 524 if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
687ed123
KS
525 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
526 m->poll_interval_usec *= 2;
bcdbbd7e
KS
527 return;
528 }
529
530 /* decrease polling interval */
3dbc7620 531 if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
687ed123
KS
532 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
533 m->poll_interval_usec /= 2;
bcdbbd7e
KS
534 return;
535 }
536}
537
856a5a7d
LP
538static bool sockaddr_equal(union sockaddr_union *a, union sockaddr_union *b) {
539 assert(a);
540 assert(b);
541
542 if (a->sa.sa_family != b->sa.sa_family)
543 return false;
544
545 if (a->sa.sa_family == AF_INET)
546 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
547
548 if (a->sa.sa_family == AF_INET6)
549 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
550
551 return false;
552}
553
554static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
687ed123 555 Manager *m = userdata;
856a5a7d
LP
556 struct ntp_msg ntpmsg;
557
bcdbbd7e 558 struct iovec iov = {
856a5a7d
LP
559 .iov_base = &ntpmsg,
560 .iov_len = sizeof(ntpmsg),
bcdbbd7e
KS
561 };
562 union {
563 struct cmsghdr cmsghdr;
564 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
565 } control;
5f8cfaee 566 union sockaddr_union server_addr;
bcdbbd7e
KS
567 struct msghdr msghdr = {
568 .msg_iov = &iov,
569 .msg_iovlen = 1,
570 .msg_control = &control,
571 .msg_controllen = sizeof(control),
572 .msg_name = &server_addr,
573 .msg_namelen = sizeof(server_addr),
574 };
575 struct cmsghdr *cmsg;
3dbc7620 576 struct timespec now_ts;
bcdbbd7e
KS
577 struct timeval *recv_time;
578 ssize_t len;
d2d66d1c 579 double origin, receive, trans, dest;
bcdbbd7e
KS
580 double delay, offset;
581 bool spike;
582 int leap_sec;
583 int r;
584
678522cf
LP
585 assert(source);
586 assert(m);
587
bcdbbd7e 588 if (revents & (EPOLLHUP|EPOLLERR)) {
678522cf
LP
589 log_warning("Server connection returned error.");
590 return manager_connect(m);
bcdbbd7e
KS
591 }
592
593 len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
594 if (len < 0) {
856a5a7d
LP
595 if (errno == EAGAIN)
596 return 0;
597
678522cf
LP
598 log_warning("Error receiving message. Disconnecting.");
599 return manager_connect(m);
bcdbbd7e
KS
600 }
601
602 if (iov.iov_len < sizeof(struct ntp_msg)) {
678522cf
LP
603 log_warning("Invalid response from server. Disconnecting.");
604 return manager_connect(m);
bcdbbd7e
KS
605 }
606
678522cf
LP
607 if (!m->current_server_name ||
608 !m->current_server_address ||
609 !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
610 log_debug("Response from unknown server.");
611 return 0;
bcdbbd7e
KS
612 }
613
614 recv_time = NULL;
615 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
616 if (cmsg->cmsg_level != SOL_SOCKET)
617 continue;
618
619 switch (cmsg->cmsg_type) {
620 case SCM_TIMESTAMP:
621 recv_time = (struct timeval *) CMSG_DATA(cmsg);
622 break;
623 }
624 }
625 if (!recv_time) {
678522cf 626 log_error("Invalid packet timestamp.");
bcdbbd7e
KS
627 return -EINVAL;
628 }
629
687ed123 630 if (!m->pending) {
07a062a7 631 log_debug("Unexpected reply. Ignoring.");
bcdbbd7e
KS
632 return 0;
633 }
bcdbbd7e
KS
634
635 /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
856a5a7d
LP
636 if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
637 be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
07a062a7 638 log_debug("Invalid reply; not our transmit time. Ignoring.");
bcdbbd7e
KS
639 return 0;
640 }
641
16c058ba
LP
642 m->event_timeout = sd_event_source_unref(m->event_timeout);
643
661278ee
LP
644 if (be32toh(ntpmsg.recv_time.sec) < TIME_EPOCH + OFFSET_1900_1970 ||
645 be32toh(ntpmsg.trans_time.sec) < TIME_EPOCH + OFFSET_1900_1970) {
646 log_debug("Invalid reply, returned times before epoch. Ignoring.");
647 return manager_connect(m);
648 }
649
856a5a7d 650 if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
07a062a7 651 log_debug("Server is not synchronized. Disconnecting.");
678522cf 652 return manager_connect(m);
bcdbbd7e
KS
653 }
654
661278ee 655 if (!IN_SET(NTP_FIELD_VERSION(ntpmsg.field), 3, 4)) {
856a5a7d 656 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
678522cf 657 return manager_connect(m);
bcdbbd7e
KS
658 }
659
856a5a7d
LP
660 if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
661 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
678522cf 662 return manager_connect(m);
bcdbbd7e
KS
663 }
664
7b415867 665 /* valid packet */
687ed123
KS
666 m->pending = false;
667 m->retry_interval = 0;
7b415867 668
bcdbbd7e 669 /* announce leap seconds */
856a5a7d 670 if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
bcdbbd7e 671 leap_sec = 1;
856a5a7d 672 else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
bcdbbd7e
KS
673 leap_sec = -1;
674 else
675 leap_sec = 0;
676
677 /*
678 * "Timestamp Name ID When Generated
679 * ------------------------------------------------------------
680 * Originate Timestamp T1 time request sent by client
681 * Receive Timestamp T2 time request received by server
682 * Transmit Timestamp T3 time reply sent by server
683 * Destination Timestamp T4 time reply received by client
684 *
07a062a7 685 * The round-trip delay, d, and system clock offset, t, are defined as:
bcdbbd7e
KS
686 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
687 */
6a5c7b7e 688 assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
687ed123 689 origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
856a5a7d
LP
690 receive = ntp_ts_to_d(&ntpmsg.recv_time);
691 trans = ntp_ts_to_d(&ntpmsg.trans_time);
bcdbbd7e
KS
692 dest = tv_to_d(recv_time) + OFFSET_1900_1970;
693
d2d66d1c
KS
694 offset = ((receive - origin) + (trans - dest)) / 2;
695 delay = (dest - origin) - (trans - receive);
bcdbbd7e 696
856a5a7d 697 spike = manager_sample_spike_detection(m, offset, delay);
bcdbbd7e 698
856a5a7d 699 manager_adjust_poll(m, offset, spike);
bcdbbd7e
KS
700
701 log_debug("NTP response:\n"
702 " leap : %u\n"
703 " version : %u\n"
704 " mode : %u\n"
705 " stratum : %u\n"
d67006fe 706 " precision : %.6f sec (%d)\n"
bcdbbd7e 707 " reference : %.4s\n"
ba9f11dc
KS
708 " origin : %.3f\n"
709 " receive : %.3f\n"
710 " transmit : %.3f\n"
711 " dest : %.3f\n"
712 " offset : %+.3f sec\n"
713 " delay : %+.3f sec\n"
8fe90522 714 " packet count : %"PRIu64"\n"
ba9f11dc 715 " jitter : %.3f%s\n"
609e002e 716 " poll interval: " USEC_FMT "\n",
856a5a7d
LP
717 NTP_FIELD_LEAP(ntpmsg.field),
718 NTP_FIELD_VERSION(ntpmsg.field),
719 NTP_FIELD_MODE(ntpmsg.field),
720 ntpmsg.stratum,
721 exp2(ntpmsg.precision), ntpmsg.precision,
722 ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
bcdbbd7e 723 origin - OFFSET_1900_1970,
d2d66d1c 724 receive - OFFSET_1900_1970,
bcdbbd7e
KS
725 trans - OFFSET_1900_1970,
726 dest - OFFSET_1900_1970,
727 offset, delay,
687ed123
KS
728 m->packet_count,
729 m->samples_jitter, spike ? " spike" : "",
730 m->poll_interval_usec / USEC_PER_SEC);
bcdbbd7e 731
bcdbbd7e 732 if (!spike) {
d636d376 733 m->sync = true;
856a5a7d 734 r = manager_adjust_clock(m, offset, leap_sec);
bcdbbd7e
KS
735 if (r < 0)
736 log_error("Failed to call clock_adjtime(): %m");
737 }
738
609e002e 739 log_info("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s",
08937720 740 m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
ef619194 741 spike ? " (ignored)" : "");
bcdbbd7e 742
678522cf
LP
743 r = manager_arm_timer(m, m->poll_interval_usec);
744 if (r < 0) {
745 log_error("Failed to rearm timer: %s", strerror(-r));
746 return r;
747 }
748
749 return 0;
bcdbbd7e
KS
750}
751
856a5a7d
LP
752static int manager_listen_setup(Manager *m) {
753 union sockaddr_union addr = {};
754 static const int tos = IPTOS_LOWDELAY;
755 static const int on = 1;
756 int r;
bcdbbd7e 757
687ed123 758 assert(m);
bcdbbd7e 759
856a5a7d
LP
760 assert(m->server_socket < 0);
761 assert(!m->event_receive);
678522cf 762 assert(m->current_server_address);
bcdbbd7e 763
678522cf 764 addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
bcdbbd7e 765
856a5a7d
LP
766 m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
767 if (m->server_socket < 0)
768 return -errno;
bcdbbd7e 769
678522cf 770 r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
856a5a7d
LP
771 if (r < 0)
772 return -errno;
773
774 r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
775 if (r < 0)
776 return -errno;
777
778 setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
bcdbbd7e 779
856a5a7d 780 return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
bcdbbd7e
KS
781}
782
678522cf 783static int manager_begin(Manager *m) {
856a5a7d 784 _cleanup_free_ char *pretty = NULL;
856a5a7d 785 int r;
bcdbbd7e 786
856a5a7d 787 assert(m);
678522cf
LP
788 assert_return(m->current_server_name, -EHOSTUNREACH);
789 assert_return(m->current_server_address, -EHOSTUNREACH);
7b415867 790
678522cf 791 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
856a5a7d 792
ae2db4e7 793 server_address_pretty(m->current_server_address, &pretty);
16c058ba
LP
794 log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
795 sd_notifyf(false, "STATUS=Using Time Server %s (%s).", strna(pretty), m->current_server_name->string);
856a5a7d
LP
796
797 r = manager_listen_setup(m);
798 if (r < 0) {
799 log_warning("Failed to setup connection socket: %s", strerror(-r));
800 return r;
801 }
802
803 r = manager_clock_watch_setup(m);
678522cf 804 if (r < 0)
856a5a7d 805 return r;
856a5a7d
LP
806
807 return manager_send_request(m);
bcdbbd7e
KS
808}
809
678522cf
LP
810static void server_name_flush_addresses(ServerName *n) {
811 ServerAddress *a;
812
813 assert(n);
814
815 while ((a = n->addresses)) {
816 LIST_REMOVE(addresses, n->addresses, a);
817 free(a);
818 }
819}
820
821static void manager_flush_names(Manager *m) {
822 ServerName *n;
823
824 assert(m);
825
826 while ((n = m->servers)) {
827 LIST_REMOVE(names, m->servers, n);
828 free(n->string);
829 server_name_flush_addresses(n);
830 free(n);
831 }
832}
833
834static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
835 Manager *m = userdata;
836 ServerAddress *a, *last = NULL;
837
838 assert(q);
839 assert(m);
840 assert(m->current_server_name);
841
842 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
843
844 if (ret != 0) {
4d40d39c 845 log_debug("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
678522cf
LP
846
847 /* Try next host */
848 return manager_connect(m);
849 }
850
851 server_name_flush_addresses(m->current_server_name);
852
853 for (; ai; ai = ai->ai_next) {
854 _cleanup_free_ char *pretty = NULL;
855
856 assert(ai->ai_addr);
857 assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
858 assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
859
860 if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
861 log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
862 continue;
863 }
864
865 a = new0(ServerAddress, 1);
866 if (!a)
867 return log_oom();
868
869 memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
870 a->socklen = ai->ai_addrlen;
871
872 LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
873 last = a;
874
875 sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
16c058ba 876 log_debug("Resolved address %s for %s.", pretty, m->current_server_name->string);
678522cf
LP
877 }
878
879 if (!m->current_server_name->addresses) {
880 log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
881
882 /* Try next host */
883 return manager_connect(m);
884 }
885
886 m->current_server_address = m->current_server_name->addresses;
887
888 return manager_begin(m);
889}
890
7a183c4c
LP
891static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
892 Manager *m = userdata;
893
894 assert(m);
895
896 return manager_connect(m);
897}
898
678522cf 899static int manager_connect(Manager *m) {
5f8cfaee 900
856a5a7d
LP
901 struct addrinfo hints = {
902 .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
903 .ai_socktype = SOCK_DGRAM,
5f8cfaee 904 };
678522cf 905 int r;
5f8cfaee 906
856a5a7d 907 assert(m);
bcdbbd7e 908
678522cf
LP
909 manager_disconnect(m);
910
7a183c4c
LP
911 m->event_retry = sd_event_source_unref(m->event_retry);
912 if (!ratelimit_test(&m->ratelimit)) {
913 log_debug("Slowing down attempts to contact servers.");
914
6a5c7b7e 915 r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry, m);
7a183c4c
LP
916 if (r < 0) {
917 log_error("Failed to create retry timer: %s", strerror(-r));
918 return r;
919 }
920
921 return 0;
922 }
923
678522cf
LP
924 /* If we already are operating on some address, switch to the
925 * next one. */
926 if (m->current_server_address && m->current_server_address->addresses_next)
927 m->current_server_address = m->current_server_address->addresses_next;
928 else {
929 /* Hmm, we are through all addresses, let's look for the next host instead */
930 m->current_server_address = NULL;
931
932 if (m->current_server_name && m->current_server_name->names_next)
933 m->current_server_name = m->current_server_name->names_next;
934 else {
935 if (!m->servers) {
936 m->current_server_name = NULL;
937 log_debug("No server found.");
938 return 0;
939 }
940
941 m->current_server_name = m->servers;
942 }
943
05f7fc0f
LP
944 /* Tell the resolver to reread /etc/resolv.conf, in
945 * case it changed. */
946 res_init();
947
678522cf
LP
948 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
949 if (r < 0) {
950 log_error("Failed to create resolver: %s", strerror(-r));
951 return r;
952 }
953
954 return 1;
955 }
956
957 r = manager_begin(m);
958 if (r < 0)
959 return r;
960
961 return 1;
962}
963
964static int manager_add_server(Manager *m, const char *server) {
60080921 965 ServerName *n, *tail;
678522cf
LP
966
967 assert(m);
968 assert(server);
bcdbbd7e 969
678522cf
LP
970 n = new0(ServerName, 1);
971 if (!n)
856a5a7d 972 return -ENOMEM;
bcdbbd7e 973
678522cf
LP
974 n->string = strdup(server);
975 if (!n->string) {
976 free(n);
977 return -ENOMEM;
978 }
bcdbbd7e 979
376cd3b8
LP
980 LIST_FIND_TAIL(names, m->servers, tail);
981 LIST_INSERT_AFTER(names, m->servers, tail, n);
60080921 982
678522cf 983 return 0;
856a5a7d 984}
bcdbbd7e 985
e8af6973 986static int manager_add_server_string(Manager *m, const char *string) {
a2a5291b 987 const char *word, *state;
e8af6973
LP
988 size_t l;
989 int r;
990
991 assert(m);
992 assert(string);
993
a2a5291b 994 FOREACH_WORD_QUOTED(word, l, string, state) {
e8af6973
LP
995 char t[l+1];
996
a2a5291b 997 memcpy(t, word, l);
e8af6973
LP
998 t[l] = 0;
999
1000 r = manager_add_server(m, t);
1001 if (r < 0)
1002 log_error("Failed to add server %s to configuration, ignoring: %s", t, strerror(-r));
1003 }
b2fadec6
ZJS
1004 if (!isempty(state))
1005 log_warning("Trailing garbage at the end of server list, ignoring.");
e8af6973
LP
1006
1007 return 0;
1008}
1009
856a5a7d
LP
1010static void manager_disconnect(Manager *m) {
1011 assert(m);
bcdbbd7e 1012
856a5a7d 1013 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
bcdbbd7e 1014
856a5a7d
LP
1015 m->event_timer = sd_event_source_unref(m->event_timer);
1016
1017 m->event_receive = sd_event_source_unref(m->event_receive);
1018 m->server_socket = safe_close(m->server_socket);
1019
856a5a7d
LP
1020 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
1021 m->clock_watch_fd = safe_close(m->clock_watch_fd);
16c058ba
LP
1022
1023 m->event_timeout = sd_event_source_unref(m->event_timeout);
1024
1025 sd_notifyf(false, "STATUS=Idle.");
7b415867
KS
1026}
1027
687ed123
KS
1028static int manager_new(Manager **ret) {
1029 _cleanup_manager_free_ Manager *m = NULL;
7b415867
KS
1030 int r;
1031
c92e531c
LP
1032 assert(ret);
1033
687ed123
KS
1034 m = new0(Manager, 1);
1035 if (!m)
7b415867
KS
1036 return -ENOMEM;
1037
856a5a7d
LP
1038 m->server_socket = m->clock_watch_fd = -1;
1039
7a183c4c
LP
1040 RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
1041
687ed123 1042 r = sd_event_default(&m->event);
7b415867
KS
1043 if (r < 0)
1044 return r;
1045
9f711549
LP
1046 sd_event_set_watchdog(m->event, true);
1047
f864fd1b
LP
1048 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
1049 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
856a5a7d
LP
1050
1051 r = sd_resolve_default(&m->resolve);
7b415867
KS
1052 if (r < 0)
1053 return r;
1054
856a5a7d
LP
1055 r = sd_resolve_attach_event(m->resolve, m->event, 0);
1056 if (r < 0)
59a9fce4 1057 return r;
856a5a7d 1058
687ed123
KS
1059 *ret = m;
1060 m = NULL;
bcdbbd7e
KS
1061
1062 return 0;
1063}
1064
687ed123 1065static void manager_free(Manager *m) {
687ed123
KS
1066 if (!m)
1067 return;
1068
856a5a7d 1069 manager_disconnect(m);
678522cf 1070 manager_flush_names(m);
856a5a7d 1071
7a183c4c
LP
1072 sd_event_source_unref(m->event_retry);
1073
e0e5ce23
TG
1074 sd_event_source_unref(m->network_event_source);
1075 sd_network_monitor_unref(m->network_monitor);
1076
856a5a7d 1077 sd_resolve_unref(m->resolve);
687ed123 1078 sd_event_unref(m->event);
856a5a7d 1079
687ed123
KS
1080 free(m);
1081}
1082
e8af6973
LP
1083int config_parse_servers(
1084 const char *unit,
1085 const char *filename,
1086 unsigned line,
1087 const char *section,
1088 unsigned section_line,
1089 const char *lvalue,
1090 int ltype,
1091 const char *rvalue,
1092 void *data,
1093 void *userdata) {
1094
1095 Manager *m = userdata;
1096
1097 assert(filename);
1098 assert(lvalue);
1099 assert(rvalue);
1100
1101 manager_flush_names(m);
1102 manager_add_server_string(m, rvalue);
1103
1104 return 0;
1105}
1106
1107static int manager_parse_config_file(Manager *m) {
36f822c4
ZJS
1108 return config_parse(NULL, "/etc/systemd/timesyncd.conf", NULL,
1109 "Time\0",
1110 config_item_perf_lookup, timesyncd_gperf_lookup,
1111 false, false, true, m);
e8af6973
LP
1112}
1113
e0e5ce23 1114static bool network_is_online(void) {
9b3310b0
TG
1115 _cleanup_free_ char *state = NULL;
1116 int r;
e0e5ce23 1117
9b3310b0 1118 r = sd_network_get_operational_state(&state);
a6cb8f87 1119 if (r >= 0 && STR_IN_SET(state, "routable", "degraded"))
9b3310b0 1120 return true;
a6cb8f87
KS
1121
1122 return false;
e0e5ce23
TG
1123}
1124
1125static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t revents,
1126 void *userdata) {
1127 Manager *m = userdata;
1128 bool connected, online;
1129 int r;
1130
1131 assert(m);
1132
1133 /* check if the machine is online */
1134 online = network_is_online();
1135
1136 /* check if the client is currently connected */
1137 connected = (m->server_socket != -1);
1138
1139 if (connected && !online) {
4d40d39c 1140 log_info("No network connectivity, watching for changes.");
e0e5ce23
TG
1141 manager_disconnect(m);
1142 } else if (!connected && online) {
4d40d39c 1143 log_info("Network configuration changed, trying to establish connection.");
e0e5ce23
TG
1144 if (m->current_server_address) {
1145 r = manager_begin(m);
1146 if (r < 0)
1147 return r;
1148 } else {
1149 r = manager_connect(m);
1150 if (r < 0)
1151 return r;
1152 }
1153 }
1154
1155 sd_network_monitor_flush(m->network_monitor);
1156
1157 return 0;
1158}
1159
1160static int manager_network_monitor_listen(Manager *m) {
1161 _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
1162 _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
1163 int r, fd, events;
1164
0014a4ad 1165 r = sd_network_monitor_new(&monitor, NULL);
e0e5ce23
TG
1166 if (r < 0)
1167 return r;
1168
1169 fd = sd_network_monitor_get_fd(monitor);
1170 if (fd < 0)
1171 return fd;
1172
1173 events = sd_network_monitor_get_events(monitor);
1174 if (events < 0)
1175 return events;
1176
1177 r = sd_event_add_io(m->event, &event_source, fd, events,
1178 &manager_network_event_handler, m);
1179 if (r < 0)
1180 return r;
1181
1182 m->network_monitor = monitor;
1183 m->network_event_source = event_source;
1184 monitor = NULL;
1185 event_source = NULL;
1186
1187 return 0;
1188}
1189
687ed123 1190int main(int argc, char *argv[]) {
ece6e766 1191 const char *user = "systemd-timesync";
687ed123 1192 _cleanup_manager_free_ Manager *m = NULL;
ece6e766
LP
1193 uid_t uid;
1194 gid_t gid;
687ed123
KS
1195 int r;
1196
e8af6973
LP
1197 if (argc > 1) {
1198 log_error("This program does not take arguments.");
1199 return EXIT_FAILURE;
1200 }
1201
687ed123 1202 log_set_target(LOG_TARGET_AUTO);
e8af6973 1203 log_set_facility(LOG_CRON);
687ed123
KS
1204 log_parse_environment();
1205 log_open();
1206
e8af6973
LP
1207 umask(0022);
1208
ece6e766
LP
1209 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
1210 if (r < 0) {
1211 log_error("Cannot resolve user name %s: %s", user, strerror(-r));
1212 return r;
1213 }
1214
d636d376 1215 r = load_clock_timestamp(uid, gid);
ece6e766
LP
1216 if (r < 0)
1217 goto out;
1218
966bff26 1219 r = drop_privileges(uid, gid, (1ULL << CAP_SYS_TIME));
a349eb10
LP
1220 if (r < 0)
1221 goto out;
1222
856a5a7d
LP
1223 assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
1224
687ed123 1225 r = manager_new(&m);
856a5a7d
LP
1226 if (r < 0) {
1227 log_error("Failed to allocate manager: %s", strerror(-r));
687ed123 1228 goto out;
856a5a7d 1229 }
687ed123 1230
c264aeab
KS
1231 if (clock_is_localtime() > 0) {
1232 log_info("The system is configured to read the RTC time in the local time zone. "
1233 "This mode can not be fully supported. All system time to RTC updates are disabled.");
1234 m->rtc_local_time = true;
1235 }
1236
e8af6973
LP
1237 manager_add_server_string(m, NTP_SERVERS);
1238 manager_parse_config_file(m);
687ed123 1239
e0e5ce23
TG
1240 r = manager_network_monitor_listen(m);
1241 if (r < 0) {
1242 log_error("Failed to listen to networkd events: %s", strerror(-r));
1243 goto out;
1244 }
1245
e8af6973
LP
1246 log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
1247 sd_notify(false, "READY=1");
39594d49 1248
e0e5ce23
TG
1249 if (network_is_online()) {
1250 r = manager_connect(m);
1251 if (r < 0)
1252 goto out;
1253 }
678522cf 1254
687ed123 1255 r = sd_event_loop(m->event);
856a5a7d
LP
1256 if (r < 0) {
1257 log_error("Failed to run event loop: %s", strerror(-r));
687ed123 1258 goto out;
856a5a7d
LP
1259 }
1260
1261 sd_event_get_exit_code(m->event, &r);
d636d376
KS
1262
1263 /* if we got an authoritative time, store it in the file system */
1264 if (m->sync)
1265 touch("/var/lib/systemd/clock");
687ed123
KS
1266
1267out:
e8af6973
LP
1268 sd_notify(false, "STATUS=Shutting down...");
1269
687ed123 1270 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
bcdbbd7e 1271}