9c49c9e
From 5917ba14ccf7c7cc2eadf8b6cc666f8be4d2d2a4 Mon Sep 17 00:00:00 2001
9c49c9e
From: Pavel Zhukov <pzhukov@redhat.com>
9c49c9e
Date: Tue, 22 Oct 2019 16:23:24 +0200
9c49c9e
Subject: [PATCH 25/26] bind: Detect system time changes
9c49c9e
Cc: pzhukov@redhat.com
9c49c9e
9c49c9e
---
9c49c9e
 bind/bind-9.11.2-P1/lib/isc/include/isc/result.h   |  4 +--
9c49c9e
 bind/bind-9.11.2-P1/lib/isc/include/isc/util.h     |  4 +++
9c49c9e
 bind/bind-9.11.2-P1/lib/isc/result.c               |  2 ++
9c49c9e
 bind/bind-9.11.2-P1/lib/isc/unix/app.c             | 41 ++++++++++++++++++++--
9c49c9e
 .../bind-9.11.2-P1/lib/isc/unix/include/isc/time.h | 20 +++++++++++
9c49c9e
 bind/bind-9.11.2-P1/lib/isc/unix/time.c            | 22 ++++++++++++
9c49c9e
 6 files changed, 89 insertions(+), 4 deletions(-)
9c49c9e
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/include/isc/result.h b/bind/bind-9.11.2-P1/lib/isc/include/isc/result.h
ae914ba
index 6f7ecf2..c7ef53c 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/include/isc/result.h
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/include/isc/result.h
ae914ba
@@ -81,9 +81,9 @@
ae914ba
 #define ISC_R_UNSET			61	/*%< unset */
ae914ba
 #define ISC_R_MULTIPLE			62	/*%< multiple */
ae914ba
 #define ISC_R_WOULDBLOCK		63	/*%< would block */
ae914ba
-
ae914ba
+#define ISC_R_TIMESHIFTED               64      /*%< system time changed */
ae914ba
 /*% Not a result code: the number of results. */
ae914ba
-#define ISC_R_NRESULTS 			64
ae914ba
+#define ISC_R_NRESULTS 			66
ae914ba
 
ae914ba
 ISC_LANG_BEGINDECLS
ae914ba
 
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/include/isc/util.h b/bind/bind-9.11.2-P1/lib/isc/include/isc/util.h
ae914ba
index f2cda26..9d54396 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/include/isc/util.h
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/include/isc/util.h
ae914ba
@@ -238,6 +238,10 @@
ae914ba
  * Time
ae914ba
  */
ae914ba
 #define TIME_NOW(tp) 	RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
ae914ba
+#ifdef CLOCK_BOOTTIME
ae914ba
+#define TIME_MONOTONIC(tp) 	RUNTIME_CHECK(isc_time_boottime((tp)) == ISC_R_SUCCESS)
ae914ba
+#endif
ae914ba
+
ae914ba
 
ae914ba
 /*%
ae914ba
  * Misc.
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/result.c b/bind/bind-9.11.2-P1/lib/isc/result.c
ae914ba
index 071dac0..e362735 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/result.c
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/result.c
ae914ba
@@ -96,6 +96,7 @@ static const char *description[ISC_R_NRESULTS] = {
ae914ba
 	"unset",				/*%< 61 */
ae914ba
 	"multiple",				/*%< 62 */
ae914ba
 	"would block",				/*%< 63 */
ae914ba
+        "time changed",                         /*%< 64 */
ae914ba
 };
ae914ba
 
ae914ba
 static const char *identifier[ISC_R_NRESULTS] = {
ae914ba
@@ -163,6 +164,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
ae914ba
 	"ISC_R_UNSET",
ae914ba
 	"ISC_R_MULTIPLE",
ae914ba
 	"ISC_R_WOULDBLOCK",
ae914ba
+        "ISC_R_TIMESHIFTED",
ae914ba
 };
ae914ba
 
ae914ba
 #define ISC_RESULT_RESULTSET			2
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/unix/app.c b/bind/bind-9.11.2-P1/lib/isc/unix/app.c
ae914ba
index 5546922..7d95ad5 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/unix/app.c
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/unix/app.c
ae914ba
@@ -438,15 +438,51 @@ isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task,
ae914ba
 static isc_result_t
ae914ba
 evloop(isc__appctx_t *ctx) {
ae914ba
 	isc_result_t result;
ae914ba
+        isc_time_t now;
ae914ba
+#ifdef CLOCK_BOOTTIME
ae914ba
+        isc_time_t monotonic;
ae914ba
+        isc_uint64_t diff  = 0;
ae914ba
+#else
ae914ba
+        isc_time_t prev;
ae914ba
+        TIME_NOW(&prev;;
ae914ba
+#endif
ae914ba
+
ae914ba
+
ae914ba
+
ae914ba
 
ae914ba
 	while (!ctx->want_shutdown) {
ae914ba
 		int n;
ae914ba
-		isc_time_t when, now;
ae914ba
+		isc_time_t when;
ae914ba
+                
ae914ba
 		struct timeval tv, *tvp;
ae914ba
 		isc_socketwait_t *swait;
ae914ba
 		isc_boolean_t readytasks;
ae914ba
 		isc_boolean_t call_timer_dispatch = ISC_FALSE;
ae914ba
 
ae914ba
+                isc_uint64_t us; 
ae914ba
+
ae914ba
+#ifdef CLOCK_BOOTTIME
ae914ba
+                // TBD macros for following three lines
ae914ba
+                TIME_NOW(&now;;
ae914ba
+                TIME_MONOTONIC(&monotonic);
ae914ba
+                INSIST(now.seconds > monotonic.seconds)
ae914ba
+                us = isc_time_microdiff (&now, &monotonic);
ae914ba
+                if (us < diff){ 
ae914ba
+                  us = diff - us;
ae914ba
+                  if (us > 1000000){ // ignoring shifts less than one second
ae914ba
+                    return ISC_R_TIMESHIFTED;
ae914ba
+                  };
ae914ba
+                  diff = isc_time_microdiff (&now, &monotonic);
ae914ba
+                } else {
ae914ba
+                  diff = isc_time_microdiff (&now, &monotonic);
ae914ba
+                  // not implemented
ae914ba
+                }
ae914ba
+#else
ae914ba
+                TIME_NOW(&now;;
ae914ba
+                if (isc_time_compare (&now, &prev) < 0)
ae914ba
+                  return ISC_R_TIMESHIFTED;
ae914ba
+                TIME_NOW(&prev;;
ae914ba
+#endif                
ae914ba
 		/*
ae914ba
 		 * Check the reload (or suspend) case first for exiting the
ae914ba
 		 * loop as fast as possible in case:
ae914ba
@@ -471,9 +507,10 @@ evloop(isc__appctx_t *ctx) {
ae914ba
 			if (result != ISC_R_SUCCESS)
ae914ba
 				tvp = NULL;
ae914ba
 			else {
ae914ba
-				isc_uint64_t us;
ae914ba
+
ae914ba
 
ae914ba
 				TIME_NOW(&now;;
ae914ba
+
ae914ba
 				us = isc_time_microdiff(&when, &now;;
ae914ba
 				if (us == 0)
ae914ba
 					call_timer_dispatch = ISC_TRUE;
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/unix/include/isc/time.h b/bind/bind-9.11.2-P1/lib/isc/unix/include/isc/time.h
ae914ba
index 939db5d..e798ee6 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/unix/include/isc/time.h
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/unix/include/isc/time.h
ae914ba
@@ -127,6 +127,26 @@ isc_time_isepoch(const isc_time_t *t);
ae914ba
  *\li	't' is a valid pointer.
ae914ba
  */
ae914ba
 
ae914ba
+#ifdef CLOCK_BOOTTIME
ae914ba
+isc_result_t
ae914ba
+isc_time_boottime(isc_time_t *t);
ae914ba
+/*%<
ae914ba
+ * Set 't' to monotonic time from previous boot
ae914ba
+ * it's not affected by system time change. It also
ae914ba
+ * includes the time system was suspended
ae914ba
+ *
ae914ba
+ * Requires:
ae914ba
+ *\li	't' is a valid pointer.
ae914ba
+ *
ae914ba
+ * Returns:
ae914ba
+ *
ae914ba
+ *\li	Success
ae914ba
+ *\li	Unexpected error
ae914ba
+ *		Getting the time from the system failed.
ae914ba
+ */
ae914ba
+#endif /* CLOCK_BOOTTIME */
ae914ba
+ 
ae914ba
+
ae914ba
 isc_result_t
ae914ba
 isc_time_now(isc_time_t *t);
ae914ba
 /*%<
ae914ba
diff --git a/bind/bind-9.11.2-P1/lib/isc/unix/time.c b/bind/bind-9.11.2-P1/lib/isc/unix/time.c
ae914ba
index 5900846..1197337 100644
ae914ba
--- a/bind/bind-9.11.2-P1/lib/isc/unix/time.c
ae914ba
+++ b/bind/bind-9.11.2-P1/lib/isc/unix/time.c
ae914ba
@@ -452,3 +452,25 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
ae914ba
 			 t->nanoseconds / NS_PER_MS);
ae914ba
 	}
ae914ba
 }
ae914ba
+
ae914ba
+
ae914ba
+#ifdef CLOCK_BOOTTIME
ae914ba
+isc_result_t
ae914ba
+isc_time_boottime(isc_time_t *t) {
ae914ba
+  struct timespec ts;
ae914ba
+  
ae914ba
+  char strbuf[ISC_STRERRORSIZE];
ae914ba
+
ae914ba
+  if (clock_gettime (CLOCK_BOOTTIME, &ts) != 0){
ae914ba
+    isc__strerror(errno, strbuf, sizeof(strbuf));
ae914ba
+    UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
ae914ba
+    return (ISC_R_UNEXPECTED);    
ae914ba
+  }
ae914ba
+
ae914ba
+  t->seconds = ts.tv_sec;
ae914ba
+  t->nanoseconds = ts.tv_nsec;
ae914ba
+
ae914ba
+  return (ISC_R_SUCCESS);
ae914ba
+  
ae914ba
+};
ae914ba
+#endif
9c49c9e
-- 
9c49c9e
2.14.5
9c49c9e