OpenVPN
dco_win.c
Go to the documentation of this file.
1 /*
2  * Interface to ovpn-win-dco networking code
3  *
4  * Copyright (C) 2020-2023 Arne Schwabe <arne@rfc2549.org>
5  * Copyright (C) 2020-2023 OpenVPN Inc <sales@openvpn.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2
9  * as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file COPYING included with this
18  * distribution); if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #if defined(_WIN32)
27 
28 #include "syshead.h"
29 
30 #include "dco.h"
31 #include "tun.h"
32 #include "crypto.h"
33 #include "ssl_common.h"
34 #include "openvpn.h"
35 
36 #include <bcrypt.h>
37 #include <winsock2.h>
38 #include <ws2tcpip.h>
39 
40 #if defined(__MINGW32__)
41 const IN_ADDR in4addr_any = { 0 };
42 #endif
43 
44 struct tuntap
45 create_dco_handle(const char *devname, struct gc_arena *gc)
46 {
47  struct tuntap tt = { .windows_driver = WINDOWS_DRIVER_DCO };
48  const char *device_guid;
49 
50  tun_open_device(&tt, devname, &device_guid, gc);
51 
52  return tt;
53 }
54 
55 bool
57 {
58  return true;
59 }
60 
61 int
62 open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
63 {
64  ASSERT(0);
65  return 0;
66 }
67 
68 static void
69 dco_wait_ready(DWORD idx)
70 {
71  for (int i = 0; i < 20; ++i)
72  {
73  MIB_IPINTERFACE_ROW row = {.InterfaceIndex = idx, .Family = AF_INET};
74  if (GetIpInterfaceEntry(&row) != ERROR_NOT_FOUND)
75  {
76  break;
77  }
78  msg(D_DCO_DEBUG, "interface %ld not yet ready, retrying", idx);
79  Sleep(50);
80  }
81 }
82 
83 void
84 dco_start_tun(struct tuntap *tt)
85 {
86  msg(D_DCO_DEBUG, "%s", __func__);
87 
88  /* reference the tt object inside the DCO context, because the latter will
89  * be passed around
90  */
91  tt->dco.tt = tt;
92 
93  DWORD bytes_returned = 0;
94  if (!DeviceIoControl(tt->hand, OVPN_IOCTL_START_VPN, NULL, 0, NULL, 0,
95  &bytes_returned, NULL))
96  {
97  msg(M_ERR, "DeviceIoControl(OVPN_IOCTL_START_VPN) failed");
98  }
99 
100  /* Sometimes IP Helper API, which we use for setting IP address etc,
101  * complains that interface is not found. Give it some time to settle
102  */
104 }
105 
106 static void
107 dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, struct signal_info *sig_info)
108 {
109  volatile int *signal_received = &sig_info->signal_received;
110  /* GetOverlappedResultEx is available starting from Windows 8 */
111  typedef BOOL (WINAPI *get_overlapped_result_ex_t)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
112  get_overlapped_result_ex_t get_overlapped_result_ex =
113  (get_overlapped_result_ex_t)GetProcAddress(GetModuleHandle("Kernel32.dll"),
114  "GetOverlappedResultEx");
115 
116  if (get_overlapped_result_ex == NULL)
117  {
118  msg(M_ERR, "Failed to load GetOverlappedResult()");
119  }
120 
121  DWORD timeout_msec = timeout * 1000;
122  const int poll_interval_ms = 50;
123 
124  while (timeout_msec > 0)
125  {
126  timeout_msec -= poll_interval_ms;
127 
128  DWORD transferred;
129  if (get_overlapped_result_ex(handle, ov, &transferred, poll_interval_ms, FALSE) != 0)
130  {
131  /* TCP connection established by dco */
132  return;
133  }
134 
135  DWORD err = GetLastError();
136  if ((err != WAIT_TIMEOUT) && (err != ERROR_IO_INCOMPLETE))
137  {
138  /* dco reported connection error */
139  msg(M_NONFATAL | M_ERRNO, "dco connect error");
140  register_signal(sig_info, SIGUSR1, "dco-connect-error");
141  return;
142  }
143 
144  get_signal(signal_received);
145  if (*signal_received)
146  {
147  return;
148  }
149 
150  management_sleep(0);
151  }
152 
153  /* we end up here when timeout occurs in userspace */
154  msg(M_NONFATAL, "dco connect timeout");
155  register_signal(sig_info, SIGUSR1, "dco-connect-timeout");
156 }
157 
158 void
159 dco_create_socket(HANDLE handle, struct addrinfo *remoteaddr, bool bind_local,
160  struct addrinfo *bind, int timeout,
161  struct signal_info *sig_info)
162 {
163  msg(D_DCO_DEBUG, "%s", __func__);
164 
165  OVPN_NEW_PEER peer = { 0 };
166 
167  struct sockaddr *local = NULL;
168  struct sockaddr *remote = remoteaddr->ai_addr;
169 
170  if (remoteaddr->ai_protocol == IPPROTO_TCP
171  || remoteaddr->ai_socktype == SOCK_STREAM)
172  {
173  peer.Proto = OVPN_PROTO_TCP;
174  }
175  else
176  {
177  peer.Proto = OVPN_PROTO_UDP;
178  }
179 
180  if (bind_local)
181  {
182  /* Use first local address with correct address family */
183  while (bind && !local)
184  {
185  if (bind->ai_family == remote->sa_family)
186  {
187  local = bind->ai_addr;
188  }
189  bind = bind->ai_next;
190  }
191  }
192 
193  if (bind_local && !local)
194  {
195  msg(M_FATAL, "DCO: Socket bind failed: Address to bind lacks %s record",
196  addr_family_name(remote->sa_family));
197  }
198 
199  if (remote->sa_family == AF_INET6)
200  {
201  peer.Remote.Addr6 = *((SOCKADDR_IN6 *)(remoteaddr->ai_addr));
202  if (local)
203  {
204  peer.Local.Addr6 = *((SOCKADDR_IN6 *)local);
205  }
206  else
207  {
208  peer.Local.Addr6.sin6_addr = in6addr_any;
209  peer.Local.Addr6.sin6_port = 0;
210  peer.Local.Addr6.sin6_family = AF_INET6;
211  }
212  }
213  else if (remote->sa_family == AF_INET)
214  {
215  peer.Remote.Addr4 = *((SOCKADDR_IN *)(remoteaddr->ai_addr));
216  if (local)
217  {
218  peer.Local.Addr4 = *((SOCKADDR_IN *)local);
219  }
220  else
221  {
222  peer.Local.Addr4.sin_addr = in4addr_any;
223  peer.Local.Addr4.sin_port = 0;
224  peer.Local.Addr4.sin_family = AF_INET;
225  }
226  }
227  else
228  {
229  ASSERT(0);
230  }
231 
232  OVERLAPPED ov = { 0 };
233  if (!DeviceIoControl(handle, OVPN_IOCTL_NEW_PEER, &peer, sizeof(peer), NULL, 0, NULL, &ov))
234  {
235  DWORD err = GetLastError();
236  if (err != ERROR_IO_PENDING)
237  {
238  msg(M_ERR, "DeviceIoControl(OVPN_IOCTL_NEW_PEER) failed");
239  }
240  else
241  {
242  dco_connect_wait(handle, &ov, timeout, sig_info);
243  }
244  }
245 }
246 
247 int
248 dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
249  struct sockaddr *localaddr, struct sockaddr *remoteaddr,
250  struct in_addr *remote_in4, struct in6_addr *remote_in6)
251 {
252  msg(D_DCO_DEBUG, "%s: peer-id %d, fd %d", __func__, peerid, sd);
253  return 0;
254 }
255 
256 int
257 dco_del_peer(dco_context_t *dco, unsigned int peerid)
258 {
259  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peerid);
260 
261  DWORD bytes_returned = 0;
262  if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_DEL_PEER, NULL,
263  0, NULL, 0, &bytes_returned, NULL))
264  {
265  msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_DEL_PEER) failed");
266  return -1;
267  }
268  return 0;
269 }
270 
271 int
272 dco_set_peer(dco_context_t *dco, unsigned int peerid,
273  int keepalive_interval, int keepalive_timeout, int mss)
274 {
275  msg(D_DCO_DEBUG, "%s: peer-id %d, keepalive %d/%d, mss %d", __func__,
276  peerid, keepalive_interval, keepalive_timeout, mss);
277 
278  OVPN_SET_PEER peer;
279 
280  peer.KeepaliveInterval = keepalive_interval;
281  peer.KeepaliveTimeout = keepalive_timeout;
282  peer.MSS = mss;
283 
284  DWORD bytes_returned = 0;
285  if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_SET_PEER, &peer,
286  sizeof(peer), NULL, 0, &bytes_returned, NULL))
287  {
288  msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_SET_PEER) failed");
289  return -1;
290  }
291  return 0;
292 }
293 
294 int
295 dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
296  dco_key_slot_t slot,
297  const uint8_t *encrypt_key, const uint8_t *encrypt_iv,
298  const uint8_t *decrypt_key, const uint8_t *decrypt_iv,
299  const char *ciphername)
300 {
301  msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s",
302  __func__, slot, keyid, peerid, ciphername);
303 
304  const int nonce_len = 8;
305  size_t key_len = cipher_kt_key_size(ciphername);
306 
307  OVPN_CRYPTO_DATA crypto_data;
308  ZeroMemory(&crypto_data, sizeof(crypto_data));
309 
310  crypto_data.CipherAlg = dco_get_cipher(ciphername);
311  crypto_data.KeyId = keyid;
312  crypto_data.PeerId = peerid;
313  crypto_data.KeySlot = slot;
314 
315  CopyMemory(crypto_data.Encrypt.Key, encrypt_key, key_len);
316  crypto_data.Encrypt.KeyLen = (char)key_len;
317  CopyMemory(crypto_data.Encrypt.NonceTail, encrypt_iv, nonce_len);
318 
319  CopyMemory(crypto_data.Decrypt.Key, decrypt_key, key_len);
320  crypto_data.Decrypt.KeyLen = (char)key_len;
321  CopyMemory(crypto_data.Decrypt.NonceTail, decrypt_iv, nonce_len);
322 
323  ASSERT(crypto_data.CipherAlg > 0);
324 
325  DWORD bytes_returned = 0;
326 
327  if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_NEW_KEY, &crypto_data,
328  sizeof(crypto_data), NULL, 0, &bytes_returned, NULL))
329  {
330  msg(M_ERR, "DeviceIoControl(OVPN_IOCTL_NEW_KEY) failed");
331  return -1;
332  }
333  return 0;
334 }
335 int
336 dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
337 {
338  msg(D_DCO, "%s: peer-id %d, slot %d called but ignored", __func__, peerid,
339  slot);
340  /* FIXME: Implement in driver first */
341  return 0;
342 }
343 
344 int
345 dco_swap_keys(dco_context_t *dco, unsigned int peer_id)
346 {
347  msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peer_id);
348 
349  DWORD bytes_returned = 0;
350  if (!DeviceIoControl(dco->tt->hand, OVPN_IOCTL_SWAP_KEYS, NULL, 0, NULL, 0,
351  &bytes_returned, NULL))
352  {
353  msg(M_ERR, "DeviceIoControl(OVPN_IOCTL_SWAP_KEYS) failed");
354  return -1;
355  }
356  return 0;
357 }
358 
359 bool
360 dco_available(int msglevel)
361 {
362  /* try to open device by symbolic name */
363  HANDLE h = CreateFile("\\\\.\\ovpn-dco", GENERIC_READ | GENERIC_WRITE,
364  0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL);
365 
366  if (h != INVALID_HANDLE_VALUE)
367  {
368  CloseHandle(h);
369  return true;
370  }
371 
372  DWORD err = GetLastError();
373  if (err == ERROR_ACCESS_DENIED)
374  {
375  /* this likely means that device exists but is already in use,
376  * don't bail out since later we try to open all existing dco
377  * devices and then bail out if all devices are in use
378  */
379  return true;
380  }
381 
382  msg(msglevel, "Note: ovpn-dco-win driver is missing, disabling data channel offload.");
383  return false;
384 }
385 
386 const char *
388 {
389  OVPN_VERSION version;
390  ZeroMemory(&version, sizeof(OVPN_VERSION));
391 
392  /* try to open device by symbolic name */
393  HANDLE h = CreateFile("\\\\.\\ovpn-dco", GENERIC_READ | GENERIC_WRITE,
394  0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL);
395 
396  if (h == INVALID_HANDLE_VALUE)
397  {
398  return "N/A";
399  }
400 
401  DWORD bytes_returned = 0;
402  if (!DeviceIoControl(h, OVPN_IOCTL_GET_VERSION, NULL, 0,
403  &version, sizeof(version), &bytes_returned, NULL))
404  {
405  CloseHandle(h);
406  return "N/A";
407  }
408 
409  CloseHandle(h);
410 
411  struct buffer out = alloc_buf_gc(256, gc);
412  buf_printf(&out, "%ld.%ld.%ld", version.Major, version.Minor, version.Patch);
413 
414  return BSTR(&out);
415 }
416 
417 int
419 {
420  /* no-op on windows */
421  ASSERT(0);
422  return 0;
423 }
424 
425 int
427 {
428  /* Not implemented. */
429  return 0;
430 }
431 
432 int
434 {
435  struct tuntap *tt = c->c1.tuntap;
436 
437  if (!tuntap_defined(tt))
438  {
439  return -1;
440  }
441 
442  OVPN_STATS stats;
443  ZeroMemory(&stats, sizeof(OVPN_STATS));
444 
445  DWORD bytes_returned = 0;
446  if (!DeviceIoControl(tt->hand, OVPN_IOCTL_GET_STATS, NULL, 0,
447  &stats, sizeof(stats), &bytes_returned, NULL))
448  {
449  msg(M_WARN | M_ERRNO, "DeviceIoControl(OVPN_IOCTL_GET_STATS) failed");
450  return -1;
451  }
452 
456  c->c2.tun_write_bytes = stats.TunBytesSent;
457 
458  return 0;
459 }
460 
461 void
463 {
464  /* no-op on windows */
465  ASSERT(0);
466 }
467 
468 const char *
470 {
471  /*
472  * this API can be called either from user mode or kernel mode,
473  * which enables us to probe driver's chachapoly support
474  * (available starting from Windows 11)
475  */
476 
477  BCRYPT_ALG_HANDLE h;
478  NTSTATUS status = BCryptOpenAlgorithmProvider(&h, L"CHACHA20_POLY1305", NULL, 0);
479  if (BCRYPT_SUCCESS(status))
480  {
481  BCryptCloseAlgorithmProvider(h, 0);
482  return "AES-128-GCM:AES-256-GCM:AES-192-GCM:CHACHA20-POLY1305";
483  }
484  else
485  {
486  return "AES-128-GCM:AES-256-GCM:AES-192-GCM";
487  }
488 }
489 
490 #endif /* defined(_WIN32) */
_OVPN_NEW_PEER::Proto
OVPN_PROTO Proto
Definition: ovpn_dco_win.h:47
signal_info::signal_received
volatile int signal_received
Definition: sig.h:43
D_DCO_DEBUG
#define D_DCO_DEBUG
Definition: errlevel.h:118
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)
Definition: dco_win.c:295
dco_connect_wait
static void dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, struct signal_info *sig_info)
Definition: dco_win.c:107
M_ERRNO
#define M_ERRNO
Definition: error.h:100
dco_get_supported_ciphers
const char * dco_get_supported_ciphers()
Definition: dco_win.c:469
_OVPN_STATS
Definition: ovpn_dco_win.h:50
M_FATAL
#define M_FATAL
Definition: error.h:95
tuntap::windows_driver
enum windows_driver_type windows_driver
Definition: tun.h:213
context_1::tuntap
struct tuntap * tuntap
Tun/tap virtual network interface.
Definition: openvpn.h:170
dco_version_string
const char * dco_version_string(struct gc_arena *gc)
Definition: dco_win.c:387
M_NONFATAL
#define M_NONFATAL
Definition: error.h:96
management_sleep
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
Definition: manage.c:4114
context
Contains all state information for one tunnel.
Definition: openvpn.h:476
es
struct env_set * es
Definition: test_pkcs11.c:133
BSTR
#define BSTR(buf)
Definition: buffer.h:129
context_2::tun_read_bytes
counter_type tun_read_bytes
Definition: openvpn.h:267
_OVPN_VERSION::Minor
LONG Minor
Definition: ovpn_dco_win.h:105
_OVPN_SET_PEER::MSS
LONG MSS
Definition: ovpn_dco_win.h:100
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
create_dco_handle
struct tuntap create_dco_handle(const char *devname, struct gc_arena *gc)
Definition: dco_win.c:45
open_tun_dco
int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
Definition: dco_win.c:62
openvpn.h
bind_local
static void bind_local(struct link_socket *sock, const sa_family_t ai_family)
Definition: socket.c:1086
_OVPN_STATS::TunBytesReceived
LONG64 TunBytesReceived
Definition: ovpn_dco_win.h:67
dco_start_tun
void dco_start_tun(struct tuntap *tt)
Definition: dco_win.c:84
addr_family_name
const char * addr_family_name(int af)
Definition: socket.c:3164
_OVPN_STATS::TransportBytesReceived
LONG64 TransportBytesReceived
Definition: ovpn_dco_win.h:64
openvpn_net_ctx_t
void * openvpn_net_ctx_t
Definition: networking.h:28
dco_get_peer_stats
int dco_get_peer_stats(struct context *c)
Definition: dco_win.c:433
dco_new_peer
int dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd, struct sockaddr *localaddr, struct sockaddr *remoteaddr, struct in_addr *remote_in4, struct in6_addr *remote_in6)
Definition: dco_win.c:248
dco_do_read
int dco_do_read(dco_context_t *dco)
Definition: dco_win.c:418
_OVPN_SET_PEER
Definition: ovpn_dco_win.h:97
OVPN_PROTO_UDP
@ OVPN_PROTO_UDP
Definition: ovpn_dco_win.h:32
OVPN_IOCTL_DEL_PEER
#define OVPN_IOCTL_DEL_PEER
Definition: ovpn_dco_win.h:115
OVPN_IOCTL_START_VPN
#define OVPN_IOCTL_START_VPN
Definition: ovpn_dco_win.h:114
context::c2
struct context_2 c2
Level 2 context.
Definition: openvpn.h:517
tuntap_defined
static bool tuntap_defined(const struct tuntap *tt)
Definition: tun.h:238
tuntap::hand
HANDLE hand
Definition: tun.h:197
OVPN_IOCTL_NEW_PEER
#define OVPN_IOCTL_NEW_PEER
Definition: ovpn_dco_win.h:109
ASSERT
#define ASSERT(x)
Definition: error.h:201
_OVPN_STATS::TransportBytesSent
LONG64 TransportBytesSent
Definition: ovpn_dco_win.h:63
D_DCO
#define D_DCO
Definition: errlevel.h:94
tun.h
WINDOWS_DRIVER_DCO
@ WINDOWS_DRIVER_DCO
Definition: tun.h:53
_OVPN_CRYPTO_DATA::PeerId
int PeerId
Definition: ovpn_dco_win.h:94
_OVPN_SET_PEER::KeepaliveTimeout
LONG KeepaliveTimeout
Definition: ovpn_dco_win.h:99
_OVPN_CRYPTO_DATA::KeyId
unsigned char KeyId
Definition: ovpn_dco_win.h:93
ovpn_dco_init
bool ovpn_dco_init(int mode, dco_context_t *dco)
Definition: dco_win.c:56
context_2::dco_write_bytes
counter_type dco_write_bytes
Definition: openvpn.h:273
M_WARN
#define M_WARN
Definition: error.h:97
tuntap::adapter_index
DWORD adapter_index
Definition: tun.h:211
OVPN_IOCTL_NEW_KEY
#define OVPN_IOCTL_NEW_KEY
Definition: ovpn_dco_win.h:111
dco_event_set
void dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
Definition: dco_win.c:462
crypto.h
M_ERR
#define M_ERR
Definition: error.h:111
_OVPN_STATS::TunBytesSent
LONG64 TunBytesSent
Definition: ovpn_dco_win.h:66
_OVPN_NEW_PEER
Definition: ovpn_dco_win.h:36
dco_context_t
void * dco_context_t
Definition: dco.h:254
OVPN_IOCTL_GET_VERSION
#define OVPN_IOCTL_GET_VERSION
Definition: ovpn_dco_win.h:116
OVPN_IOCTL_GET_STATS
#define OVPN_IOCTL_GET_STATS
Definition: ovpn_dco_win.h:110
dco_available
bool dco_available(int msglevel)
Definition: dco_win.c:360
context_2::tun_write_bytes
counter_type tun_write_bytes
Definition: openvpn.h:268
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
dco_create_socket
void dco_create_socket(HANDLE handle, struct addrinfo *remoteaddr, bool bind_local, struct addrinfo *bind, int timeout, struct signal_info *sig_info)
Definition: dco_win.c:159
_OVPN_NEW_PEER::Local
union _OVPN_NEW_PEER::@8 Local
dco_set_peer
int dco_set_peer(dco_context_t *dco, unsigned int peerid, int keepalive_interval, int keepalive_timeout, int mss)
Definition: dco_win.c:272
_OVPN_NEW_PEER::Addr4
SOCKADDR_IN Addr4
Definition: ovpn_dco_win.h:38
_OVPN_CRYPTO_DATA::KeySlot
OVPN_KEY_SLOT KeySlot
Definition: ovpn_dco_win.h:91
_OVPN_VERSION
Definition: ovpn_dco_win.h:103
syshead.h
_OVPN_CRYPTO_DATA
Definition: ovpn_dco_win.h:88
_OVPN_SET_PEER::KeepaliveInterval
LONG KeepaliveInterval
Definition: ovpn_dco_win.h:98
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
dco_del_peer
int dco_del_peer(dco_context_t *dco, unsigned int peerid)
Definition: dco_win.c:257
_OVPN_CRYPTO_DATA::Decrypt
OVPN_KEY_DIRECTION Decrypt
Definition: ovpn_dco_win.h:90
_OVPN_CRYPTO_DATA::Encrypt
OVPN_KEY_DIRECTION Encrypt
Definition: ovpn_dco_win.h:89
_OVPN_KEY_DIRECTION::NonceTail
unsigned char NonceTail[8]
Definition: ovpn_dco_win.h:85
_OVPN_VERSION::Major
LONG Major
Definition: ovpn_dco_win.h:104
multi_context
Main OpenVPN server state structure.
Definition: multi.h:155
cipher_kt_key_size
int cipher_kt_key_size(const char *ciphername)
Returns the size of keys used by the cipher, in bytes.
Definition: crypto_openssl.c:658
dco.h
event_set
Definition: event.h:124
dco_del_key
int dco_del_key(dco_context_t *dco, unsigned int peerid, dco_key_slot_t slot)
Definition: dco_win.c:336
dco_swap_keys
int dco_swap_keys(dco_context_t *dco, unsigned int peer_id)
Definition: dco_win.c:345
OVPN_PROTO_TCP
@ OVPN_PROTO_TCP
Definition: ovpn_dco_win.h:33
tuntap::dco
dco_context_t dco
Definition: tun.h:234
signal_info
Definition: sig.h:41
context_2::dco_read_bytes
counter_type dco_read_bytes
Definition: openvpn.h:270
status
static SERVICE_STATUS status
Definition: interactive.c:52
tuntap
Definition: tun.h:171
_OVPN_KEY_DIRECTION::KeyLen
unsigned char KeyLen
Definition: ovpn_dco_win.h:84
_OVPN_KEY_DIRECTION::Key
unsigned char Key[32]
Definition: ovpn_dco_win.h:83
dco_wait_ready
static void dco_wait_ready(DWORD idx)
Definition: dco_win.c:69
config.h
ssl_common.h
_OVPN_NEW_PEER::Remote
union _OVPN_NEW_PEER::@9 Remote
get_signal
static void get_signal(volatile int *sig)
Copy the global signal_received (if non-zero) to the passed-in argument sig.
Definition: sig.h:110
dco_get_peer_stats_multi
int dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m)
Definition: dco_win.c:426
_OVPN_NEW_PEER::Addr6
SOCKADDR_IN6 Addr6
Definition: ovpn_dco_win.h:39
OVPN_IOCTL_SWAP_KEYS
#define OVPN_IOCTL_SWAP_KEYS
Definition: ovpn_dco_win.h:112
_OVPN_VERSION::Patch
LONG Patch
Definition: ovpn_dco_win.h:106
_OVPN_CRYPTO_DATA::CipherAlg
OVPN_CIPHER_ALG CipherAlg
Definition: ovpn_dco_win.h:92
register_signal
void register_signal(struct signal_info *si, int signum, const char *signal_text)
Register a soft signal in the signal_info struct si respecting priority.
Definition: sig.c:231
tun_open_device
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
Definition: tun.c:6648
msg
#define msg(flags,...)
Definition: error.h:150
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
OVPN_IOCTL_SET_PEER
#define OVPN_IOCTL_SET_PEER
Definition: ovpn_dco_win.h:113
context::c1
struct context_1 c1
Level 1 context.
Definition: openvpn.h:516