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