a2a915
diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h
a2a915
index 246aefb..0007543 100644
a2a915
--- a/lib/isc/include/isc/result.h
a2a915
+++ b/lib/isc/include/isc/result.h
a2a915
@@ -83,9 +83,9 @@
a2a915
 #define ISC_R_UNSET			61	/*%< unset */
a2a915
 #define ISC_R_MULTIPLE			62	/*%< multiple */
a2a915
 #define ISC_R_WOULDBLOCK		63	/*%< would block */
a2a915
-
a2a915
+#define ISC_R_TIMESHIFTED               64      /*%< system time changed */
a2a915
 /*% Not a result code: the number of results. */
a2a915
-#define ISC_R_NRESULTS 			64
a2a915
+#define ISC_R_NRESULTS 			66
a2a915
 
a2a915
 ISC_LANG_BEGINDECLS
a2a915
 
a2a915
diff --git a/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h
a2a915
index 332dc0c..f81967d 100644
a2a915
--- a/lib/isc/include/isc/util.h
a2a915
+++ b/lib/isc/include/isc/util.h
a2a915
@@ -233,6 +233,10 @@
a2a915
  * Time
a2a915
  */
a2a915
 #define TIME_NOW(tp) 	RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
a2a915
+#ifdef CLOCK_BOOTTIME
a2a915
+#define TIME_MONOTONIC(tp) 	RUNTIME_CHECK(isc_time_boottime((tp)) == ISC_R_SUCCESS)
a2a915
+#endif
a2a915
+
a2a915
 
a2a915
 /*%
a2a915
  * Misc
a2a915
diff --git a/lib/isc/result.c b/lib/isc/result.c
a2a915
index a707c32..6776fc6 100644
a2a915
--- a/lib/isc/result.c
a2a915
+++ b/lib/isc/result.c
a2a915
@@ -99,6 +99,7 @@ static const char *description[ISC_R_NRESULTS] = {
a2a915
 	"unset",				/*%< 61 */
a2a915
 	"multiple",				/*%< 62 */
a2a915
 	"would block",				/*%< 63 */
a2a915
+        "time changed",                         /*%< 64 */
a2a915
 };
a2a915
 
a2a915
 static const char *identifier[ISC_R_NRESULTS] = {
a2a915
@@ -166,6 +167,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
a2a915
 	"ISC_R_UNSET",
a2a915
 	"ISC_R_MULTIPLE",
a2a915
 	"ISC_R_WOULDBLOCK",
a2a915
+        "ISC_R_TIMESHIFTED",
a2a915
 };
a2a915
 
a2a915
 #define ISC_RESULT_RESULTSET			2
a2a915
diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c
a2a915
index bace2bd..e9814d2 100644
a2a915
--- a/lib/isc/unix/app.c
a2a915
+++ b/lib/isc/unix/app.c
a2a915
@@ -441,15 +441,51 @@ isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task,
a2a915
 static isc_result_t
a2a915
 evloop(isc__appctx_t *ctx) {
a2a915
 	isc_result_t result;
a2a915
+        isc_time_t now;
a2a915
+#ifdef CLOCK_BOOTTIME
a2a915
+        isc_time_t monotonic;
a2a915
+        isc_uint64_t diff  = 0;
a2a915
+#else
a2a915
+        isc_time_t prev;
a2a915
+        TIME_NOW(&prev;;
a2a915
+#endif
a2a915
+
a2a915
+
a2a915
+
a2a915
 
a2a915
 	while (!ctx->want_shutdown) {
a2a915
 		int n;
a2a915
-		isc_time_t when, now;
a2a915
+		isc_time_t when;
a2a915
+                
a2a915
 		struct timeval tv, *tvp;
a2a915
 		isc_socketwait_t *swait;
a2a915
 		isc_boolean_t readytasks;
a2a915
 		isc_boolean_t call_timer_dispatch = ISC_FALSE;
a2a915
 
a2a915
+                isc_uint64_t us; 
a2a915
+
a2a915
+#ifdef CLOCK_BOOTTIME
a2a915
+                // TBD macros for following three lines
a2a915
+                TIME_NOW(&now;;
a2a915
+                TIME_MONOTONIC(&monotonic);
a2a915
+                // INSIST(now.seconds > monotonic.seconds) 
a2a915
+                us = isc_time_microdiff (&now, &monotonic);
a2a915
+                if (us < diff){ 
a2a915
+                  us = diff - us;
a2a915
+                  if (us > 1000000){ // ignoring shifts less than one second
a2a915
+                    return ISC_R_TIMESHIFTED;
a2a915
+                  };
a2a915
+                  diff = isc_time_microdiff (&now, &monotonic);
a2a915
+                } else {
a2a915
+                  diff = isc_time_microdiff (&now, &monotonic);
a2a915
+                  // not implemented
a2a915
+                }
a2a915
+#else
a2a915
+                TIME_NOW(&now;;
a2a915
+                if (isc_time_compare (&now, &prev) < 0)
a2a915
+                  return ISC_R_TIMESHIFTED;
a2a915
+                TIME_NOW(&prev;;
a2a915
+#endif                
a2a915
 		/*
a2a915
 		 * Check the reload (or suspend) case first for exiting the
a2a915
 		 * loop as fast as possible in case:
a2a915
@@ -474,9 +510,10 @@ evloop(isc__appctx_t *ctx) {
a2a915
 			if (result != ISC_R_SUCCESS)
a2a915
 				tvp = NULL;
a2a915
 			else {
a2a915
-				isc_uint64_t us;
a2a915
+
a2a915
 
a2a915
 				TIME_NOW(&now;;
a2a915
+
a2a915
 				us = isc_time_microdiff(&when, &now;;
a2a915
 				if (us == 0)
a2a915
 					call_timer_dispatch = ISC_TRUE;
a2a915
diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h
a2a915
index 75e24b9..de8b399 100644
a2a915
--- a/lib/isc/unix/include/isc/time.h
a2a915
+++ b/lib/isc/unix/include/isc/time.h
a2a915
@@ -129,6 +129,26 @@ isc_time_isepoch(const isc_time_t *t);
a2a915
  *\li	't' is a valid pointer.
a2a915
  */
a2a915
 
a2a915
+#ifdef CLOCK_BOOTTIME
a2a915
+isc_result_t
a2a915
+isc_time_boottime(isc_time_t *t);
a2a915
+/*%<
a2a915
+ * Set 't' to monotonic time from previous boot
a2a915
+ * it's not affected by system time change. It also
a2a915
+ * includes the time system was suspended
a2a915
+ *
a2a915
+ * Requires:
a2a915
+ *\li	't' is a valid pointer.
a2a915
+ *
a2a915
+ * Returns:
a2a915
+ *
a2a915
+ *\li	Success
a2a915
+ *\li	Unexpected error
a2a915
+ *		Getting the time from the system failed.
a2a915
+ */
a2a915
+#endif /* CLOCK_BOOTTIME */
a2a915
+ 
a2a915
+
a2a915
 isc_result_t
a2a915
 isc_time_now(isc_time_t *t);
a2a915
 /*%<
a2a915
diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c
a2a915
index 2210240..d7613b8 100644
a2a915
--- a/lib/isc/unix/time.c
a2a915
+++ b/lib/isc/unix/time.c
a2a915
@@ -496,3 +496,25 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
a2a915
 			 t->nanoseconds / NS_PER_MS);
a2a915
 	}
a2a915
 }
a2a915
+
a2a915
+
a2a915
+#ifdef CLOCK_BOOTTIME
a2a915
+isc_result_t
a2a915
+isc_time_boottime(isc_time_t *t) {
a2a915
+  struct timespec ts;
a2a915
+  
a2a915
+  char strbuf[ISC_STRERRORSIZE];
a2a915
+
a2a915
+  if (clock_gettime (CLOCK_BOOTTIME, &ts) != 0){
a2a915
+    isc__strerror(errno, strbuf, sizeof(strbuf));
a2a915
+    UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
a2a915
+    return (ISC_R_UNEXPECTED);    
a2a915
+  }
a2a915
+
a2a915
+  t->seconds = ts.tv_sec;
a2a915
+  t->nanoseconds = ts.tv_nsec;
a2a915
+
a2a915
+  return (ISC_R_SUCCESS);
a2a915
+  
a2a915
+};
a2a915
+#endif