diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index 0d6cdb8c..04eec966 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -5,6 +5,7 @@ import ( "encoding/json" "net" "strings" + "syscall" N "github.com/Dreamacro/clash/common/net" "github.com/Dreamacro/clash/common/utils" @@ -204,7 +205,10 @@ func (c *conn) Upstream() any { } func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { - return &conn{N.NewDeadlineConn(c), []string{a.Name()}, parseRemoteDestination(a.Addr())} + if _, ok := c.(syscall.Conn); !ok { // exclusion system conn like *net.TCPConn + c = N.NewDeadlineConn(c) // most conn from outbound can't handle readDeadline correctly + } + return &conn{N.NewExtendedConn(c), []string{a.Name()}, parseRemoteDestination(a.Addr())} } type packetConn struct { @@ -235,7 +239,10 @@ func (c *packetConn) LocalAddr() net.Addr { } func newPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn { - return &packetConn{N.NewDeadlinePacketConn(pc), []string{a.Name()}, a.Name(), utils.NewUUIDV4().String(), parseRemoteDestination(a.Addr())} + if _, ok := pc.(syscall.Conn); !ok { // exclusion system conn like *net.UDPConn + pc = N.NewDeadlinePacketConn(pc) // most conn from outbound can't handle readDeadline correctly + } + return &packetConn{pc, []string{a.Name()}, a.Name(), utils.NewUUIDV4().String(), parseRemoteDestination(a.Addr())} } func parseRemoteDestination(addr string) string { diff --git a/common/net/sing.go b/common/net/sing.go index 4aad5523..89517326 100644 --- a/common/net/sing.go +++ b/common/net/sing.go @@ -19,17 +19,11 @@ type ExtendedWriter = network.ExtendedWriter type ExtendedReader = network.ExtendedReader func NewDeadlineConn(conn net.Conn) ExtendedConn { - if dc, ok := conn.(*deadline.Conn); ok { - return dc - } - return deadline.NewConn(conn) + return deadline.NewFallbackConn(conn) } func NewDeadlinePacketConn(pc net.PacketConn) net.PacketConn { - if dpc, ok := pc.(*deadline.PacketConn); ok { - return dpc - } - return deadline.NewPacketConn(bufio.NewPacketConn(pc)) + return deadline.NewFallbackPacketConn(bufio.NewPacketConn(pc)) } func NeedHandshake(conn any) bool { diff --git a/component/dialer/tfo.go b/component/dialer/tfo.go index 0041a976..d5337bdb 100644 --- a/component/dialer/tfo.go +++ b/component/dialer/tfo.go @@ -105,6 +105,10 @@ func (c *tfoConn) Upstream() any { return c.Conn } +func (c *tfoConn) NeedAdditionalReadDeadline() bool { + return c.Conn == nil +} + func (c *tfoConn) NeedHandshake() bool { return c.Conn == nil } diff --git a/go.mod b/go.mod index 971d4291..eb2957a7 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/mdlayher/netlink v1.7.2-0.20221213171556-9881fafed8c7 github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594 - github.com/metacubex/sing-shadowsocks v0.2.2-0.20230414151724-274b69df9875 + github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc github.com/metacubex/sing-tun v0.1.3 github.com/metacubex/sing-wireguard v0.0.0-20230413082948-e51777dcf025 github.com/miekg/dns v1.1.52 @@ -28,9 +28,9 @@ require ( github.com/openacid/low v0.1.21 github.com/oschwald/geoip2-golang v1.8.0 github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 - github.com/sagernet/sing v0.2.3 - github.com/sagernet/sing-shadowtls v0.1.1 - github.com/sagernet/sing-vmess v0.1.4 + github.com/sagernet/sing v0.2.4-0.20230417103520-0b4d134fe945 + github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b + github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c diff --git a/go.sum b/go.sum index c45880a9..45cdfeff 100644 --- a/go.sum +++ b/go.sum @@ -96,8 +96,8 @@ github.com/metacubex/gvisor v0.0.0-20230323114922-412956fb6a03 h1:gREIdurac9fpyB github.com/metacubex/gvisor v0.0.0-20230323114922-412956fb6a03/go.mod h1:wqEuzdImyqD2MCGE8CYRJXbB77oSEJeoSSXXdwKjnsE= github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594 h1:KD96JPdTIayTGGgRl6PuVqo2Bpo6+x3LqDDyqrYDDXw= github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594/go.mod h1:9nOiGX6kqV3+ZbkDKdTNzdFD726QQHPH6WDb36jUSpA= -github.com/metacubex/sing-shadowsocks v0.2.2-0.20230414151724-274b69df9875 h1:TrTg8JY//QOu4JZuXjKzB35Gppz4B4Us9EIvtdno6vo= -github.com/metacubex/sing-shadowsocks v0.2.2-0.20230414151724-274b69df9875/go.mod h1:0ebzwmiUVa4wAmjhzaEx5BgeuhJFT5QYO0oxwolKlYE= +github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc h1:ctwahnHNAgoicCUJqKrHNVcyjEeNIoK4Dqyjh5uIkEE= +github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc/go.mod h1:4uQQReKMTU7KTfOykVBe/oGJ00pl38d+BYJ99+mx26s= github.com/metacubex/sing-tun v0.1.3 h1:LCz8TlAZUWwnBYZxs1PEE04PyfLA9xdsye6CjHZlZGQ= github.com/metacubex/sing-tun v0.1.3/go.mod h1:kHkYHoRlYA4I12QPTt/ADyRGqy5YweLUfye1E1hC/q4= github.com/metacubex/sing-wireguard v0.0.0-20230413082948-e51777dcf025 h1:itjCqEeem+BKZFiBEhQmWHDHKK4FgTGvnYCFS0JOb3A= @@ -144,12 +144,12 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h 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/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= -github.com/sagernet/sing v0.2.3 h1:V50MvZ4c3Iij2lYFWPlzL1PyipwSzjGeN9x+Ox89vpk= -github.com/sagernet/sing v0.2.3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= -github.com/sagernet/sing-shadowtls v0.1.1 h1:Gf8YD/4zCjfM9xxVzI0QVYAnjMCtsDHcIp84CUdY3VA= -github.com/sagernet/sing-shadowtls v0.1.1/go.mod h1:espnHDPRQeG95ZoU3xfHDFnc6Nt4GvbbuPV2okN+x/E= -github.com/sagernet/sing-vmess v0.1.4 h1:aZ03KgmR9COPitVqo8NTPHeaHmbJYDZ8mkumnUV4oGQ= -github.com/sagernet/sing-vmess v0.1.4/go.mod h1:NensKZJDgfPsUf3TzFD8kTuzI3CQfN1Tj3Eygti5Isg= +github.com/sagernet/sing v0.2.4-0.20230417103520-0b4d134fe945 h1:mh7/K6IU1ZJ2CKRyfnyq3G/zKQVoBSVw8oWtaR1Hj6M= +github.com/sagernet/sing v0.2.4-0.20230417103520-0b4d134fe945/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b h1:ouW/6IDCrxkBe19YSbdCd7buHix7b+UZ6BM4Zz74XF4= +github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= +github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= +github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9/go.mod h1:FUyTEc5ye5NjKnDTDMuiLF2M6T4BE6y6KZuax//UCEg= github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 h1:kDUqhc9Vsk5HJuhfIATJ8oQwBmpOZJuozQG7Vk88lL4= diff --git a/listener/shadowsocks/tcp.go b/listener/shadowsocks/tcp.go index 4e25a7b9..6884b960 100644 --- a/listener/shadowsocks/tcp.go +++ b/listener/shadowsocks/tcp.go @@ -100,7 +100,8 @@ func (l *Listener) AddrList() (addrList []net.Addr) { } func (l *Listener) HandleConn(conn net.Conn, in chan<- C.ConnContext, additions ...inbound.Addition) { - conn = N.NewDeadlineConn(l.pickCipher.StreamConn(conn)) + conn = l.pickCipher.StreamConn(conn) + conn = N.NewDeadlineConn(conn) // embed ss can't handle readDeadline correctly target, err := socks5.ReadAddr(conn, make([]byte, socks5.MaxAddrLen)) if err != nil { diff --git a/listener/shadowsocks/udp.go b/listener/shadowsocks/udp.go index d884c2b8..3f058406 100644 --- a/listener/shadowsocks/udp.go +++ b/listener/shadowsocks/udp.go @@ -4,7 +4,6 @@ import ( "net" "github.com/Dreamacro/clash/adapter/inbound" - N "github.com/Dreamacro/clash/common/net" "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/common/sockopt" C "github.com/Dreamacro/clash/constant" @@ -30,7 +29,7 @@ func NewUDP(addr string, pickCipher core.Cipher, in chan<- C.PacketAdapter) (*UD } sl := &UDPListener{l, false} - conn := N.NewDeadlinePacketConn(pickCipher.PacketConn(l)) + conn := pickCipher.PacketConn(l) go func() { for { buf := pool.Get(pool.RelayBufferSize) diff --git a/listener/sing/sing.go b/listener/sing/sing.go index 7421a4f1..2941f6ca 100644 --- a/listener/sing/sing.go +++ b/listener/sing/sing.go @@ -17,6 +17,7 @@ import ( vmess "github.com/sagernet/sing-vmess" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio/deadline" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" "github.com/sagernet/sing/common/network" @@ -80,6 +81,9 @@ func (h *ListenerHandler) NewConnection(ctx context.Context, conn net.Conn, meta defer wg.Wait() // this goroutine must exit after conn.Close() wg.Add(1) + if deadline.NeedAdditionalReadDeadline(conn) { + conn = N.NewDeadlineConn(conn) // conn from sing should check NeedAdditionalReadDeadline + } h.TcpIn <- inbound.NewSocket(target, &waitCloseConn{ExtendedConn: N.NewExtendedConn(conn), wg: wg, rAddr: metadata.Source.TCPAddr()}, h.Type, additions...) return nil }