summaryrefslogtreecommitdiff
path: root/usr.sbin/ntpd/constraint.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ntpd/constraint.c')
-rw-r--r--usr.sbin/ntpd/constraint.c142
1 files changed, 118 insertions, 24 deletions
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)
{