mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-03-14 14:09:22 +00:00
chore: adapt new ReadWait interfaces
This commit is contained in:
@@ -138,41 +138,36 @@ func (h *ListenerHandler) NewConnection(ctx context.Context, conn net.Conn, meta
|
||||
}
|
||||
|
||||
func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.PacketConn, metadata M.Metadata) error {
|
||||
if deadline.NeedAdditionalReadDeadline(conn) {
|
||||
conn = deadline.NewFallbackPacketConn(bufio.NewNetPacketConn(conn)) // conn from sing should check NeedAdditionalReadDeadline
|
||||
}
|
||||
defer func() { _ = conn.Close() }()
|
||||
mutex := sync.Mutex{}
|
||||
conn2 := conn // a new interface to set nil in defer
|
||||
conn2 := bufio.NewNetPacketConn(conn) // a new interface to set nil in defer
|
||||
defer func() {
|
||||
mutex.Lock() // this goroutine must exit after all conn.WritePacket() is not running
|
||||
defer mutex.Unlock()
|
||||
conn2 = nil
|
||||
}()
|
||||
var buff *buf.Buffer
|
||||
newBuffer := func() *buf.Buffer {
|
||||
buff = buf.NewPacket() // do not use stack buffer
|
||||
return buff
|
||||
}
|
||||
rwOptions := network.ReadWaitOptions{}
|
||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||
if isReadWaiter {
|
||||
readWaiter.InitializeReadWaiter(newBuffer)
|
||||
readWaiter.InitializeReadWaiter(rwOptions)
|
||||
}
|
||||
for {
|
||||
var (
|
||||
buff *buf.Buffer
|
||||
dest M.Socksaddr
|
||||
err error
|
||||
)
|
||||
buff = nil // clear last loop status, avoid repeat release
|
||||
if isReadWaiter {
|
||||
dest, err = readWaiter.WaitReadPacket()
|
||||
buff, dest, err = readWaiter.WaitReadPacket()
|
||||
} else {
|
||||
dest, err = conn.ReadPacket(newBuffer())
|
||||
buff = rwOptions.NewPacketBuffer()
|
||||
dest, err = conn.ReadPacket(buff)
|
||||
if buff != nil {
|
||||
rwOptions.PostReturn(buff)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if buff != nil {
|
||||
buff.Release()
|
||||
}
|
||||
buff.Release()
|
||||
if ShouldIgnorePacketError(err) {
|
||||
break
|
||||
}
|
||||
@@ -212,7 +207,7 @@ func ShouldIgnorePacketError(err error) bool {
|
||||
}
|
||||
|
||||
type packet struct {
|
||||
conn *network.PacketConn
|
||||
conn *network.NetPacketConn
|
||||
mutex *sync.Mutex
|
||||
rAddr net.Addr
|
||||
lAddr net.Addr
|
||||
@@ -238,18 +233,7 @@ func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
buff := buf.NewPacket()
|
||||
defer buff.Release()
|
||||
n, err = buff.Write(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = conn.WritePacket(buff, M.SocksaddrFromNet(addr))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
return conn.WriteTo(b, addr)
|
||||
}
|
||||
|
||||
// LocalAddr returns the source IP/Port of UDP Packet
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
@@ -96,30 +97,33 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi
|
||||
|
||||
go func() {
|
||||
conn := bufio.NewPacketConn(ul)
|
||||
var buff *buf.Buffer
|
||||
newBuffer := func() *buf.Buffer {
|
||||
buff = buf.NewPacket() // do not use stack buffer
|
||||
return buff
|
||||
rwOptions := network.ReadWaitOptions{
|
||||
FrontHeadroom: network.CalculateFrontHeadroom(sl.service),
|
||||
RearHeadroom: network.CalculateRearHeadroom(sl.service),
|
||||
MTU: network.CalculateMTU(conn, sl.service),
|
||||
}
|
||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||
if isReadWaiter {
|
||||
readWaiter.InitializeReadWaiter(newBuffer)
|
||||
readWaiter.InitializeReadWaiter(rwOptions)
|
||||
}
|
||||
for {
|
||||
var (
|
||||
buff *buf.Buffer
|
||||
dest M.Socksaddr
|
||||
err error
|
||||
)
|
||||
buff = nil // clear last loop status, avoid repeat release
|
||||
if isReadWaiter {
|
||||
dest, err = readWaiter.WaitReadPacket()
|
||||
buff, dest, err = readWaiter.WaitReadPacket()
|
||||
} else {
|
||||
dest, err = conn.ReadPacket(newBuffer())
|
||||
buff = rwOptions.NewPacketBuffer()
|
||||
dest, err = conn.ReadPacket(buff)
|
||||
if buff != nil {
|
||||
rwOptions.PostReturn(buff)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if buff != nil {
|
||||
buff.Release()
|
||||
}
|
||||
buff.Release()
|
||||
if sl.closed {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -109,29 +109,29 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||
defer mutex.Unlock()
|
||||
conn2 = nil
|
||||
}()
|
||||
|
||||
var buff *buf.Buffer
|
||||
newBuffer := func() *buf.Buffer {
|
||||
// safe size which is 1232 from https://dnsflagday.net/2020/.
|
||||
// so 2048 is enough
|
||||
buff = buf.NewSize(2 * 1024)
|
||||
return buff
|
||||
rwOptions := network.ReadWaitOptions{
|
||||
MTU: 2 * 1024, // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough
|
||||
}
|
||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||
if isReadWaiter {
|
||||
readWaiter.InitializeReadWaiter(newBuffer)
|
||||
readWaiter.InitializeReadWaiter(rwOptions)
|
||||
}
|
||||
for {
|
||||
var (
|
||||
buff *buf.Buffer
|
||||
dest M.Socksaddr
|
||||
err error
|
||||
)
|
||||
_ = conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout))
|
||||
buff = nil // clear last loop status, avoid repeat release
|
||||
if isReadWaiter {
|
||||
dest, err = readWaiter.WaitReadPacket()
|
||||
buff, dest, err = readWaiter.WaitReadPacket()
|
||||
} else {
|
||||
dest, err = conn.ReadPacket(newBuffer())
|
||||
buff = rwOptions.NewPacketBuffer()
|
||||
dest, err = conn.ReadPacket(buff)
|
||||
if buff != nil {
|
||||
rwOptions.PostReturn(buff)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if buff != nil {
|
||||
@@ -142,7 +142,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||
}
|
||||
return err
|
||||
}
|
||||
go func(buff *buf.Buffer) {
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
||||
defer cancel()
|
||||
inData := buff.Bytes()
|
||||
@@ -167,7 +167,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(buff) // catch buff at goroutine create, avoid next loop change buff
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user