BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file BConnection.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #ifndef BADVPN_SYSTEM_BCONNECTION
31 #define BADVPN_SYSTEM_BCONNECTION
32  
33 #include <misc/debug.h>
34 #include <flow/StreamPassInterface.h>
35 #include <flow/StreamRecvInterface.h>
36 #include <system/BAddr.h>
37 #include <system/BReactor.h>
38 #include <system/BNetwork.h>
39  
40  
41  
42 /**
43 * Checks if the given address is supported by {@link BConnection} and related objects.
44 *
45 * @param addr address to check. Must be a proper {@link BAddr} object according to
46 * {@link BIPAddr_Assert}.
47 * @return 1 if supported, 0 if not
48 */
49 int BConnection_AddressSupported (BAddr addr);
50  
51  
52 #define BLISCON_FROM_ADDR 1
53 #define BLISCON_FROM_UNIX 2
54  
55 struct BLisCon_from {
56 int type;
57 union {
58 struct {
59 BAddr addr;
60 } from_addr;
61 #ifndef BADVPN_USE_WINAPI
62 struct {
63 char const *socket_path;
64 } from_unix;
65 #endif
66 } u;
67 };
68  
69 static struct BLisCon_from BLisCon_from_addr (BAddr addr)
70 {
71 struct BLisCon_from res;
72 res.type = BLISCON_FROM_ADDR;
73 res.u.from_addr.addr = addr;
74 return res;
75 }
76  
77 #ifndef BADVPN_USE_WINAPI
78 static struct BLisCon_from BLisCon_from_unix (char const *socket_path)
79 {
80 struct BLisCon_from res;
81 res.type = BLISCON_FROM_UNIX;
82 res.u.from_unix.socket_path = socket_path;
83 return res;
84 }
85 #endif
86  
87  
88 struct BListener_s;
89  
90 /**
91 * Object which listens for connections on an address.
92 * When a connection is ready, the {@link BListener_handler} handler is called, from which
93 * the connection can be accepted into a new {@link BConnection} object.
94 */
95 typedef struct BListener_s BListener;
96  
97 /**
98 * Handler called when a new connection is ready.
99 * The connection can be accepted by calling {@link BConnection_Init} with the a
100 * BCONNECTION_SOURCE_LISTENER 'source' argument.
101 * If no attempt is made to accept the connection from the job closure of this handler,
102 * the connection will be discarded.
103 *
104 * @param user as in {@link BListener_Init}
105 */
106 typedef void (*BListener_handler) (void *user);
107  
108 /**
109 * Common listener initialization function.
110 *
111 * The other type-specific init functions are wrappers around this one.
112 */
113 int BListener_InitFrom (BListener *o, struct BLisCon_from from,
114 BReactor *reactor, void *user,
115 BListener_handler handler) WARN_UNUSED;
116  
117 /**
118 * Initializes the object for listening on an address.
119 * {@link BNetwork_GlobalInit} must have been done.
120 *
121 * @param o the object
122 * @param addr address to listen on
123 * @param reactor reactor we live in
124 * @param user argument to handler
125 * @param handler handler called when a connection can be accepted
126 * @return 1 on success, 0 on failure
127 */
128 int BListener_Init (BListener *o, BAddr addr, BReactor *reactor, void *user,
129 BListener_handler handler) WARN_UNUSED;
130  
131 #ifndef BADVPN_USE_WINAPI
132 /**
133 * Initializes the object for listening on a Unix socket.
134 * {@link BNetwork_GlobalInit} must have been done.
135 *
136 * @param o the object
137 * @param socket_path socket path for listening
138 * @param reactor reactor we live in
139 * @param user argument to handler
140 * @param handler handler called when a connection can be accepted
141 * @return 1 on success, 0 on failure
142 */
143 int BListener_InitUnix (BListener *o, const char *socket_path, BReactor *reactor, void *user,
144 BListener_handler handler) WARN_UNUSED;
145 #endif
146  
147 /**
148 * Frees the object.
149 *
150 * @param o the object
151 */
152 void BListener_Free (BListener *o);
153  
154  
155  
156 struct BConnector_s;
157  
158 /**
159 * Object which connects to an address.
160 * When the connection attempt finishes, the {@link BConnector_handler} handler is called, from which,
161 * if successful, the resulting connection can be moved to a new {@link BConnection} object.
162 */
163 typedef struct BConnector_s BConnector;
164  
165 /**
166 * Handler called when the connection attempt finishes.
167 * If the connection attempt succeeded (is_error==0), the new connection can be used by calling
168 * {@link BConnection_Init} with a BCONNECTION_SOURCE_TYPE_CONNECTOR 'source' argument.
169 * This handler will be called at most once. The connector object need not be freed after it
170 * is called.
171 *
172 * @param user as in {@link BConnector_Init}
173 * @param is_error whether the connection attempt succeeded (0) or failed (1)
174 */
175 typedef void (*BConnector_handler) (void *user, int is_error);
176  
177 /**
178 * Common connector initialization function.
179 *
180 * The other type-specific init functions are wrappers around this one.
181 */
182 int BConnector_InitFrom (BConnector *o, struct BLisCon_from from, BReactor *reactor, void *user,
183 BConnector_handler handler) WARN_UNUSED;
184  
185 /**
186 * Initializes the object for connecting to an address.
187 * {@link BNetwork_GlobalInit} must have been done.
188 *
189 * @param o the object
190 * @param addr address to connect to
191 * @param reactor reactor we live in
192 * @param user argument to handler
193 * @param handler handler called when the connection attempt finishes
194 * @return 1 on success, 0 on failure
195 */
196 int BConnector_Init (BConnector *o, BAddr addr, BReactor *reactor, void *user,
197 BConnector_handler handler) WARN_UNUSED;
198  
199 #ifndef BADVPN_USE_WINAPI
200 /**
201 * Initializes the object for connecting to a Unix socket.
202 * {@link BNetwork_GlobalInit} must have been done.
203 *
204 * @param o the object
205 * @param socket_path socket path for connecting
206 * @param reactor reactor we live in
207 * @param user argument to handler
208 * @param handler handler called when the connection attempt finishes
209 * @return 1 on success, 0 on failure
210 */
211 int BConnector_InitUnix (BConnector *o, const char *socket_path, BReactor *reactor, void *user,
212 BConnector_handler handler) WARN_UNUSED;
213 #endif
214  
215 /**
216 * Frees the object.
217 *
218 * @param o the object
219 */
220 void BConnector_Free (BConnector *o);
221  
222  
223  
224 #define BCONNECTION_SOURCE_TYPE_LISTENER 1
225 #define BCONNECTION_SOURCE_TYPE_CONNECTOR 2
226 #define BCONNECTION_SOURCE_TYPE_PIPE 3
227  
228 struct BConnection_source {
229 int type;
230 union {
231 struct {
232 BListener *listener;
233 BAddr *out_addr;
234 } listener;
235 struct {
236 BConnector *connector;
237 } connector;
238 #ifndef BADVPN_USE_WINAPI
239 struct {
240 int pipefd;
241 int close_it;
242 } pipe;
243 #endif
244 } u;
245 };
246  
247 static struct BConnection_source BConnection_source_listener (BListener *listener, BAddr *out_addr)
248 {
249 struct BConnection_source s;
250 s.type = BCONNECTION_SOURCE_TYPE_LISTENER;
251 s.u.listener.listener = listener;
252 s.u.listener.out_addr = out_addr;
253 return s;
254 }
255  
256 static struct BConnection_source BConnection_source_connector (BConnector *connector)
257 {
258 struct BConnection_source s;
259 s.type = BCONNECTION_SOURCE_TYPE_CONNECTOR;
260 s.u.connector.connector = connector;
261 return s;
262 }
263  
264 #ifndef BADVPN_USE_WINAPI
265 static struct BConnection_source BConnection_source_pipe (int pipefd, int close_it)
266 {
267 struct BConnection_source s;
268 s.type = BCONNECTION_SOURCE_TYPE_PIPE;
269 s.u.pipe.pipefd = pipefd;
270 s.u.pipe.close_it = close_it;
271 return s;
272 }
273 #endif
274  
275 struct BConnection_s;
276  
277 /**
278 * Object which represents a stream connection. This is usually a TCP connection, either client
279 * or server, but may also be used with any file descriptor (e.g. pipe) on Unix-like systems.
280 * Sending and receiving is performed via {@link StreamPassInterface} and {@link StreamRecvInterface},
281 * respectively.
282 */
283 typedef struct BConnection_s BConnection;
284  
285 #define BCONNECTION_EVENT_ERROR 1
286 #define BCONNECTION_EVENT_RECVCLOSED 2
287  
288 /**
289 * Handler called when an error occurs or the receive end of the connection was closed
290 * by the remote peer.
291 * - If event is BCONNECTION_EVENT_ERROR, the connection is no longer usable and must be freed
292 * from withing the job closure of this handler. No further I/O or interface initialization
293 * must occur.
294 * - If event is BCONNECTION_EVENT_RECVCLOSED, no further receive I/O or receive interface
295 * initialization must occur. It is guarantted that the receive interface was initialized.
296 *
297 * @param user as in {@link BConnection_Init} or {@link BConnection_SetHandlers}
298 * @param event what happened - BCONNECTION_EVENT_ERROR or BCONNECTION_EVENT_RECVCLOSED
299 */
300 typedef void (*BConnection_handler) (void *user, int event);
301  
302 /**
303 * Initializes the object.
304 * {@link BNetwork_GlobalInit} must have been done.
305 *
306 * @param o the object
307 * @param source specifies what the connection comes from. This argument must be created with one of the
308 * following macros:
309 * - BCONNECTION_SOURCE_LISTENER(BListener *, BAddr *)
310 * Accepts a connection ready on a {@link BListener} object. Must be called from the job
311 * closure of the listener's {@link BListener_handler}, and must be the first attempt
312 * for this handler invocation. The address of the client is written if the address
313 * argument is not NULL (theoretically an invalid address may be returned).
314 * - BCONNECTION_SOURCE_CONNECTOR(Bconnector *)
315 * Uses a connection establised with {@link BConnector}. Must be called from the job
316 * closure of the connector's {@link BConnector_handler}, the handler must be reporting
317 * successful connection, and must be the first attempt for this handler invocation.
318 * - BCONNECTION_SOURCE_PIPE(int pipefd, int close_it)
319 * On Unix-like systems, uses the provided file descriptor. The file descriptor number must
320 * be >=0. If close_it is true, the connector will take responsibility of closing the
321 * pipefd. Note that it will be closed even when this Init fails.
322 * @param reactor reactor we live in
323 * @param user argument to handler
324 * @param handler handler called when an error occurs or the receive end of the connection was closed
325 * by the remote peer.
326 * @return 1 on success, 0 on failure
327 */
328 int BConnection_Init (BConnection *o, struct BConnection_source source, BReactor *reactor, void *user,
329 BConnection_handler handler) WARN_UNUSED;
330  
331 /**
332 * Frees the object.
333 * The send and receive interfaces must not be initialized.
334 * If the connection was created with a BCONNECTION_SOURCE_PIPE 'source' argument, the file descriptor
335 * will not be closed.
336 *
337 * @param o the object
338 */
339 void BConnection_Free (BConnection *o);
340  
341 /**
342 * Updates the handler function.
343 *
344 * @param o the object
345 * @param user argument to handler
346 * @param handler new handler function, as in {@link BConnection_Init}. Additionally, may be NULL to
347 * remove the current handler. In this case, a proper handler must be set before anything
348 * can happen with the connection. This is used when moving the connection ownership from
349 * one module to another.
350 */
351 void BConnection_SetHandlers (BConnection *o, void *user, BConnection_handler handler);
352  
353 /**
354 * Sets the SO_SNDBUF socket option.
355 *
356 * @param o the object
357 * @param buf_size value for SO_SNDBUF option
358 * @return 1 on success, 0 on failure
359 */
360 int BConnection_SetSendBuffer (BConnection *o, int buf_size);
361  
362 /**
363 * Determines the local address.
364 *
365 * This calls getsockname() to determine the local address and returns the result as
366 * BAddr. This function fails if the address cannot be determined or translated to
367 * BAddr (it never succeeds but returns a BADDR_TYPE_NONE address).
368 *
369 * @param o the object
370 * @param local_addr returns the local bound address.
371 * @return 1 on success, 0 on failure
372 */
373 int BConnection_GetLocalAddress (BConnection *o, BAddr *local_addr);
374  
375 /**
376 * Initializes the send interface for the connection.
377 * The send interface must not be initialized.
378 *
379 * @param o the object
380 */
381 void BConnection_SendAsync_Init (BConnection *o);
382  
383 /**
384 * Frees the send interface for the connection.
385 * The send interface must be initialized.
386 * If the send interface was busy when this is called, the connection is no longer usable and must be
387 * freed before any further I/O or interface initialization.
388 *
389 * @param o the object
390 */
391 void BConnection_SendAsync_Free (BConnection *o);
392  
393 /**
394 * Returns the send interface.
395 * The send interface must be initialized.
396 *
397 * @param o the object
398 * @return send interface
399 */
400 StreamPassInterface * BConnection_SendAsync_GetIf (BConnection *o);
401  
402 /**
403 * Initializes the receive interface for the connection.
404 * The receive interface must not be initialized.
405 *
406 * @param o the object
407 */
408 void BConnection_RecvAsync_Init (BConnection *o);
409  
410 /**
411 * Frees the receive interface for the connection.
412 * The receive interface must be initialized.
413 * If the receive interface was busy when this is called, the connection is no longer usable and must be
414 * freed before any further I/O or interface initialization.
415 *
416 * @param o the object
417 */
418 void BConnection_RecvAsync_Free (BConnection *o);
419  
420 /**
421 * Returns the receive interface.
422 * The receive interface must be initialized.
423 *
424 * @param o the object
425 * @return receive interface
426 */
427 StreamRecvInterface * BConnection_RecvAsync_GetIf (BConnection *o);
428  
429  
430  
431 #ifdef BADVPN_USE_WINAPI
432 #include "BConnection_win.h"
433 #else
434 #include "BConnection_unix.h"
435 #endif
436  
437 #endif