OpenVPN 3 Core Library
Loading...
Searching...
No Matches
dcocli.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#pragma once
13
14#include <memory>
15#include <sstream>
16#include <vector>
17
22#include <openvpn/time/time.hpp>
28
29#if defined(ENABLE_KOVPN)
30#include <openvpn/kovpn/kodevtun.hpp>
31#include <openvpn/kovpn/kostats.hpp>
32#include <openvpn/kovpn/kovpn.hpp>
33#include <openvpn/kovpn/rps_xps.hpp>
34#elif defined(ENABLE_OVPNDCO)
37#include <openvpn/dco/key.hpp>
40#elif defined(ENABLE_OVPNDCOWIN)
41#include <bcrypt.h>
42#include <openvpn/dco/key.hpp>
45#else
46#error either ENABLE_KOVPN, ENABLE_OVPNDCO or ENABLE_OVPNDCOWIN must be defined
47#endif
48
50
51// client-side DCO (Data Channel Offload) module for Linux/kovpn
52
54enum
55{
56 OVPN_PEER_ID_UNDEF = 0x00FFFFFF,
57};
58
59class ClientConfig : public DCO,
61 public TunClientFactory
62{
63 public:
65
66 std::string dev_name;
67
70
71 unsigned int ping_restart_override = 0;
72
73 void process_push(const OptionList &opt) override
74 {
76 }
77
78 void finalize(const bool disconnected) override
79 {
80#if defined(ENABLE_OVPNDCOWIN)
81 if (disconnected)
82 tun.tun_persist.reset();
83#endif
84 }
85
87 {
88 tun = conf;
89
90 // set a default MTU
91 if (!tun.tun_prop.mtu)
93
94 // parse "dev" option
95 {
96 const Option *dev = opt.get_ptr("dev");
97 if (dev)
98 dev_name = dev->get(1, 64);
99 else
100 dev_name = "ovpnc";
101 }
102
103 // parse ping-restart-override
105 "ping-restart-override", 1, ping_restart_override, 0, 3600);
106
107 return TunClientFactory::Ptr(this);
108 }
109
115
116 TunClient::Ptr new_tun_client_obj(openvpn_io::io_context &io_context,
117 TunClientParent &parent,
118 TransportClient *transcli) override;
119
120 TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context,
121 TransportClientParent *parent) override;
122
124 {
125 auto ctrl = new ClientConfig();
126 if (ctrl)
127 ctrl->builder = tb;
128 return ctrl;
129 }
130
131 bool supports_epoch_data() override
132 {
133 /* Currently, there is no version of ovpn-dco for Linux or Windows that supports
134 * the new features, so we always return false here */
135 return false;
136 }
137
138 protected:
139 ClientConfig() = default;
140};
141
142class Client : public TransportClient,
143 public TunClient,
144 public AsyncResolvableUDP
145{
146 friend class ClientConfig;
147
149
150 public:
151 // transport methods
152
154 {
155 return false;
156 }
157
159 {
160 return false;
161 }
162
164 {
165 return 0;
166 }
167
168 void reset_align_adjust(const size_t align_adjust) override
169 {
170 }
171
173 {
174 }
175
176 void server_endpoint_info(std::string &host,
177 std::string &port,
178 std::string &proto,
179 std::string &ip_addr) const override
180 {
181 host = server_host;
182 port = server_port;
183 const IP::Addr addr = server_endpoint_addr();
184 proto = std::string(transport_protocol().str());
185 proto += "-DCO";
186 ip_addr = addr.to_string();
187 }
188
189 void stop() override
190 {
191 stop_();
192 }
193
194 // tun methods
195
196 void set_disconnect() override
197 {
198 }
199
200 bool tun_send(BufferAllocated &buf) override // return true if send succeeded
201 {
202 return false;
203 }
204
205 std::string vpn_ip4() const override
206 {
207 if (state->vpn_ip4_addr.specified())
208 return state->vpn_ip4_addr.to_string();
209 else
210 return "";
211 }
212
213 std::string vpn_ip6() const override
214 {
215 if (state->vpn_ip6_addr.specified())
216 return state->vpn_ip6_addr.to_string();
217 else
218 return "";
219 }
220
221 std::string vpn_gw4() const override
222 {
223 if (state->vpn_ip4_gw.specified())
224 return state->vpn_ip4_gw.to_string();
225 else
226 return "";
227 }
228
229 std::string vpn_gw6() const override
230 {
231 if (state->vpn_ip6_gw.specified())
232 return state->vpn_ip6_gw.to_string();
233 else
234 return "";
235 }
236
237 int vpn_mtu() const override
238 {
239 return state->mtu;
240 }
241
242 protected:
243 Client(openvpn_io::io_context &io_context_arg,
244 ClientConfig *config_arg,
245 TransportClientParent *parent_arg)
246 : AsyncResolvableUDP(io_context_arg), io_context(io_context_arg),
247 halt(false), state(new TunProp::State()), config(config_arg),
248 transport_parent(parent_arg), tun_parent(nullptr),
250 {
251 }
252
253 void transport_reparent(TransportClientParent *parent_arg) override
254 {
255 transport_parent = parent_arg;
256 }
257
258 virtual void stop_() = 0;
259
260 openvpn_io::io_context &io_context;
261 bool halt;
262
264
268
270
271 std::string server_host;
272 std::string server_port;
273
274 uint32_t peer_id;
275};
276
277#if defined(ENABLE_KOVPN)
278#include <openvpn/kovpn/kovpncli.hpp>
279inline DCO::Ptr new_controller(TunBuilderBase *)
280{
281 return KovpnClientConfig::new_controller();
282}
284ClientConfig::new_transport_client_obj(openvpn_io::io_context &io_context,
285 TransportClientParent *parent)
286{
287 return TransportClient::Ptr(new KovpnClient(io_context, this, parent));
288}
289#elif defined(ENABLE_OVPNDCO)
291inline DCO::Ptr new_controller(TunBuilderBase *tb)
292{
294 return nullptr;
295
301}
303ClientConfig::new_transport_client_obj(openvpn_io::io_context &io_context,
304 TransportClientParent *parent)
305{
306 return TransportClient::Ptr(new OvpnDcoClient(io_context, this, parent));
307}
308#elif defined(ENABLE_OVPNDCOWIN)
310inline DCO::Ptr new_controller(TunBuilderBase *tb)
311{
313 return nullptr;
314
316 BCRYPT_ALG_HANDLE h;
317 NTSTATUS status = BCryptOpenAlgorithmProvider(&h, L"CHACHA20_POLY1305", NULL, 0);
318 if (BCRYPT_SUCCESS(status))
319 {
320 BCryptCloseAlgorithmProvider(h, 0);
322 }
323
325 return ClientConfig::new_controller(nullptr);
326}
328ClientConfig::new_transport_client_obj(openvpn_io::io_context &io_context,
329 TransportClientParent *parent)
330{
331 return TransportClient::Ptr(new OvpnDcoWinClient(io_context, this, parent));
332}
333#endif
334
335inline TunClient::Ptr
336ClientConfig::new_tun_client_obj(openvpn_io::io_context &io_context,
337 TunClientParent &parent,
338 TransportClient *transcli)
339{
340 Client *cli = static_cast<Client *>(transcli);
341 cli->tun_parent = &parent;
342 return TunClient::Ptr(cli);
343}
344} // namespace openvpn::DCOTransport
static bool available(TunBuilderBase *tb)
static bool available()
void process_push(const OptionList &opt) override
Definition dcocli.hpp:73
TransportClient::Ptr new_transport_client_obj(openvpn_io::io_context &io_context, TransportClientParent *parent) override
DCO::TransportConfig transport
Definition dcocli.hpp:68
TunClientFactory::Ptr new_tun_factory(const DCO::TunConfig &conf, const OptionList &opt) override
Definition dcocli.hpp:86
RCPtr< ClientConfig > Ptr
Definition dcocli.hpp:64
TunClient::Ptr new_tun_client_obj(openvpn_io::io_context &io_context, TunClientParent &parent, TransportClient *transcli) override
Definition dcocli.hpp:336
void finalize(const bool disconnected) override
Definition dcocli.hpp:78
TransportClientFactory::Ptr new_transport_factory(const DCO::TransportConfig &conf) override
Definition dcocli.hpp:110
static DCO::Ptr new_controller(TunBuilderBase *tb)
Definition dcocli.hpp:123
void server_endpoint_info(std::string &host, std::string &port, std::string &proto, std::string &ip_addr) const override
Definition dcocli.hpp:176
std::string vpn_ip4() const override
Definition dcocli.hpp:205
void transport_stop_requeueing() override
Definition dcocli.hpp:172
ClientConfig::Ptr config
Definition dcocli.hpp:265
void transport_reparent(TransportClientParent *parent_arg) override
Definition dcocli.hpp:253
int vpn_mtu() const override
Definition dcocli.hpp:237
size_t transport_send_queue_size() override
Definition dcocli.hpp:163
std::string vpn_gw6() const override
Definition dcocli.hpp:229
std::string vpn_ip6() const override
Definition dcocli.hpp:213
bool transport_send_queue_empty() override
Definition dcocli.hpp:153
ActionList::Ptr remove_cmds
Definition dcocli.hpp:269
void reset_align_adjust(const size_t align_adjust) override
Definition dcocli.hpp:168
openvpn_io::io_context & io_context
Definition dcocli.hpp:260
TransportClientParent * transport_parent
Definition dcocli.hpp:266
Client(openvpn_io::io_context &io_context_arg, ClientConfig *config_arg, TransportClientParent *parent_arg)
Definition dcocli.hpp:243
std::string vpn_gw4() const override
Definition dcocli.hpp:221
bool tun_send(BufferAllocated &buf) override
Definition dcocli.hpp:200
bool transport_has_send_queue() override
Definition dcocli.hpp:158
void set_disconnect() override
Definition dcocli.hpp:196
TunProp::State::Ptr state
Definition dcocli.hpp:263
TunClientParent * tun_parent
Definition dcocli.hpp:267
std::string to_string() const
Definition ip.hpp:528
T get_num(const std::string &name, const size_t idx, const T default_value) const
Definition options.hpp:1395
const Option * get_ptr(const std::string &name) const
Definition options.hpp:1174
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:184
The smart pointer class.
Definition rc.hpp:119
void process_push(const OptionList &opt)
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
Definition base.hpp:42
void allow_dc_algs(const std::list< Type > types)
std::array< Alg, Type::SIZE > algs
@ TUN_MTU_DEFAULT
Definition tunmtu.hpp:20
RemoteList::Ptr remote_list
Definition dco.hpp:47
TunProp::Config tun_prop
Definition dco.hpp:70
RCPtr< DCO > Ptr
Definition dco.hpp:37
RCPtr< TransportClientFactory > Ptr
RCPtr< TransportClient > Ptr
Definition transbase.hpp:37
virtual IP::Addr server_endpoint_addr() const =0
virtual Protocol transport_protocol() const =0
RCPtr< TunClientFactory > Ptr
Definition tunbase.hpp:102
RCPtr< TunClient > Ptr
Definition tunbase.hpp:34