big svn cleanup
[anytun.git] / src / openvpn / multi.h
blobda1e471efe5a71f472a16e1f3d1c8f04950b2329
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.
8 * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifndef MULTI_H
26 #define MULTI_H
28 #if P2MP_SERVER
30 #include "init.h"
31 #include "forward.h"
32 #include "mroute.h"
33 #include "mbuf.h"
34 #include "list.h"
35 #include "schedule.h"
36 #include "pool.h"
37 #include "mudp.h"
38 #include "mtcp.h"
39 #include "perf.h"
42 * Walk (don't run) through the routing table,
43 * deleting old entries, and possibly multi_instance
44 * structs as well which have been marked for deletion.
46 struct multi_reap
48 int bucket_base;
49 int buckets_per_pass;
50 time_t last_call;
54 * One multi_instance object per client instance.
56 struct multi_instance {
57 struct schedule_entry se; /* this must be the first element of the structure */
58 struct gc_arena gc;
59 MUTEX_DEFINE (mutex);
60 bool defined;
61 bool halt;
62 int refcount;
63 int route_count; /* number of routes (including cached routes) owned by this instance */
64 time_t created;
65 struct timeval wakeup; /* absolute time */
66 struct mroute_addr real;
67 ifconfig_pool_handle vaddr_handle;
68 const char *msg_prefix;
70 /* queued outgoing data in Server/TCP mode */
71 unsigned int tcp_rwflags;
72 struct mbuf_set *tcp_link_out_deferred;
73 bool socket_set_called;
75 in_addr_t reporting_addr; /* IP address shown in status listing */
77 bool did_open_context;
78 bool did_real_hash;
79 bool did_iter;
80 bool connection_established_flag;
81 bool did_iroutes;
83 struct context context;
87 * One multi_context object per server daemon thread.
89 struct multi_context {
90 # define MC_UNDEF 0
91 # define MC_SINGLE_THREADED (1<<0)
92 # define MC_MULTI_THREADED_MASTER (1<<1)
93 # define MC_MULTI_THREADED_WORKER (1<<2)
94 # define MC_MULTI_THREADED_SCHEDULER (1<<3)
95 # define MC_WORK_THREAD (MC_MULTI_THREADED_WORKER|MC_MULTI_THREADED_SCHEDULER)
96 int thread_mode;
98 struct hash *hash; /* client instances indexed by real address */
99 struct hash *vhash; /* client instances indexed by virtual address */
100 struct hash *iter; /* like real address hash but optimized for iteration */
101 struct schedule *schedule;
102 struct mbuf_set *mbuf;
103 struct multi_tcp *mtcp;
104 struct ifconfig_pool *ifconfig_pool;
105 struct frequency_limit *new_connection_limiter;
106 struct mroute_helper *route_helper;
107 struct multi_reap *reaper;
108 struct mroute_addr local;
109 bool enable_c2c;
110 int max_clients;
111 int tcp_queue_limit;
112 int status_file_version;
114 struct multi_instance *pending;
115 struct multi_instance *earliest_wakeup;
116 struct multi_instance **mpp_touched;
117 struct context_buffers *context_buffers;
118 time_t per_second_trigger;
120 struct context top;
124 * Host route
126 struct multi_route
128 struct mroute_addr addr;
129 struct multi_instance *instance;
131 # define MULTI_ROUTE_CACHE (1<<0)
132 # define MULTI_ROUTE_AGEABLE (1<<1)
133 unsigned int flags;
135 unsigned int cache_generation;
136 time_t last_reference;
140 * top level function, called by openvpn.c
142 void tunnel_server (struct context *top);
144 const char *multi_instance_string (const struct multi_instance *mi, bool null, struct gc_arena *gc);
146 void multi_bcast (struct multi_context *m,
147 const struct buffer *buf,
148 struct multi_instance *omit);
151 * Called by mtcp.c, mudp.c, or other (to be written) protocol drivers
154 void multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode);
155 void multi_uninit (struct multi_context *m);
157 void multi_top_init (struct multi_context *m, const struct context *top, const bool alloc_buffers);
158 void multi_top_free (struct multi_context *m);
160 struct multi_instance *multi_create_instance (struct multi_context *m, const struct mroute_addr *real);
161 void multi_close_instance (struct multi_context *m, struct multi_instance *mi, bool shutdown);
163 bool multi_process_timeout (struct multi_context *m, const unsigned int mpp_flags);
165 #define MPP_PRE_SELECT (1<<0)
166 #define MPP_CONDITIONAL_PRE_SELECT (1<<1)
167 #define MPP_CLOSE_ON_SIGNAL (1<<2)
168 #define MPP_RECORD_TOUCH (1<<3)
169 bool multi_process_post (struct multi_context *m, struct multi_instance *mi, const unsigned int flags);
171 bool multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags);
172 bool multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flags);
174 void multi_process_drop_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags);
176 void multi_print_status (struct multi_context *m, struct status_output *so, const int version);
178 struct multi_instance *multi_get_queue (struct mbuf_set *ms);
180 void multi_add_mbuf (struct multi_context *m,
181 struct multi_instance *mi,
182 struct mbuf_buffer *mb);
184 void multi_ifconfig_pool_persist (struct multi_context *m, bool force);
186 bool multi_process_signal (struct multi_context *m);
188 void multi_close_instance_on_signal (struct multi_context *m, struct multi_instance *mi);
190 void init_management_callback_multi (struct multi_context *m);
191 void uninit_management_callback_multi (struct multi_context *m);
194 * Return true if our output queue is not full
196 static inline bool
197 multi_output_queue_ready (const struct multi_context *m,
198 const struct multi_instance *mi)
200 if (mi->tcp_link_out_deferred)
201 return mbuf_len (mi->tcp_link_out_deferred) <= m->tcp_queue_limit;
202 else
203 return true;
207 * Determine which instance has pending output
208 * and prepare the output for sending in
209 * the to_link buffer.
211 static inline struct multi_instance *
212 multi_process_outgoing_link_pre (struct multi_context *m)
214 struct multi_instance *mi = NULL;
216 if (m->pending)
217 mi = m->pending;
218 else if (mbuf_defined (m->mbuf))
219 mi = multi_get_queue (m->mbuf);
220 return mi;
224 * Per-client route quota management
227 void route_quota_exceeded (const struct multi_context *m, const struct multi_instance *mi);
229 static inline void
230 route_quota_inc (struct multi_instance *mi)
232 ++mi->route_count;
235 static inline void
236 route_quota_dec (struct multi_instance *mi)
238 --mi->route_count;
241 /* can we add a new route? */
242 static inline bool
243 route_quota_test (const struct multi_context *m, const struct multi_instance *mi)
245 if (mi->route_count >= mi->context.options.max_routes_per_client)
247 route_quota_exceeded (m, mi);
248 return false;
250 else
251 return true;
255 * Instance reference counting
258 static inline void
259 multi_instance_inc_refcount (struct multi_instance *mi)
261 ++mi->refcount;
264 static inline void
265 multi_instance_dec_refcount (struct multi_instance *mi)
267 if (--mi->refcount <= 0)
269 gc_free (&mi->gc);
270 mutex_destroy (&mi->mutex);
271 free (mi);
275 static inline void
276 multi_route_del (struct multi_route *route)
278 struct multi_instance *mi = route->instance;
279 route_quota_dec (mi);
280 multi_instance_dec_refcount (mi);
281 free (route);
284 static inline bool
285 multi_route_defined (const struct multi_context *m,
286 const struct multi_route *r)
288 if (r->instance->halt)
289 return false;
290 else if ((r->flags & MULTI_ROUTE_CACHE)
291 && r->cache_generation != m->route_helper->cache_generation)
292 return false;
293 else if ((r->flags & MULTI_ROUTE_AGEABLE)
294 && r->last_reference + m->route_helper->ageable_ttl_secs < now)
295 return false;
296 else
297 return true;
301 * Set a msg() function prefix with our current client instance ID.
304 static inline void
305 set_prefix (struct multi_instance *mi)
307 #ifdef MULTI_DEBUG_EVENT_LOOP
308 if (mi->msg_prefix)
309 printf ("[%s]\n", mi->msg_prefix);
310 #endif
311 msg_set_prefix (mi->msg_prefix);
314 static inline void
315 clear_prefix (void)
317 #ifdef MULTI_DEBUG_EVENT_LOOP
318 printf ("[NULL]\n");
319 #endif
320 msg_set_prefix (NULL);
324 * Instance Reaper
326 * Reaper constants. The reaper is the process where the virtual address
327 * and virtual route hash table is scanned for dead entries which are
328 * then removed. The hash table could potentially be quite large, so we
329 * don't want to reap in a single pass.
332 #define REAP_MAX_WAKEUP 10 /* Do reap pass at least once per n seconds */
333 #define REAP_DIVISOR 256 /* How many passes to cover whole hash table */
334 #define REAP_MIN 16 /* Minimum number of buckets per pass */
335 #define REAP_MAX 1024 /* Maximum number of buckets per pass */
338 * Mark a cached host route for deletion after this
339 * many seconds without any references.
341 #define MULTI_CACHE_ROUTE_TTL 60
343 static inline void
344 multi_reap_process (const struct multi_context *m)
346 void multi_reap_process_dowork (const struct multi_context *m);
347 if (m->reaper->last_call != now)
348 multi_reap_process_dowork (m);
351 static inline void
352 multi_process_per_second_timers (struct multi_context *m)
354 if (m->per_second_trigger != now)
356 void multi_process_per_second_timers_dowork (struct multi_context *m);
357 multi_process_per_second_timers_dowork (m);
358 m->per_second_trigger = now;
363 * Compute earliest timeout expiry from the set of
364 * all instances. Output:
366 * m->earliest_wakeup : instance needing the earliest service.
367 * dest : earliest timeout as a delta in relation
368 * to current time.
370 static inline void
371 multi_get_timeout (struct multi_context *m, struct timeval *dest)
373 struct timeval tv, current;
375 CLEAR (tv);
376 m->earliest_wakeup = (struct multi_instance *) schedule_get_earliest_wakeup (m->schedule, &tv);
377 if (m->earliest_wakeup)
379 ASSERT (!gettimeofday (&current, NULL));
380 tv_delta (dest, &current, &tv);
381 if (dest->tv_sec >= REAP_MAX_WAKEUP)
383 m->earliest_wakeup = NULL;
384 dest->tv_sec = REAP_MAX_WAKEUP;
385 dest->tv_usec = 0;
388 else
390 dest->tv_sec = REAP_MAX_WAKEUP;
391 dest->tv_usec = 0;
396 * Send a packet to TUN/TAP interface.
398 static inline bool
399 multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags)
401 struct multi_instance *mi = m->pending;
402 bool ret = true;
404 ASSERT (mi);
405 #ifdef MULTI_DEBUG_EVENT_LOOP
406 printf ("%s -> TUN len=%d\n",
407 id(mi),
408 mi->context.c2.to_tun.len);
409 #endif
410 set_prefix (mi);
411 process_outgoing_tun (&mi->context);
412 ret = multi_process_post (m, mi, mpp_flags);
413 clear_prefix ();
414 return ret;
417 static inline bool
418 multi_process_outgoing_link_dowork (struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)
420 bool ret = true;
421 set_prefix (mi);
422 process_outgoing_link (&mi->context);
423 ret = multi_process_post (m, mi, mpp_flags);
424 clear_prefix ();
425 return ret;
429 * Check for signals.
431 #define MULTI_CHECK_SIG(m) EVENT_LOOP_CHECK_SIGNAL (&(m)->top, multi_process_signal, (m))
433 static inline void
434 multi_set_pending (struct multi_context *m, struct multi_instance *mi)
436 m->pending = mi;
439 static inline void
440 multi_release_io_lock (struct multi_context *m)
444 #endif /* P2MP_SERVER */
445 #endif /* MULTI_H */