Browse Source

rework dns handling with all its cosequences...

we know have both a "server" and "servers" keyword. they differ when the
hostname resolves to more than one IP, server picks one and servers expands
to all.
that means no longer stuffing a sockaddr_storage into ntp_peer but a pointer
to a linked list of ntp_addr structs.
in the "servers" case the list of n addresses returned by host() is expanded
into n ntp_peer structs and thus n individual peers.
in the "server" case the whole list is attached to ntp_peer, and whenever we
do not receive a reply in time we traverse the list one further, so that
hosts with both AAAA and A records are first tried with the AAAA one but
we gracefully fall back to the A one.
semantics with theo; hacked up on the Montreal->Frankfurt flight.
again Air Canada surprised me, that older 767 hat pretty decent seats.
OPENBSD_3_6
henning 20 years ago
parent
commit
cf385f93cd
4 changed files with 76 additions and 33 deletions
  1. +38
    -18
      src/usr.sbin/ntpd/client.c
  2. +6
    -5
      src/usr.sbin/ntpd/ntp.c
  3. +4
    -2
      src/usr.sbin/ntpd/ntpd.h
  4. +28
    -8
      src/usr.sbin/ntpd/parse.y

+ 38
- 18
src/usr.sbin/ntpd/client.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: client.c,v 1.17 2004/07/08 01:20:21 henning Exp $ */
/* $OpenBSD: client.c,v 1.18 2004/07/09 10:53:33 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -31,27 +31,30 @@ client_peer_init(struct ntp_peer *p)
{
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
struct ntp_addr *h;
if ((p->query = calloc(1, sizeof(struct ntp_query))) == NULL)
fatal("client_query calloc");
switch (p->ss.ss_family) {
case AF_INET:
sa_in = (struct sockaddr_in *)&p->ss;
if (ntohs(sa_in->sin_port) == 0)
sa_in->sin_port = htons(123);
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *)&p->ss;
if (ntohs(sa_in6->sin6_port) == 0)
sa_in6->sin6_port = htons(123);
break;
default:
fatal("king bula sez: wrong AF in client_peer_init");
/* not reached */
for (h = p->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(123);
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *)&h->ss;
if (ntohs(sa_in6->sin6_port) == 0)
sa_in6->sin6_port = htons(123);
break;
default:
fatal("king bula sez: wrong AF in client_peer_init");
/* not reached */
}
}
if ((p->query->fd = socket(p->ss.ss_family, SOCK_DGRAM, 0)) == -1)
if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM, 0)) == -1)
fatal("client_query socket");
p->query->msg.status = MODE_CLIENT | (NTP_VERSION << 3);
@ -63,6 +66,23 @@ client_peer_init(struct ntp_peer *p)
return (0);
}
int
client_nextaddr(struct ntp_peer *p)
{
close(p->query->fd);
if ((p->addr = p->addr->next) == NULL)
p->addr = p->addr_head;
if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM, 0)) == -1)
fatal("client_query socket");
p->shift = 0;
p->trustlevel = TRUSTLEVEL_PATHETIC;
return (0);
}
int
client_query(struct ntp_peer *p)
{
@ -84,8 +104,8 @@ client_query(struct ntp_peer *p)
p->query->msg.xmttime.fraction = arc4random();
p->query->xmttime = gettime();
ntp_sendmsg(p->query->fd, (struct sockaddr *)&p->ss, &p->query->msg,
NTP_MSGSIZE_NOAUTH, 0);
ntp_sendmsg(p->query->fd, (struct sockaddr *)&p->addr->ss,
&p->query->msg, NTP_MSGSIZE_NOAUTH, 0);
p->state = STATE_QUERY_SENT;
p->next = 0;
p->deadline = time(NULL) + QUERYTIME_MAX;


+ 6
- 5
src/usr.sbin/ntpd/ntp.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntp.c,v 1.18 2004/07/09 10:22:07 henning Exp $ */
/* $OpenBSD: ntp.c,v 1.19 2004/07/09 10:53:33 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -164,7 +164,6 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *conf)
TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
if (p->next > 0 && p->next < nextaction)
nextaction = p->next;
if (p->next > 0 && p->next <= time(NULL))
client_query(p);
@ -172,12 +171,14 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *conf)
nextaction = p->deadline;
if (p->deadline > 0 && p->deadline <= time(NULL)) {
log_debug("no reply from %s received in time",
log_sockaddr((struct sockaddr *)&p->ss));
log_sockaddr(
(struct sockaddr *)&p->addr->ss));
if (p->trustlevel >= TRUSTLEVEL_BADPEER &&
--p->trustlevel < TRUSTLEVEL_BADPEER)
log_info("peer %s now invalid",
log_sockaddr(
(struct sockaddr *)&p->ss));
(struct sockaddr *)&p->addr->ss));
client_nextaddr(p);
client_query(p);
}
@ -324,7 +325,7 @@ get_peer_update(struct ntp_peer *p, double *offset)
if (good < 8 && p->trustlevel > 0) {
if (p->trustlevel >= TRUSTLEVEL_BADPEER)
log_info("peer %s now invalid",
log_sockaddr((struct sockaddr *)&p->ss));
log_sockaddr((struct sockaddr *)&p->addr->ss));
p->trustlevel /= 2;
}


+ 4
- 2
src/usr.sbin/ntpd/ntpd.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntpd.h,v 1.18 2004/07/08 01:22:57 henning Exp $ */
/* $OpenBSD: ntpd.h,v 1.19 2004/07/09 10:53:33 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -76,7 +76,8 @@ struct ntp_offset {
struct ntp_peer {
TAILQ_ENTRY(ntp_peer) entry;
struct sockaddr_storage ss;
struct ntp_addr *addr_head;
struct ntp_addr *addr;
struct ntp_query *query;
enum client_state state;
time_t next;
@ -197,6 +198,7 @@ int server_dispatch(int fd);
/* client.c */
int client_peer_init(struct ntp_peer *);
int client_nextaddr(struct ntp_peer *);
int client_query(struct ntp_peer *);
int client_dispatch(struct ntp_peer *);


+ 28
- 8
src/usr.sbin/ntpd/parse.y View File

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.9 2004/07/08 15:06:43 henning Exp $ */
/* $OpenBSD: parse.y,v 1.10 2004/07/09 10:53:33 henning Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -77,7 +77,7 @@ typedef struct {
%}
%token LISTEN ON
%token SERVER
%token SERVER SERVERS
%token ERROR
%token <v.string> STRING
%type <v.number> number
@ -146,7 +146,7 @@ conf_main : LISTEN ON address {
free(h);
}
}
| SERVER address {
| SERVERS address {
struct ntp_peer *p;
struct ntp_addr *h, *next;
@ -161,12 +161,32 @@ conf_main : LISTEN ON address {
p = calloc(1, sizeof(struct ntp_peer));
if (p == NULL)
fatal("conf_main server calloc");
memcpy(&p->ss, &h->ss,
sizeof(struct sockaddr_storage));
h->next = NULL;
p->addr = h;
TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
free(h);
}
}
| SERVER address {
struct ntp_peer *p;
struct ntp_addr *h, *next;
if ((p = calloc(1, sizeof(struct ntp_peer))) == NULL)
fatal("conf_main server calloc");
for (h = $2; 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 "
"or hostname expected");
YYERROR;
}
h->next = p->addr;
p->addr = h;
}
p->addr_head = p->addr;
TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
}
;
address : STRING {
@ -216,7 +236,8 @@ lookup(char *s)
static const struct keywords keywords[] = {
{ "listen", LISTEN},
{ "on", ON},
{ "server", SERVER}
{ "server", SERVER},
{ "servers", SERVERS}
};
const struct keywords *p;
@ -434,7 +455,6 @@ parse_config(char *filename, struct ntpd_conf *xconf)
if ((fin = fopen(filename, "r")) == NULL) {
log_warn("%s", filename);
free(conf);
return (-1);
}
infile = filename;


Loading…
Cancel
Save