mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-10 01:53:49 +00:00
7675c3ebf2
In df6014f1d7bf437adf239b75a62fd4c2f389ea2a we removed build tag gating preventing importation, which tripped a NetworkExtension limit test in corp. This was a reversal of 25f0a3fc8f6f9cf681bb5afda8e1762816c67a8b which actually made the situation worse, hence the simplification. This commit goes back to the strategy in 25f0a3fc8f6f9cf681bb5afda8e1762816c67a8b, and gets us back under the limit in my local testing. Admittedly, we don't fully understand the effects of importing or excluding importation of this package, and have seen mixed results, but this commit allows us to move forward again. Updates tailscale/corp#22125 Signed-off-by: Jordan Whited <jordan@tailscale.com>
77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build !ios
|
|
|
|
package gro
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
|
nsgro "gvisor.dev/gvisor/pkg/tcpip/stack/gro"
|
|
"tailscale.com/net/packet"
|
|
)
|
|
|
|
var (
|
|
groPool sync.Pool
|
|
)
|
|
|
|
func init() {
|
|
groPool.New = func() any {
|
|
g := &GRO{}
|
|
g.gro.Init(true)
|
|
return g
|
|
}
|
|
}
|
|
|
|
// GRO coalesces incoming packets to increase throughput. It is NOT thread-safe.
|
|
type GRO struct {
|
|
gro nsgro.GRO
|
|
maybeEnqueued bool
|
|
}
|
|
|
|
// NewGRO returns a new instance of *GRO from a sync.Pool. It can be returned to
|
|
// the pool with GRO.Flush().
|
|
func NewGRO() *GRO {
|
|
return groPool.Get().(*GRO)
|
|
}
|
|
|
|
// SetDispatcher sets the underlying stack.NetworkDispatcher where packets are
|
|
// delivered.
|
|
func (g *GRO) SetDispatcher(d stack.NetworkDispatcher) {
|
|
g.gro.Dispatcher = d
|
|
}
|
|
|
|
// Enqueue enqueues the provided packet for GRO. It may immediately deliver
|
|
// it to the underlying stack.NetworkDispatcher depending on its contents. To
|
|
// explicitly flush previously enqueued packets see Flush().
|
|
func (g *GRO) Enqueue(p *packet.Parsed) {
|
|
if g.gro.Dispatcher == nil {
|
|
return
|
|
}
|
|
pkt := RXChecksumOffload(p)
|
|
if pkt == nil {
|
|
return
|
|
}
|
|
// TODO(jwhited): g.gro.Enqueue() duplicates a lot of p.Decode().
|
|
// We may want to push stack.PacketBuffer further up as a
|
|
// replacement for packet.Parsed, or inversely push packet.Parsed
|
|
// down into refactored GRO logic.
|
|
g.gro.Enqueue(pkt)
|
|
g.maybeEnqueued = true
|
|
pkt.DecRef()
|
|
}
|
|
|
|
// Flush flushes previously enqueued packets to the underlying
|
|
// stack.NetworkDispatcher, and returns GRO to a pool for later re-use. Callers
|
|
// MUST NOT use GRO once it has been Flush()'d.
|
|
func (g *GRO) Flush() {
|
|
if g.gro.Dispatcher != nil && g.maybeEnqueued {
|
|
g.gro.Flush()
|
|
}
|
|
g.gro.Dispatcher = nil
|
|
g.maybeEnqueued = false
|
|
groPool.Put(g)
|
|
}
|