From 3303745ec61f1ec5879d63779fb84bf229a2c4e8 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@ --- usr.sbin/ntpd/constraint.c | 59 ++++++++++++++++++++++---------------- usr.sbin/ntpd/ntpd.h | 4 ++- usr.sbin/ntpd/parse.y | 14 ++++----- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/usr.sbin/ntpd/constraint.c b/usr.sbin/ntpd/constraint.c index 24748712bef..fe9dc00b09e 100644 --- a/usr.sbin/ntpd/constraint.c +++ b/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/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h index 1ffd46a279f..246afcdd21b 100644 --- a/usr.sbin/ntpd/ntpd.h +++ b/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/usr.sbin/ntpd/parse.y b/usr.sbin/ntpd/parse.y index ba3d592a29e..1295c7c9611 100644 --- a/usr.sbin/ntpd/parse.y +++ b/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); } -- 2.20.1