2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 time_t now
= 0; /* GLOBAL */
33 #if TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY)
35 static time_t now_adj
= 0; /* GLOBAL */
36 time_t now_usec
= 0; /* GLOBAL */
39 * Try to filter out time instability caused by the system
40 * clock backtracking or jumping forward.
44 update_now (const time_t system_time
)
46 const int forward_threshold
= 86400; /* threshold at which to dampen forward jumps */
47 const int backward_trigger
= 10; /* backward jump must be >= this many seconds before we adjust */
48 time_t real_time
= system_time
+ now_adj
;
52 const time_t overshoot
= real_time
- now
- 1;
53 if (overshoot
> forward_threshold
&& now_adj
>= overshoot
)
56 real_time
-= overshoot
;
60 else if (real_time
< now
- backward_trigger
)
61 now_adj
+= (now
- real_time
);
65 update_now_usec (struct timeval
*tv
)
67 const time_t last
= now
;
68 update_now (tv
->tv_sec
);
69 if (now
> last
|| (now
== last
&& tv
->tv_usec
> now_usec
))
70 now_usec
= tv
->tv_usec
;
73 #endif /* TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) */
76 * Return a numerical string describing a struct timeval.
79 tv_string (const struct timeval
*tv
, struct gc_arena
*gc
)
81 struct buffer out
= alloc_buf_gc (64, gc
);
82 buf_printf (&out
, "[%d/%d]",
89 * Return an ascii string describing an absolute
90 * date/time in a struct timeval.
94 tv_string_abs (const struct timeval
*tv
, struct gc_arena
*gc
)
96 return time_string ((time_t) tv
->tv_sec
,
102 /* format a time_t as ascii, or use current time if 0 */
105 time_string (time_t t
, int usec
, bool show_usec
, struct gc_arena
*gc
)
107 struct buffer out
= alloc_buf_gc (64, gc
);
117 #ifdef HAVE_GETTIMEOFDAY
118 if (gettimeofday (&tv
, NULL
))
121 tv
.tv_sec
= time (NULL
);
126 mutex_lock_static (L_CTIME
);
128 buf_printf (&out
, "%s", ctime(&t
));
129 mutex_unlock_static (L_CTIME
);
130 buf_rmtail (&out
, '\n');
132 if (show_usec
&& tv
.tv_usec
)
133 buf_printf (&out
, " us=%d", (int)tv
.tv_usec
);
139 * Limit the frequency of an event stream.
141 * Used to control maximum rate of new
142 * incoming connections.
145 struct frequency_limit
*
146 frequency_limit_init (int max
, int per
)
148 struct frequency_limit
*f
;
150 ASSERT (max
>= 0 && per
>= 0);
152 ALLOC_OBJ (f
, struct frequency_limit
);
161 frequency_limit_free (struct frequency_limit
*f
)
167 frequency_limit_event_allowed (struct frequency_limit
*f
)
172 if (now
>= f
->reset
+ f
->per
)
177 ret
= (++f
->n
<= f
->max
);
186 static time_t gtc_base
= 0;
187 static DWORD gtc_last
= 0;
188 static time_t last_sec
= 0;
189 static unsigned int last_msec
= 0;
190 static bool bt_last
= false;
193 gettimeofday_calibrate (void)
195 const time_t t
= time(NULL
);
196 const DWORD gtc
= GetTickCount();
197 gtc_base
= t
- gtc
/1000;
202 * Rewritten by JY for OpenVPN 2.1, after I realized that
203 * QueryPerformanceCounter takes nearly 2 orders of magnitude
204 * more processor cycles than GetTickCount.
207 gettimeofday (struct timeval
*tv
, void *tz
)
209 const DWORD gtc
= GetTickCount();
213 const int backtrack_hold_seconds
= 10;
215 /* recalibrate at the dreaded 49.7 day mark */
216 if (!gtc_base
|| gtc
< gtc_last
)
217 gettimeofday_calibrate ();
220 sec
= gtc_base
+ gtc
/ 1000;
225 if (msec
< last_msec
)
231 else if (sec
< last_sec
)
233 /* We try to dampen out backtracks of less than backtrack_hold_seconds.
234 Larger backtracks will be passed through and dealt with by the
235 TIME_BACKTRACK_PROTECTION code (if enabled) */
236 if (sec
> last_sec
- backtrack_hold_seconds
)
244 tv
->tv_sec
= last_sec
= sec
;
245 tv
->tv_usec
= (last_msec
= msec
) * 1000;
248 gettimeofday_calibrate ();
263 for (i
= 0; i
< 10000; ++i
)
266 gettimeofday (&tv
, NULL
);
268 msg (M_INFO
, "t=%u s=%u us=%u",
270 (unsigned int)tv
.tv_sec
,
271 (unsigned int)tv
.tv_usec
);