Improve darwin forwarding

This commit is contained in:
世界 2026-07-08 19:38:44 +08:00
parent dcfbe83ca6
commit b0188bc3f1
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 116 additions and 56 deletions

View file

@ -6,6 +6,7 @@ import (
"net"
"net/netip"
"os"
"sync"
"syscall"
"unsafe"
@ -36,6 +37,8 @@ type NativeTun struct {
msgHdrsOutput []rawfile.MsgHdrX
buffers []*buf.Buffer
stopFd stopfd.StopFD
readPoller *rawfile.Poller
writeAccess sync.Mutex
options Options
inet4Address [4]byte
inet6Address [16]byte
@ -132,6 +135,7 @@ func New(options Options) (Tun, error) {
stopFd: common.Must1(stopfd.New()),
sendMsgX: options.EXP_SendMsgX,
}
nativeTun.readPoller = common.Must1(rawfile.NewPoller(nativeTun.stopFd.ReadFD, tunFd))
for i := range batchSize {
nativeTun.iovecs[i] = newIovecBuffer(int(options.MTU))
nativeTun.iovecsOutput[i] = newIovecBuffer(int(options.MTU))
@ -155,15 +159,26 @@ func (t *NativeTun) Start() error {
func (t *NativeTun) Close() error {
if t.options.EXP_ExternalConfiguration {
return t.tunFile.Close()
t.stopFd.Stop()
err := t.tunFile.Close()
t.closePollers()
t.stopFd.Close()
return err
}
defer flushDNSCache()
t.stopFd.Stop()
err := E.Errors(t.unsetRoutes(), t.tunFile.Close())
t.closePollers()
t.stopFd.Close()
return err
}
func (t *NativeTun) closePollers() {
if t.readPoller != nil {
_ = t.readPoller.Close()
}
}
func (t *NativeTun) Read(p []byte) (n int, err error) {
return t.tunFile.Read(p)
}
@ -350,7 +365,7 @@ func (t *NativeTun) BatchRead() ([]*buf.Buffer, error) {
t.msgHdrs[i].Msg.Iov = &iovecs[0]
t.msgHdrs[i].Msg.Iovlen = 2
}
n, errno := rawfile.BlockingRecvMMsgUntilStopped(t.stopFd.ReadFD, t.tunFd, t.msgHdrs)
n, errno := rawfile.BlockingRecvMMsgUntilStopped(t.readPoller, t.tunFd, t.msgHdrs)
if errno != 0 {
for k := range n {
t.iovecs[k].buffer.Release()
@ -377,6 +392,23 @@ func (t *NativeTun) BatchRead() ([]*buf.Buffer, error) {
}
func (t *NativeTun) BatchWrite(buffers []*buf.Buffer) error {
t.writeAccess.Lock()
defer t.writeAccess.Unlock()
for len(buffers) > 0 {
chunk := buffers
if len(chunk) > t.batchSize {
chunk = chunk[:t.batchSize]
}
buffers = buffers[len(chunk):]
err := t.batchWriteChunk(chunk)
if err != nil {
return err
}
}
return nil
}
func (t *NativeTun) batchWriteChunk(buffers []*buf.Buffer) error {
if !t.sendMsgX {
for i, buffer := range buffers {
t.iovecsOutput[i].nextIovecsOutput(buffer)