address for outgoing ntp queries.
From Job Snijders, thanks!
with feedback and ok henning@
-/* $OpenBSD: client.c,v 1.104 2016/09/03 11:52:06 reyk Exp $ */
+/* $OpenBSD: client.c,v 1.105 2017/05/30 23:30:48 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
if (p->query->fd == -1) {
struct sockaddr *sa = (struct sockaddr *)&p->addr->ss;
+ struct sockaddr *qa4 = (struct sockaddr *)&p->query_addr4;
+ struct sockaddr *qa6 = (struct sockaddr *)&p->query_addr6;
if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM,
0)) == -1)
fatal("client_query socket");
+ if (p->addr->ss.ss_family == qa4->sa_family) {
+ if (bind(p->query->fd, qa4, SA_LEN(qa4)) == -1)
+ fatal("couldn't bind to IPv4 query address: %s",
+ log_sockaddr(qa4));
+ } else if (p->addr->ss.ss_family == qa6->sa_family) {
+ if (bind(p->query->fd, qa6, SA_LEN(qa6)) == -1)
+ fatal("couldn't bind to IPv6 query address: %s",
+ log_sockaddr(qa6));
+ }
+
if (connect(p->query->fd, sa, SA_LEN(sa)) == -1) {
if (errno == ECONNREFUSED || errno == ENETUNREACH ||
errno == EHOSTUNREACH || errno == EADDRNOTAVAIL) {
-/* $OpenBSD: ntp.c,v 1.145 2017/01/20 01:21:18 phessler Exp $ */
+/* $OpenBSD: ntp.c,v 1.146 2017/05/30 23:30:48 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
if (peer->addr_head.pool) {
npeer = new_peer();
npeer->weight = peer->weight;
+ npeer->query_addr4 = peer->query_addr4;
+ npeer->query_addr6 = peer->query_addr6;
h->next = NULL;
npeer->addr = h;
npeer->addr_head.a = h;
-.\" $OpenBSD: ntpd.conf.5,v 1.34 2016/12/30 10:24:15 jmc Exp $
+.\" $OpenBSD: ntpd.conf.5,v 1.35 2017/05/30 23:30:48 benno Exp $
.\"
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\"
.\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: December 30 2016 $
+.Dd $Mdocdate: May 30 2017 $
.Dt NTPD.CONF 5
.Os
.Sh NAME
listen on 127.0.0.1
listen on ::1
listen on 127.0.0.1 rtable 4
+.It Xo Ic query from Ar address
+.Xc
+Specify a Local IP address the
+.Xr ntpd 8
+daemon should use for outgoing queries.
+.Bd -literal -offset indent
+query from 192.0.2.1
+query from 2001:db8::1
.Ed
.It Xo Ic sensor Ar device
.Op Ic correction Ar microseconds
-/* $OpenBSD: ntpd.h,v 1.134 2017/01/09 14:49:22 reyk Exp $ */
+/* $OpenBSD: ntpd.h,v 1.135 2017/05/30 23:30:48 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
struct ntp_query *query;
struct ntp_offset reply[OFFSET_ARRAY_SIZE];
struct ntp_offset update;
+ struct sockaddr_in query_addr4;
+ struct sockaddr_in6 query_addr6;
enum client_state state;
time_t next;
time_t deadline;
TAILQ_HEAD(constraints, constraint) constraints;
struct ntp_status status;
struct ntp_freq freq;
+ struct sockaddr_in query_addr4;
+ struct sockaddr_in6 query_addr6;
u_int32_t scale;
int debug;
int verbose;
-/* $OpenBSD: parse.y,v 1.65 2015/10/31 19:32:18 naddy Exp $ */
+/* $OpenBSD: parse.y,v 1.66 2017/05/30 23:30:48 benno Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
int findeol(void);
struct ntpd_conf *conf;
+struct sockaddr_in query_addr4;
+struct sockaddr_in6 query_addr6;
struct opts {
int weight;
%}
-%token LISTEN ON CONSTRAINT CONSTRAINTS FROM
+%token LISTEN ON CONSTRAINT CONSTRAINTS FROM QUERY
%token SERVER SERVERS SENSOR CORRECTION RTABLE REFID STRATUM WEIGHT
%token ERROR
%token <v.string> STRING
free($3->name);
free($3);
}
+ | QUERY FROM STRING {
+ struct sockaddr_in sin4;
+ struct sockaddr_in6 sin6;
+
+ sin4.sin_family = AF_INET;
+ sin4.sin_len = sizeof(struct sockaddr_in);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+
+ if (inet_pton(AF_INET, $3, &sin4.sin_addr) == 1)
+ memcpy(&query_addr4, &sin4, sin4.sin_len);
+ else if (inet_pton(AF_INET6, $3, &sin6.sin6_addr) == 1)
+ memcpy(&query_addr6, &sin6, sin6.sin6_len);
+ else {
+ yyerror("invalid IPv4 or IPv6 address: %s\n",
+ $3);
+ free($3);
+ YYERROR;
+ }
+
+ free($3);
+ }
| SERVERS address server_opts {
struct ntp_peer *p;
struct ntp_addr *h, *next;
p = new_peer();
p->weight = $3.weight;
+ p->query_addr4 = query_addr4;
+ p->query_addr6 = query_addr6;
p->addr = h;
p->addr_head.a = h;
p->addr_head.pool = 1;
}
p->weight = $3.weight;
+ p->query_addr4 = query_addr4;
+ p->query_addr6 = query_addr6;
p->addr_head.a = p->addr;
p->addr_head.pool = 0;
p->addr_head.name = strdup($2->name);
{ "from", FROM},
{ "listen", LISTEN},
{ "on", ON},
+ { "query", QUERY},
{ "refid", REFID},
{ "rtable", RTABLE},
{ "sensor", SENSOR},