OpenVPN 3 Core Library
Loading...
Searching...
No Matches
client.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// Generic, cross-platform tun interface that drives a TunBuilderBase API.
13// Fully supports IPv6. To make this work on a given platform, define
14// a TunBuilderBase for the platform.
15
16#ifndef OPENVPN_TUN_BUILDER_CLIENT_H
17#define OPENVPN_TUN_BUILDER_CLIENT_H
18
19#include <memory>
20
24#include <openvpn/tun/tunio.hpp>
25
27
28OPENVPN_EXCEPTION(tun_builder_error);
29
30// struct used to pass received tun packets
32{
33 typedef std::unique_ptr<PacketFrom> SPtr;
35};
36
37// our TunPersist class, specialized for Unix file descriptors
39
40// A simplified tun interface where pre-existing
41// socket is provided.
42template <typename ReadHandler>
43class Tun : public TunIO<ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor>
44{
46
47 public:
48 typedef RCPtr<Tun> Ptr;
49
50 Tun(openvpn_io::io_context &io_context,
51 const int socket,
52 const bool retain_sd_arg,
53 const bool tun_prefix_arg,
54 ReadHandler read_handler_arg,
55 const Frame::Ptr &frame_arg,
56 const SessionStats::Ptr &stats_arg)
57 : Base(read_handler_arg, frame_arg, stats_arg)
58 {
59 Base::stream = new openvpn_io::posix::stream_descriptor(io_context, socket);
60 Base::name_ = "tun";
61 Base::retain_stream = retain_sd_arg;
62 Base::tun_prefix = tun_prefix_arg;
63 }
64
66 {
67 Base::stop();
68 }
69};
70
71// A factory for the Client class
73{
74 public:
76
78 int n_parallel; // number of parallel async reads on tun socket
86
87 static Ptr new_obj()
88 {
89 return new ClientConfig;
90 }
91
92 TunClient::Ptr new_tun_client_obj(openvpn_io::io_context &io_context,
93 TunClientParent &parent,
94 TransportClient *transcli) override;
95
96 void finalize(const bool disconnected) override
97 {
98 if (disconnected)
100 }
101
102 bool supports_epoch_data() override
103 {
104 return true;
105 }
106
107 private:
109 : n_parallel(8), retain_sd(false), tun_prefix(false), builder(nullptr)
110 {
111 }
112};
113
114// The tun interface
115class Client : public TunClient
116{
117 friend class ClientConfig; // calls constructor
118 friend class TunIO<Client *, PacketFrom, openvpn_io::posix::stream_descriptor>; // calls tun_read_handler
119
121
122 public:
123 void tun_start(const OptionList &opt, TransportClient &transcli, CryptoDCSettings &) override
124 {
125 if (!impl)
126 {
127 halt = false;
128 if (config->tun_persist)
129 tun_persist = config->tun_persist; // long-term persistent
130 else
131 tun_persist.reset(new TunPersist(false,
133 config->builder)); // short-term
134
135 try
136 {
137 int sd = -1;
138 const IP::Addr server_addr = transcli.server_endpoint_addr();
139
140 // Check if persisted tun session matches properties of to-be-created session
141 if (tun_persist->use_persisted_tun(server_addr, config->tun_prop, opt))
142 {
143 sd = tun_persist->obj();
144 state = tun_persist->state();
145 OPENVPN_LOG("TunPersist: reused tun context");
146
147 // indicate reconnection with persisted state
148 config->builder->tun_builder_establish_lite();
149 }
150 else
151 {
152 TunBuilderBase *tb = config->builder;
153
154 // reset target tun builder object
155 if (!tb->tun_builder_new())
156 throw tun_builder_error("tun_builder_new failed");
157
158 // notify parent
160
161 // configure the tun builder
163 state.get(),
164 config->stats.get(),
165 server_addr,
166 config->tun_prop,
167 opt,
168 config->eer_factory.get(),
169 false);
170
171 // start tun
172 sd = tb->tun_builder_establish();
173 }
174
175 if (sd == -1)
176 {
177 parent.tun_error(Error::TUN_IFACE_CREATE, "cannot acquire tun interface socket");
178 return;
179 }
180
181 // persist state
182 if (tun_persist->persist_tun_state(sd, state))
183 OPENVPN_LOG("TunPersist: saving tun context:" << std::endl
184 << tun_persist->options());
185
187 sd,
188 true,
189 config->tun_prefix,
190 this,
191 config->frame,
192 config->stats));
193 impl->start(config->n_parallel);
194
195 // signal that we are connected
197 }
198 catch (const std::exception &e)
199 {
200 if (tun_persist)
201 tun_persist->close();
202 stop();
204 }
205 }
206 }
207
208 bool tun_send(BufferAllocated &buf) override
209 {
210 return send(buf);
211 }
212
213 std::string tun_name() const override
214 {
215 if (impl)
216 return impl->name();
217 else
218 return "UNDEF_TUN";
219 }
220
221 std::string vpn_ip4() const override
222 {
223 if (state->vpn_ip4_addr.specified())
224 return state->vpn_ip4_addr.to_string();
225 else
226 return "";
227 }
228
229 std::string vpn_ip6() const override
230 {
231 if (state->vpn_ip6_addr.specified())
232 return state->vpn_ip6_addr.to_string();
233 else
234 return "";
235 }
236
237 std::string vpn_gw4() const override
238 {
239 if (state->vpn_ip4_gw.specified())
240 return state->vpn_ip4_gw.to_string();
241 else
242 return "";
243 }
244
245 std::string vpn_gw6() const override
246 {
247 if (state->vpn_ip6_gw.specified())
248 return state->vpn_ip6_gw.to_string();
249 else
250 return "";
251 }
252
253 int vpn_mtu() const override
254 {
255 return state->mtu;
256 }
257
258 void set_disconnect() override
259 {
260 if (tun_persist)
261 tun_persist->set_disconnect();
262 }
263
264 void stop() override
265 {
266 stop_();
267 }
268 virtual ~Client()
269 {
270 stop_();
271 }
272
273 void apply_push_update(const OptionList &opt, TransportClient &transcli) override
274 {
275 stop_();
276 if (impl)
277 {
278 impl.reset();
279 }
280
281 // this has to be done in post, because we need to wait
282 // for all async tun read requests to complete
283 openvpn_io::post(io_context, [self = Ptr(this), opt, &transcli]
284 {
287 self->tun_start(opt, transcli, c); });
288 }
289
290 private:
291 Client(openvpn_io::io_context &io_context_arg,
292 ClientConfig *config_arg,
293 TunClientParent &parent_arg)
294 : io_context(io_context_arg),
295 config(config_arg),
296 parent(parent_arg),
297 halt(false),
298 state(new TunProp::State())
299 {
300 }
301
302 bool send(Buffer &buf)
303 {
304 if (impl)
305 return impl->write(buf);
306 else
307 return false;
308 }
309
310 void tun_read_handler(PacketFrom::SPtr &pfp) // called by TunImpl
311 {
312 parent.tun_recv(pfp->buf);
313 }
314
315 void tun_error_handler(const Error::Type errtype, // called by TunImpl
316 const openvpn_io::error_code *error)
317 {
318 }
319
320 void stop_()
321 {
322 if (!halt)
323 {
324 halt = true;
325
326 // stop tun
327 if (impl)
328 impl->stop();
330 }
331 }
332
333
334 openvpn_io::io_context &io_context;
335 TunPersist::Ptr tun_persist; // owns the tun socket descriptor
339 bool halt;
341};
342
343inline TunClient::Ptr ClientConfig::new_tun_client_obj(openvpn_io::io_context &io_context,
344 TunClientParent &parent,
345 TransportClient *transcli)
346{
347 return TunClient::Ptr(new Client(io_context, this, parent));
348}
349
350} // namespace openvpn::TunBuilderClient
351
352#endif
#define OPENVPN_ASYNC_HANDLER
Definition bigmutex.hpp:36
The smart pointer class.
Definition rc.hpp:119
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
Definition rc.hpp:290
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Definition rc.hpp:321
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
Definition base.hpp:42
virtual int tun_builder_establish()
Callback to establish the VPN tunnel.
Definition base.hpp:361
virtual bool tun_builder_new()
Callback to construct a new TunBuilder. This function should be called first.
Definition base.hpp:50
void finalize(const bool disconnected) override
Definition client.hpp:96
EmulateExcludeRouteFactory::Ptr eer_factory
Definition client.hpp:83
TunClient::Ptr new_tun_client_obj(openvpn_io::io_context &io_context, TunClientParent &parent, TransportClient *transcli) override
Definition client.hpp:343
openvpn_io::io_context & io_context
Definition client.hpp:334
Client(openvpn_io::io_context &io_context_arg, ClientConfig *config_arg, TunClientParent &parent_arg)
Definition client.hpp:291
std::string tun_name() const override
Definition client.hpp:213
void tun_read_handler(PacketFrom::SPtr &pfp)
Definition client.hpp:310
bool tun_send(BufferAllocated &buf) override
Definition client.hpp:208
void apply_push_update(const OptionList &opt, TransportClient &transcli) override
Notifies tun client about received PUSH_UPDATE control channel message.
Definition client.hpp:273
TunProp::State::Ptr state
Definition client.hpp:340
void tun_error_handler(const Error::Type errtype, const openvpn_io::error_code *error)
Definition client.hpp:315
std::string vpn_gw6() const override
Definition client.hpp:245
std::string vpn_gw4() const override
Definition client.hpp:237
int vpn_mtu() const override
Definition client.hpp:253
void tun_start(const OptionList &opt, TransportClient &transcli, CryptoDCSettings &) override
Definition client.hpp:123
std::string vpn_ip6() const override
Definition client.hpp:229
std::string vpn_ip4() const override
Definition client.hpp:221
TunIO< ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor > Base
Definition client.hpp:45
Tun(openvpn_io::io_context &io_context, const int socket, const bool retain_sd_arg, const bool tun_prefix_arg, ReadHandler read_handler_arg, const Frame::Ptr &frame_arg, const SessionStats::Ptr &stats_arg)
Definition client.hpp:50
static void configure_builder(TunBuilderBase *tb, State *state, SessionStats *stats, const IP::Addr &server_addr, const Config &config, const OptionList &opt, const EmulateExcludeRouteFactory *eer_factory, const bool quiet)
Definition tunprop.hpp:92
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_LOG(args)
TunPersistTemplate< ScopedFD > TunPersist
Definition client.hpp:38
virtual IP::Addr server_endpoint_addr() const =0
std::unique_ptr< PacketFrom > SPtr
Definition client.hpp:33
virtual void tun_error(const Error::Type fatal_err, const std::string &err_text)=0
virtual void tun_connected()=0
virtual void tun_pre_tun_config()=0
virtual void tun_recv(BufferAllocated &buf)=0
RCPtr< TunClient > Ptr
Definition tunbase.hpp:34