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