# OpenVPN/openvpn3: the C++ client library behind the OpenVPN Connect apps

> OpenVPN 3 is a C++ class library that implements an OpenVPN client and speaks the protocol of the 2.x branch, and it is the core of the OpenVPN Connect clients for iOS, Android, Linux, Windows and macOS. It ships a minimal command line wrapper for demonstration, does not implement server functionality, and its most interesting piece of engineering is a unit test that runs the protocol implementation across a virtualised lossy network.

**OpenVPN/openvpn3** — OpenVPN 3 is a C++ class library that implements the functionality of an OpenVPN client, and is protocol-compatible with the OpenVPN 2.x branch.

- Repository: https://github.com/OpenVPN/openvpn3
- Website: https://openvpn.github.io/openvpn3/
- Stars: 1,187 · Forks: 471
- Language: C++
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/openvpn-openvpn3

## A client library, and the note about servers

OpenVPN 3 is a C++ class library that implements the functionality of an OpenVPN client, and is protocol-compatible with the OpenVPN 2.x branch.

That last clause is the design constraint. The library exists to speak the protocol that a large existing deployment of 2.x servers and configurations expects, while being written as a modern C++ class library rather than as the daemon that 2.x shipped as.

The scope note comes early and is unambiguous. OpenVPN 3 does not currently implement server functionality. So this is a client codebase, and the interesting consumer is anything that needs an OpenVPN client without being the classic openvpn binary.

The stated production user is the OpenVPN Connect clients for iOS, Android, Linux, Windows and Mac OS X, where OpenVPN 3 is used as the core. That is the reference point for judging the project, because five platform applications that a commercial VPN vendor ships are running on this library, and the constraints that implies, a build that works on a phone, on a desktop and on a command line, with a portable toolchain, are the constraints the code is shaped around.

The repository reflects that shape, with `openvpn/` for the protocol implementation, `client/` for the public client API, `test/` for the wrapper and the unit tests, `cmake/` for the build system, `deps/` for bundled dependencies, `javacli/` for a Java binding, and `doc/` for documentation. There is also a `vcpkg.json` for the Windows build, `CMakePresets.json` for the preset based builds, `renovate.json` for dependency updates, and a `LICENSES/` directory.

## The API is one header, the wrapper is the tutorial

The library is organised as a C++ class library, and the API is defined in `client/ovpncli.hpp`. A simple command line wrapper for the API is provided in `test/ovpncli/cli.cpp`, and the Doxygen generated API documentation is published at openvpn.github.io/openvpn3.

The placement of the wrapper inside `test/` is a nice detail, because it says what the wrapper is for. It is not the product, it is a demonstration of how the API is driven, and it lives with the tests so that it stays honest as the API changes. The library itself includes a minimal client wrapper, `cli`, which links against the library and provides basic command line functionality.

So the intended reading order for a new user is the header for the shape of the API, the wrapper source for how a session is actually started, and the Doxygen site for the details. That is a sensible arrangement for a C++ library whose primary consumers are in-house platform teams rather than open source hobbyists.

## Building on Linux with CMake and Ninja

The Linux instructions were tested on Ubuntu 24.04, and they are complete enough to follow without guessing.

The essential dependencies are installed with `--no-install-recommends`:

```
$ sudo apt install --no-install-recommends ca-certificates cmake g++ git iproute2 ninja-build pkg-config
$ sudo apt install --no-install-recommends libasio-dev libcap-dev libfmt-dev liblz4-dev libjsoncpp-dev libssl-dev libxxhash-dev
```

and the optional ones, which are the mbedTLS backend, LZO compression, Python headers and SWIG:

```
$ sudo apt install --no-install-recommends libmbedtls-dev liblzo2-dev python3-dev swig
```

Then the clone and the build:

```
$ git clone https://github.com/OpenVPN/openvpn3.git
$ cd openvpn3 && mkdir build && cd build
$ cmake -GNinja ..
$ cmake --build .
$ ctest # Run Unit Tests
```

Two details are worth noting. The generator is Ninja rather than Make, and the unit tests are run through `ctest` as part of the same build, so a broken protocol implementation fails the build rather than being discovered later. And the TLS backend is a build option, since to use mbedTLS you configure with `cmake -GNinja -DUSE_MBEDTLS=ON ..`, which is how you build the same source against a different crypto library.

Running the client is one command:

```
$ sudo test/ovpncli/ovpncli myprofile.ovpn route-nopull
```

where `myprofile.ovpn` is an OpenVPN config file that must have the `.ovpn` extension, and `route-nopull` means that if you are connected over SSH it prevents the SSH session from locking itself out. That last flag is a small piece of practical advice that only comes from having done it the hard way.

## DCO, the kernel module, and why performance is a build decision

The optional `ovpn` kernel module optimises the data channel encryption and transport, providing better performance, and the client wrapper will detect when the kernel module is available and enable DCO automatically, with `--no-dco` to disable it.

The status of that module is now a kernel question rather than a third party question. The ovpn kernel module has been merged upstream as of linux-6.16, and from that kernel version onwards you get the DCO module as shipped by your kernel. If you run an older kernel, or you want a more recent DCO module than your kernel ships, you need the ovpn-backports project, whose README covers building the module yourself.

Building the client with that support needs one more library, `libnl-genl-3-dev`, and one more CMake option:

```
$ cd openvpn3/build
$ cmake -DCLI_OVPNDCO=ON .. && cmake --build .
$ sudo test/ovpncli/ovpncli [--no-dco] myprofile.ovpn
```

So the performance path in this project is layered, and the layering is deliberate. The same source builds a client that does its crypto in userspace, a client that offloads the data channel to a kernel module, and, on newer kernels, gets that module for free. The `--no-dco` flag exists so you can compare the two paths on the same machine, which is the only way to know whether the offload is worth it for your setup.

## macOS, Windows and MinGW

The macOS instructions start with a constraint that is easy to miss. OpenVPN 3 should be built in a non-root macOS account, and you need Xcode with the optional command line tools installed. Homebrew provides the dependencies, `asio cmake fmt jsoncpp lz4 openssl pkg-config xxhash`, and then the OpenSSL root differs between architectures, with `/opt/homebrew/opt/openssl` on an ARM64 Mac and `/usr/local/opt/openssl` on an Intel one.

```
$ brew install asio cmake fmt jsoncpp lz4 openssl pkg-config xxhash
$ cd ~/src/
$ mkdir build-openvpn3
$ cd build-openvpn3
$ cmake -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCMAKE_PREFIX_PATH=/opt/homebrew ~/src/openvpn3
$ cmake --build .
```

There is also a note that the macOS tuntap driver is not required, as OpenVPN 3 can use the integrated utun interface if available, which removes the need for a kernel extension on that platform.

Windows has two paths. Visual Studio 2022 with CMake, vcpkg and git, using the `win-amd64-release` preset and the `ovpncli` target. Or MinGW, with mingw-w64, CMake, vcpkg and git, using the `mingw-x64-release` preset, and that build should work on both Windows and Linux.

The MinGW path is the interesting one, because it means the same Windows binaries can be produced on a Linux build machine, which is how a project that ships on several platforms keeps one CI configuration. The `vcpkg.json` in the repository is the dependency manifest for that build, and the presence of `CMakePresets.json` with named presets is what makes the two toolchains selectable from one command.

## The test that runs the protocol over a lossy network

The testing section describes something more interesting than a unit test suite, and it is the part of the project that tells you how seriously the protocol implementation is treated.

The OpenVPN 3 core includes a stress and performance test of the OpenVPN protocol implementation. The test creates a virtualised lossy network between two OpenVPN protocol objects, triggers TLS negotiations between them, passes control and data channel messages, and measures the ability of the OpenVPN protocol objects to perform and remain in a valid state.

Read that carefully, because it is a design decision about what to test. Rather than asserting that a message is formatted a particular way, the test runs two real protocol objects against each other over a network that drops and delays traffic, and checks that the pair negotiates TLS, exchanges control and data channel messages, and stays in a valid state under adversity. That is closer to an integration test of the protocol's behaviour than a unit test of its functions, and it is the kind of test that catches the failures that matter, a rekey that never completes, a renegotiation that deadlocks, a state machine that goes invalid after a lost packet.

The implementation under test lives in `openvpn/ssl/proto.hpp` and the test itself in `test/unittests/test_proto.cpp`, and it is built and run as part of the unit test suite. The unit tests are based on the Google Test framework, and to run them you need CMake and a build of Google Test:

```
$ cd openvpn3/build
$ cmake --build . -- coreUnitTests
$ make test
```

The target name `coreUnitTests` and the separate `ctest` invocation in the Linux build instructions are two views of the same suite, and the presence of a dedicated performance and stress test among them is a good sign for a protocol library that ships in mobile applications.

## Where openvpn3 is the wrong choice

The first wrong case is a server. The project says directly that it does not currently implement server functionality.

The second is a user who wants a command line VPN today. The `cli` wrapper here is a demonstration of the API, it lives in the test directory, and it is a demonstration rather than a polished end-user front end.

The third is an environment where you cannot build a C++ project with vcpkg, CMake and a TLS library. The build is not hermetic, the crypto library is a system or package manager dependency, and while the MinGW path helps with cross compilation, it does not remove the toolchain requirement.

The fourth is a product that needs the protocol to change with the server. Compatibility here means compatibility with the 2.x branch, which is the point, and it also means the library follows the protocol that the existing server fleet implements, so a deployment that wants a newer protocol feature is not served by this library.

On the state of the project, the last push to the repository was on 2026-10-13, the repository is not archived, and there are no GitHub releases, so the versioning is tracked in the repository itself, with a `VersionNumbering.md` document describing the scheme. The licence file is `LICENSE.md`, with a `LICENSES/` directory alongside it for the per component terms, and the repository is covered by an automated dependency update configuration and a pre-commit configuration.

## Conclusion

Adopt openvpn3 if you are writing a native client for OpenVPN, an embedded VPN stack or a platform that needs the protocol without the daemon, since this library is what the OpenVPN Connect applications are built on and it covers the platforms you are likely to target. Do not adopt it as a server implementation, because the project states plainly that it does not currently implement server functionality. Verify first that your platform's build path is covered, since Linux, macOS, Windows with Visual Studio and MinGW are all documented separately, that the TLS backend you need is available, with OpenSSL by default and mbedTLS behind a build option, and that the unit tests pass in your environment, because the protocol code is exercised through a virtualised lossy network rather than a mock.

## FAQ

### What is OpenVPN 3 and what is it not?

It is a C++ class library that implements an OpenVPN client and is protocol-compatible with the OpenVPN 2.x branch, used in production as the core of the OpenVPN Connect clients for iOS, Android, Linux, Windows and macOS. It does not currently implement server functionality, and the bundled `cli` wrapper is a demonstration of the API rather than a full front end.

### How do I build the OpenVPN 3 client on Linux?

On Ubuntu 24.04, install the dependencies with apt, including cmake, g++, ninja-build, libasio-dev, libcap-dev, libfmt-dev, liblz4-dev, libjsoncpp-dev, libssl-dev and libxxhash-dev, then clone the repository, create a build directory, run `cmake -GNinja ..`, `cmake --build .` and `ctest`. Configuring with `-DUSE_MBEDTLS=ON` switches the TLS backend to mbedTLS.

### What is DCO in the OpenVPN 3 client and how is it enabled?

DCO is the data channel offload provided by the ovpn kernel module, which optimises data channel encryption and transport for better performance. The client detects the module and enables DCO automatically, with `--no-dco` to disable it. The module has been merged upstream as of linux-6.16, older kernels need the ovpn-backports project, and building the client with support requires the `CLI_OVPNDCO=ON` option and `libnl-genl-3-dev`.

### How is the OpenVPN 3 protocol implementation tested?

Besides the Google Test based unit tests, the core includes a stress and performance test that creates a virtualised lossy network between two OpenVPN protocol objects, triggers TLS negotiations between them, passes control and data channel messages, and measures whether they remain in a valid state. The implementation is in `openvpn/ssl/proto.hpp` and the test in `test/unittests/test_proto.cpp`.

### Can I build the OpenVPN 3 client on Windows?

Yes, two ways. With Visual Studio 2022, CMake, vcpkg and git, using the `win-amd64-release` preset and the `ovpncli` target, or with MinGW using mingw-w64 and the `mingw-x64-release` preset, a build that should work on both Windows and Linux.

## Sources

- [Issues](https://github.com/OpenVPN/openvpn3/issues)
- [OpenVPN/openvpn3 on GitHub](https://github.com/OpenVPN/openvpn3)
- [Project website](https://openvpn.github.io/openvpn3/)
- [README](https://github.com/OpenVPN/openvpn3/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/openvpn-openvpn3
