device: improve MTU change handling

The old code silently accepted negative MTUs.
It also set MTUs above the maximum.
It also had hard to follow deeply nested conditionals.

Add more paranoid handling,
and make the code more straight-line.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
Josh Bleecher Snyder 2021-01-21 09:23:45 -08:00
parent 3516ccc1e2
commit 675ff32e6c

View file

@ -6,6 +6,7 @@
package device package device
import ( import (
"fmt"
"sync/atomic" "sync/atomic"
"golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/tun"
@ -20,16 +21,22 @@ func (device *Device) RoutineTUNEventReader() {
for event := range device.tun.device.Events() { for event := range device.tun.device.Events() {
if event&tun.EventMTUUpdate != 0 { if event&tun.EventMTUUpdate != 0 {
mtu, err := device.tun.device.MTU() mtu, err := device.tun.device.MTU()
old := atomic.LoadInt32(&device.tun.mtu)
if err != nil { if err != nil {
device.log.Errorf("Failed to load updated MTU of device: %v", err) device.log.Errorf("Failed to load updated MTU of device: %v", err)
} else if int(old) != mtu { continue
if mtu+MessageTransportSize > MaxMessageSize {
device.log.Verbosef("MTU updated: %v (too large)", mtu)
} else {
device.log.Verbosef("MTU updated: %v", mtu)
} }
atomic.StoreInt32(&device.tun.mtu, int32(mtu)) if mtu < 0 {
device.log.Errorf("MTU not updated to negative value: %v", mtu)
continue
}
var tooLarge string
if mtu > MaxContentSize {
tooLarge = fmt.Sprintf(" (too large, capped at %v)", MaxContentSize)
mtu = MaxContentSize
}
old := atomic.SwapInt32(&device.tun.mtu, int32(mtu))
if int(old) != mtu {
device.log.Verbosef("MTU updated: %v%s", mtu, tooLarge)
} }
} }