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
31{
32 int max;
33 int per;
34 int n;
35 time_t reset;
36};
37
39
41
43
44/* format a time_t as ascii, or use current time if 0 */
45const char *time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc);
46
47/* struct timeval functions */
48
49const char *tv_string(const struct timeval *tv, struct gc_arena *gc);
50
51const char *tv_string_abs(const struct timeval *tv, struct gc_arena *gc);
52
53extern time_t now; /* updated frequently to time(NULL) */
54
55void time_test(void);
56
57void update_now(const time_t system_time);
58
59extern time_t now_usec;
60void update_now_usec(struct timeval *tv);
61
62#if defined(__GNUC__) || defined(__clang__)
63#pragma GCC diagnostic push
64#pragma GCC diagnostic ignored "-Wconversion"
65#endif
66
67static inline int
68openvpn_gettimeofday(struct timeval *tv, void *tz)
69{
70 const int status = gettimeofday(tv, tz);
71 if (!status)
72 {
74 tv->tv_sec = now;
75 tv->tv_usec = now_usec;
76 }
77 return status;
78}
79
80static inline void
82{
83#ifdef _WIN32
84 /* on _WIN32, gettimeofday is faster than time(NULL) */
85 struct timeval tv;
86 openvpn_gettimeofday(&tv, NULL);
87#else
88 update_now(time(NULL));
89 now_usec = 0;
90#endif
91}
92
93static inline time_t
94openvpn_time(time_t *t)
95{
97 if (t)
98 {
99 *t = now;
100 }
101 return now;
102}
103
104static inline void
105tv_clear(struct timeval *tv)
106{
107 tv->tv_sec = 0;
108 tv->tv_usec = 0;
109}
110
111static inline bool
112tv_defined(const struct timeval *tv)
113{
114 return tv->tv_sec > 0 && tv->tv_usec > 0;
115}
116
117/* return tv1 - tv2 in usec, constrained by max_seconds */
118static inline int
119tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
120{
121 const int max_usec = max_seconds * 1000000;
122 const int sec_diff = tv1->tv_sec - tv2->tv_sec;
123
124 if (sec_diff > ((int)max_seconds + 10))
125 {
126 return max_usec;
127 }
128 else if (sec_diff < -((int)max_seconds + 10))
129 {
130 return -max_usec;
131 }
132 return constrain_int(sec_diff * 1000000 + (tv1->tv_usec - tv2->tv_usec), -max_usec, max_usec);
133}
134
135static inline void
136tv_add(struct timeval *dest, const struct timeval *src)
137{
138 dest->tv_sec += src->tv_sec;
139 dest->tv_usec += src->tv_usec;
140 dest->tv_sec += (dest->tv_usec >> 20);
141 dest->tv_usec &= 0x000FFFFF;
142 if (dest->tv_usec >= 1000000)
143 {
144 dest->tv_usec -= 1000000;
145 dest->tv_sec += 1;
146 }
147}
148
149static inline bool
150tv_lt(const struct timeval *t1, const struct timeval *t2)
151{
152 if (t1->tv_sec < t2->tv_sec)
153 {
154 return true;
155 }
156 else if (t1->tv_sec > t2->tv_sec)
157 {
158 return false;
159 }
160 else
161 {
162 return t1->tv_usec < t2->tv_usec;
163 }
164}
165
166static inline bool
167tv_le(const struct timeval *t1, const struct timeval *t2)
168{
169 if (t1->tv_sec < t2->tv_sec)
170 {
171 return true;
172 }
173 else if (t1->tv_sec > t2->tv_sec)
174 {
175 return false;
176 }
177 else
178 {
179 return t1->tv_usec <= t2->tv_usec;
180 }
181}
182
183static inline bool
184tv_ge(const struct timeval *t1, const struct timeval *t2)
185{
186 if (t1->tv_sec > t2->tv_sec)
187 {
188 return true;
189 }
190 else if (t1->tv_sec < t2->tv_sec)
191 {
192 return false;
193 }
194 else
195 {
196 return t1->tv_usec >= t2->tv_usec;
197 }
198}
199
200static inline bool
201tv_gt(const struct timeval *t1, const struct timeval *t2)
202{
203 if (t1->tv_sec > t2->tv_sec)
204 {
205 return true;
206 }
207 else if (t1->tv_sec < t2->tv_sec)
208 {
209 return false;
210 }
211 else
212 {
213 return t1->tv_usec > t2->tv_usec;
214 }
215}
216
217static inline bool
218tv_eq(const struct timeval *t1, const struct timeval *t2)
219{
220 return t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec;
221}
222
223static inline void
224tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
225{
226 int sec = t2->tv_sec - t1->tv_sec;
227 int usec = t2->tv_usec - t1->tv_usec;
228
229 while (usec < 0)
230 {
231 usec += 1000000;
232 sec -= 1;
233 }
234
235 if (sec < 0)
236 {
237 usec = sec = 0;
238 }
239
240 dest->tv_sec = sec;
241 dest->tv_usec = usec;
242}
243
244#if defined(__GNUC__) || defined(__clang__)
245#pragma GCC diagnostic pop
246#endif
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:35
static int constrain_int(int x, int min, int max)
Definition integer.h:118
static SERVICE_STATUS status
Definition interactive.c:51
static int tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
Definition otime.h:119
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:109
static bool tv_le(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:167
static bool tv_eq(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:218
static void tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
Definition otime.h:224
static void interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
Definition otime.h:267
time_t now_usec
Definition otime.c:36
struct frequency_limit * frequency_limit_init(int max, int per)
Definition otime.c:150
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:184
void frequency_limit_free(struct frequency_limit *f)
Definition otime.c:165
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:150
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:171
static time_t openvpn_time(time_t *t)
Definition otime.h:94
static bool tv_gt(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:201
static void update_time(void)
Definition otime.h:81
static int openvpn_gettimeofday(struct timeval *tv, void *tz)
Definition otime.h:68
void time_test(void)
static void tv_clear(struct timeval *tv)
Definition otime.h:105
static bool tv_defined(const struct timeval *tv)
Definition otime.h:112
#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 void tv_add(struct timeval *dest, const struct timeval *src)
Definition otime.h:136
time_t reset
Definition otime.h:35
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
struct gc_arena gc
Definition test_ssl.c:131