mirror of
https://github.com/tailscale/tailscale.git
synced 2025-06-10 01:38:35 +00:00
go.mod,wgengine/magicsock: update wireguard-go (#16148)
Our conn.Bind implementation is updated to make Send() offset-aware for future VXLAN/Geneve encapsulation support. Updates tailscale/corp#27502 Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
parent
c9a5d638e9
commit
5f35143d83
2
go.mod
2
go.mod
@ -90,7 +90,7 @@ require (
|
||||
github.com/tailscale/setec v0.0.0-20250205144240-8898a29c3fbb
|
||||
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976
|
||||
github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250304000100-91a0587fb251
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250530210235-65cd6eed7d7f
|
||||
github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e
|
||||
github.com/tc-hib/winres v0.2.1
|
||||
github.com/tcnksm/go-httpstat v0.2.0
|
||||
|
4
go.sum
4
go.sum
@ -975,8 +975,8 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:U
|
||||
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ=
|
||||
github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M=
|
||||
github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y=
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250304000100-91a0587fb251 h1:h/41LFTrwMxB9Xvvug0kRdQCU5TlV1+pAMQw0ZtDE3U=
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250304000100-91a0587fb251/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250530210235-65cd6eed7d7f h1:vg3PmQdq1BbB2V81iC1VBICQtfwbVGZ/4A/p7QKXTK0=
|
||||
github.com/tailscale/wireguard-go v0.0.0-20250530210235-65cd6eed7d7f/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
|
||||
github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek=
|
||||
github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg=
|
||||
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
|
||||
|
@ -21,5 +21,5 @@ var (
|
||||
type batchingConn interface {
|
||||
nettype.PacketConn
|
||||
ReadBatch(msgs []ipv6.Message, flags int) (n int, err error)
|
||||
WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error
|
||||
WriteBatchTo(buffs [][]byte, addr netip.AddrPort, offset int) error
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ const (
|
||||
|
||||
// coalesceMessages iterates msgs, coalescing them where possible while
|
||||
// maintaining datagram order. All msgs have their Addr field set to addr.
|
||||
func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, buffs [][]byte, msgs []ipv6.Message) int {
|
||||
func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, buffs [][]byte, msgs []ipv6.Message, offset int) int {
|
||||
var (
|
||||
base = -1 // index of msg we are currently coalescing into
|
||||
gsoSize int // segmentation size of msgs[base]
|
||||
@ -106,6 +106,7 @@ func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, buffs [][]byte,
|
||||
maxPayloadLen = maxIPv6PayloadLen
|
||||
}
|
||||
for i, buff := range buffs {
|
||||
buff = buff[offset:]
|
||||
if i > 0 {
|
||||
msgLen := len(buff)
|
||||
baseLenBefore := len(msgs[base].Buffers[0])
|
||||
@ -162,7 +163,7 @@ func (c *linuxBatchingConn) putSendBatch(batch *sendBatch) {
|
||||
c.sendBatchPool.Put(batch)
|
||||
}
|
||||
|
||||
func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error {
|
||||
func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort, offset int) error {
|
||||
batch := c.getSendBatch()
|
||||
defer c.putSendBatch(batch)
|
||||
if addr.Addr().Is6() {
|
||||
@ -181,10 +182,10 @@ func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) er
|
||||
)
|
||||
retry:
|
||||
if c.txOffload.Load() {
|
||||
n = c.coalesceMessages(batch.ua, buffs, batch.msgs)
|
||||
n = c.coalesceMessages(batch.ua, buffs, batch.msgs, offset)
|
||||
} else {
|
||||
for i := range buffs {
|
||||
batch.msgs[i].Buffers[0] = buffs[i]
|
||||
batch.msgs[i].Buffers[0] = buffs[i][offset:]
|
||||
batch.msgs[i].Addr = batch.ua
|
||||
batch.msgs[i].OOB = batch.msgs[i].OOB[:0]
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/ipv6"
|
||||
"tailscale.com/net/packet"
|
||||
)
|
||||
|
||||
func setGSOSize(control *[]byte, gsoSize uint16) {
|
||||
@ -154,6 +155,10 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
getGSOSizeFromControl: getGSOSize,
|
||||
}
|
||||
|
||||
withGeneveSpace := func(len, cap int) []byte {
|
||||
return make([]byte, len+packet.GeneveFixedHeaderLength, cap+packet.GeneveFixedHeaderLength)
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
buffs [][]byte
|
||||
@ -163,7 +168,7 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
{
|
||||
name: "one message no coalesce",
|
||||
buffs: [][]byte{
|
||||
make([]byte, 1, 1),
|
||||
withGeneveSpace(1, 1),
|
||||
},
|
||||
wantLens: []int{1},
|
||||
wantGSO: []int{0},
|
||||
@ -171,8 +176,8 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
{
|
||||
name: "two messages equal len coalesce",
|
||||
buffs: [][]byte{
|
||||
make([]byte, 1, 2),
|
||||
make([]byte, 1, 1),
|
||||
withGeneveSpace(1, 2),
|
||||
withGeneveSpace(1, 1),
|
||||
},
|
||||
wantLens: []int{2},
|
||||
wantGSO: []int{1},
|
||||
@ -180,8 +185,8 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
{
|
||||
name: "two messages unequal len coalesce",
|
||||
buffs: [][]byte{
|
||||
make([]byte, 2, 3),
|
||||
make([]byte, 1, 1),
|
||||
withGeneveSpace(2, 3),
|
||||
withGeneveSpace(1, 1),
|
||||
},
|
||||
wantLens: []int{3},
|
||||
wantGSO: []int{2},
|
||||
@ -189,9 +194,9 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
{
|
||||
name: "three messages second unequal len coalesce",
|
||||
buffs: [][]byte{
|
||||
make([]byte, 2, 3),
|
||||
make([]byte, 1, 1),
|
||||
make([]byte, 2, 2),
|
||||
withGeneveSpace(2, 3),
|
||||
withGeneveSpace(1, 1),
|
||||
withGeneveSpace(2, 2),
|
||||
},
|
||||
wantLens: []int{3, 2},
|
||||
wantGSO: []int{2, 0},
|
||||
@ -199,9 +204,9 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
{
|
||||
name: "three messages limited cap coalesce",
|
||||
buffs: [][]byte{
|
||||
make([]byte, 2, 4),
|
||||
make([]byte, 2, 2),
|
||||
make([]byte, 2, 2),
|
||||
withGeneveSpace(2, 4),
|
||||
withGeneveSpace(2, 2),
|
||||
withGeneveSpace(2, 2),
|
||||
},
|
||||
wantLens: []int{4, 2},
|
||||
wantGSO: []int{2, 0},
|
||||
@ -219,7 +224,7 @@ func Test_linuxBatchingConn_coalesceMessages(t *testing.T) {
|
||||
msgs[i].Buffers = make([][]byte, 1)
|
||||
msgs[i].OOB = make([]byte, 0, 2)
|
||||
}
|
||||
got := c.coalesceMessages(addr, tt.buffs, msgs)
|
||||
got := c.coalesceMessages(addr, tt.buffs, msgs, packet.GeneveFixedHeaderLength)
|
||||
if got != len(tt.wantLens) {
|
||||
t.Fatalf("got len %d want: %d", got, len(tt.wantLens))
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ var (
|
||||
errPingTooBig = errors.New("ping size too big")
|
||||
)
|
||||
|
||||
func (de *endpoint) send(buffs [][]byte) error {
|
||||
func (de *endpoint) send(buffs [][]byte, offset int) error {
|
||||
de.mu.Lock()
|
||||
if de.expired {
|
||||
de.mu.Unlock()
|
||||
@ -961,7 +961,7 @@ func (de *endpoint) send(buffs [][]byte) error {
|
||||
}
|
||||
var err error
|
||||
if udpAddr.IsValid() {
|
||||
_, err = de.c.sendUDPBatch(udpAddr, buffs)
|
||||
_, err = de.c.sendUDPBatch(udpAddr, buffs, offset)
|
||||
|
||||
// If the error is known to indicate that the endpoint is no longer
|
||||
// usable, clear the endpoint statistics so that the next send will
|
||||
@ -972,7 +972,7 @@ func (de *endpoint) send(buffs [][]byte) error {
|
||||
|
||||
var txBytes int
|
||||
for _, b := range buffs {
|
||||
txBytes += len(b)
|
||||
txBytes += len(b[offset:])
|
||||
}
|
||||
|
||||
switch {
|
||||
@ -993,6 +993,7 @@ func (de *endpoint) send(buffs [][]byte) error {
|
||||
allOk := true
|
||||
var txBytes int
|
||||
for _, buff := range buffs {
|
||||
buff = buff[offset:]
|
||||
const isDisco = false
|
||||
ok, _ := de.c.sendAddr(derpAddr, de.publicKey, buff, isDisco)
|
||||
txBytes += len(buff)
|
||||
|
@ -1264,8 +1264,8 @@ func (c *Conn) networkDown() bool { return !c.networkUp.Load() }
|
||||
|
||||
// Send implements conn.Bind.
|
||||
//
|
||||
// See https://pkg.go.dev/golang.zx2c4.com/wireguard/conn#Bind.Send
|
||||
func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint) (err error) {
|
||||
// See https://pkg.go.dev/github.com/tailscale/wireguard-go/conn#Bind.Send
|
||||
func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint, offset int) (err error) {
|
||||
n := int64(len(buffs))
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@ -1278,7 +1278,7 @@ func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint) (err error) {
|
||||
return errNetworkDown
|
||||
}
|
||||
if ep, ok := ep.(*endpoint); ok {
|
||||
return ep.send(buffs)
|
||||
return ep.send(buffs, offset)
|
||||
}
|
||||
// If it's not of type *endpoint, it's probably *lazyEndpoint, which means
|
||||
// we don't actually know who the peer is and we're waiting for wireguard-go
|
||||
@ -1294,7 +1294,7 @@ var errNoUDP = errors.New("no UDP available on platform")
|
||||
|
||||
var errUnsupportedConnType = errors.New("unsupported connection type")
|
||||
|
||||
func (c *Conn) sendUDPBatch(addr netip.AddrPort, buffs [][]byte) (sent bool, err error) {
|
||||
func (c *Conn) sendUDPBatch(addr netip.AddrPort, buffs [][]byte, offset int) (sent bool, err error) {
|
||||
isIPv6 := false
|
||||
switch {
|
||||
case addr.Addr().Is4():
|
||||
@ -1304,9 +1304,9 @@ func (c *Conn) sendUDPBatch(addr netip.AddrPort, buffs [][]byte) (sent bool, err
|
||||
panic("bogus sendUDPBatch addr type")
|
||||
}
|
||||
if isIPv6 {
|
||||
err = c.pconn6.WriteBatchTo(buffs, addr)
|
||||
err = c.pconn6.WriteBatchTo(buffs, addr, offset)
|
||||
} else {
|
||||
err = c.pconn4.WriteBatchTo(buffs, addr)
|
||||
err = c.pconn4.WriteBatchTo(buffs, addr, offset)
|
||||
}
|
||||
if err != nil {
|
||||
var errGSO neterror.ErrUDPGSODisabled
|
||||
|
@ -3147,7 +3147,7 @@ func TestNetworkDownSendErrors(t *testing.T) {
|
||||
defer conn.Close()
|
||||
|
||||
conn.SetNetworkUp(false)
|
||||
if err := conn.Send([][]byte{{00}}, &lazyEndpoint{}); err == nil {
|
||||
if err := conn.Send([][]byte{{00}}, &lazyEndpoint{}, 0); err == nil {
|
||||
t.Error("expected error, got nil")
|
||||
}
|
||||
resp := httptest.NewRecorder()
|
||||
|
@ -71,12 +71,13 @@ func (c *RebindingUDPConn) ReadFromUDPAddrPort(b []byte) (int, netip.AddrPort, e
|
||||
}
|
||||
|
||||
// WriteBatchTo writes buffs to addr.
|
||||
func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error {
|
||||
func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort, offset int) error {
|
||||
for {
|
||||
pconn := *c.pconnAtomic.Load()
|
||||
b, ok := pconn.(batchingConn)
|
||||
if !ok {
|
||||
for _, buf := range buffs {
|
||||
buf = buf[offset:]
|
||||
_, err := c.writeToUDPAddrPortWithInitPconn(pconn, buf, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -84,7 +85,7 @@ func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := b.WriteBatchTo(buffs, addr)
|
||||
err := b.WriteBatchTo(buffs, addr, offset)
|
||||
if err != nil {
|
||||
if pconn != c.currentConn() {
|
||||
continue
|
||||
|
@ -242,9 +242,9 @@ type noopBind struct{}
|
||||
func (noopBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {
|
||||
return nil, 1, nil
|
||||
}
|
||||
func (noopBind) Close() error { return nil }
|
||||
func (noopBind) SetMark(mark uint32) error { return nil }
|
||||
func (noopBind) Send(b [][]byte, ep conn.Endpoint) error { return nil }
|
||||
func (noopBind) Close() error { return nil }
|
||||
func (noopBind) SetMark(mark uint32) error { return nil }
|
||||
func (noopBind) Send(b [][]byte, ep conn.Endpoint, offset int) error { return nil }
|
||||
func (noopBind) ParseEndpoint(s string) (conn.Endpoint, error) {
|
||||
return dummyEndpoint(s), nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user