Browse code

Temporarily backed out time backtrack handling code due to issues on Windows.

Rewrote gettimeofday function for Windows to be
simpler and more efficient.


git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1005 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2006/04/13 18:48:11
Showing 4 changed files
... ...
@@ -286,6 +286,11 @@ init_static (void)
286 286
   return false;
287 287
 #endif
288 288
 
289
+#ifdef TIME_TEST
290
+  time_test ();
291
+  return false;
292
+#endif
293
+
289 294
   return true;
290 295
 }
291 296
 
... ...
@@ -36,51 +36,10 @@
36 36
 
37 37
 time_t now = 0;            /* GLOBAL */
38 38
 
39
-#if TIME_BACKTRACK_PROTECTION
40
-
41
-static time_t now_adj = 0; /* GLOBAL */
42
-
43
-/*
44
- * Try to filter out time instability caused by the system
45
- * clock backtracking or jumping forward.
46
- */
47
-
48
-void
49
-update_now (const time_t system_time)
50
-{
51
-  const int threshold = 86400; /* threshold at which to dampen forward jumps */
52
-  time_t real_time = system_time + now_adj;
53
-  if (real_time > now)
54
-    {
55
-      const time_t overshoot = real_time - now - 1;
56
-      if (overshoot > threshold && now_adj >= overshoot)
57
-        {
58
-          now_adj -= overshoot;
59
-          real_time -= overshoot;
60
-        }
61
-      now = real_time;
62
-    }
63
-  else if (real_time < now)
64
-    {
65
-      now_adj += (now - real_time);
66
-    }
67
-}
68
-
69 39
 #ifdef HAVE_GETTIMEOFDAY
70 40
 
71 41
 time_t now_usec = 0;       /* GLOBAL */
72 42
 
73
-void
74
-update_now_usec (struct timeval *tv)
75
-{
76
-  const time_t last = now;
77
-  update_now (tv->tv_sec);
78
-  if (now > last || tv->tv_usec > now_usec)
79
-    now_usec = tv->tv_usec;
80
-}
81
-
82
-#endif
83
-
84 43
 #endif
85 44
 
86 45
 /* 
... ...
@@ -193,53 +152,84 @@ frequency_limit_event_allowed (struct frequency_limit *f)
193 193
 
194 194
 #ifdef WIN32
195 195
 
196
-static double counterPerMicrosecond = -1.0;            /* GLOBAL */
197
-static unsigned __int64 frequency = 0;                 /* GLOBAL */
198
-static unsigned __int64 timeSecOffset = 0;             /* GLOBAL */
199
-static unsigned __int64 startPerformanceCounter = 0;   /* GLOBAL */
196
+static time_t gtc_base = 0;
197
+static DWORD gtc_last = 0;
198
+static time_t last_sec = 0;
199
+static unsigned int last_msec = 0;
200
+static bool bt_last = false;
200 201
 
201
-/*
202
- * gettimeofday for windows
203
- *
204
- * CounterPerMicrosecond is the number of counts per microsecond.
205
- * Double is required if we have less than 1 counter per microsecond.  This has not been tested.
206
- * On a PIII 700, I get about 3.579545.  This is guaranteed not to change while the processor is running.
207
- * We really don't need to check for loop detection.  On my machine it would take about 59645564 days to loop.
208
- * (2^64) / frequency / 60 / 60 / 24.
209
- *
210
- */
211
-int
212
-gettimeofday(struct timeval *tv, void *tz)
202
+static void
203
+gettimeofday_calibrate (void)
213 204
 {
214
-  unsigned __int64 counter;
215
-
216
-  QueryPerformanceCounter((LARGE_INTEGER *) &counter);
217
-
218
-  if (counter < startPerformanceCounter || counterPerMicrosecond == -1.0)
219
-    {
220
-      time_t t;
221
-      mutex_lock (L_GETTIMEOFDAY);
222
-
223
-      QueryPerformanceFrequency((LARGE_INTEGER *) &frequency);
224
-
225
-      counterPerMicrosecond = (double) ((__int64) frequency) / 1000000.0f;
205
+  const time_t t = time(NULL);
206
+  const DWORD gtc = GetTickCount();
207
+  gtc_base = t - gtc/1000;
208
+  gtc_last = gtc;
209
+}
226 210
 
227
-      time(&t);
228
-      QueryPerformanceCounter((LARGE_INTEGER *) &counter);
229
-      startPerformanceCounter = counter;
211
+int
212
+gettimeofday (struct timeval *tv, void *tz)
213
+{
214
+  const DWORD gtc = GetTickCount();
215
+  bool bt = false;
216
+  time_t sec;
217
+  unsigned int msec;
218
+  const int backtrack_hold_seconds = 10;
230 219
 
231
-      counter /= frequency;
220
+  if (!gtc_base || gtc < gtc_last)
221
+    gettimeofday_calibrate ();
222
+  gtc_last = gtc;
232 223
 
233
-      timeSecOffset = t - counter;
224
+  sec = gtc_base + gtc / 1000;
225
+  msec = gtc % 1000;
234 226
 
235
-      mutex_unlock (L_GETTIMEOFDAY);
236
-      QueryPerformanceCounter((LARGE_INTEGER *) &counter);
227
+  if (sec == last_sec)
228
+    {
229
+      if (msec < last_msec)
230
+	{
231
+	  msec = last_msec;
232
+	  bt = true;
233
+	}
234
+    }
235
+  else if (sec < last_sec)
236
+    {
237
+      if (sec > last_sec - backtrack_hold_seconds)
238
+	{
239
+	  sec = last_sec;
240
+	  msec = last_msec;
241
+	}
242
+      bt = true;
237 243
     }
238 244
 
239
-  tv->tv_sec = (counter / frequency) + timeSecOffset;
240
-  tv->tv_usec = ((__int64) (((__int64) counter) / counterPerMicrosecond) % 1000000);
245
+  tv->tv_sec = last_sec = sec;
246
+  tv->tv_usec = (last_msec = msec) * 1000;
247
+
248
+  if (bt && !bt_last)
249
+    gettimeofday_calibrate ();
250
+  bt_last = bt;
241 251
 
242 252
   return 0;
243 253
 }
244 254
 
245 255
 #endif /* WIN32 */
256
+
257
+#ifdef TIME_TEST
258
+void
259
+time_test (void)
260
+{
261
+  struct timeval tv;
262
+  time_t t;
263
+  int i;
264
+  for (i = 0; i < 10000; ++i)
265
+    {
266
+      t = time(NULL);
267
+      gettimeofday (&tv, NULL);
268
+#if 1
269
+      msg (M_INFO, "t=%u s=%u us=%u",
270
+	       (unsigned int)t,
271
+	       (unsigned int)tv.tv_sec,
272
+	       (unsigned int)tv.tv_usec);
273
+#endif
274
+    }
275
+}
276
+#endif
... ...
@@ -56,44 +56,23 @@ const char *tv_string_abs (const struct timeval *tv, struct gc_arena *gc);
56 56
 
57 57
 extern time_t now; /* updated frequently to time(NULL) */
58 58
 
59
-#if TIME_BACKTRACK_PROTECTION
60
-
61
-void update_now (const time_t system_time);
59
+void time_test (void);
62 60
 
63 61
 static inline void
64 62
 update_time (void)
65 63
 {
66
-  update_now (time (NULL));
67
-}
68
-
69
-#ifdef HAVE_GETTIMEOFDAY
70
-
71
-extern time_t now_usec;
72
-void update_now_usec (struct timeval *tv);
73
-
74
-static inline int
75
-openvpn_gettimeofday (struct timeval *tv, void *tz)
76
-{
77
-  const int status = gettimeofday (tv, tz);
78
-  if (!status)
64
+#if defined(WIN32) && defined(HAVE_GETTIMEOFDAY)
65
+  struct timeval tv;
66
+  if (!gettimeofday (&tv, NULL))
79 67
     {
80
-      update_now_usec (tv);
81
-      tv->tv_sec = now;
82
-      tv->tv_usec = now_usec;
68
+      if (tv.tv_sec != now)
69
+	now = tv.tv_sec;
83 70
     }
84
-  return status;
85
-}
86
-
87
-#endif
88
-
89 71
 #else
90
-
91
-static inline void
92
-update_time (void)
93
-{
94 72
   const time_t real_time = time (NULL);
95 73
   if (real_time != now)
96 74
     now = real_time;
75
+#endif
97 76
 }
98 77
 
99 78
 #ifdef HAVE_GETTIMEOFDAY
... ...
@@ -106,8 +85,6 @@ openvpn_gettimeofday (struct timeval *tv, void *tz)
106 106
 
107 107
 #endif
108 108
 
109
-#endif
110
-
111 109
 static inline time_t
112 110
 openvpn_time (time_t *t)
113 111
 {
... ...
@@ -498,7 +498,7 @@ socket_defined (const socket_descriptor_t sd)
498 498
  * Reduce sensitivity to system clock instability
499 499
  * and backtracks.
500 500
  */
501
-#define TIME_BACKTRACK_PROTECTION 1
501
+//#define TIME_BACKTRACK_PROTECTION 1 // JYFIXME
502 502
 
503 503
 /*
504 504
  * Is non-blocking connect() supported?