[Git][NTPsec/ntpsec][master] 3 commits: Add attic/random.c, fix backwards to use CLOCK_REALTIME

Hal Murray gitlab at mg.gitlab.com
Sun Dec 8 13:08:04 UTC 2019



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
16a2c0c2 by Hal Murray at 2019-12-08T13:07:27Z
Add attic/random.c, fix backwards to use CLOCK_REALTIME

- - - - -
19b89c98 by Hal Murray at 2019-12-08T13:07:27Z
Remove NO_MAIN_ALLOWED and HAVE_WORKING_FORK (just clutter)

- - - - -
22c134c8 by Hal Murray at 2019-12-08T13:07:27Z
Clean up NTS-KE client ALPN checking.
  ALPN is now required if using TLSv1.3
  It is not required if using TLSv1.2 (not supported)

- - - - -


10 changed files:

- NEWS.adoc
- attic/backwards.c
- + attic/random.c
- attic/wscript
- include/ntp_machine.h
- include/ntpd.h
- ntpd/ntp_proto.c
- ntpd/ntpd.c
- ntpd/nts_client.c
- wscript


Changes:

=====================================
NEWS.adoc
=====================================
@@ -12,6 +12,8 @@ on user-visible changes.
 
 == 2019-11-17: 1.1.8 ==
 
+NTS client now requires ALPN on TLSv1.3.
+
 Fix bug in NTS-KE client so that NTP server names work.
 
 Fix/tweak several NTS logging messages.


=====================================
attic/backwards.c
=====================================
@@ -31,10 +31,10 @@ main(int argc, char *argv[])
 	/* Some systems return equal.
 	 * Print first 5 equal examples. */
 	for(int equal = 0; equal < 5; ) {
-		clock_gettime(CLOCK_MONOTONIC, &ts0);  /* warm up cache */
-		clock_gettime(CLOCK_MONOTONIC, &ts1);
-		clock_gettime(CLOCK_MONOTONIC, &ts0);
-		clock_gettime(CLOCK_MONOTONIC, &ts1);
+		clock_gettime(CLOCK_REALTIME, &ts0);  /* warm up cache */
+		clock_gettime(CLOCK_REALTIME, &ts1);
+		clock_gettime(CLOCK_REALTIME, &ts0);
+		clock_gettime(CLOCK_REALTIME, &ts1);
 
 		if ((ts0.tv_sec < ts1.tv_sec) ||
 		    ((ts0.tv_sec == ts1.tv_sec) &&
@@ -49,10 +49,10 @@ main(int argc, char *argv[])
 	}
 
 	for(;;) {
-		clock_gettime(CLOCK_MONOTONIC, &ts0);  /* warm up cache */
-		clock_gettime(CLOCK_MONOTONIC, &ts1);
-		clock_gettime(CLOCK_MONOTONIC, &ts0);
-		clock_gettime(CLOCK_MONOTONIC, &ts1);
+		clock_gettime(CLOCK_REALTIME, &ts0);  /* warm up cache */
+		clock_gettime(CLOCK_REALTIME, &ts1);
+		clock_gettime(CLOCK_REALTIME, &ts0);
+		clock_gettime(CLOCK_REALTIME, &ts1);
 
 		if ((ts0.tv_sec < ts1.tv_sec) ||
 		    ((ts0.tv_sec == ts1.tv_sec) &&


=====================================
attic/random.c
=====================================
@@ -0,0 +1,247 @@
+/* Last modified on Sat Aug 28 14:30:11 PDT 1999 by murray */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "ntp.h"
+
+#define BATCHSIZE 1000000
+#define BILLION 1000000000
+#define HISTSIZE 2500
+#define NSPERBUCKET 1
+#define MAXHISTLINES 10
+
+/* hack for libntp */
+const char *progname = "foo";
+
+int do_average(void);
+int do_average(void) {
+	long int sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos;
+
+	clock_gettime(CLOCK_REALTIME, &start);
+	for (int i = 0; i < BATCHSIZE; i++) {
+		sum += random();
+	}
+	clock_gettime(CLOCK_REALTIME, &stop);
+
+	/* Beware of overflowing 32 bits. */
+	sec = (stop.tv_sec-start.tv_sec);
+	nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+	return nanos/BATCHSIZE;
+}
+
+int do_average32(void);
+int do_average32(void) {
+	int32_t sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos;
+
+	clock_gettime(CLOCK_REALTIME, &start);
+	for (int i = 0; i < BATCHSIZE; i++) {
+		sum += ntp_random();
+	}
+	clock_gettime(CLOCK_REALTIME, &stop);
+
+	/* Beware of overflowing 32 bits. */
+	sec = (stop.tv_sec-start.tv_sec);
+	nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+	return nanos/BATCHSIZE;
+}
+
+int do_average64(void);
+int do_average64(void) {
+	uint64_t sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos;
+
+	clock_gettime(CLOCK_REALTIME, &start);
+	for (int i = 0; i < BATCHSIZE; i++) {
+		sum += ntp_random64();
+	}
+	clock_gettime(CLOCK_REALTIME, &stop);
+
+	/* Beware of overflowing 32 bits. */
+	sec = (stop.tv_sec-start.tv_sec);
+	nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+	return nanos/BATCHSIZE;
+}
+
+int do_fastest(void);
+int do_fastest(void) {
+	int sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos, fastest;
+
+	fastest = 999999999;
+	for (int i = 0; i < BATCHSIZE; i++) {
+                clock_gettime(CLOCK_REALTIME, &start);
+		sum += random();
+		clock_gettime(CLOCK_REALTIME, &stop);
+		sec = (stop.tv_sec-start.tv_sec);
+		nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+		if (nanos < fastest) {
+			fastest = nanos;
+		}
+	}
+
+	return fastest;
+}
+
+int do_fastest32(void);
+int do_fastest32(void) {
+	int sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos, fastest;
+
+	fastest = 999999999;
+	for (int i = 0; i < BATCHSIZE; i++) {
+                clock_gettime(CLOCK_REALTIME, &start);
+		sum += ntp_random();
+		clock_gettime(CLOCK_REALTIME, &stop);
+		sec = (stop.tv_sec-start.tv_sec);
+		nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+		if (nanos < fastest) {
+			fastest = nanos;
+		}
+	}
+
+	return fastest;
+}
+
+int do_fastest64(void);
+int do_fastest64(void) {
+	uint64_t sum = 0;
+	struct timespec start, stop;
+	uint64_t sec, nanos, fastest;
+
+	fastest = 999999999;
+	for (int i = 0; i < BATCHSIZE; i++) {
+                clock_gettime(CLOCK_REALTIME, &start);
+		sum += ntp_random64();
+		clock_gettime(CLOCK_REALTIME, &stop);
+		sec = (stop.tv_sec-start.tv_sec);
+		nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+		if (nanos < fastest) {
+			fastest = nanos;
+		}
+	}
+
+	return fastest;
+}
+
+int dups = 0;
+int do_hist(int type, int fastest);
+int do_hist(int type, int fastest) {
+	int nsPerBucket = NSPERBUCKET;
+	int i;
+	int delta, lines, toobig, hits, miss;
+	struct timespec start, stop;
+	int64_t sec, nanos;
+	unsigned int hist[HISTSIZE];
+	int faster = 0;
+
+	toobig = 0;
+	for (i = 0; i < HISTSIZE; i++) {
+		hist[i] = 0;
+	}
+
+	for (i = 0; i < BATCHSIZE; i++) {
+		clock_gettime(type, &start);  /* warm up cache */
+		clock_gettime(type, &stop);
+		clock_gettime(type, &start);
+		clock_gettime(type, &stop);
+		sec = (stop.tv_sec-start.tv_sec);
+		nanos = sec*BILLION + (stop.tv_nsec-start.tv_nsec);
+		if (0 > nanos) {
+			printf("## Time went backwards: %ld.%9ld-%ld.%9ld=>%ld\n",
+			       (long)stop.tv_sec, stop.tv_nsec,
+			       (long)start.tv_sec, start.tv_nsec,
+			       (long)nanos);
+			continue;
+		}
+		if (0 == nanos) {
+			/* I've seen this on Pi 1. */
+			dups++;
+			continue;
+		}
+		delta = (nanos-fastest) / nsPerBucket;
+		if (0 > delta) {
+			/* fastest wasn't fast enough */
+			if (0 == faster) {
+				faster = delta;
+			}
+			if (faster > delta) {
+				faster = delta;
+			}
+			continue;
+		}
+		if (delta < HISTSIZE) {
+			hist[delta]++;
+		} else {
+			toobig++;
+		}
+	}
+	if (faster) { return faster;
+	}
+	printf("\n");
+	printf("Histogram: CLOCK_REALTIME, %d ns per bucket, %d samples.\n",
+	       nsPerBucket, BATCHSIZE);
+	printf("        ns      hits\n");
+	lines = 0;
+	hits = 0;
+	for (i=0; i<HISTSIZE; i++) {
+		if ((MAXHISTLINES <= lines) && (0.98*BATCHSIZE < hits)) {
+			break;  /* Avoid clutter of printing long tail */
+		}
+		if (hist[i]) {
+			printf("%10d  %8u\n", i*nsPerBucket+fastest, hist[i]);
+			lines++;
+			hits += hist[i];
+		}
+	}
+	miss = i-1;
+	for (  ; i<HISTSIZE; i++) {
+		toobig += hist[i];
+	}
+
+	if (dups) {
+		printf("%d samples were duplicated.\n", dups);
+	}
+	if (toobig) { printf("%d samples were bigger than %d.\n",
+			     toobig, miss*nsPerBucket+fastest);
+	}
+	return faster;
+}
+
+
+int main(int argc, char *argv[]) {
+	int average, fastest;
+
+	(void)argc;  /* Squash unused warnings */
+	(void)argv;
+
+	printf("                  avg  fastest\n");
+
+	average = do_average();
+	fastest = do_fastest();
+	printf("random():       %5d %8d\n", average, fastest);
+	fflush(stdout);
+
+	average = do_average32();
+	fastest = do_fastest32();
+	printf("ntp_random():   %5d %8d\n", average, fastest);
+	fflush(stdout);
+
+	average = do_average64();
+	fastest = do_fastest64();
+	printf("ntp_random64(): %5d %8d\n", average, fastest);
+	fflush(stdout);
+
+	return 0;
+
+}
+


=====================================
attic/wscript
=====================================
@@ -1,5 +1,7 @@
 def build(ctx):
-    util = ['sht', 'digest-find', 'digest-timing', 'clocks', 'backwards']
+    util = [	'sht',
+		'digest-find', 'digest-timing', 'clocks', 'random',
+		'backwards']
 
     for name in util:
         ctx(


=====================================
include/ntp_machine.h
=====================================
@@ -24,48 +24,4 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp);
 
 int ntp_set_tod (struct timespec *tvs);
 
-#ifdef NO_MAIN_ALLOWED
-/* we have no main routines so lets make a plan */
-#define CALL(callname, progname, callmain) \
-	extern int callmain (int,char**); \
-	void callname (a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
-		char *a0;  \
-		char *a1;  \
-		char *a2;  \
-		char *a3;  \
-		char *a4;  \
-		char *a5;  \
-		char *a6;  \
-		char *a7;  \
-		char *a8;  \
-		char *a9;  \
-		char *a10; \
-	{ \
-	  char *x[11]; \
-	  int argc; \
-	  char *argv[] = {progname,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; \
-	  int i; \
-	  for (i=0;i<11;i++) \
-	   x[i] = NULL; \
-	  x[0] = a0; \
-	  x[1] = a1; \
-	  x[2] = a2; \
-	  x[3] = a3; \
-	  x[4] = a4; \
-	  x[5] = a5; \
-	  x[6] = a6; \
-	  x[7] = a7; \
-	  x[8] = a8; \
-	  x[9] = a9; \
-	  x[10] = a10; \
-	  argc=1; \
-	  for (i=0; i<11;i++) \
-		if (x[i]) \
-		{ \
-		  argv[argc++] = x[i];	\
-		} \
-	 callmain(argc,argv);  \
-	}
-#endif /* NO_MAIN_ALLOWED */
-
 #endif	/* GUARD_NTP_MACHINE_H */


=====================================
include/ntpd.h
=====================================
@@ -432,9 +432,7 @@ extern	bool	stats_control;		/* write stats to fileset? */
 extern	double	wander_threshold;
 
 /* ntpd.c */
-#ifdef HAVE_WORKING_FORK
 extern	int	waitsync_fd_to_close;	/* -w/--wait-sync */
-#endif
 
 /* refclock_conf.c */
 #ifdef REFCLOCK


=====================================
ntpd/ntp_proto.c
=====================================
@@ -1103,13 +1103,11 @@ clock_update(
 			 * If our parent process is waiting for the
 			 * first clock sync, send them home satisfied.
 			 */
-#ifdef HAVE_WORKING_FORK
 			if (waitsync_fd_to_close != -1) {
 				close(waitsync_fd_to_close);
 				waitsync_fd_to_close = -1;
 				DPRINT(1, ("notified parent --wait-sync is done\n"));
 			}
-#endif /* HAVE_WORKING_FORK */
 
 		}
 


=====================================
ntpd/ntpd.c
=====================================
@@ -78,15 +78,11 @@ static char *user;		/* User to switch to */
 static char *group;		/* group to switch to */
 static const char *chrootdir;	/* directory to chroot to */
 
-#ifdef HAVE_WORKING_FORK
 int	waitsync_fd_to_close = -1;	/* -w/--wait-sync */
-#endif
 
 const char *progname;
 
-#if defined(HAVE_WORKING_FORK)
 static int	wait_child_sync_if	(int, long);
-#endif
 
 static	void	catchHUP	(int);
 static	void	catchDNS	(int);
@@ -101,7 +97,6 @@ static	void	no_debug	(int);
 static int	saved_argc;
 static char **	saved_argv;
 
-static int	ntpdmain(int, char **) __attribute__((noreturn));
 static void	mainloop		(void)
 			__attribute__	((__noreturn__));
 static void	set_process_priority	(void);
@@ -412,19 +407,6 @@ parse_cmdline_opts(
 	}
 }
 
-#ifdef NO_MAIN_ALLOWED
-CALL(ntpd,"ntpd",ntpdmain);
-#else	/* !NO_MAIN_ALLOWED follows */
-int
-main(
-	int argc,
-	char *argv[]
-	)
-{
-	return ntpdmain(argc, argv);
-}
-#endif /* !NO_MAIN_ALLOWED */
-
 #ifdef SIGDANGER
 /*
  * Signal handler for SIGDANGER. (AIX)
@@ -490,20 +472,18 @@ const char *ntpd_version(void)
  * Main program.  Initialize us, disconnect us from the tty if necessary,
  * and loop waiting for I/O and/or timer expiries.
  */
-static int
-ntpdmain(
+int
+main(
 	int argc,
 	char *argv[]
 	)
 {
 	mode_t		uv;
 	uid_t		uid;
-# if defined(HAVE_WORKING_FORK)
 	int		pipe_fds[2];
 	int		rc;
 	int		exit_code;
 	struct sigaction sa;
-# endif	/* HAVE_WORKING_FORK*/
 	int op;
 
 	uv = umask(0);
@@ -548,7 +528,6 @@ ntpdmain(
 
 	set_prettydate_pivot(time(NULL));
 
-# ifdef HAVE_WORKING_FORK
 	/* make sure the FDs are initialised */
 	pipe_fds[0] = -1;
 	pipe_fds[1] = -1;
@@ -567,7 +546,6 @@ ntpdmain(
 	    }
 	    waitsync_fd_to_close = pipe_fds[1];
 	}
-# endif	/* HAVE_WORKING_FORK */
 
 	init_network();
 	/*
@@ -575,7 +553,6 @@ ntpdmain(
 	 */
 	if (!nofork) {
 
-# ifdef HAVE_WORKING_FORK
 		rc = fork();
 		if (-1 == rc) {
 			exit_code = (errno) ? errno : -1;
@@ -606,14 +583,13 @@ ntpdmain(
 
 		if (setsid() == (pid_t)-1)
 			msyslog(LOG_ERR, "INIT: setsid(): %s", strerror(errno));
-#  ifdef SIGDANGER
+#ifdef SIGDANGER
 		/* Don't get killed by low-on-memory signal. */
 		sa.sa_handler = catch_danger;
 		sigemptyset(&sa.sa_mask);
 		sa.sa_flags = SA_RESTART;
 		sigaction(SIGDANGER, &sa, NULL);
-#  endif	/* SIGDANGER */
-# endif		/* HAVE_WORKING_FORK */
+#endif	/* SIGDANGER */
 	}
 
 	/* Ignore SIGPIPE - from OpenSSL */
@@ -1063,7 +1039,6 @@ static void catchDNS(int sig)
 /*
  * wait_child_sync_if - implements parent side of -w/--wait-sync
  */
-# ifdef HAVE_WORKING_FORK
 static int
 wait_child_sync_if(
 	int	pipe_read_fd,
@@ -1127,7 +1102,6 @@ wait_child_sync_if(
 		progname, wait_sync1);
 	return ETIMEDOUT;
 }
-# endif	/* HAVE_WORKING_FORK */
 
 
 /*


=====================================
ntpd/nts_client.c
=====================================
@@ -395,39 +395,41 @@ bool check_certificate(SSL *ssl, struct peer* peer) {
 bool check_aead(SSL *ssl, struct peer* peer, const char *hostname) {
 	UNUSED_ARG(peer);
 #if (OPENSSL_VERSION_NUMBER > 0x1000200fL)
-	bool bad = true;  /* Always return OK for now. */
 	const unsigned char *data;
 	unsigned int len;
-	unsigned int i;
-	char buff [100];
 	SSL_get0_alpn_selected(ssl, &data, &len);
 	if (0 == len) {
 		/* This happens when talking to old/TLSv1.2 systems. */
+		if (TLS1_2_VERSION == SSL_version(ssl)) {
+			msyslog(LOG_DEBUG, "NTSc: No ALPN from %s, TLSv1.2",
+			hostname);
+			return true;
+		}
 		msyslog(LOG_DEBUG, "NTSc: No ALPN from %s (%s)",
 			hostname, SSL_get_version(ssl));
-		return bad;
-	}
-	if (sizeof(buff) <= len) {
-		/* Broken or malicious server */
-		msyslog(LOG_DEBUG, "NTSc: Very long ALPN from %s (%u)",
-			hostname, len);
-		return bad;
-	}
-	memcpy(buff, data, len);
-	buff[len] = '\0';
-	for (i=0; i<len; i++) {
-		if (!isgraph(buff[i])) {
-			buff[i] = '*'; /* fix non-printing crap */
-		}
+		return false;
 	}
 	/* For now, we only support one version.
-	 * This gets more complicated when version 2 arrives. */
-	if (0 != strcmp((const char*)data, "ntske/1")) {
-		msyslog(LOG_DEBUG, "NTSc: Strange ALPN returned: %s (%u) from %s",
+	 * This will get more complicated when version 2 arrives. */
+	if (len != 7 ||
+	    0 != memcmp(data, "ntske/1", len)) {
+		/* copy data over so we can print it. */
+		/* don't read past end of data */
+		unsigned int i, l;
+		char buff [16];
+		l = min(len, sizeof(buff)-1);
+		memcpy(buff, data, l);
+		buff[l] = '\0';
+		for (i=0; i<l; i++) {
+			if (!isgraph(buff[i])) {
+			  buff[i] = '*'; /* fix non-printing crap */
+			}
+		}
+		msyslog(LOG_DEBUG, "NTSc: Strange ALPN %s (%u) from %s",
 			buff, len, hostname);
-		return bad;
+		return false;
 	}
-        msyslog(LOG_DEBUG, "NTSc: Good ALPN from: %s", hostname);
+	msyslog(LOG_DEBUG, "NTSc: Good ALPN from %s", hostname);
 
 #else
 	UNUSED_ARG(ssl);


=====================================
wscript
=====================================
@@ -796,10 +796,6 @@ int main(int argc, char **argv) {
         ctx.define("ENABLE_FUZZ", 1,
                    comment="Enable fuzzing low bits of time")
 
-    # This is true under every Unix-like OS.
-    ctx.define("HAVE_WORKING_FORK", 1,
-               comment="Whether a working fork() exists")
-
     # SO_REUSEADDR socket option is needed to open a socket on an
     # interface when the port number is already in use on another
     # interface. Linux needs this, NetBSD does not, status on



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/feab268d1adb1ba4016ed393cb4fa3b901618b10...22c134c8b20e9a897fc5521df871606167067b2e

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/feab268d1adb1ba4016ed393cb4fa3b901618b10...22c134c8b20e9a897fc5521df871606167067b2e
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20191208/f6e73df3/attachment-0001.htm>


More information about the vc mailing list