OpenVPN
mudp.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-2021 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 #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 #include "multi.h"
33 #include <inttypes.h>
34 #include "forward.h"
35 
36 #include "memdbg.h"
37 
38 #ifdef HAVE_SYS_INOTIFY_H
39 #include <sys/inotify.h>
40 #endif
41 
42 /*
43  * Get a client instance based on real address. If
44  * the instance doesn't exist, create it while
45  * maintaining real address hash table atomicity.
46  */
47 
48 struct multi_instance *
50 {
51  struct gc_arena gc = gc_new();
52  struct mroute_addr real;
53  struct multi_instance *mi = NULL;
54  struct hash *hash = m->hash;
55 
56  if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true)
57  && m->top.c2.buf.len > 0)
58  {
59  struct hash_element *he;
60  const uint32_t hv = hash_value(hash, &real);
61  struct hash_bucket *bucket = hash_bucket(hash, hv);
62  uint8_t *ptr = BPTR(&m->top.c2.buf);
63  uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
64  bool v2 = (op == P_DATA_V2) && (m->top.c2.buf.len >= (1 + 3));
65  bool peer_id_disabled = false;
66 
67  /* make sure buffer has enough length to read opcode (1 byte) and peer-id (3 bytes) */
68  if (v2)
69  {
70  uint32_t peer_id = ntohl(*(uint32_t *)ptr) & 0xFFFFFF;
71  peer_id_disabled = (peer_id == MAX_PEER_ID);
72 
73  if (!peer_id_disabled && (peer_id < m->max_clients) && (m->instances[peer_id]))
74  {
75  mi = m->instances[peer_id];
76 
77  *floated = !link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from);
78 
79  if (*floated)
80  {
81  /* reset prefix, since here we are not sure peer is the one it claims to be */
83  msg(D_MULTI_MEDIUM, "Float requested for peer %" PRIu32 " to %s", peer_id,
84  mroute_addr_print(&real, &gc));
85  }
86  }
87  }
88  if (!v2 || peer_id_disabled)
89  {
90  he = hash_lookup_fast(hash, bucket, &real, hv);
91  if (he)
92  {
93  mi = (struct multi_instance *) he->value;
94  }
95  }
96  if (!mi)
97  {
98  if (!m->top.c2.tls_auth_standalone
100  {
102  {
103  mi = multi_create_instance(m, &real);
104  if (mi)
105  {
106  hash_add_fast(hash, bucket, &mi->real, hv, mi);
107  mi->did_real_hash = true;
108  multi_assign_peer_id(m, mi);
109  }
110  }
111  else
112  {
114  "MULTI: Connection from %s would exceed new connection frequency limit as controlled by --connect-freq",
115  mroute_addr_print(&real, &gc));
116  }
117  }
118  }
119 
120 #ifdef ENABLE_DEBUG
122  {
123  const char *status = mi ? "[ok]" : "[failed]";
124 
125  dmsg(D_MULTI_DEBUG, "GET INST BY REAL: %s %s",
126  mroute_addr_print(&real, &gc),
127  status);
128  }
129 #endif
130  }
131 
132  gc_free(&gc);
133  ASSERT(!(mi && mi->halt));
134  return mi;
135 }
136 
137 /*
138  * Send a packet to TCP/UDP socket.
139  */
140 static inline void
141 multi_process_outgoing_link(struct multi_context *m, const unsigned int mpp_flags)
142 {
144  if (mi)
145  {
146  multi_process_outgoing_link_dowork(m, mi, mpp_flags);
147  }
148 }
149 
150 /*
151  * Process an I/O event.
152  */
153 static void
155 {
156  const unsigned int status = m->top.c2.event_set_status;
157  const unsigned int mpp_flags = m->top.c2.fast_io
160 
161 #ifdef MULTI_DEBUG_EVENT_LOOP
162  char buf[16];
163  buf[0] = 0;
164  if (status & SOCKET_READ)
165  {
166  strcat(buf, "SR/");
167  }
168  else if (status & SOCKET_WRITE)
169  {
170  strcat(buf, "SW/");
171  }
172  else if (status & TUN_READ)
173  {
174  strcat(buf, "TR/");
175  }
176  else if (status & TUN_WRITE)
177  {
178  strcat(buf, "TW/");
179  }
180  else if (status & FILE_CLOSED)
181  {
182  strcat(buf, "FC/");
183  }
184  printf("IO %s\n", buf);
185 #endif /* ifdef MULTI_DEBUG_EVENT_LOOP */
186 
187 #ifdef ENABLE_MANAGEMENT
188  if (status & (MANAGEMENT_READ|MANAGEMENT_WRITE))
189  {
192  }
193 #endif
194 
195  /* UDP port ready to accept write */
196  if (status & SOCKET_WRITE)
197  {
198  multi_process_outgoing_link(m, mpp_flags);
199  }
200  /* TUN device ready to accept write */
201  else if (status & TUN_WRITE)
202  {
203  multi_process_outgoing_tun(m, mpp_flags);
204  }
205  /* Incoming data on UDP port */
206  else if (status & SOCKET_READ)
207  {
208  read_incoming_link(&m->top);
209  if (!IS_SIG(&m->top))
210  {
211  multi_process_incoming_link(m, NULL, mpp_flags);
212  }
213  }
214  /* Incoming data on TUN device */
215  else if (status & TUN_READ)
216  {
217  read_incoming_tun(&m->top);
218  if (!IS_SIG(&m->top))
219  {
220  multi_process_incoming_tun(m, mpp_flags);
221  }
222  }
223 #ifdef ENABLE_ASYNC_PUSH
224  /* INOTIFY callback */
225  else if (status & FILE_CLOSED)
226  {
227  multi_process_file_closed(m, mpp_flags);
228  }
229 #endif
230 }
231 
232 /*
233  * Return the io_wait() flags appropriate for
234  * a point-to-multipoint tunnel.
235  */
236 static inline unsigned int
238 {
239  unsigned int flags = IOW_WAIT_SIGNAL;
240  if (m->pending)
241  {
242  if (TUN_OUT(&m->pending->context))
243  {
244  flags |= IOW_TO_TUN;
245  }
246  if (LINK_OUT(&m->pending->context))
247  {
248  flags |= IOW_TO_LINK;
249  }
250  }
251  else if (mbuf_defined(m->mbuf))
252  {
253  flags |= IOW_MBUF;
254  }
255  else
256  {
257  flags |= IOW_READ;
258  }
259 #ifdef _WIN32
260  if (tuntap_ring_empty(m->top.c1.tuntap))
261  {
262  flags &= ~IOW_READ_TUN;
263  }
264 #endif
265  return flags;
266 }
267 
268 
269 void
271 {
272  struct multi_context multi;
273 
274  top->mode = CM_TOP;
275  context_clear_2(top);
276 
277  /* initialize top-tunnel instance */
279  if (IS_SIG(top))
280  {
281  return;
282  }
283 
284  /* initialize global multi_context object */
285  multi_init(&multi, top, false);
286 
287  /* initialize our cloned top object */
288  multi_top_init(&multi, top);
289 
290  /* initialize management interface */
292 
293  /* finished with initialization */
294  initialization_sequence_completed(top, ISC_SERVER); /* --mode server --proto udp */
295 
296 #ifdef ENABLE_ASYNC_PUSH
297  multi.top.c2.inotify_fd = inotify_init();
298  if (multi.top.c2.inotify_fd < 0)
299  {
300  msg(D_MULTI_ERRORS | M_ERRNO, "MULTI: inotify_init error");
301  }
302 #endif
303 
304  /* per-packet event loop */
305  while (true)
306  {
308 
309  /* set up and do the io_wait() */
310  multi_get_timeout(&multi, &multi.top.c2.timeval);
311  io_wait(&multi.top, p2mp_iow_flags(&multi));
312  MULTI_CHECK_SIG(&multi);
313 
314  /* check on status of coarse timers */
316 
317  /* timeout? */
318  if (multi.top.c2.event_set_status == ES_TIMEOUT)
319  {
321  }
322  else
323  {
324  /* process I/O */
325  multi_process_io_udp(&multi);
326  MULTI_CHECK_SIG(&multi);
327  }
328 
329  perf_pop();
330  }
331 
332 #ifdef ENABLE_ASYNC_PUSH
333  close(top->c2.inotify_fd);
334 #endif
335 
336  /* shut down management interface */
338 
339  /* save ifconfig-pool */
340  multi_ifconfig_pool_persist(&multi, true);
341 
342  /* tear down tunnel instance (unless --persist-tun) */
343  multi_uninit(&multi);
344  multi_top_free(&multi);
345  close_instance(top);
346 }
347 
struct multi_instance ** instances
Array of multi_instances.
Definition: multi.h:153
#define TUN_OUT(c)
Definition: forward.h:38
void multi_init(struct multi_context *m, struct context *t, bool tcp_mode)
Definition: multi.c:292
#define SOCKET_READ
Definition: event.h:62
#define D_MULTI_ERRORS
Definition: errlevel.h:65
#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:165
Contains all state information for one tunnel.
Definition: openvpn.h:461
struct env_set * es
Set of environment variables.
Definition: openvpn.h:484
void multi_assign_peer_id(struct multi_context *m, struct multi_instance *mi)
Assigns a peer-id to a a client and adds the instance to the the instances array of the multi_context...
Definition: multi.c:3896
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1023
static void multi_process_outgoing_link(struct multi_context *m, const unsigned int mpp_flags)
Definition: mudp.c:141
void ungenerate_prefix(struct multi_instance *mi)
Definition: multi.c:505
static struct multi_instance * multi_process_outgoing_link_pre(struct multi_context *m)
Definition: multi.h:408
struct buffer buf
Definition: openvpn.h:365
struct tls_auth_standalone * tls_auth_standalone
TLS state structure required for the initial authentication of a client&#39;s connection attempt...
Definition: openvpn.h:322
bool frequency_limit_event_allowed(struct frequency_limit *f)
Definition: otime.c:169
void close_instance(struct context *c)
Definition: init.c:4371
void multi_top_free(struct multi_context *m)
Definition: multi.c:3567
#define FILE_CLOSED
Definition: event.h:74
static void perf_pop(void)
Definition: perf.h:82
static void perf_push(int type)
Definition: perf.h:78
#define dmsg(flags,...)
Definition: error.h:157
#define MAX_PEER_ID
Definition: openvpn.h:535
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition: openvpn.h:167
#define ES_TIMEOUT
Definition: event.h:69
#define ASSERT(x)
Definition: error.h:204
#define IOW_TO_LINK
Definition: forward.h:55
static bool check_debug_level(unsigned int level)
Definition: error.h:234
bool tls_pre_decrypt_lite(const struct tls_auth_standalone *tas, const struct link_socket_actual *from, const struct buffer *buf)
Inspect an incoming packet for which no VPN tunnel is active, and determine whether a new VPN tunnel ...
Definition: ssl.c:3784
void read_incoming_link(struct context *c)
Read a packet from the external network interface.
Definition: forward.c:793
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:3289
bool did_real_hash
Definition: multi.h:124
#define MPP_CLOSE_ON_SIGNAL
Definition: multi.h:282
#define D_MULTI_MEDIUM
Definition: errlevel.h:102
list flags
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
void init_instance_handle_signals(struct context *c, const struct env_set *env, const unsigned int flags)
Definition: init.c:4043
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:635
void multi_uninit(struct multi_context *m)
Definition: multi.c:689
struct context_1 c1
Level 1 context.
Definition: openvpn.h:501
#define IOW_TO_TUN
Definition: forward.h:54
#define BPTR(buf)
Definition: buffer.h:124
void multi_top_init(struct multi_context *m, const struct context *top)
Definition: multi.c:3560
void init_management_callback_multi(struct multi_context *m)
Definition: multi.c:3872
void multi_ifconfig_pool_persist(struct multi_context *m, bool force)
Definition: multi.c:163
const char * mroute_addr_print(const struct mroute_addr *ma, struct gc_arena *gc)
Definition: mroute.c:378
static bool multi_process_outgoing_link_dowork(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
Definition: multi.h:659
static struct gc_arena gc_new(void)
Definition: buffer.h:1015
#define IOW_MBUF
Definition: forward.h:61
#define MPP_PRE_SELECT
Definition: multi.h:280
struct multi_instance * multi_create_instance(struct multi_context *m, const struct mroute_addr *real)
Definition: multi.c:736
#define TUN_WRITE
Definition: event.h:66
bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port)
Definition: mroute.c:266
struct timeval timeval
Definition: openvpn.h:384
#define D_MULTI_DEBUG
Definition: errlevel.h:123
struct context context
The context structure storing state for this VPN tunnel.
Definition: multi.h:133
#define MULTI_CHECK_SIG(m)
Definition: multi.h:672
struct multi_instance * pending
Definition: multi.h:185
#define MANAGEMENT_READ
Definition: event.h:71
#define LINK_OUT(c)
Definition: forward.h:39
static void io_wait(struct context *c, const unsigned int flags)
Definition: forward.h:363
#define M_ERRNO
Definition: error.h:103
void initialization_sequence_completed(struct context *c, const unsigned int flags)
Definition: init.c:1568
Interface functions to the internal and external multiplexers.
#define IS_SIG(c)
Definition: sig.h:50
struct context_2 c2
Level 2 context.
Definition: openvpn.h:502
void read_incoming_tun(struct context *c)
Read a packet from the virtual tun/tap network interface.
Definition: forward.c:1092
struct mbuf_set * mbuf
Set of buffers for passing data channel packets between VPN tunnel instances.
Definition: multi.h:164
#define IOW_WAIT_SIGNAL
Definition: forward.h:63
static void multi_process_io_udp(struct multi_context *m)
Definition: mudp.c:154
#define P_OPCODE_SHIFT
Definition: ssl.h:51
static struct hash_bucket * hash_bucket(struct hash *hash, uint32_t hv)
Definition: list.h:141
#define msg(flags,...)
Definition: error.h:153
static void multi_get_timeout(struct multi_context *m, struct timeval *dest)
Definition: multi.h:592
bool halt
Definition: multi.h:103
static uint32_t hash_value(const struct hash *hash, const void *key)
Definition: list.h:123
static bool tuntap_ring_empty(struct tuntap *tt)
Definition: tun.h:241
#define CM_TOP
Definition: openvpn.h:471
struct mroute_addr real
External network address of the remote peer.
Definition: multi.h:111
Main OpenVPN server state structure.
Definition: multi.h:152
int mode
Role of this context within the OpenVPN process.
Definition: openvpn.h:475
static bool mbuf_defined(const struct mbuf_set *ms)
Definition: mbuf.h:80
struct hash_element * hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv)
Definition: list.c:85
void management_io(struct management *man)
Definition: manage.c:3084
struct hash * hash
VPN tunnel instances indexed by real address of the remote peer.
Definition: multi.h:156
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:3085
void context_clear_2(struct context *c)
Definition: init.c:86
#define SOCKET_WRITE
Definition: event.h:63
#define ISC_SERVER
Definition: init.h:118
struct frequency_limit * new_connection_limiter
Definition: multi.h:170
struct context top
Storage structure for process-wide configuration.
Definition: multi.h:191
bool fast_io
Definition: openvpn.h:412
void * value
Definition: list.h:47
void tunnel_server_udp(struct context *top)
Main event loop for OpenVPN in UDP server mode.
Definition: mudp.c:270
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
#define IOW_READ_TUN
Definition: forward.h:56
static bool link_socket_actual_match(const struct link_socket_actual *a1, const struct link_socket_actual *a2)
Definition: socket.h:872
struct link_socket_actual from
Definition: openvpn.h:245
struct multi_instance * multi_get_create_instance_udp(struct multi_context *m, bool *floated)
Get, and if necessary create, the multi_instance associated with a packet&#39;s source address...
Definition: mudp.c:49
Server-mode state structure for one single VPN tunnel.
Definition: multi.h:100
static SERVICE_STATUS status
Definition: interactive.c:56
Definition: list.h:58
unsigned int event_set_status
Definition: openvpn.h:235
static unsigned int p2mp_iow_flags(const struct multi_context *m)
Definition: mudp.c:237
#define MPP_CONDITIONAL_PRE_SELECT
Definition: multi.h:281
#define P_DATA_V2
Definition: ssl.h:60
#define MANAGEMENT_WRITE
Definition: event.h:72
#define TUN_READ
Definition: event.h:65
static void multi_process_per_second_timers(struct multi_context *m)
Definition: multi.h:574
#define CC_HARD_USR1_TO_HUP
Definition: init.h:108
void uninit_management_callback(void)
Definition: init.c:4028
bool multi_process_timeout(struct multi_context *m, const unsigned int mpp_flags)
Definition: multi.c:3420
#define IOW_READ
Definition: forward.h:65