OpenVPN
ring_buffer.h
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
9  * 2019 Lev Stipakov <lev@openvpn.net>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2
13  * as published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 #ifdef _WIN32
26 #ifndef OPENVPN_RING_BUFFER_H
27 #define OPENVPN_RING_BUFFER_H
28 
29 #include <windows.h>
30 #include <winioctl.h>
31 
32 #include <stdint.h>
33 #include <stdbool.h>
34 
35 /*
36  * Values below are taken from Wireguard Windows client
37  * https://github.com/WireGuard/wireguard-go/blob/master/tun/wintun/ring_windows.go#L14
38  */
39 #define WINTUN_RING_CAPACITY 0x800000
40 #define WINTUN_RING_TRAILING_BYTES 0x10000
41 #define WINTUN_MAX_PACKET_SIZE 0xffff
42 #define WINTUN_PACKET_ALIGN 4
43 
44 #define TUN_IOCTL_REGISTER_RINGS CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
45 
50 struct tun_ring
51 {
52  volatile ULONG head;
53  volatile ULONG tail;
54  volatile LONG alertable;
56 };
57 
63 {
64  struct
65  {
66  ULONG ring_size;
67  struct tun_ring *ring;
68  HANDLE tail_moved;
69  } send, receive;
70 };
71 
73 {
74  uint32_t size;
75 };
76 
77 struct TUN_PACKET
78 {
79  uint32_t size;
81 };
82 
97 static bool
98 register_ring_buffers(HANDLE device,
99  struct tun_ring *send_ring,
100  struct tun_ring *receive_ring,
101  HANDLE send_tail_moved,
102  HANDLE receive_tail_moved)
103 {
104  struct tun_register_rings rr;
105  BOOL res;
106  DWORD bytes_returned;
107 
108  ZeroMemory(&rr, sizeof(rr));
109 
110  rr.send.ring = send_ring;
111  rr.send.ring_size = sizeof(struct tun_ring);
112  rr.send.tail_moved = send_tail_moved;
113 
114  rr.receive.ring = receive_ring;
115  rr.receive.ring_size = sizeof(struct tun_ring);
116  rr.receive.tail_moved = receive_tail_moved;
117 
118  res = DeviceIoControl(device, TUN_IOCTL_REGISTER_RINGS, &rr, sizeof(rr),
119  NULL, 0, &bytes_returned, NULL);
120 
121  return res != FALSE;
122 }
123 
124 #endif /* ifndef OPENVPN_RING_BUFFER_H */
125 #endif /* ifdef _WIN32 */
#define TUN_IOCTL_REGISTER_RINGS
Definition: ring_buffer.h:44
volatile ULONG head
Definition: ring_buffer.h:52
volatile ULONG tail
Definition: ring_buffer.h:53
#define WINTUN_RING_TRAILING_BYTES
Definition: ring_buffer.h:40
uint32_t size
Definition: ring_buffer.h:79
static bool register_ring_buffers(HANDLE device, struct tun_ring *send_ring, struct tun_ring *receive_ring, HANDLE send_tail_moved, HANDLE receive_tail_moved)
Registers ring buffers used to exchange data between userspace openvpn process and wintun kernel driv...
Definition: ring_buffer.h:98
struct tun_register_rings::@9 receive
struct tun_ring * ring
Definition: ring_buffer.h:67
volatile LONG alertable
Definition: ring_buffer.h:54
#define WINTUN_RING_CAPACITY
Definition: ring_buffer.h:39
UCHAR data[WINTUN_RING_CAPACITY+WINTUN_RING_TRAILING_BYTES]
Definition: ring_buffer.h:55
#define WINTUN_MAX_PACKET_SIZE
Definition: ring_buffer.h:41
Wintun ring buffer See https://github.com/WireGuard/wintun#ring-layout.
Definition: ring_buffer.h:50
Struct for ring buffers registration See https://github.com/WireGuard/wintun#registering-rings.
Definition: ring_buffer.h:62
struct tun_register_rings::@9 send