Chore: gVisor use bufferv2

This commit is contained in:
metacubex 2022-08-11 23:47:45 +08:00
parent 4ac192f520
commit 95e602bf3b

View File

@ -7,11 +7,12 @@ package iobased
import ( import (
"context" "context"
"errors" "errors"
"gvisor.dev/gvisor/pkg/bufferv2"
"io" "io"
"sync" "sync"
"github.com/Dreamacro/clash/common/pool"
"gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/buffer"
"gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/link/channel" "gvisor.dev/gvisor/pkg/tcpip/link/channel"
"gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/stack"
@ -95,31 +96,44 @@ func (e *Endpoint) dispatchLoop(cancel context.CancelFunc) {
mtu := int(e.mtu) mtu := int(e.mtu)
for { for {
data := make([]byte, mtu) data := pool.Get(mtu)
n, err := e.rw.Read(data) n, err := e.rw.Read(data)
if err != nil { if err != nil {
_ = pool.Put(data)
break break
} }
if n == 0 || n > mtu { if n == 0 || n > mtu {
_ = pool.Put(data)
continue continue
} }
if !e.IsAttached() { if !e.IsAttached() {
_ = pool.Put(data)
continue /* unattached, drop packet */ continue /* unattached, drop packet */
} }
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ var p tcpip.NetworkProtocolNumber
Data: buffer.View(data[:n]).ToVectorisedView(),
})
switch header.IPVersion(data) { switch header.IPVersion(data) {
case header.IPv4Version: case header.IPv4Version:
e.InjectInbound(header.IPv4ProtocolNumber, pkt) p = header.IPv4ProtocolNumber
case header.IPv6Version: case header.IPv6Version:
e.InjectInbound(header.IPv6ProtocolNumber, pkt) p = header.IPv6ProtocolNumber
default:
_ = pool.Put(data)
continue
} }
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
Payload: bufferv2.MakeWithData(data),
OnRelease: func() {
_ = pool.Put(data)
},
})
e.InjectInbound(p, pkt)
pkt.DecRef() pkt.DecRef()
} }
} }
@ -138,13 +152,14 @@ func (e *Endpoint) outboundLoop(ctx context.Context) {
// writePacket writes outbound packets to the io.Writer. // writePacket writes outbound packets to the io.Writer.
func (e *Endpoint) writePacket(pkt *stack.PacketBuffer) tcpip.Error { func (e *Endpoint) writePacket(pkt *stack.PacketBuffer) tcpip.Error {
defer pkt.DecRef() pktView := pkt.ToView()
size := pkt.Size() defer func() {
views := pkt.Views() pktView.Release()
pkt.DecRef()
}()
vView := buffer.NewVectorisedView(size, views) if _, err := e.rw.Write(pktView.AsSlice()); err != nil {
if _, err := e.rw.Write(vView.ToView()); err != nil {
return &tcpip.ErrInvalidEndpointState{} return &tcpip.ErrInvalidEndpointState{}
} }
return nil return nil