Add read deadline for udpnat conn

This commit is contained in:
世界 2022-06-28 21:07:12 +08:00
parent 1805ecdd1a
commit aa7007a947
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 31 additions and 12 deletions

View file

@ -5,6 +5,7 @@ import (
"io" "io"
"net" "net"
"os" "os"
"sync/atomic"
"time" "time"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
@ -113,25 +114,40 @@ type packet struct {
} }
type conn struct { type conn struct {
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
data chan packet data chan packet
localAddr M.Socksaddr localAddr M.Socksaddr
remoteAddr M.Socksaddr remoteAddr M.Socksaddr
source N.PacketWriter source N.PacketWriter
fastClose bool fastClose bool
readDeadline atomic.Value
} }
func (c *conn) ReadPacketThreadSafe() (buffer *buf.Buffer, addr M.Socksaddr, err error) { func (c *conn) ReadPacketThreadSafe() (buffer *buf.Buffer, addr M.Socksaddr, err error) {
var deadline <-chan time.Time
if d, ok := c.readDeadline.Load().(time.Time); ok && !d.IsZero() {
timer := time.NewTimer(time.Until(d))
defer timer.Stop()
deadline = timer.C
}
select { select {
case p := <-c.data: case p := <-c.data:
return p.data, p.destination, nil return p.data, p.destination, nil
case <-c.ctx.Done(): case <-c.ctx.Done():
return nil, M.Socksaddr{}, c.ctx.Err() return nil, M.Socksaddr{}, io.ErrClosedPipe
case <-deadline:
return nil, M.Socksaddr{}, os.ErrDeadlineExceeded
} }
} }
func (c *conn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) { func (c *conn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) {
var deadline <-chan time.Time
if d, ok := c.readDeadline.Load().(time.Time); ok && !d.IsZero() {
timer := time.NewTimer(time.Until(d))
defer timer.Stop()
deadline = timer.C
}
select { select {
case p := <-c.data: case p := <-c.data:
_, err = buffer.ReadFrom(p.data) _, err = buffer.ReadFrom(p.data)
@ -139,6 +155,8 @@ func (c *conn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) {
return p.destination, err return p.destination, err
case <-c.ctx.Done(): case <-c.ctx.Done():
return M.Socksaddr{}, io.ErrClosedPipe return M.Socksaddr{}, io.ErrClosedPipe
case <-deadline:
return M.Socksaddr{}, os.ErrDeadlineExceeded
} }
} }
@ -191,7 +209,8 @@ func (c *conn) SetDeadline(t time.Time) error {
} }
func (c *conn) SetReadDeadline(t time.Time) error { func (c *conn) SetReadDeadline(t time.Time) error {
return os.ErrInvalid c.readDeadline.Store(t)
return nil
} }
func (c *conn) SetWriteDeadline(t time.Time) error { func (c *conn) SetWriteDeadline(t time.Time) error {

2
go.mod
View file

@ -2,4 +2,4 @@ module github.com/sagernet/sing
go 1.18 go 1.18
require golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c require golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b

4
go.sum
View file

@ -1,2 +1,2 @@
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=