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