OpenVPN
interval.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 /*
25  * The interval_ routines are designed to optimize the calling of a routine
26  * (normally tls_multi_process()) which can be called less frequently
27  * between triggers.
28  */
29 
30 #ifndef INTERVAL_H
31 #define INTERVAL_H
32 
33 #include "otime.h"
34 
35 #define INTERVAL_DEBUG 0
36 
37 /*
38  * Designed to limit calls to expensive functions that need to be called
39  * regularly.
40  */
41 
42 struct interval
43 {
47  time_t last_action;
49 };
50 
51 void interval_init(struct interval *top, int horizon, int refresh);
52 
53 /*
54  * IF
55  * last_action less than horizon seconds ago
56  * OR last_test_true more than refresh seconds ago
57  * OR hit future_trigger
58  * THEN
59  * return true
60  * ELSE
61  * set wakeup to the number of seconds until a true return
62  * return false
63  */
64 
65 static inline bool
66 interval_test(struct interval *top)
67 {
68  bool trigger = false;
69  const time_t local_now = now;
70 
71  if (top->future_trigger && local_now >= top->future_trigger)
72  {
73  trigger = true;
74  top->future_trigger = 0;
75  }
76 
77  if (top->last_action + top->horizon > local_now
78  || top->last_test_true + top->refresh <= local_now
79  || trigger)
80  {
81  top->last_test_true = local_now;
82 #if INTERVAL_DEBUG
83  dmsg(D_INTERVAL, "INTERVAL interval_test true");
84 #endif
85  return true;
86  }
87  else
88  {
89  return false;
90  }
91 }
92 
93 static inline void
95 {
96  const time_t local_now = now;
97  interval_earliest_wakeup(wakeup, top->last_test_true + top->refresh, local_now);
98  interval_earliest_wakeup(wakeup, top->future_trigger, local_now);
99 #if INTERVAL_DEBUG
100  dmsg(D_INTERVAL, "INTERVAL interval_schedule wakeup=%d", (int)*wakeup);
101 #endif
102 }
103 
104 /*
105  * In wakeup seconds, interval_test will return true once.
106  */
107 static inline void
109 {
110  if (wakeup)
111  {
112 #if INTERVAL_DEBUG
113  dmsg(D_INTERVAL, "INTERVAL interval_future_trigger %d", (int)wakeup);
114 #endif
115  top->future_trigger = now + wakeup;
116  }
117 }
118 
119 /*
120  * Once an action is triggered, interval_test will remain true for
121  * horizon seconds.
122  */
123 static inline void
125 {
126 #if INTERVAL_DEBUG
127  dmsg(D_INTERVAL, "INTERVAL action");
128 #endif
129  top->last_action = now;
130 }
131 
132 /*
133  * Measure when n seconds beyond an event have elapsed
134  */
135 
137 {
138  bool defined;
140  time_t last;
141 };
142 
143 static inline bool
145 {
146  return et->defined;
147 }
154 static inline void
156 {
157  et->defined = false;
158  et->n = 0;
159  et->last = 0;
160 }
161 
162 
173 static inline void
174 event_timeout_init(struct event_timeout *et, interval_t n, const time_t last)
175 {
176  et->defined = true;
177  et->n = (n >= 0) ? n : 0;
178  et->last = last;
179 }
180 
188 static inline void
190 {
191  if (et->defined)
192  {
193  et->last = now;
194  }
195 }
196 
205 static inline void
207 {
208  if (et->defined)
209  {
210  et->n = (n >= 0) ? n : 0;
211  }
212 }
213 
218 static inline interval_t
220 {
221  return (interval_t) ((et->last + et->n) - now);
222 }
223 
224 #define ETT_DEFAULT (-1)
225 
258 bool event_timeout_trigger(struct event_timeout *et,
259  struct timeval *tv,
260  int et_const_retry);
261 
262 /*
263  * Measure time intervals in microseconds
264  */
265 
266 #define USEC_TIMER_MAX 60 /* maximum interval size in seconds */
267 
268 #define USEC_TIMER_MAX_USEC (USEC_TIMER_MAX * 1000000)
269 
270 struct usec_timer {
271  struct timeval start;
272  struct timeval end;
273 };
274 
275 #ifdef HAVE_GETTIMEOFDAY
276 
277 static inline void
279 {
280  CLEAR(*obj);
281  openvpn_gettimeofday(&obj->start, NULL);
282 }
283 
284 static inline void
286 {
287  openvpn_gettimeofday(&obj->end, NULL);
288 }
289 
290 #endif /* HAVE_GETTIMEOFDAY */
291 
292 static inline bool
294 {
295  return obj->start.tv_sec && obj->end.tv_sec;
296 }
297 
298 static inline int
300 {
301  return tv_subtract(&obj->end, &obj->start, USEC_TIMER_MAX);
302 }
303 
304 #endif /* INTERVAL_H */
interval_t
int interval_t
Definition: common.h:36
interval_action
static void interval_action(struct interval *top)
Definition: interval.h:124
tv_subtract
static int tv_subtract(const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
Definition: otime.h:115
interval_init
void interval_init(struct interval *top, int horizon, int refresh)
Definition: interval.c:35
interval_schedule_wakeup
static void interval_schedule_wakeup(struct interval *top, interval_t *wakeup)
Definition: interval.h:94
interval_earliest_wakeup
static void interval_earliest_wakeup(interval_t *wakeup, time_t at, time_t current)
Definition: otime.h:258
dmsg
#define dmsg(flags,...)
Definition: error.h:154
event_timeout_init
static void event_timeout_init(struct event_timeout *et, interval_t n, const time_t last)
Initialises a timer struct.
Definition: interval.h:174
usec_timer_start
static void usec_timer_start(struct usec_timer *obj)
Definition: interval.h:278
event_timeout_modify_wakeup
static void event_timeout_modify_wakeup(struct event_timeout *et, interval_t n)
Sets the interval n of a timeout.
Definition: interval.h:206
interval::horizon
interval_t horizon
Definition: interval.h:45
usec_timer::start
struct timeval start
Definition: interval.h:271
CLEAR
#define CLEAR(x)
Definition: basic.h:33
interval::refresh
interval_t refresh
Definition: interval.h:44
event_timeout_trigger
bool event_timeout_trigger(struct event_timeout *et, struct timeval *tv, int et_const_retry)
This is the principal function for testing and triggering recurring timers.
Definition: interval.c:43
usec_timer_end
static void usec_timer_end(struct usec_timer *obj)
Definition: interval.h:285
event_timeout::defined
bool defined
This timeout is active.
Definition: interval.h:138
event_timeout::n
interval_t n
periodic interval for periodic timeouts
Definition: interval.h:139
usec_timer::end
struct timeval end
Definition: interval.h:272
usec_timer
Definition: interval.h:270
USEC_TIMER_MAX
#define USEC_TIMER_MAX
Definition: interval.h:266
interval_test
static bool interval_test(struct interval *top)
Definition: interval.h:66
usec_timer_interval_defined
static bool usec_timer_interval_defined(struct usec_timer *obj)
Definition: interval.h:293
interval::future_trigger
time_t future_trigger
Definition: interval.h:46
interval
Definition: interval.h:42
interval::last_test_true
time_t last_test_true
Definition: interval.h:48
usec_timer_interval
static int usec_timer_interval(struct usec_timer *obj)
Definition: interval.h:299
otime.h
openvpn_gettimeofday
static int openvpn_gettimeofday(struct timeval *tv, void *tz)
Definition: otime.h:64
now
time_t now
Definition: otime.c:34
event_timeout
Definition: interval.h:136
D_INTERVAL
#define D_INTERVAL
Definition: errlevel.h:158
event_timeout_defined
static bool event_timeout_defined(const struct event_timeout *et)
Definition: interval.h:144
event_timeout_clear
static void event_timeout_clear(struct event_timeout *et)
Clears the timeout and reset all values to 0.
Definition: interval.h:155
interval::last_action
time_t last_action
Definition: interval.h:47
event_timeout::last
time_t last
time of last event
Definition: interval.h:140
interval_future_trigger
static void interval_future_trigger(struct interval *top, interval_t wakeup)
Definition: interval.h:108
event_timeout_reset
static void event_timeout_reset(struct event_timeout *et)
Resets a timer.
Definition: interval.h:189
event_timeout_remaining
static interval_t event_timeout_remaining(struct event_timeout *et)
Returns the time until the timeout should triggered, from now.
Definition: interval.h:219