Author: Otto Moerbeek <otto@openbsd.org> and Sergey B Kirpichev <skirpichev@gmail.com>
Description: Dies if none peer servername is invalid, and logs badpeers through syslog critical.
 This patch provides two differnt solutions for badpeer(s) non handled by default:
 1. Exit, if there is no peers at all (no server(s) directive) or if badpeers.
 2. Dump peer info to syslog with LOG_CRIT periodically, if badpeers > half of the
    total number of peers

Index: openntpd-3.9p1+debian/ntp.c
===================================================================
--- openntpd-3.9p1+debian.orig/ntp.c	2009-02-01 20:41:19.000000000 +0300
+++ openntpd-3.9p1+debian/ntp.c	2009-02-01 20:50:33.000000000 +0300
@@ -44,14 +44,17 @@
 #define	PFD_MAX		1
 
 volatile sig_atomic_t	 ntp_quit = 0;
+volatile sig_atomic_t  ntp_report = 0;
 struct imsgbuf		*ibuf_main;
 struct ntpd_conf	*conf;
 u_int			 peer_cnt;
+time_t lastreport;
 
 void	ntp_sighdlr(int);
 int	ntp_dispatch_imsg(void);
 void	peer_add(struct ntp_peer *);
 void	peer_remove(struct ntp_peer *);
+void  report_peers(int);
 int	offset_compare(const void *, const void *);
 
 void
@@ -62,6 +65,9 @@
 	case SIGTERM:
 		ntp_quit = 1;
 		break;
+	case SIGUSR1:
+		ntp_report = 1;
+		break;
 	}
 }
 
@@ -139,6 +145,7 @@
 
 	signal(SIGTERM, ntp_sighdlr);
 	signal(SIGINT, ntp_sighdlr);
+	signal(SIGUSR1, ntp_sighdlr);
 	signal(SIGPIPE, SIG_IGN);
 	signal(SIGHUP, SIG_IGN);
 
@@ -165,6 +172,15 @@
 	TAILQ_FOREACH(p, &conf->ntp_peers, entry)
 		peer_cnt++;
 
+	/* wait 5 min before reporting first status to let things settle down */
+	lastreport = time(NULL) + (5 * 60) - REPORT_INTERVAL;
+
+	/* trivial error, no server(s) in config file */
+	if (peer_cnt == 0) {
+		log_warnx("no valid peers");
+		ntp_quit = 1;
+	}
+
 	while (ntp_quit == 0) {
 		if (peer_cnt > idx2peer_elms) {
 			if ((newp = realloc(idx2peer, sizeof(void *) *
@@ -283,6 +299,9 @@
 				    conf->settime) == -1)
 					ntp_quit = 1;
 			}
+
+		report_peers(ntp_report);
+		ntp_report = 0;
 	}
 
 	msgbuf_write(&ibuf_main->w);
@@ -361,6 +380,9 @@
 					h->next = NULL;
 					npeer->addr = h;
 					npeer->addr_head.a = h;
+					npeer->addr_head.name =
+					    peer->addr_head.name;
+					npeer->addr_head.pool = 1;
 					client_peer_init(npeer);
 					npeer->state = STATE_DNS_DONE;
 					peer_add(npeer);
@@ -546,3 +568,43 @@
 	return (interval + r);
 }
 
+void
+report_peers(int always)
+{
+	time_t now;
+	u_int badpeers = 0;
+	struct ntp_peer *p;
+
+	TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
+		if (p->trustlevel < TRUSTLEVEL_BADPEER)
+			badpeers++;
+	}
+
+	now = time(NULL);
+	if (!always) {
+		if (peer_cnt == 0 || badpeers == 0 || badpeers < peer_cnt / 2)
+			return;
+
+		if (lastreport + REPORT_INTERVAL > now)
+			return;
+	}
+	lastreport = now;
+	if (peer_cnt > 0) {
+		log_warnx("%u out of %u peers valid", peer_cnt - badpeers,
+		    peer_cnt);
+		TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
+			if (p->trustlevel < TRUSTLEVEL_BADPEER) {
+				const char *a = "not resolved";
+				const char *pool = "";
+				if (p->addr)
+					a = log_sockaddr(
+					    (struct sockaddr *)&p->addr->ss);
+				if (p->addr_head.pool)
+					pool = "from pool ";
+				log_warnx("bad peer %s%s (%s)",  pool,
+				    p->addr_head.name, a);
+			}
+		}
+	}
+}
+
Index: openntpd-3.9p1+debian/ntpd.h
===================================================================
--- openntpd-3.9p1+debian.orig/ntpd.h	2009-02-01 20:41:24.000000000 +0300
+++ openntpd-3.9p1+debian/ntpd.h	2009-02-01 20:41:24.000000000 +0300
@@ -61,6 +61,7 @@
 #define	SETTIME_MIN_OFFSET	180	/* min offset for settime at start */
 #define	SETTIME_TIMEOUT		15	/* max seconds to wait with -s */
 #define	LOG_NEGLIGEE		128	/* negligible drift to not log (ms) */
+#define REPORT_INTERVAL          (24*60*60) /* interval between status reports */
 
 enum client_state {
 	STATE_NONE,
Index: openntpd-3.9p1+debian/ntpd.8
===================================================================
--- openntpd-3.9p1+debian.orig/ntpd.8	2009-02-01 20:41:24.000000000 +0300
+++ openntpd-3.9p1+debian/ntpd.8	2009-02-01 20:41:24.000000000 +0300
@@ -61,6 +61,13 @@
 typically
 .Xr ntpd.conf 5 .
 .Pp
+When
+.Nm
+receives a
+.Dv SIGUSR1
+signal, it writes its peer status to
+.Xr syslog 3 .
+.Pp
 The options are as follows:
 .Bl -tag -width "-f fileXXX"
 .It Fl d
