OpenVPN
mtcp.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-2017 OpenVPN Technologies, 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 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #if P2MP_SERVER
33 
34 #include "multi.h"
35 #include "forward-inline.h"
36 
37 #include "memdbg.h"
38 
39 #ifdef HAVE_SYS_INOTIFY_H
40 #include <sys/inotify.h>
41 #endif
42 
43 /*
44  * TCP States
45  */
46 #define TA_UNDEF 0
47 #define TA_SOCKET_READ 1
48 #define TA_SOCKET_READ_RESIDUAL 2
49 #define TA_SOCKET_WRITE 3
50 #define TA_SOCKET_WRITE_READY 4
51 #define TA_SOCKET_WRITE_DEFERRED 5
52 #define TA_TUN_READ 6
53 #define TA_TUN_WRITE 7
54 #define TA_INITIAL 8
55 #define TA_TIMEOUT 9
56 #define TA_TUN_WRITE_TIMEOUT 10
57 
58 /*
59  * Special tags passed to event.[ch] functions
60  */
61 #define MTCP_SOCKET ((void *)1)
62 #define MTCP_TUN ((void *)2)
63 #define MTCP_SIG ((void *)3) /* Only on Windows */
64 #ifdef ENABLE_MANAGEMENT
65 #define MTCP_MANAGEMENT ((void *)4)
66 #endif
67 
68 #ifdef ENABLE_ASYNC_PUSH
69 #define MTCP_FILE_CLOSE_WRITE ((void *)5)
70 #endif
71 
72 #define MTCP_N ((void *)16) /* upper bound on MTCP_x */
73 
75 {
76  unsigned int flags;
77  unsigned int ret;
78  unsigned int tun;
79  unsigned int sock;
80 };
81 
82 static const char *
83 pract(int action)
84 {
85  switch (action)
86  {
87  case TA_UNDEF:
88  return "TA_UNDEF";
89 
90  case TA_SOCKET_READ:
91  return "TA_SOCKET_READ";
92 
94  return "TA_SOCKET_READ_RESIDUAL";
95 
96  case TA_SOCKET_WRITE:
97  return "TA_SOCKET_WRITE";
98 
100  return "TA_SOCKET_WRITE_READY";
101 
103  return "TA_SOCKET_WRITE_DEFERRED";
104 
105  case TA_TUN_READ:
106  return "TA_TUN_READ";
107 
108  case TA_TUN_WRITE:
109  return "TA_TUN_WRITE";
110 
111  case TA_INITIAL:
112  return "TA_INITIAL";
113 
114  case TA_TIMEOUT:
115  return "TA_TIMEOUT";
116 
118  return "TA_TUN_WRITE_TIMEOUT";
119 
120  default:
121  return "?";
122  }
123 }
124 
125 static struct multi_instance *
127 {
128  struct gc_arena gc = gc_new();
129  struct multi_instance *mi = NULL;
130  struct hash *hash = m->hash;
131 
132  mi = multi_create_instance(m, NULL);
133  if (mi)
134  {
135  struct hash_element *he;
136  const uint32_t hv = hash_value(hash, &mi->real);
137  struct hash_bucket *bucket = hash_bucket(hash, hv);
138 
139  he = hash_lookup_fast(hash, bucket, &mi->real, hv);
140 
141  if (he)
142  {
143  struct multi_instance *oldmi = (struct multi_instance *) he->value;
144  msg(D_MULTI_LOW, "MULTI TCP: new incoming client address matches existing client address -- new client takes precedence");
145  oldmi->did_real_hash = false;
146  multi_close_instance(m, oldmi, false);
147  he->key = &mi->real;
148  he->value = mi;
149  }
150  else
151  {
152  hash_add_fast(hash, bucket, &mi->real, hv, mi);
153  }
154 
155  mi->did_real_hash = true;
156  }
157 
158 #ifdef ENABLE_DEBUG
159  if (mi)
160  {
161  dmsg(D_MULTI_DEBUG, "MULTI TCP: instance added: %s", mroute_addr_print(&mi->real, &gc));
162  }
163  else
164  {
165  dmsg(D_MULTI_DEBUG, "MULTI TCP: new client instance failed");
166  }
167 #endif
168 
169  gc_free(&gc);
170  ASSERT(!(mi && mi->halt));
171  return mi;
172 }
173 
174 bool
176 {
177  /* buffer for queued TCP socket output packets */
179 
183  ASSERT(mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET
184  || mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6
185  );
187  {
188  msg(D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined");
189  return false;
190  }
191  return true;
192 }
193 
194 void
196 {
198 }
199 
200 struct multi_tcp *
201 multi_tcp_init(int maxevents, int *maxclients)
202 {
203  struct multi_tcp *mtcp;
204  const int extra_events = BASE_N_EVENTS;
205 
206  ASSERT(maxevents >= 1);
207  ASSERT(maxclients);
208 
209  ALLOC_OBJ_CLEAR(mtcp, struct multi_tcp);
210  mtcp->maxevents = maxevents + extra_events;
211  mtcp->es = event_set_init(&mtcp->maxevents, 0);
212  wait_signal(mtcp->es, MTCP_SIG);
213  ALLOC_ARRAY(mtcp->esr, struct event_set_return, mtcp->maxevents);
214  *maxclients = max_int(min_int(mtcp->maxevents - extra_events, *maxclients), 1);
215  msg(D_MULTI_LOW, "MULTI: TCP INIT maxclients=%d maxevents=%d", *maxclients, mtcp->maxevents);
216  return mtcp;
217 }
218 
219 void
221 {
222  if (mtcp && mtcp->es)
223  {
224  event_del(mtcp->es, event);
225  }
226 }
227 
228 void
230 {
231  if (mtcp)
232  {
233  event_free(mtcp->es);
234  if (mtcp->esr)
235  {
236  free(mtcp->esr);
237  }
238  free(mtcp);
239  }
240 }
241 
242 void
244 {
245  struct link_socket *ls = mi->context.c2.link_socket;
246  if (ls && mi->socket_set_called)
247  {
248  event_del(mtcp->es, socket_event_handle(ls));
249  }
250  mtcp->n_esr = 0;
251 }
252 
253 static inline void
255 {
256  if (mi)
257  {
258  mi->socket_set_called = true;
260  m->mtcp->es,
262  mi,
263  &mi->tcp_rwflags);
264  }
265 }
266 
267 static inline int
268 multi_tcp_wait(const struct context *c,
269  struct multi_tcp *mtcp)
270 {
271  int status;
273  tun_set(c->c1.tuntap, mtcp->es, EVENT_READ, MTCP_TUN, &mtcp->tun_rwflags);
274 #ifdef ENABLE_MANAGEMENT
275  if (management)
276  {
278  }
279 #endif
280 
281 #ifdef ENABLE_ASYNC_PUSH
282  /* arm inotify watcher */
283  event_ctl(mtcp->es, c->c2.inotify_fd, EVENT_READ, MTCP_FILE_CLOSE_WRITE);
284 #endif
285 
286  status = event_wait(mtcp->es, &c->c2.timeval, mtcp->esr, mtcp->maxevents);
287  update_time();
288  mtcp->n_esr = 0;
289  if (status > 0)
290  {
291  mtcp->n_esr = status;
292  }
293  return status;
294 }
295 
296 static inline struct context *
298 {
299  if (mi)
300  {
301  return &mi->context;
302  }
303  else
304  {
305  return &m->top;
306  }
307 }
308 
309 static bool
310 multi_tcp_process_outgoing_link_ready(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
311 {
312  struct mbuf_item item;
313  bool ret = true;
314  ASSERT(mi);
315 
316  /* extract from queue */
317  if (mbuf_extract_item(mi->tcp_link_out_deferred, &item)) /* ciphertext IP packet */
318  {
319  dmsg(D_MULTI_TCP, "MULTI TCP: transmitting previously deferred packet");
320 
321  ASSERT(mi == item.instance);
322  mi->context.c2.to_link = item.buffer->buf;
323  ret = multi_process_outgoing_link_dowork(m, mi, mpp_flags);
324  if (!ret)
325  {
326  mi = NULL;
327  }
328  mbuf_free_buf(item.buffer);
329  }
330  return ret;
331 }
332 
333 static bool
334 multi_tcp_process_outgoing_link(struct multi_context *m, bool defer, const unsigned int mpp_flags)
335 {
337  bool ret = true;
338 
339  if (mi)
340  {
341  if (defer || mbuf_defined(mi->tcp_link_out_deferred))
342  {
343  /* save to queue */
344  struct buffer *buf = &mi->context.c2.to_link;
345  if (BLEN(buf) > 0)
346  {
347  struct mbuf_buffer *mb = mbuf_alloc_buf(buf);
348  struct mbuf_item item;
349 
350  set_prefix(mi);
351  dmsg(D_MULTI_TCP, "MULTI TCP: queuing deferred packet");
352  item.buffer = mb;
353  item.instance = mi;
355  mbuf_free_buf(mb);
356  buf_reset(buf);
357  ret = multi_process_post(m, mi, mpp_flags);
358  if (!ret)
359  {
360  mi = NULL;
361  }
362  clear_prefix();
363  }
364  }
365  else
366  {
367  ret = multi_process_outgoing_link_dowork(m, mi, mpp_flags);
368  if (!ret)
369  {
370  mi = NULL;
371  }
372  }
373  }
374  return ret;
375 }
376 
377 static int
378 multi_tcp_wait_lite(struct multi_context *m, struct multi_instance *mi, const int action, bool *tun_input_pending)
379 {
380  struct context *c = multi_tcp_context(m, mi);
381  unsigned int looking_for = 0;
382 
383  dmsg(D_MULTI_DEBUG, "MULTI TCP: multi_tcp_wait_lite a=%s mi=" ptr_format,
384  pract(action),
385  (ptr_type)mi);
386 
387  tv_clear(&c->c2.timeval); /* ZERO-TIMEOUT */
388 
389  switch (action)
390  {
391  case TA_TUN_READ:
392  looking_for = TUN_READ;
393  tun_input_pending = NULL;
394  io_wait(c, IOW_READ_TUN);
395  break;
396 
397  case TA_SOCKET_READ:
398  looking_for = SOCKET_READ;
399  tun_input_pending = NULL;
401  break;
402 
403  case TA_TUN_WRITE:
404  looking_for = TUN_WRITE;
405  tun_input_pending = NULL;
406  c->c2.timeval.tv_sec = 1; /* For some reason, the Linux 2.2 TUN/TAP driver hits this timeout */
408  io_wait(c, IOW_TO_TUN);
409  perf_pop();
410  break;
411 
412  case TA_SOCKET_WRITE:
413  looking_for = SOCKET_WRITE;
415  break;
416 
417  default:
418  msg(M_FATAL, "MULTI TCP: multi_tcp_wait_lite, unhandled action=%d", action);
419  }
420 
421  if (tun_input_pending && (c->c2.event_set_status & TUN_READ))
422  {
423  *tun_input_pending = true;
424  }
425 
426  if (c->c2.event_set_status & looking_for)
427  {
428  return action;
429  }
430  else
431  {
432  switch (action)
433  {
434  /* TCP socket output buffer is full */
435  case TA_SOCKET_WRITE:
437 
438  /* TUN device timed out on accepting write */
439  case TA_TUN_WRITE:
440  return TA_TUN_WRITE_TIMEOUT;
441  }
442 
443  return TA_UNDEF;
444  }
445 }
446 
447 static struct multi_instance *
448 multi_tcp_dispatch(struct multi_context *m, struct multi_instance *mi, const int action)
449 {
450  const unsigned int mpp_flags = MPP_PRE_SELECT|MPP_RECORD_TOUCH;
451  struct multi_instance *touched = mi;
452  m->mpp_touched = &touched;
453 
454  dmsg(D_MULTI_DEBUG, "MULTI TCP: multi_tcp_dispatch a=%s mi=" ptr_format,
455  pract(action),
456  (ptr_type)mi);
457 
458  switch (action)
459  {
460  case TA_TUN_READ:
461  read_incoming_tun(&m->top);
462  if (!IS_SIG(&m->top))
463  {
464  multi_process_incoming_tun(m, mpp_flags);
465  }
466  break;
467 
468  case TA_SOCKET_READ:
470  ASSERT(mi);
471  ASSERT(mi->context.c2.link_socket);
472  set_prefix(mi);
473  read_incoming_link(&mi->context);
474  clear_prefix();
475  if (!IS_SIG(&mi->context))
476  {
477  multi_process_incoming_link(m, mi, mpp_flags);
478  if (!IS_SIG(&mi->context))
479  {
480  stream_buf_read_setup(mi->context.c2.link_socket);
481  }
482  }
483  break;
484 
485  case TA_TIMEOUT:
486  multi_process_timeout(m, mpp_flags);
487  break;
488 
489  case TA_TUN_WRITE:
490  multi_process_outgoing_tun(m, mpp_flags);
491  break;
492 
494  multi_process_drop_outgoing_tun(m, mpp_flags);
495  break;
496 
498  ASSERT(mi);
499  multi_tcp_process_outgoing_link_ready(m, mi, mpp_flags);
500  break;
501 
502  case TA_SOCKET_WRITE:
503  multi_tcp_process_outgoing_link(m, false, mpp_flags);
504  break;
505 
507  multi_tcp_process_outgoing_link(m, true, mpp_flags);
508  break;
509 
510  case TA_INITIAL:
511  ASSERT(mi);
513  multi_process_post(m, mi, mpp_flags);
514  break;
515 
516  default:
517  msg(M_FATAL, "MULTI TCP: multi_tcp_dispatch, unhandled action=%d", action);
518  }
519 
520  m->mpp_touched = NULL;
521  return touched;
522 }
523 
524 static int
525 multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int action)
526 {
527  struct context *c = multi_tcp_context(m, mi);
528  int newaction = TA_UNDEF;
529 
530 #define MTP_NONE 0
531 #define MTP_TUN_OUT (1<<0)
532 #define MTP_LINK_OUT (1<<1)
533  unsigned int flags = MTP_NONE;
534 
535  if (TUN_OUT(c))
536  {
537  flags |= MTP_TUN_OUT;
538  }
539  if (LINK_OUT(c))
540  {
541  flags |= MTP_LINK_OUT;
542  }
543 
544  switch (flags)
545  {
547  case MTP_TUN_OUT:
548  newaction = TA_TUN_WRITE;
549  break;
550 
551  case MTP_LINK_OUT:
552  newaction = TA_SOCKET_WRITE;
553  break;
554 
555  case MTP_NONE:
556  if (mi && socket_read_residual(c->c2.link_socket))
557  {
558  newaction = TA_SOCKET_READ_RESIDUAL;
559  }
560  else
561  {
563  }
564  break;
565 
566  default:
567  {
568  struct gc_arena gc = gc_new();
569  msg(M_FATAL, "MULTI TCP: multi_tcp_post bad state, mi=%s flags=%d",
570  multi_instance_string(mi, false, &gc),
571  flags);
572  gc_free(&gc);
573  break;
574  }
575  }
576 
577  dmsg(D_MULTI_DEBUG, "MULTI TCP: multi_tcp_post %s -> %s",
578  pract(action),
579  pract(newaction));
580 
581  return newaction;
582 }
583 
584 static void
585 multi_tcp_action(struct multi_context *m, struct multi_instance *mi, int action, bool poll)
586 {
587  bool tun_input_pending = false;
588 
589  do
590  {
591  dmsg(D_MULTI_DEBUG, "MULTI TCP: multi_tcp_action a=%s p=%d",
592  pract(action),
593  poll);
594 
595  /*
596  * If TA_SOCKET_READ_RESIDUAL, it means we still have pending
597  * input packets which were read by a prior TCP recv.
598  *
599  * Otherwise do a "lite" wait, which means we wait with 0 timeout
600  * on I/O events only related to the current instance, not
601  * the big list of events.
602  *
603  * On our first pass, poll will be false because we already know
604  * that input is available, and to call io_wait would be redundant.
605  */
606  if (poll && action != TA_SOCKET_READ_RESIDUAL)
607  {
608  const int orig_action = action;
609  action = multi_tcp_wait_lite(m, mi, action, &tun_input_pending);
610  if (action == TA_UNDEF)
611  {
612  msg(M_FATAL, "MULTI TCP: I/O wait required blocking in multi_tcp_action, action=%d", orig_action);
613  }
614  }
615 
616  /*
617  * Dispatch the action
618  */
619  {
620  struct multi_instance *touched = multi_tcp_dispatch(m, mi, action);
621 
622  /*
623  * Signal received or TCP connection
624  * reset by peer?
625  */
626  if (touched && IS_SIG(&touched->context))
627  {
628  if (mi == touched)
629  {
630  mi = NULL;
631  }
632  multi_close_instance_on_signal(m, touched);
633  }
634  }
635 
636  /*
637  * If dispatch produced any pending output
638  * for a particular instance, point to
639  * that instance.
640  */
641  if (m->pending)
642  {
643  mi = m->pending;
644  }
645 
646  /*
647  * Based on the effects of the action,
648  * such as generating pending output,
649  * possibly transition to a new action state.
650  */
651  action = multi_tcp_post(m, mi, action);
652 
653  /*
654  * If we are finished processing the original action,
655  * check if we have any TUN input. If so, transition
656  * our action state to processing this input.
657  */
658  if (tun_input_pending && action == TA_UNDEF)
659  {
660  action = TA_TUN_READ;
661  mi = NULL;
662  tun_input_pending = false;
663  poll = false;
664  }
665  else
666  {
667  poll = true;
668  }
669 
670  } while (action != TA_UNDEF);
671 }
672 
673 static void
675 {
676  struct multi_tcp *mtcp = m->mtcp;
677  int i;
678 
679  for (i = 0; i < mtcp->n_esr; ++i)
680  {
681  struct event_set_return *e = &mtcp->esr[i];
682 
683  /* incoming data for instance? */
684  if (e->arg >= MTCP_N)
685  {
686  struct multi_instance *mi = (struct multi_instance *) e->arg;
687  if (mi)
688  {
689  if (e->rwflags & EVENT_WRITE)
690  {
692  }
693  else if (e->rwflags & EVENT_READ)
694  {
695  multi_tcp_action(m, mi, TA_SOCKET_READ, false);
696  }
697  }
698  }
699  else
700  {
701 #ifdef ENABLE_MANAGEMENT
702  if (e->arg == MTCP_MANAGEMENT)
703  {
706  }
707  else
708 #endif
709  /* incoming data on TUN? */
710  if (e->arg == MTCP_TUN)
711  {
712  if (e->rwflags & EVENT_WRITE)
713  {
714  multi_tcp_action(m, NULL, TA_TUN_WRITE, false);
715  }
716  else if (e->rwflags & EVENT_READ)
717  {
718  multi_tcp_action(m, NULL, TA_TUN_READ, false);
719  }
720  }
721  /* new incoming TCP client attempting to connect? */
722  else if (e->arg == MTCP_SOCKET)
723  {
724  struct multi_instance *mi;
725  ASSERT(m->top.c2.link_socket);
728  if (mi)
729  {
730  multi_tcp_action(m, mi, TA_INITIAL, false);
731  }
732  }
733  /* signal received? */
734  else if (e->arg == MTCP_SIG)
735  {
737  }
738 #ifdef ENABLE_ASYNC_PUSH
739  else if (e->arg == MTCP_FILE_CLOSE_WRITE)
740  {
741  multi_process_file_closed(m, MPP_PRE_SELECT | MPP_RECORD_TOUCH);
742  }
743 #endif
744  }
745  if (IS_SIG(&m->top))
746  {
747  break;
748  }
749  }
750  mtcp->n_esr = 0;
751 
752  /*
753  * Process queued mbuf packets destined for TCP socket
754  */
755  {
756  struct multi_instance *mi;
757  while (!IS_SIG(&m->top) && (mi = mbuf_peek(m->mbuf)) != NULL)
758  {
759  multi_tcp_action(m, mi, TA_SOCKET_WRITE, true);
760  }
761  }
762 }
763 
764 /*
765  * Top level event loop for single-threaded operation.
766  * TCP mode.
767  */
768 void
770 {
771  struct multi_context multi;
772  int status;
773 
774  top->mode = CM_TOP;
775  context_clear_2(top);
776 
777  /* initialize top-tunnel instance */
779  if (IS_SIG(top))
780  {
781  return;
782  }
783 
784  /* initialize global multi_context object */
785  multi_init(&multi, top, true, MC_SINGLE_THREADED);
786 
787  /* initialize our cloned top object */
788  multi_top_init(&multi, top);
789 
790  /* initialize management interface */
792 
793  /* finished with initialization */
794  initialization_sequence_completed(top, ISC_SERVER); /* --mode server --proto tcp-server */
795 
796 #ifdef ENABLE_ASYNC_PUSH
797  multi.top.c2.inotify_fd = inotify_init();
798  if (multi.top.c2.inotify_fd < 0)
799  {
800  msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error");
801  }
802 #endif
803 
804  /* per-packet event loop */
805  while (true)
806  {
808 
809  /* wait on tun/socket list */
810  multi_get_timeout(&multi, &multi.top.c2.timeval);
811  status = multi_tcp_wait(&multi.top, multi.mtcp);
812  MULTI_CHECK_SIG(&multi);
813 
814  /* check on status of coarse timers */
816 
817  /* timeout? */
818  if (status > 0)
819  {
820  /* process the I/O which triggered select */
821  multi_tcp_process_io(&multi);
822  MULTI_CHECK_SIG(&multi);
823  }
824  else if (status == 0)
825  {
826  multi_tcp_action(&multi, NULL, TA_TIMEOUT, false);
827  }
828 
829  perf_pop();
830  }
831 
832 #ifdef ENABLE_ASYNC_PUSH
833  close(top->c2.inotify_fd);
834 #endif
835 
836  /* shut down management interface */
838 
839  /* save ifconfig-pool */
840  multi_ifconfig_pool_persist(&multi, true);
841 
842  /* tear down tunnel instance (unless --persist-tun) */
843  multi_uninit(&multi);
844  multi_top_free(&multi);
845  close_instance(top);
846 }
847 
848 #endif /* if P2MP_SERVER */
struct multi_instance ** mpp_touched
Definition: multi.h:174
static struct multi_instance * mbuf_peek(struct mbuf_set *ms)
Definition: mbuf.h:100
struct buffer to_link
Definition: openvpn.h:392
void multi_process_drop_outgoing_tun(struct multi_context *m, const unsigned int mpp_flags)
Definition: multi.c:2902
#define MTCP_SOCKET
Definition: mtcp.c:61
union openvpn_sockaddr::@6 addr
bool socket_set_called
Definition: multi.h:96
#define TA_SOCKET_READ
Definition: mtcp.c:47
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:510
#define TUN_OUT(c)
Definition: forward.h:38
#define BASE_N_EVENTS
Definition: init.h:33
int maxevents
Definition: mtcp.h:43
#define D_MULTI_ERRORS
Definition: errlevel.h:65
unsigned int sock
Definition: mtcp.c:79
#define PERF_EVENT_LOOP
Definition: perf.h:44
static void hash_add_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv, void *value)
Definition: list.h:171
Contains all state information for one tunnel.
Definition: openvpn.h:508
#define TA_SOCKET_WRITE
Definition: mtcp.c:49
void multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode)
Definition: multi.c:293
struct env_set * es
Set of environment variables.
Definition: openvpn.h:531
unsigned long ptr_type
Definition: common.h:67
struct event_set_return * esr
Definition: mtcp.h:41
static void gc_free(struct gc_arena *a)
Definition: buffer.h:990
#define IOW_READ_LINK
Definition: forward.h:53
static struct multi_instance * multi_process_outgoing_link_pre(struct multi_context *m)
Definition: multi.h:387
void close_instance(struct context *c)
Definition: init.c:4265
#define ASSERT(x)
Definition: error.h:221
const void * key
Definition: list.h:50
void multi_top_free(struct multi_context *m)
Definition: multi.c:3018
void multi_tcp_instance_specific_free(struct multi_instance *mi)
Definition: mtcp.c:195
void mbuf_free(struct mbuf_set *ms)
Definition: mbuf.c:53
static void perf_pop(void)
Definition: perf.h:82
#define PERF_PROC_OUT_TUN_MTCP
Definition: perf.h:57
#define M_FATAL
Definition: error.h:94
static void perf_push(int type)
Definition: perf.h:78
static bool multi_tcp_process_outgoing_link_ready(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
Definition: mtcp.c:310
#define MTCP_MANAGEMENT
Definition: mtcp.c:65
#define TUN_READ
Definition: openvpn.h:242
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:533
#define TA_TUN_READ
Definition: mtcp.c:52
#define SOCKET_READ
Definition: openvpn.h:240
static void get_signal(volatile int *sig)
Definition: sig.h:92
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition: openvpn.h:171
#define ALLOC_ARRAY(dptr, type, n)
Definition: buffer.h:1023
static int event_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
Definition: event.h:125
#define IOW_TO_LINK
Definition: forward.h:51
void read_incoming_link(struct context *c)
Read a packet from the external network interface.
Definition: forward.c:715
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:2719
void * arg
Definition: event.h:80
static unsigned int tun_set(struct tuntap *tt, struct event_set *es, unsigned int rwflags, void *arg, unsigned int *persistent)
Definition: tun.h:508
static void tv_clear(struct timeval *tv)
Definition: otime.h:134
static void clear_prefix(void)
Definition: multi.h:511
bool did_real_hash
Definition: multi.h:102
struct mbuf_set * tcp_link_out_deferred
Definition: multi.h:95
static event_t socket_event_handle(const struct link_socket *s)
Definition: socket.h:1228
void multi_tcp_delete_event(struct multi_tcp *mtcp, event_t event)
Definition: mtcp.c:220
void multi_close_instance(struct multi_context *m, struct multi_instance *mi, bool shutdown)
Definition: multi.c:610
#define TA_TUN_WRITE
Definition: mtcp.c:53
struct event_set * event_set_init(int *maxevents, unsigned int flags)
Definition: event.c:1180
static bool multi_tcp_process_outgoing_link(struct multi_context *m, bool defer, const unsigned int mpp_flags)
Definition: mtcp.c:334
void init_instance_handle_signals(struct context *c, const struct env_set *env, const unsigned int flags)
Definition: init.c:3927
static bool multi_process_outgoing_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.h:614
void multi_uninit(struct multi_context *m)
Definition: multi.c:713
#define LS_MODE_TCP_ACCEPT_FROM
Definition: socket.h:198
void mbuf_free_buf(struct mbuf_buffer *mb)
Definition: mbuf.c:80
struct context_1 c1
Level 1 context.
Definition: openvpn.h:546
#define IOW_TO_TUN
Definition: forward.h:50
#define TA_TUN_WRITE_TIMEOUT
Definition: mtcp.c:56
void multi_top_init(struct multi_context *m, const struct context *top)
Definition: multi.c:3011
#define TA_UNDEF
Definition: mtcp.c:46
static int multi_tcp_wait_lite(struct multi_context *m, struct multi_instance *mi, const int action, bool *tun_input_pending)
Definition: mtcp.c:378
void init_management_callback_multi(struct multi_context *m)
Definition: multi.c:3332
unsigned int tun
Definition: mtcp.c:78
void multi_ifconfig_pool_persist(struct multi_context *m, bool force)
Definition: multi.c:164
#define IOW_READ_TUN_FORCE
Definition: forward.h:58
const char * mroute_addr_print(const struct mroute_addr *ma, struct gc_arena *gc)
Definition: mroute.c:400
static bool multi_process_outgoing_link_dowork(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
Definition: multi.h:635
static struct gc_arena gc_new(void)
Definition: buffer.h:982
static struct multi_instance * multi_tcp_dispatch(struct multi_context *m, struct multi_instance *mi, const int action)
Definition: mtcp.c:448
static void event_del(struct event_set *es, event_t event)
Definition: event.h:113
static void set_prefix(struct multi_instance *mi)
Definition: multi.h:499
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1017
Definition: mbuf.h:52
void management_socket_set(struct management *man, struct event_set *es, void *arg, unsigned int *persistent)
Definition: manage.c:3022
#define MPP_PRE_SELECT
Definition: multi.h:256
struct multi_instance * multi_create_instance(struct multi_context *m, const struct mroute_addr *real)
Definition: multi.c:769
void multi_tcp_dereference_instance(struct multi_tcp *mtcp, struct multi_instance *mi)
Definition: mtcp.c:243
bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port)
Definition: mroute.c:288
struct timeval timeval
Definition: openvpn.h:409
unsigned int flags
Definition: mtcp.c:76
void multi_close_instance_on_signal(struct multi_context *m, struct multi_instance *mi)
Definition: multi.c:3097
struct multi_tcp * multi_tcp_init(int maxevents, int *maxclients)
Definition: mtcp.c:201
#define D_MULTI_DEBUG
Definition: errlevel.h:123
#define MTCP_N
Definition: mtcp.c:72
unsigned int tun_rwflags
Definition: mtcp.h:44
#define TA_TIMEOUT
Definition: mtcp.c:55
unsigned __int32 uint32_t
Definition: config-msvc.h:121
static void multi_tcp_action(struct multi_context *m, struct multi_instance *mi, int action, bool poll)
Definition: mtcp.c:585
struct context context
The context structure storing state for this VPN tunnel.
Definition: multi.h:112
#define MULTI_CHECK_SIG(m)
Definition: multi.h:648
struct multi_instance * pending
Definition: multi.h:172
#define MC_SINGLE_THREADED
Definition: multi.h:133
#define LINK_OUT(c)
Definition: forward.h:39
const char * multi_instance_string(const struct multi_instance *mi, bool null, struct gc_arena *gc)
Definition: multi.c:464
static SERVICE_STATUS status
Definition: automatic.c:47
int n_bcast_buf
Definition: options.h:421
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition: event.h:119
struct multi_instance * instance
Definition: mbuf.h:55
#define TA_SOCKET_READ_RESIDUAL
Definition: mtcp.c:48
struct link_socket * link_socket
Definition: openvpn.h:256
#define TA_SOCKET_WRITE_READY
Definition: mtcp.c:50
void initialization_sequence_completed(struct context *c, const unsigned int flags)
Definition: init.c:1476
#define IS_SIG(c)
Definition: sig.h:50
#define MTP_NONE
bool multi_tcp_instance_specific_init(struct multi_context *m, struct multi_instance *mi)
Definition: mtcp.c:175
struct context_2 c2
Level 2 context.
Definition: openvpn.h:547
static void event_free(struct event_set *es)
Definition: event.h:98
#define dmsg
Definition: error.h:174
void read_incoming_tun(struct context *c)
Read a packet from the virtual tun/tap network interface.
Definition: forward.c:1029
struct mbuf_set * mbuf
Set of buffers for passing data channel packets between VPN tunnel instances.
Definition: multi.h:151
bool mbuf_extract_item(struct mbuf_set *ms, struct mbuf_item *item)
Definition: mbuf.c:115
unsigned int ret
Definition: mtcp.c:77
struct mbuf_set * mbuf_init(unsigned int size)
Definition: mbuf.c:43
#define EVENT_READ
Definition: event.h:36
static bool stream_buf_read_setup(struct link_socket *sock)
Definition: socket.h:1013
Definition: mtcp.h:38
#define BLEN(buf)
Definition: buffer.h:127
void tunnel_server_tcp(struct context *top)
Main event loop for OpenVPN in TCP server mode.
Definition: mtcp.c:769
void mbuf_add_item(struct mbuf_set *ms, const struct mbuf_item *item)
Definition: mbuf.c:93
static struct hash_bucket * hash_bucket(struct hash *hash, uint32_t hv)
Definition: list.h:147
int n_esr
Definition: mtcp.h:42
static void multi_get_timeout(struct multi_context *m, struct timeval *dest)
Definition: multi.h:571
bool halt
Definition: multi.h:80
struct event_set * es
Definition: mtcp.h:40
struct multi_tcp * mtcp
State specific to OpenVPN using TCP as external transport.
Definition: multi.h:154
static int max_int(int x, int y)
Definition: integer.h:34
static uint32_t hash_value(const struct hash *hash, const void *key)
Definition: list.h:129
void uninit_management_callback_multi(struct multi_context *m)
Definition: multi.c:3361
#define CM_TOP
Definition: openvpn.h:518
struct mroute_addr real
External network address of the remote peer.
Definition: multi.h:88
unsigned int socket_set(struct link_socket *s, struct event_set *es, unsigned int rwflags, void *arg, unsigned int *persistent)
Definition: socket.c:3794
unsigned int tcp_rwflags
Definition: multi.h:94
static int multi_tcp_wait(const struct context *c, struct multi_tcp *mtcp)
Definition: mtcp.c:268
volatile int signal_received
Definition: sig.h:45
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:2322
Main OpenVPN server state structure.
Definition: multi.h:131
#define MTP_LINK_OUT
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:522
#define msg
Definition: error.h:173
static bool mbuf_defined(const struct mbuf_set *ms)
Definition: mbuf.h:82
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
#define MPP_RECORD_TOUCH
Definition: multi.h:259
struct hash_element * hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv)
Definition: list.c:86
unsigned int management_persist_flags
Definition: mtcp.h:46
struct buffer buf
Definition: mbuf.h:45
void management_io(struct management *man)
Definition: manage.c:3062
struct hash * hash
VPN tunnel instances indexed by real address of the remote peer.
Definition: multi.h:143
static void wait_signal(struct event_set *es, void *arg)
Definition: event.h:144
#define TUN_WRITE
Definition: openvpn.h:243
static void socket_reset_listen_persistent(struct link_socket *s)
Definition: socket.h:1259
bool multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags)
Demultiplex and process a packet received over the external network interface.
Definition: multi.c:2488
static void multi_tcp_set_global_rw_flags(struct multi_context *m, struct multi_instance *mi)
Definition: mtcp.c:254
void context_clear_2(struct context *c)
Definition: init.c:81
static const char * pract(int action)
Definition: mtcp.c:83
static struct multi_instance * multi_create_instance_tcp(struct multi_context *m)
Definition: mtcp.c:126
static int min_int(int x, int y)
Definition: integer.h:47
#define ISC_SERVER
Definition: init.h:117
static void buf_reset(struct buffer *buf)
Definition: buffer.h:285
static int multi_tcp_post(struct multi_context *m, struct multi_instance *mi, const int action)
Definition: mtcp.c:525
struct context top
Storage structure for process-wide configuration.
Definition: multi.h:178
void * value
Definition: list.h:49
#define MTCP_TUN
Definition: mtcp.c:62
#define EVENT_WRITE
Definition: event.h:37
#define SOCKET_WRITE
Definition: openvpn.h:241
static bool socket_read_residual(const struct link_socket *s)
Definition: socket.h:1222
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
#define IOW_READ_TUN
Definition: forward.h:52
#define MTCP_SIG
Definition: mtcp.c:63
static struct context * multi_tcp_context(struct multi_context *m, struct multi_instance *mi)
Definition: mtcp.c:297
#define M_ERRNO
Definition: error.h:99
Server-mode state structure for one single VPN tunnel.
Definition: multi.h:76
#define TA_SOCKET_WRITE_DEFERRED
Definition: mtcp.c:51
static void update_time(void)
Definition: otime.h:93
Definition: list.h:60
#define MTP_TUN_OUT
struct mbuf_buffer * mbuf_alloc_buf(const struct buffer *buf)
Definition: mbuf.c:69
static void socket_set_listen_persistent(struct link_socket *s, struct event_set *es, void *arg)
Definition: socket.h:1247
static void io_wait(struct context *c, const unsigned int flags)
struct sockaddr sa
Definition: socket.h:68
#define TA_INITIAL
Definition: mtcp.c:54
unsigned int event_set_status
Definition: openvpn.h:254
void multi_tcp_free(struct multi_tcp *mtcp)
Definition: mtcp.c:229
unsigned int rwflags
Definition: event.h:79
#define D_MULTI_LOW
Definition: errlevel.h:86
static void multi_process_per_second_timers(struct multi_context *m)
Definition: multi.h:551
#define CC_HARD_USR1_TO_HUP
Definition: init.h:107
bool multi_process_timeout(struct multi_context *m, const unsigned int mpp_flags)
Definition: multi.c:2871
static void multi_tcp_process_io(struct multi_context *m)
Definition: mtcp.c:674
struct mbuf_buffer * buffer
Definition: mbuf.h:54
#define D_MULTI_TCP
Definition: errlevel.h:158
#define ptr_format
Definition: common.h:58