diff --git a/adapter/outbound/base.go b/adapter/outbound/base.go index 03e9e6ca..e0efe595 100644 --- a/adapter/outbound/base.go +++ b/adapter/outbound/base.go @@ -7,12 +7,11 @@ import ( "net" "strings" + N "github.com/Dreamacro/clash/common/net" "github.com/Dreamacro/clash/component/dialer" C "github.com/Dreamacro/clash/constant" "github.com/gofrs/uuid" - "github.com/sagernet/sing/common/bufio" - "github.com/sagernet/sing/common/network" ) type Base struct { @@ -169,7 +168,7 @@ func NewBase(opt BaseOption) *Base { } type conn struct { - network.ExtendedConn + N.ExtendedConn chain C.Chain actualRemoteDestination string } @@ -189,14 +188,14 @@ func (c *conn) AppendToChains(a C.ProxyAdapter) { } func (c *conn) Upstream() any { - if wrapper, ok := c.ExtendedConn.(*bufio.ExtendedConnWrapper); ok { + if wrapper, ok := c.ExtendedConn.(*N.ExtendedConnWrapper); ok { return wrapper.Conn } return c.ExtendedConn } func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { - return &conn{bufio.NewExtendedConn(c), []string{a.Name()}, parseRemoteDestination(a.Addr())} + return &conn{N.NewExtendedConn(c), []string{a.Name()}, parseRemoteDestination(a.Addr())} } type packetConn struct { diff --git a/adapter/outbound/trojan.go b/adapter/outbound/trojan.go index a36f5f57..c90ee377 100644 --- a/adapter/outbound/trojan.go +++ b/adapter/outbound/trojan.go @@ -8,14 +8,13 @@ import ( "net/http" "strconv" + N "github.com/Dreamacro/clash/common/net" "github.com/Dreamacro/clash/component/dialer" tlsC "github.com/Dreamacro/clash/component/tls" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/transport/gun" "github.com/Dreamacro/clash/transport/trojan" "github.com/Dreamacro/clash/transport/vless" - - "github.com/sagernet/sing/common/bufio" ) type Trojan struct { @@ -97,7 +96,7 @@ func (t *Trojan) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) return c, err } err = t.instance.WriteHeader(c, trojan.CommandTCP, serializesSocksAddr(metadata)) - return bufio.NewExtendedConn(c), err + return N.NewExtendedConn(c), err } // DialContext implements C.ProxyAdapter diff --git a/common/buf/sing.go b/common/buf/sing.go new file mode 100644 index 00000000..b5e015f5 --- /dev/null +++ b/common/buf/sing.go @@ -0,0 +1,19 @@ +package buf + +import ( + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/buf" +) + +type Buffer = buf.Buffer + +var StackNewSize = buf.StackNewSize +var KeepAlive = common.KeepAlive + +//go:norace +func Dup[T any](obj T) T { + return common.Dup(obj) +} + +var Must = common.Must +var Error = common.Error diff --git a/common/net/bufconn.go b/common/net/bufconn.go index bcac11d3..b3e3d1f3 100644 --- a/common/net/bufconn.go +++ b/common/net/bufconn.go @@ -4,23 +4,21 @@ import ( "bufio" "net" - "github.com/sagernet/sing/common/buf" - sing_bufio "github.com/sagernet/sing/common/bufio" - "github.com/sagernet/sing/common/network" + "github.com/Dreamacro/clash/common/buf" ) -var _ network.ExtendedConn = (*BufferedConn)(nil) +var _ ExtendedConn = (*BufferedConn)(nil) type BufferedConn struct { r *bufio.Reader - network.ExtendedConn + ExtendedConn } func NewBufferedConn(c net.Conn) *BufferedConn { if bc, ok := c.(*BufferedConn); ok { return bc } - return &BufferedConn{bufio.NewReader(c), sing_bufio.NewExtendedConn(c)} + return &BufferedConn{bufio.NewReader(c), NewExtendedConn(c)} } // Reader returns the internal bufio.Reader. @@ -58,7 +56,7 @@ func (c *BufferedConn) ReadBuffer(buffer *buf.Buffer) (err error) { } func (c *BufferedConn) Upstream() any { - if wrapper, ok := c.ExtendedConn.(*sing_bufio.ExtendedConnWrapper); ok { + if wrapper, ok := c.ExtendedConn.(*ExtendedConnWrapper); ok { return wrapper.Conn } return c.ExtendedConn diff --git a/common/net/relay.go b/common/net/relay.go index d4edede2..6191e76b 100644 --- a/common/net/relay.go +++ b/common/net/relay.go @@ -1,24 +1,24 @@ package net -import ( - "io" - "net" - "time" -) - -// Relay copies between left and right bidirectionally. -func Relay(leftConn, rightConn net.Conn) { - ch := make(chan error) - - go func() { - // Wrapping to avoid using *net.TCPConn.(ReadFrom) - // See also https://github.com/Dreamacro/clash/pull/1209 - _, err := io.Copy(WriteOnlyWriter{Writer: leftConn}, ReadOnlyReader{Reader: rightConn}) - leftConn.SetReadDeadline(time.Now()) - ch <- err - }() - - _, _ = io.Copy(WriteOnlyWriter{Writer: rightConn}, ReadOnlyReader{Reader: leftConn}) - rightConn.SetReadDeadline(time.Now()) - <-ch -} +//import ( +// "io" +// "net" +// "time" +//) +// +//// Relay copies between left and right bidirectionally. +//func Relay(leftConn, rightConn net.Conn) { +// ch := make(chan error) +// +// go func() { +// // Wrapping to avoid using *net.TCPConn.(ReadFrom) +// // See also https://github.com/Dreamacro/clash/pull/1209 +// _, err := io.Copy(WriteOnlyWriter{Writer: leftConn}, ReadOnlyReader{Reader: rightConn}) +// leftConn.SetReadDeadline(time.Now()) +// ch <- err +// }() +// +// _, _ = io.Copy(WriteOnlyWriter{Writer: rightConn}, ReadOnlyReader{Reader: leftConn}) +// rightConn.SetReadDeadline(time.Now()) +// <-ch +//} diff --git a/common/net/sing.go b/common/net/sing.go new file mode 100644 index 00000000..37ba3f0c --- /dev/null +++ b/common/net/sing.go @@ -0,0 +1,24 @@ +package net + +import ( + "context" + "net" + + "github.com/sagernet/sing/common/bufio" + "github.com/sagernet/sing/common/network" +) + +type ExtendedConnWrapper = bufio.ExtendedConnWrapper + +var NewExtendedConn = bufio.NewExtendedConn +var NewExtendedWriter = bufio.NewExtendedWriter +var NewExtendedReader = bufio.NewExtendedReader + +type ExtendedConn = network.ExtendedConn +type ExtendedWriter = network.ExtendedWriter +type ExtendedReader = network.ExtendedReader + +// Relay copies between left and right bidirectionally. +func Relay(leftConn, rightConn net.Conn) { + _ = bufio.CopyConn(context.TODO(), leftConn, rightConn) +} diff --git a/transport/vless/conn.go b/transport/vless/conn.go index 72d14d0c..d57f3ae1 100644 --- a/transport/vless/conn.go +++ b/transport/vless/conn.go @@ -7,17 +7,16 @@ import ( "io" "net" + "github.com/Dreamacro/clash/common/buf" + N "github.com/Dreamacro/clash/common/net" + "github.com/gofrs/uuid" - "github.com/sagernet/sing/common" - "github.com/sagernet/sing/common/buf" - "github.com/sagernet/sing/common/bufio" - "github.com/sagernet/sing/common/network" xtls "github.com/xtls/go" "google.golang.org/protobuf/proto" ) type Conn struct { - network.ExtendedConn + N.ExtendedConn dst *DstAddr id *uuid.UUID addons *Addons @@ -67,30 +66,30 @@ func (vc *Conn) sendRequest() (err error) { requestLen += len(vc.dst.Addr) } _buffer := buf.StackNewSize(requestLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + defer buf.KeepAlive(_buffer) + buffer := buf.Dup(_buffer) defer buffer.Release() - common.Must( - buffer.WriteByte(Version), // protocol version - common.Error(buffer.Write(vc.id.Bytes())), // 16 bytes of uuid + buf.Must( + buffer.WriteByte(Version), // protocol version + buf.Error(buffer.Write(vc.id.Bytes())), // 16 bytes of uuid buffer.WriteByte(byte(len(addonsBytes))), - common.Error(buffer.Write(addonsBytes)), + buf.Error(buffer.Write(addonsBytes)), ) if vc.dst.Mux { - common.Must(buffer.WriteByte(CommandMux)) + buf.Must(buffer.WriteByte(CommandMux)) } else { if vc.dst.UDP { - common.Must(buffer.WriteByte(CommandUDP)) + buf.Must(buffer.WriteByte(CommandUDP)) } else { - common.Must(buffer.WriteByte(CommandTCP)) + buf.Must(buffer.WriteByte(CommandTCP)) } binary.BigEndian.PutUint16(buffer.Extend(2), vc.dst.Port) - common.Must( + buf.Must( buffer.WriteByte(vc.dst.AddrType), - common.Error(buffer.Write(vc.dst.Addr)), + buf.Error(buffer.Write(vc.dst.Addr)), ) } @@ -124,7 +123,7 @@ func (vc *Conn) recvResponse() error { } func (vc *Conn) Upstream() any { - if wrapper, ok := vc.ExtendedConn.(*bufio.ExtendedConnWrapper); ok { + if wrapper, ok := vc.ExtendedConn.(*N.ExtendedConnWrapper); ok { return wrapper.Conn } return vc.ExtendedConn @@ -133,7 +132,7 @@ func (vc *Conn) Upstream() any { // newConn return a Conn instance func newConn(conn net.Conn, client *Client, dst *DstAddr) (*Conn, error) { c := &Conn{ - ExtendedConn: bufio.NewExtendedConn(conn), + ExtendedConn: N.NewExtendedConn(conn), id: client.uuid, dst: dst, } diff --git a/transport/vmess/websocket.go b/transport/vmess/websocket.go index 735ea7f2..ce5615d5 100644 --- a/transport/vmess/websocket.go +++ b/transport/vmess/websocket.go @@ -19,10 +19,10 @@ import ( "time" _ "unsafe" + "github.com/Dreamacro/clash/common/buf" + N "github.com/Dreamacro/clash/common/net" + "github.com/gorilla/websocket" - "github.com/sagernet/sing/common/buf" - "github.com/sagernet/sing/common/bufio" - "github.com/sagernet/sing/common/network" ) //go:linkname maskBytes github.com/gorilla/websocket.maskBytes @@ -33,7 +33,7 @@ type websocketConn struct { reader io.Reader remoteAddr net.Addr - rawWriter network.ExtendedWriter + rawWriter N.ExtendedWriter // https://godoc.org/github.com/gorilla/websocket#hdr-Concurrency rMux sync.Mutex @@ -42,7 +42,7 @@ type websocketConn struct { type websocketWithEarlyDataConn struct { net.Conn - wsWriter network.ExtendedWriter + wsWriter N.ExtendedWriter underlay net.Conn closed bool dialed chan bool @@ -209,7 +209,7 @@ func (wsedc *websocketWithEarlyDataConn) Dial(earlyData []byte) error { } wsedc.dialed <- true - wsedc.wsWriter = bufio.NewExtendedWriter(wsedc.Conn) + wsedc.wsWriter = N.NewExtendedWriter(wsedc.Conn) if earlyDataBuf.Len() != 0 { _, err = wsedc.Conn.Write(earlyDataBuf.Bytes()) } @@ -373,7 +373,7 @@ func streamWebsocketConn(conn net.Conn, c *WebsocketConfig, earlyData *bytes.Buf return &websocketConn{ conn: wsConn, - rawWriter: bufio.NewExtendedWriter(wsConn.UnderlyingConn()), + rawWriter: N.NewExtendedWriter(wsConn.UnderlyingConn()), remoteAddr: conn.RemoteAddr(), }, nil } diff --git a/tunnel/connection.go b/tunnel/connection.go index 1747597e..c63bab78 100644 --- a/tunnel/connection.go +++ b/tunnel/connection.go @@ -1,16 +1,14 @@ package tunnel import ( - "context" "errors" "net" "net/netip" "time" + N "github.com/Dreamacro/clash/common/net" "github.com/Dreamacro/clash/common/pool" C "github.com/Dreamacro/clash/constant" - - "github.com/sagernet/sing/common/bufio" ) func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error { @@ -62,5 +60,5 @@ func handleUDPToLocal(packet C.UDPPacket, pc net.PacketConn, key string, oAddr, } func handleSocket(ctx C.ConnContext, outbound net.Conn) { - bufio.CopyConn(context.TODO(), ctx.Conn(), outbound) + N.Relay(ctx.Conn(), outbound) } diff --git a/tunnel/statistic/tracker.go b/tunnel/statistic/tracker.go index 32d44f0c..c034d75d 100644 --- a/tunnel/statistic/tracker.go +++ b/tunnel/statistic/tracker.go @@ -4,12 +4,11 @@ import ( "net" "time" + "github.com/Dreamacro/clash/common/buf" + N "github.com/Dreamacro/clash/common/net" C "github.com/Dreamacro/clash/constant" "github.com/gofrs/uuid" - "github.com/sagernet/sing/common/buf" - "github.com/sagernet/sing/common/bufio" - "github.com/sagernet/sing/common/network" "go.uber.org/atomic" ) @@ -33,8 +32,8 @@ type tcpTracker struct { C.Conn `json:"-"` *trackerInfo manager *Manager - extendedReader network.ExtendedReader - extendedWriter network.ExtendedWriter + extendedReader N.ExtendedReader + extendedWriter N.ExtendedWriter } func (tt *tcpTracker) ID() string { @@ -107,8 +106,8 @@ func NewTCPTracker(conn C.Conn, manager *Manager, metadata *C.Metadata, rule C.R UploadTotal: atomic.NewInt64(0), DownloadTotal: atomic.NewInt64(0), }, - extendedReader: bufio.NewExtendedReader(conn), - extendedWriter: bufio.NewExtendedWriter(conn), + extendedReader: N.NewExtendedReader(conn), + extendedWriter: N.NewExtendedWriter(conn), } if rule != nil {