Introduction

Development processes

General workflow

The basic development process we follow is outlined in this diagram. So, in a nutshell:

All patches must be sent to "openvpn-devel" mailing list for review. The subject should preferably be prefixed with [PATCH]

All patches need to be reviewed and accepted (ACK) by at least one other developer to make sure they meet our quality criteria

All accepted patches go to the OpenVPN "testing" tree (Git) first

Code is moved to the OpenVPN "stable" tree (SVN) after initial testing

All official releases are based on the "stable" (SVN) tree and go through a feature freeze and a Beta/RC process

If someone maintains their modifications in a git tree already, those git trees can be pulled as long as it will not cause any conflicts against the master/SVN development branch. However, the author must send a pull request to the devel mailing list, including a description in plain English of the changes. This is so to open up for a public discussion of the changes, and to allow the ACK process to work. Changes in git trees needs to get ACKed as well, just like patches. Pull requests to the mailing list should preferably be prefixed with [GIT PULL].

NOTE: Patches or "git pull requests" sent directly to a development tree ("stable" or "testing") maintainer will be rejected. All patches and contents of git pull requests must be public and must be discussed in public.

The initial process was drafted in the IRC meeting on 18th Feb 2010. It has since been discussed in detail on the devel mailinglist in the "[PATCH v2] Do not randomize resolving of IP addresses in getaddr()" thread.

The FRP process

Ask users if they are depending on a feature considered for deprecation (e.g. using the openvpn-users mailing list)

If users complain, discuss the issue and possible solutions with them

If there are no complaints, proceed to 2

Warn the user about feature deprecation on application startup. The deprecated code itself can also output a warning itself, depending on how often it's triggered. The warning can be a simple log message (e.g. "WARNING: this feature is being deprecated and will be removed soon"). The deprecated code will still be enabled by default. The deprecated code should probably be #ifdef'd at this point to find it easily during next steps.

If users complain now, discuss the issue and possible solutions with them

If there are no complaints, proceed to 3

Make the feature disabled by default, but allow enabling it at compile-time (use #ifdef's).

If users complain now, discuss the issue and possible solutions with them

If there are no complaints, proceed to 4

Remove the feature entirely from the code

If users complain now, discuss the issue and possible solutions with them

If there are no complaints, proceed to 5

Finished. The feature was not really important to anyone and is not cluttering the code anymore.

Each feature could be kept around in "deprecated" mode in the first stable release, disabled but available in the second and removed in the third release. This will give users plenty of time to reach, depending on the release cycle.

It is also necessary that each feature deprecation / removal needs is documented visibly in the release notes of each stable release.

What to do - code wise

First phase: Disable the feature on request

Remove the feature by using #ifdef's wherever this feature is called or executed in the source code

The #ifdef name should start with DEPRECATED_ and then a sensible name for the feature

Add a warning (using #warning statements) for compile time warnings when the feature is enabled.

Add log messages (using msg()) whenever this feature is called.

Make sure that the logging will not be too extensive and happen too often. It should catch attention, but not flood the log.

[TBD] Update deprecated.c and add an appropriate warning, inside a #ifdef block for the feature going through the FRP.

Update configure.ac

Locate the section for deprecated features, (search for "Deprecated features")

Add a new configure argument to disable this feature, ie. enabled by default. The argument should start with --disable-depr- and then a sensible and descriptive feature name.

Test the change by compiling and smoke testing OpenVPN.

When the feature is enabled (the default)

A warning should be clearly visible during compilation

OpenVPN should provide a warning early at startup about a enabled deprecated feature

OpenVPN should create a log entry whenever the feature's code path is hit

Verify that the feature indeed still works

When the feature is disabled (through ./configure arguments)

No warning about the feature deprecation should be seen at startup

No warning or errors when OpenVPN passes the code path where this feature was enabled

Verify that the feature really is removed when running OpenVPN and that it behaves as expected

Commit the patch(es) and submit them to the openvpn-devel mailinglist. The subject must start with [PATCH] followed by FRP:

Example: [PATCH] FRP: Preparing for removal of feature X

Second phase: Enable the feature on request

Update configure.ac

Rename argument from --disable-depr-* to --enable-depr-*

Change default value from "yes" to "no"

Test the change by compiling and smoke testing OpenVPN.

When the feature is disabled (the default)

No warning about the feature deprecation should be seen at startup

No warning or errors when OpenVPN passes the code path where this feature was enabled

Verify that the feature really is removed when running OpenVPN and that it behaves as expected

When the feature is enabled (through ./configure arguments)

A warning should be clearly visible during compilation

OpenVPN should provide a warning early at startup about a enabled deprecated feature

OpenVPN should create a log entry whenever the feature's code path is hit

Verify that the feature indeed still works

Commit the patch(es) and submit them to the openvpn-devel mailinglist. The subject must start with [PATCH] followed by FRP2:

Example: [PATCH] FRP2: Deprecating feature X by default

Third phase: Complete removal of the feature

Remove all code blocks which are encapsulated by the feature's #ifdef blocks from the source code

Beware of #else blocks, and make sure they are not removed.

Update configure.ac

Remove the configure arguments related to the feature

Test the change by compiling and smoke testing OpenVPN. Check that:

No warning about the feature deprecation should be seen at startup

No warning or errors when OpenVPN passes the code path where this feature was enabled

Verify that the feature really is removed when running OpenVPN and that it behaves as expected

Commit the patch(es) and submit them to the openvpn-devel mailinglist. The subject must start with [PATCH] followed by FRP3:

Example: [PATCH] FRP3: Removing deprecated feature X

Code quality

All patches need to meet certain generic quality criteria before being accepted:

All patches should be useful and beneficial for several OpenVPN users. This way we avoid spoiling the code base with features which is only requested for very special conditions.

All patches must contain an argumentation why this patch should be included and how it solves the issue in plain English.

Everyone who has contributed to this patch should be mentioned, with at least a valid e-mail address, preferably with full name in addition. This is to give credit to contributors.

All patches must be against the SVN development branch or git master branch, at least until a feature branch is created.

The patch should apply cleanly, without merge conflicts.

All initial patches must be sent as unified diff (diff -u)

New features need to make use of #ifdef's so that they can be disabled at compile-time. This is to enable better support for embedded systems and to track which code belongs to which feature.

Coding conventions

Code repositories

Old CVS repository

There is an old CVS repository hosted in SF.net. This is not used for any development.

Stable (SVN) repository

The OpenVPN project makes use of two code repositories. The Stable SVN repository is maintained by James Yonan and hosted at openvpn.net. Instructions for using it can be found here. Currently (Feb 2010) only James has write access to this repository, but anonymous read-only access is available.

Code from this repository should be used if stability is important for you, but the official releases are missing some essential piece of functionality.

Testing (Git) repository

The Testing repository is maintained by David Sommerseth and uses Git. This repository is hosted by SF.net under the OpenVPN project. The master branch in the git tree is based on the openvpn/branches/BETA21 SVN branch.

There are several branches in the Git tree, each of which tracks the different patches/contributions separately. There's also one branch that contains all the available patches:

This gives James a possibility to only include/merge in the features and bugfixes which he wants to include into his "stable" development branch.

It is expected that each contributor which have received a feature branch makes sure it merges cleanly against the development branch at
any time. The same applies to maintainers of external development Git trees. Also, the development of the feature branch is the author's responsibility - "testing" tree maintainer only collects the patches and makes sure all features and bugfixes play nicely together to catch conflicts as early as possible (and of course do sanity review of all patches).

Generic instructions for using Git in SF.net can be found here. Generic usage instructions for OpenVPN project's Git repository can be found here. To fetch the latest development code, use

You will here get a openvpn-testing directory. When entering this directory, you will get the 'master' branch by default. To checkout the allmerged branch, use

git checkout -b allmerged origin/allmerged

To see all available branches, use

git branch -a

Use the code in the allmerged branch from this git tree if you want the latest and greatest features and you're willing to encounter problems. If you're unfamiliar with Git in general, take a look at these links: