summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2015-02-12 01:54:58 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2015-02-12 01:54:58 +0000
commit73f8916e495feb768300ba85f85847bb0c83c6f0 (patch)
treee73a912ffdad6380f54b133366aee1d69614227b /usr.sbin
parent63c1d43867a57fc2ada4bbeff717668b4a3eee18 (diff)
Use ntpd's deferred DNS resolving for constraints as well. This
allows to get constraint addresses even if network/DNS is not available at startup (or system boot). thumbs up & OK henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ntpd/client.c4
-rw-r--r--usr.sbin/ntpd/constraint.c142
-rw-r--r--usr.sbin/ntpd/ntp.c13
-rw-r--r--usr.sbin/ntpd/ntp_dns.c14
-rw-r--r--usr.sbin/ntpd/ntpd.h6
-rw-r--r--usr.sbin/ntpd/parse.y19
6 files changed, 147 insertions, 51 deletions
diff --git a/usr.sbin/ntpd/client.c b/usr.sbin/ntpd/client.c
index 06c5e92457b..bf7cdd0e2f0 100644
--- a/usr.sbin/ntpd/client.c
+++ b/usr.sbin/ntpd/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.99 2015/02/10 06:40:08 reyk Exp $ */
+/* $OpenBSD: client.c,v 1.100 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -107,7 +107,7 @@ client_nextaddr(struct ntp_peer *p)
return (-1);
if (p->addr_head.a == NULL) {
- priv_host_dns(p->addr_head.name, p->id);
+ priv_dns(IMSG_HOST_DNS, p->addr_head.name, p->id);
p->state = STATE_DNS_INPROGRESS;
return (-1);
}
diff --git a/usr.sbin/ntpd/constraint.c b/usr.sbin/ntpd/constraint.c
index 5272cdf19e7..8e0b2974f21 100644
--- a/usr.sbin/ntpd/constraint.c
+++ b/usr.sbin/ntpd/constraint.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: constraint.c,v 1.3 2015/02/10 23:52:41 reyk Exp $ */
+/* $OpenBSD: constraint.c,v 1.4 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -44,6 +44,8 @@
int constraint_addr_init(struct constraint *);
struct constraint *
+ constraint_byid(u_int32_t);
+struct constraint *
constraint_byfd(int);
struct constraint *
constraint_bypid(pid_t);
@@ -51,6 +53,8 @@ int constraint_close(int);
void constraint_update(void);
void constraint_reset(void);
int constraint_cmp(const void *, const void *);
+void constraint_add(struct constraint *);
+void constraint_remove(struct constraint *);
struct httpsdate *
httpsdate_init(const char *, const char *, const char *,
@@ -63,6 +67,8 @@ void *httpsdate_query(const char *, const char *, const char *,
char *tls_readline(struct tls *, size_t *, size_t *, struct timeval *);
+extern u_int constraint_cnt;
+
struct httpsdate {
char *tls_host;
char *tls_port;
@@ -91,31 +97,37 @@ constraint_addr_init(struct constraint *cstr)
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
struct ntp_addr *h;
- int cnt = 0;
-
- for (h = cstr->addr; h != NULL; h = h->next) {
- switch (h->ss.ss_family) {
- case AF_INET:
- sa_in = (struct sockaddr_in *)&h->ss;
- if (ntohs(sa_in->sin_port) == 0)
- sa_in->sin_port = htons(443);
- cstr->state = STATE_DNS_DONE;
- break;
- case AF_INET6:
- sa_in6 = (struct sockaddr_in6 *)&h->ss;
- if (ntohs(sa_in6->sin6_port) == 0)
- sa_in6->sin6_port = htons(443);
- cstr->state = STATE_DNS_DONE;
- break;
- default:
- /* XXX king bula sez it? */
- fatalx("wrong AF in constraint_addr_init");
- /* NOTREACHED */
- }
- cnt++;
+
+ if (cstr->state == STATE_DNS_INPROGRESS)
+ return (0);
+
+ if (cstr->addr_head.a == NULL) {
+ priv_dns(IMSG_CONSTRAINT_DNS, cstr->addr_head.name, cstr->id);
+ cstr->state = STATE_DNS_INPROGRESS;
+ return (0);
+ }
+
+ h = cstr->addr;
+ switch (h->ss.ss_family) {
+ case AF_INET:
+ sa_in = (struct sockaddr_in *)&h->ss;
+ if (ntohs(sa_in->sin_port) == 0)
+ sa_in->sin_port = htons(443);
+ cstr->state = STATE_DNS_DONE;
+ break;
+ case AF_INET6:
+ sa_in6 = (struct sockaddr_in6 *)&h->ss;
+ if (ntohs(sa_in6->sin6_port) == 0)
+ sa_in6->sin6_port = htons(443);
+ cstr->state = STATE_DNS_DONE;
+ break;
+ default:
+ /* XXX king bula sez it? */
+ fatalx("wrong AF in constraint_addr_init");
+ /* NOTREACHED */
}
- return (cnt);
+ return (1);
}
int
@@ -134,6 +146,10 @@ constraint_query(struct constraint *cstr)
case STATE_DNS_DONE:
/* Proceed and query the time */
break;
+ case STATE_DNS_TEMPFAIL:
+ /* Retry resolving the address */
+ constraint_init(cstr);
+ return (-1);
case STATE_QUERY_SENT:
if (cstr->last + CONSTRAINT_SCAN_TIMEOUT > now) {
/* The caller should expect a reply */
@@ -278,6 +294,19 @@ constraint_check_child(void)
}
struct constraint *
+constraint_byid(u_int32_t id)
+{
+ struct constraint *cstr;
+
+ TAILQ_FOREACH(cstr, &conf->constraints, entry) {
+ if (cstr->id == id)
+ return (cstr);
+ }
+
+ return (NULL);
+}
+
+struct constraint *
constraint_byfd(int fd)
{
struct constraint *cstr;
@@ -326,6 +355,23 @@ constraint_close(int fd)
return (1);
}
+void
+constraint_add(struct constraint *cstr)
+{
+ TAILQ_INSERT_TAIL(&conf->constraints, cstr, entry);
+ constraint_cnt += constraint_init(cstr);
+}
+
+void
+constraint_remove(struct constraint *cstr)
+{
+ TAILQ_REMOVE(&conf->constraints, cstr, entry);
+ free(cstr->addr_head.name);
+ free(cstr->addr_head.path);
+ free(cstr);
+ constraint_cnt--;
+}
+
int
constraint_dispatch_msg(struct pollfd *pfd)
{
@@ -383,6 +429,54 @@ constraint_dispatch_msg(struct pollfd *pfd)
return (0);
}
+void
+constraint_dns(u_int32_t id, u_int8_t *data, size_t len)
+{
+ struct constraint *cstr, *ncstr;
+ u_int8_t *p;
+ struct ntp_addr *h;
+
+ if ((cstr = constraint_byid(id)) == NULL) {
+ log_warnx("IMSG_CONSTRAINT_DNS with invalid constraint id");
+ return;
+ }
+ if (cstr->addr != NULL) {
+ log_warnx("IMSG_CONSTRAINT_DNS but addr != NULL!");
+ return;
+ }
+ if (len == 0) {
+ log_debug("%s FAILED", __func__);
+ cstr->state = STATE_DNS_TEMPFAIL;
+ return;
+ }
+
+ if ((len % sizeof(struct sockaddr_storage)) != 0)
+ fatalx("IMSG_CONSTRAINT_DNS len");
+
+ p = data;
+ do {
+ if ((h = calloc(1, sizeof(*h))) == NULL)
+ fatal("calloc ntp_addr");
+ memcpy(&h->ss, p, sizeof(h->ss));
+ p += sizeof(h->ss);
+ len -= sizeof(h->ss);
+
+ ncstr = new_constraint();
+ ncstr->addr = h;
+ ncstr->addr_head.a = h;
+ ncstr->addr_head.name = strdup(cstr->addr_head.name);
+ ncstr->addr_head.path = strdup(cstr->addr_head.path);
+ if (ncstr->addr_head.name == NULL ||
+ ncstr->addr_head.path == NULL)
+ fatal("calloc name");
+ ncstr->addr_head.pool = cstr->addr_head.pool;
+
+ constraint_add(ncstr);
+ } while (len && cstr->addr_head.pool);
+
+ constraint_remove(cstr);
+}
+
int
constraint_cmp(const void *a, const void *b)
{
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c
index 76629af5ef3..a836f4cabfa 100644
--- a/usr.sbin/ntpd/ntp.c
+++ b/usr.sbin/ntpd/ntp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp.c,v 1.128 2015/02/10 06:40:08 reyk Exp $ */
+/* $OpenBSD: ntp.c,v 1.129 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -49,6 +49,7 @@ struct ntpd_conf *conf;
struct ctl_conns ctl_conns;
u_int peer_cnt;
u_int sensors_cnt;
+u_int constraint_cnt;
time_t lastreport;
void ntp_sighdlr(int);
@@ -84,7 +85,7 @@ ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
int ctls, boundaries;
u_int pfd_elms = 0, idx2peer_elms = 0;
u_int listener_cnt, new_cnt, sent_cnt, trial_cnt;
- u_int ctl_cnt, constraint_cnt;
+ u_int ctl_cnt;
pid_t pid;
struct pollfd *pfd = NULL;
struct servent *se;
@@ -582,6 +583,10 @@ ntp_dispatch_imsg_dns(void)
else
client_addr_init(peer);
break;
+ case IMSG_CONSTRAINT_DNS:
+ constraint_dns(imsg.hdr.peerid,
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
+ break;
default:
break;
}
@@ -762,12 +767,12 @@ priv_settime(double offset)
}
void
-priv_host_dns(char *name, u_int32_t peerid)
+priv_dns(int cmd, char *name, u_int32_t peerid)
{
u_int16_t dlen;
dlen = strlen(name) + 1;
- imsg_compose(ibuf_dns, IMSG_HOST_DNS, peerid, 0, -1, name, dlen);
+ imsg_compose(ibuf_dns, cmd, peerid, 0, -1, name, dlen);
}
void
diff --git a/usr.sbin/ntpd/ntp_dns.c b/usr.sbin/ntpd/ntp_dns.c
index 37dea75bbd2..08cdb13ff3d 100644
--- a/usr.sbin/ntpd/ntp_dns.c
+++ b/usr.sbin/ntpd/ntp_dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp_dns.c,v 1.8 2015/01/21 03:14:10 bcook Exp $ */
+/* $OpenBSD: ntp_dns.c,v 1.9 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2003-2008 Henning Brauer <henning@openbsd.org>
@@ -129,6 +129,7 @@ dns_dispatch_imsg(void)
char *name;
struct ntp_addr *h, *hn;
struct ibuf *buf;
+ const char *str;
if ((n = imsg_read(ibuf_dns)) == -1)
return (-1);
@@ -147,16 +148,21 @@ dns_dispatch_imsg(void)
switch (imsg.hdr.type) {
case IMSG_HOST_DNS:
+ case IMSG_CONSTRAINT_DNS:
+ if (imsg.hdr.type == IMSG_HOST_DNS)
+ str = "IMSG_HOST_DNS";
+ else
+ str = "IMSG_CONSTRAINT_DNS";
name = imsg.data;
if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE)
- fatalx("invalid IMSG_HOST_DNS received");
+ fatalx("invalid %s received", str);
imsg.hdr.len -= 1 + IMSG_HEADER_SIZE;
if (name[imsg.hdr.len] != '\0' ||
strlen(name) != imsg.hdr.len)
- fatalx("invalid IMSG_HOST_DNS received");
+ fatalx("invalid %s received", str);
if ((cnt = host_dns(name, &hn)) == -1)
break;
- buf = imsg_create(ibuf_dns, IMSG_HOST_DNS,
+ buf = imsg_create(ibuf_dns, imsg.hdr.type,
imsg.hdr.peerid, 0,
cnt * sizeof(struct sockaddr_storage));
if (cnt > 0) {
diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h
index 9c65ee2d4bc..1ffd46a279f 100644
--- a/usr.sbin/ntpd/ntpd.h
+++ b/usr.sbin/ntpd/ntpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntpd.h,v 1.118 2015/02/10 06:40:08 reyk Exp $ */
+/* $OpenBSD: ntpd.h,v 1.119 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -280,6 +280,7 @@ enum imsg_type {
IMSG_SETTIME,
IMSG_HOST_DNS,
IMSG_CONSTRAINT,
+ IMSG_CONSTRAINT_DNS,
IMSG_CTL_SHOW_STATUS,
IMSG_CTL_SHOW_PEERS,
IMSG_CTL_SHOW_PEERS_END,
@@ -302,7 +303,7 @@ enum ctl_actions {
pid_t ntp_main(int[2], int, struct ntpd_conf *, struct passwd *);
int priv_adjtime(void);
void priv_settime(double);
-void priv_host_dns(char *, u_int32_t);
+void priv_dns(int, char *, u_int32_t);
int offset_compare(const void *, const void *);
void update_scale(double);
time_t scale_interval(time_t);
@@ -345,6 +346,7 @@ int constraint_query(struct constraint *);
int constraint_dispatch_msg(struct pollfd *);
void constraint_check_child(void);
int constraint_check(double);
+void constraint_dns(u_int32_t, u_int8_t *, size_t);
/* util.c */
double gettime_corrected(void);
diff --git a/usr.sbin/ntpd/parse.y b/usr.sbin/ntpd/parse.y
index 01c35234454..e5b403b4f72 100644
--- a/usr.sbin/ntpd/parse.y
+++ b/usr.sbin/ntpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.59 2015/02/10 11:46:39 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.60 2015/02/12 01:54:57 reyk Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -251,11 +251,10 @@ main : LISTEN ON address listen_opts {
}
| CONSTRAINT FROM url {
struct constraint *p;
- struct ntp_addr *h, *next;
+ struct ntp_addr *h;
p = new_constraint();
- for (h = $3->a; h != NULL; h = next) {
- next = h->next;
+ if ((h = $3->a) != NULL) {
if (h->ss.ss_family != AF_INET &&
h->ss.ss_family != AF_INET6) {
yyerror("IPv4 or IPv6 address "
@@ -267,8 +266,8 @@ main : LISTEN ON address listen_opts {
free($3);
YYERROR;
}
- h->next = p->addr;
p->addr = h;
+ host_dns_free(h->next);
}
p->addr_head.a = p->addr;
@@ -332,16 +331,6 @@ url : STRING {
if (($$->name = strdup(hname)) == NULL)
fatal("strdup");
}
-
- if ($$->a == NULL &&
- (host_dns($$->name, &$$->a) == -1 ||
- $$->a == NULL)) {
- yyerror("could not resolve \"%s\"", $$->name);
- free($$->name);
- free($$->path);
- free($$);
- YYERROR;
- }
}
;