]> git.ipfire.org Git - thirdparty/openvpn.git/blame - src/openvpn/ring_buffer.h
Update Copyright statements to 2024
[thirdparty/openvpn.git] / src / openvpn / ring_buffer.h
CommitLineData
da2e66ca
LS
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 *
b25c6d7e 8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
da2e66ca
LS
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
46/**
47 * Wintun ring buffer
48 * See https://github.com/WireGuard/wintun#ring-layout
49 */
50struct tun_ring
51{
52 volatile ULONG head;
53 volatile ULONG tail;
54 volatile LONG alertable;
55 UCHAR data[WINTUN_RING_CAPACITY + WINTUN_RING_TRAILING_BYTES];
56};
57
58/**
59 * Struct for ring buffers registration
60 * See https://github.com/WireGuard/wintun#registering-rings
61 */
62struct tun_register_rings
63{
64 struct
65 {
66 ULONG ring_size;
67 struct tun_ring *ring;
68 HANDLE tail_moved;
69 } send, receive;
70};
71
72struct TUN_PACKET_HEADER
73{
74 uint32_t size;
75};
76
77struct TUN_PACKET
78{
79 uint32_t size;
80 UCHAR data[WINTUN_MAX_PACKET_SIZE];
81};
82
83/**
84 * Registers ring buffers used to exchange data between
85 * userspace openvpn process and wintun kernel driver,
86 * see https://github.com/WireGuard/wintun#registering-rings
87 *
88 * @param device handle to opened wintun device
89 * @param send_ring pointer to send ring
90 * @param receive_ring pointer to receive ring
91 * @param send_tail_moved event set by wintun to signal openvpn
92 * that data is available for reading in send ring
93 * @param receive_tail_moved event set by openvpn to signal wintun
94 * that data has been written to receive ring
089fbe65 95 * @return true if registration is successful, false otherwise - use GetLastError()
da2e66ca 96 */
71371f04 97static inline bool
6d19775a
LS
98register_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),
abe49856 119 NULL, 0, &bytes_returned, NULL);
6d19775a
LS
120
121 return res != FALSE;
122}
da2e66ca
LS
123
124#endif /* ifndef OPENVPN_RING_BUFFER_H */
125#endif /* ifdef _WIN32 */