chore: adapt new ReadWait interfaces
This commit is contained in:
parent
c5d1db7905
commit
cbec564af9
12 changed files with 249 additions and 114 deletions
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
restlsC "github.com/3andne/restls-client-go"
|
restlsC "github.com/3andne/restls-client-go"
|
||||||
shadowsocks "github.com/metacubex/sing-shadowsocks2"
|
shadowsocks "github.com/metacubex/sing-shadowsocks2"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
"github.com/sagernet/sing/common/uot"
|
"github.com/sagernet/sing/common/uot"
|
||||||
)
|
)
|
||||||
|
@ -187,7 +188,7 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pc = ss.method.DialPacketConn(N.NewBindPacketConn(pc, addr))
|
pc = ss.method.DialPacketConn(bufio.NewBindPacketConn(pc, addr))
|
||||||
return newPacketConn(pc, ss), nil
|
return newPacketConn(pc, ss), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
149
common/net/deadline/conn.go
Normal file
149
common/net/deadline/conn.go
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
package deadline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/atomic"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common/buf"
|
||||||
|
"github.com/sagernet/sing/common/bufio"
|
||||||
|
"github.com/sagernet/sing/common/network"
|
||||||
|
)
|
||||||
|
|
||||||
|
type connReadResult struct {
|
||||||
|
buffer []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Conn struct {
|
||||||
|
network.ExtendedConn
|
||||||
|
deadline atomic.TypedValue[time.Time]
|
||||||
|
pipeDeadline pipeDeadline
|
||||||
|
disablePipe atomic.Bool
|
||||||
|
inRead atomic.Bool
|
||||||
|
resultCh chan *connReadResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConn(conn net.Conn) *Conn {
|
||||||
|
c := &Conn{
|
||||||
|
ExtendedConn: bufio.NewExtendedConn(conn),
|
||||||
|
pipeDeadline: makePipeDeadline(),
|
||||||
|
resultCh: make(chan *connReadResult, 1),
|
||||||
|
}
|
||||||
|
c.resultCh <- nil
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Read(p []byte) (n int, err error) {
|
||||||
|
select {
|
||||||
|
case result := <-c.resultCh:
|
||||||
|
if result != nil {
|
||||||
|
n = copy(p, result.buffer)
|
||||||
|
err = result.err
|
||||||
|
if n >= len(result.buffer) {
|
||||||
|
c.resultCh <- nil // finish cache read
|
||||||
|
} else {
|
||||||
|
result.buffer = result.buffer[n:]
|
||||||
|
c.resultCh <- result // push back for next call
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
c.resultCh <- nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case <-c.pipeDeadline.wait():
|
||||||
|
return 0, os.ErrDeadlineExceeded
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.disablePipe.Load() {
|
||||||
|
return c.ExtendedConn.Read(p)
|
||||||
|
} else if c.deadline.Load().IsZero() {
|
||||||
|
c.inRead.Store(true)
|
||||||
|
defer c.inRead.Store(false)
|
||||||
|
return c.ExtendedConn.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
<-c.resultCh
|
||||||
|
go c.pipeRead(len(p))
|
||||||
|
|
||||||
|
return c.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) pipeRead(size int) {
|
||||||
|
buffer := make([]byte, size)
|
||||||
|
n, err := c.ExtendedConn.Read(buffer)
|
||||||
|
buffer = buffer[:n]
|
||||||
|
c.resultCh <- &connReadResult{
|
||||||
|
buffer: buffer,
|
||||||
|
err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) ReadBuffer(buffer *buf.Buffer) (err error) {
|
||||||
|
select {
|
||||||
|
case result := <-c.resultCh:
|
||||||
|
if result != nil {
|
||||||
|
n, _ := buffer.Write(result.buffer)
|
||||||
|
err = result.err
|
||||||
|
|
||||||
|
if n >= len(result.buffer) {
|
||||||
|
c.resultCh <- nil // finish cache read
|
||||||
|
} else {
|
||||||
|
result.buffer = result.buffer[n:]
|
||||||
|
c.resultCh <- result // push back for next call
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
c.resultCh <- nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case <-c.pipeDeadline.wait():
|
||||||
|
return os.ErrDeadlineExceeded
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.disablePipe.Load() {
|
||||||
|
return c.ExtendedConn.ReadBuffer(buffer)
|
||||||
|
} else if c.deadline.Load().IsZero() {
|
||||||
|
c.inRead.Store(true)
|
||||||
|
defer c.inRead.Store(false)
|
||||||
|
return c.ExtendedConn.ReadBuffer(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
<-c.resultCh
|
||||||
|
go c.pipeRead(buffer.FreeLen())
|
||||||
|
|
||||||
|
return c.ReadBuffer(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) SetReadDeadline(t time.Time) error {
|
||||||
|
if c.disablePipe.Load() {
|
||||||
|
return c.ExtendedConn.SetReadDeadline(t)
|
||||||
|
} else if c.inRead.Load() {
|
||||||
|
c.disablePipe.Store(true)
|
||||||
|
return c.ExtendedConn.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
c.deadline.Store(t)
|
||||||
|
c.pipeDeadline.set(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) ReaderReplaceable() bool {
|
||||||
|
select {
|
||||||
|
case result := <-c.resultCh:
|
||||||
|
c.resultCh <- result
|
||||||
|
if result != nil {
|
||||||
|
return false // cache reading
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false // pipe reading
|
||||||
|
}
|
||||||
|
return c.disablePipe.Load() || c.deadline.Load().IsZero()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Upstream() any {
|
||||||
|
return c.ExtendedConn
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/common/net/packet"
|
"github.com/metacubex/mihomo/common/net/packet"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
@ -121,17 +122,18 @@ type singPacketReadWaiter struct {
|
||||||
|
|
||||||
type singWaitReadResult singReadResult
|
type singWaitReadResult singReadResult
|
||||||
|
|
||||||
func (c *singPacketReadWaiter) InitializeReadWaiter(newBuffer func() *buf.Buffer) {
|
func (c *singPacketReadWaiter) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
|
||||||
c.packetReadWaiter.InitializeReadWaiter(newBuffer)
|
return c.packetReadWaiter.InitializeReadWaiter(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *singPacketReadWaiter) WaitReadPacket() (destination M.Socksaddr, err error) {
|
func (c *singPacketReadWaiter) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
|
||||||
FOR:
|
FOR:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case result := <-c.netPacketConn.resultCh:
|
case result := <-c.netPacketConn.resultCh:
|
||||||
if result != nil {
|
if result != nil {
|
||||||
if result, ok := result.(*singWaitReadResult); ok {
|
if result, ok := result.(*singWaitReadResult); ok {
|
||||||
|
buffer = result.buffer
|
||||||
destination = result.destination
|
destination = result.destination
|
||||||
err = result.err
|
err = result.err
|
||||||
c.netPacketConn.resultCh <- nil // finish cache read
|
c.netPacketConn.resultCh <- nil // finish cache read
|
||||||
|
@ -145,7 +147,7 @@ FOR:
|
||||||
break FOR
|
break FOR
|
||||||
}
|
}
|
||||||
case <-c.netPacketConn.pipeDeadline.wait():
|
case <-c.netPacketConn.pipeDeadline.wait():
|
||||||
return M.Socksaddr{}, os.ErrDeadlineExceeded
|
return nil, M.Socksaddr{}, os.ErrDeadlineExceeded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +156,7 @@ FOR:
|
||||||
} else if c.netPacketConn.deadline.Load().IsZero() {
|
} else if c.netPacketConn.deadline.Load().IsZero() {
|
||||||
c.netPacketConn.inRead.Store(true)
|
c.netPacketConn.inRead.Store(true)
|
||||||
defer c.netPacketConn.inRead.Store(false)
|
defer c.netPacketConn.inRead.Store(false)
|
||||||
destination, err = c.packetReadWaiter.WaitReadPacket()
|
return c.packetReadWaiter.WaitReadPacket()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<-c.netPacketConn.resultCh
|
<-c.netPacketConn.resultCh
|
||||||
|
@ -165,8 +166,9 @@ FOR:
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *singPacketReadWaiter) pipeWaitReadPacket() {
|
func (c *singPacketReadWaiter) pipeWaitReadPacket() {
|
||||||
destination, err := c.packetReadWaiter.WaitReadPacket()
|
buffer, destination, err := c.packetReadWaiter.WaitReadPacket()
|
||||||
result := &singWaitReadResult{}
|
result := &singWaitReadResult{}
|
||||||
|
result.buffer = buffer
|
||||||
result.destination = destination
|
result.destination = destination
|
||||||
result.err = err
|
result.err = err
|
||||||
c.netPacketConn.resultCh <- result
|
c.netPacketConn.resultCh <- result
|
||||||
|
|
|
@ -24,16 +24,16 @@ type enhanceSingPacketConn struct {
|
||||||
func (c *enhanceSingPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
|
func (c *enhanceSingPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
|
||||||
var buff *buf.Buffer
|
var buff *buf.Buffer
|
||||||
var dest M.Socksaddr
|
var dest M.Socksaddr
|
||||||
newBuffer := func() *buf.Buffer {
|
rwOptions := N.ReadWaitOptions{}
|
||||||
buff = buf.NewPacket() // do not use stack buffer
|
|
||||||
return buff
|
|
||||||
}
|
|
||||||
if c.packetReadWaiter != nil {
|
if c.packetReadWaiter != nil {
|
||||||
c.packetReadWaiter.InitializeReadWaiter(newBuffer)
|
c.packetReadWaiter.InitializeReadWaiter(rwOptions)
|
||||||
defer c.packetReadWaiter.InitializeReadWaiter(nil)
|
buff, dest, err = c.packetReadWaiter.WaitReadPacket()
|
||||||
dest, err = c.packetReadWaiter.WaitReadPacket()
|
|
||||||
} else {
|
} else {
|
||||||
dest, err = c.SingPacketConn.ReadPacket(newBuffer())
|
buff = rwOptions.NewPacketBuffer()
|
||||||
|
dest, err = c.SingPacketConn.ReadPacket(buff)
|
||||||
|
if buff != nil {
|
||||||
|
rwOptions.PostReturn(buff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if dest.IsFqdn() {
|
if dest.IsFqdn() {
|
||||||
addr = dest
|
addr = dest
|
||||||
|
@ -41,9 +41,7 @@ func (c *enhanceSingPacketConn) WaitReadFrom() (data []byte, put func(), addr ne
|
||||||
addr = dest.UDPAddr()
|
addr = dest.UDPAddr()
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if buff != nil {
|
|
||||||
buff.Release()
|
buff.Release()
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if buff == nil {
|
if buff == nil {
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/net/deadline"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
"github.com/sagernet/sing/common/bufio/deadline"
|
|
||||||
"github.com/sagernet/sing/common/network"
|
"github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,8 +20,10 @@ type ExtendedConn = network.ExtendedConn
|
||||||
type ExtendedWriter = network.ExtendedWriter
|
type ExtendedWriter = network.ExtendedWriter
|
||||||
type ExtendedReader = network.ExtendedReader
|
type ExtendedReader = network.ExtendedReader
|
||||||
|
|
||||||
|
var WriteBuffer = bufio.WriteBuffer
|
||||||
|
|
||||||
func NewDeadlineConn(conn net.Conn) ExtendedConn {
|
func NewDeadlineConn(conn net.Conn) ExtendedConn {
|
||||||
return deadline.NewFallbackConn(conn)
|
return deadline.NewConn(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NeedHandshake(conn any) bool {
|
func NeedHandshake(conn any) bool {
|
||||||
|
|
22
go.mod
22
go.mod
|
@ -21,12 +21,12 @@ require (
|
||||||
github.com/mdlayher/netlink v1.7.2
|
github.com/mdlayher/netlink v1.7.2
|
||||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
|
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
|
||||||
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394
|
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394
|
||||||
github.com/metacubex/sing-quic v0.0.0-20231130141855-0022295e524b
|
github.com/metacubex/sing-quic v0.0.0-20231207122758-cc17b154daa8
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.5
|
github.com/metacubex/sing-shadowsocks v0.2.5
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.1.4
|
github.com/metacubex/sing-shadowsocks2 v0.1.5-0.20231207115048-3abf19378f0d
|
||||||
github.com/metacubex/sing-tun v0.1.15-0.20231103033938-170591e8d5bd
|
github.com/metacubex/sing-tun v0.1.15-0.20231207115657-1aa1d8cadd9a
|
||||||
github.com/metacubex/sing-vmess v0.1.9-0.20230921005247-a0488d7dac74
|
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20231001110902-321836559170
|
github.com/metacubex/sing-wireguard v0.0.0-20231207123053-1367f0b8f173
|
||||||
github.com/miekg/dns v1.1.57
|
github.com/miekg/dns v1.1.57
|
||||||
github.com/mroth/weightedrand/v2 v2.1.0
|
github.com/mroth/weightedrand/v2 v2.1.0
|
||||||
github.com/openacid/low v0.1.21
|
github.com/openacid/low v0.1.21
|
||||||
|
@ -34,8 +34,8 @@ require (
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.0.2
|
github.com/puzpuzpuz/xsync/v3 v3.0.2
|
||||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
|
||||||
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c
|
github.com/sagernet/sing v0.2.19-0.20231207034108-445cd4f41e3f
|
||||||
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07
|
github.com/sagernet/sing-mux v0.1.6-0.20231207143704-9f6c20fb5266
|
||||||
github.com/sagernet/sing-shadowtls v0.1.4
|
github.com/sagernet/sing-shadowtls v0.1.4
|
||||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
|
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
|
||||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
|
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
|
||||||
|
@ -49,7 +49,7 @@ require (
|
||||||
go.uber.org/automaxprocs v1.5.3
|
go.uber.org/automaxprocs v1.5.3
|
||||||
golang.org/x/crypto v0.16.0
|
golang.org/x/crypto v0.16.0
|
||||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
||||||
golang.org/x/net v0.18.0
|
golang.org/x/net v0.19.0
|
||||||
golang.org/x/sync v0.5.0
|
golang.org/x/sync v0.5.0
|
||||||
golang.org/x/sys v0.15.0
|
golang.org/x/sys v0.15.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.31.0
|
||||||
|
@ -105,11 +105,11 @@ require (
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
|
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
|
||||||
go.uber.org/mock v0.3.0 // indirect
|
go.uber.org/mock v0.3.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.14.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.4.0 // indirect
|
||||||
golang.org/x/tools v0.15.0 // indirect
|
golang.org/x/tools v0.15.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20231118023733-957d84f17d2c
|
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20231207144554-52b6f9095d02
|
||||||
|
|
41
go.sum
41
go.sum
|
@ -107,20 +107,20 @@ github.com/metacubex/gvisor v0.0.0-20231206145044-b6960a648d8b h1:xJHepHYyQ7NOpU
|
||||||
github.com/metacubex/gvisor v0.0.0-20231206145044-b6960a648d8b/go.mod h1:rhBU9tD5ktoGPBtXUquhWuGJ4u+8ZZzBMi2cAdv9q8Y=
|
github.com/metacubex/gvisor v0.0.0-20231206145044-b6960a648d8b/go.mod h1:rhBU9tD5ktoGPBtXUquhWuGJ4u+8ZZzBMi2cAdv9q8Y=
|
||||||
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394 h1:dIT+KB2hknBCrwVAXPeY9tpzzkOZP5m40yqUteRT6/Y=
|
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394 h1:dIT+KB2hknBCrwVAXPeY9tpzzkOZP5m40yqUteRT6/Y=
|
||||||
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394/go.mod h1:F/t8VnA47xoia8ABlNA4InkZjssvFJ5p6E6jKdbkgAs=
|
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394/go.mod h1:F/t8VnA47xoia8ABlNA4InkZjssvFJ5p6E6jKdbkgAs=
|
||||||
github.com/metacubex/sing v0.0.0-20231118023733-957d84f17d2c h1:SZwaf42NVCIDaHw5X2HOnNcEiK9ao6yO+N4zYyKfXe8=
|
github.com/metacubex/sing v0.0.0-20231207144554-52b6f9095d02 h1:gB2vNdDTaOfko9z9WJXQkNn+rbdSEMTM7s61V4TaKhI=
|
||||||
github.com/metacubex/sing v0.0.0-20231118023733-957d84f17d2c/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
github.com/metacubex/sing v0.0.0-20231207144554-52b6f9095d02/go.mod h1:Ce5LNojQOgOiWhiD8pPD6E9H7e2KgtOe3Zxx4Ou5u80=
|
||||||
github.com/metacubex/sing-quic v0.0.0-20231130141855-0022295e524b h1:7XXoEePvxfkQN9b2wB8UXU3uzb9uL8syEFF7A9VAKKQ=
|
github.com/metacubex/sing-quic v0.0.0-20231207122758-cc17b154daa8 h1:gmZb7M2Z4y6BQSWljJORGVGZlKaYWEpoIJlVMg9naEY=
|
||||||
github.com/metacubex/sing-quic v0.0.0-20231130141855-0022295e524b/go.mod h1:Gu5/zqZDd5G1AUtoV2yjAPWOEy7zwbU2DBUjdxJh0Kw=
|
github.com/metacubex/sing-quic v0.0.0-20231207122758-cc17b154daa8/go.mod h1:E1e1Uu6YaJddD+c0DtJlSOkfMI0NLdOVhM60KAlcssY=
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.5 h1:O2RRSHlKGEpAVG/OHJQxyHqDy8uvvdCW/oW2TDBOIhc=
|
github.com/metacubex/sing-shadowsocks v0.2.5 h1:O2RRSHlKGEpAVG/OHJQxyHqDy8uvvdCW/oW2TDBOIhc=
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.5/go.mod h1:Xz2uW9BEYGEoA8B4XEpoxt7ERHClFCwsMAvWaruoyMo=
|
github.com/metacubex/sing-shadowsocks v0.2.5/go.mod h1:Xz2uW9BEYGEoA8B4XEpoxt7ERHClFCwsMAvWaruoyMo=
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.1.4 h1:OOCf8lgsVcpTOJUeaFAMzyKVebaQOBnKirDdUdBoKIE=
|
github.com/metacubex/sing-shadowsocks2 v0.1.5-0.20231207115048-3abf19378f0d h1:hMs2isnO6198XaBwqbPff5bYt3uz1498osDC0sVe/dA=
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.1.4/go.mod h1:Qz028sLfdY3qxGRm9FDI+IM2Ae3ty2wR7HIzD/56h/k=
|
github.com/metacubex/sing-shadowsocks2 v0.1.5-0.20231207115048-3abf19378f0d/go.mod h1:Y7Dm/rJpieN2xkU/pnxJCQxqmFptUCYiGd8oJhiHd0w=
|
||||||
github.com/metacubex/sing-tun v0.1.15-0.20231103033938-170591e8d5bd h1:k0+92eARqyTAovGhg2AxdsMWHjUsdiGCnR5NuXF3CQY=
|
github.com/metacubex/sing-tun v0.1.15-0.20231207115657-1aa1d8cadd9a h1:uVDQ9vdp9MXzaX0GUf5sTqCYkf3P3v+vNcddR84F7F4=
|
||||||
github.com/metacubex/sing-tun v0.1.15-0.20231103033938-170591e8d5bd/go.mod h1:Q7zmpJ+qOvMMXyUoYlxGQuWkqALUpXzFSSqO+KLPyzA=
|
github.com/metacubex/sing-tun v0.1.15-0.20231207115657-1aa1d8cadd9a/go.mod h1:c/FrkpUp2emectVh3getHn5BxvvaEiNuEVrBdonw8U8=
|
||||||
github.com/metacubex/sing-vmess v0.1.9-0.20230921005247-a0488d7dac74 h1:FtupiyFkaVjFvRa7B/uDtRWg5BNsoyPC9MTev3sDasY=
|
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ=
|
||||||
github.com/metacubex/sing-vmess v0.1.9-0.20230921005247-a0488d7dac74/go.mod h1:8EWBZpc+qNvf5gmvjAtMHK1/DpcWqzfcBL842K00BsM=
|
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20231001110902-321836559170 h1:DBGA0hmrP4pVIwLiXUONdphjcppED+plmVaKf1oqkwk=
|
github.com/metacubex/sing-wireguard v0.0.0-20231207123053-1367f0b8f173 h1:q5wu7tynMlhGPsRXgZ2+a16vDo6uOe9cwz483n7MRwM=
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20231001110902-321836559170/go.mod h1:/VbJfbdLnANE+SKXyMk/96sTRrD4GdFLh5mkegqqFcY=
|
github.com/metacubex/sing-wireguard v0.0.0-20231207123053-1367f0b8f173/go.mod h1:swI5NYmpSOavsMyKnxSLikD9CvnCUcpjzwLdaWPNS9g=
|
||||||
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
||||||
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
|
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
|
||||||
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
|
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
|
||||||
|
@ -158,8 +158,8 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c
|
||||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||||
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07 h1:ncKb5tVOsCQgCsv6UpsA0jinbNb5OQ5GMPJlyQP3EHM=
|
github.com/sagernet/sing-mux v0.1.6-0.20231207143704-9f6c20fb5266 h1:QqwwUyEfmOuoGVTZ2cYvUJEeSWlzunvQLRmv+9B41uk=
|
||||||
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07/go.mod h1:u/MZf32xPG8jEKe3t+xUV67EBnKtDtCaPhsJQOQGUYU=
|
github.com/sagernet/sing-mux v0.1.6-0.20231207143704-9f6c20fb5266/go.mod h1:uxpcXa8JqSR+ufC1sGAPsCs027wpE7v1ltnhuJKqyBQ=
|
||||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||||
|
@ -221,8 +221,8 @@ go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||||
|
@ -235,8 +235,8 @@ golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
@ -256,14 +256,13 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
|
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
|
||||||
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
|
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
|
||||||
|
|
|
@ -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 {
|
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() }()
|
defer func() { _ = conn.Close() }()
|
||||||
mutex := sync.Mutex{}
|
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() {
|
defer func() {
|
||||||
mutex.Lock() // this goroutine must exit after all conn.WritePacket() is not running
|
mutex.Lock() // this goroutine must exit after all conn.WritePacket() is not running
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
conn2 = nil
|
conn2 = nil
|
||||||
}()
|
}()
|
||||||
var buff *buf.Buffer
|
rwOptions := network.ReadWaitOptions{}
|
||||||
newBuffer := func() *buf.Buffer {
|
|
||||||
buff = buf.NewPacket() // do not use stack buffer
|
|
||||||
return buff
|
|
||||||
}
|
|
||||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
readWaiter.InitializeReadWaiter(newBuffer)
|
readWaiter.InitializeReadWaiter(rwOptions)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
|
buff *buf.Buffer
|
||||||
dest M.Socksaddr
|
dest M.Socksaddr
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
buff = nil // clear last loop status, avoid repeat release
|
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
dest, err = readWaiter.WaitReadPacket()
|
buff, dest, err = readWaiter.WaitReadPacket()
|
||||||
} else {
|
} else {
|
||||||
dest, err = conn.ReadPacket(newBuffer())
|
buff = rwOptions.NewPacketBuffer()
|
||||||
|
dest, err = conn.ReadPacket(buff)
|
||||||
|
if buff != nil {
|
||||||
|
rwOptions.PostReturn(buff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if buff != nil {
|
|
||||||
buff.Release()
|
buff.Release()
|
||||||
}
|
|
||||||
if ShouldIgnorePacketError(err) {
|
if ShouldIgnorePacketError(err) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -212,7 +207,7 @@ func ShouldIgnorePacketError(err error) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type packet struct {
|
type packet struct {
|
||||||
conn *network.PacketConn
|
conn *network.NetPacketConn
|
||||||
mutex *sync.Mutex
|
mutex *sync.Mutex
|
||||||
rAddr net.Addr
|
rAddr net.Addr
|
||||||
lAddr net.Addr
|
lAddr net.Addr
|
||||||
|
@ -238,18 +233,7 @@ func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buff := buf.NewPacket()
|
return conn.WriteTo(b, addr)
|
||||||
defer buff.Release()
|
|
||||||
n, err = buff.Write(b)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = conn.WritePacket(buff, M.SocksaddrFromNet(addr))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalAddr returns the source IP/Port of UDP Packet
|
// 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/buf"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
|
"github.com/sagernet/sing/common/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Listener struct {
|
type Listener struct {
|
||||||
|
@ -96,30 +97,33 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
conn := bufio.NewPacketConn(ul)
|
conn := bufio.NewPacketConn(ul)
|
||||||
var buff *buf.Buffer
|
rwOptions := network.ReadWaitOptions{
|
||||||
newBuffer := func() *buf.Buffer {
|
FrontHeadroom: network.CalculateFrontHeadroom(sl.service),
|
||||||
buff = buf.NewPacket() // do not use stack buffer
|
RearHeadroom: network.CalculateRearHeadroom(sl.service),
|
||||||
return buff
|
MTU: network.CalculateMTU(conn, sl.service),
|
||||||
}
|
}
|
||||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
readWaiter.InitializeReadWaiter(newBuffer)
|
readWaiter.InitializeReadWaiter(rwOptions)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
|
buff *buf.Buffer
|
||||||
dest M.Socksaddr
|
dest M.Socksaddr
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
buff = nil // clear last loop status, avoid repeat release
|
buff = nil // clear last loop status, avoid repeat release
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
dest, err = readWaiter.WaitReadPacket()
|
buff, dest, err = readWaiter.WaitReadPacket()
|
||||||
} else {
|
} else {
|
||||||
dest, err = conn.ReadPacket(newBuffer())
|
buff = rwOptions.NewPacketBuffer()
|
||||||
|
dest, err = conn.ReadPacket(buff)
|
||||||
|
if buff != nil {
|
||||||
|
rwOptions.PostReturn(buff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if buff != nil {
|
|
||||||
buff.Release()
|
buff.Release()
|
||||||
}
|
|
||||||
if sl.closed {
|
if sl.closed {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,29 +109,29 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
conn2 = nil
|
conn2 = nil
|
||||||
}()
|
}()
|
||||||
|
rwOptions := network.ReadWaitOptions{
|
||||||
var buff *buf.Buffer
|
MTU: 2 * 1024, // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough
|
||||||
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
|
|
||||||
}
|
}
|
||||||
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn)
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
readWaiter.InitializeReadWaiter(newBuffer)
|
readWaiter.InitializeReadWaiter(rwOptions)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
|
buff *buf.Buffer
|
||||||
dest M.Socksaddr
|
dest M.Socksaddr
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
_ = conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout))
|
_ = conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout))
|
||||||
buff = nil // clear last loop status, avoid repeat release
|
buff = nil // clear last loop status, avoid repeat release
|
||||||
if isReadWaiter {
|
if isReadWaiter {
|
||||||
dest, err = readWaiter.WaitReadPacket()
|
buff, dest, err = readWaiter.WaitReadPacket()
|
||||||
} else {
|
} else {
|
||||||
dest, err = conn.ReadPacket(newBuffer())
|
buff = rwOptions.NewPacketBuffer()
|
||||||
|
dest, err = conn.ReadPacket(buff)
|
||||||
|
if buff != nil {
|
||||||
|
rwOptions.PostReturn(buff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if buff != nil {
|
if buff != nil {
|
||||||
|
@ -142,7 +142,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func(buff *buf.Buffer) {
|
go func() {
|
||||||
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
ctx, cancel := context.WithTimeout(ctx, DefaultDnsRelayTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inData := buff.Bytes()
|
inData := buff.Bytes()
|
||||||
|
@ -167,7 +167,7 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}(buff) // catch buff at goroutine create, avoid next loop change buff
|
}()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,14 +157,7 @@ func (vc *Conn) ReadBuffer(buffer *buf.Buffer) error {
|
||||||
|
|
||||||
func (vc *Conn) Write(p []byte) (int, error) {
|
func (vc *Conn) Write(p []byte) (int, error) {
|
||||||
if vc.writeFilterApplicationData {
|
if vc.writeFilterApplicationData {
|
||||||
buffer := buf.New()
|
return N.WriteBuffer(vc, buf.As(p))
|
||||||
defer buffer.Release()
|
|
||||||
buffer.Write(p)
|
|
||||||
err := vc.WriteBuffer(buffer)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return len(p), nil
|
|
||||||
}
|
}
|
||||||
return vc.ExtendedWriter.Write(p)
|
return vc.ExtendedWriter.Write(p)
|
||||||
}
|
}
|
||||||
|
@ -266,6 +259,10 @@ func (vc *Conn) FrontHeadroom() int {
|
||||||
return PaddingHeaderLen - uuid.Size
|
return PaddingHeaderLen - uuid.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vc *Conn) RearHeadroom() int {
|
||||||
|
return 500 + 900
|
||||||
|
}
|
||||||
|
|
||||||
func (vc *Conn) NeedHandshake() bool {
|
func (vc *Conn) NeedHandshake() bool {
|
||||||
return vc.needHandshake
|
return vc.needHandshake
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,7 +375,6 @@ func handleUDPConn(packet C.PacketAdapter) {
|
||||||
cond.Broadcast()
|
cond.Broadcast()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pCtx := icontext.NewPacketConnContext(metadata)
|
|
||||||
proxy, rule, err := resolveMetadata(metadata)
|
proxy, rule, err := resolveMetadata(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnln("[UDP] Parse metadata failed: %s", err.Error())
|
log.Warnln("[UDP] Parse metadata failed: %s", err.Error())
|
||||||
|
@ -402,7 +401,6 @@ func handleUDPConn(packet C.PacketAdapter) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pCtx.InjectPacketConn(rawPc)
|
|
||||||
|
|
||||||
pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule, 0, 0, true)
|
pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule, 0, 0, true)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue