From e89a82629198e38e288c84eb465a6bbf13e2c16e Mon Sep 17 00:00:00 2001 From: reyk <> Date: Sun, 17 May 2015 18:31:32 +0000 Subject: [PATCH] When resolving the "constraint" (singular), store all returned IP addresses and try one after another until the connection succeeded - based on the existing mechanism of "server". "constraint" previously only tried to connect to the first returned address, aborted and skipped the constraint on failure. In difference to "constraints" (plural), it still only connects to one address at a time and not to all of them at once. Pointed out by rpe@ OK rpe@ deraadt@ --- src/usr.sbin/ntpd/constraint.c | 59 ++++++++++++++++++++-------------- src/usr.sbin/ntpd/ntpd.h | 4 ++- src/usr.sbin/ntpd/parse.y | 14 ++++---- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/usr.sbin/ntpd/constraint.c b/src/usr.sbin/ntpd/constraint.c index 24748712..fe9dc00b 100644 --- a/src/usr.sbin/ntpd/constraint.c +++ b/src/usr.sbin/ntpd/constraint.c @@ -1,4 +1,4 @@ -/* $OpenBSD: constraint.c,v 1.8 2015/04/21 01:49:19 jsg Exp $ */ +/* $OpenBSD: constraint.c,v 1.9 2015/05/17 18:31:32 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -53,8 +53,6 @@ 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 *, @@ -87,6 +85,7 @@ constraint_init(struct constraint *cstr) cstr->fd = -1; cstr->last = getmonotime(); cstr->constraint = 0; + cstr->senderrors = 0; return (constraint_addr_init(cstr)); } @@ -338,21 +337,27 @@ constraint_close(int fd) msgbuf_clear(&cstr->ibuf.w); close(cstr->fd); cstr->fd = -1; - if (cstr->senderrors) - cstr->state = STATE_INVALID; - else if (cstr->state >= STATE_QUERY_SENT) - cstr->state = STATE_DNS_DONE; - cstr->last = getmonotime(); - return (1); + if (cstr->addr == NULL || (cstr->addr = cstr->addr->next) == NULL) { + /* Either a pool or all addresses have been tried */ + cstr->addr = cstr->addr_head.a; + if (cstr->senderrors) + cstr->state = STATE_INVALID; + else if (cstr->state >= STATE_QUERY_SENT) + cstr->state = STATE_DNS_DONE; + + return (1); + } + + /* Go on and try the next resolved address for this constraint */ + return (constraint_init(cstr)); } void constraint_add(struct constraint *cstr) { TAILQ_INSERT_TAIL(&conf->constraints, cstr, entry); - constraint_cnt += constraint_init(cstr); } void @@ -362,7 +367,6 @@ constraint_remove(struct constraint *cstr) free(cstr->addr_head.name); free(cstr->addr_head.path); free(cstr); - constraint_cnt--; } int @@ -425,7 +429,7 @@ constraint_dispatch_msg(struct pollfd *pfd) void constraint_dns(u_int32_t id, u_int8_t *data, size_t len) { - struct constraint *cstr, *ncstr; + struct constraint *cstr, *ncstr = NULL; u_int8_t *p; struct ntp_addr *h; @@ -454,18 +458,25 @@ constraint_dns(u_int32_t id, u_int8_t *data, size_t len) 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); + if (ncstr == NULL || cstr->addr_head.pool) { + 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; + ncstr->state = STATE_DNS_DONE; + constraint_add(ncstr); + constraint_cnt += constraint_init(ncstr); + } else { + h->next = ncstr->addr; + ncstr->addr = h; + ncstr->addr_head.a = h; + } + } while (len); constraint_remove(cstr); } diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index 1ffd46a2..246afcdd 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.119 2015/02/12 01:54:57 reyk Exp $ */ +/* $OpenBSD: ntpd.h,v 1.120 2015/05/17 18:31:32 reyk Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -341,6 +341,8 @@ void client_log_error(struct ntp_peer *, const char *, int); void set_next(struct ntp_peer *, time_t); /* constraint.c */ +void constraint_add(struct constraint *); +void constraint_remove(struct constraint *); int constraint_init(struct constraint *); int constraint_query(struct constraint *); int constraint_dispatch_msg(struct pollfd *); diff --git a/src/usr.sbin/ntpd/parse.y b/src/usr.sbin/ntpd/parse.y index ba3d592a..1295c7c9 100644 --- a/src/usr.sbin/ntpd/parse.y +++ b/src/usr.sbin/ntpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.61 2015/02/12 23:07:52 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.62 2015/05/17 18:31:32 reyk Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -241,8 +241,7 @@ main : LISTEN ON address listen_opts { fatal(NULL); if (p->addr != NULL) p->state = STATE_DNS_DONE; - TAILQ_INSERT_TAIL(&conf->constraints, - p, entry); + constraint_add(p); h = next; } while (h != NULL); @@ -251,10 +250,11 @@ main : LISTEN ON address listen_opts { } | CONSTRAINT FROM url { struct constraint *p; - struct ntp_addr *h; + struct ntp_addr *h, *next; p = new_constraint(); - if ((h = $3->a) != NULL) { + for (h = $3->a; h != NULL; h = next) { + next = h->next; if (h->ss.ss_family != AF_INET && h->ss.ss_family != AF_INET6) { yyerror("IPv4 or IPv6 address " @@ -266,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; @@ -279,7 +279,7 @@ main : LISTEN ON address listen_opts { fatal(NULL); if (p->addr != NULL) p->state = STATE_DNS_DONE; - TAILQ_INSERT_TAIL(&conf->constraints, p, entry); + constraint_add(p); free($3->name); free($3); }