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-2018 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 EVENT_H
25 #define EVENT_H
26
27 #include "win32.h"
28 #include "sig.h"
29 #include "perf.h"
30
31 /*
32 * rwflags passed to event_ctl and returned by
33 * struct event_set_return.
34 */
35 #define READ_SHIFT 0
36 #define WRITE_SHIFT 1
37
38 #define EVENT_UNDEF 4
39 #define EVENT_READ (1 << READ_SHIFT)
40 #define EVENT_WRITE (1 << WRITE_SHIFT)
41
42 /* event flags returned by io_wait.
43 *
44 * All these events are defined as bits in a bitfield.
45 * Each event 'type' owns two bits in the bitfield: one for the READ
46 * event and one for the WRITE event.
47 *
48 * For this reason, the specific event bit is calculated by adding
49 * the event type identifier (always a multiple of 2, as defined
50 * below) to 0 for READ and 1 for WRITE.
51 *
52 * E.g.
53 * MANAGEMENT_SHIFT = 6; <---- event type identifier
54 * MANAGEMENT_READ = (1 << (6 + 0)), <---- READ event
55 * MANAGEMENT_WRITE = (1 << (6 + 1)) <---- WRITE event
56 *
57 * 'error' and 'file_close' are special and use read/write for different
58 * signals.
59 */
60
61 #define SOCKET_SHIFT 0
62 #define SOCKET_READ (1 << (SOCKET_SHIFT + READ_SHIFT))
63 #define SOCKET_WRITE (1 << (SOCKET_SHIFT + WRITE_SHIFT))
64 #define TUN_SHIFT 2
65 #define TUN_READ (1 << (TUN_SHIFT + READ_SHIFT))
66 #define TUN_WRITE (1 << (TUN_SHIFT + WRITE_SHIFT))
67 #define ERR_SHIFT 4
68 #define ES_ERROR (1 << (ERR_SHIFT + READ_SHIFT))
69 #define ES_TIMEOUT (1 << (ERR_SHIFT + WRITE_SHIFT))
70 #define MANAGEMENT_SHIFT 6
71 #define MANAGEMENT_READ (1 << (MANAGEMENT_SHIFT + READ_SHIFT))
72 #define MANAGEMENT_WRITE (1 << (MANAGEMENT_SHIFT + WRITE_SHIFT))
73 #define FILE_SHIFT 8
74 #define FILE_CLOSED (1 << (FILE_SHIFT + READ_SHIFT))
75
76 /*
77 * Initialization flags passed to event_set_init
78 */
79 #define EVENT_METHOD_US_TIMEOUT (1<<0)
80 #define EVENT_METHOD_FAST (1<<1)
81
82 #ifdef _WIN32
83
84 typedef const struct rw_handle *event_t;
85
86 #define UNDEFINED_EVENT (NULL)
87
88 #else /* ifdef _WIN32 */
89
90 typedef int event_t;
91
92 #define UNDEFINED_EVENT (-1)
93
94 #endif
95
96 struct event_set;
97 struct event_set_return;
98
99 struct event_set_functions
100 {
101 void (*free)(struct event_set *es);
102 void (*reset)(struct event_set *es);
103 void (*del)(struct event_set *es, event_t event);
104 void (*ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg);
105
106 /*
107 * Return status for wait:
108 * -1 on signal or error
109 * 0 on timeout
110 * length of event_set_return if at least 1 event is returned
111 */
112 int (*wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen);
113 };
114
115 struct event_set_return
116 {
117 unsigned int rwflags;
118 void *arg;
119 };
120
121 struct event_set
122 {
123 struct event_set_functions func;
124 };
125
126 /*
127 * maxevents on input: desired max number of event_t descriptors
128 * simultaneously set with event_ctl
129 * maxevents on output: may be modified down, depending on limitations
130 * of underlying API
131 * flags: EVENT_METHOD_x flags
132 */
133 struct event_set *event_set_init(int *maxevents, unsigned int flags);
134
135 static inline void
event_free(struct event_set * es)136 event_free(struct event_set *es)
137 {
138 if (es)
139 {
140 (*es->func.free)(es);
141 }
142 }
143
144 static inline void
event_reset(struct event_set * es)145 event_reset(struct event_set *es)
146 {
147 (*es->func.reset)(es);
148 }
149
150 static inline void
event_del(struct event_set * es,event_t event)151 event_del(struct event_set *es, event_t event)
152 {
153 (*es->func.del)(es, event);
154 }
155
156 static inline void
event_ctl(struct event_set * es,event_t event,unsigned int rwflags,void * arg)157 event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
158 {
159 (*es->func.ctl)(es, event, rwflags, arg);
160 }
161
162 static inline int
event_wait(struct event_set * es,const struct timeval * tv,struct event_set_return * out,int outlen)163 event_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
164 {
165 int ret;
166 perf_push(PERF_IO_WAIT);
167 ret = (*es->func.wait)(es, tv, out, outlen);
168 perf_pop();
169 return ret;
170 }
171
172 static inline void
event_set_return_init(struct event_set_return * esr)173 event_set_return_init(struct event_set_return *esr)
174 {
175 esr->rwflags = 0;
176 esr->arg = NULL;
177 }
178
179 #ifdef _WIN32
180
181 static inline void
wait_signal(struct event_set * es,void * arg)182 wait_signal(struct event_set *es, void *arg)
183 {
184 if (HANDLE_DEFINED(win32_signal.in.read))
185 {
186 event_ctl(es, &win32_signal.in, EVENT_READ, arg);
187 }
188 }
189
190 #else /* ifdef _WIN32 */
191
192 static inline void
wait_signal(struct event_set * es,void * arg)193 wait_signal(struct event_set *es, void *arg)
194 {
195 }
196
197 #endif
198
199 #endif /* ifndef EVENT_H */
200