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
62static inline int
63openvpn_gettimeofday(struct timeval *tv, void *tz)
64{
65 const int status = gettimeofday(tv, tz);
66 if (!status)
67 {
69 tv->tv_sec = now;
70 tv->tv_usec = now_usec;
71 }
72 return status;
73}
74
75static inline void
77{
78#ifdef _WIN32
79 /* on _WIN32, gettimeofday is faster than time(NULL) */
80 struct timeval tv;
81 openvpn_gettimeofday(&tv, NULL);
82#else
83 update_now(time(NULL));
84 now_usec = 0;
85#endif
86}
87
88static inline time_t
89openvpn_time(time_t *t)
90{
92 if (t)
93 {
94 *t = now;
95 }
96 return now;
97}
98
99static inline void
100tv_clear(struct timeval *tv)
101{
102 tv->tv_sec = 0;
103 tv->tv_usec = 0;
104}
105
106static inline bool
107tv_defined(const struct timeval *tv)
108{
109 return tv->tv_sec > 0 && tv->tv_usec > 0;
110}
111
112/* return tv1 - tv2 in usec, constrained by max_seconds */
113static inline int
114tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
115{
116 const int max_usec = max_seconds * 1000000;
117 const int sec_diff = tv1->tv_sec - tv2->tv_sec;
118
119 if (sec_diff > ((int)max_seconds + 10))
120 {
121 return max_usec;
122 }
123 else if (sec_diff < -((int)max_seconds + 10))
124 {
125 return -max_usec;
126 }
127 return constrain_int(sec_diff * 1000000 + (tv1->tv_usec - tv2->tv_usec), -max_usec, max_usec);
128}
129
130static inline void
131tv_add(struct timeval *dest, const struct timeval *src)
132{
133 dest->tv_sec += src->tv_sec;
134 dest->tv_usec += src->tv_usec;
135 dest->tv_sec += (dest->tv_usec >> 20);
136 dest->tv_usec &= 0x000FFFFF;
137 if (dest->tv_usec >= 1000000)
138 {
139 dest->tv_usec -= 1000000;
140 dest->tv_sec += 1;
141 }
142}
143
144static inline bool
145tv_lt(const struct timeval *t1, const struct timeval *t2)
146{
147 if (t1->tv_sec < t2->tv_sec)
148 {
149 return true;
150 }
151 else if (t1->tv_sec > t2->tv_sec)
152 {
153 return false;
154 }
155 else
156 {
157 return t1->tv_usec < t2->tv_usec;
158 }
159}
160
161static inline bool
162tv_le(const struct timeval *t1, const struct timeval *t2)
163{
164 if (t1->tv_sec < t2->tv_sec)
165 {
166 return true;
167 }
168 else if (t1->tv_sec > t2->tv_sec)
169 {
170 return false;
171 }
172 else
173 {
174 return t1->tv_usec <= t2->tv_usec;
175 }
176}
177
178static inline bool
179tv_ge(const struct timeval *t1, const struct timeval *t2)
180{
181 if (t1->tv_sec > t2->tv_sec)
182 {
183 return true;
184 }
185 else if (t1->tv_sec < t2->tv_sec)
186 {
187 return false;
188 }
189 else
190 {
191 return t1->tv_usec >= t2->tv_usec;
192 }
193}
194
195static inline bool
196tv_gt(const struct timeval *t1, const struct timeval *t2)
197{
198 if (t1->tv_sec > t2->tv_sec)
199 {
200 return true;
201 }
202 else if (t1->tv_sec < t2->tv_sec)
203 {
204 return false;
205 }
206 else
207 {
208 return t1->tv_usec > t2->tv_usec;
209 }
210}
211
212static inline bool
213tv_eq(const struct timeval *t1, const struct timeval *t2)
214{
215 return t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec;
216}
217
218static inline void
219tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
220{
221 int sec = t2->tv_sec - t1->tv_sec;
222 int usec = t2->tv_usec - t1->tv_usec;
223
224 while (usec < 0)
225 {
226 usec += 1000000;
227 sec -= 1;
228 }
229
230 if (sec < 0)
231 {
232 usec = sec = 0;
233 }
234
235 dest->tv_sec = sec;
236 dest->tv_usec = usec;
237}
238
239#define TV_WITHIN_SIGMA_MAX_SEC 600
240#define TV_WITHIN_SIGMA_MAX_USEC (TV_WITHIN_SIGMA_MAX_SEC * 1000000)
241
242/*
243 * Is t1 and t2 within sigma microseconds of each other?
244 */
245static inline bool
246tv_within_sigma(const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
247{
248 /* sigma should be less than 10 minutes */
249 const int delta = tv_subtract(t1, t2, TV_WITHIN_SIGMA_MAX_SEC);
250 return -(int)sigma <= delta && delta <= (int)sigma;
251}
252
253/*
254 * Used to determine in how many seconds we should be
255 * called again.
256 */
257static inline void
258interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
259{
260 if (at > current)
261 {
262 const interval_t delta = (interval_t)(at - current);
263 if (delta < *wakeup)
264 {
265 *wakeup = delta;
266 }
267 if (*wakeup < 0)
268 {
269 *wakeup = 0;
270 }
271 }
272}
273
274#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:114
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
static bool tv_le(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:162
static bool tv_eq(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:213
static void tv_delta(struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
Definition otime.h:219
static void interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
Definition otime.h:258
time_t now_usec
Definition otime.c:36
struct frequency_limit * frequency_limit_init(int max, int per)
Definition otime.c:141
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:179
void frequency_limit_free(struct frequency_limit *f)
Definition otime.c:156
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:145
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:162
static time_t openvpn_time(time_t *t)
Definition otime.h:89
static bool tv_gt(const struct timeval *t1, const struct timeval *t2)
Definition otime.h:196
static void update_time(void)
Definition otime.h:76
static int openvpn_gettimeofday(struct timeval *tv, void *tz)
Definition otime.h:63
void time_test(void)
static void tv_clear(struct timeval *tv)
Definition otime.h:100
static bool tv_defined(const struct timeval *tv)
Definition otime.h:107
#define TV_WITHIN_SIGMA_MAX_SEC
Definition otime.h:239
static bool tv_within_sigma(const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
Definition otime.h:246
static void tv_add(struct timeval *dest, const struct timeval *src)
Definition otime.h:131
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:154