Things That Might Be Accomplished

There are various things that need to be done. Below is an non-comprehensive list of interesting projects in no particular order. Some don't really matter at all; others are critically important; some will be postponed into just immediately before submitting to mainline. If you're interested in working on any of these, please write an email to the WireGuard development team.

Android App

The Android application has been started but has quite a bit of work to do, particularly with wiring up the Go implementation to the Java. Due to the motley crew working on the app, an Android-specific todo list is available here.

iOS App

We currently have not started on an iOS application. The goal is for it to mirror the functionality of the Android application.

Cross-platform Userspace Implementations

There is an almost-complete Go implementation and an in-progress Rust implementation. These have been developed primarily with Linux in mind, and now efforts are needed in porting these to macOS, Windows, and the BSDs. The Go and Rust implementations themselves could use a hand in development.

BSD/NT/Darwin Kernel Implementations

Having a real kernel driver to obtain good performance, particularly on the BSDs, would be desirable. There is currently no progress in this front.

Exotic Implementations

Some have expressed interest in getting WireGuard running on DPDK, on FPGAs, in unikernels, and so forth.

Cryptographic Proofs and Formal Verifications

There has been some academic work in verifying the crypto, but always more is needed, particularly with regards to verifying WireGuard's state machines, as well as a proof of the protocol in a computational model, which may require extending ACCE.

Lock-free Multi-producer Multi-consumer Queue / Ring Buffer

Currently the queueing code uses ptr_ring.h, which is a ring buffer that uses spinlocks. This does not scale well to tons of CPUs. It would be useful to replace this with a lock-free data structure that can be both read and written from multiple CPUs at once.

CPU Auto-scaling

In the current multicore algorithm, all CPUs are started for packet processing. However, it would be more efficient to scale these up and scale these down, depending on load, dynamically. This would need to take into account NUMA.

Packet Locality

While WireGuard does multicore encryption, maintaining some sort of packet-cpu locality would be useful.

Generic Receive Offload

struct udp_tunnel_sock_cfg has two members that we don't currently use -- gro_receive and gro_complete. Wiring these up to get groups of packets and then adjusting receive.c to iterate through NULL-terminated packet lists like send.c would deliver significant performance benefits.

Resizable Hashtables

Rather than using a few large hashtables as we currently do in hashtables.c, it would be useful to port to struct rhashtable or something similar so that hashtables can dynamically resize.

Per-peer PMTU

Use path-MTU to use the optimal splitting per-peer endpoint, instead of having a single MTU per-interface.

Testing Infrastructure

The test infrastructure works great, but it could use more tests to examine more code paths. Separately, some tests that explore packets per second, latency, and buffer bloat issues would be quite handy.

Onion Routing

Related to the above, determine a strategy for routing WireGuard packets inside the same WireGuard device.

Integration into Network Managers

Integrate WireGuard's Netlink API -- uapi/wireguard.h -- into various network management tools, such as systemd-networkd, NetworkManager, and so forth.

Integration into Routing Daemons

Routing daemons need to be extended to take into account WireGuard's notion of AllowedIPs. It is somewhat important to have this be a separate notion, because it forces such daemons to consider the implications of changing routes based on differing trust models.

Mesh Networking Tools

It is possible to build a mesh network out of WireGuard using WireGuard as the building block. Write a tool that builds meshes and has peers discover each other, taking into account important authentication and trust properties.

WireGuard-Centric Networking Utilities

As WireGuard is a building block, it is now time to create interesting utilities out of this building block.

Configuration Daemons and Protocols

While most users are best off with static IPs, some people seem to want dynamic IPs. While this is technically a layer much beyond what WireGuard is about, it would indeed be useful to have some de facto standard mechanism and protocol for doing this. So let's develop this, maybe reusing existing standards, maybe sprinkling NIH as needed.

Timer Documentation

Better document the WireGuard state machine and required logic to obtain maximal security properties and interoperability. This task will require a complete understanding of the WireGuard paper, the Noise protocol, and the kernel C codebase.

Performance Improvements

There are many low-hanging fruits. Take your pick from the basket.

There needs to be a way of marking an struct sk_buff as "zero on free", so that we can securely zero out key information after passing it to userspace. This will involve patching the upstream kernel.

fq_codel Integration

In order to combat buffer bloat, WireGuard could benefit from integrating the fq_codel algorithm and kernel-library, for managing packet queues and parallelism. There is much related work in the kernel to base this on; in particular, many wireless drivers take the same technique using the same library.

Dynamic Queue Limits

Closely related to the above, struct dql could be used for controlling queue lengths, rather than hard coding sane values.

Exponential Backoff and Dynamic Timers

The timer state machine could benefit from being dynamic, in order to deal with extremely high latency networks, such as between Earth and the Moon. This project is likely too big to undertake at the present moment, but will be curious for investigating in the future.

Crypto API Integration

WireGuard currently uses its own crypto primitives. Moving to the Crypto API will require some work, both to WireGuard and more so to the kernel's crypto API.

Routing Table Improvements

The not_oif patch would be extremely helpful to complete. Here is the initial LKML thread. Implementation should be straightforward and indeed would be quite helpful. Pair not_oif with a setsockopt SO_NOTIF and this would solve all sorts of general Linux networking issues.

Accelerated Primitives

Add more accelerated primitives for crypto functions on new platforms or improve existing ones.

Lock Auditing

Does WireGuard make correct use of locking contexts? Are there any races?

Buffer Auditing

Are functions such as skb_prepare_header correct?

IPv6 Flowinfo, TTL, etc

Figure out what to do with IPv6 Flowinfo, TTL, and other interesting header fields.

Error Counters

A simple unsigned long for each error event, accessible to userspace, would be a useful aid for debugging.

Unaligned Accesses and Cache Lines

Audit the entire send and receive path to squelch any remaining unaligned accesses or accesses that cross cache lines.


The WireGuard project needs guides, howtos, in depth explanations, expanded man pages, blog posts, and every other type of guide for users, novice and expert alike.

Code Formatting

Due to various pathologies, the WireGuard codebase has very long lines. Clean things up in order to fit the Linux Kernel style guidelines. This task will be left until the final stages before submitting to mainline and not before.

Dynamic Web App for Provisioning

Many folks would like to run their own web app that dynamically provisions IPs and accepts keys based on some credential. It would be nice to revamp to use this.

Reevaluate skb_reset

It might be the case that skb_reset is doing too many things, and instead a simple __skb_tunnel_rx would do the trick. Should things be different on rx and tx? With regards to network namespaces? Header probing?

Fixup Includes

There's a bit of #include redundancy redundancy that could be cleaned up and reorganized.

Timer Pending Race Conditions

What happens if a timer fires in between a check of timer_pending and timer_mod or timer_del? Something to analyze, and possibly introduce a timer locking API to deal with this.