OpenVPN
otime.h
Go to the documentation of this file.
1/*
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
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
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.
13 *
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.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifndef OTIME_H
24#define OTIME_H
25
26#include "common.h"
27#include "integer.h"
28#include "buffer.h"
29
30#ifdef _WIN32
31typedef long tv_sec_t;
32typedef long tv_usec_t;
33#else
34typedef time_t tv_sec_t;
35typedef suseconds_t tv_usec_t;
36#endif
37
39{
40 int max;
41 int per;
42 int n;
43 time_t reset;
44};
45
47
49
51
52/* format a time_t as ascii, or use current time if 0 */
53const char *time_string(time_t t, tv_usec_t usec, bool show_usec, struct gc_arena *gc);
54
55/* struct timeval functions */
56
57const char *tv_string(const struct timeval *tv, struct gc_arena *gc);
58
59const char *tv_string_abs(const struct timeval *tv, struct gc_arena *gc);
60
61extern time_t now; /* updated frequently to time(NULL) */
62
63void time_test(void);
64
65void update_now(const time_t system_time);
66
67extern time_t now_usec;
68void update_now_usec(struct timeval *tv);
69
70static inline int
71openvpn_gettimeofday(struct timeval *tv, void *tz)
72{
73 const int status = gettimeofday(tv, tz);
74 if (!status)
75 {
77 tv->tv_sec = (tv_sec_t)now;
78 tv->tv_usec = (tv_usec_t)now_usec;
79 }
80 return status;
81}
82
83static inline void
85{
86#ifdef _WIN32
87 /* on _WIN32, gettimeofday is faster than time(NULL) */
88 struct timeval tv;
89 openvpn_gettimeofday(&tv, NULL);
90#else
91 update_now(time(NULL));
92 now_usec = 0;
93#endif
94}
95
96static inline time_t
97openvpn_time(time_t *t)
98{
100 if (t)
101 {
102 *t = now;
103 }
104 return now;
105}
106
107static inline void
108tv_clear(struct timeval *tv)
109{
110 tv->tv_sec = 0;
111 tv->tv_usec = 0;
112}
113
114static inline bool
115tv_defined(const struct timeval *tv)
116{
117 return tv->tv_sec > 0 && tv->tv_usec > 0;
118}
119
120/* return tv1 - tv2 in usec, constrained by max_seconds */
121static inline int
122tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const int max_seconds)
123{
124 const int max_usec = max_seconds * 1000000;
125 const tv_sec_t sec_diff = tv1->tv_sec - tv2->tv_sec;
126
127 if (sec_diff > (max_seconds + 10))
128 {
129 return max_usec;
130 }
131 else if (sec_diff < -(max_seconds + 10))
132 {
133 return -max_usec;
134 }
135 const time_t complete_diff = sec_diff * 1000000 + (tv1->tv_usec - tv2->tv_usec);
136 return constrain_int((int)complete_diff, -max_usec, max_usec);
137}
138
139static inline void
140tv_add(struct timeval *dest, const struct timeval *src)
141{
142 dest->tv_sec += src->tv_sec;
143 dest->tv_usec += src->tv_usec;
144 dest->tv_sec += (dest->tv_usec >> 20);
145 dest->tv_usec &= 0x000FFFFF;
146 if (dest->tv_usec >= 1000000)
147 {
148 dest->tv_usec -= 1000000;
149 dest->tv_sec += 1;
150 }
151}
152
153static inline bool
154tv_lt(const struct timeval *t1, const struct timeval *t2)
155{
156 if (t1->tv_sec < t2->tv_sec)
157 {
158 return true;
159 }
160 else if (t1->tv_sec > t2->tv_sec)
161 {
162 return false;
163 }
164 else
165 {
166 return t1->tv_usec < t2->tv_usec;
167 }
168}
169
170static inline bool
171tv_le(const struct timeval *t1, const struct timeval *t2)
172{
173 if (t1->tv_sec < t2->tv_sec)
174 {
175 return true;
176 }
177 else if (t1->tv_sec > t2->tv_sec)
178 {
179 return false;
180 }
181 else
182 {
183 return t1->tv_usec <= t2->tv_usec;
184 }
185}
186
187static inline bool
188tv_ge(const struct timeval *t1, const struct timeval *t2)
189{
190 if (t1->tv_sec > t2->tv_sec)
191 {
192 return true;
193 }
194 else if (t1->tv_sec < t2->tv_sec)
195 {
196 return false;
197 }
198 else
199 {
200 return t1->tv_usec >= t2->tv_usec;
201 }
202}
203
204static inline bool
205tv_gt(const struct timeval *t1, const struct timeval *t2)
206{
207 if (t1->tv_sec > t2->tv_sec)
208 {
209 return true;
210 }
211 else if (t1->tv_sec < t2->tv_sec)
212 {
213 return false;
214 }
215 else
216 {
217 return t1->tv_usec > t2->tv_usec;
218 }
219}
220
221static inline bool
222tv_eq(const struct timeval *t1, const struct timeval *t2)
223{
224 return t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec;
225}
226
227static inline void
228tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
229{
230 tv_sec_t sec = t2->tv_sec - t1->tv_sec;
231 tv_usec_t usec = t2->tv_usec - t1->tv_usec;
232
233 while (usec < 0)
234 {
235 usec += 1000000;
236 sec -= 1;
237 }
238
239 if (sec < 0)
240 {
241 usec = sec = 0;
242 }
243
244 dest->tv_sec = sec;
245 dest->tv_usec = usec;
246}
247
248#define TV_WITHIN_SIGMA_MAX_SEC 600
249#define TV_WITHIN_SIGMA_MAX_USEC (TV_WITHIN_SIGMA_MAX_SEC * 1000000)
250
251/*
252 * Is t1 and t2 within sigma microseconds of each other?
253 */
254static inline bool
255tv_within_sigma(const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
256{
257 /* sigma should be less than 10 minutes */
258 const int delta = tv_subtract(t1, t2, TV_WITHIN_SIGMA_MAX_SEC);
259 return -(int)sigma <= delta && delta <= (int)sigma;
260}
261
262/*
263 * Used to determine in how many seconds we should be
264 * called again.
265 */
266static inline void
267interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
268{
269 if (at > current)
270 {
271 const interval_t delta = (interval_t)(at - current);
272 if (delta < *wakeup)
273 {
274 *wakeup = delta;
275 }
276 if (*wakeup < 0)
277 {
278 *wakeup = 0;
279 }
280 }
281}
282
283#endif /* ifndef OTIME_H */
int interval_t
Definition common.h:37
static int constrain_int(int x, int min, int max)
Definition integer.h:118
static SERVICE_STATUS status
Definition interactive.c:51
static bool tv_le(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:171
static bool tv_eq(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:222
static void tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
Definition otime.h:228
static void interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
Definition otime.h:267
const char * time_string(time_t t, tv_usec_t usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
time_t now_usec
Definition otime.c:36
struct frequency_limit * frequency_limit_init(int max, int per)
Definition otime.c:137
void update_now(const time_t system_time)
Definition otime.c:44
void update_now_usec(struct timeval *tv)
Definition otime.c:69
time_t now
Definition otime.c:33
static bool tv_ge(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:188
void frequency_limit_free(struct frequency_limit *f)
Definition otime.c:152
const char * tv_string(const struct timeval *tv, struct gc_arena *gc)
Definition otime.c:83
static bool tv_lt(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:154
const char * tv_string_abs(const struct timeval *tv, struct gc_arena *gc)
Definition otime.c:96
bool frequency_limit_event_allowed(struct frequency_limit *f)
Definition otime.c:158
static time_t openvpn_time(time_t *t)
Definition otime.h:97
static bool tv_gt(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:205
static void update_time(void)
Definition otime.h:84
static int openvpn_gettimeofday(struct timeval *tv, void *tz)
Definition otime.h:71
long tv_sec_t
Definition otime.h:31
void time_test(void)
static void tv_clear(struct timeval *tv)
Definition otime.h:108
static bool tv_defined(const struct timeval *tv)
Definition otime.h:115
#define TV_WITHIN_SIGMA_MAX_SEC
Definition otime.h:248
static bool tv_within_sigma(const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
Definition otime.h:255
static int tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const int max_seconds)
Definition otime.h:122
long tv_usec_t
Definition otime.h:32
static void tv_add(struct timeval *dest, const struct timeval *src)
Definition otime.h:140
time_t reset
Definition otime.h:43
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
struct gc_arena gc
Definition test_ssl.c:131