From 98619012e242176bcbdc3215fa462fa2cf882e36 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 28 Jul 2011 23:56:24 +0200 Subject: Added main/control docs Signed-off-by: Adriaan de Jong Acked-by: James Yonan Signed-off-by: David Sommerseth --- doc_control_processor.h | 189 ++++++++++++++++++++++++++++++++++++++++++ doc_data_control.h | 103 +++++++++++++++++++++++ doc_eventloop.h | 67 +++++++++++++++ doc_external_multiplexer.h | 46 +++++++++++ doc_internal_multiplexer.h | 44 ++++++++++ doc_mainpage.h | 162 ++++++++++++++++++++++++++++++++++++ doc_protocol_overview.h | 199 +++++++++++++++++++++++++++++++++++++++++++++ doc_tunnel_state.h | 155 +++++++++++++++++++++++++++++++++++ forward.h | 163 ++++++++++++++++++++++++++++++++++++- mtcp.h | 9 ++ mtu.h | 68 ++++++++-------- mudp.c | 14 +++- mudp.h | 29 +++++++ multi.h | 161 ++++++++++++++++++++++++++++++++---- openvpn.c | 31 +++++++ openvpn.h | 153 ++++++++++++++++++++-------------- 16 files changed, 1476 insertions(+), 117 deletions(-) create mode 100644 doc_control_processor.h create mode 100644 doc_data_control.h create mode 100644 doc_eventloop.h create mode 100644 doc_external_multiplexer.h create mode 100644 doc_internal_multiplexer.h create mode 100644 doc_mainpage.h create mode 100644 doc_protocol_overview.h create mode 100644 doc_tunnel_state.h diff --git a/doc_control_processor.h b/doc_control_processor.h new file mode 100644 index 0000000..072dc37 --- /dev/null +++ b/doc_control_processor.h @@ -0,0 +1,189 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * Control Channel Processor module documentation file. + */ + +/** + * @defgroup control_processor Control Channel Processor module + * + * This module controls the setup and maintenance of VPN tunnels and the + * associated security parameters. + * + * @par This module's role + * The Control Channel Processor module lies at the core of OpenVPN's + * activities. It handles the setup of new VPN tunnels, the negotiation + * of data channel security parameters, the managing of active VPN + * tunnels, and finally the cleanup of expired VPN tunnels. + * + * @par State structures + * A large amount of VPN tunnel state information must be stored within an + * OpenVPN process. A wide variety of container structures are used by + * this module for that purpose. Several of these structures are listed + * below, and the function of the first three VPN tunnel state containers + * is described in more detail later. + * - VPN tunnel state containers: + * - \c tls_multi, security parameter state for a single VPN tunnel. + * Contains three instances of the \c tls_session structure. + * - \c tls_session, security parameter state of a single session + * within a VPN tunnel. Contains two instances of the \c key_state + * structure. + * - \c key_state, security parameter state of one TLS and data + * channel %key set. + * - Data channel security parameter containers: + * - \c key_ctx_bi, container for two sets of OpenSSL cipher and/or + * HMAC context (both directions). Contains two instances of the \c + * key_ctx structure. + * - \c key_ctx, container for one set of OpenSSL cipher and/or HMAC + * context (one directions. + * - Key material containers: + * - \c key2, container for two sets of cipher and/or HMAC %key + * material (both directions). Contains two instances of the \c key + * structure. + * - \c key, container for one set of cipher and/or HMAC %key material + * (one direction). + * - \c key_direction_state, ordering of %key material within the \c + * key2.key array. + * - Key method 2 random material containers: + * - \c key_source2, container for both halves of random material used + * for %key method 2. Contains two instances of the \c key_source + * structure. + * - \c key_source, container for one half of random material used for + * %key method 2. + * + * @par The life of a \c tls_multi object + * A \c tls_multi structure contains all the security parameter state + * information related to the control and data channels of one VPN tunnel. + * Its life cycle can be summarized as follows: + * -# Initialization: \c tls_multi_init() and \c + * tls_multi_init_finalize(), which are called (indirectly) from \c + * init_instance() when initializing a new \c context structure. + * - Initializes a \c tls_multi structure. + * - Allocates the three \c tls_session objects contained by the \c + * tls_multi structure, and initializes as appropriate. + * -# Management: \c tls_multi_process() and \c tls_pre_decrypt() + * - If a new session is initiated by the remote peer, then \c + * tls_pre_decrypt() starts the new session negotiation in the + * un-trusted \c tls_session. + * - If the, as yet, un-trusted \c tls_session authenticates + * successfully, then \c tls_multi_process() moves it so as to be + * the active \c tls_session. + * - If an error occurs during processing of a \c key_state object, + * then \c tls_multi_process() cleans up and initializes the + * associated \c tls_session object. If the error occurred in the + * active \c key_state of the active \c tls_session and the + * lame-duck \c key_state of that \c tls_session has not yet + * expired, it is preserved as fallback. + * -# Cleanup: \c tls_multi_free(), which is called (indirectly) from \c + * close_instance() when cleaning up a \c context structure. + * - Cleans up a \c tls_multi structure. + * - Cleans up the three \c tls_session objects contained by the \c + * tls_multi structure. + * + * @par The life of a \c tls_session object + * A \c tls_session structure contains the state information related to an + * active and a lame-duck \c key_state. Its life cycle can be summarized + * as follows: + * -# Initialization: \c tls_session_init() + * - Initializes a \c tls_session structure. + * - Initializes the primary \c key_state by calling \c + * key_state_init(). + * -# Renegotiation: \c key_state_soft_reset() + * - Cleans up the old lame-duck \c key_state by calling \c + * key_state_free(). + * - Moves the old primary \c key_state to be the new lame-duck \c + * key_state. + * - Initializes a new primary \c key_state by calling \c + * key_state_init(). + * -# Cleanup: \c tls_session_free() + * - Cleans up a \c tls_session structure. + * - Cleans up all \c key_state objects associated with the session by + * calling \c key_state_free() for each. + * + * @par The life of a \c key_state object + * A \c key_state structure represents one control and data channel %key + * set. It contains an OpenSSL TLS object that encapsulates the control + * channel, and the data channel security parameters needed by the \link + * data_crypto Data Channel Crypto module\endlink to perform cryptographic + * operations on data channel packets. Its life cycle can be summarized + * as follows: + * -# Initialization: \c key_state_init() + * - Initializes a \c key_state structure. + * - Creates a new OpenSSL TLS object to encapsulate this new control + * channel session. + * - Sets \c key_state.state to \c S_INITIAL. + * - Allocates several internal buffers. + * - Initializes new reliability layer structures for this key set. + * -# Negotiation: \c tls_process() + * - The OpenSSL TLS object negotiates a TLS session between itself + * and the remote peer's TLS object. + * - Key material is generated and exchanged through the TLS session + * between OpenVPN peers. + * - Both peers initialize their data channel cipher and HMAC key + * contexts. + * - On successful negotiation, the \c key_state.state will progress + * from \c S_INITIAL to \c S_ACTIVE and \c S_NORMAL. + * -# Active tunneling: \link data_crypto Data Channel Crypto + * module\endlink + * - Data channel packet to be sent to a remote OpenVPN peer: + * - \c tls_pre_encrypt() loads the security parameters from the \c + * key_state into a \c crypto_options structure. + * - \c openvpn_encrypt() uses the \c crypto_options to an encrypt + * and HMAC sign the data channel packet. + * - Data channel packet received from a remote OpenVPN peer: + * - \c tls_pre_decrypt() loads the security parameters from the \c + * key_state into a \c crypto_options structure. + * - \c openvpn_encrypt() uses the \c crypto_options to + * authenticate and decrypt the data channel packet. + * -# Cleanup: \c key_state_free() + * - Cleans up a \c key_state structure together with its OpenSSL TLS + * object, key material, internal buffers, and reliability layer + * structures. + * + * @par Control functions + * The following two functions drive the Control Channel Processor's + * activities. + * - \c tls_multi_process(), iterates through the \c tls_session objects + * within a given \c tls_multi of a VPN tunnel, and calls \c + * tls_process() for each \c tls_session which is being set up, is + * already active, or is busy expiring. + * - \c tls_process(), performs the Control Channel Processor module's + * core handling of received control channel messages, and generates + * appropriate messages to be sent. + * + * @par Functions which control data channel key generation + * - Key method 1 key exchange functions: + * - \c key_method_1_write(), generates and processes key material to + * be sent to the remote OpenVPN peer. + * - \c key_method_1_read(), processes key material received from the + * remote OpenVPN peer. + * - Key method 2 key exchange functions: + * - \c key_method_2_write(), generates and processes key material to + * be sent to the remote OpenVPN peer. + * - \c key_method_2_read(), processes key material received from the + * remote OpenVPN peer. + */ diff --git a/doc_data_control.h b/doc_data_control.h new file mode 100644 index 0000000..d0f65ba --- /dev/null +++ b/doc_data_control.h @@ -0,0 +1,103 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * Data Channel Control module documentation file. + */ + +/** + * @defgroup data_control Data Channel Control module + * + * This module controls the processing of packets as they pass through the + * data channel. + * + * The Data Channel Control module controls the processing of packets as + * they pass through the data channel. The processing includes packet + * compression, fragmentation, and the performing of security operations + * on the packets. This module does not do the processing itself, but + * passes the packet to other data channel modules to perform the + * appropriate actions. + * + * Packets can travel in two directions through the data channel. They + * can be going to a remote destination which is reachable through a VPN + * tunnel, in which case this module prepares them to be sent out through + * a VPN tunnel. On the other hand, they can have been received through a + * VPN tunnel from a remote OpenVPN peer, in which case this module + * retrieves the packet in its original form as it was before entering the + * VPN tunnel on the remote OpenVPN peer. How this module processes + * packets traveling in the two directions is discussed in more detail + * below. + * + * @par Packets to be sent to a remote OpenVPN peer + * This module's main function for processing packets traveling in this + * direction is \c encrypt_sign(), which performs the following processing + * steps: + * - Call the \link compression Data Channel Compression module\endlink to + * perform packet compression if necessary. + * - Call the \link fragmentation Data Channel Fragmentation + * module\endlink to perform packet fragmentation if necessary. + * - Call the \link data_crypto Data Channel Crypto module\endlink to + * perform the required security operations. + * + * @par + * See the \c encrypt_sign() documentation for details of these + * interactions. + * + * @par + * After the above processing is complete, the packet is ready to be sent + * to a remote OpenVPN peer as a VPN tunnel packet. The actual sending of + * the packet is handled by the \link external_multiplexer External + * Multiplexer\endlink. + * + * @par Packets received from a remote OpenVPN peer + * The function that controls how packets traveling in this direction are + * processed is \c process_incoming_link(). That function, however, also + * performs some of the tasks required for the \link external_multiplexer + * External Multiplexer\endlink and is therefore listed as part of that + * module, instead of here. + * + * @par + * After the \c process_incoming_link() function has determined that a + * received packet is a data channel packet, it performs the following + * processing steps: + * - Call the \link data_crypto Data Channel Crypto module\endlink to + * perform the required security operations. + * - Call the \link fragmentation Data Channel Fragmentation + * module\endlink to perform packet reassembly if necessary. + * - Call the \link compression Data Channel Compression module\endlink to + * perform packet decompression if necessary. + * + * @par + * See the \c process_incoming_link() documentation for details of these + * interactions. + * + * @par + * After the above processing is complete, the packet is in its original + * form again as it was received by the remote OpenVPN peer. It can now + * be routed further to its final destination. If that destination is a + * locally reachable host, then the \link internal_multiplexer Internal + * Multiplexer\endlink will send it there. + */ diff --git a/doc_eventloop.h b/doc_eventloop.h new file mode 100644 index 0000000..a860db6 --- /dev/null +++ b/doc_eventloop.h @@ -0,0 +1,67 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * Main Event Loop module documentation file. + */ + +/** + * @defgroup eventloop Main Event Loop module + * + * This main event loop module drives the packet processing of OpenVPN. + * + * OpenVPN is an event driven system. Its activities are driven by a main + * event loop, which repeatedly waits for one of several predefined events + * to occur, and then calls the appropriate module to handle the event. + * The major types of network events that OpenVPN processes are: + * - A packet can be read from the external network interface. + * - The main event loop activates the \link external_multiplexer + * External Multiplexer\endlink to read and process the packet. + * - A packet can be read from the virtual tun/tap network interface. + * - The main event loop activates the \link internal_multiplexer + * Internal Multiplexer\endlink to read and process the packet. + * - If a packet is ready to be sent out as a VPN tunnel packet: the + * external network interface can be written to. + * - The main event loop activates the \link external_multiplexer + * External Multiplexer\endlink to send the packet. + * - If a packet is ready to be sent to a locally reachable destination: + * the virtual tun/tap network interface can be written to. + * - The main event loop activates the \link internal_multiplexer + * Internal Multiplexer\endlink to send the packet. + * + * Beside these external events, OpenVPN also processes other types of + * internal events. These include scheduled events, such as resending of + * non-acknowledged control channel messages. + * + * @par Main event loop implementations + * + * Depending on the mode in which OpenVPN is running, a different main + * event loop function is called to drive the event processing. The + * following implementations are available: + * - Client mode using UDP or TCP: \c tunnel_point_to_point() + * - Server mode using UDP: \c tunnel_server_udp_single_threaded() + * - Server mode using TCP: \c tunnel_server_tcp() + */ diff --git a/doc_external_multiplexer.h b/doc_external_multiplexer.h new file mode 100644 index 0000000..7653255 --- /dev/null +++ b/doc_external_multiplexer.h @@ -0,0 +1,46 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * External Multiplexer module documentation file. + */ + +/** + * @addtogroup external_multiplexer External Multiplexer module + * + * The External Multiplexer is the link between the external network + * interface and the other OpenVPN modules. It reads packets from the + * external network interface, determines which remote OpenVPN peer and + * VPN tunnel they are associated with, and whether they are data channel + * or control channel packets. It then passes the packets on to the + * appropriate processing module. + * + * This module also handles packets traveling in the reverse direction, + * which have been generated by the local control channel or which have + * already been processed by the \link data_control Data Channel Control + * module\endlink and are destined for a remote host reachable through a + * VPN tunnel. + */ diff --git a/doc_internal_multiplexer.h b/doc_internal_multiplexer.h new file mode 100644 index 0000000..5142dd0 --- /dev/null +++ b/doc_internal_multiplexer.h @@ -0,0 +1,44 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * Internal Multiplexer module documentation file. + */ + +/** + * @addtogroup internal_multiplexer Internal Multiplexer module + * + * The Internal Multiplexer is the link between the virtual tun/tap + * network interface and the \link data_control Data Channel Control + * module\endlink. It reads packets from the virtual network interface, + * determines for which remote OpenVPN peer they are destined, and then + * passes the packets on to the Data Channel Control module together with + * information about their destination VPN tunnel instance. + * + * This module also handles packets traveling in the reverse direction, + * which have already been processed by the Data Channel Control module + * and are destined for a locally reachable host. + */ diff --git a/doc_mainpage.h b/doc_mainpage.h new file mode 100644 index 0000000..821b2e8 --- /dev/null +++ b/doc_mainpage.h @@ -0,0 +1,162 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * Main page documentation file. + */ + +/** + * @mainpage OpenVPN v2.1 source code documentation + * + * This documentation describes the internal structure of OpenVPN. It was + * automatically generated from specially formatted comment blocks in + * OpenVPN's source code using Doxygen. (See + * http://www.stack.nl/~dimitri/doxygen/ for more information on Doxygen) + * + * The \ref mainpage_modules "Modules section" below gives an introduction + * into the high-level module concepts used throughout this documentation. + * The \ref mainpage_relatedpages "Related Pages section" below describes + * various special subjects related to OpenVPN's implementation which are + * discussed in the related pages section. + * + * @section mainpage_modules Modules + * + * For the purpose of describing the internal structure of OpenVPN, this + * documentation and the underlying source code has been broken up into a + * number of conceptually well-defined parts, known as modules. Each + * module plays a specific role within the OpenVPN process, and in most + * cases each module has a clear interfacing strategy for interacting with + * other modules. + * + * The following modules have been defined: + * - Driver module: + * - The \link eventloop Main Event Loop\endlink: this module drives the + * event handling of OpenVPN. It implements various types of + * select-loop which wait until an event happens, and then delegate + * the handling of that event to the appropriate module. + * - Network interface modules: + * - The \link external_multiplexer External Multiplexer\endlink: this + * module sends and receives packets to and from remote OpenVPN peers + * over the external network interface. It also takes care of + * demultiplexing received packets to their appropriate VPN tunnel and + * splitting control channel and data channel packets. + * - The \link internal_multiplexer Internal Multiplexer\endlink: this + * module sends and receives packets to and from locally reachable + * posts over the virtual tun/tap network interface. It also takes + * care of determining through which VPN tunnel a received packet must + * be sent to reach its destination. + * - Control channel modules: + * - The \link reliable Reliability Layer\endlink: this module offers a + * %reliable and sequential transport layer for control channel + * messages. + * - The \link control_tls Control Channel TLS module\endlink: this + * module offers a secure encapsulation of control channel messages + * using the TLS protocol. + * - The \link control_processor Control Channel Processor\endlink: his + * module manages the setup, maintenance, and shut down of VPN + * tunnels. + * - Data channel modules: + * - The \link data_control Data Channel Control module\endlink: this + * module controls the processing of data channel packets and, + * depending on the settings of the packet's VPN tunnel, passes the + * packet to the three modules below for handling. + * - The \link data_crypto Data Channel Crypto module\endlink: this + * module performs security operations on data channel packets. + * - The \link fragmentation Data Channel Fragmentation module\endlink: + * this module offers fragmentation of data channel packets larger + * than the VPN tunnel's MTU. + * - The \link compression Data Channel Compression module\endlink: this + * module offers compression of data channel packets. + * + * @subsection mainpage_modules_example Example event: receiving a packet + * + * OpenVPN handles many types of events during operation. These include + * external events, such as network traffic being received, and internal + * events, such as a %key session timing out causing renegotiation. An + * example event, receiving a packet over the network, is described here + * together with which modules play what roles: + * -# The \link eventloop Main Event Loop\endlink detects that a packet + * can be read from the external or the virtual tun/tap network + * interface. + * -# The \link eventloop Main Event Loop\endlink calls the \link + * external_multiplexer External Multiplexer\endlink or \link + * internal_multiplexer Internal Multiplexer\endlink to read and + * process the packet. + * -# The multiplexer module determines the type of packet and its + * destination, and passes the packet on to the appropriate handling + * module: + * - A control channel packet received by the \link + * external_multiplexer External Multiplexer\endlink is passed on + * through the \link reliable Reliability Layer\endlink and the \link + * control_tls Control Channel TLS module\endlink to the \link + * control_processor Control Channel Processor\endlink. + * - A data channel packet received by either multiplexer module is + * passed on to the \link data_control Data Channel Control + * module\endlink. + * -# The packet is processed by the appropriate control channel or data + * channel modules. + * -# If, after processing the packet, a resulting packet is generated + * that needs to be sent to a local or remote destination, it is given + * to the \link external_multiplexer External Multiplexer\endlink or + * \link internal_multiplexer Internal Multiplexer\endlink for sending. + * -# If a packet is waiting to be sent by either multiplexer module and + * the \link eventloop Main Event Loop\endlink detects that data can be + * written to the associated network interface, it calls the + * multiplexer module to send the packet. + * + * @section mainpage_relatedpages Related pages + * + * This documentation includes a number of descriptions of various aspects + * of OpenVPN and its implementation. These are not directly related to + * one module, function, or data structure, and are therefore listed + * separately under "Related Pages". + * + * @subsection mainpage_relatedpages_key_generation Data channel key generation + * + * The @ref key_generation "Data channel key generation" related page + * describes how, during VPN tunnel setup and renegotiation, OpenVPN peers + * generate and exchange the %key material required for the symmetric + * encryption/decryption and HMAC signing/verifying security operations + * performed on data channel packets. + * + * @subsection mainpage_relatedpages_tunnel_state VPN tunnel state + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes how an OpenVPN process manages the state information + * associated with its active VPN tunnels. + * + * @subsection mainpage_relatedpages_network_protocol Network protocol + * + * The @ref network_protocol "Network protocol" related page describes the + * format and content of VPN tunnel packets exchanged between OpenVPN + * peers. + * + * @subsection mainpage_relatedpages_memory_management Memory management + * + * The @ref memory_management "Memory management strategies" related page + * gives a brief introduction into OpenVPN's memory %buffer library and + * garbage collection facilities. + */ diff --git a/doc_protocol_overview.h b/doc_protocol_overview.h new file mode 100644 index 0000000..26fed33 --- /dev/null +++ b/doc_protocol_overview.h @@ -0,0 +1,199 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file Network protocol overview documentation file. + */ + +/** + * @page network_protocol OpenVPN's network protocol + * + * Description of packet structure in OpenVPN's network protocol. + * + * This document describes the structure of packets exchanged between + * OpenVPN peers. It is based on the protocol description in the \c ssl.h + * file. + * + * @section network_protocol_external Outer structure of packets exchanged between OpenVPN peers + * + * VPN tunnel packets are transported between OpenVPN peers using the UDP + * or TCP protocols. Their structure is described below. + * + * @subsection network_protocol_external_structure External packet structure + * + * - packet length (16 bits, unsigned) [TCP-mode only]: always sent as + * plain text. Since TCP is a stream protocol, this packet length + * defines the packetization of the stream. + * - packet opcode and key_id (8 bits) [TLS-mode only]: + * - package message type (high 5 bits) + * - key_id (low 3 bits): the key_id refers to an already negotiated + * TLS session. OpenVPN seamlessly renegotiates the TLS session by + * using a new key_id for the new session. Overlap (controlled by + * user definable parameters) between old and new TLS sessions is + * allowed, providing a seamless transition during tunnel operation. + * - payload (n bytes) + * + * @subsection network_protocol_external_types Message types + * + * The type of a VPN tunnel packet is indicated by its opcode. The + * following describes the various opcodes available. + * + * - Control channel messages: + * - \c P_CONTROL_HARD_RESET_CLIENT_V1 -- %Key method 1, initial %key + * from client, forget previous state. + * - \c P_CONTROL_HARD_RESET_SERVER_V1 -- %Key method 1, initial %key + * from server, forget previous state. + * - \c P_CONTROL_HARD_RESET_CLIENT_V2 -- %Key method 2, initial %key + * from client, forget previous state. + * - \c P_CONTROL_HARD_RESET_SERVER_V2 -- %Key method 2, initial %key + * from server, forget previous state. + * - \c P_CONTROL_SOFT_RESET_V1 -- New %key, with a graceful + * transition from old to new %key in the sense that a transition + * window exists where both the old or new key_id can be used. + * - \c P_CONTROL_V1 -- Control channel packet (usually TLS + * ciphertext). + * - \c P_ACK_V1 -- Acknowledgement for control channel packets + * received. + * - Data channel messages: + * - \c P_DATA_V1 -- Data channel packet containing data channel + * ciphertext. + * + * @subsection network_protocol_external_key_id Session IDs and Key IDs + * + * OpenVPN uses two different forms of packet identifiers: + * - The first form is 64 bits and is used for all control channel + * messages. This form is referred to as a \c session_id. + * - Data channel messages on the other hand use a shortened form of 3 + * bits for efficiency reasons since the vast majority of OpenVPN + * packets in an active tunnel will be data channel messages. This + * form is referred to as a \c key_id. + * + * The control and data channels use independent packet-id sequences, + * because the data channel is an unreliable channel while the control + * channel is a %reliable channel. Each use their own independent HMAC + * keys. + * + * @subsection network_protocol_external_reliable Control channel reliability layer + * + * Control channel messages (\c P_CONTROL_* and \c P_ACK_* message types) + * are TLS ciphertext packets which have been encapsulated inside of a + * reliability layer. The reliability layer is implemented as a + * straightforward acknowledge and retransmit model. + * + * Acknowledgments of received messages can be encoded in either the + * dedicated \c P_ACK_* record or they can be prepended to a \c + * P_CONTROL_* message. + * + * See the \link reliable Reliability Layer\endlink module for a detailed + * description. + * + * @section network_protocol_control Structure of control channel messages + * + * @subsection network_protocol_control_ciphertext Structure of ciphertext control channel messages + * + * Control channel packets in ciphertext form consist of the following + * parts: + * + * - local \c session_id (random 64 bit value to identify TLS session). + * - HMAC signature of entire encapsulation header for HMAC firewall + * [only if \c --tls-auth is specified] (usually 16 or 20 bytes). + * - packet-id for replay protection (4 or 8 bytes, includes sequence + * number and optional \c time_t timestamp). + * - acknowledgment packet-id array length (1 byte). + * - acknowledgment packet-id array (if length > 0). + * - acknowledgment remote session-id (if length > 0). + * - packet-id of this message (4 bytes). + * - TLS payload ciphertext (n bytes) (only for \c P_CONTROL_V1). + * + * Note that when \c --tls-auth is used, all message types are protected + * with an HMAC signature, even the initial packets of the TLS handshake. + * This makes it easy for OpenVPN to throw away bogus packets quickly, + * without wasting resources on attempting a TLS handshake which will + * ultimately fail. + * + * @subsection network_protocol_control_key_methods Control channel key methods and + * + * Once the TLS session has been initialized and authenticated, the TLS + * channel is used to exchange random %key material for bidirectional + * cipher and HMAC keys which will be used to secure data channel packets. + * OpenVPN currently implements two %key methods. %Key method 1 directly + * derives keys using random bits obtained from the \c RAND_bytes() + * OpenSSL function. %Key method 2 mixes random %key material from both + * sides of the connection using the TLS PRF mixing function. %Key method + * 2 is the preferred method and is the default for OpenVPN 2.0. + * + * The @ref key_generation "Data channel key generation" related page + * describes the %key methods in more detail. + * + * @subsection network_protocol_control_plaintext Structure of plaintext control channel messages + * + * - %Key method 1: + * - Cipher %key length in bytes (1 byte). + * - Cipher %key (n bytes). + * - HMAC %key length in bytes (1 byte). + * - HMAC %key (n bytes). + * - %Options string (n bytes, null terminated, client/server %options + * string should match). + * - %Key method 2: + * - Literal 0 (4 bytes). + * - %Key method (1 byte). + * - \c key_source structure (\c key_source.pre_master only defined + * for client -> server). + * - %Options string length, including null (2 bytes). + * - %Options string (n bytes, null terminated, client/server %options + * string must match). + * - [The username/password data below is optional, record can end at + * this point.] + * - Username string length, including null (2 bytes). + * - Username string (n bytes, null terminated). + * - Password string length, including null (2 bytes). + * - Password string (n bytes, null terminated). + * + * @section network_protocol_data Structure of data channel messages + * + * @subsection network_protocol_data_ciphertext Structure of ciphertext data channel messages + * + * The P_DATA_* payload represents encrypted, encapsulated tunnel packets + * which tend to be either IP packets or Ethernet frames. This is + * essentially the "payload" of the VPN. + * + * Data channel packets in ciphertext form consist of the following parts: + * - HMAC of ciphertext IV + ciphertext (if not disabled by \c --auth + * none). + * - Ciphertext IV (size is cipher-dependent, if not disabled by \c + * --no-iv). + * - Tunnel packet ciphertext. + * + * @subsection network_protocol_data_plaintext Structure of plaintext data channel messages + * + * Data channel packets in plaintext form consist of the following parts: + * - packet-id (4 or 8 bytes, if not disabled by --no-replay). + * - In TLS mode, 4 bytes are used because the implementation can + * force a TLS renegotation before \c 2^32 packets are sent. + * - In pre-shared %key mode, 8 bytes are used (sequence number and \c + * time_t value) to allow long-term %key usage without packet-id + * collisions. + * - User plaintext (n bytes). + */ diff --git a/doc_tunnel_state.h b/doc_tunnel_state.h new file mode 100644 index 0000000..6c93e71 --- /dev/null +++ b/doc_tunnel_state.h @@ -0,0 +1,155 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single TCP/UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2010 Fox Crypto B.V. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file + * VPN tunnel state documentation file. + */ + +/** + * @page tunnel_state Structure of the VPN tunnel state storage + * + * This section describes how OpenVPN stores its VPN tunnel state during + * operation. + * + * OpenVPN uses several data structures as storage containers for state + * information of active VPN tunnels. These are described in this + * section, together with a little bit of history to help understand the + * origin of the current architecture. + * + * Whether an OpenVPN process is running in client-mode or server-mode + * determines whether it can support only one or multiple simultaneously + * active VPN tunnels. This consequently also determines how the + * associated state information is wrapped up internally. This section + * gives an overview of the differences. + * + * @section tunnel_state_history Historic developments + * + * In the old v1.x series, an OpenVPN process managed only one single VPN + * tunnel. This allowed the VPN tunnel state to be stored together with + * process-global information in one single \c context structure. + * + * This changed, however, in the v2.x series, as new OpenVPN versions + * running in server-mode can support multiple simultaneously active VPN + * tunnels. This necessitated a redesign of the VPN tunnel state + * container structures, and modification of the \link + * external_multiplexer External Multiplexer\endlink and \link + * internal_multiplexer Internal Multiplexer\endlink systems. The + * majority of these changes are only relevant for OpenVPN processes + * running in server-mode, and the client-mode structure has remained very + * similar to the v1.x single-tunnel form. + * + * @section tunnel_state_client Client-mode state + * + * An OpenVPN process running in client-mode can manage at most one single + * VPN tunnel at any one time. The state information for a client's VPN + * tunnel is stored in a \c context structure. + * + * The \c context structure is created in the \c main() function. That is + * also where process-wide initialization takes place, such as parsing + * command line %options and reading configuration files. The \c context + * is then passed to \c tunnel_point_to_point() which drives OpenVPN's + * main event processing loop. These functions are both part of the \link + * eventloop Main Event Loop\endlink module. + * + * @subsection tunnel_state_client_init Initialization and cleanup + * + * Because there is only one \c context structure present, it can be + * initialized and cleaned up from the client's main event processing + * function. Before the \c tunnel_point_to_point() function enters its + * event loop, it calls \c init_instance_handle_signals() which calls \c + * init_instance() to initialize the single \c context structure. After + * the event loop stops, it calls \c close_instance() to clean up the \c + * context. + * + * @subsection tunnel_state_client_event Event processing + * + * When the main event processing loop activates the external or internal + * multiplexer to handle a network event, it is not necessary to determine + * which VPN tunnel the event is associated with, because there is only + * one VPN tunnel active. + * + * @section tunnel_state_server Server-mode state + * + * An OpenVPN process running in server-mode can manage multiple + * simultaneously active VPN tunnels. For every VPN tunnel active, in + * other words for every OpenVPN client which is connected to a server, + * the OpenVPN server has one \c context structure in which it stores that + * particular VPN tunnel's state information. + * + * @subsection tunnel_state_server_multi Multi_context and multi_instance structures + * + * To support multiple \c context structures, each is wrapped in a \c + * multi_instance structure, and all the \c multi_instance structures are + * registered in one single \c multi_context structure. The \link + * external_multiplexer External Multiplexer\endlink and \link + * internal_multiplexer Internal Multiplexer\endlink then use the \c + * multi_context to retrieve the correct \c multi_instance and \c context + * associated with a given network address. + * + * @subsection tunnel_state_server_init Startup and initialization + * + * An OpenVPN process running in server-mode starts in the same \c main() + * function as it would in client-mode. The same process-wide + * initialization is performed, and the resulting state and configuration + * is stored in a \c context structure. The server-mode and client-mode + * processes diverge when the \c main() function calls one of \c + * tunnel_point_to_point() or \c tunnel_server(). + * + * In server-mode, \c main() calls the \c tunnel_server() function, which + * transfers control to \c tunnel_server_udp_single_threaded() or \c + * tunnel_server_tcp() depending on the external transport protocol. + * + * These functions receive the \c context created in \c main(). This + * object has a special status in server-mode, as it does not represent an + * active VPN tunnel, but does contain process-wide configuration + * parameters. In the source code, it is often stored in "top" variables. + * To distinguish this object from other instances of the same type, its + * \c context.mode value is set to \c CM_TOP. Other \c context objects, + * which do represent active VPN tunnels, have a \c context.mode set to \c + * CM_CHILD_UDP or \c CM_CHILD_TCP, depending on the external transport + * protocol. + * + * Both \c tunnel_server_udp_single_threaded() and \c tunnel_server_tcp() + * perform similar initialization. In either case, a \c multi_context + * structure is created, and it is initialized according to the + * configuration stored in the top \c context by the \c multi_init() and + * \c multi_top_init() functions. + * + * @subsection tunnel_state_server_tunnels Creating and destroying VPN tunnels + * + * When an OpenVPN client makes a new connection to a server, the server + * creates a new \c context and \c multi_instance. The latter is + * registered in the \c multi_context, which makes it possible for the + * external and internal multiplexers to retrieve the correct \c + * multi_instance and \c context when a network event occurs. + * + * @subsection tunnel_state_server_cleanup Final cleanup + * + * After the main event loop exits, both \c + * tunnel_server_udp_single_threaded() and \c tunnel_server_tcp() perform + * similar cleanup. They call \c multi_uninit() followed by \c + * multi_top_free() to clean up the \c multi_context structure. + */ diff --git a/forward.h b/forward.h index 76d8b9e..0f829bd 100644 --- a/forward.h +++ b/forward.h @@ -22,6 +22,13 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + * @file + * Interface functions to the internal and external multiplexers. + */ + + #ifndef FORWARD_H #define FORWARD_H @@ -54,22 +61,170 @@ #define IOW_READ (IOW_READ_TUN|IOW_READ_LINK) -void pre_select (struct context *c); +void pre_select (struct context *c); void process_io (struct context *c); -void encrypt_sign (struct context *c, bool comp_frag); - const char *wait_status_string (struct context *c, struct gc_arena *gc); void show_wait_status (struct context *c); + +/**********************************************************************/ +/** + * Process a data channel packet that will be sent through a VPN tunnel. + * @ingroup data_control + * + * This function controls the processing of a data channel packet which + * will be sent through a VPN tunnel to a remote OpenVPN peer. It's + * general structure is as follows: + * - Check that the client authentication has succeeded; if not, drop the + * packet. + * - If the \a comp_frag argument is true: + * - Call \c lzo_compress() of the \link Data Channel Compression + * module\endlink to (possibly) compress the packet. + * - Call \c fragment_outgoing() of the \link Data Channel Fragmentation + * module\endlink to (possibly) fragment the packet. + * - Activate the \link Data Channel Crypto module\endlink to perform + * security operations on the packet. + * - Call \c tls_pre_encrypt() to choose the appropriate security + * parameters for this packet. + * - Call \c openvpn_encrypt() to encrypt and HMAC signed the packet. + * - Call \c tls_post_encrypt() to prepend the one-byte OpenVPN header + * and do some TLS accounting. + * - Place the resulting packet in \c c->c2.to_link so that it can be sent + * over the external network interface to its remote destination by the + * \link external_multiplexer External Multiplexer\endlink. + * + * @param c - The context structure of the VPN tunnel associated with this + * packet. + * @param comp_frag - Whether to do packet compression and fragmentation. + * This flag is set to true the first time a packet is processed. If + * the packet then gets fragmented, this function will be called again + * once for each remaining fragment with this parameter set to false. + */ +void encrypt_sign (struct context *c, bool comp_frag); + + +/**********************************************************************/ +/** + * Read a packet from the external network interface. + * @ingroup external_multiplexer + * + * The packet read from the external network interface is stored in \c + * c->c2.buf and its source address in \c c->c2.from. If an error + * occurred, the length of \c c->c2.buf will be 0. + * + * OpenVPN running as client or as UDP server only has a single external + * network socket, so this function can be called with the single (client + * mode) or top level (UDP server) context as its argument. OpenVPN + * running as TCP server, on the other hand, has a network socket for each + * active VPN tunnel. In that case this function must be called with the + * context associated with the appropriate VPN tunnel for which data is + * available to be read. + * + * @param c - The context structure which contains the external + * network socket from which to read incoming packets. + */ void read_incoming_link (struct context *c); + + +/** + * Process a packet read from the external network interface. + * @ingroup external_multiplexer + * + * This function controls the processing of a data channel packet which + * has come out of a VPN tunnel. It's high-level structure is as follows: + * - Verify that a nonzero length packet has been received from a valid + * source address for the given context \a c. + * - Call \c tls_pre_decrypt(), which splits data channel and control + * channel packets: + * - If a data channel packet, the appropriate security parameters are + * loaded. + * - If a control channel packet, this function process is it and + * afterwards sets the packet's buffer length to 0, so that the data + * channel processing steps below will ignore it. + * - Call \c openvpn_decrypt() of the \link data_crypto Data Channel + * Crypto module\endlink to authenticate and decrypt the packet using + * the security parameters loaded by \c tls_pre_decrypt() above. + * - Call \c fragment_incoming() of the \link fragmentation Data Channel + * Fragmentation module\endlink to reassemble the packet if it's + * fragmented. + * - Call \c lzo_decompress() of the \link compression Data Channel + * Compression module\endlink to decompress the packet if it's + * compressed. + * - Place the resulting packet in \c c->c2.to_tun so that it can be sent + * over the virtual tun/tap network interface to its local destination + * by the \link internal_multiplexer Internal Multiplexer\endlink. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ void process_incoming_link (struct context *c); + + +/** + * Write a packet to the external network interface. + * @ingroup external_multiplexer + * + * This function writes the packet stored in \c c->c2.to_link to the + * external network device contained within \c c->c1.link_socket. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ +void process_outgoing_link (struct context *c); + + +/**************************************************************************/ +/** + * Read a packet from the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function reads a packet from the virtual tun/tap network device \c + * c->c1.tuntap and stores it in \c c->c2.buf. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure in which to store the received + * packet. + */ void read_incoming_tun (struct context *c); + + +/** + * Process a packet read from the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function calls \c encrypt_sign() of the \link data_control Data + * Channel Control module\endlink to process the packet. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with the + * packet. + */ void process_incoming_tun (struct context *c); -void process_outgoing_link (struct context *c); + + +/** + * Write a packet to the virtual tun/tap network interface. + * @ingroup internal_multiplexer + * + * This function writes the packet stored in \c c->c2.to_tun to the + * virtual tun/tap network device \c c->c1.tuntap. + * + * If an error occurs, it is logged and the packet is dropped. + * + * @param c - The context structure of the VPN tunnel associated with + * the packet. + */ void process_outgoing_tun (struct context *c); + +/**************************************************************************/ + bool send_control_channel_string (struct context *c, const char *str, int msglevel); #define PIPV4_PASSTOS (1<<0) diff --git a/mtcp.h b/mtcp.h index 3585af4..b677b48 100644 --- a/mtcp.h +++ b/mtcp.h @@ -60,8 +60,17 @@ void multi_tcp_instance_specific_free (struct multi_instance *mi); void multi_tcp_link_out_deferred (struct multi_context *m, struct multi_instance *mi); + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in TCP server mode. + * @ingroup eventloop + * + * @param top - Top-level context structure. + */ void tunnel_server_tcp (struct context *top); + void multi_tcp_delete_event (struct multi_tcp *mtcp, event_t event); #endif diff --git a/mtu.h b/mtu.h index d9fa020..29ec21f 100644 --- a/mtu.h +++ b/mtu.h @@ -86,39 +86,43 @@ */ #define PAYLOAD_ALIGN 4 -struct frame { - /* - * Maximum datagram size to be sent over the tunnel TCP/UDP channel. - */ - int link_mtu; - int link_mtu_dynamic; - - /* - * How many extra bytes might each subsystem (crypto, TLS, or, compression) - * add to frame in worst case? - * - * mtu + extra_frame = MTU of TCP/UDP transport - */ - int extra_frame; - - /* - * Worst case size added to internal buffer due to functions - * such as compression which can potentially expand the size of uncompressible - * data. - */ - int extra_buffer; - - /* - * Max number of bytes in excess of tun mtu size that we might read - * or write from TUN/TAP device. - */ - int extra_tun; - /* - * Max number of bytes in excess of link mtu size that we might read - * or write from UDP/TCP link. - */ - int extra_link; +/**************************************************************************/ +/** + * Packet geometry parameters. + */ +struct frame { + int link_mtu; /**< Maximum packet size to be sent over + * the external network interface. */ + + int link_mtu_dynamic; /**< Dynamic MTU value for the external + * network interface. */ + + int extra_frame; /**< Maximum number of bytes that all + * processing steps together could add. + * @code + * frame.link_mtu = "socket MTU" - extra_frame; + * @endcode + */ + + int extra_buffer; /**< Maximum number of bytes that + * processing steps could expand the + * internal work buffer. + * + * This is used by the \link compression + * Data Channel Compression + * module\endlink to give enough working + * space for worst-case expansion of + * incompressible content. */ + + int extra_tun; /**< Maximum number of bytes in excess of + * the tun/tap MTU that might be read + * from or written to the virtual + * tun/tap network interface. */ + + int extra_link; /**< Maximum number of bytes in excess of + * external network interface's MTU that + * might be read from or written to it. */ /* * Alignment control diff --git a/mudp.c b/mudp.c index a478b29..7648ec6 100644 --- a/mudp.c +++ b/mudp.c @@ -199,9 +199,17 @@ p2mp_iow_flags (const struct multi_context *m) return flags; } -/* - * Top level event loop for single-threaded operation. - * UDP mode. + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in UDP server mode. + * @ingroup eventloop + * + * This function implements OpenVPN's main event loop for UDP server mode. + * At this time, OpenVPN does not yet support multithreading. This + * function's name is therefore slightly misleading. + * + * @param top - Top-level context structure. */ static void tunnel_server_udp_single_threaded (struct context *top) diff --git a/mudp.h b/mudp.h index dc9cfde..97f961b 100644 --- a/mudp.h +++ b/mudp.h @@ -34,8 +34,37 @@ struct context; struct multi_context; + +/**************************************************************************/ +/** + * Main event loop wrapper function for OpenVPN in UDP server mode. + * @ingroup eventloop + * + * This function simply calls \c tunnel_server_udp_single_threaded(). + * + * @param top - Top-level context structure. + */ void tunnel_server_udp (struct context *top); + +/**************************************************************************/ +/** + * Get, and if necessary create, the multi_instance associated with a + * packet's source address. + * @ingroup external_multiplexer + * + * This function extracts the source address of a recently read packet + * from \c m->top.c2.from and uses that source address as a hash key for + * the hash table \c m->hash. If an entry exists, this function returns + * it. If no entry exists, this function handles its creation, and if + * successful, returns the newly created instance. + * + * @param m - The single multi_context structure. + * + * @return A pointer to a multi_instance if one already existed for the + * packet's source address or if one was a newly created successfully. + * NULL if one did not yet exist and a new one was not created. + */ struct multi_instance *multi_get_create_instance_udp (struct multi_context *m); #endif diff --git a/multi.h b/multi.h index 08964a2..58e65a3 100644 --- a/multi.h +++ b/multi.h @@ -22,6 +22,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/** + * @file Header file for server-mode related structures and functions. + */ + #ifndef MULTI_H #define MULTI_H @@ -50,8 +54,16 @@ struct multi_reap time_t last_call; }; -/* - * One multi_instance object per client instance. + +/** + * Server-mode state structure for one single VPN tunnel. + * + * This structure is used by OpenVPN processes running in server-mode to + * store state information related to one single VPN tunnel. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes the role the structure plays when OpenVPN is running in + * server-mode. */ struct multi_instance { struct schedule_entry se; /* this must be the first element of the structure */ @@ -60,9 +72,13 @@ struct multi_instance { bool halt; int refcount; int route_count; /* number of routes (including cached routes) owned by this instance */ - time_t created; + time_t created; /**< Time at which a VPN tunnel instance + * was created. This parameter is set + * by the \c multi_create_instance() + * function. */ struct timeval wakeup; /* absolute time */ - struct mroute_addr real; + struct mroute_addr real; /**< External network address of the + * remote peer. */ ifconfig_pool_handle vaddr_handle; const char *msg_prefix; @@ -84,11 +100,20 @@ struct multi_instance { bool did_iroutes; int n_clients_delta; /* added to multi_context.n_clients when instance is closed */ - struct context context; + struct context context; /**< The context structure storing state + * for this VPN tunnel. */ }; -/* - * One multi_context object per server daemon thread. + +/** + * Main OpenVPN server state structure. + * + * This structure is used by OpenVPN processes running in server-mode to + * store all the VPN tunnel and process-wide state. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes the role the structure plays when OpenVPN is running in + * server-mode. */ struct multi_context { # define MC_UNDEF 0 @@ -99,12 +124,19 @@ struct multi_context { # define MC_WORK_THREAD (MC_MULTI_THREADED_WORKER|MC_MULTI_THREADED_SCHEDULER) int thread_mode; - struct hash *hash; /* client instances indexed by real address */ - struct hash *vhash; /* client instances indexed by virtual address */ - struct hash *iter; /* like real address hash but optimized for iteration */ + struct hash *hash; /**< VPN tunnel instances indexed by real + * address of the remote peer. */ + struct hash *vhash; /**< VPN tunnel instances indexed by + * virtual address of remote hosts. */ + struct hash *iter; /**< VPN tunnel instances indexed by real + * address of the remote peer, optimized + * for iteration. */ struct schedule *schedule; - struct mbuf_set *mbuf; - struct multi_tcp *mtcp; + struct mbuf_set *mbuf; /**< Set of buffers for passing data + * channel packets between VPN tunnel + * instances. */ + struct multi_tcp *mtcp; /**< State specific to OpenVPN using TCP + * as external transport. */ struct ifconfig_pool *ifconfig_pool; struct frequency_limit *new_connection_limiter; struct mroute_helper *route_helper; @@ -127,7 +159,8 @@ struct multi_context { struct context_buffers *context_buffers; time_t per_second_trigger; - struct context top; + struct context top; /**< Storage structure for process-wide + * configuration. */ }; /* @@ -146,11 +179,22 @@ struct multi_route time_t last_reference; }; -/* - * top level function, called by openvpn.c + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in server mode. + * @ingroup eventloop + * + * This function calls the appropriate main event loop function depending + * on the transport protocol used: + * - \c tunnel_server_udp() + * - \c tunnel_server_tcp() + * + * @param top - Top-level context structure. */ void tunnel_server (struct context *top); + const char *multi_instance_string (const struct multi_instance *mi, bool null, struct gc_arena *gc); /* @@ -172,11 +216,77 @@ bool multi_process_timeout (struct multi_context *m, const unsigned int mpp_flag #define MPP_CONDITIONAL_PRE_SELECT (1<<1) #define MPP_CLOSE_ON_SIGNAL (1<<2) #define MPP_RECORD_TOUCH (1<<3) + + +/**************************************************************************/ +/** + * Perform postprocessing of a VPN tunnel instance. + * + * After some VPN tunnel activity has taken place, the VPN tunnel's state + * may need updating and some follow-up action may be required. This + * function controls the necessary postprocessing. It is called by many + * other functions that handle VPN tunnel related activity, such as \c + * multi_process_incoming_link(), \c multi_process_outgoing_link(), \c + * multi_process_incoming_tun(), \c multi_process_outgoing_tun(), and \c + * multi_process_timeout(), among others. + * + * @param m - The single \c multi_context structure. + * @param mi - The \c multi_instance of the VPN tunnel to be + * postprocessed. + * @param flags - Fast I/O optimization flags. + * + * @return + * - True, if the VPN tunnel instance \a mi was not closed due to a + * signal during processing. + * - False, if the VPN tunnel instance \a mi was closed. + */ bool multi_process_post (struct multi_context *m, struct multi_instance *mi, const unsigned int flags); + +/**************************************************************************/ +/** + * Demultiplex and process a packet received over the external network + * interface. + * @ingroup external_multiplexer + * + * This function determines which VPN tunnel instance the incoming packet + * is associated with, and then calls \c process_incoming_link() to handle + * it. Afterwards, if the packet is destined for a broadcast/multicast + * address or a remote host reachable through a different VPN tunnel, this + * function takes care of sending it they are. + * + * @note This function is only used by OpenVPN processes which are running + * in server mode, and can therefore sustain multiple active VPN + * tunnels. + * + * @param m - The single \c multi_context structure. + * @param instance - The VPN tunnel state structure associated with + * the incoming packet, if known, as is the case + * when using TCP transport. Otherwise NULL, as is + * the case when using UDP transport. + * @param mpp_flags - Fast I/O optimization flags. + */ bool multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags); + + +/** + * Determine the destination VPN tunnel of a packet received over the + * virtual tun/tap network interface and then process it accordingly. + * @ingroup internal_multiplexer + * + * This function determines which VPN tunnel instance the packet is + * destined for, and then calls \c process_outgoing_tun() to handle it. + * + * @note This function is only used by OpenVPN processes which are running + * in server mode, and can therefore sustain multiple active VPN + * tunnels. + * + * @param m - The single \c multi_context structure. + * @param mpp_flags - Fast I/O optimization flags. + */ bool multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flags); + void multi_process_drop_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags); void multi_print_status (struct multi_context *m, struct status_output *so, const int version); @@ -397,8 +507,23 @@ multi_get_timeout (struct multi_context *m, struct timeval *dest) } } -/* - * Send a packet to TUN/TAP interface. + +/** + * Send a packet over the virtual tun/tap network interface to its locally + * reachable destination. + * @ingroup internal_multiplexer + * + * This function calls \c process_outgoing_tun() to perform the actual + * sending of the packet. Afterwards, it calls \c multi_process_post() to + * perform server-mode postprocessing. + * + * @param m - The single \c multi_context structure. + * @param mpp_flags - Fast I/O optimization flags. + * + * @return + * - True, if the \c multi_instance associated with the packet sent was + * not closed due to a signal during processing. + * - Falls, if the \c multi_instance was closed. */ static inline bool multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flags) @@ -419,6 +544,8 @@ multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flag return ret; } + + static inline bool multi_process_outgoing_link_dowork (struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags) { diff --git a/openvpn.c b/openvpn.c index 99b343b..520fda1 100644 --- a/openvpn.c +++ b/openvpn.c @@ -42,6 +42,16 @@ process_signal_p2p (struct context *c) return process_signal (c); } + + +/**************************************************************************/ +/** + * Main event loop for OpenVPN in client mode, where only one VPN tunnel + * is active. + * @ingroup eventloop + * + * @param c - The context structure of the single active VPN tunnel. + */ static void tunnel_point_to_point (struct context *c) { @@ -90,6 +100,27 @@ tunnel_point_to_point (struct context *c) #undef PROCESS_SIGNAL_P2P + +/**************************************************************************/ +/** + * OpenVPN's main init-run-cleanup loop. + * @ingroup eventloop + * + * This function contains the two outer OpenVPN loops. Its structure is + * as follows: + * - Once-per-process initialization. + * - Outer loop, run at startup and then once per \c SIGHUP: + * - Level 1 initialization + * - Inner loop, run at startup and then once per \c SIGUSR1: + * - Call event loop function depending on client or server mode: + * - \c tunnel_point_to_point() + * - \c tunnel_server() + * - Level 1 cleanup + * - Once-per-process cleanup. + * + * @param argc - Commandline argument count. + * @param argv - Commandline argument values. + */ int main (int argc, char *argv[]) { diff --git a/openvpn.h b/openvpn.h index 33661df..bd6e873 100644 --- a/openvpn.h +++ b/openvpn.h @@ -126,10 +126,14 @@ struct context_persist int restart_sleep_seconds; }; -/* - * level 0 context contains data related to - * once-per OpenVPN instantiation events - * such as daemonization. + +/**************************************************************************/ +/** + * Level 0 %context containing information related to the OpenVPN process. + * + * Level 0 state is initialized once at program startup, and then remains + * throughout the lifetime of the OpenVPN process. This structure + * contains information related to the process's PID, user, and group. */ struct context_0 { @@ -143,14 +147,21 @@ struct context_0 struct group_state group_state; }; -/* - * Contains the persist-across-restart OpenVPN tunnel instance state. - * Reset only for SIGHUP restarts. + +/** + * Level 1 %context containing state that persists across \c SIGUSR1 + * restarts. + * + * Level 1 state is reset on \c SIGHUP restarts. This structure is + * initialized for every iteration of the \c main() function's outer \c + * SIGHUP loop, but persists over iteration of that function's inner \c + * SIGUSR1 loop. */ struct context_1 { - /* local and remote addresses */ struct link_socket_addr link_socket_addr; + /**< Local and remote addresses on the + * external network. */ /* tunnel session keys */ struct key_schedule ks; @@ -158,12 +169,14 @@ struct context_1 /* persist crypto sequence number to/from file */ struct packet_id_persist pid_persist; - /* TUN/TAP interface */ - struct tuntap *tuntap; - bool tuntap_owned; + struct tuntap *tuntap; /**< Tun/tap virtual network interface. */ + bool tuntap_owned; /**< Whether the tun/tap interface should + * be cleaned up when this %context is + * cleaned up. */ - /* list of --route directives */ struct route_list *route_list; + /**< List of routing information. See the + * \c --route command line option. */ /* list of --route-ipv6 directives */ struct route_ipv6_list *route_ipv6_list; @@ -194,20 +207,30 @@ struct context_1 /* if client mode, hash of option strings we pulled from server */ struct md5_digest pulled_options_digest_save; + /**< Hash of option strings received from the + * remote OpenVPN server. Only used in + * client-mode. */ - /* save user/pass for authentication */ struct user_pass *auth_user_pass; + /**< Username and password for + * authentication. */ #endif }; -/* - * Contains the OpenVPN tunnel instance state, wiped across - * SIGUSR1 and SIGHUP restarts. +/** + * Level 2 %context containing state that is reset on both \c SIGHUP and + * \c SIGUSR1 restarts. + * + * This structure is initialized at the top of the \c + * tunnel_point_to_point(), \c tunnel_server_udp_single_threaded(), and \c + * tunnel_server_tcp() functions. In other words, it is reset for every + * iteration of the \c main() function's inner \c SIGUSR1 loop. */ struct context_2 { - /* garbage collection arena for context_2 scope */ - struct gc_arena gc; + struct gc_arena gc; /**< Garbage collection arena for + * allocations done in the level 2 scope + * of this context_2 structure. */ /* our global wait events */ struct event_set *event_set; @@ -315,12 +338,19 @@ struct context_2 */ #ifdef USE_SSL - /* master OpenVPN SSL/TLS object */ - struct tls_multi *tls_multi; + struct tls_multi *tls_multi; /**< TLS state structure for this VPN + * tunnel. */ - /* check --tls-auth signature without needing - a full-size tls_multi object */ struct tls_auth_standalone *tls_auth_standalone; + /**< TLS state structure required for the + * initial authentication of a client's + * connection attempt. This structure + * is used by the \c + * tls_pre_decrypt_lite() function when + * it performs the HMAC firewall check + * on the first connection packet + * received from a new client. See the + * \c --tls-auth commandline option. */ /* used to optimize calls to tls_multi_process */ struct interval tmp_int; @@ -330,10 +360,11 @@ struct context_2 #endif /* USE_SSL */ - /* passed to encrypt or decrypt, contains all - crypto-related command line options related - to data channel encryption/decryption */ struct crypto_options crypto_options; + /**< Security parameters and crypto state + * used by the \link data_crypto Data + * Channel Crypto module\endlink to + * process data channel packet. */ /* used to keep track of data channel packet sequence numbers */ struct packet_id packet_id; @@ -341,11 +372,11 @@ struct context_2 #endif /* USE_CRYPTO */ - /* - * LZO compression library workspace. - */ #ifdef USE_LZO struct lzo_compress_workspace lzo_compwork; + /**< Compression workspace used by the + * \link compression Data Channel + * Compression module\endlink. */ #endif /* @@ -462,16 +493,25 @@ struct context_2 #endif }; -/* + +/** * Contains all state information for one tunnel. + * + * This structure represents one VPN tunnel. It is used to store state + * information related to a VPN tunnel, but also includes process-wide + * data, such as configuration options. + * + * The @ref tunnel_state "Structure of VPN tunnel state storage" related + * page describes how this structure is used in client-mode and + * server-mode. */ struct context { - /* command line or config file options */ - struct options options; + struct options options; /**< Options loaded from command line or + * configuration file. */ - /* true on initial VPN iteration */ - bool first_time; + bool first_time; /**< True on the first iteration of + * OpenVPN's main loop. */ /* context modes */ # define CM_P2P 0 /* standalone point-to-point session or client */ @@ -479,41 +519,32 @@ struct context # define CM_TOP_CLONE 2 /* clone of a CM_TOP context for one thread */ # define CM_CHILD_UDP 3 /* child context of a CM_TOP or CM_THREAD */ # define CM_CHILD_TCP 4 /* child context of a CM_TOP or CM_THREAD */ - int mode; + int mode; /**< Role of this context within the + * OpenVPN process. Valid values are \c + * CM_P2P, \c CM_TOP, \c CM_TOP_CLONE, + * \c CM_CHILD_UDP, and \c CM_CHILD_TCP. */ - /* garbage collection for context scope - allocations */ - struct gc_arena gc; + struct gc_arena gc; /**< Garbage collection arena for + * allocations done in the scope of this + * context structure. */ - /* environmental variable settings */ - struct env_set *es; + struct env_set *es; /**< Set of environment variables. */ - /* signal info */ - struct signal_info *sig; + struct signal_info *sig; /**< Internal error signaling object. */ - /* shared object plugins */ - struct plugin_list *plugins; - bool plugins_owned; + struct plugin_list *plugins; /**< List of plug-ins. */ + bool plugins_owned; /**< Whether the plug-ins should be + * cleaned up when this %context is + * cleaned up. */ - /* set to true after we daemonize */ - bool did_we_daemonize; + bool did_we_daemonize; /**< Whether demonization has already + * taken place. */ - /* persistent across SIGHUP */ struct context_persist persist; - - /* level 0 context contains data related to - once-per OpenVPN instantiation events - such as daemonization */ - struct context_0 *c0; - - /* level 1 context is preserved for - SIGUSR1 restarts, but initialized - for SIGHUP restarts */ - struct context_1 c1; - - /* level 2 context is initialized for all - restarts (SIGUSR1 and SIGHUP) */ - struct context_2 c2; + /**< Persistent %context. */ + struct context_0 *c0; /**< Level 0 %context. */ + struct context_1 c1; /**< Level 1 %context. */ + struct context_2 c2; /**< Level 2 %context. */ }; /* -- cgit