OpenVPN
Functions
External Multiplexer module

The External Multiplexer is the link between the external network interface and the other OpenVPN modules. More...

Functions

void read_incoming_link (struct context *c)
 Read a packet from the external network interface. More...
 
bool process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated)
 Starts processing a packet read from the external network interface. More...
 
void process_incoming_link_part2 (struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf)
 Continues processing a packet read from the external network interface. More...
 
void process_outgoing_link (struct context *c)
 Write a packet to the external network interface. More...
 
struct multi_instancemulti_get_create_instance_udp (struct multi_context *m, bool *floated)
 Get, and if necessary create, the multi_instance associated with a packet's source address. More...
 
bool multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags)
 Demultiplex and process a packet received over the external network interface. More...
 
bool tls_pre_decrypt (struct tls_multi *multi, const struct link_socket_actual *from, struct buffer *buf, struct crypto_options **opt, bool floated, const uint8_t **ad_start)
 Determine whether an incoming packet is a data channel or control channel packet, and process accordingly. More...
 

Detailed Description

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 Data Channel Control module and are destined for a remote host reachable through a VPN tunnel.

Function Documentation

◆ multi_get_create_instance_udp()

struct multi_instance* multi_get_create_instance_udp ( struct multi_context m,
bool floated 
)

Get, and if necessary create, the multi_instance associated with a packet's source address.

This function extracts the source address of a recently read packet from m->top.c2.from and uses that source address as a hash key for the hash table 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.

Parameters
m- The single multi_context structure.
Returns
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.

Definition at line 51 of file mudp.c.

References ASSERT, BPTR, context_2::buf, context::c2, check_debug_level(), multi_instance::context, D_MULTI_DEBUG, D_MULTI_ERRORS, D_MULTI_MEDIUM, link_socket_actual::dest, multi_instance::did_real_hash, dmsg, frequency_limit_event_allowed(), context_2::from, gc_free(), gc_new(), multi_instance::halt, multi_context::hash, hash_add_fast(), hash_bucket(), hash_lookup_fast(), hash_value(), multi_context::instances, buffer::len, link_socket_actual_match(), multi_context::max_clients, MAX_PEER_ID, mroute_addr_print(), mroute_extract_openvpn_sockaddr(), msg, multi_create_instance(), multi_context::new_connection_limiter, P_DATA_V2, P_OPCODE_SHIFT, tls_multi::peer_id, multi_instance::real, status, context_2::tls_auth_standalone, context_2::tls_multi, tls_pre_decrypt_lite(), multi_context::top, ungenerate_prefix(), and hash_element::value.

Referenced by multi_process_incoming_link().

◆ multi_process_incoming_link()

bool multi_process_incoming_link ( struct multi_context m,
struct multi_instance instance,
const unsigned int  mpp_flags 
)

Demultiplex and process a packet received over the external network interface.

This function determines which VPN tunnel instance the incoming packet is associated with, and then calls 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.
Parameters
m- The single multi_context structure.
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.
mpp_flags- Fast I/O optimization flags.

Definition at line 2488 of file multi.c.

References ASSERT, BLEN, context_2::buf, context::c1, context::c2, clear_prefix(), multi_instance::context, D_MULTI_DROPPED, D_PF_DROPPED, buffer::data, DEV_TYPE_TAP, DEV_TYPE_TUN, multi_context::enable_c2c, ENABLE_PF, context_2::from, gc_free(), gc_new(), get_link_socket_info(), buffer::len, MAPF_SHOW_ARP, mi_prefix(), MR_ADDR_IPV6, MR_ADDR_MASK, mroute_addr_print(), mroute_addr_print_ex(), mroute_addr_reset(), mroute_extract_addr_from_packet(), MROUTE_EXTRACT_BCAST, MROUTE_EXTRACT_MCAST, MROUTE_EXTRACT_SUCCEEDED, msg, multi_bcast(), multi_get_create_instance_udp(), multi_get_instance_by_virtual_addr(), multi_learn_addr(), multi_process_float(), multi_process_post(), multi_set_pending(), multi_unicast(), multi_context::pending, perf_pop(), PERF_PROC_IN_LINK, perf_push(), process_incoming_link_part1(), process_incoming_link_part2(), register_activity(), set_prefix(), context_2::to_tun, multi_context::top, TUNNEL_TYPE, context_1::tuntap, mroute_addr::type, and mroute_addr::v6.

Referenced by multi_process_io_udp(), and multi_tcp_dispatch().

◆ process_incoming_link_part1()

bool process_incoming_link_part1 ( struct context c,
struct link_socket_info lsi,
bool  floated 
)

Starts processing a packet read from the external network interface.

This function starts 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 c.
  • Call 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 openvpn_decrypt() of the Data Channel Crypto module to authenticate and decrypt the packet using the security parameters loaded by tls_pre_decrypt() above.
Parameters
c- The context structure of the VPN tunnel associated with the packet.
lsi- link_socket_info obtained from context before processing.
floated- Flag indicates that peer has floated.
Returns
true if packet is authenticated, false otherwise.

Definition at line 783 of file forward.c.

References link_socket_info::af, BLEN, BPTR, context_2::buf, buf_reset(), context_2::buffers, context::c2, CAS_SUCCEEDED, context_2::context_auth, context_2::crypto_options, D_LINK_RW, D_STREAM_ERRORS, context_buffers::decrypt_buf, event_timeout_reset(), context_2::frame, context_2::frame_initial, context_2::from, gc_free(), gc_new(), interval_action(), is_hard_reset(), options::key_method, buffer::len, context_2::link_read_bytes, link_read_bytes_global, context_2::link_socket, link_socket_bad_incoming_addr(), link_socket_connection_oriented(), link_socket_verify_incoming_addr(), context_2::link_write_bytes, context_2::log_rw, management_bytes_in(), msg, openvpn_decrypt(), context::options, context_2::original_recv_size, P_OPCODE_SHIFT, context_2::ping_rec_interval, options::ping_rec_timeout, print_link_socket_actual(), link_socket_info::proto, proto2ascii(), PROTO_DUMP, register_signal(), SIGUSR1, context_2::tls_multi, tls_pre_decrypt(), context_2::tmp_int, and context_2::to_tun.

Referenced by multi_process_incoming_link(), and process_incoming_link().

◆ process_incoming_link_part2()

void process_incoming_link_part2 ( struct context c,
struct link_socket_info lsi,
const uint8_t orig_buf 
)

Continues processing a packet read from the external network interface.

This function continues the processing of a data channel packet which has come out of a VPN tunnel. It must be called after process_incoming_link_part1() function.

It's high-level structure is as follows:

Parameters
c- The context structure of the VPN tunnel associated with the packet.
lsi- link_socket_info obtained from context before processing.
orig_buf- Pointer to a buffer data.

Definition at line 926 of file forward.c.

References BLEN, BPTR, context_2::buf, buf_reset(), buffer_turnover(), context_2::buffers, context::c1, context::c2, D_PING, dmsg, context_2::es, event_timeout_reset(), context_2::fragment, fragment_incoming(), context_2::frame, context_2::frame_fragment, context_2::from, is_occ_msg(), is_ping_msg(), buffer::len, context_2::link_read_bytes_auth, link_socket_set_outgoing_addr(), max_int(), context_2::max_recv_size_local, context::options, context_2::original_recv_size, context_2::ping_rec_interval, options::ping_rec_timeout, process_received_occ_msg(), context_buffers::read_link_buf, TLS_MODE, context_2::to_tun, TUNNEL_TYPE, context_1::tuntap, and tuntap_defined().

Referenced by multi_process_incoming_link(), and process_incoming_link().

◆ process_outgoing_link()

void process_outgoing_link ( struct context c)

◆ read_incoming_link()

void read_incoming_link ( struct context c)

Read a packet from the external network interface.

The packet read from the external network interface is stored in c->c2.buf and its source address in c->c2.from. If an error occurred, the length of 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.

Parameters
c- The context structure which contains the external network socket from which to read incoming packets.

Definition at line 715 of file forward.c.

References ASSERT, context_2::buf, buf_init, context_2::buffers, context::c2, check_status(), D_STREAM_ERRORS, event_timeout_defined(), context_2::explicit_exit_notification_interval, context_2::frame, FRAME_HEADROOM_ADJ, FRAME_HEADROOM_MARKER_READ_LINK, context_2::from, options::inetd, context_2::link_socket, link_socket_read(), management_sleep(), msg, context::options, perf_pop(), perf_push(), PERF_READ_IN_LINK, context_buffers::read_link_buf, register_signal(), SIGTERM, SIGUSR1, socket_connection_reset(), socks_postprocess_incoming_link(), and status.

Referenced by multi_process_io_udp(), multi_tcp_dispatch(), and process_io().

◆ tls_pre_decrypt()

bool tls_pre_decrypt ( struct tls_multi multi,
const struct link_socket_actual from,
struct buffer buf,
struct crypto_options **  opt,
bool  floated,
const uint8_t **  ad_start 
)

Determine whether an incoming packet is a data channel or control channel packet, and process accordingly.

When OpenVPN is in TLS mode, this is the first function to process an incoming packet. It inspects the packet's one-byte header which contains the packet's opcode and key ID. Depending on the opcode, the packet is processed as a data channel or as a control channel packet.

Data channel packets

If the opcode indicates the packet is a data channel packet, then the packet's key ID is used to find the local TLS state it is associated with. This state is checked whether it is active, authenticated, and its remote peer is the source of this packet. If these checks passed, the state's security parameters are loaded into the opt crypto options so that openvpn_decrypt() can later use them to authenticate and decrypt the packet.

This function then returns false. The buf buffer has not been modified, except for removing the header.

Control channel packets

If the opcode indicates the packet is a control channel packet, then this function will process it based on its plaintext header. depending on the packet's opcode and session ID this function determines if it is destined for an active TLS session, or whether a new TLS session should be started. This function also initiates data channel session key renegotiation if the received opcode requests that.

If the incoming packet is destined for an active TLS session, then the packet is inserted into the Reliability Layer and will be handled later.

Parameters
multi- The TLS multi structure associated with the VPN tunnel of this packet.
from- The source address of the packet.
buf- A buffer structure containing the incoming packet.
opt- Returns a crypto options structure with the appropriate security parameters to handle the packet if it is a data channel packet.
ad_start- Returns a pointer to the start of the authenticated data of of this packet
Returns
  • True if the packet is a control channel packet that has been processed successfully.
  • False if the packet is a data channel packet, or if an error occurred during processing of a control channel packet.

Definition at line 3305 of file ssl.c.

References ASSERT, key_state::authenticated, BPTR, buf_advance(), buf_copy(), tls_session::burst, key_state::crypto_options, D_MULTI_DROPPED, D_TLS_DEBUG, D_TLS_DEBUG_LOW, D_TLS_ERRORS, D_TLS_KEYSELECT, DECRYPT_KEY_ENABLED, dmsg, ENABLE_DEF_AUTH, gc_free(), gc_new(), key_ctx_bi::initialized, is_hard_reset(), tls_session::key, crypto_options::key_ctx_bi, key_state::key_id, tls_options::key_method, tls_multi::key_scan, KEY_SCAN_SIZE, key_state_soft_reset(), KS_PRIMARY, buffer::len, reliable_ack::len, link_socket_actual_match(), management_set_state(), msg, key_state::n_bytes, key_state::n_packets, tls_multi::n_sessions, tls_multi::n_soft_errors, OPENVPN_STATE_AUTH, tls_multi::opt, P_ACK_V1, P_CONTROL_HARD_RESET_CLIENT_V1, P_CONTROL_HARD_RESET_CLIENT_V2, P_CONTROL_HARD_RESET_SERVER_V1, P_CONTROL_HARD_RESET_SERVER_V2, P_CONTROL_SOFT_RESET_V1, P_DATA_V1, P_DATA_V2, P_KEY_ID_MASK, P_LAST_OPCODE, P_OPCODE_SHIFT, packet_opcode_name(), print_key_id(), print_link_socket_actual(), read_control_auth(), key_state::rec_ack, key_state::rec_reliable, reliable_ack_acknowledge_packet_id(), reliable_ack_read(), reliable_ack_read_packet_id(), reliable_can_get(), reliable_get_buf(), reliable_mark_active_incoming(), reliable_not_replay(), reliable_schedule_now(), reliable_send_purge(), reliable_wont_break_sequentiality(), key_state::remote_addr, S_ERROR, S_UNDEF, key_state::send_reliable, tls_options::server, tls_multi::session, tls_session::session_id, session_id_defined(), session_id_equal(), session_id_print(), session_id_read(), key_state::session_id_remote, tls_options::single_session, key_state::state, state_name(), tls_clear_error(), tls_session::tls_wrap, TM_ACTIVE, TM_LAME_DUCK, TM_SIZE, TM_UNTRUSTED, and tls_session::untrusted_addr.

Referenced by process_incoming_link_part1().