OpenVPN
dco_win.c File Reference
#include "syshead.h"
#include "dco.h"
#include "forward.h"
#include "tun.h"
#include "crypto.h"
#include "multi.h"
#include "ssl_common.h"
#include "openvpn.h"
#include <bcrypt.h>
#include <winsock2.h>
#include <ws2tcpip.h>
Include dependency graph for dco_win.c:

Go to the source code of this file.

Functions

static void dco_wait_ready (DWORD idx)
static bool dco_get_version (OVPN_VERSION *version)
 Gets version of dco-win driver.
void ovpn_dco_init_mp (dco_context_t *dco, const char *dev_node)
 Initializes the DCO adapter in multipeer mode and sets it to "connected" state.
void dco_p2p_start_vpn (struct tuntap *tt)
 Transitions the DCO adapter to the connected state in P2P mode.
bool ovpn_dco_init (struct context *c)
 Initializes DCO depends on mode.
int open_tun_dco (struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
static void dco_connect_wait (HANDLE handle, OVERLAPPED *ov, int timeout, struct signal_info *sig_info)
void dco_mp_start_vpn (HANDLE handle, struct link_socket *sock)
 Initializes and binds the kernel UDP transport socket for multipeer mode.
void dco_p2p_new_peer (HANDLE handle, OVERLAPPED *ov, struct link_socket *sock, struct signal_info *sig_info)
int dco_new_peer (dco_context_t *dco, unsigned int peerid, socket_descriptor_t sd, struct sockaddr *localaddr, struct sockaddr *remoteaddr, const struct in_addr *vpn_ipv4, const struct in6_addr *vpn_ipv6)
int dco_del_peer (dco_context_t *dco, unsigned int peerid)
int dco_set_peer (dco_context_t *dco, unsigned int peerid, int keepalive_interval, int keepalive_timeout, int mss)
int dco_new_key (dco_context_t *dco, unsigned int peerid, int keyid, dco_key_slot_t slot, const uint8_t *encrypt_key, const uint8_t *encrypt_iv, const uint8_t *decrypt_key, const uint8_t *decrypt_iv, const char *ciphername, bool epoch)
int dco_del_key (dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
int dco_swap_keys (dco_context_t *dco, unsigned int peer_id)
bool dco_available (msglvl_t msglevel)
const char * dco_version_string (struct gc_arena *gc)
static void dco_handle_overlapped_success (dco_context_t *dco, bool queued)
 Handles successful completion of overlapped operation.
int dco_read_and_process (dco_context_t *dco)
int dco_get_peer_stats_multi (dco_context_t *dco, const bool raise_sigusr1_on_err)
int dco_get_peer_stats_fallback (struct context *c, const bool raise_sigusr1_on_err)
int dco_get_peer_stats (struct context *c, const bool raise_sigusr1_on_err)
void dco_event_set (dco_context_t *dco, struct event_set *es, void *arg)
const char * dco_get_supported_ciphers (void)
bool dco_win_supports_multipeer (void)
void dco_win_add_iroute_ipv4 (dco_context_t *dco, in_addr_t dst, unsigned int netbits, unsigned int peer_id)
void dco_win_add_iroute_ipv6 (dco_context_t *dco, struct in6_addr dst, unsigned int netbits, unsigned int peer_id)
void dco_win_del_iroute_ipv4 (dco_context_t *dco, in_addr_t dst, unsigned int netbits)
void dco_win_del_iroute_ipv6 (dco_context_t *dco, struct in6_addr dst, unsigned int netbits)
bool dco_supports_epoch_data (struct context *c)

Function Documentation

◆ dco_available()

bool dco_available ( msglvl_t msglevel)

Definition at line 620 of file dco_win.c.

References msg.

◆ dco_connect_wait()

void dco_connect_wait ( HANDLE handle,
OVERLAPPED * ov,
int timeout,
struct signal_info * sig_info )
static

◆ dco_del_key()

int dco_del_key ( dco_context_t * dco,
unsigned int peerid,
dco_key_slot_t slot )

Definition at line 586 of file dco_win.c.

References D_DCO, and msg.

◆ dco_del_peer()

int dco_del_peer ( dco_context_t * dco,
unsigned int peerid )

Definition at line 471 of file dco_win.c.

References D_DCO_DEBUG, M_ERRNO, M_WARN, msg, OVPN_IOCTL_DEL_PEER, and OVPN_IOCTL_MP_DEL_PEER.

◆ dco_event_set()

void dco_event_set ( dco_context_t * dco,
struct event_set * es,
void * arg )

◆ dco_get_peer_stats()

◆ dco_get_peer_stats_fallback()

◆ dco_get_peer_stats_multi()

◆ dco_get_supported_ciphers()

const char * dco_get_supported_ciphers ( void )

Definition at line 991 of file dco_win.c.

References status.

◆ dco_get_version()

bool dco_get_version ( OVPN_VERSION * version)
static

Gets version of dco-win driver.

Fills Major/Minor/Patch fields in a passed OVPN_VERSION struct. If version cannot be obtained, fields are set to 0.

Parameters
versionpointer to OVPN_VERSION struct
Returns
true if version has been obtained, false otherwise

Definition at line 73 of file dco_win.c.

References CLEAR, D_DCO_DEBUG, _OVPN_VERSION::Major, _OVPN_VERSION::Minor, msg, OVPN_IOCTL_GET_VERSION, and _OVPN_VERSION::Patch.

Referenced by dco_supports_epoch_data(), dco_version_string(), and dco_win_supports_multipeer().

◆ dco_handle_overlapped_success()

void dco_handle_overlapped_success ( dco_context_t * dco,
bool queued )
static

Handles successful completion of overlapped operation.

We use overlapped I/O (Windows term for asynchronous I/O) to get notifications from kernel to userspace. This gets the result of overlapped operation and, in case of success, copies data from kernel-filled buffer into userspace-provided dco context.

Parameters
dcoPointer to the dco context
queuedtrue if operation was queued, false if it has completed immediately

Definition at line 674 of file dco_win.c.

References D_DCO_DEBUG, M_ERRNO, and msg.

Referenced by dco_read_and_process().

◆ dco_mp_start_vpn()

void dco_mp_start_vpn ( HANDLE handle,
struct link_socket * sock )

Initializes and binds the kernel UDP transport socket for multipeer mode.

Sends OVPN_IOCTL_MP_START_VPN to create a kernel-mode UDP socket, binds it to the specified address, ready for incoming connections.

Parameters
handleDevice handle for the DCO adapter.
sockPointer to the link_socket structure containing socket information.

Definition at line 283 of file dco_win.c.

References _OVPN_MP_START_VPN::Addr4, _OVPN_MP_START_VPN::Addr6, addr_family_name(), link_socket_info::bind_ipv6_only, link_socket_addr::bind_local, D_DCO_DEBUG, link_socket::info, _OVPN_MP_START_VPN::IPv6Only, _OVPN_MP_START_VPN::ListenAddress, link_socket_info::lsa, M_ERR, M_FATAL, msg, OVPN_IOCTL_MP_START_VPN, SF_PREPEND_SA, and link_socket::sockflags.

Referenced by create_socket_dco_win().

◆ dco_new_key()

int dco_new_key ( dco_context_t * dco,
unsigned int peerid,
int keyid,
dco_key_slot_t slot,
const uint8_t * encrypt_key,
const uint8_t * encrypt_iv,
const uint8_t * decrypt_key,
const uint8_t * decrypt_iv,
const char * ciphername,
bool epoch )

◆ dco_new_peer()

int dco_new_peer ( dco_context_t * dco,
unsigned int peerid,
socket_descriptor_t sd,
struct sockaddr * localaddr,
struct sockaddr * remoteaddr,
const struct in_addr * vpn_ipv4,
const struct in6_addr * vpn_ipv6 )

◆ dco_p2p_new_peer()

◆ dco_p2p_start_vpn()

void dco_p2p_start_vpn ( struct tuntap * tt)

Transitions the DCO adapter to the connected state in P2P mode.

Sends OVPN_IOCTL_START_VPN to start the VPN and waits for the adapter to become ready.

Parameters
ttPointer to the tuntap structure representing the adapter.

Definition at line 165 of file dco_win.c.

References tuntap::adapter_index, dco_wait_ready(), tuntap::hand, M_ERR, msg, and OVPN_IOCTL_START_VPN.

Referenced by ovpn_dco_init().

◆ dco_read_and_process()

◆ dco_set_peer()

int dco_set_peer ( dco_context_t * dco,
unsigned int peerid,
int keepalive_interval,
int keepalive_timeout,
int mss )

◆ dco_supports_epoch_data()

bool dco_supports_epoch_data ( struct context * c)

Definition at line 1104 of file dco_win.c.

References dco_get_version(), _OVPN_VERSION::Major, and _OVPN_VERSION::Minor.

◆ dco_swap_keys()

int dco_swap_keys ( dco_context_t * dco,
unsigned int peer_id )

Definition at line 594 of file dco_win.c.

References D_DCO_DEBUG, M_ERRNO, M_WARN, msg, OVPN_IOCTL_MP_SWAP_KEYS, and OVPN_IOCTL_SWAP_KEYS.

◆ dco_version_string()

const char * dco_version_string ( struct gc_arena * gc)

◆ dco_wait_ready()

void dco_wait_ready ( DWORD idx)
static

Definition at line 49 of file dco_win.c.

References D_DCO_DEBUG, and msg.

Referenced by dco_p2p_start_vpn(), and ovpn_dco_init_mp().

◆ dco_win_add_iroute_ipv4()

void dco_win_add_iroute_ipv4 ( dco_context_t * dco,
in_addr_t dst,
unsigned int netbits,
unsigned int peer_id )

◆ dco_win_add_iroute_ipv6()

void dco_win_add_iroute_ipv6 ( dco_context_t * dco,
struct in6_addr dst,
unsigned int netbits,
unsigned int peer_id )

◆ dco_win_del_iroute_ipv4()

void dco_win_del_iroute_ipv4 ( dco_context_t * dco,
in_addr_t dst,
unsigned int netbits )

◆ dco_win_del_iroute_ipv6()

void dco_win_del_iroute_ipv6 ( dco_context_t * dco,
struct in6_addr dst,
unsigned int netbits )

◆ dco_win_supports_multipeer()

bool dco_win_supports_multipeer ( void )

Definition at line 1013 of file dco_win.c.

References dco_get_version(), and _OVPN_VERSION::Major.

◆ open_tun_dco()

int open_tun_dco ( struct tuntap * tt,
openvpn_net_ctx_t * ctx,
const char * dev )

Definition at line 215 of file dco_win.c.

References ASSERT.

◆ ovpn_dco_init()

bool ovpn_dco_init ( struct context * c)

Initializes DCO depends on mode.

  • for P2P it puts adapter in "connected" state. The peer should be already added by dco_p2p_new_peer().
  • for multipeer it opens DCO adapter and puts it into "connected" state. The server socket should be initialized later by dco_mp_start_vpn().

Definition at line 190 of file dco_win.c.

References ASSERT, context::c1, tuntap::dco, dco_p2p_start_vpn(), options::dev_node, context::mode, MODE_POINT_TO_POINT, MODE_SERVER, context::options, ovpn_dco_init_mp(), and context_1::tuntap.

◆ ovpn_dco_init_mp()

void ovpn_dco_init_mp ( dco_context_t * dco,
const char * dev_node )

Initializes the DCO adapter in multipeer mode and sets it to "connected" state.

Opens the DCO device, sets the adapter mode using OVPN_IOCTL_SET_MODE, which transitions the adapter to the "connected" state, and waits for it to become ready.

Parameters
dcoPointer to the dco_context_t structure representing the DCO context.
dev_nodeDevice node string for the DCO adapter.

Definition at line 122 of file dco_win.c.

References ASSERT, dco_wait_ready(), gc, gc_free(), gc_new(), M_ERR, msg, OVPN_IOCTL_SET_MODE, OVPN_MODE_MP, and tun_open_device().

Referenced by ovpn_dco_init().