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.
Integration into Network Managers
Integrate WireGuard's Netlink API -- uapi/wireguard.h
-- into various network management tools.
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.
Onion Routing
Related to the above, determine a strategy for routing WireGuard packets inside the same WireGuard device.
Configuration Daemons and Protocols (wg-dynamic
)
The wg-dynamic
project is underway and could use a hand.
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. Build onto of wg-dynamic
.
WireGuard-Centric Networking Utilities
As WireGuard is a building block, it is now time to create interesting utilities out of this building block.
Windows App
See the todo list specific to the Windows work.
macOS and iOS Apps
See the todo list specific to Apple work.
Android App
See the todo list specific to Android work.
NT/Darwin Kernel Implementations
Having a real kernel driver to obtain good performance would be desirable. This is not essential, as the userspace implementation is quite high performance, but for those who have a particular proclivity to kernel programming, this might be fun.
Exotic Implementations
Some have expressed interest in getting WireGuard running on DPDK, on FPGAs, in unikernels, and so forth.
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. More importantly, is it possible to do this securely?
Testing Infrastructure
The netns.sh
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.
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.
Socket Buffer Netlink Zeroing
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.
Trie Improvements
Removal by peer is currently slow, as it has to traverse the entire trie. Since the peer already knows which nodes are his, we could instead walk through this list for removal. Challenges of this approach include finding space for a parent pointer (to keep the size of the node ≤64 bytes) and studying the complexity of sorting the list of nodes for removal prior to removal or during insertion, and whether a rbtree would therefore be more apt or if we're regressing entirely with that kind of complexity.
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.
Documentation
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.
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 demo.wireguard.com to use this. A vague write-up of one potential means of implementation lives here.
Fixup Includes
There's a bit of #include
redundancy redundancy that could be cleaned up and reorganized.
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.
Better Timestamps
Rather than using ktime_get_real_ts64
for the noise timestamp, can we instead use some sort of basetime + monotonic counter? See this branch.
What about blinding the timestamp by some private+public pair hash?