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
8 * Copyright (C) 2002-2008 Telethra, Inc. <sales@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
37 #include "forward-inline.h"
38 #include "pf-inline.h"
40 /*#define MULTI_DEBUG_EVENT_LOOP*/
42 #ifdef MULTI_DEBUG_EVENT_LOOP
44 id (struct multi_instance
*mi
)
47 return tls_common_name (mi
->context
.c2
.tls_multi
, false);
53 #ifdef MANAGEMENT_DEF_AUTH
55 set_cc_config (struct multi_instance
*mi
, struct buffer_list
*cc_config
)
58 buffer_list_free (mi
->cc_config
);
59 mi
->cc_config
= cc_config
;
64 learn_address_script (const struct multi_context
*m
,
65 const struct multi_instance
*mi
,
67 const struct mroute_addr
*addr
)
69 struct gc_arena gc
= gc_new ();
72 struct plugin_list
*plugins
;
74 /* get environmental variable source */
75 if (mi
&& mi
->context
.c2
.es
)
76 es
= mi
->context
.c2
.es
;
78 es
= env_set_create (&gc
);
80 /* get plugin source */
82 plugins
= mi
->context
.plugins
;
84 plugins
= m
->top
.plugins
;
86 if (plugin_defined (plugins
, OPENVPN_PLUGIN_LEARN_ADDRESS
))
88 struct argv argv
= argv_new ();
89 argv_printf (&argv
, "%s %s",
91 mroute_addr_print (addr
, &gc
));
93 argv_printf_cat (&argv
, "%s", tls_common_name (mi
->context
.c2
.tls_multi
, false));
94 if (plugin_call (plugins
, OPENVPN_PLUGIN_LEARN_ADDRESS
, &argv
, NULL
, es
) != OPENVPN_PLUGIN_FUNC_SUCCESS
)
96 msg (M_WARN
, "WARNING: learn-address plugin call failed");
102 if (m
->top
.options
.learn_address_script
)
104 struct argv argv
= argv_new ();
105 setenv_str (es
, "script_type", "learn-address");
106 argv_printf (&argv
, "%sc %s %s",
107 m
->top
.options
.learn_address_script
,
109 mroute_addr_print (addr
, &gc
));
111 argv_printf_cat (&argv
, "%s", tls_common_name (mi
->context
.c2
.tls_multi
, false));
112 if (!openvpn_execve_check (&argv
, es
, S_SCRIPT
, "WARNING: learn-address command failed"))
122 multi_ifconfig_pool_persist (struct multi_context
*m
, bool force
)
124 /* write pool data to file */
126 && m
->top
.c1
.ifconfig_pool_persist
127 && (force
|| ifconfig_pool_write_trigger (m
->top
.c1
.ifconfig_pool_persist
)))
129 ifconfig_pool_write (m
->top
.c1
.ifconfig_pool_persist
, m
->ifconfig_pool
);
134 multi_reap_range (const struct multi_context
*m
,
138 struct gc_arena gc
= gc_new ();
139 struct hash_iterator hi
;
140 struct hash_element
*he
;
142 if (start_bucket
< 0)
145 end_bucket
= hash_n_buckets (m
->vhash
);
148 dmsg (D_MULTI_DEBUG
, "MULTI: REAP range %d -> %d", start_bucket
, end_bucket
);
149 hash_iterator_init_range (m
->vhash
, &hi
, true, start_bucket
, end_bucket
);
150 while ((he
= hash_iterator_next (&hi
)) != NULL
)
152 struct multi_route
*r
= (struct multi_route
*) he
->value
;
153 if (!multi_route_defined (m
, r
))
155 dmsg (D_MULTI_DEBUG
, "MULTI: REAP DEL %s",
156 mroute_addr_print (&r
->addr
, &gc
));
157 learn_address_script (m
, NULL
, "delete", &r
->addr
);
159 hash_iterator_delete_element (&hi
);
162 hash_iterator_free (&hi
);
167 multi_reap_all (const struct multi_context
*m
)
169 multi_reap_range (m
, -1, 0);
172 static struct multi_reap
*
173 multi_reap_new (int buckets_per_pass
)
175 struct multi_reap
*mr
;
176 ALLOC_OBJ (mr
, struct multi_reap
);
178 mr
->buckets_per_pass
= buckets_per_pass
;
184 multi_reap_process_dowork (const struct multi_context
*m
)
186 struct multi_reap
*mr
= m
->reaper
;
187 if (mr
->bucket_base
>= hash_n_buckets (m
->vhash
))
189 multi_reap_range (m
, mr
->bucket_base
, mr
->bucket_base
+ mr
->buckets_per_pass
);
190 mr
->bucket_base
+= mr
->buckets_per_pass
;
195 multi_reap_free (struct multi_reap
*mr
)
201 * How many buckets in vhash to reap per pass.
204 reap_buckets_per_pass (int n_buckets
)
206 return constrain_int (n_buckets
/ REAP_DIVISOR
, REAP_MIN
, REAP_MAX
);
209 #ifdef MANAGEMENT_DEF_AUTH
212 cid_hash_function (const void *key
, uint32_t iv
)
214 const unsigned long *k
= (const unsigned long *)key
;
215 return (uint32_t) *k
;
219 cid_compare_function (const void *key1
, const void *key2
)
221 const unsigned long *k1
= (const unsigned long *)key1
;
222 const unsigned long *k2
= (const unsigned long *)key2
;
229 * Main initialization function, init multi_context object.
232 multi_init (struct multi_context
*m
, struct context
*t
, bool tcp_mode
, int thread_mode
)
234 int dev
= DEV_TYPE_UNDEF
;
236 msg (D_MULTI_LOW
, "MULTI: multi_init called, r=%d v=%d",
237 t
->options
.real_hash_size
,
238 t
->options
.virtual_hash_size
);
241 * Get tun/tap/null device type
243 dev
= dev_type_enum (t
->options
.dev
, t
->options
.dev_type
);
246 * Init our multi_context object.
250 m
->thread_mode
= thread_mode
;
253 * Real address hash table (source port number is
254 * considered to be part of the address). Used
255 * to determine which client sent an incoming packet
256 * which is seen on the TCP/UDP socket.
258 m
->hash
= hash_init (t
->options
.real_hash_size
,
260 mroute_addr_hash_function
,
261 mroute_addr_compare_function
);
264 * Virtual address hash table. Used to determine
265 * which client to route a packet to.
267 m
->vhash
= hash_init (t
->options
.virtual_hash_size
,
269 mroute_addr_hash_function
,
270 mroute_addr_compare_function
);
273 * This hash table is a clone of m->hash but with a
274 * bucket size of one so that it can be used
275 * for fast iteration through the list.
277 m
->iter
= hash_init (1,
279 mroute_addr_hash_function
,
280 mroute_addr_compare_function
);
282 #ifdef MANAGEMENT_DEF_AUTH
283 m
->cid_hash
= hash_init (t
->options
.real_hash_size
,
286 cid_compare_function
);
290 * This is our scheduler, for time-based wakeup
293 m
->schedule
= schedule_init ();
296 * Limit frequency of incoming connections to control
299 m
->new_connection_limiter
= frequency_limit_init (t
->options
.cf_max
,
303 * Allocate broadcast/multicast buffer list
305 m
->mbuf
= mbuf_init (t
->options
.n_bcast_buf
);
308 * Different status file format options are available
310 m
->status_file_version
= t
->options
.status_file_version
;
313 * Possibly allocate an ifconfig pool, do it
314 * differently based on whether a tun or tap style
317 if (t
->options
.ifconfig_pool_defined
)
319 if (dev
== DEV_TYPE_TAP
)
321 m
->ifconfig_pool
= ifconfig_pool_init (IFCONFIG_POOL_INDIV
,
322 t
->options
.ifconfig_pool_start
,
323 t
->options
.ifconfig_pool_end
,
324 t
->options
.duplicate_cn
);
326 else if (dev
== DEV_TYPE_TUN
)
328 m
->ifconfig_pool
= ifconfig_pool_init (
329 (t
->options
.topology
== TOP_NET30
) ? IFCONFIG_POOL_30NET
: IFCONFIG_POOL_INDIV
,
330 t
->options
.ifconfig_pool_start
,
331 t
->options
.ifconfig_pool_end
,
332 t
->options
.duplicate_cn
);
339 /* reload pool data from file */
340 if (t
->c1
.ifconfig_pool_persist
)
341 ifconfig_pool_read (t
->c1
.ifconfig_pool_persist
, m
->ifconfig_pool
);
345 * Help us keep track of routing table.
347 m
->route_helper
= mroute_helper_init (MULTI_CACHE_ROUTE_TTL
);
350 * Initialize route and instance reaper.
352 m
->reaper
= multi_reap_new (reap_buckets_per_pass (t
->options
.virtual_hash_size
));
355 * Get local ifconfig address
358 ASSERT (t
->c1
.tuntap
);
359 mroute_extract_in_addr_t (&m
->local
, t
->c1
.tuntap
->local
);
364 m
->max_clients
= t
->options
.max_clients
;
367 * Initialize multi-socket TCP I/O wait object
370 m
->mtcp
= multi_tcp_init (t
->options
.max_clients
, &m
->max_clients
);
371 m
->tcp_queue_limit
= t
->options
.tcp_queue_limit
;
374 * Allow client <-> client communication, without going through
375 * tun/tap interface and network stack?
377 m
->enable_c2c
= t
->options
.enable_c2c
;
381 multi_instance_string (const struct multi_instance
*mi
, bool null
, struct gc_arena
*gc
)
385 struct buffer out
= alloc_buf_gc (256, gc
);
386 const char *cn
= tls_common_name (mi
->context
.c2
.tls_multi
, true);
389 buf_printf (&out
, "%s/", cn
);
390 buf_printf (&out
, "%s", mroute_addr_print (&mi
->real
, gc
));
400 generate_prefix (struct multi_instance
*mi
)
402 mi
->msg_prefix
= multi_instance_string (mi
, true, &mi
->gc
);
407 ungenerate_prefix (struct multi_instance
*mi
)
409 mi
->msg_prefix
= NULL
;
414 mi_prefix (const struct multi_instance
*mi
)
416 if (mi
&& mi
->msg_prefix
)
417 return mi
->msg_prefix
;
423 * Tell the route helper about deleted iroutes so
424 * that it can update its mask of currently used
428 multi_del_iroutes (struct multi_context
*m
,
429 struct multi_instance
*mi
)
431 const struct iroute
*ir
;
432 if (TUNNEL_TYPE (mi
->context
.c1
.tuntap
) == DEV_TYPE_TUN
)
434 for (ir
= mi
->context
.options
.iroutes
; ir
!= NULL
; ir
= ir
->next
)
435 mroute_helper_del_iroute (m
->route_helper
, ir
);
440 multi_client_disconnect_setenv (struct multi_context
*m
,
441 struct multi_instance
*mi
)
443 /* setenv client real IP address */
444 setenv_trusted (mi
->context
.c2
.es
, get_link_socket_info (&mi
->context
));
447 setenv_counter (mi
->context
.c2
.es
, "bytes_received", mi
->context
.c2
.link_read_bytes
);
448 setenv_counter (mi
->context
.c2
.es
, "bytes_sent", mi
->context
.c2
.link_write_bytes
);
450 /* setenv connection duration */
452 const unsigned int duration
= (unsigned int) now
- mi
->created
;
453 setenv_unsigned (mi
->context
.c2
.es
, "time_duration", duration
);
458 multi_client_disconnect_script (struct multi_context
*m
,
459 struct multi_instance
*mi
)
461 if ((mi
->context
.c2
.context_auth
== CAS_SUCCEEDED
&& mi
->connection_established_flag
)
462 || mi
->context
.c2
.context_auth
== CAS_PARTIAL
)
464 multi_client_disconnect_setenv (m
, mi
);
466 if (plugin_defined (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_DISCONNECT
))
468 if (plugin_call (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_DISCONNECT
, NULL
, NULL
, mi
->context
.c2
.es
) != OPENVPN_PLUGIN_FUNC_SUCCESS
)
469 msg (M_WARN
, "WARNING: client-disconnect plugin call failed");
472 if (mi
->context
.options
.client_disconnect_script
)
474 struct argv argv
= argv_new ();
475 setenv_str (mi
->context
.c2
.es
, "script_type", "client-disconnect");
476 argv_printf (&argv
, "%sc", mi
->context
.options
.client_disconnect_script
);
477 openvpn_execve_check (&argv
, mi
->context
.c2
.es
, S_SCRIPT
, "client-disconnect command failed");
480 #ifdef MANAGEMENT_DEF_AUTH
482 management_notify_client_close (management
, &mi
->context
.c2
.mda_context
, mi
->context
.c2
.es
);
489 multi_close_instance (struct multi_context
*m
,
490 struct multi_instance
*mi
,
493 perf_push (PERF_MULTI_CLOSE_INSTANCE
);
498 dmsg (D_MULTI_DEBUG
, "MULTI: multi_close_instance called");
500 /* prevent dangling pointers */
501 if (m
->pending
== mi
)
502 multi_set_pending (m
, NULL
);
503 if (m
->earliest_wakeup
== mi
)
504 m
->earliest_wakeup
= NULL
;
508 if (mi
->did_real_hash
)
510 ASSERT (hash_remove (m
->hash
, &mi
->real
));
514 ASSERT (hash_remove (m
->iter
, &mi
->real
));
516 #ifdef MANAGEMENT_DEF_AUTH
517 if (mi
->did_cid_hash
)
519 ASSERT (hash_remove (m
->cid_hash
, &mi
->context
.c2
.mda_context
.cid
));
523 schedule_remove_entry (m
->schedule
, (struct schedule_entry
*) mi
);
525 ifconfig_pool_release (m
->ifconfig_pool
, mi
->vaddr_handle
, false);
529 multi_del_iroutes (m
, mi
);
530 mi
->did_iroutes
= false;
534 multi_tcp_dereference_instance (m
->mtcp
, mi
);
536 mbuf_dereference_instance (m
->mbuf
, mi
);
539 #ifdef MANAGEMENT_DEF_AUTH
540 set_cc_config (mi
, NULL
);
543 multi_client_disconnect_script (m
, mi
);
545 if (mi
->did_open_context
)
546 close_context (&mi
->context
, SIGTERM
, CC_GC_FREE
);
548 multi_tcp_instance_specific_free (mi
);
550 ungenerate_prefix (mi
);
553 * Don't actually delete the instance memory allocation yet,
554 * because virtual routes may still point to it. Let the
555 * vhash reaper deal with it.
557 multi_instance_dec_refcount (mi
);
563 * Called on shutdown or restart.
566 multi_uninit (struct multi_context
*m
)
568 if (m
->thread_mode
& MC_WORK_THREAD
)
571 m
->thread_mode
= MC_UNDEF
;
573 else if (m
->thread_mode
)
577 struct hash_iterator hi
;
578 struct hash_element
*he
;
580 hash_iterator_init (m
->iter
, &hi
, true);
581 while ((he
= hash_iterator_next (&hi
)))
583 struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
584 mi
->did_iter
= false;
585 multi_close_instance (m
, mi
, true);
587 hash_iterator_free (&hi
);
592 hash_free (m
->vhash
);
594 #ifdef MANAGEMENT_DEF_AUTH
595 hash_free (m
->cid_hash
);
599 schedule_free (m
->schedule
);
601 ifconfig_pool_free (m
->ifconfig_pool
);
602 frequency_limit_free (m
->new_connection_limiter
);
603 multi_reap_free (m
->reaper
);
604 mroute_helper_free (m
->route_helper
);
605 multi_tcp_free (m
->mtcp
);
606 m
->thread_mode
= MC_UNDEF
;
612 * Create a client instance object for a newly connected client.
614 struct multi_instance
*
615 multi_create_instance (struct multi_context
*m
, const struct mroute_addr
*real
)
617 struct gc_arena gc
= gc_new ();
618 struct multi_instance
*mi
;
620 perf_push (PERF_MULTI_CREATE_INSTANCE
);
622 msg (D_MULTI_LOW
, "MULTI: multi_create_instance called");
624 ALLOC_OBJ_CLEAR (mi
, struct multi_instance
);
626 mutex_init (&mi
->mutex
);
628 multi_instance_inc_refcount (mi
);
629 mi
->vaddr_handle
= -1;
631 mroute_addr_init (&mi
->real
);
636 generate_prefix (mi
);
639 mi
->did_open_context
= true;
640 inherit_context_child (&mi
->context
, &m
->top
);
641 if (IS_SIG (&mi
->context
))
644 mi
->context
.c2
.context_auth
= CAS_PENDING
;
646 if (hash_n_elements (m
->hash
) >= m
->max_clients
)
648 msg (D_MULTI_ERRORS
, "MULTI: new incoming connection would exceed maximum number of clients (%d)", m
->max_clients
);
652 if (!real
) /* TCP mode? */
654 if (!multi_tcp_instance_specific_init (m
, mi
))
656 generate_prefix (mi
);
659 if (!hash_add (m
->iter
, &mi
->real
, mi
, false))
661 msg (D_MULTI_LOW
, "MULTI: unable to add real address [%s] to iterator hash table",
662 mroute_addr_print (&mi
->real
, &gc
));
667 #ifdef MANAGEMENT_DEF_AUTH
669 mi
->context
.c2
.mda_context
.cid
= m
->cid_counter
++;
670 } while (!hash_add (m
->cid_hash
, &mi
->context
.c2
.mda_context
.cid
, mi
, false));
671 mi
->did_cid_hash
= true;
674 mi
->context
.c2
.push_reply_deferred
= true;
676 if (!multi_process_post (m
, mi
, MPP_PRE_SELECT
))
678 msg (D_MULTI_ERRORS
, "MULTI: signal occurred during client instance initialization");
687 multi_close_instance (m
, mi
, false);
694 * Dump tables -- triggered by SIGUSR2.
695 * If status file is defined, write to file.
696 * If status file is NULL, write to syslog.
699 multi_print_status (struct multi_context
*m
, struct status_output
*so
, const int version
)
703 struct gc_arena gc_top
= gc_new ();
704 struct hash_iterator hi
;
705 const struct hash_element
*he
;
709 if (version
== 1) /* WAS: m->status_file_version */
712 * Status file version 1
714 status_printf (so
, PACKAGE_NAME
" CLIENT LIST");
715 status_printf (so
, "Updated,%s", time_string (0, 0, false, &gc_top
));
716 status_printf (so
, "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since");
717 hash_iterator_init (m
->hash
, &hi
, true);
718 while ((he
= hash_iterator_next (&hi
)))
720 struct gc_arena gc
= gc_new ();
721 const struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
725 status_printf (so
, "%s,%s," counter_format
"," counter_format
",%s",
726 tls_common_name (mi
->context
.c2
.tls_multi
, false),
727 mroute_addr_print (&mi
->real
, &gc
),
728 mi
->context
.c2
.link_read_bytes
,
729 mi
->context
.c2
.link_write_bytes
,
730 time_string (mi
->created
, 0, false, &gc
));
734 hash_iterator_free (&hi
);
736 status_printf (so
, "ROUTING TABLE");
737 status_printf (so
, "Virtual Address,Common Name,Real Address,Last Ref");
738 hash_iterator_init (m
->vhash
, &hi
, true);
739 while ((he
= hash_iterator_next (&hi
)))
741 struct gc_arena gc
= gc_new ();
742 const struct multi_route
*route
= (struct multi_route
*) he
->value
;
744 if (multi_route_defined (m
, route
))
746 const struct multi_instance
*mi
= route
->instance
;
747 const struct mroute_addr
*ma
= &route
->addr
;
748 char flags
[2] = {0, 0};
750 if (route
->flags
& MULTI_ROUTE_CACHE
)
752 status_printf (so
, "%s%s,%s,%s,%s",
753 mroute_addr_print (ma
, &gc
),
755 tls_common_name (mi
->context
.c2
.tls_multi
, false),
756 mroute_addr_print (&mi
->real
, &gc
),
757 time_string (route
->last_reference
, 0, false, &gc
));
761 hash_iterator_free (&hi
);
763 status_printf (so
, "GLOBAL STATS");
765 status_printf (so
, "Max bcast/mcast queue length,%d",
766 mbuf_maximum_queued (m
->mbuf
));
768 status_printf (so
, "END");
770 else if (version
== 2)
773 * Status file version 2
775 status_printf (so
, "TITLE,%s", title_string
);
776 status_printf (so
, "TIME,%s,%u", time_string (now
, 0, false, &gc_top
), (unsigned int)now
);
777 status_printf (so
, "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)");
778 hash_iterator_init (m
->hash
, &hi
, true);
779 while ((he
= hash_iterator_next (&hi
)))
781 struct gc_arena gc
= gc_new ();
782 const struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
786 status_printf (so
, "CLIENT_LIST,%s,%s,%s," counter_format
"," counter_format
",%s,%u",
787 tls_common_name (mi
->context
.c2
.tls_multi
, false),
788 mroute_addr_print (&mi
->real
, &gc
),
789 print_in_addr_t (mi
->reporting_addr
, IA_EMPTY_IF_UNDEF
, &gc
),
790 mi
->context
.c2
.link_read_bytes
,
791 mi
->context
.c2
.link_write_bytes
,
792 time_string (mi
->created
, 0, false, &gc
),
793 (unsigned int)mi
->created
);
797 hash_iterator_free (&hi
);
799 status_printf (so
, "HEADER,ROUTING_TABLE,Virtual Address,Common Name,Real Address,Last Ref,Last Ref (time_t)");
800 hash_iterator_init (m
->vhash
, &hi
, true);
801 while ((he
= hash_iterator_next (&hi
)))
803 struct gc_arena gc
= gc_new ();
804 const struct multi_route
*route
= (struct multi_route
*) he
->value
;
806 if (multi_route_defined (m
, route
))
808 const struct multi_instance
*mi
= route
->instance
;
809 const struct mroute_addr
*ma
= &route
->addr
;
810 char flags
[2] = {0, 0};
812 if (route
->flags
& MULTI_ROUTE_CACHE
)
814 status_printf (so
, "ROUTING_TABLE,%s%s,%s,%s,%s,%u",
815 mroute_addr_print (ma
, &gc
),
817 tls_common_name (mi
->context
.c2
.tls_multi
, false),
818 mroute_addr_print (&mi
->real
, &gc
),
819 time_string (route
->last_reference
, 0, false, &gc
),
820 (unsigned int)route
->last_reference
);
824 hash_iterator_free (&hi
);
827 status_printf (so
, "GLOBAL_STATS,Max bcast/mcast queue length,%d",
828 mbuf_maximum_queued (m
->mbuf
));
830 status_printf (so
, "END");
834 status_printf (so
, "ERROR: bad status format version number");
837 #ifdef PACKET_TRUNCATION_CHECK
839 status_printf (so
, "HEADER,ERRORS,Common Name,TUN Read Trunc,TUN Write Trunc,Pre-encrypt Trunc,Post-decrypt Trunc");
840 hash_iterator_init (m
->hash
, &hi
, true);
841 while ((he
= hash_iterator_next (&hi
)))
843 struct gc_arena gc
= gc_new ();
844 const struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
848 status_printf (so
, "ERRORS,%s," counter_format
"," counter_format
"," counter_format
"," counter_format
,
849 tls_common_name (mi
->context
.c2
.tls_multi
, false),
850 m
->top
.c2
.n_trunc_tun_read
,
851 mi
->context
.c2
.n_trunc_tun_write
,
852 mi
->context
.c2
.n_trunc_pre_encrypt
,
853 mi
->context
.c2
.n_trunc_post_decrypt
);
857 hash_iterator_free (&hi
);
867 * Learn a virtual address or route.
868 * The learn will fail if the learn address
869 * script/plugin fails. In this case the
870 * return value may be != mi.
871 * Return the instance which owns this route,
874 static struct multi_instance
*
875 multi_learn_addr (struct multi_context
*m
,
876 struct multi_instance
*mi
,
877 const struct mroute_addr
*addr
,
878 const unsigned int flags
)
880 struct hash_element
*he
;
881 const uint32_t hv
= hash_value (m
->vhash
, addr
);
882 struct hash_bucket
*bucket
= hash_bucket (m
->vhash
, hv
);
883 struct multi_route
*oldroute
= NULL
;
884 struct multi_instance
*owner
= NULL
;
886 hash_bucket_lock (bucket
);
888 /* if route currently exists, get the instance which owns it */
889 he
= hash_lookup_fast (m
->vhash
, bucket
, addr
, hv
);
891 oldroute
= (struct multi_route
*) he
->value
;
892 if (oldroute
&& multi_route_defined (m
, oldroute
))
893 owner
= oldroute
->instance
;
895 /* do we need to add address to hash table? */
896 if ((!owner
|| owner
!= mi
)
897 && mroute_learnable_address (addr
)
898 && !mroute_addr_equal (addr
, &m
->local
))
900 struct gc_arena gc
= gc_new ();
901 struct multi_route
*newroute
;
902 bool learn_succeeded
= false;
904 ALLOC_OBJ (newroute
, struct multi_route
);
905 newroute
->addr
= *addr
;
906 newroute
->instance
= mi
;
907 newroute
->flags
= flags
;
908 newroute
->last_reference
= now
;
909 newroute
->cache_generation
= 0;
911 /* The cache is invalidated when cache_generation is incremented */
912 if (flags
& MULTI_ROUTE_CACHE
)
913 newroute
->cache_generation
= m
->route_helper
->cache_generation
;
915 if (oldroute
) /* route already exists? */
917 if (route_quota_test (m
, mi
) && learn_address_script (m
, mi
, "update", &newroute
->addr
))
919 learn_succeeded
= true;
921 multi_instance_inc_refcount (mi
);
922 route_quota_inc (mi
);
924 /* delete old route */
925 multi_route_del (oldroute
);
927 /* modify hash table entry, replacing old route */
928 he
->key
= &newroute
->addr
;
929 he
->value
= newroute
;
934 if (route_quota_test (m
, mi
) && learn_address_script (m
, mi
, "add", &newroute
->addr
))
936 learn_succeeded
= true;
938 multi_instance_inc_refcount (mi
);
939 route_quota_inc (mi
);
942 hash_add_fast (m
->vhash
, bucket
, &newroute
->addr
, hv
, newroute
);
946 msg (D_MULTI_LOW
, "MULTI: Learn%s: %s -> %s",
947 learn_succeeded
? "" : " FAILED",
948 mroute_addr_print (&newroute
->addr
, &gc
),
949 multi_instance_string (mi
, false, &gc
));
951 if (!learn_succeeded
)
957 hash_bucket_unlock (bucket
);
962 * Get client instance based on virtual address.
964 static struct multi_instance
*
965 multi_get_instance_by_virtual_addr (struct multi_context
*m
,
966 const struct mroute_addr
*addr
,
969 struct multi_route
*route
;
970 struct multi_instance
*ret
= NULL
;
972 /* check for local address */
973 if (mroute_addr_equal (addr
, &m
->local
))
976 route
= (struct multi_route
*) hash_lookup (m
->vhash
, addr
);
978 /* does host route (possible cached) exist? */
979 if (route
&& multi_route_defined (m
, route
))
981 struct multi_instance
*mi
= route
->instance
;
982 route
->last_reference
= now
;
985 else if (cidr_routing
) /* do we need to regenerate a host route cache entry? */
987 struct mroute_helper
*rh
= m
->route_helper
;
988 struct mroute_addr tryaddr
;
991 mroute_helper_lock (rh
);
993 /* cycle through each CIDR length */
994 for (i
= 0; i
< rh
->n_net_len
; ++i
)
997 tryaddr
.type
|= MR_WITH_NETBITS
;
998 tryaddr
.netbits
= rh
->net_len
[i
];
999 mroute_addr_mask_host_bits (&tryaddr
);
1001 /* look up a possible route with netbits netmask */
1002 route
= (struct multi_route
*) hash_lookup (m
->vhash
, &tryaddr
);
1004 if (route
&& multi_route_defined (m
, route
))
1006 /* found an applicable route, cache host route */
1007 struct multi_instance
*mi
= route
->instance
;
1008 multi_learn_addr (m
, mi
, addr
, MULTI_ROUTE_CACHE
|MULTI_ROUTE_AGEABLE
);
1014 mroute_helper_unlock (rh
);
1018 if (check_debug_level (D_MULTI_DEBUG
))
1020 struct gc_arena gc
= gc_new ();
1021 const char *addr_text
= mroute_addr_print (addr
, &gc
);
1024 dmsg (D_MULTI_DEBUG
, "GET INST BY VIRT: %s -> %s via %s",
1026 multi_instance_string (ret
, false, &gc
),
1027 mroute_addr_print (&route
->addr
, &gc
));
1031 dmsg (D_MULTI_DEBUG
, "GET INST BY VIRT: %s [failed]",
1038 ASSERT (!(ret
&& ret
->halt
));
1043 * Helper function to multi_learn_addr().
1045 static struct multi_instance
*
1046 multi_learn_in_addr_t (struct multi_context
*m
,
1047 struct multi_instance
*mi
,
1049 int netbits
, /* -1 if host route, otherwise # of network bits in address */
1052 struct openvpn_sockaddr remote_si
;
1053 struct mroute_addr addr
;
1056 remote_si
.sa
.sin_family
= AF_INET
;
1057 remote_si
.sa
.sin_addr
.s_addr
= htonl (a
);
1058 ASSERT (mroute_extract_openvpn_sockaddr (&addr
, &remote_si
, false));
1062 addr
.type
|= MR_WITH_NETBITS
;
1063 addr
.netbits
= (uint8_t) netbits
;
1067 struct multi_instance
*owner
= multi_learn_addr (m
, mi
, &addr
, 0);
1068 #ifdef MANAGEMENT_DEF_AUTH
1069 if (management
&& owner
)
1070 management_learn_addr (management
, &mi
->context
.c2
.mda_context
, &addr
, primary
);
1077 * A new client has connected, add routes (server -> client)
1078 * to internal routing table.
1081 multi_add_iroutes (struct multi_context
*m
,
1082 struct multi_instance
*mi
)
1084 struct gc_arena gc
= gc_new ();
1085 const struct iroute
*ir
;
1086 if (TUNNEL_TYPE (mi
->context
.c1
.tuntap
) == DEV_TYPE_TUN
)
1088 mi
->did_iroutes
= true;
1089 for (ir
= mi
->context
.options
.iroutes
; ir
!= NULL
; ir
= ir
->next
)
1091 if (ir
->netbits
>= 0)
1092 msg (D_MULTI_LOW
, "MULTI: internal route %s/%d -> %s",
1093 print_in_addr_t (ir
->network
, 0, &gc
),
1095 multi_instance_string (mi
, false, &gc
));
1097 msg (D_MULTI_LOW
, "MULTI: internal route %s -> %s",
1098 print_in_addr_t (ir
->network
, 0, &gc
),
1099 multi_instance_string (mi
, false, &gc
));
1101 mroute_helper_add_iroute (m
->route_helper
, ir
);
1103 multi_learn_in_addr_t (m
, mi
, ir
->network
, ir
->netbits
, false);
1110 * Given an instance (new_mi), delete all other instances which use the
1114 multi_delete_dup (struct multi_context
*m
, struct multi_instance
*new_mi
)
1118 const char *new_cn
= tls_common_name (new_mi
->context
.c2
.tls_multi
, true);
1121 struct hash_iterator hi
;
1122 struct hash_element
*he
;
1125 hash_iterator_init (m
->iter
, &hi
, true);
1126 while ((he
= hash_iterator_next (&hi
)))
1128 struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
1129 if (mi
!= new_mi
&& !mi
->halt
)
1131 const char *cn
= tls_common_name (mi
->context
.c2
.tls_multi
, true);
1132 if (cn
&& !strcmp (cn
, new_cn
))
1134 mi
->did_iter
= false;
1135 multi_close_instance (m
, mi
, false);
1136 hash_iterator_delete_element (&hi
);
1141 hash_iterator_free (&hi
);
1144 msg (D_MULTI_LOW
, "MULTI: new connection by client '%s' will cause previous active sessions by this client to be dropped. Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.", new_cn
);
1150 * Ensure that endpoint to be pushed to client
1151 * complies with --ifconfig-push-constraint directive.
1154 ifconfig_push_constraint_satisfied (const struct context
*c
)
1156 const struct options
*o
= &c
->options
;
1157 if (o
->push_ifconfig_constraint_defined
&& c
->c2
.push_ifconfig_defined
)
1158 return (o
->push_ifconfig_constraint_netmask
& c
->c2
.push_ifconfig_local
) == o
->push_ifconfig_constraint_network
;
1164 * Select a virtual address for a new client instance.
1165 * Use an --ifconfig-push directive, if given (static IP).
1166 * Otherwise use an --ifconfig-pool address (dynamic IP).
1169 multi_select_virtual_addr (struct multi_context
*m
, struct multi_instance
*mi
)
1171 struct gc_arena gc
= gc_new ();
1174 * If ifconfig addresses were set by dynamic config file,
1175 * release pool addresses, otherwise keep them.
1177 if (mi
->context
.options
.push_ifconfig_defined
)
1179 /* ifconfig addresses were set statically,
1180 release dynamic allocation */
1181 if (mi
->vaddr_handle
>= 0)
1183 ifconfig_pool_release (m
->ifconfig_pool
, mi
->vaddr_handle
, true);
1184 mi
->vaddr_handle
= -1;
1187 mi
->context
.c2
.push_ifconfig_defined
= true;
1188 mi
->context
.c2
.push_ifconfig_local
= mi
->context
.options
.push_ifconfig_local
;
1189 mi
->context
.c2
.push_ifconfig_remote_netmask
= mi
->context
.options
.push_ifconfig_remote_netmask
;
1191 else if (m
->ifconfig_pool
&& mi
->vaddr_handle
< 0) /* otherwise, choose a pool address */
1193 in_addr_t local
=0, remote
=0;
1194 const char *cn
= NULL
;
1196 if (!mi
->context
.options
.duplicate_cn
)
1197 cn
= tls_common_name (mi
->context
.c2
.tls_multi
, true);
1199 mi
->vaddr_handle
= ifconfig_pool_acquire (m
->ifconfig_pool
, &local
, &remote
, cn
);
1200 if (mi
->vaddr_handle
>= 0)
1202 const int tunnel_type
= TUNNEL_TYPE (mi
->context
.c1
.tuntap
);
1203 const int tunnel_topology
= TUNNEL_TOPOLOGY (mi
->context
.c1
.tuntap
);
1205 /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
1206 mi
->context
.c2
.push_ifconfig_local
= remote
;
1207 if (tunnel_type
== DEV_TYPE_TAP
|| (tunnel_type
== DEV_TYPE_TUN
&& tunnel_topology
== TOP_SUBNET
))
1209 mi
->context
.c2
.push_ifconfig_remote_netmask
= mi
->context
.options
.ifconfig_pool_netmask
;
1210 if (!mi
->context
.c2
.push_ifconfig_remote_netmask
)
1211 mi
->context
.c2
.push_ifconfig_remote_netmask
= mi
->context
.c1
.tuntap
->remote_netmask
;
1213 else if (tunnel_type
== DEV_TYPE_TUN
)
1215 if (tunnel_topology
== TOP_P2P
)
1216 mi
->context
.c2
.push_ifconfig_remote_netmask
= mi
->context
.c1
.tuntap
->local
;
1217 else if (tunnel_topology
== TOP_NET30
)
1218 mi
->context
.c2
.push_ifconfig_remote_netmask
= local
;
1221 if (mi
->context
.c2
.push_ifconfig_remote_netmask
)
1222 mi
->context
.c2
.push_ifconfig_defined
= true;
1224 msg (D_MULTI_ERRORS
, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
1225 multi_instance_string (mi
, false, &gc
));
1229 msg (D_MULTI_ERRORS
, "MULTI: no free --ifconfig-pool addresses are available");
1236 * Set virtual address environmental variables.
1239 multi_set_virtual_addr_env (struct multi_context
*m
, struct multi_instance
*mi
)
1241 setenv_del (mi
->context
.c2
.es
, "ifconfig_pool_local_ip");
1242 setenv_del (mi
->context
.c2
.es
, "ifconfig_pool_remote_ip");
1243 setenv_del (mi
->context
.c2
.es
, "ifconfig_pool_netmask");
1245 if (mi
->context
.c2
.push_ifconfig_defined
)
1247 const int tunnel_type
= TUNNEL_TYPE (mi
->context
.c1
.tuntap
);
1248 const int tunnel_topology
= TUNNEL_TOPOLOGY (mi
->context
.c1
.tuntap
);
1250 setenv_in_addr_t (mi
->context
.c2
.es
,
1251 "ifconfig_pool_remote_ip",
1252 mi
->context
.c2
.push_ifconfig_local
,
1255 if (tunnel_type
== DEV_TYPE_TAP
|| (tunnel_type
== DEV_TYPE_TUN
&& tunnel_topology
== TOP_SUBNET
))
1257 setenv_in_addr_t (mi
->context
.c2
.es
,
1258 "ifconfig_pool_netmask",
1259 mi
->context
.c2
.push_ifconfig_remote_netmask
,
1262 else if (tunnel_type
== DEV_TYPE_TUN
)
1264 setenv_in_addr_t (mi
->context
.c2
.es
,
1265 "ifconfig_pool_local_ip",
1266 mi
->context
.c2
.push_ifconfig_remote_netmask
,
1273 * Called after client-connect script is called
1276 multi_client_connect_post (struct multi_context
*m
,
1277 struct multi_instance
*mi
,
1278 const char *dc_file
,
1279 unsigned int option_permissions_mask
,
1280 unsigned int *option_types_found
)
1282 /* Did script generate a dynamic config file? */
1283 if (test_file (dc_file
))
1285 options_server_import (&mi
->context
.options
,
1287 D_IMPORT_ERRORS
|M_OPTERR
,
1288 option_permissions_mask
,
1292 if (!delete_file (dc_file
))
1293 msg (D_MULTI_ERRORS
, "MULTI: problem deleting temporary file: %s",
1297 * If the --client-connect script generates a config file
1298 * with an --ifconfig-push directive, it will override any
1299 * --ifconfig-push directive from the --client-config-dir
1300 * directory or any --ifconfig-pool dynamic address.
1302 multi_select_virtual_addr (m
, mi
);
1303 multi_set_virtual_addr_env (m
, mi
);
1307 #ifdef ENABLE_PLUGIN
1310 * Called after client-connect plug-in is called
1313 multi_client_connect_post_plugin (struct multi_context
*m
,
1314 struct multi_instance
*mi
,
1315 const struct plugin_return
*pr
,
1316 unsigned int option_permissions_mask
,
1317 unsigned int *option_types_found
)
1319 struct plugin_return config
;
1321 plugin_return_get_column (pr
, &config
, "config");
1323 /* Did script generate a dynamic config file? */
1324 if (plugin_return_defined (&config
))
1327 for (i
= 0; i
< config
.n
; ++i
)
1329 if (config
.list
[i
] && config
.list
[i
]->value
)
1330 options_string_import (&mi
->context
.options
,
1331 config
.list
[i
]->value
,
1332 D_IMPORT_ERRORS
|M_OPTERR
,
1333 option_permissions_mask
,
1339 * If the --client-connect script generates a config file
1340 * with an --ifconfig-push directive, it will override any
1341 * --ifconfig-push directive from the --client-config-dir
1342 * directory or any --ifconfig-pool dynamic address.
1344 multi_select_virtual_addr (m
, mi
);
1345 multi_set_virtual_addr_env (m
, mi
);
1351 #ifdef MANAGEMENT_DEF_AUTH
1354 * Called to load management-derived client-connect config
1357 multi_client_connect_mda (struct multi_context
*m
,
1358 struct multi_instance
*mi
,
1359 const struct buffer_list
*config
,
1360 unsigned int option_permissions_mask
,
1361 unsigned int *option_types_found
)
1365 struct buffer_entry
*be
;
1367 for (be
= config
->head
; be
!= NULL
; be
= be
->next
)
1369 const char *opt
= BSTR(&be
->buf
);
1370 options_string_import (&mi
->context
.options
,
1372 D_IMPORT_ERRORS
|M_OPTERR
,
1373 option_permissions_mask
,
1379 * If the --client-connect script generates a config file
1380 * with an --ifconfig-push directive, it will override any
1381 * --ifconfig-push directive from the --client-config-dir
1382 * directory or any --ifconfig-pool dynamic address.
1384 multi_select_virtual_addr (m
, mi
);
1385 multi_set_virtual_addr_env (m
, mi
);
1392 multi_client_connect_setenv (struct multi_context
*m
,
1393 struct multi_instance
*mi
)
1395 struct gc_arena gc
= gc_new ();
1397 /* setenv incoming cert common name for script */
1398 setenv_str (mi
->context
.c2
.es
, "common_name", tls_common_name (mi
->context
.c2
.tls_multi
, true));
1400 /* setenv client real IP address */
1401 setenv_trusted (mi
->context
.c2
.es
, get_link_socket_info (&mi
->context
));
1403 /* setenv client virtual IP address */
1404 multi_set_virtual_addr_env (m
, mi
);
1406 /* setenv connection time */
1408 const char *created_ascii
= time_string (mi
->created
, 0, false, &gc
);
1409 setenv_str (mi
->context
.c2
.es
, "time_ascii", created_ascii
);
1410 setenv_unsigned (mi
->context
.c2
.es
, "time_unix", (unsigned int)mi
->created
);
1417 * Called as soon as the SSL/TLS connection authenticates.
1419 * Instance-specific directives to be processed:
1421 * iroute start-ip end-ip
1422 * ifconfig-push local remote-netmask
1426 multi_connection_established (struct multi_context
*m
, struct multi_instance
*mi
)
1428 if (tls_authentication_status (mi
->context
.c2
.tls_multi
, 0) == TLS_AUTHENTICATION_SUCCEEDED
)
1430 struct gc_arena gc
= gc_new ();
1431 unsigned int option_types_found
= 0;
1433 const unsigned int option_permissions_mask
=
1443 int cc_succeeded
= true; /* client connect script status */
1444 int cc_succeeded_count
= 0;
1446 ASSERT (mi
->context
.c1
.tuntap
);
1448 /* lock down the common name so it can't change during future TLS renegotiations */
1449 tls_lock_common_name (mi
->context
.c2
.tls_multi
);
1451 /* generate a msg() prefix for this client instance */
1452 generate_prefix (mi
);
1454 /* delete instances of previous clients with same common-name */
1455 if (!mi
->context
.options
.duplicate_cn
)
1456 multi_delete_dup (m
, mi
);
1458 /* reset pool handle to null */
1459 mi
->vaddr_handle
= -1;
1462 * Try to source a dynamic config file from the
1463 * --client-config-dir directory.
1465 if (mi
->context
.options
.client_config_dir
)
1467 const char *ccd_file
;
1469 ccd_file
= gen_path (mi
->context
.options
.client_config_dir
,
1470 tls_common_name (mi
->context
.c2
.tls_multi
, false),
1473 /* try common-name file */
1474 if (test_file (ccd_file
))
1476 options_server_import (&mi
->context
.options
,
1478 D_IMPORT_ERRORS
|M_OPTERR
,
1479 option_permissions_mask
,
1480 &option_types_found
,
1483 else /* try default file */
1485 ccd_file
= gen_path (mi
->context
.options
.client_config_dir
,
1489 if (test_file (ccd_file
))
1491 options_server_import (&mi
->context
.options
,
1493 D_IMPORT_ERRORS
|M_OPTERR
,
1494 option_permissions_mask
,
1495 &option_types_found
,
1502 * Select a virtual address from either --ifconfig-push in --client-config-dir file
1503 * or --ifconfig-pool.
1505 multi_select_virtual_addr (m
, mi
);
1507 /* do --client-connect setenvs */
1508 multi_client_connect_setenv (m
, mi
);
1510 #ifdef ENABLE_PLUGIN
1512 * Call client-connect plug-in.
1515 /* deprecated callback, use a file for passing back return info */
1516 if (plugin_defined (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_CONNECT
))
1518 struct argv argv
= argv_new ();
1519 const char *dc_file
= create_temp_filename (mi
->context
.options
.tmp_dir
, "cc", &gc
);
1520 argv_printf (&argv
, "%s", dc_file
);
1521 delete_file (dc_file
);
1522 if (plugin_call (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_CONNECT
, &argv
, NULL
, mi
->context
.c2
.es
) != OPENVPN_PLUGIN_FUNC_SUCCESS
)
1524 msg (M_WARN
, "WARNING: client-connect plugin call failed");
1525 cc_succeeded
= false;
1529 multi_client_connect_post (m
, mi
, dc_file
, option_permissions_mask
, &option_types_found
);
1530 ++cc_succeeded_count
;
1535 /* V2 callback, use a plugin_return struct for passing back return info */
1536 if (plugin_defined (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_CONNECT_V2
))
1538 struct plugin_return pr
;
1540 plugin_return_init (&pr
);
1542 if (plugin_call (mi
->context
.plugins
, OPENVPN_PLUGIN_CLIENT_CONNECT_V2
, NULL
, &pr
, mi
->context
.c2
.es
) != OPENVPN_PLUGIN_FUNC_SUCCESS
)
1544 msg (M_WARN
, "WARNING: client-connect-v2 plugin call failed");
1545 cc_succeeded
= false;
1549 multi_client_connect_post_plugin (m
, mi
, &pr
, option_permissions_mask
, &option_types_found
);
1550 ++cc_succeeded_count
;
1553 plugin_return_free (&pr
);
1558 * Run --client-connect script.
1560 if (mi
->context
.options
.client_connect_script
&& cc_succeeded
)
1562 struct argv argv
= argv_new ();
1563 const char *dc_file
= NULL
;
1565 setenv_str (mi
->context
.c2
.es
, "script_type", "client-connect");
1567 dc_file
= create_temp_filename (mi
->context
.options
.tmp_dir
, "cc", &gc
);
1569 delete_file (dc_file
);
1571 argv_printf (&argv
, "%sc %s",
1572 mi
->context
.options
.client_connect_script
,
1575 if (openvpn_execve_check (&argv
, mi
->context
.c2
.es
, S_SCRIPT
, "client-connect command failed"))
1577 multi_client_connect_post (m
, mi
, dc_file
, option_permissions_mask
, &option_types_found
);
1578 ++cc_succeeded_count
;
1581 cc_succeeded
= false;
1587 * Check for client-connect script left by management interface client
1589 #ifdef MANAGEMENT_DEF_AUTH
1590 if (cc_succeeded
&& mi
->cc_config
)
1592 multi_client_connect_mda (m
, mi
, mi
->cc_config
, option_permissions_mask
, &option_types_found
);
1593 ++cc_succeeded_count
;
1598 * Check for "disable" directive in client-config-dir file
1599 * or config file generated by --client-connect script.
1601 if (mi
->context
.options
.disable
)
1603 msg (D_MULTI_ERRORS
, "MULTI: client has been rejected due to 'disable' directive");
1604 cc_succeeded
= false;
1610 * Process sourced options.
1612 do_deferred_options (&mi
->context
, option_types_found
);
1615 * make sure we got ifconfig settings from somewhere
1617 if (!mi
->context
.c2
.push_ifconfig_defined
)
1619 msg (D_MULTI_ERRORS
, "MULTI: no dynamic or static remote --ifconfig address is available for %s",
1620 multi_instance_string (mi
, false, &gc
));
1624 * make sure that ifconfig settings comply with constraints
1626 if (!ifconfig_push_constraint_satisfied (&mi
->context
))
1628 /* JYFIXME -- this should cause the connection to fail */
1629 msg (D_MULTI_ERRORS
, "MULTI ERROR: primary virtual IP for %s (%s) violates tunnel network/netmask constraint (%s/%s)",
1630 multi_instance_string (mi
, false, &gc
),
1631 print_in_addr_t (mi
->context
.c2
.push_ifconfig_local
, 0, &gc
),
1632 print_in_addr_t (mi
->context
.options
.push_ifconfig_constraint_network
, 0, &gc
),
1633 print_in_addr_t (mi
->context
.options
.push_ifconfig_constraint_netmask
, 0, &gc
));
1637 * For routed tunnels, set up internal route to endpoint
1638 * plus add all iroute routes.
1640 if (TUNNEL_TYPE (mi
->context
.c1
.tuntap
) == DEV_TYPE_TUN
)
1642 if (mi
->context
.c2
.push_ifconfig_defined
)
1644 multi_learn_in_addr_t (m
, mi
, mi
->context
.c2
.push_ifconfig_local
, -1, true);
1645 msg (D_MULTI_LOW
, "MULTI: primary virtual IP for %s: %s",
1646 multi_instance_string (mi
, false, &gc
),
1647 print_in_addr_t (mi
->context
.c2
.push_ifconfig_local
, 0, &gc
));
1650 /* add routes locally, pointing to new client, if
1651 --iroute options have been specified */
1652 multi_add_iroutes (m
, mi
);
1655 * iroutes represent subnets which are "owned" by a particular
1656 * client. Therefore, do not actually push a route to a client
1657 * if it matches one of the client's iroutes.
1659 remove_iroutes_from_push_route_list (&mi
->context
.options
);
1661 else if (mi
->context
.options
.iroutes
)
1663 msg (D_MULTI_ERRORS
, "MULTI: --iroute options rejected for %s -- iroute only works with tun-style tunnels",
1664 multi_instance_string (mi
, false, &gc
));
1667 /* set our client's VPN endpoint for status reporting purposes */
1668 mi
->reporting_addr
= mi
->context
.c2
.push_ifconfig_local
;
1670 /* set context-level authentication flag */
1671 mi
->context
.c2
.context_auth
= CAS_SUCCEEDED
;
1675 /* set context-level authentication flag */
1676 mi
->context
.c2
.context_auth
= cc_succeeded_count
? CAS_PARTIAL
: CAS_FAILED
;
1679 /* set flag so we don't get called again */
1680 mi
->connection_established_flag
= true;
1682 #ifdef MANAGEMENT_DEF_AUTH
1684 management_connection_established (management
, &mi
->context
.c2
.mda_context
);
1691 * Reply now to client's PUSH_REQUEST query
1693 mi
->context
.c2
.push_reply_deferred
= false;
1697 * Add a mbuf buffer to a particular
1701 multi_add_mbuf (struct multi_context
*m
,
1702 struct multi_instance
*mi
,
1703 struct mbuf_buffer
*mb
)
1705 if (multi_output_queue_ready (m
, mi
))
1707 struct mbuf_item item
;
1710 mbuf_add_item (m
->mbuf
, &item
);
1714 msg (D_MULTI_DROPPED
, "MULTI: packet dropped due to output saturation (multi_add_mbuf)");
1719 * Add a packet to a client instance output queue.
1722 multi_unicast (struct multi_context
*m
,
1723 const struct buffer
*buf
,
1724 struct multi_instance
*mi
)
1726 struct mbuf_buffer
*mb
;
1730 mb
= mbuf_alloc_buf (buf
);
1731 mb
->flags
= MF_UNICAST
;
1732 multi_add_mbuf (m
, mi
, mb
);
1738 * Broadcast a packet to all clients.
1741 multi_bcast (struct multi_context
*m
,
1742 const struct buffer
*buf
,
1743 const struct multi_instance
*sender_instance
,
1744 const struct mroute_addr
*sender_addr
)
1746 struct hash_iterator hi
;
1747 struct hash_element
*he
;
1748 struct multi_instance
*mi
;
1749 struct mbuf_buffer
*mb
;
1753 perf_push (PERF_MULTI_BCAST
);
1754 #ifdef MULTI_DEBUG_EVENT_LOOP
1755 printf ("BCAST len=%d\n", BLEN (buf
));
1757 mb
= mbuf_alloc_buf (buf
);
1758 hash_iterator_init (m
->iter
, &hi
, true);
1760 while ((he
= hash_iterator_next (&hi
)))
1762 mi
= (struct multi_instance
*) he
->value
;
1763 if (mi
!= sender_instance
&& !mi
->halt
)
1766 if (sender_instance
)
1768 if (!pf_c2c_test (&sender_instance
->context
, &mi
->context
, "bcast_c2c"))
1770 msg (D_PF_DROPPED_BCAST
, "PF: client[%s] -> client[%s] packet dropped by BCAST packet filter",
1771 mi_prefix (sender_instance
),
1778 if (!pf_addr_test (&mi
->context
, sender_addr
, "bcast_src_addr"))
1780 struct gc_arena gc
= gc_new ();
1781 msg (D_PF_DROPPED_BCAST
, "PF: addr[%s] -> client[%s] packet dropped by BCAST packet filter",
1782 mroute_addr_print_ex (sender_addr
, MAPF_SHOW_ARP
, &gc
),
1789 multi_add_mbuf (m
, mi
, mb
);
1793 hash_iterator_free (&hi
);
1800 * Given a time delta, indicating that we wish to be
1801 * awoken by the scheduler at time now + delta, figure
1802 * a sigma parameter (in microseconds) that represents
1803 * a sort of fuzz factor around delta, so that we're
1804 * really telling the scheduler to wake us up any time
1805 * between now + delta - sigma and now + delta + sigma.
1807 * The sigma parameter helps the scheduler to run more efficiently.
1808 * Sigma should be no larger than TV_WITHIN_SIGMA_MAX_USEC
1810 static inline unsigned int
1811 compute_wakeup_sigma (const struct timeval
*delta
)
1813 if (delta
->tv_sec
< 1)
1815 /* if < 1 sec, fuzz = # of microseconds / 8 */
1816 return delta
->tv_usec
>> 3;
1820 /* if < 10 minutes, fuzz = 13.1% of timeout */
1821 if (delta
->tv_sec
< 600)
1822 return delta
->tv_sec
<< 17;
1824 return 120000000; /* if >= 10 minutes, fuzz = 2 minutes */
1829 * Figure instance-specific timers, convert
1830 * earliest to absolute time in mi->wakeup,
1831 * call scheduler with our future wakeup time.
1833 * Also close context on signal.
1836 multi_process_post (struct multi_context
*m
, struct multi_instance
*mi
, const unsigned int flags
)
1840 if (!IS_SIG (&mi
->context
) && ((flags
& MPP_PRE_SELECT
) || ((flags
& MPP_CONDITIONAL_PRE_SELECT
) && !ANY_OUT (&mi
->context
))))
1842 /* figure timeouts and fetch possible outgoing
1843 to_link packets (such as ping or TLS control) */
1844 pre_select (&mi
->context
);
1846 if (!IS_SIG (&mi
->context
))
1848 /* calculate an absolute wakeup time */
1849 ASSERT (!openvpn_gettimeofday (&mi
->wakeup
, NULL
));
1850 tv_add (&mi
->wakeup
, &mi
->context
.c2
.timeval
);
1852 /* tell scheduler to wake us up at some point in the future */
1853 schedule_add_entry (m
->schedule
,
1854 (struct schedule_entry
*) mi
,
1856 compute_wakeup_sigma (&mi
->context
.c2
.timeval
));
1858 /* connection is "established" when SSL/TLS key negotiation succeeds
1859 and (if specified) auth user/pass succeeds */
1860 if (!mi
->connection_established_flag
&& CONNECTION_ESTABLISHED (&mi
->context
))
1861 multi_connection_established (m
, mi
);
1865 if (IS_SIG (&mi
->context
))
1867 if (flags
& MPP_CLOSE_ON_SIGNAL
)
1869 multi_close_instance_on_signal (m
, mi
);
1875 /* continue to pend on output? */
1876 multi_set_pending (m
, ANY_OUT (&mi
->context
) ? mi
: NULL
);
1878 #ifdef MULTI_DEBUG_EVENT_LOOP
1879 printf ("POST %s[%d] to=%d lo=%d/%d w=%d/%d\n",
1881 (int) (mi
== m
->pending
),
1882 mi
? mi
->context
.c2
.to_tun
.len
: -1,
1883 mi
? mi
->context
.c2
.to_link
.len
: -1,
1884 (mi
&& mi
->context
.c2
.fragment
) ? mi
->context
.c2
.fragment
->outgoing
.len
: -1,
1885 (int)mi
->context
.c2
.timeval
.tv_sec
,
1886 (int)mi
->context
.c2
.timeval
.tv_usec
);
1890 if ((flags
& MPP_RECORD_TOUCH
) && m
->mpp_touched
)
1891 *m
->mpp_touched
= mi
;
1897 * Process packets in the TCP/UDP socket -> TUN/TAP interface direction,
1898 * i.e. client -> server direction.
1901 multi_process_incoming_link (struct multi_context
*m
, struct multi_instance
*instance
, const unsigned int mpp_flags
)
1903 struct gc_arena gc
= gc_new ();
1906 struct mroute_addr src
, dest
;
1907 unsigned int mroute_flags
;
1908 struct multi_instance
*mi
;
1916 #ifdef MULTI_DEBUG_EVENT_LOOP
1917 printf ("TCP/UDP -> TUN [%d]\n", BLEN (&m
->top
.c2
.buf
));
1919 multi_set_pending (m
, multi_get_create_instance_udp (m
));
1922 multi_set_pending (m
, instance
);
1926 set_prefix (m
->pending
);
1928 /* get instance context */
1929 c
= &m
->pending
->context
;
1933 /* transfer packet pointer from top-level context buffer to instance */
1934 c
->c2
.buf
= m
->top
.c2
.buf
;
1936 /* transfer from-addr from top-level context buffer to instance */
1937 c
->c2
.from
= m
->top
.c2
.from
;
1940 if (BLEN (&c
->c2
.buf
) > 0)
1942 /* decrypt in instance context */
1943 process_incoming_link (c
);
1945 if (TUNNEL_TYPE (m
->top
.c1
.tuntap
) == DEV_TYPE_TUN
)
1947 /* extract packet source and dest addresses */
1948 mroute_flags
= mroute_extract_addr_from_packet (&src
,
1955 /* drop packet if extract failed */
1956 if (!(mroute_flags
& MROUTE_EXTRACT_SUCCEEDED
))
1958 c
->c2
.to_tun
.len
= 0;
1960 /* make sure that source address is associated with this client */
1961 else if (multi_get_instance_by_virtual_addr (m
, &src
, true) != m
->pending
)
1963 msg (D_MULTI_DROPPED
, "MULTI: bad source address from client [%s], packet dropped",
1964 mroute_addr_print (&src
, &gc
));
1965 c
->c2
.to_tun
.len
= 0;
1967 /* client-to-client communication enabled? */
1968 else if (m
->enable_c2c
)
1971 if (mroute_flags
& MROUTE_EXTRACT_MCAST
)
1973 /* for now, treat multicast as broadcast */
1974 multi_bcast (m
, &c
->c2
.to_tun
, m
->pending
, NULL
);
1976 else /* possible client to client routing */
1978 ASSERT (!(mroute_flags
& MROUTE_EXTRACT_BCAST
));
1979 mi
= multi_get_instance_by_virtual_addr (m
, &dest
, true);
1981 /* if dest addr is a known client, route to it */
1985 if (!pf_c2c_test (c
, &mi
->context
, "tun_c2c"))
1987 msg (D_PF_DROPPED
, "PF: client -> client[%s] packet dropped by TUN packet filter",
1993 multi_unicast (m
, &c
->c2
.to_tun
, mi
);
1994 register_activity (c
, BLEN(&c
->c2
.to_tun
));
1996 c
->c2
.to_tun
.len
= 0;
2001 if (c
->c2
.to_tun
.len
&& !pf_addr_test (c
, &dest
, "tun_dest_addr"))
2003 msg (D_PF_DROPPED
, "PF: client -> addr[%s] packet dropped by TUN packet filter",
2004 mroute_addr_print_ex (&dest
, MAPF_SHOW_ARP
, &gc
));
2005 c
->c2
.to_tun
.len
= 0;
2009 else if (TUNNEL_TYPE (m
->top
.c1
.tuntap
) == DEV_TYPE_TAP
)
2012 struct mroute_addr edest
;
2013 mroute_addr_reset (&edest
);
2015 /* extract packet source and dest addresses */
2016 mroute_flags
= mroute_extract_addr_from_packet (&src
,
2027 if (mroute_flags
& MROUTE_EXTRACT_SUCCEEDED
)
2029 if (multi_learn_addr (m
, m
->pending
, &src
, 0) == m
->pending
)
2031 /* check for broadcast */
2034 if (mroute_flags
& (MROUTE_EXTRACT_BCAST
|MROUTE_EXTRACT_MCAST
))
2036 multi_bcast (m
, &c
->c2
.to_tun
, m
->pending
, NULL
);
2038 else /* try client-to-client routing */
2040 mi
= multi_get_instance_by_virtual_addr (m
, &dest
, false);
2042 /* if dest addr is a known client, route to it */
2046 if (!pf_c2c_test (c
, &mi
->context
, "tap_c2c"))
2048 msg (D_PF_DROPPED
, "PF: client -> client[%s] packet dropped by TAP packet filter",
2054 multi_unicast (m
, &c
->c2
.to_tun
, mi
);
2055 register_activity (c
, BLEN(&c
->c2
.to_tun
));
2057 c
->c2
.to_tun
.len
= 0;
2062 if (c
->c2
.to_tun
.len
&& !pf_addr_test (c
, &edest
, "tap_dest_addr"))
2064 msg (D_PF_DROPPED
, "PF: client -> addr[%s] packet dropped by TAP packet filter",
2065 mroute_addr_print_ex (&edest
, MAPF_SHOW_ARP
, &gc
));
2066 c
->c2
.to_tun
.len
= 0;
2072 msg (D_MULTI_DROPPED
, "MULTI: bad source address from client [%s], packet dropped",
2073 mroute_addr_print (&src
, &gc
));
2074 c
->c2
.to_tun
.len
= 0;
2079 c
->c2
.to_tun
.len
= 0;
2084 /* postprocess and set wakeup */
2085 ret
= multi_process_post (m
, m
->pending
, mpp_flags
);
2095 * Process packets in the TUN/TAP interface -> TCP/UDP socket direction,
2096 * i.e. server -> client direction.
2099 multi_process_incoming_tun (struct multi_context
*m
, const unsigned int mpp_flags
)
2101 struct gc_arena gc
= gc_new ();
2104 if (BLEN (&m
->top
.c2
.buf
) > 0)
2106 unsigned int mroute_flags
;
2107 struct mroute_addr src
, dest
;
2108 const int dev_type
= TUNNEL_TYPE (m
->top
.c1
.tuntap
);
2111 struct mroute_addr esrc
, *e1
, *e2
;
2112 if (dev_type
== DEV_TYPE_TUN
)
2120 mroute_addr_reset (&esrc
);
2124 #ifdef MULTI_DEBUG_EVENT_LOOP
2125 printf ("TUN -> TCP/UDP [%d]\n", BLEN (&m
->top
.c2
.buf
));
2132 * Route an incoming tun/tap packet to
2133 * the appropriate multi_instance object.
2136 mroute_flags
= mroute_extract_addr_from_packet (&src
,
2147 if (mroute_flags
& MROUTE_EXTRACT_SUCCEEDED
)
2151 /* broadcast or multicast dest addr? */
2152 if (mroute_flags
& (MROUTE_EXTRACT_BCAST
|MROUTE_EXTRACT_MCAST
))
2154 /* for now, treat multicast as broadcast */
2156 multi_bcast (m
, &m
->top
.c2
.buf
, NULL
, e2
);
2158 multi_bcast (m
, &m
->top
.c2
.buf
, NULL
, NULL
);
2163 multi_set_pending (m
, multi_get_instance_by_virtual_addr (m
, &dest
, dev_type
== DEV_TYPE_TUN
));
2167 /* get instance context */
2168 c
= &m
->pending
->context
;
2170 set_prefix (m
->pending
);
2173 if (!pf_addr_test (c
, e2
, "tun_tap_src_addr"))
2175 msg (D_PF_DROPPED
, "PF: addr[%s] -> client packet dropped by packet filter",
2176 mroute_addr_print_ex (&src
, MAPF_SHOW_ARP
, &gc
));
2177 buf_reset_len (&c
->c2
.buf
);
2182 if (multi_output_queue_ready (m
, m
->pending
))
2184 /* transfer packet pointer from top-level context buffer to instance */
2185 c
->c2
.buf
= m
->top
.c2
.buf
;
2190 msg (D_MULTI_DROPPED
, "MULTI: packet dropped due to output saturation (multi_process_incoming_tun)");
2191 buf_reset_len (&c
->c2
.buf
);
2195 /* encrypt in instance context */
2196 process_incoming_tun (c
);
2198 /* postprocess and set wakeup */
2199 ret
= multi_process_post (m
, m
->pending
, mpp_flags
);
2211 * Process a possible client-to-client/bcast/mcast message in the
2214 struct multi_instance
*
2215 multi_get_queue (struct mbuf_set
*ms
)
2217 struct mbuf_item item
;
2219 if (mbuf_extract_item (ms
, &item
, true)) /* cleartext IP packet */
2221 unsigned int pipv4_flags
= PIPV4_PASSTOS
;
2223 set_prefix (item
.instance
);
2224 item
.instance
->context
.c2
.buf
= item
.buffer
->buf
;
2225 if (item
.buffer
->flags
& MF_UNICAST
) /* --mssfix doesn't make sense for broadcast or multicast */
2226 pipv4_flags
|= PIPV4_MSSFIX
;
2227 process_ipv4_header (&item
.instance
->context
, pipv4_flags
, &item
.instance
->context
.c2
.buf
);
2228 encrypt_sign (&item
.instance
->context
, true);
2229 mbuf_free_buf (item
.buffer
);
2231 dmsg (D_MULTI_DEBUG
, "MULTI: C2C/MCAST/BCAST");
2234 return item
.instance
;
2243 * Called when an I/O wait times out. Usually means that a particular
2244 * client instance object needs timer-based service.
2247 multi_process_timeout (struct multi_context
*m
, const unsigned int mpp_flags
)
2251 #ifdef MULTI_DEBUG_EVENT_LOOP
2252 printf ("%s -> TIMEOUT\n", id(m
->earliest_wakeup
));
2255 /* instance marked for wakeup? */
2256 if (m
->earliest_wakeup
)
2258 set_prefix (m
->earliest_wakeup
);
2259 ret
= multi_process_post (m
, m
->earliest_wakeup
, mpp_flags
);
2260 m
->earliest_wakeup
= NULL
;
2267 * Drop a TUN/TAP outgoing packet..
2270 multi_process_drop_outgoing_tun (struct multi_context
*m
, const unsigned int mpp_flags
)
2272 struct multi_instance
*mi
= m
->pending
;
2278 msg (D_MULTI_ERRORS
, "MULTI: Outgoing TUN queue full, dropped packet len=%d",
2279 mi
->context
.c2
.to_tun
.len
);
2281 buf_reset (&mi
->context
.c2
.to_tun
);
2283 multi_process_post (m
, mi
, mpp_flags
);
2288 * Per-client route quota management
2292 route_quota_exceeded (const struct multi_context
*m
, const struct multi_instance
*mi
)
2294 struct gc_arena gc
= gc_new ();
2295 msg (D_ROUTE_QUOTA
, "MULTI ROUTE: route quota (%d) exceeded for %s (see --max-routes-per-client option)",
2296 mi
->context
.options
.max_routes_per_client
,
2297 multi_instance_string (mi
, false, &gc
));
2303 * Flood clients with random packets
2306 gremlin_flood_clients (struct multi_context
*m
)
2308 const int level
= GREMLIN_PACKET_FLOOD_LEVEL (m
->top
.options
.gremlin
);
2311 struct gc_arena gc
= gc_new ();
2312 struct buffer buf
= alloc_buf_gc (BUF_SIZE (&m
->top
.c2
.frame
), &gc
);
2313 struct packet_flood_parms parm
= get_packet_flood_parms (level
);
2316 ASSERT (buf_init (&buf
, FRAME_HEADROOM (&m
->top
.c2
.frame
)));
2317 parm
.packet_size
= min_int (parm
.packet_size
, MAX_RW_SIZE_TUN (&m
->top
.c2
.frame
));
2319 msg (D_GREMLIN
, "GREMLIN_FLOOD_CLIENTS: flooding clients with %d packets of size %d",
2323 for (i
= 0; i
< parm
.packet_size
; ++i
)
2324 ASSERT (buf_write_u8 (&buf
, get_random () & 0xFF));
2326 for (i
= 0; i
< parm
.n_packets
; ++i
)
2327 multi_bcast (m
, &buf
, NULL
, NULL
);
2335 * Process timers in the top-level context
2338 multi_process_per_second_timers_dowork (struct multi_context
*m
)
2340 /* possibly reap instances/routes in vhash */
2341 multi_reap_process (m
);
2343 /* possibly print to status log */
2344 if (m
->top
.c1
.status_output
)
2346 if (status_trigger (m
->top
.c1
.status_output
))
2347 multi_print_status (m
, m
->top
.c1
.status_output
, m
->status_file_version
);
2350 /* possibly flush ifconfig-pool file */
2351 multi_ifconfig_pool_persist (m
, false);
2354 gremlin_flood_clients (m
);
2359 multi_top_init (struct multi_context
*m
, const struct context
*top
, const bool alloc_buffers
)
2361 inherit_context_top (&m
->top
, top
);
2362 m
->top
.c2
.buffers
= NULL
;
2364 m
->top
.c2
.buffers
= init_context_buffers (&top
->c2
.frame
);
2368 multi_top_free (struct multi_context
*m
)
2370 close_context (&m
->top
, -1, CC_GC_FREE
);
2371 free_context_buffers (m
->top
.c2
.buffers
);
2375 * Return true if event loop should break,
2376 * false if it should continue.
2379 multi_process_signal (struct multi_context
*m
)
2381 if (m
->top
.sig
->signal_received
== SIGUSR2
)
2383 struct status_output
*so
= status_open (NULL
, 0, M_INFO
, NULL
, 0);
2384 multi_print_status (m
, so
, m
->status_file_version
);
2386 m
->top
.sig
->signal_received
= 0;
2393 * Called when an instance should be closed due to the
2394 * reception of a soft signal.
2397 multi_close_instance_on_signal (struct multi_context
*m
, struct multi_instance
*mi
)
2399 remap_signal (&mi
->context
);
2401 print_signal (mi
->context
.sig
, "client-instance", D_MULTI_LOW
);
2403 multi_close_instance (m
, mi
, false);
2407 multi_signal_instance (struct multi_context
*m
, struct multi_instance
*mi
, const int sig
)
2409 mi
->context
.sig
->signal_received
= sig
;
2410 multi_close_instance_on_signal (m
, mi
);
2414 * Management subsystem callbacks
2417 #ifdef ENABLE_MANAGEMENT
2420 management_callback_status (void *arg
, const int version
, struct status_output
*so
)
2422 struct multi_context
*m
= (struct multi_context
*) arg
;
2425 multi_print_status (m
, so
, m
->status_file_version
);
2427 multi_print_status (m
, so
, version
);
2431 management_callback_kill_by_cn (void *arg
, const char *del_cn
)
2433 struct multi_context
*m
= (struct multi_context
*) arg
;
2434 struct hash_iterator hi
;
2435 struct hash_element
*he
;
2438 hash_iterator_init (m
->iter
, &hi
, true);
2439 while ((he
= hash_iterator_next (&hi
)))
2441 struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
2444 const char *cn
= tls_common_name (mi
->context
.c2
.tls_multi
, false);
2445 if (cn
&& !strcmp (cn
, del_cn
))
2447 multi_signal_instance (m
, mi
, SIGTERM
);
2452 hash_iterator_free (&hi
);
2457 management_callback_kill_by_addr (void *arg
, const in_addr_t addr
, const int port
)
2459 struct multi_context
*m
= (struct multi_context
*) arg
;
2460 struct hash_iterator hi
;
2461 struct hash_element
*he
;
2462 struct openvpn_sockaddr saddr
;
2463 struct mroute_addr maddr
;
2467 saddr
.sa
.sin_family
= AF_INET
;
2468 saddr
.sa
.sin_addr
.s_addr
= htonl (addr
);
2469 saddr
.sa
.sin_port
= htons (port
);
2470 if (mroute_extract_openvpn_sockaddr (&maddr
, &saddr
, true))
2472 hash_iterator_init (m
->iter
, &hi
, true);
2473 while ((he
= hash_iterator_next (&hi
)))
2475 struct multi_instance
*mi
= (struct multi_instance
*) he
->value
;
2476 if (!mi
->halt
&& mroute_addr_equal (&maddr
, &mi
->real
))
2478 multi_signal_instance (m
, mi
, SIGTERM
);
2482 hash_iterator_free (&hi
);
2488 management_delete_event (void *arg
, event_t event
)
2490 struct multi_context
*m
= (struct multi_context
*) arg
;
2492 multi_tcp_delete_event (m
->mtcp
, event
);
2497 #ifdef MANAGEMENT_DEF_AUTH
2499 static struct multi_instance
*
2500 lookup_by_cid (struct multi_context
*m
, const unsigned long cid
)
2504 struct multi_instance
*mi
= (struct multi_instance
*) hash_lookup (m
->cid_hash
, &cid
);
2505 if (mi
&& !mi
->halt
)
2512 management_kill_by_cid (void *arg
, const unsigned long cid
)
2514 struct multi_context
*m
= (struct multi_context
*) arg
;
2515 struct multi_instance
*mi
= lookup_by_cid (m
, cid
);
2518 multi_signal_instance (m
, mi
, SIGTERM
);
2526 management_client_auth (void *arg
,
2527 const unsigned long cid
,
2528 const unsigned int mda_key_id
,
2531 struct buffer_list
*cc_config
) /* ownership transferred */
2533 struct multi_context
*m
= (struct multi_context
*) arg
;
2534 struct multi_instance
*mi
= lookup_by_cid (m
, cid
);
2535 bool cc_config_owned
= true;
2540 ret
= tls_authenticate_key (mi
->context
.c2
.tls_multi
, mda_key_id
, auth
);
2543 if (auth
&& !mi
->connection_established_flag
)
2545 set_cc_config (mi
, cc_config
);
2546 cc_config_owned
= false;
2548 if (!auth
&& reason
)
2549 msg (D_MULTI_LOW
, "MULTI: connection rejected: %s", reason
);
2552 if (cc_config_owned
&& cc_config
)
2553 buffer_list_free (cc_config
);
2558 #ifdef MANAGEMENT_PF
2560 management_client_pf (void *arg
,
2561 const unsigned long cid
,
2562 struct buffer_list
*pf_config
) /* ownership transferred */
2564 struct multi_context
*m
= (struct multi_context
*) arg
;
2565 struct multi_instance
*mi
= lookup_by_cid (m
, cid
);
2568 if (mi
&& pf_config
)
2569 ret
= pf_load_from_buffer_list (&mi
->context
, pf_config
);
2572 buffer_list_free (pf_config
);
2578 init_management_callback_multi (struct multi_context
*m
)
2580 #ifdef ENABLE_MANAGEMENT
2583 struct management_callback cb
;
2586 cb
.status
= management_callback_status
;
2587 cb
.show_net
= management_show_net_callback
;
2588 cb
.kill_by_cn
= management_callback_kill_by_cn
;
2589 cb
.kill_by_addr
= management_callback_kill_by_addr
;
2590 cb
.delete_event
= management_delete_event
;
2591 #ifdef MANAGEMENT_DEF_AUTH
2592 cb
.kill_by_cid
= management_kill_by_cid
;
2593 cb
.client_auth
= management_client_auth
;
2595 #ifdef MANAGEMENT_PF
2596 cb
.client_pf
= management_client_pf
;
2598 management_set_callback (management
, &cb
);
2604 uninit_management_callback_multi (struct multi_context
*m
)
2606 uninit_management_callback ();
2610 * Top level event loop.
2613 tunnel_server (struct context
*top
)
2615 ASSERT (top
->options
.mode
== MODE_SERVER
);
2617 switch (top
->options
.ce
.proto
) {
2619 tunnel_server_udp (top
);
2621 case PROTO_TCPv4_SERVER
:
2622 tunnel_server_tcp (top
);
2630 static void dummy(void) {}
2631 #endif /* P2MP_SERVER */