Update dependencies
This commit is contained in:
140
vendor/tailscale.com/net/tstun/wrap.go
generated
vendored
140
vendor/tailscale.com/net/tstun/wrap.go
generated
vendored
@@ -36,7 +36,6 @@ import (
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/usermetric"
|
||||
"tailscale.com/wgengine/capture"
|
||||
"tailscale.com/wgengine/filter"
|
||||
"tailscale.com/wgengine/netstack/gro"
|
||||
"tailscale.com/wgengine/wgcfg"
|
||||
@@ -53,7 +52,8 @@ const PacketStartOffset = device.MessageTransportHeaderSize
|
||||
// of a packet that can be injected into a tstun.Wrapper.
|
||||
const MaxPacketSize = device.MaxContentSize
|
||||
|
||||
const tapDebug = false // for super verbose TAP debugging
|
||||
// TAPDebug is whether super verbose TAP debugging is enabled.
|
||||
const TAPDebug = false
|
||||
|
||||
var (
|
||||
// ErrClosed is returned when attempting an operation on a closed Wrapper.
|
||||
@@ -109,9 +109,7 @@ type Wrapper struct {
|
||||
lastActivityAtomic mono.Time // time of last send or receive
|
||||
|
||||
destIPActivity syncs.AtomicValue[map[netip.Addr]func()]
|
||||
//lint:ignore U1000 used in tap_linux.go
|
||||
destMACAtomic syncs.AtomicValue[[6]byte]
|
||||
discoKey syncs.AtomicValue[key.DiscoPublic]
|
||||
discoKey syncs.AtomicValue[key.DiscoPublic]
|
||||
|
||||
// timeNow, if non-nil, will be used to obtain the current time.
|
||||
timeNow func() time.Time
|
||||
@@ -209,30 +207,20 @@ type Wrapper struct {
|
||||
// stats maintains per-connection counters.
|
||||
stats atomic.Pointer[connstats.Statistics]
|
||||
|
||||
captureHook syncs.AtomicValue[capture.Callback]
|
||||
captureHook syncs.AtomicValue[packet.CaptureCallback]
|
||||
|
||||
metrics *metrics
|
||||
}
|
||||
|
||||
type metrics struct {
|
||||
inboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[dropPacketLabel]
|
||||
outboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[dropPacketLabel]
|
||||
inboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[usermetric.DropLabels]
|
||||
outboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[usermetric.DropLabels]
|
||||
}
|
||||
|
||||
func registerMetrics(reg *usermetric.Registry) *metrics {
|
||||
return &metrics{
|
||||
inboundDroppedPacketsTotal: usermetric.NewMultiLabelMapWithRegistry[dropPacketLabel](
|
||||
reg,
|
||||
"tailscaled_inbound_dropped_packets_total",
|
||||
"counter",
|
||||
"Counts the number of dropped packets received by the node from other peers",
|
||||
),
|
||||
outboundDroppedPacketsTotal: usermetric.NewMultiLabelMapWithRegistry[dropPacketLabel](
|
||||
reg,
|
||||
"tailscaled_outbound_dropped_packets_total",
|
||||
"counter",
|
||||
"Counts the number of packets dropped while being sent to other peers",
|
||||
),
|
||||
inboundDroppedPacketsTotal: reg.DroppedPacketsInbound(),
|
||||
outboundDroppedPacketsTotal: reg.DroppedPacketsOutbound(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,12 +245,6 @@ type tunVectorReadResult struct {
|
||||
dataOffset int
|
||||
}
|
||||
|
||||
type setWrapperer interface {
|
||||
// setWrapper enables the underlying TUN/TAP to have access to the Wrapper.
|
||||
// It MUST be called only once during initialization, other usage is unsafe.
|
||||
setWrapper(*Wrapper)
|
||||
}
|
||||
|
||||
// Start unblocks any Wrapper.Read calls that have already started
|
||||
// and makes the Wrapper functional.
|
||||
//
|
||||
@@ -313,10 +295,6 @@ func wrap(logf logger.Logf, tdev tun.Device, isTAP bool, m *usermetric.Registry)
|
||||
w.bufferConsumed <- struct{}{}
|
||||
w.noteActivity()
|
||||
|
||||
if sw, ok := w.tdev.(setWrapperer); ok {
|
||||
sw.setWrapper(w)
|
||||
}
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
@@ -459,12 +437,18 @@ const ethernetFrameSize = 14 // 2 six byte MACs, 2 bytes ethertype
|
||||
func (t *Wrapper) pollVector() {
|
||||
sizes := make([]int, len(t.vectorBuffer))
|
||||
readOffset := PacketStartOffset
|
||||
reader := t.tdev.Read
|
||||
if t.isTAP {
|
||||
readOffset = PacketStartOffset - ethernetFrameSize
|
||||
type tapReader interface {
|
||||
ReadEthernet(buffs [][]byte, sizes []int, offset int) (int, error)
|
||||
}
|
||||
if r, ok := t.tdev.(tapReader); ok {
|
||||
readOffset = PacketStartOffset - ethernetFrameSize
|
||||
reader = r.ReadEthernet
|
||||
}
|
||||
}
|
||||
|
||||
for range t.bufferConsumed {
|
||||
DoRead:
|
||||
for i := range t.vectorBuffer {
|
||||
t.vectorBuffer[i] = t.vectorBuffer[i][:cap(t.vectorBuffer[i])]
|
||||
}
|
||||
@@ -474,8 +458,8 @@ func (t *Wrapper) pollVector() {
|
||||
if t.isClosed() {
|
||||
return
|
||||
}
|
||||
n, err = t.tdev.Read(t.vectorBuffer[:], sizes, readOffset)
|
||||
if t.isTAP && tapDebug {
|
||||
n, err = reader(t.vectorBuffer[:], sizes, readOffset)
|
||||
if t.isTAP && TAPDebug {
|
||||
s := fmt.Sprintf("% x", t.vectorBuffer[0][:])
|
||||
for strings.HasSuffix(s, " 00") {
|
||||
s = strings.TrimSuffix(s, " 00")
|
||||
@@ -486,21 +470,6 @@ func (t *Wrapper) pollVector() {
|
||||
for i := range sizes[:n] {
|
||||
t.vectorBuffer[i] = t.vectorBuffer[i][:readOffset+sizes[i]]
|
||||
}
|
||||
if t.isTAP {
|
||||
if err == nil {
|
||||
ethernetFrame := t.vectorBuffer[0][readOffset:]
|
||||
if t.handleTAPFrame(ethernetFrame) {
|
||||
goto DoRead
|
||||
}
|
||||
}
|
||||
// Fall through. We got an IP packet.
|
||||
if sizes[0] >= ethernetFrameSize {
|
||||
t.vectorBuffer[0] = t.vectorBuffer[0][:readOffset+sizes[0]-ethernetFrameSize]
|
||||
}
|
||||
if tapDebug {
|
||||
t.logf("tap regular frame: %x", t.vectorBuffer[0][PacketStartOffset:PacketStartOffset+sizes[0]])
|
||||
}
|
||||
}
|
||||
t.sendVectorOutbound(tunVectorReadResult{
|
||||
data: t.vectorBuffer[:n],
|
||||
dataOffset: PacketStartOffset,
|
||||
@@ -823,10 +792,21 @@ func (pc *peerConfigTable) outboundPacketIsJailed(p *packet.Parsed) bool {
|
||||
return c.jailed
|
||||
}
|
||||
|
||||
// SetIPer is the interface expected to be implemented by the TAP implementation
|
||||
// of tun.Device.
|
||||
type SetIPer interface {
|
||||
// SetIP sets the IP addresses of the TAP device.
|
||||
SetIP(ipV4, ipV6 netip.Addr) error
|
||||
}
|
||||
|
||||
// SetWGConfig is called when a new NetworkMap is received.
|
||||
func (t *Wrapper) SetWGConfig(wcfg *wgcfg.Config) {
|
||||
if t.isTAP {
|
||||
if sip, ok := t.tdev.(SetIPer); ok {
|
||||
sip.SetIP(findV4(wcfg.Addresses), findV6(wcfg.Addresses))
|
||||
}
|
||||
}
|
||||
cfg := peerConfigTableFromWGConfig(wcfg)
|
||||
|
||||
old := t.peerConfig.Swap(cfg)
|
||||
if !reflect.DeepEqual(old, cfg) {
|
||||
t.logf("peer config: %v", cfg)
|
||||
@@ -896,11 +876,13 @@ func (t *Wrapper) filterPacketOutboundToWireGuard(p *packet.Parsed, pc *peerConf
|
||||
return filter.Drop, gro
|
||||
}
|
||||
|
||||
if filt.RunOut(p, t.filterFlags) != filter.Accept {
|
||||
if resp, reason := filt.RunOut(p, t.filterFlags); resp != filter.Accept {
|
||||
metricPacketOutDropFilter.Add(1)
|
||||
t.metrics.outboundDroppedPacketsTotal.Add(dropPacketLabel{
|
||||
Reason: DropReasonACL,
|
||||
}, 1)
|
||||
if reason != "" {
|
||||
t.metrics.outboundDroppedPacketsTotal.Add(usermetric.DropLabels{
|
||||
Reason: reason,
|
||||
}, 1)
|
||||
}
|
||||
return filter.Drop, gro
|
||||
}
|
||||
|
||||
@@ -925,9 +907,23 @@ func (t *Wrapper) IdleDuration() time.Duration {
|
||||
return mono.Since(t.lastActivityAtomic.LoadAtomic())
|
||||
}
|
||||
|
||||
func (t *Wrapper) awaitStart() {
|
||||
for {
|
||||
select {
|
||||
case <-t.startCh:
|
||||
return
|
||||
case <-time.After(1 * time.Second):
|
||||
// Multiple times while remixing tailscaled I (Brad) have forgotten
|
||||
// to call Start and then wasted far too much time debugging.
|
||||
// I do not wish that debugging on anyone else. Hopefully this'll help:
|
||||
t.logf("tstun: awaiting Wrapper.Start call")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
if !t.started.Load() {
|
||||
<-t.startCh
|
||||
t.awaitStart()
|
||||
}
|
||||
// packet from OS read and sent to WG
|
||||
res, ok := <-t.vectorOutbound
|
||||
@@ -958,7 +954,7 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
||||
}
|
||||
}
|
||||
if captHook != nil {
|
||||
captHook(capture.FromLocal, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
captHook(packet.FromLocal, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
}
|
||||
if !t.disableFilter {
|
||||
var response filter.Response
|
||||
@@ -1104,9 +1100,9 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (t *Wrapper) filterPacketInboundFromWireGuard(p *packet.Parsed, captHook capture.Callback, pc *peerConfigTable, gro *gro.GRO) (filter.Response, *gro.GRO) {
|
||||
func (t *Wrapper) filterPacketInboundFromWireGuard(p *packet.Parsed, captHook packet.CaptureCallback, pc *peerConfigTable, gro *gro.GRO) (filter.Response, *gro.GRO) {
|
||||
if captHook != nil {
|
||||
captHook(capture.FromPeer, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
captHook(packet.FromPeer, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
}
|
||||
|
||||
if p.IPProto == ipproto.TSMP {
|
||||
@@ -1170,8 +1166,8 @@ func (t *Wrapper) filterPacketInboundFromWireGuard(p *packet.Parsed, captHook ca
|
||||
|
||||
if outcome != filter.Accept {
|
||||
metricPacketInDropFilter.Add(1)
|
||||
t.metrics.inboundDroppedPacketsTotal.Add(dropPacketLabel{
|
||||
Reason: DropReasonACL,
|
||||
t.metrics.inboundDroppedPacketsTotal.Add(usermetric.DropLabels{
|
||||
Reason: usermetric.ReasonACL,
|
||||
}, 1)
|
||||
|
||||
// Tell them, via TSMP, we're dropping them due to the ACL.
|
||||
@@ -1251,8 +1247,8 @@ func (t *Wrapper) Write(buffs [][]byte, offset int) (int, error) {
|
||||
t.noteActivity()
|
||||
_, err := t.tdevWrite(buffs, offset)
|
||||
if err != nil {
|
||||
t.metrics.inboundDroppedPacketsTotal.Add(dropPacketLabel{
|
||||
Reason: DropReasonError,
|
||||
t.metrics.inboundDroppedPacketsTotal.Add(usermetric.DropLabels{
|
||||
Reason: usermetric.ReasonError,
|
||||
}, int64(len(buffs)))
|
||||
}
|
||||
return len(buffs), err
|
||||
@@ -1320,7 +1316,7 @@ func (t *Wrapper) InjectInboundPacketBuffer(pkt *stack.PacketBuffer, buffs [][]b
|
||||
p.Decode(buf)
|
||||
captHook := t.captureHook.Load()
|
||||
if captHook != nil {
|
||||
captHook(capture.SynthesizedToLocal, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
captHook(packet.SynthesizedToLocal, t.now(), p.Buffer(), p.CaptureMeta)
|
||||
}
|
||||
|
||||
invertGSOChecksum(buf, pkt.GSOOptions)
|
||||
@@ -1452,7 +1448,7 @@ func (t *Wrapper) InjectOutboundPacketBuffer(pkt *stack.PacketBuffer) error {
|
||||
}
|
||||
if capt := t.captureHook.Load(); capt != nil {
|
||||
b := pkt.ToBuffer()
|
||||
capt(capture.SynthesizedToPeer, t.now(), b.Flatten(), packet.CaptureMeta{})
|
||||
capt(packet.SynthesizedToPeer, t.now(), b.Flatten(), packet.CaptureMeta{})
|
||||
}
|
||||
|
||||
t.injectOutbound(tunInjectedRead{packet: pkt})
|
||||
@@ -1494,20 +1490,6 @@ var (
|
||||
metricPacketOutDropSelfDisco = clientmetric.NewCounter("tstun_out_to_wg_drop_self_disco")
|
||||
)
|
||||
|
||||
type DropReason string
|
||||
|
||||
const (
|
||||
DropReasonACL DropReason = "acl"
|
||||
DropReasonError DropReason = "error"
|
||||
)
|
||||
|
||||
type dropPacketLabel struct {
|
||||
// Reason indicates what we have done with the packet, and has the following values:
|
||||
// - acl (rejected packets because of ACL)
|
||||
// - error (rejected packets because of an error)
|
||||
Reason DropReason
|
||||
}
|
||||
|
||||
func (t *Wrapper) InstallCaptureHook(cb capture.Callback) {
|
||||
func (t *Wrapper) InstallCaptureHook(cb packet.CaptureCallback) {
|
||||
t.captureHook.Store(cb)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user