]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/timesync/timesyncd.c
sd-network: fix parameter order for sd_network_monitor_new()
[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 */
856a5a7d
LP
248 assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
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,
280 CLOCK_MONOTONIC,
281 now(CLOCK_MONOTONIC) + TIMEOUT_USEC, 0,
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
KS
310 if (m->event_timer) {
311 r = sd_event_source_set_time(m->event_timer, now(CLOCK_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,
6a0f1f6d
LP
321 CLOCK_MONOTONIC,
322 now(CLOCK_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.
389 *
390 * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
391 * syncs the system time periodically to the hardware clock.
392 */
687ed123 393 if (fabs(offset) < NTP_MAX_ADJUST) {
d67006fe 394 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
bcdbbd7e 395 tmx.status = STA_PLL;
d67006fe
KS
396 tmx.offset = offset * NSEC_PER_SEC;
397 tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
12c0d47c
KS
398 tmx.maxerror = 0;
399 tmx.esterror = 0;
d67006fe 400 log_debug(" adjust (slew): %+.3f sec\n", offset);
bcdbbd7e 401 } else {
d67006fe
KS
402 tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
403
404 /* ADJ_NANO uses nanoseconds in the microseconds field */
405 tmx.time.tv_sec = (long)offset;
406 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
407
408 /* the kernel expects -0.3s as {-1, 7000.000.000} */
409 if (tmx.time.tv_usec < 0) {
ef619194 410 tmx.time.tv_sec -= 1;
d67006fe
KS
411 tmx.time.tv_usec += NSEC_PER_SEC;
412 }
7b415867 413
687ed123 414 m->jumped = true;
d67006fe 415 log_debug(" adjust (jump): %+.3f sec\n", offset);
bcdbbd7e
KS
416 }
417
418 switch (leap_sec) {
419 case 1:
420 tmx.status |= STA_INS;
421 break;
422 case -1:
423 tmx.status |= STA_DEL;
424 break;
425 }
426
81c36b3f 427 r = clock_adjtime(CLOCK_REALTIME, &tmx);
bcdbbd7e
KS
428 if (r < 0)
429 return r;
430
d636d376
KS
431 touch("/var/lib/systemd/clock");
432
ef619194
KS
433 m->drift_ppm = tmx.freq / 65536;
434
bcdbbd7e 435 log_debug(" status : %04i %s\n"
609e002e 436 " time now : %li.%03llu\n"
bcdbbd7e 437 " constant : %li\n"
ba9f11dc 438 " offset : %+.3f sec\n"
d67006fe 439 " freq offset : %+li (%i ppm)\n",
bcdbbd7e 440 tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
609e002e 441 tmx.time.tv_sec, (unsigned long long) (tmx.time.tv_usec / NSEC_PER_MSEC),
bcdbbd7e 442 tmx.constant,
d67006fe 443 (double)tmx.offset / NSEC_PER_SEC,
ef619194 444 tmx.freq, m->drift_ppm);
bcdbbd7e
KS
445
446 return 0;
447}
448
856a5a7d 449static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
bcdbbd7e
KS
450 unsigned int i, idx_cur, idx_new, idx_min;
451 double jitter;
3dbc7620 452 double j;
bcdbbd7e 453
856a5a7d
LP
454 assert(m);
455
687ed123 456 m->packet_count++;
d8c21348
KS
457
458 /* ignore initial sample */
687ed123 459 if (m->packet_count == 1)
d8c21348
KS
460 return false;
461
bcdbbd7e 462 /* store the current data in our samples array */
687ed123
KS
463 idx_cur = m->samples_idx;
464 idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
465 m->samples_idx = idx_new;
466 m->samples[idx_new].offset = offset;
467 m->samples[idx_new].delay = delay;
bcdbbd7e 468
bcdbbd7e 469 /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
687ed123
KS
470 jitter = m->samples_jitter;
471 for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
472 if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
bcdbbd7e
KS
473 idx_min = i;
474
3dbc7620 475 j = 0;
687ed123
KS
476 for (i = 0; i < ELEMENTSOF(m->samples); i++)
477 j += square(m->samples[i].offset - m->samples[idx_min].offset);
478 m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
bcdbbd7e 479
a47b9e62 480 /* ignore samples when resyncing */
687ed123 481 if (m->poll_resync)
a47b9e62
KS
482 return false;
483
484 /* always accept offset if we are farther off than the round-trip delay */
485 if (fabs(offset) > delay)
486 return false;
487
488 /* we need a few samples before looking at them */
687ed123 489 if (m->packet_count < 4)
a47b9e62
KS
490 return false;
491
3dbc7620 492 /* do not accept anything worse than the maximum possible error of the best sample */
687ed123 493 if (fabs(offset) > m->samples[idx_min].delay)
3dbc7620
KS
494 return true;
495
496 /* compare the difference between the current offset to the previous offset and jitter */
687ed123 497 return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
bcdbbd7e
KS
498}
499
856a5a7d
LP
500static void manager_adjust_poll(Manager *m, double offset, bool spike) {
501 assert(m);
502
687ed123
KS
503 if (m->poll_resync) {
504 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
505 m->poll_resync = false;
7b415867
KS
506 return;
507 }
508
bcdbbd7e 509 /* set to minimal poll interval */
18bb8adb 510 if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
687ed123 511 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
bcdbbd7e
KS
512 return;
513 }
514
515 /* increase polling interval */
3dbc7620 516 if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
687ed123
KS
517 if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
518 m->poll_interval_usec *= 2;
bcdbbd7e
KS
519 return;
520 }
521
522 /* decrease polling interval */
3dbc7620 523 if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
687ed123
KS
524 if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
525 m->poll_interval_usec /= 2;
bcdbbd7e
KS
526 return;
527 }
528}
529
856a5a7d
LP
530static bool sockaddr_equal(union sockaddr_union *a, union sockaddr_union *b) {
531 assert(a);
532 assert(b);
533
534 if (a->sa.sa_family != b->sa.sa_family)
535 return false;
536
537 if (a->sa.sa_family == AF_INET)
538 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
539
540 if (a->sa.sa_family == AF_INET6)
541 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
542
543 return false;
544}
545
546static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
687ed123 547 Manager *m = userdata;
856a5a7d
LP
548 struct ntp_msg ntpmsg;
549
bcdbbd7e 550 struct iovec iov = {
856a5a7d
LP
551 .iov_base = &ntpmsg,
552 .iov_len = sizeof(ntpmsg),
bcdbbd7e
KS
553 };
554 union {
555 struct cmsghdr cmsghdr;
556 uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
557 } control;
5f8cfaee 558 union sockaddr_union server_addr;
bcdbbd7e
KS
559 struct msghdr msghdr = {
560 .msg_iov = &iov,
561 .msg_iovlen = 1,
562 .msg_control = &control,
563 .msg_controllen = sizeof(control),
564 .msg_name = &server_addr,
565 .msg_namelen = sizeof(server_addr),
566 };
567 struct cmsghdr *cmsg;
3dbc7620 568 struct timespec now_ts;
bcdbbd7e
KS
569 struct timeval *recv_time;
570 ssize_t len;
d2d66d1c 571 double origin, receive, trans, dest;
bcdbbd7e
KS
572 double delay, offset;
573 bool spike;
574 int leap_sec;
575 int r;
576
678522cf
LP
577 assert(source);
578 assert(m);
579
bcdbbd7e 580 if (revents & (EPOLLHUP|EPOLLERR)) {
678522cf
LP
581 log_warning("Server connection returned error.");
582 return manager_connect(m);
bcdbbd7e
KS
583 }
584
585 len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
586 if (len < 0) {
856a5a7d
LP
587 if (errno == EAGAIN)
588 return 0;
589
678522cf
LP
590 log_warning("Error receiving message. Disconnecting.");
591 return manager_connect(m);
bcdbbd7e
KS
592 }
593
594 if (iov.iov_len < sizeof(struct ntp_msg)) {
678522cf
LP
595 log_warning("Invalid response from server. Disconnecting.");
596 return manager_connect(m);
bcdbbd7e
KS
597 }
598
678522cf
LP
599 if (!m->current_server_name ||
600 !m->current_server_address ||
601 !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
602 log_debug("Response from unknown server.");
603 return 0;
bcdbbd7e
KS
604 }
605
606 recv_time = NULL;
607 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
608 if (cmsg->cmsg_level != SOL_SOCKET)
609 continue;
610
611 switch (cmsg->cmsg_type) {
612 case SCM_TIMESTAMP:
613 recv_time = (struct timeval *) CMSG_DATA(cmsg);
614 break;
615 }
616 }
617 if (!recv_time) {
678522cf 618 log_error("Invalid packet timestamp.");
bcdbbd7e
KS
619 return -EINVAL;
620 }
621
687ed123 622 if (!m->pending) {
07a062a7 623 log_debug("Unexpected reply. Ignoring.");
bcdbbd7e
KS
624 return 0;
625 }
bcdbbd7e
KS
626
627 /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
856a5a7d
LP
628 if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
629 be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
07a062a7 630 log_debug("Invalid reply; not our transmit time. Ignoring.");
bcdbbd7e
KS
631 return 0;
632 }
633
16c058ba
LP
634 m->event_timeout = sd_event_source_unref(m->event_timeout);
635
661278ee
LP
636 if (be32toh(ntpmsg.recv_time.sec) < TIME_EPOCH + OFFSET_1900_1970 ||
637 be32toh(ntpmsg.trans_time.sec) < TIME_EPOCH + OFFSET_1900_1970) {
638 log_debug("Invalid reply, returned times before epoch. Ignoring.");
639 return manager_connect(m);
640 }
641
856a5a7d 642 if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
07a062a7 643 log_debug("Server is not synchronized. Disconnecting.");
678522cf 644 return manager_connect(m);
bcdbbd7e
KS
645 }
646
661278ee 647 if (!IN_SET(NTP_FIELD_VERSION(ntpmsg.field), 3, 4)) {
856a5a7d 648 log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
678522cf 649 return manager_connect(m);
bcdbbd7e
KS
650 }
651
856a5a7d
LP
652 if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
653 log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
678522cf 654 return manager_connect(m);
bcdbbd7e
KS
655 }
656
7b415867 657 /* valid packet */
687ed123
KS
658 m->pending = false;
659 m->retry_interval = 0;
7b415867 660
bcdbbd7e 661 /* announce leap seconds */
856a5a7d 662 if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
bcdbbd7e 663 leap_sec = 1;
856a5a7d 664 else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
bcdbbd7e
KS
665 leap_sec = -1;
666 else
667 leap_sec = 0;
668
669 /*
670 * "Timestamp Name ID When Generated
671 * ------------------------------------------------------------
672 * Originate Timestamp T1 time request sent by client
673 * Receive Timestamp T2 time request received by server
674 * Transmit Timestamp T3 time reply sent by server
675 * Destination Timestamp T4 time reply received by client
676 *
07a062a7 677 * The round-trip delay, d, and system clock offset, t, are defined as:
bcdbbd7e
KS
678 * d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
679 */
856a5a7d 680 assert_se(clock_gettime(CLOCK_MONOTONIC, &now_ts) >= 0);
687ed123 681 origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
856a5a7d
LP
682 receive = ntp_ts_to_d(&ntpmsg.recv_time);
683 trans = ntp_ts_to_d(&ntpmsg.trans_time);
bcdbbd7e
KS
684 dest = tv_to_d(recv_time) + OFFSET_1900_1970;
685
d2d66d1c
KS
686 offset = ((receive - origin) + (trans - dest)) / 2;
687 delay = (dest - origin) - (trans - receive);
bcdbbd7e 688
856a5a7d 689 spike = manager_sample_spike_detection(m, offset, delay);
bcdbbd7e 690
856a5a7d 691 manager_adjust_poll(m, offset, spike);
bcdbbd7e
KS
692
693 log_debug("NTP response:\n"
694 " leap : %u\n"
695 " version : %u\n"
696 " mode : %u\n"
697 " stratum : %u\n"
d67006fe 698 " precision : %.6f sec (%d)\n"
bcdbbd7e 699 " reference : %.4s\n"
ba9f11dc
KS
700 " origin : %.3f\n"
701 " receive : %.3f\n"
702 " transmit : %.3f\n"
703 " dest : %.3f\n"
704 " offset : %+.3f sec\n"
705 " delay : %+.3f sec\n"
8fe90522 706 " packet count : %"PRIu64"\n"
ba9f11dc 707 " jitter : %.3f%s\n"
609e002e 708 " poll interval: " USEC_FMT "\n",
856a5a7d
LP
709 NTP_FIELD_LEAP(ntpmsg.field),
710 NTP_FIELD_VERSION(ntpmsg.field),
711 NTP_FIELD_MODE(ntpmsg.field),
712 ntpmsg.stratum,
713 exp2(ntpmsg.precision), ntpmsg.precision,
714 ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
bcdbbd7e 715 origin - OFFSET_1900_1970,
d2d66d1c 716 receive - OFFSET_1900_1970,
bcdbbd7e
KS
717 trans - OFFSET_1900_1970,
718 dest - OFFSET_1900_1970,
719 offset, delay,
687ed123
KS
720 m->packet_count,
721 m->samples_jitter, spike ? " spike" : "",
722 m->poll_interval_usec / USEC_PER_SEC);
bcdbbd7e 723
bcdbbd7e 724 if (!spike) {
d636d376 725 m->sync = true;
856a5a7d 726 r = manager_adjust_clock(m, offset, leap_sec);
bcdbbd7e
KS
727 if (r < 0)
728 log_error("Failed to call clock_adjtime(): %m");
729 }
730
609e002e 731 log_info("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s",
08937720 732 m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
ef619194 733 spike ? " (ignored)" : "");
bcdbbd7e 734
678522cf
LP
735 r = manager_arm_timer(m, m->poll_interval_usec);
736 if (r < 0) {
737 log_error("Failed to rearm timer: %s", strerror(-r));
738 return r;
739 }
740
741 return 0;
bcdbbd7e
KS
742}
743
856a5a7d
LP
744static int manager_listen_setup(Manager *m) {
745 union sockaddr_union addr = {};
746 static const int tos = IPTOS_LOWDELAY;
747 static const int on = 1;
748 int r;
bcdbbd7e 749
687ed123 750 assert(m);
bcdbbd7e 751
856a5a7d
LP
752 assert(m->server_socket < 0);
753 assert(!m->event_receive);
678522cf 754 assert(m->current_server_address);
bcdbbd7e 755
678522cf 756 addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
bcdbbd7e 757
856a5a7d
LP
758 m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
759 if (m->server_socket < 0)
760 return -errno;
bcdbbd7e 761
678522cf 762 r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
856a5a7d
LP
763 if (r < 0)
764 return -errno;
765
766 r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
767 if (r < 0)
768 return -errno;
769
770 setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
bcdbbd7e 771
856a5a7d 772 return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
bcdbbd7e
KS
773}
774
678522cf 775static int manager_begin(Manager *m) {
856a5a7d 776 _cleanup_free_ char *pretty = NULL;
856a5a7d 777 int r;
bcdbbd7e 778
856a5a7d 779 assert(m);
678522cf
LP
780 assert_return(m->current_server_name, -EHOSTUNREACH);
781 assert_return(m->current_server_address, -EHOSTUNREACH);
7b415867 782
678522cf 783 m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
856a5a7d 784
ae2db4e7 785 server_address_pretty(m->current_server_address, &pretty);
16c058ba
LP
786 log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
787 sd_notifyf(false, "STATUS=Using Time Server %s (%s).", strna(pretty), m->current_server_name->string);
856a5a7d
LP
788
789 r = manager_listen_setup(m);
790 if (r < 0) {
791 log_warning("Failed to setup connection socket: %s", strerror(-r));
792 return r;
793 }
794
795 r = manager_clock_watch_setup(m);
678522cf 796 if (r < 0)
856a5a7d 797 return r;
856a5a7d
LP
798
799 return manager_send_request(m);
bcdbbd7e
KS
800}
801
678522cf
LP
802static void server_name_flush_addresses(ServerName *n) {
803 ServerAddress *a;
804
805 assert(n);
806
807 while ((a = n->addresses)) {
808 LIST_REMOVE(addresses, n->addresses, a);
809 free(a);
810 }
811}
812
813static void manager_flush_names(Manager *m) {
814 ServerName *n;
815
816 assert(m);
817
818 while ((n = m->servers)) {
819 LIST_REMOVE(names, m->servers, n);
820 free(n->string);
821 server_name_flush_addresses(n);
822 free(n);
823 }
824}
825
826static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
827 Manager *m = userdata;
828 ServerAddress *a, *last = NULL;
829
830 assert(q);
831 assert(m);
832 assert(m->current_server_name);
833
834 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
835
836 if (ret != 0) {
4d40d39c 837 log_debug("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
678522cf
LP
838
839 /* Try next host */
840 return manager_connect(m);
841 }
842
843 server_name_flush_addresses(m->current_server_name);
844
845 for (; ai; ai = ai->ai_next) {
846 _cleanup_free_ char *pretty = NULL;
847
848 assert(ai->ai_addr);
849 assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
850 assert(ai->ai_addrlen <= sizeof(union sockaddr_union));
851
852 if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
853 log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
854 continue;
855 }
856
857 a = new0(ServerAddress, 1);
858 if (!a)
859 return log_oom();
860
861 memcpy(&a->sockaddr, ai->ai_addr, ai->ai_addrlen);
862 a->socklen = ai->ai_addrlen;
863
864 LIST_INSERT_AFTER(addresses, m->current_server_name->addresses, last, a);
865 last = a;
866
867 sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, &pretty);
16c058ba 868 log_debug("Resolved address %s for %s.", pretty, m->current_server_name->string);
678522cf
LP
869 }
870
871 if (!m->current_server_name->addresses) {
872 log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
873
874 /* Try next host */
875 return manager_connect(m);
876 }
877
878 m->current_server_address = m->current_server_name->addresses;
879
880 return manager_begin(m);
881}
882
7a183c4c
LP
883static int manager_retry(sd_event_source *source, usec_t usec, void *userdata) {
884 Manager *m = userdata;
885
886 assert(m);
887
888 return manager_connect(m);
889}
890
678522cf 891static int manager_connect(Manager *m) {
5f8cfaee 892
856a5a7d
LP
893 struct addrinfo hints = {
894 .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
895 .ai_socktype = SOCK_DGRAM,
5f8cfaee 896 };
678522cf 897 int r;
5f8cfaee 898
856a5a7d 899 assert(m);
bcdbbd7e 900
678522cf
LP
901 manager_disconnect(m);
902
7a183c4c
LP
903 m->event_retry = sd_event_source_unref(m->event_retry);
904 if (!ratelimit_test(&m->ratelimit)) {
905 log_debug("Slowing down attempts to contact servers.");
906
907 r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
908 if (r < 0) {
909 log_error("Failed to create retry timer: %s", strerror(-r));
910 return r;
911 }
912
913 return 0;
914 }
915
678522cf
LP
916 /* If we already are operating on some address, switch to the
917 * next one. */
918 if (m->current_server_address && m->current_server_address->addresses_next)
919 m->current_server_address = m->current_server_address->addresses_next;
920 else {
921 /* Hmm, we are through all addresses, let's look for the next host instead */
922 m->current_server_address = NULL;
923
924 if (m->current_server_name && m->current_server_name->names_next)
925 m->current_server_name = m->current_server_name->names_next;
926 else {
927 if (!m->servers) {
928 m->current_server_name = NULL;
929 log_debug("No server found.");
930 return 0;
931 }
932
933 m->current_server_name = m->servers;
934 }
935
05f7fc0f
LP
936 /* Tell the resolver to reread /etc/resolv.conf, in
937 * case it changed. */
938 res_init();
939
678522cf
LP
940 r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
941 if (r < 0) {
942 log_error("Failed to create resolver: %s", strerror(-r));
943 return r;
944 }
945
946 return 1;
947 }
948
949 r = manager_begin(m);
950 if (r < 0)
951 return r;
952
953 return 1;
954}
955
956static int manager_add_server(Manager *m, const char *server) {
60080921 957 ServerName *n, *tail;
678522cf
LP
958
959 assert(m);
960 assert(server);
bcdbbd7e 961
678522cf
LP
962 n = new0(ServerName, 1);
963 if (!n)
856a5a7d 964 return -ENOMEM;
bcdbbd7e 965
678522cf
LP
966 n->string = strdup(server);
967 if (!n->string) {
968 free(n);
969 return -ENOMEM;
970 }
bcdbbd7e 971
376cd3b8
LP
972 LIST_FIND_TAIL(names, m->servers, tail);
973 LIST_INSERT_AFTER(names, m->servers, tail, n);
60080921 974
678522cf 975 return 0;
856a5a7d 976}
bcdbbd7e 977
e8af6973
LP
978static int manager_add_server_string(Manager *m, const char *string) {
979 char *w, *state;
980 size_t l;
981 int r;
982
983 assert(m);
984 assert(string);
985
986 FOREACH_WORD_QUOTED(w, l, string, state) {
987 char t[l+1];
988
989 memcpy(t, w, l);
990 t[l] = 0;
991
992 r = manager_add_server(m, t);
993 if (r < 0)
994 log_error("Failed to add server %s to configuration, ignoring: %s", t, strerror(-r));
995 }
996
997 return 0;
998}
999
856a5a7d
LP
1000static void manager_disconnect(Manager *m) {
1001 assert(m);
bcdbbd7e 1002
856a5a7d 1003 m->resolve_query = sd_resolve_query_unref(m->resolve_query);
bcdbbd7e 1004
856a5a7d
LP
1005 m->event_timer = sd_event_source_unref(m->event_timer);
1006
1007 m->event_receive = sd_event_source_unref(m->event_receive);
1008 m->server_socket = safe_close(m->server_socket);
1009
856a5a7d
LP
1010 m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
1011 m->clock_watch_fd = safe_close(m->clock_watch_fd);
16c058ba
LP
1012
1013 m->event_timeout = sd_event_source_unref(m->event_timeout);
1014
1015 sd_notifyf(false, "STATUS=Idle.");
7b415867
KS
1016}
1017
687ed123
KS
1018static int manager_new(Manager **ret) {
1019 _cleanup_manager_free_ Manager *m = NULL;
7b415867
KS
1020 int r;
1021
c92e531c
LP
1022 assert(ret);
1023
687ed123
KS
1024 m = new0(Manager, 1);
1025 if (!m)
7b415867
KS
1026 return -ENOMEM;
1027
856a5a7d
LP
1028 m->server_socket = m->clock_watch_fd = -1;
1029
7a183c4c
LP
1030 RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
1031
687ed123 1032 r = sd_event_default(&m->event);
7b415867
KS
1033 if (r < 0)
1034 return r;
1035
9f711549
LP
1036 sd_event_set_watchdog(m->event, true);
1037
f864fd1b
LP
1038 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
1039 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
856a5a7d
LP
1040
1041 r = sd_resolve_default(&m->resolve);
7b415867
KS
1042 if (r < 0)
1043 return r;
1044
856a5a7d
LP
1045 r = sd_resolve_attach_event(m->resolve, m->event, 0);
1046 if (r < 0)
59a9fce4 1047 return r;
856a5a7d 1048
687ed123
KS
1049 *ret = m;
1050 m = NULL;
bcdbbd7e
KS
1051
1052 return 0;
1053}
1054
687ed123 1055static void manager_free(Manager *m) {
687ed123
KS
1056 if (!m)
1057 return;
1058
856a5a7d 1059 manager_disconnect(m);
678522cf 1060 manager_flush_names(m);
856a5a7d 1061
7a183c4c
LP
1062 sd_event_source_unref(m->event_retry);
1063
e0e5ce23
TG
1064 sd_event_source_unref(m->network_event_source);
1065 sd_network_monitor_unref(m->network_monitor);
1066
856a5a7d 1067 sd_resolve_unref(m->resolve);
687ed123 1068 sd_event_unref(m->event);
856a5a7d 1069
687ed123
KS
1070 free(m);
1071}
1072
e8af6973
LP
1073int config_parse_servers(
1074 const char *unit,
1075 const char *filename,
1076 unsigned line,
1077 const char *section,
1078 unsigned section_line,
1079 const char *lvalue,
1080 int ltype,
1081 const char *rvalue,
1082 void *data,
1083 void *userdata) {
1084
1085 Manager *m = userdata;
1086
1087 assert(filename);
1088 assert(lvalue);
1089 assert(rvalue);
1090
1091 manager_flush_names(m);
1092 manager_add_server_string(m, rvalue);
1093
1094 return 0;
1095}
1096
1097static int manager_parse_config_file(Manager *m) {
36f822c4
ZJS
1098 return config_parse(NULL, "/etc/systemd/timesyncd.conf", NULL,
1099 "Time\0",
1100 config_item_perf_lookup, timesyncd_gperf_lookup,
1101 false, false, true, m);
e8af6973
LP
1102}
1103
e0e5ce23 1104static bool network_is_online(void) {
9b3310b0
TG
1105 _cleanup_free_ char *state = NULL;
1106 int r;
e0e5ce23 1107
9b3310b0 1108 r = sd_network_get_operational_state(&state);
a6cb8f87 1109 if (r >= 0 && STR_IN_SET(state, "routable", "degraded"))
9b3310b0 1110 return true;
a6cb8f87
KS
1111
1112 return false;
e0e5ce23
TG
1113}
1114
1115static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t revents,
1116 void *userdata) {
1117 Manager *m = userdata;
1118 bool connected, online;
1119 int r;
1120
1121 assert(m);
1122
1123 /* check if the machine is online */
1124 online = network_is_online();
1125
1126 /* check if the client is currently connected */
1127 connected = (m->server_socket != -1);
1128
1129 if (connected && !online) {
4d40d39c 1130 log_info("No network connectivity, watching for changes.");
e0e5ce23
TG
1131 manager_disconnect(m);
1132 } else if (!connected && online) {
4d40d39c 1133 log_info("Network configuration changed, trying to establish connection.");
e0e5ce23
TG
1134 if (m->current_server_address) {
1135 r = manager_begin(m);
1136 if (r < 0)
1137 return r;
1138 } else {
1139 r = manager_connect(m);
1140 if (r < 0)
1141 return r;
1142 }
1143 }
1144
1145 sd_network_monitor_flush(m->network_monitor);
1146
1147 return 0;
1148}
1149
1150static int manager_network_monitor_listen(Manager *m) {
1151 _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
1152 _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
1153 int r, fd, events;
1154
0014a4ad 1155 r = sd_network_monitor_new(&monitor, NULL);
e0e5ce23
TG
1156 if (r < 0)
1157 return r;
1158
1159 fd = sd_network_monitor_get_fd(monitor);
1160 if (fd < 0)
1161 return fd;
1162
1163 events = sd_network_monitor_get_events(monitor);
1164 if (events < 0)
1165 return events;
1166
1167 r = sd_event_add_io(m->event, &event_source, fd, events,
1168 &manager_network_event_handler, m);
1169 if (r < 0)
1170 return r;
1171
1172 m->network_monitor = monitor;
1173 m->network_event_source = event_source;
1174 monitor = NULL;
1175 event_source = NULL;
1176
1177 return 0;
1178}
1179
687ed123 1180int main(int argc, char *argv[]) {
ece6e766 1181 const char *user = "systemd-timesync";
687ed123 1182 _cleanup_manager_free_ Manager *m = NULL;
ece6e766
LP
1183 uid_t uid;
1184 gid_t gid;
687ed123
KS
1185 int r;
1186
e8af6973
LP
1187 if (argc > 1) {
1188 log_error("This program does not take arguments.");
1189 return EXIT_FAILURE;
1190 }
1191
687ed123 1192 log_set_target(LOG_TARGET_AUTO);
e8af6973 1193 log_set_facility(LOG_CRON);
687ed123
KS
1194 log_parse_environment();
1195 log_open();
1196
e8af6973
LP
1197 umask(0022);
1198
ece6e766
LP
1199 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
1200 if (r < 0) {
1201 log_error("Cannot resolve user name %s: %s", user, strerror(-r));
1202 return r;
1203 }
1204
d636d376 1205 r = load_clock_timestamp(uid, gid);
ece6e766
LP
1206 if (r < 0)
1207 goto out;
1208
966bff26 1209 r = drop_privileges(uid, gid, (1ULL << CAP_SYS_TIME));
a349eb10
LP
1210 if (r < 0)
1211 goto out;
1212
856a5a7d
LP
1213 assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
1214
687ed123 1215 r = manager_new(&m);
856a5a7d
LP
1216 if (r < 0) {
1217 log_error("Failed to allocate manager: %s", strerror(-r));
687ed123 1218 goto out;
856a5a7d 1219 }
687ed123 1220
e8af6973
LP
1221 manager_add_server_string(m, NTP_SERVERS);
1222 manager_parse_config_file(m);
687ed123 1223
e0e5ce23
TG
1224 r = manager_network_monitor_listen(m);
1225 if (r < 0) {
1226 log_error("Failed to listen to networkd events: %s", strerror(-r));
1227 goto out;
1228 }
1229
e8af6973
LP
1230 log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
1231 sd_notify(false, "READY=1");
39594d49 1232
e0e5ce23
TG
1233 if (network_is_online()) {
1234 r = manager_connect(m);
1235 if (r < 0)
1236 goto out;
1237 }
678522cf 1238
687ed123 1239 r = sd_event_loop(m->event);
856a5a7d
LP
1240 if (r < 0) {
1241 log_error("Failed to run event loop: %s", strerror(-r));
687ed123 1242 goto out;
856a5a7d
LP
1243 }
1244
1245 sd_event_get_exit_code(m->event, &r);
d636d376
KS
1246
1247 /* if we got an authoritative time, store it in the file system */
1248 if (m->sync)
1249 touch("/var/lib/systemd/clock");
687ed123
KS
1250
1251out:
e8af6973
LP
1252 sd_notify(false, "STATUS=Shutting down...");
1253
687ed123 1254 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
bcdbbd7e 1255}