OpenVPN
multi_io.c
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-2026 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#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include "memdbg.h"
30
31#include "multi.h"
32#include "forward.h"
33#include "multi_io.h"
34
35#ifdef HAVE_SYS_INOTIFY_H
36#include <sys/inotify.h>
37#endif
38
39/*
40 * Special tags passed to event.[ch] functions
41 */
42#define MULTI_IO_SOCKET ((void *)1)
43#define MULTI_IO_TUN ((void *)2)
44#define MULTI_IO_SIG ((void *)3) /* Only on Windows */
45#define MULTI_IO_MANAGEMENT ((void *)4)
46#define MULTI_IO_FILE_CLOSE_WRITE ((void *)5)
47#define MULTI_IO_DCO ((void *)6)
48
49#ifndef ENABLE_SMALL
50static const char *
51pract(int action)
52{
53 switch (action)
54 {
55 case TA_UNDEF:
56 return "TA_UNDEF";
57
58 case TA_SOCKET_READ:
59 return "TA_SOCKET_READ";
60
62 return "TA_SOCKET_READ_RESIDUAL";
63
64 case TA_SOCKET_WRITE:
65 return "TA_SOCKET_WRITE";
66
68 return "TA_SOCKET_WRITE_READY";
69
71 return "TA_SOCKET_WRITE_DEFERRED";
72
73 case TA_TUN_READ:
74 return "TA_TUN_READ";
75
76 case TA_TUN_WRITE:
77 return "TA_TUN_WRITE";
78
79 case TA_INITIAL:
80 return "TA_INITIAL";
81
82 case TA_TIMEOUT:
83 return "TA_TIMEOUT";
84
86 return "TA_TUN_WRITE_TIMEOUT";
87
88 default:
89 return "?";
90 }
91}
92#endif
93
94static inline struct context *
96{
97 if (mi)
98 {
99 return &mi->context;
100 }
101 else
102 {
103 return &m->top;
104 }
105}
106
107struct multi_io *
108multi_io_init(const int maxclients)
109{
110 struct multi_io *multi_io;
111
112 ASSERT(maxclients >= 1);
113
115 multi_io->maxevents = maxclients + BASE_N_EVENTS;
119 msg(D_MULTI_LOW, "MULTI IO: MULTI_IO INIT maxclients=%d maxevents=%d", maxclients,
121 return multi_io;
122}
123
124void
126{
127 if (multi_io)
128 {
130 free(multi_io->esr);
131 free(multi_io);
132 }
133}
134
135/*
136 * Return the io flags appropriate for
137 * a point-to-multipoint tunnel.
138 */
139static unsigned int
140p2mp_iow_flags(const struct multi_context *m, const struct link_socket *sock)
141{
142 unsigned int flags = IOW_WAIT_SIGNAL;
143
144 if (m->pending)
145 {
146 if (TUN_OUT(&m->pending->context))
147 {
148 flags |= IOW_TO_TUN;
149 }
150
151 /* If the to be processed socket happens to be the same one on the pending
152 * UDP client instance, we set that socket ready for write */
153 if (LINK_OUT(&m->pending->context) && m->pending->context.c2.link_sockets[0] == sock)
154 {
155 flags |= IOW_TO_LINK;
156 }
157 }
158 else
159 {
160 flags |= IOW_READ;
161 }
162 return flags;
163}
164
165int
167{
168 int status;
169 unsigned int *persistent = &m->multi_io->tun_rwflags;
170
171 for (int i = 0; i < m->top.c1.link_sockets_num; i++)
172 {
173 struct link_socket *sock = m->top.c2.link_sockets[i];
174
175 if (proto_is_dgram(sock->info.proto))
176 {
177 multi_io_process_flags(&m->top, m->multi_io->es, sock, p2mp_iow_flags(m, sock));
178 }
179 else if (!tuntap_is_dco_win(m->top.c1.tuntap))
180 {
182 }
183 }
184
185 tun_set(m->top.c1.tuntap, m->multi_io->es, EVENT_READ, MULTI_IO_TUN, persistent);
186#if defined(ENABLE_DCO)
188#endif
189
190#ifdef ENABLE_MANAGEMENT
191 if (management)
192 {
195 }
196#endif
197
198#ifdef ENABLE_ASYNC_PUSH
199 /* arm inotify watcher */
201#endif
202
203 status =
205 update_time();
206 m->multi_io->n_esr = 0;
207 if (status > 0)
208 {
209 m->multi_io->n_esr = status;
210 }
211 return status;
212}
213
214static int
215multi_io_wait_lite(struct multi_context *m, struct multi_instance *mi, const int action,
216 bool *tun_input_pending)
217{
218 struct context *c = multi_get_context(m, mi);
219 unsigned int looking_for = 0;
220
221 dmsg(D_MULTI_DEBUG, "MULTI IO: multi_io_wait_lite a=%s mi=" ptr_format, pract(action),
222 (ptr_type)mi);
223
224 tv_clear(&c->c2.timeval); /* ZERO-TIMEOUT */
225
226 switch (action)
227 {
228 case TA_TUN_WRITE:
229 looking_for = TUN_WRITE;
230 tun_input_pending = NULL;
231 /* For some reason, the Linux 2.2 TUN/TAP driver hits this timeout */
232 c->c2.timeval.tv_sec = 1;
234 break;
235
236 case TA_SOCKET_WRITE:
237 looking_for = SOCKET_WRITE;
239 break;
240
241 default:
242 msg(M_FATAL, "MULTI IO: multi_io_wait_lite, unhandled action=%d", action);
243 }
244
245 if (tun_input_pending && (c->c2.event_set_status & TUN_READ))
246 {
247 *tun_input_pending = true;
248 }
249
250 if (c->c2.event_set_status & looking_for)
251 {
252 return action;
253 }
254 else
255 {
256 switch (action)
257 {
258 /* MULTI PROTOCOL socket output buffer is full */
259 case TA_SOCKET_WRITE:
261
262 /* TUN device timed out on accepting write */
263 case TA_TUN_WRITE:
265 }
266
267 return TA_UNDEF;
268 }
269}
270
288static bool
289multi_io_write_tun(struct multi_context *m, const unsigned int mpp_flags)
290{
291 struct multi_instance *mi = m->pending;
292 bool ret = true;
293
294 ASSERT(mi);
295#ifdef MULTI_DEBUG_EVENT_LOOP
296 printf("%s -> TUN len=%d\n", id(mi), mi->context.c2.to_tun.len);
297#endif
298 set_prefix(mi);
301 ret = multi_process_post(m, mi, mpp_flags);
302 clear_prefix();
303 return ret;
304}
305
306/*
307 * Drop a TUN/TAP outgoing packet..
308 */
309static void
310multi_io_drop_tun(struct multi_context *m, const unsigned int mpp_flags)
311{
312 struct multi_instance *mi = m->pending;
313
314 ASSERT(mi);
315
316 set_prefix(mi);
317
318 msg(D_MULTI_ERRORS, "MULTI: Outgoing TUN queue full, dropped packet len=%d",
319 mi->context.c2.to_tun.len);
320
322
323 multi_process_post(m, mi, mpp_flags);
324 clear_prefix();
325}
326
327/*
328 * Determine which instance has pending output
329 * and prepare the output for sending in
330 * the to_link buffer.
331 */
332static struct multi_instance *
334{
335 struct multi_instance *mi = NULL;
336
337 if (m->pending)
338 {
339 mi = m->pending;
340 }
341 else if (mbuf_defined(m->mbuf))
342 {
343 mi = multi_get_queue(m->mbuf);
344 }
345 return mi;
346}
347
348bool
349multi_io_send_link(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
350{
351 bool ret = true;
352 set_prefix(mi);
354 ret = multi_process_post(m, mi, mpp_flags);
355 clear_prefix();
356 return ret;
357}
358
359static bool
361 const unsigned int mpp_flags)
362{
363 struct mbuf_item item;
364 bool ret = true;
365 ASSERT(mi);
366
367 /* extract from queue */
368 if (mbuf_extract_item(mi->tcp_link_out_deferred, &item)) /* ciphertext IP packet */
369 {
370 dmsg(D_MULTI_TCP, "MULTI TCP: transmitting previously deferred packet");
371
372 ASSERT(mi == item.instance);
373 mi->context.c2.to_link = item.buffer->buf;
374 ret = multi_io_send_link(m, mi, mpp_flags);
375 mbuf_free_buf(item.buffer);
376 }
377 return ret;
378}
379
380static bool
381multi_io_write_link(struct multi_context *m, bool defer, const unsigned int mpp_flags)
382{
384 bool ret = true;
385
386 if (mi)
387 {
388 if ((defer && !proto_is_dgram(mi->context.c2.link_sockets[0]->info.proto))
390 {
391 /* save to queue */
392 struct buffer *buf = &mi->context.c2.to_link;
393 if (BLEN(buf) > 0)
394 {
395 struct mbuf_buffer *mb = mbuf_alloc_buf(buf);
396 struct mbuf_item item;
397
398 set_prefix(mi);
399 dmsg(D_MULTI_TCP, "MULTI TCP: queuing deferred packet");
400 item.buffer = mb;
401 item.instance = mi;
403 mbuf_free_buf(mb);
404 buf_reset(buf);
405 ret = multi_process_post(m, mi, mpp_flags);
406 if (!ret)
407 {
408 mi = NULL;
409 }
410 clear_prefix();
411 }
412 }
413 else
414 {
415 ret = multi_io_send_link(m, mi, mpp_flags);
416 if (!ret)
417 {
418 mi = NULL;
419 }
420 }
421 }
422 return ret;
423}
424
425static struct multi_instance *
426multi_io_dispatch(struct multi_context *m, struct multi_instance *mi, const int action)
427{
428 const unsigned int mpp_flags = MPP_PRE_SELECT | MPP_RECORD_TOUCH;
429 struct multi_instance *touched = mi;
430 // cppcheck-suppress autoVariables ; yes, we know this is dangerous
431 m->mpp_touched = &touched;
432
433 dmsg(D_MULTI_DEBUG, "MULTI IO: multi_io_dispatch a=%s mi=" ptr_format, pract(action),
434 (ptr_type)mi);
435
436 switch (action)
437 {
438 case TA_TUN_READ:
440 if (!IS_SIG(&m->top))
441 {
442 multi_process_incoming_tun(m, mpp_flags);
443 }
444 break;
445
446 case TA_SOCKET_READ:
448 ASSERT(mi);
451 set_prefix(mi);
453 clear_prefix();
454 if (!IS_SIG(&mi->context))
455 {
456 multi_process_incoming_link(m, mi, mpp_flags, mi->context.c2.link_sockets[0]);
457 if (!IS_SIG(&mi->context))
458 {
460 }
461 }
462 break;
463
464 case TA_TIMEOUT:
465 multi_process_timeout(m, mpp_flags);
466 break;
467
468 case TA_TUN_WRITE:
469 multi_io_write_tun(m, mpp_flags);
470 break;
471
473 multi_io_drop_tun(m, mpp_flags);
474 break;
475
477 ASSERT(mi);
478 multi_io_write_link_deferred(m, mi, mpp_flags);
479 break;
480
481 case TA_SOCKET_WRITE:
482 multi_io_write_link(m, false, mpp_flags);
483 break;
484
486 multi_io_write_link(m, true, mpp_flags);
487 break;
488
489 case TA_INITIAL:
490 ASSERT(mi);
492 multi_process_post(m, mi, mpp_flags);
493 break;
494
495 default:
496 msg(M_FATAL, "MULTI IO: multi_io_dispatch, unhandled action=%d", action);
497 }
498
499 m->mpp_touched = NULL;
500 return touched;
501}
502
503static int
504multi_io_post(struct multi_context *m, struct multi_instance *mi, const int action)
505{
506 struct context *c = multi_get_context(m, mi);
507 int newaction = TA_UNDEF;
508
509#define MTP_NONE 0
510#define MTP_TUN_OUT (1 << 0)
511#define MTP_LINK_OUT (1 << 1)
512 unsigned int flags = MTP_NONE;
513
514 if (TUN_OUT(c))
515 {
516 flags |= MTP_TUN_OUT;
517 }
518 if (LINK_OUT(c))
519 {
520 flags |= MTP_LINK_OUT;
521 }
522
523 switch (flags)
524 {
526 case MTP_TUN_OUT:
527 newaction = TA_TUN_WRITE;
528 break;
529
530 case MTP_LINK_OUT:
531 newaction = TA_SOCKET_WRITE;
532 break;
533
534 case MTP_NONE:
535 if (mi && sockets_read_residual(c))
536 {
537 newaction = TA_SOCKET_READ_RESIDUAL;
538 }
539 else
540 {
542 }
543 break;
544
545 default:
546 {
547 struct gc_arena gc = gc_new();
548 msg(M_FATAL, "MULTI IO: multi_io_post bad state, mi=%s flags=%u",
549 multi_instance_string(mi, false, &gc), flags);
550 gc_free(&gc);
551 break;
552 }
553 }
554
555 dmsg(D_MULTI_DEBUG, "MULTI IO: multi_io_post %s -> %s", pract(action), pract(newaction));
556
557 return newaction;
558}
559
560void
562{
563 struct multi_io *multi_io = m->multi_io;
564 int i;
565
566 for (i = 0; i < multi_io->n_esr; ++i)
567 {
568 struct event_set_return *e = &multi_io->esr[i];
569 struct event_arg *ev_arg = (struct event_arg *)e->arg;
570
571 /* incoming data for instance or listening socket? */
572 if (e->arg >= MULTI_N)
573 {
574 switch (ev_arg->type)
575 {
576 struct multi_instance *mi;
577
578 /* react to event on child instance */
580 if (!ev_arg->u.mi)
581 {
582 msg(D_MULTI_ERRORS, "MULTI IO: multi_io_proc_io: null minstance");
583 break;
584 }
585
586 mi = ev_arg->u.mi;
587 if (e->rwflags & EVENT_WRITE)
588 {
590 }
591 else if (e->rwflags & EVENT_READ)
592 {
593 multi_io_action(m, mi, TA_SOCKET_READ, false);
594 }
595 break;
596
598 if (!ev_arg->u.sock)
599 {
600 msg(D_MULTI_ERRORS, "MULTI IO: multi_io_proc_io: null socket");
601 break;
602 }
603 /* new incoming TCP client attempting to connect? */
605 {
608 }
609 else
610 {
612 mi = m->pending;
613 }
614 /* monitor and/or handle events that are
615 * triggered in succession by the first one
616 * before returning to the main loop. */
617 if (mi)
618 {
619 multi_io_action(m, mi, TA_INITIAL, false);
620 }
621 break;
622 }
623 }
624 else
625 {
626#ifdef ENABLE_MANAGEMENT
627 if (e->arg == MULTI_IO_MANAGEMENT)
628 {
631 }
632 else
633#endif
634 /* incoming data on TUN? */
635 if (e->arg == MULTI_IO_TUN)
636 {
637 if (e->rwflags & EVENT_WRITE)
638 {
639 multi_io_action(m, NULL, TA_TUN_WRITE, false);
640 }
641 else if (e->rwflags & EVENT_READ)
642 {
643 multi_io_action(m, NULL, TA_TUN_READ, false);
644 }
645 }
646
647#if defined(ENABLE_DCO)
648 /* incoming data on DCO? */
649 else if (e->arg == MULTI_IO_DCO)
650 {
652 }
653#endif
654 /* signal received? */
655 else if (e->arg == MULTI_IO_SIG)
656 {
658 }
659#ifdef ENABLE_ASYNC_PUSH
660 else if (e->arg == MULTI_IO_FILE_CLOSE_WRITE)
661 {
662 multi_process_file_closed(m, MPP_PRE_SELECT | MPP_RECORD_TOUCH);
663 }
664#endif
665 }
666 if (IS_SIG(&m->top))
667 {
668 break;
669 }
670 }
671 multi_io->n_esr = 0;
672
673 /*
674 * Drain the queued mbuf packets, datagram and TCP instances alike
675 */
676 {
677 struct multi_instance *mi;
678 while (!IS_SIG(&m->top) && (mi = mbuf_peek(m->mbuf)) != NULL)
679 {
680 multi_io_action(m, mi, TA_SOCKET_WRITE, true);
681 }
682 }
683}
684
685void
686multi_io_action(struct multi_context *m, struct multi_instance *mi, int action, bool poll)
687{
688 bool tun_input_pending = false;
689
690 do
691 {
692 dmsg(D_MULTI_DEBUG, "MULTI IO: multi_io_action a=%s p=%d", pract(action), poll);
693
694 /*
695 * If TA_SOCKET_READ_RESIDUAL, it means we still have pending
696 * input packets which were read by a prior recv.
697 *
698 * Otherwise do a "lite" wait, which means we wait with 0 timeout
699 * on I/O events only related to the current instance, not
700 * the big list of events.
701 *
702 * On our first pass, poll will be false because we already know
703 * that input is available, and to call io_wait would be redundant.
704 */
705 if (poll && action != TA_SOCKET_READ_RESIDUAL)
706 {
707 const int orig_action = action;
708 action = multi_io_wait_lite(m, mi, action, &tun_input_pending);
709 if (action == TA_UNDEF)
710 {
711 msg(M_FATAL, "MULTI IO: I/O wait required blocking in multi_io_action, action=%d",
712 orig_action);
713 }
714 }
715
716 /*
717 * Dispatch the action
718 */
719 struct multi_instance *touched = multi_io_dispatch(m, mi, action);
720
721 /*
722 * Signal received or connection
723 * reset by peer?
724 */
725 if (touched && IS_SIG(&touched->context))
726 {
727 if (mi == touched)
728 {
729 mi = NULL;
730 }
732 }
733
734
735 /*
736 * If dispatch produced any pending output
737 * for a particular instance, point to
738 * that instance.
739 */
740 if (m->pending)
741 {
742 mi = m->pending;
743 }
744
745 /*
746 * Based on the effects of the action,
747 * such as generating pending output,
748 * possibly transition to a new action state.
749 */
750 action = multi_io_post(m, mi, action);
751
752 /*
753 * If we are finished processing the original action,
754 * check if we have any TUN input. If so, transition
755 * our action state to processing this input.
756 */
757 if (tun_input_pending && action == TA_UNDEF)
758 {
759 action = TA_TUN_READ;
760 mi = NULL;
761 tun_input_pending = false;
762 poll = false;
763 }
764 else
765 {
766 poll = true;
767 }
768
769 } while (action != TA_UNDEF);
770}
771
772void
774{
775 if (multi_io && multi_io->es)
776 {
777 event_del(multi_io->es, event);
778 }
779}
static void buf_reset(struct buffer *buf)
Reset a buffer to an undefined (unallocated) state.
Definition buffer.h:599
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:151
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1965
#define ALLOC_OBJ_CLEAR(dptr, type)
Allocate and zero-initialise memory for a single object of the given type.
Definition buffer.h:2027
#define ALLOC_ARRAY(dptr, type, n)
Allocate memory for an array of n elements of the given type.
Definition buffer.h:2043
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1949
unsigned long ptr_type
Definition common.h:59
#define ptr_format
Definition common.h:50
static void dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
Definition dco.h:316
static int dco_read_and_process(dco_context_t *dco)
Definition dco.h:309
#define D_MULTI_ERRORS
Definition errlevel.h:64
#define D_MULTI_DEBUG
Definition errlevel.h:126
#define D_MULTI_TCP
Definition errlevel.h:162
#define D_MULTI_LOW
Definition errlevel.h:85
struct event_set * event_set_init(int *maxevents, unsigned int flags)
Definition event.c:1187
#define TUN_WRITE
Definition event.h:64
static void event_free(struct event_set *es)
Definition event.h:159
static void event_del(struct event_set *es, event_t event)
Definition event.h:174
static int event_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
Definition event.h:186
#define SOCKET_WRITE
Definition event.h:61
#define EVENT_WRITE
Definition event.h:38
#define MULTI_N
Definition event.h:85
#define EVENT_READ
Definition event.h:37
#define TUN_READ
Definition event.h:63
static void wait_signal(struct event_set *es, void *arg)
Definition event.h:196
@ EVENT_ARG_LINK_SOCKET
Definition event.h:135
@ EVENT_ARG_MULTI_INSTANCE
Definition event.h:134
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition event.h:180
void io_wait(struct context *c, const unsigned int flags)
Definition forward.c:2153
void multi_io_process_flags(struct context *c, struct event_set *es, struct link_socket *sock, const unsigned int flags)
Processes I/O flags to configure socket and TUN/TAP event monitors.
Definition forward.c:2059
Interface functions to the internal and external multiplexers.
#define IOW_WAIT_SIGNAL
Definition forward.h:62
#define LINK_OUT(c)
Definition forward.h:38
#define TUN_OUT(c)
Definition forward.h:37
#define IOW_TO_TUN
Definition forward.h:54
#define IOW_READ_TUN_FORCE
Definition forward.h:61
#define IOW_READ
Definition forward.h:64
#define IOW_TO_LINK
Definition forward.h:55
bool multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags, struct link_socket *sock)
Demultiplex and process a packet received over the external network interface.
Definition multi.c:3564
void process_outgoing_link(struct context *c, struct link_socket *sock)
Write a packet to the external network interface.
Definition forward.c:1774
void read_incoming_link(struct context *c, struct link_socket *sock)
Read a packet from the external network interface.
Definition forward.c:954
void read_incoming_tun(struct context *c)
Read a packet from the virtual tun/tap network interface.
Definition forward.c:1326
void process_outgoing_tun(struct context *c, struct link_socket *in_sock)
Write a packet to the virtual tun/tap network interface.
Definition forward.c:1907
static bool multi_io_write_tun(struct multi_context *m, const unsigned int mpp_flags)
Send a packet over the virtual tun/tap network interface to its locally reachable destination.
Definition multi_io.c:289
bool multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags)
Determine the destination VPN tunnel of a packet received over the virtual tun/tap network interface ...
Definition multi.c:3627
#define BASE_N_EVENTS
Definition init.h:32
static SERVICE_STATUS status
Definition interactive.c:52
void management_socket_set(struct management *man, struct event_set *es, void *arg, unsigned int *persistent)
Definition manage.c:3309
void management_io(struct management *man)
Definition manage.c:3347
void mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
Definition mbuf.c:104
struct mbuf_buffer * mbuf_alloc_buf(const struct buffer *buf)
Definition mbuf.c:65
void mbuf_free_buf(struct mbuf_buffer *mb)
Definition mbuf.c:76
bool mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
Definition mbuf.c:126
static struct multi_instance * mbuf_peek(struct mbuf_set *ms)
Definition mbuf.h:101
static bool mbuf_defined(const struct mbuf_set *ms)
Definition mbuf.h:81
void multi_tcp_set_global_rw_flags(struct multi_context *m, struct multi_instance *mi)
Definition mtcp.c:119
struct multi_instance * multi_create_instance_tcp(struct multi_context *m, struct link_socket *sock)
Definition mtcp.c:41
void multi_process_io_udp(struct multi_context *m, struct link_socket *sock, unsigned int rwflags)
Definition mudp.c:482
void multi_close_instance_on_signal(struct multi_context *m, struct multi_instance *mi)
Definition multi.c:3286
bool multi_process_post(struct multi_context *m, struct multi_instance *mi, const unsigned int flags)
Perform postprocessing of a VPN tunnel instance.
Definition multi.c:3045
struct multi_instance * multi_get_queue(struct mbuf_set *ms)
Definition multi.c:3718
bool multi_process_timeout(struct multi_context *m, const unsigned int mpp_flags)
Definition multi.c:3754
const char * multi_instance_string(const struct multi_instance *mi, bool null, struct gc_arena *gc)
Definition multi.c:426
Header file for server-mode related structures and functions.
static void clear_prefix(void)
Definition multi.h:523
static void set_prefix(const struct multi_instance *mi)
Definition multi.h:511
#define MPP_RECORD_TOUCH
Definition multi.h:288
#define MPP_PRE_SELECT
Definition multi.h:286
struct multi_io * multi_io_init(const int maxclients)
Definition multi_io.c:108
#define MULTI_IO_SIG
Definition multi_io.c:44
void multi_io_process_io(struct multi_context *m)
Definition multi_io.c:561
static int multi_io_wait_lite(struct multi_context *m, struct multi_instance *mi, const int action, bool *tun_input_pending)
Definition multi_io.c:215
bool multi_io_send_link(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
Definition multi_io.c:349
#define MULTI_IO_TUN
Definition multi_io.c:43
void multi_io_free(struct multi_io *multi_io)
Definition multi_io.c:125
#define MTP_NONE
static unsigned int p2mp_iow_flags(const struct multi_context *m, const struct link_socket *sock)
Definition multi_io.c:140
#define MTP_TUN_OUT
#define MULTI_IO_DCO
Definition multi_io.c:47
#define MTP_LINK_OUT
static struct multi_instance * multi_io_write_link_pre(struct multi_context *m)
Definition multi_io.c:333
int multi_io_wait(struct multi_context *m)
Definition multi_io.c:166
#define MULTI_IO_FILE_CLOSE_WRITE
Definition multi_io.c:46
static struct multi_instance * multi_io_dispatch(struct multi_context *m, struct multi_instance *mi, const int action)
Definition multi_io.c:426
static bool multi_io_write_link(struct multi_context *m, bool defer, const unsigned int mpp_flags)
Definition multi_io.c:381
static bool multi_io_write_link_deferred(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
Definition multi_io.c:360
static const char * pract(int action)
Definition multi_io.c:51
static void multi_io_drop_tun(struct multi_context *m, const unsigned int mpp_flags)
Definition multi_io.c:310
void multi_io_delete_event(struct multi_io *multi_io, event_t event)
Definition multi_io.c:773
static struct context * multi_get_context(struct multi_context *m, struct multi_instance *mi)
Definition multi_io.c:95
static int multi_io_post(struct multi_context *m, struct multi_instance *mi, const int action)
Definition multi_io.c:504
void multi_io_action(struct multi_context *m, struct multi_instance *mi, int action, bool poll)
Definition multi_io.c:686
#define MULTI_IO_MANAGEMENT
Definition multi_io.c:45
#define TA_UNDEF
Definition multi_io.h:36
#define TA_SOCKET_WRITE_READY
Definition multi_io.h:40
#define TA_SOCKET_READ_RESIDUAL
Definition multi_io.h:38
#define TA_SOCKET_READ
Definition multi_io.h:37
#define TA_INITIAL
Definition multi_io.h:44
#define TA_TUN_WRITE
Definition multi_io.h:43
#define TA_TIMEOUT
Definition multi_io.h:45
#define TA_SOCKET_WRITE_DEFERRED
Definition multi_io.h:41
#define TA_TUN_WRITE_TIMEOUT
Definition multi_io.h:46
#define TA_TUN_READ
Definition multi_io.h:42
#define TA_SOCKET_WRITE
Definition multi_io.h:39
#define M_FATAL
Definition error.h:90
#define dmsg(flags,...)
Definition error.h:164
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:221
static void update_time(void)
Definition otime.h:84
static void tv_clear(struct timeval *tv)
Definition otime.h:97
#define IS_SIG(c)
Definition sig.h:47
static void get_signal(volatile int *sig)
Copy the global signal_received (if non-zero) to the passed-in argument sig.
Definition sig.h:109
bool sockets_read_residual(const struct context *c)
Definition socket.c:46
static void socket_set_listen_persistent(struct link_socket *sock, struct event_set *es, void *arg)
Definition socket.h:812
static bool stream_buf_read_setup(struct link_socket *sock)
Definition socket.h:563
static void socket_reset_listen_persistent(struct link_socket *sock)
Definition socket.h:822
static bool proto_is_dgram(int proto)
Return if the protocol is datagram (UDP)
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
int link_sockets_num
Definition openvpn.h:159
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition openvpn.h:173
unsigned int event_set_status
Definition openvpn.h:236
struct buffer to_link
Definition openvpn.h:377
struct buffer to_tun
Definition openvpn.h:376
struct link_socket ** link_sockets
Definition openvpn.h:238
struct timeval timeval
Time to next event of timers and similar.
Definition openvpn.h:396
Contains all state information for one tunnel.
Definition openvpn.h:471
struct signal_info * sig
Internal error signaling object.
Definition openvpn.h:500
struct context_2 c2
Level 2 context.
Definition openvpn.h:516
struct context_1 c1
Level 1 context.
Definition openvpn.h:515
struct link_socket * sock
Definition event.h:145
struct multi_instance * mi
Definition event.h:144
union event_arg::@1 u
event_arg_t type
Definition event.h:141
unsigned int rwflags
Definition event.h:123
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
struct buffer buf
Definition mbuf.h:44
struct mbuf_buffer * buffer
Definition mbuf.h:53
struct multi_instance * instance
Definition mbuf.h:54
Main OpenVPN server state structure.
Definition multi.h:170
struct mbuf_set * mbuf
Set of buffers for passing data channel packets between VPN tunnel instances.
Definition multi.h:190
struct multi_io * multi_io
I/O state and events tracker.
Definition multi.h:193
struct context top
Storage structure for process-wide configuration.
Definition multi.h:217
struct multi_instance * pending
Definition multi.h:211
struct multi_instance ** mpp_touched
Definition multi.h:213
Server-mode state structure for one single VPN tunnel.
Definition multi.h:102
struct mbuf_set * tcp_link_out_deferred
Definition multi.h:128
struct event_arg ev_arg
this struct will store a pointer to either mi or link_socket, depending on the event type,...
Definition multi.h:107
struct context context
The context structure storing state for this VPN tunnel.
Definition multi.h:150
struct event_set * es
Definition multi_io.h:53
int n_esr
Definition multi_io.h:55
struct event_set_return * esr
Definition multi_io.h:54
unsigned int tun_rwflags
Definition multi_io.h:57
int maxevents
Definition multi_io.h:56
unsigned int management_persist_flags
Definition multi_io.h:59
volatile int signal_received
Definition sig.h:42
dco_context_t dco
Definition tun.h:247
struct gc_arena gc
Definition test_ssl.c:138
static void tun_set(struct tuntap *tt, struct event_set *es, unsigned int rwflags, void *arg, unsigned int *persistent)
Definition tun.h:601
static bool tuntap_is_dco_win(const struct tuntap *tt)
Definition tun.h:532
void vlan_process_outgoing_tun(const struct multi_context *m, struct multi_instance *mi)
Definition vlan.c:291