Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !ts_omit_connreject
|
||||
|
||||
package tstun
|
||||
|
||||
import (
|
||||
"tailscale.com/net/connreject"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/syncs"
|
||||
)
|
||||
|
||||
// connRejectState holds the connreject feature's per-Wrapper storage.
|
||||
// Its definition only references [tailscale.com/net/connreject] when
|
||||
// the feature is built in; see connreject_stub.go for the no-op
|
||||
// counterpart used under -tags ts_omit_connreject.
|
||||
type connRejectState struct {
|
||||
cb syncs.AtomicValue[func(connreject.Event)]
|
||||
}
|
||||
|
||||
// SetConnRejectCallback installs a callback that is invoked when the
|
||||
// Wrapper emits an outbound TSMP reject for an inbound peer connection
|
||||
// that was dropped by the packet filter. The callback receives a fully
|
||||
// populated [connreject.Event] of [connreject.Incoming] direction.
|
||||
//
|
||||
// A nil fn unsets any previously installed callback.
|
||||
func (t *Wrapper) SetConnRejectCallback(fn func(connreject.Event)) {
|
||||
t.connReject.cb.Store(fn)
|
||||
}
|
||||
|
||||
// notifyConnRejectTSMPSent delivers an Incoming-direction event to the
|
||||
// installed callback, if any, derived from a TSMP reject we just
|
||||
// injected outbound.
|
||||
func (t *Wrapper) notifyConnRejectTSMPSent(rj packet.TailscaleRejectedHeader) {
|
||||
fn := t.connReject.cb.Load()
|
||||
if fn == nil {
|
||||
return
|
||||
}
|
||||
reason := connreject.ReasonACL
|
||||
if rj.Reason == packet.RejectedDueToShieldsUp {
|
||||
reason = connreject.ReasonShields
|
||||
}
|
||||
fn(connreject.Event{
|
||||
Direction: connreject.Incoming,
|
||||
Proto: rj.Proto,
|
||||
Src: rj.Src,
|
||||
Dst: rj.Dst,
|
||||
Reason: reason,
|
||||
Source: connreject.SourceTSMPSent,
|
||||
})
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build ts_omit_connreject
|
||||
|
||||
package tstun
|
||||
|
||||
import "tailscale.com/net/packet"
|
||||
|
||||
// connRejectState is the omit-build counterpart of the type in
|
||||
// connreject.go. It is an empty struct so the Wrapper's connReject
|
||||
// field exists in both builds without referencing
|
||||
// tailscale.com/net/connreject.
|
||||
type connRejectState struct{}
|
||||
|
||||
// notifyConnRejectTSMPSent is a no-op when the connreject feature is
|
||||
// omitted at build time.
|
||||
func (*Wrapper) notifyConnRejectTSMPSent(packet.TailscaleRejectedHeader) {}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tstun
|
||||
@@ -33,7 +33,7 @@ func (t *fakeTUN) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *fakeTUN) Read(out [][]byte, sizes []int, offset int) (int, error) {
|
||||
func (t *fakeTUN) Read(slab []byte, packets []tun.ReadPacket) (int, error) {
|
||||
<-t.closechan
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !windows
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tstun
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tstun
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build ts_omit_netstack
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !ts_omit_netstack
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build aix || solaris || illumos
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !wasm && !tamago && !aix && !solaris && !illumos
|
||||
|
||||
// Package tun creates a tuntap device, working around OS-specific
|
||||
// quirks if necessary.
|
||||
// Package tstun creates a tuntap device, working around OS-specific quirks if
|
||||
// necessary.
|
||||
package tstun
|
||||
|
||||
import (
|
||||
|
||||
+27
-9
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tstun
|
||||
@@ -86,14 +86,32 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error)
|
||||
logf("kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: %s", findOut)
|
||||
}
|
||||
case distro.OpenWrt:
|
||||
out, err := exec.Command("opkg", "list-installed").CombinedOutput()
|
||||
if err != nil {
|
||||
logf("error querying OpenWrt installed packages: %s", out)
|
||||
return
|
||||
}
|
||||
for _, pkg := range []string{"kmod-tun", "ca-bundle"} {
|
||||
if !bytes.Contains(out, []byte(pkg+" - ")) {
|
||||
logf("Missing required package %s; run: opkg install %s", pkg, pkg)
|
||||
// OpenWRT switched to using apk as a package manager as of OpenWrt 25.12.0.
|
||||
// Find out what is used on this system and use that, Maybe we can get rid
|
||||
// of opkg in the future but for now keep checking.
|
||||
|
||||
if path, err := exec.LookPath("apk"); err == nil && path != "" {
|
||||
// Test with apk
|
||||
out, err := exec.Command("apk", "info").CombinedOutput()
|
||||
if err != nil {
|
||||
logf("error querying OpenWrt installed packages with apk: %s", out)
|
||||
return
|
||||
}
|
||||
for _, pkg := range []string{"kmod-tun", "ca-bundle"} {
|
||||
if !bytes.Contains(out, []byte(pkg)) {
|
||||
logf("Missing required package %s; run: apk add %s", pkg, pkg)
|
||||
}
|
||||
}
|
||||
} else { // Check for package with opkg (legacy)
|
||||
out, err := exec.Command("opkg", "list-installed").CombinedOutput()
|
||||
if err != nil {
|
||||
logf("error querying OpenWrt installed packages with opkg: %s", out)
|
||||
return
|
||||
}
|
||||
for _, pkg := range []string{"kmod-tun", "ca-bundle"} {
|
||||
if !bytes.Contains(out, []byte(pkg+" - ")) {
|
||||
logf("Missing required package %s; run: opkg install %s", pkg, pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build darwin && !ios
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !windows
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tstun
|
||||
|
||||
+346
-331
File diff suppressed because it is too large.
Load diff
+41
-12
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux && !ts_omit_gro
|
||||
@@ -15,22 +15,26 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/checksum"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"tailscale.com/control/controlknobs"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/tsaddr"
|
||||
)
|
||||
|
||||
// SetLinkFeaturesPostUp configures link features on t based on select TS_TUN_
|
||||
// environment variables and OS feature tests. Callers should ensure t is
|
||||
// up prior to calling, otherwise OS feature tests may be inconclusive.
|
||||
func (t *Wrapper) SetLinkFeaturesPostUp() {
|
||||
// environment variables, control-plane node attributes (via knobs, which may be
|
||||
// nil), and OS feature tests. Callers should ensure t is up prior to calling,
|
||||
// otherwise OS feature tests may be inconclusive.
|
||||
func (t *Wrapper) SetLinkFeaturesPostUp(knobs *controlknobs.Knobs) {
|
||||
if t.isTAP || runtime.GOOS == "android" {
|
||||
return
|
||||
}
|
||||
if groDev, ok := t.tdev.(tun.GRODevice); ok {
|
||||
if envknob.Bool("TS_TUN_DISABLE_UDP_GRO") {
|
||||
if envknob.Bool("TS_TUN_DISABLE_UDP_GRO") ||
|
||||
(knobs != nil && knobs.DisableTUNUDPGRO.Load()) {
|
||||
groDev.DisableUDPGRO()
|
||||
}
|
||||
if envknob.Bool("TS_TUN_DISABLE_TCP_GRO") {
|
||||
if envknob.Bool("TS_TUN_DISABLE_TCP_GRO") ||
|
||||
(knobs != nil && knobs.DisableTUNTCPGRO.Load()) {
|
||||
groDev.DisableTCPGRO()
|
||||
}
|
||||
err := probeTCPGRO(groDev)
|
||||
@@ -42,6 +46,31 @@ func (t *Wrapper) SetLinkFeaturesPostUp() {
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyGROKnobs applies the [tailcfg.NodeAttrDisableTUNUDPGRO] and
|
||||
// [tailcfg.NodeAttrDisableTUNTCPGRO] knob values (via knobs, which must be
|
||||
// non-nil) to t's underlying device. It is intended to be called when a
|
||||
// control-plane node attribute change is detected after [SetLinkFeaturesPostUp]
|
||||
// has already run.
|
||||
//
|
||||
// Note: wireguard-go's GRO disablement is one-way (sticky); ApplyGROKnobs can
|
||||
// move TUN UDP/TCP GRO from enabled to disabled, but the reverse requires a
|
||||
// client restart.
|
||||
func (t *Wrapper) ApplyGROKnobs(knobs *controlknobs.Knobs) {
|
||||
if t.isTAP || runtime.GOOS == "android" || knobs == nil {
|
||||
return
|
||||
}
|
||||
groDev, ok := t.tdev.(tun.GRODevice)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if knobs.DisableTUNUDPGRO.Load() {
|
||||
groDev.DisableUDPGRO()
|
||||
}
|
||||
if knobs.DisableTUNTCPGRO.Load() {
|
||||
groDev.DisableTCPGRO()
|
||||
}
|
||||
}
|
||||
|
||||
func probeTCPGRO(dev tun.GRODevice) error {
|
||||
ipPort := netip.MustParseAddrPort(tsaddr.TailscaleServiceIPString + ":0")
|
||||
fingerprint := []byte("tailscale-probe-tun-gro")
|
||||
@@ -52,8 +81,8 @@ func probeTCPGRO(dev tun.GRODevice) error {
|
||||
ipAs4 := ipPort.Addr().As4()
|
||||
bufs := make([][]byte, 2)
|
||||
for i := range bufs {
|
||||
bufs[i] = make([]byte, PacketStartOffset+totalLen, PacketStartOffset+(totalLen*2))
|
||||
ipv4H := header.IPv4(bufs[i][PacketStartOffset:])
|
||||
bufs[i] = make([]byte, WritePacketStartOffset+totalLen, WritePacketStartOffset+(totalLen*2))
|
||||
ipv4H := header.IPv4(bufs[i][WritePacketStartOffset:])
|
||||
ipv4H.Encode(&header.IPv4Fields{
|
||||
SrcAddr: tcpip.AddrFromSlice(ipAs4[:]),
|
||||
DstAddr: tcpip.AddrFromSlice(ipAs4[:]),
|
||||
@@ -63,7 +92,7 @@ func probeTCPGRO(dev tun.GRODevice) error {
|
||||
TTL: 0,
|
||||
TotalLength: uint16(totalLen),
|
||||
})
|
||||
tcpH := header.TCP(bufs[i][PacketStartOffset+iphLen:])
|
||||
tcpH := header.TCP(bufs[i][WritePacketStartOffset+iphLen:])
|
||||
tcpH.Encode(&header.TCPFields{
|
||||
SrcPort: ipPort.Port(),
|
||||
DstPort: ipPort.Port(),
|
||||
@@ -73,12 +102,12 @@ func probeTCPGRO(dev tun.GRODevice) error {
|
||||
Flags: header.TCPFlagAck,
|
||||
WindowSize: 3000,
|
||||
})
|
||||
copy(bufs[i][PacketStartOffset+iphLen+tcphLen:], fingerprint)
|
||||
copy(bufs[i][WritePacketStartOffset+iphLen+tcphLen:], fingerprint)
|
||||
ipv4H.SetChecksum(^ipv4H.CalculateChecksum())
|
||||
pseudoCsum := header.PseudoHeaderChecksum(unix.IPPROTO_TCP, ipv4H.SourceAddress(), ipv4H.DestinationAddress(), uint16(tcphLen+segmentSize))
|
||||
pseudoCsum = checksum.Checksum(bufs[i][PacketStartOffset+iphLen+tcphLen:], pseudoCsum)
|
||||
pseudoCsum = checksum.Checksum(bufs[i][WritePacketStartOffset+iphLen+tcphLen:], pseudoCsum)
|
||||
tcpH.SetChecksum(^tcpH.CalculateChecksum(pseudoCsum))
|
||||
}
|
||||
_, err := dev.Write(bufs, PacketStartOffset)
|
||||
_, err := dev.Write(bufs, WritePacketStartOffset)
|
||||
return err
|
||||
}
|
||||
+6
-2
@@ -1,8 +1,12 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !linux || ts_omit_gro
|
||||
|
||||
package tstun
|
||||
|
||||
func (t *Wrapper) SetLinkFeaturesPostUp() {}
|
||||
import "tailscale.com/control/controlknobs"
|
||||
|
||||
func (t *Wrapper) SetLinkFeaturesPostUp(_ *controlknobs.Knobs) {}
|
||||
|
||||
func (t *Wrapper) ApplyGROKnobs(_ *controlknobs.Knobs) {}
|
||||
Reference in new issue
Block a user