<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-go, branch master</title>
<subtitle>Go implementation of WireGuard</subtitle>
<id>https://git.zx2c4.com/wireguard-go/atom/?h=master</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-go/atom/?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/'/>
<updated>2026-10-24T22:09:52Z</updated>
<entry>
<title>device: don't overflow uint16 when adding v4 header length</title>
<updated>2026-10-24T22:09:52Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-10-24T22:09:52Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=b3bc704ef0ee21a36298601a9e1e5ff90377ac52'/>
<id>urn:sha1:b3bc704ef0ee21a36298601a9e1e5ff90377ac52</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: noise: reject response consumption after intermediate initiation</title>
<updated>2026-10-06T16:45:05Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2026-10-06T16:45:05Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=2631ce99a06f27120d581611cf125d68bc6aa565'/>
<id>urn:sha1:2631ce99a06f27120d581611cf125d68bc6aa565</id>
<content type='text'>
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one, B,
gets partway through, and during that slow calculation, A completes and
then also a handshake initiation that's already been queued up runs in
thread C. The handshake initiation creation succeeds, and sets the state
back to waiting-for-response, at which point thread B resumes. Thread B
then copies the state back to the peer, and begins a new session, using
that state, which is the same session as the one made in thread A.

This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>tun: clear virtioNetHdr when deleting item from tcpGROTable</title>
<updated>2026-05-22T21:04:24Z</updated>
<author>
<name>Jordan Whited</name>
<email>jordan@tailscale.com</email>
</author>
<published>2026-05-20T22:43:17Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=ecfc5a8d54462e18e13c72173e2623d16d8e25a0'/>
<id>urn:sha1:ecfc5a8d54462e18e13c72173e2623d16d8e25a0</id>
<content type='text'>
Otherwise the deleted packet gets written to the TUN fd with an invalid
virtioNetHdr.

Fixes: 9e2f386 ("conn, device, tun: implement vectorized I/O on Linux")
Signed-off-by: Jordan Whited &lt;jordan@tailscale.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>version: bump snapshot</title>
<updated>2025-05-21T23:45:02Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-21T23:45:02Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=f333402bd9cbe0f3eeb02507bd14e23d7d639280'/>
<id>urn:sha1:f333402bd9cbe0f3eeb02507bd14e23d7d639280</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>conn: don't enable GRO on Linux &lt; 5.12</title>
<updated>2025-05-21T23:43:39Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-21T23:33:55Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=c92064f1ce35f82bf0c5a183b54e51fd5d58ad50'/>
<id>urn:sha1:c92064f1ce35f82bf0c5a183b54e51fd5d58ad50</id>
<content type='text'>
Kernels below 5.12 are missing this:

    commit 98184612aca0a9ee42b8eb0262a49900ee9eef0d
    Author: Norman Maurer &lt;norman_maurer@apple.com&gt;
    Date:   Thu Apr 1 08:59:17 2021

        net: udp: Add support for getsockopt(..., ..., UDP_GRO, ..., ...);

        Support for UDP_GRO was added in the past but the implementation for
        getsockopt was missed which did lead to an error when we tried to
        retrieve the setting for UDP_GRO. This patch adds the missing switch
        case for UDP_GRO

        Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
        Signed-off-by: Norman Maurer &lt;norman_maurer@apple.com&gt;
        Reviewed-by: David Ahern &lt;dsahern@kernel.org&gt;
        Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;

That means we can't set the option and then read it back later. Given
how buggy UDP_GRO is in general on odd kernels, just disable it on older
kernels all together.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: optimize message encoding</title>
<updated>2025-05-20T22:09:36Z</updated>
<author>
<name>Alexander Yastrebov</name>
<email>yastrebov.alex@gmail.com</email>
</author>
<published>2025-05-17T09:34:30Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=264889f0bbdf9250bb8389a637dd5f38389bfe0b'/>
<id>urn:sha1:264889f0bbdf9250bb8389a637dd5f38389bfe0b</id>
<content type='text'>
Optimize message encoding by eliminating binary.Write (which internally
uses reflection) in favour of hand-rolled encoding.

This is companion to 9e7529c3d2d0c54f4d5384c01645a9279e4740ae.

Synthetic benchmark:

    var packetSink []byte
    func BenchmarkMessageInitiationMarshal(b *testing.B) {
        var msg MessageInitiation
        b.Run("binary.Write", func(b *testing.B) {
            b.ReportAllocs()
            for range b.N {
                var buf [MessageInitiationSize]byte
                writer := bytes.NewBuffer(buf[:0])
                _ = binary.Write(writer, binary.LittleEndian, msg)
                packetSink = writer.Bytes()
            }
        })
        b.Run("binary.Encode", func(b *testing.B) {
            b.ReportAllocs()
            for range b.N {
                packet := make([]byte, MessageInitiationSize)
                _, _ = binary.Encode(packet, binary.LittleEndian, msg)
                packetSink = packet
            }
        })
        b.Run("marshal", func(b *testing.B) {
            b.ReportAllocs()
            for range b.N {
                packet := make([]byte, MessageInitiationSize)
                _ = msg.marshal(packet)
                packetSink = packet
            }
        })
    }

Results:
                                             │      -      │
                                             │   sec/op    │
    MessageInitiationMarshal/binary.Write-8    1.337µ ± 0%
    MessageInitiationMarshal/binary.Encode-8   1.242µ ± 0%
    MessageInitiationMarshal/marshal-8         53.05n ± 1%

                                             │     -      │
                                             │    B/op    │
    MessageInitiationMarshal/binary.Write-8    368.0 ± 0%
    MessageInitiationMarshal/binary.Encode-8   160.0 ± 0%
    MessageInitiationMarshal/marshal-8         160.0 ± 0%

                                             │     -      │
                                             │ allocs/op  │
    MessageInitiationMarshal/binary.Write-8    3.000 ± 0%
    MessageInitiationMarshal/binary.Encode-8   1.000 ± 0%
    MessageInitiationMarshal/marshal-8         1.000 ± 0%

Signed-off-by: Alexander Yastrebov &lt;yastrebov.alex@gmail.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: add support for removing allowedips individually</title>
<updated>2025-05-20T21:03:06Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-20T21:03:06Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=256bcbd70d5b4eaae2a9f21a9889498c0f89041c'/>
<id>urn:sha1:256bcbd70d5b4eaae2a9f21a9889498c0f89041c</id>
<content type='text'>
This pairs with the recent change in wireguard-tools.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>version: bump snapshot</title>
<updated>2025-05-15T14:54:03Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-15T14:54:03Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=1571e0fbae8e1d955e05dde80071bc86880d61b3'/>
<id>urn:sha1:1571e0fbae8e1d955e05dde80071bc86880d61b3</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: make unmarshall length checks exact</title>
<updated>2025-05-15T14:48:14Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-15T14:48:14Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=842888ac5c93ccc5ee6344eceaadf783fcf1e243'/>
<id>urn:sha1:842888ac5c93ccc5ee6344eceaadf783fcf1e243</id>
<content type='text'>
This is already enforced in receive.go, but if these unmarshallers are
to have error return values anyway, make them as explicit as possible.

Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: reduce RoutineHandshake allocations</title>
<updated>2025-05-15T14:42:06Z</updated>
<author>
<name>Alexander Yastrebov</name>
<email>yastrebov.alex@gmail.com</email>
</author>
<published>2024-12-26T19:36:53Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=9e7529c3d2d0c54f4d5384c01645a9279e4740ae'/>
<id>urn:sha1:9e7529c3d2d0c54f4d5384c01645a9279e4740ae</id>
<content type='text'>
Reduce allocations by eliminating byte reader, hand-rolled decoding and
reusing message structs.

Synthetic benchmark:

    var msgSink MessageInitiation
    func BenchmarkMessageInitiationUnmarshal(b *testing.B) {
        packet := make([]byte, MessageInitiationSize)
        reader := bytes.NewReader(packet)
        err := binary.Read(reader, binary.LittleEndian, &amp;msgSink)
        if err != nil {
            b.Fatal(err)
        }
        b.Run("binary.Read", func(b *testing.B) {
            b.ReportAllocs()
            for range b.N {
                reader := bytes.NewReader(packet)
                _ = binary.Read(reader, binary.LittleEndian, &amp;msgSink)
            }
        })
        b.Run("unmarshal", func(b *testing.B) {
            b.ReportAllocs()
            for range b.N {
                _ = msgSink.unmarshal(packet)
            }
        })
    }

Results:
                                         │      -      │
                                         │   sec/op    │
MessageInitiationUnmarshal/binary.Read-8   1.508µ ± 2%
MessageInitiationUnmarshal/unmarshal-8     12.66n ± 2%

                                         │      -       │
                                         │     B/op     │
MessageInitiationUnmarshal/binary.Read-8   208.0 ± 0%
MessageInitiationUnmarshal/unmarshal-8     0.000 ± 0%

                                         │      -       │
                                         │  allocs/op   │
MessageInitiationUnmarshal/binary.Read-8   2.000 ± 0%
MessageInitiationUnmarshal/unmarshal-8     0.000 ± 0%

Signed-off-by: Alexander Yastrebov &lt;yastrebov.alex@gmail.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
</feed>
