<feed xmlns='http://www.w3.org/2005/Atom'>
<title>wireguard-go/device, branch master</title>
<subtitle>Go implementation of WireGuard</subtitle>
<id>https://git.zx2c4.com/wireguard-go/atom/device?h=master</id>
<link rel='self' href='https://git.zx2c4.com/wireguard-go/atom/device?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/'/>
<updated>2025-05-20T22:09:36Z</updated>
<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>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>
<entry>
<title>device: use rand.NewSource instead of rand.Seed</title>
<updated>2025-05-05T13:10:08Z</updated>
<author>
<name>Tom Holford</name>
<email>tomholford@users.noreply.github.com</email>
</author>
<published>2025-05-04T16:49:49Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=0e4482a086cb6dd9bb2baac8b538d1dbf354c136'/>
<id>urn:sha1:0e4482a086cb6dd9bb2baac8b538d1dbf354c136</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>global: replaced unused function params with _</title>
<updated>2025-05-05T13:10:08Z</updated>
<author>
<name>Tom Holford</name>
<email>tomholford@users.noreply.github.com</email>
</author>
<published>2025-05-04T16:49:03Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=77b6c824a8225328aebca78eba676ea7eb606a69'/>
<id>urn:sha1:77b6c824a8225328aebca78eba676ea7eb606a69</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>global: bump copyright notice</title>
<updated>2025-05-05T13:05:35Z</updated>
<author>
<name>Jason A. Donenfeld</name>
<email>Jason@zx2c4.com</email>
</author>
<published>2025-05-04T15:48:53Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=9eb3221f1de589e5dd6a1721fdd7dc0fde0eb10b'/>
<id>urn:sha1:9eb3221f1de589e5dd6a1721fdd7dc0fde0eb10b</id>
<content type='text'>
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
<entry>
<title>device: fix missed return of QueueOutboundElementsContainer to its WaitPool</title>
<updated>2025-05-04T16:11:00Z</updated>
<author>
<name>Jordan Whited</name>
<email>jordan@tailscale.com</email>
</author>
<published>2024-06-27T16:06:40Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=867a4c4a3f3a1a8fc4934553c8091c094ed6bdf8'/>
<id>urn:sha1:867a4c4a3f3a1a8fc4934553c8091c094ed6bdf8</id>
<content type='text'>
Fixes: 3bb8fec ("conn, device, tun: implement vectorized I/O plumbing")
Reviewed-by: Brad Fitzpatrick &lt;bradfitz@tailscale.com&gt;
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>device: fix WaitPool sync.Cond usage</title>
<updated>2025-05-04T16:11:00Z</updated>
<author>
<name>Jordan Whited</name>
<email>jordan@tailscale.com</email>
</author>
<published>2024-06-27T15:43:41Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=113c8f1340ed8748da68528112d746469de11ae0'/>
<id>urn:sha1:113c8f1340ed8748da68528112d746469de11ae0</id>
<content type='text'>
The sync.Locker used with a sync.Cond must be acquired when changing
the associated condition, otherwise there is a window within
sync.Cond.Wait() where a wake-up may be missed.

Fixes: 4846070 ("device: use a waiting sync.Pool instead of a channel")
Reviewed-by: Brad Fitzpatrick &lt;bradfitz@tailscale.com&gt;
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>device: fix possible deadlock in close method</title>
<updated>2023-12-11T15:38:47Z</updated>
<author>
<name>Martin Basovnik</name>
<email>martin.basovnik@gmail.com</email>
</author>
<published>2023-11-10T10:10:12Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/wireguard-go/commit/?id=12269c2761734b15625017d8565745096325392f'/>
<id>urn:sha1:12269c2761734b15625017d8565745096325392f</id>
<content type='text'>
There is a possible deadlock in `device.Close()` when you try to close
the device very soon after its start. The problem is that two different
methods acquire the same locks in different order:

1. device.Close()
 - device.ipcMutex.Lock()
 - device.state.Lock()

2. device.changeState(deviceState)
 - device.state.Lock()
 - device.ipcMutex.Lock()

Reproducer:

    func TestDevice_deadlock(t *testing.T) {
    	d := randDevice(t)
    	d.Close()
    }

Problem:

    $ go clean -testcache &amp;&amp; go test -race -timeout 3s -run TestDevice_deadlock ./device | grep -A 10 sync.runtime_SemacquireMutex
    sync.runtime_SemacquireMutex(0xc000117d20?, 0x94?, 0x0?)
            /usr/local/opt/go/libexec/src/runtime/sema.go:77 +0x25
    sync.(*Mutex).lockSlow(0xc000130518)
            /usr/local/opt/go/libexec/src/sync/mutex.go:171 +0x213
    sync.(*Mutex).Lock(0xc000130518)
            /usr/local/opt/go/libexec/src/sync/mutex.go:90 +0x55
    golang.zx2c4.com/wireguard/device.(*Device).Close(0xc000130500)
            /Users/martin.basovnik/git/basovnik/wireguard-go/device/device.go:373 +0xb6
    golang.zx2c4.com/wireguard/device.TestDevice_deadlock(0x0?)
            /Users/martin.basovnik/git/basovnik/wireguard-go/device/device_test.go:480 +0x2c
    testing.tRunner(0xc00014c000, 0x131d7b0)
    --
    sync.runtime_SemacquireMutex(0xc000130564?, 0x60?, 0xc000130548?)
            /usr/local/opt/go/libexec/src/runtime/sema.go:77 +0x25
    sync.(*Mutex).lockSlow(0xc000130750)
            /usr/local/opt/go/libexec/src/sync/mutex.go:171 +0x213
    sync.(*Mutex).Lock(0xc000130750)
            /usr/local/opt/go/libexec/src/sync/mutex.go:90 +0x55
    sync.(*RWMutex).Lock(0xc000130750)
            /usr/local/opt/go/libexec/src/sync/rwmutex.go:147 +0x45
    golang.zx2c4.com/wireguard/device.(*Device).upLocked(0xc000130500)
            /Users/martin.basovnik/git/basovnik/wireguard-go/device/device.go:179 +0x72
    golang.zx2c4.com/wireguard/device.(*Device).changeState(0xc000130500, 0x1)

Signed-off-by: Martin Basovnik &lt;martin.basovnik@gmail.com&gt;
Signed-off-by: Jason A. Donenfeld &lt;Jason@zx2c4.com&gt;
</content>
</entry>
</feed>
