From 6f5c796c99a15ddb34657d09395f637906ceb308 Mon Sep 17 00:00:00 2001 From: otto <> Date: Thu, 20 Jun 2019 07:28:18 +0000 Subject: [PATCH] Do a quick DNS probe to decide to stay in the forground and attempt an (auto) settime or give up. 15s timeout is still in effect. ok florian@ --- src/usr.sbin/ntpd/client.c | 8 +++---- src/usr.sbin/ntpd/ntp.c | 20 ++++++++++++---- src/usr.sbin/ntpd/ntp_dns.c | 48 ++++++++++++++++++++++++++++++++++++- src/usr.sbin/ntpd/ntpd.h | 7 +++--- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index 4566b59c..49c18adb 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.108 2019/06/16 07:36:25 otto Exp $ */ +/* $OpenBSD: client.c,v 1.109 2019/06/20 07:28:18 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -240,7 +240,7 @@ handle_auto(double offset) if (offset < AUTO_THRESHOLD) { /* don't bother */ - priv_settime(0); + priv_settime(0, "offset is negative or close enough"); return; } /* collect some more */ @@ -254,7 +254,7 @@ handle_auto(double offset) offset = (v[AUTO_REPLIES / 2 - 1] + v[AUTO_REPLIES / 2]) / 2; else offset = v[AUTO_REPLIES / 2]; - priv_settime(offset); + priv_settime(offset, ""); } int @@ -459,7 +459,7 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime, u_int8_t automatic) if (automatic) handle_auto(p->reply[p->shift].offset); else - priv_settime(p->reply[p->shift].offset); + priv_settime(p->reply[p->shift].offset, ""); } if (++p->shift >= OFFSET_ARRAY_SIZE) diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 9e7fee5c..90420303 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.155 2019/06/16 07:36:25 otto Exp $ */ +/* $OpenBSD: ntp.c,v 1.156 2019/06/20 07:28:18 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -302,7 +302,7 @@ ntp_main(struct ntpd_conf *nconf, struct passwd *pw, int argc, char **argv) sensors_cnt = 0; TAILQ_FOREACH(s, &conf->ntp_sensors, entry) { if (conf->settime && s->offsets[0].offset) - priv_settime(s->offsets[0].offset); + priv_settime(s->offsets[0].offset, NULL); sensors_cnt++; if (s->next > 0 && s->next < nextaction) nextaction = s->next; @@ -312,7 +312,7 @@ ntp_main(struct ntpd_conf *nconf, struct passwd *pw, int argc, char **argv) if (conf->settime && ((trial_cnt > 0 && sent_cnt == 0) || (peer_cnt == 0 && sensors_cnt == 0))) - priv_settime(0); /* no good peers, don't wait */ + priv_settime(0, "no valid peers configured"); TAILQ_FOREACH(cstr, &conf->constraints, entry) { if (constraint_query(cstr) == -1) @@ -521,7 +521,7 @@ ntp_dispatch_imsg_dns(void) log_warnx("DNS lookup tempfail"); peer->state = STATE_DNS_TEMPFAIL; if (++conf->tmpfail > TRIES_AUTO_DNSFAIL) - priv_settime(0); + priv_settime(0, "of dns failures"); break; } @@ -569,6 +569,14 @@ ntp_dispatch_imsg_dns(void) constraint_msg_dns(imsg.hdr.peerid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); break; + case IMSG_PROBE_ROOT: + dlen = imsg.hdr.len - IMSG_HEADER_SIZE; + if (dlen != sizeof(int)) + fatalx("IMSG_PROBE_ROOT"); + memcpy(&n, imsg.data, sizeof(int)); + if (n < 0) + priv_settime(0, "dns probe failed"); + break; default: break; } @@ -754,8 +762,10 @@ offset_compare(const void *aa, const void *bb) } void -priv_settime(double offset) +priv_settime(double offset, char *msg) { + if (offset == 0) + log_info("cancel settime because %s", msg); imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, -1, &offset, sizeof(offset)); conf->settime = 0; diff --git a/src/usr.sbin/ntpd/ntp_dns.c b/src/usr.sbin/ntpd/ntp_dns.c index cf79af5c..ca784be4 100644 --- a/src/usr.sbin/ntpd/ntp_dns.c +++ b/src/usr.sbin/ntpd/ntp_dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp_dns.c,v 1.22 2019/06/12 05:04:45 otto Exp $ */ +/* $OpenBSD: ntp_dns.c,v 1.23 2019/06/20 07:28:18 otto Exp $ */ /* * Copyright (c) 2003-2008 Henning Brauer @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include @@ -40,6 +43,8 @@ struct imsgbuf *ibuf_dns; void sighdlr_dns(int); int dns_dispatch_imsg(struct ntpd_conf *); +int probe_root_ns(void); +void probe_root(void); void sighdlr_dns(int sig) @@ -96,6 +101,8 @@ ntp_dns(struct ntpd_conf *nconf, struct passwd *pw) if (pledge("stdio dns", NULL) == -1) err(1, "pledge"); + probe_root(); + while (quit_dns == 0) { pfd[0].fd = ibuf_dns->fd; pfd[0].events = POLLIN; @@ -202,3 +209,42 @@ dns_dispatch_imsg(struct ntpd_conf *nconf) } return (0); } + +int +probe_root_ns(void) +{ + int ret; + int old_retrans, old_retry, old_options; + unsigned char buf[4096]; + + old_retrans = _res.retrans; + old_retry = _res.retry; + old_options = _res.options; + _res.retrans = 1; + _res.retry = 1; + _res.options |= RES_USE_CD; + + ret = res_query(".", C_IN, T_NS, buf, sizeof(buf)); + + _res.retrans = old_retrans; + _res.retry = old_retry; + _res.options = old_options; + + return ret; +} + +void +probe_root(void) +{ + int n; + + n = probe_root_ns(); + if (n < 0) { + /* give programs like unwind a second chance */ + sleep(1); + n = probe_root_ns(); + } + if (imsg_compose(ibuf_dns, IMSG_PROBE_ROOT, 0, 0, -1, &n, + sizeof(int)) == -1) + fatalx("probe_root"); +} diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index da3936b3..3b20b24a 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.143 2019/06/16 07:36:25 otto Exp $ */ +/* $OpenBSD: ntpd.h,v 1.144 2019/06/20 07:28:18 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -311,7 +311,8 @@ enum imsg_type { IMSG_CTL_SHOW_ALL, IMSG_CTL_SHOW_ALL_END, IMSG_SYNCED, - IMSG_UNSYNCED + IMSG_UNSYNCED, + IMSG_PROBE_ROOT }; enum ctl_actions { @@ -327,7 +328,7 @@ enum ctl_actions { void ntp_main(struct ntpd_conf *, struct passwd *, int, char **); void peer_addr_head_clear(struct ntp_peer *); int priv_adjtime(void); -void priv_settime(double); +void priv_settime(double, char *); void priv_dns(int, char *, u_int32_t); int offset_compare(const void *, const void *); void update_scale(double);