mirror of
https://github.com/SagerNet/sing-tun.git
synced 2025-12-24 13:18:21 +08:00
Allocate small iovec arrays on the stack
This commit is contained in:
@@ -25,21 +25,20 @@ var _ DarwinTUN = (*NativeTun)(nil)
|
||||
const PacketOffset = 4
|
||||
|
||||
type NativeTun struct {
|
||||
tunFd int
|
||||
tunFile *os.File
|
||||
batchSize int
|
||||
iovecs []iovecBuffer
|
||||
iovecsOutput []iovecBuffer
|
||||
iovecsOutputDefault []unix.Iovec
|
||||
msgHdrs []rawfile.MsgHdrX
|
||||
msgHdrsOutput []rawfile.MsgHdrX
|
||||
buffers []*buf.Buffer
|
||||
stopFd stopfd.StopFD
|
||||
options Options
|
||||
inet4Address [4]byte
|
||||
inet6Address [16]byte
|
||||
routeSet bool
|
||||
writeMsgX bool
|
||||
tunFd int
|
||||
tunFile *os.File
|
||||
batchSize int
|
||||
iovecs []iovecBuffer
|
||||
iovecsOutput []iovecBuffer
|
||||
msgHdrs []rawfile.MsgHdrX
|
||||
msgHdrsOutput []rawfile.MsgHdrX
|
||||
buffers []*buf.Buffer
|
||||
stopFd stopfd.StopFD
|
||||
options Options
|
||||
inet4Address [4]byte
|
||||
inet6Address [16]byte
|
||||
routeSet bool
|
||||
writeMsgX bool
|
||||
}
|
||||
|
||||
type iovecBuffer struct {
|
||||
|
||||
@@ -15,14 +15,24 @@ import (
|
||||
var _ GVisorTun = (*NativeTun)(nil)
|
||||
|
||||
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||
iovecs := t.iovecsOutputDefault
|
||||
views := pkt.AsSlices()
|
||||
numIovecs := len(views)
|
||||
numIovecs++ // for packetHeaderVec4/6
|
||||
|
||||
// Allocate small iovec arrays on the stack.
|
||||
var iovecsArr [8]unix.Iovec
|
||||
iovecs := iovecsArr[:0]
|
||||
if numIovecs > len(iovecsArr) {
|
||||
iovecs = make([]unix.Iovec, 0, numIovecs)
|
||||
}
|
||||
|
||||
if pkt.NetworkProtocolNumber == header.IPv4ProtocolNumber {
|
||||
iovecs = append(iovecs, packetHeaderVec4)
|
||||
} else {
|
||||
iovecs = append(iovecs, packetHeaderVec6)
|
||||
}
|
||||
var dataLen int
|
||||
for _, packetSlice := range pkt.AsSlices() {
|
||||
for _, packetSlice := range views {
|
||||
dataLen += len(packetSlice)
|
||||
iovec := unix.Iovec{
|
||||
Base: &packetSlice[0],
|
||||
@@ -30,9 +40,6 @@ func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||
iovec.SetLen(len(packetSlice))
|
||||
iovecs = append(iovecs, iovec)
|
||||
}
|
||||
if cap(iovecs) > cap(t.iovecsOutputDefault) {
|
||||
t.iovecsOutputDefault = iovecs[:0]
|
||||
}
|
||||
errno := rawfile.NonBlockingWriteIovec(t.tunFd, iovecs)
|
||||
if errno == 0 {
|
||||
return dataLen, nil
|
||||
|
||||
27
tun_linux.go
27
tun_linux.go
@@ -25,20 +25,19 @@ import (
|
||||
var _ LinuxTUN = (*NativeTun)(nil)
|
||||
|
||||
type NativeTun struct {
|
||||
tunFd int
|
||||
tunFile *os.File
|
||||
iovecsOutputDefault []unix.Iovec
|
||||
interfaceCallback *list.Element[DefaultInterfaceUpdateCallback]
|
||||
options Options
|
||||
ruleIndex6 []int
|
||||
gsoEnabled bool
|
||||
gsoBuffer []byte
|
||||
gsoToWrite []int
|
||||
gsoReadAccess sync.Mutex
|
||||
tcpGROAccess sync.Mutex
|
||||
tcp4GROTable *tcpGROTable
|
||||
tcp6GROTable *tcpGROTable
|
||||
txChecksumOffload bool
|
||||
tunFd int
|
||||
tunFile *os.File
|
||||
interfaceCallback *list.Element[DefaultInterfaceUpdateCallback]
|
||||
options Options
|
||||
ruleIndex6 []int
|
||||
gsoEnabled bool
|
||||
gsoBuffer []byte
|
||||
gsoToWrite []int
|
||||
gsoReadAccess sync.Mutex
|
||||
tcpGROAccess sync.Mutex
|
||||
tcp4GROTable *tcpGROTable
|
||||
tcp6GROTable *tcpGROTable
|
||||
txChecksumOffload bool
|
||||
}
|
||||
|
||||
func New(options Options) (Tun, error) {
|
||||
|
||||
@@ -17,9 +17,18 @@ func init() {
|
||||
var _ GVisorTun = (*NativeTun)(nil)
|
||||
|
||||
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||
iovecs := t.iovecsOutputDefault
|
||||
views := pkt.AsSlices()
|
||||
numIovecs := len(views)
|
||||
|
||||
// Allocate small iovec arrays on the stack.
|
||||
var iovecsArr [8]unix.Iovec
|
||||
iovecs := iovecsArr[:0]
|
||||
if numIovecs > len(iovecsArr) {
|
||||
iovecs = make([]unix.Iovec, 0, numIovecs)
|
||||
}
|
||||
|
||||
var dataLen int
|
||||
for _, packetSlice := range pkt.AsSlices() {
|
||||
for _, packetSlice := range views {
|
||||
dataLen += len(packetSlice)
|
||||
iovec := unix.Iovec{
|
||||
Base: &packetSlice[0],
|
||||
@@ -27,9 +36,6 @@ func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
|
||||
iovec.SetLen(len(packetSlice))
|
||||
iovecs = append(iovecs, iovec)
|
||||
}
|
||||
if cap(iovecs) > cap(t.iovecsOutputDefault) {
|
||||
t.iovecsOutputDefault = iovecs[:0]
|
||||
}
|
||||
errno := rawfile.NonBlockingWriteIovec(t.tunFd, iovecs)
|
||||
if errno == 0 {
|
||||
return dataLen, nil
|
||||
|
||||
Reference in New Issue
Block a user