From d0b467671a454ea420f7ccf8ecf60d7eb4056d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 21 Sep 2022 22:11:11 +0800 Subject: [PATCH] Merge VLESS to library --- go.mod | 4 +- go.sum | 8 +- outbound/vless.go | 10 +-- transport/vless/client.go | 146 ------------------------------------ transport/vless/protocol.go | 98 ------------------------ 5 files changed, 11 insertions(+), 255 deletions(-) delete mode 100644 transport/vless/client.go delete mode 100644 transport/vless/protocol.go diff --git a/go.mod b/go.mod index 0db1d8b9..10300c28 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617 - github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d + github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e github.com/spf13/cobra v1.5.0 @@ -35,7 +35,7 @@ require ( go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.10.0 go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d - golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 + golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 golang.org/x/net v0.0.0-20220909164309-bea034e7d591 golang.org/x/sys v0.0.0-20220913120320-3275c407cedc golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b diff --git a/go.sum b/go.sum index 5d1baba8..7cda2b8d 100644 --- a/go.sum +++ b/go.sum @@ -153,8 +153,8 @@ github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDe github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617 h1:fNTNmylhB/UjoBLusmrFu2B1fat4OCkDkQXTgrE7ZsE= github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM= -github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d h1:/GNWxSrQj4chFYk2jahIXNPdvUa9DW8IdgyqYFbq9oQ= -github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0= +github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f h1:xyJ3Wbibcug4DxLi/FCHX2Td667SfieyZv645b8+eEE= +github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs= @@ -196,8 +196,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY= +golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= diff --git a/outbound/vless.go b/outbound/vless.go index 70f6a23b..45df44d0 100644 --- a/outbound/vless.go +++ b/outbound/vless.go @@ -11,9 +11,9 @@ import ( "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/transport/v2ray" - "github.com/sagernet/sing-box/transport/vless" "github.com/sagernet/sing-dns" "github.com/sagernet/sing-vmess/packetaddr" + "github.com/sagernet/sing-vmess/vless" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" @@ -105,7 +105,7 @@ func (h *VLESS) DialContext(ctx context.Context, network string, destination M.S return h.client.DialEarlyConn(conn, destination), nil case N.NetworkUDP: h.logger.InfoContext(ctx, "outbound packet connection to ", destination) - return h.client.DialPacketConn(conn, destination), nil + return h.client.DialEarlyPacketConn(conn, destination), nil default: return nil, E.Extend(N.ErrUnknownNetwork, network) } @@ -130,11 +130,11 @@ func (h *VLESS) ListenPacket(ctx context.Context, destination M.Socksaddr) (net. return nil, err } if h.xudp { - return h.client.DialXUDPPacketConn(conn, destination), nil + return h.client.DialEarlyXUDPPacketConn(conn, destination), nil } else if h.packetAddr { - return dialer.NewResolvePacketConn(ctx, h.router, dns.DomainStrategyAsIS, packetaddr.NewConn(h.client.DialPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress}), destination)), nil + return dialer.NewResolvePacketConn(ctx, h.router, dns.DomainStrategyAsIS, packetaddr.NewConn(h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress}), destination)), nil } else { - return h.client.DialPacketConn(conn, destination), nil + return h.client.DialEarlyPacketConn(conn, destination), nil } } diff --git a/transport/vless/client.go b/transport/vless/client.go deleted file mode 100644 index a03c0a46..00000000 --- a/transport/vless/client.go +++ /dev/null @@ -1,146 +0,0 @@ -package vless - -import ( - "encoding/binary" - "io" - "net" - - "github.com/sagernet/sing-vmess" - "github.com/sagernet/sing/common" - "github.com/sagernet/sing/common/buf" - M "github.com/sagernet/sing/common/metadata" - - "github.com/gofrs/uuid" -) - -type Client struct { - key []byte -} - -func NewClient(userId string) (*Client, error) { - user := uuid.FromStringOrNil(userId) - if user == uuid.Nil { - user = uuid.NewV5(user, userId) - } - return &Client{key: user.Bytes()}, nil -} - -func (c *Client) DialEarlyConn(conn net.Conn, destination M.Socksaddr) *Conn { - return &Conn{Conn: conn, key: c.key, command: vmess.CommandTCP, destination: destination} -} - -func (c *Client) DialPacketConn(conn net.Conn, destination M.Socksaddr) *PacketConn { - return &PacketConn{Conn: conn, key: c.key, destination: destination} -} - -func (c *Client) DialXUDPPacketConn(conn net.Conn, destination M.Socksaddr) vmess.PacketConn { - return vmess.NewXUDPConn(&Conn{Conn: conn, key: c.key, command: vmess.CommandMux, destination: destination}, destination) -} - -type Conn struct { - net.Conn - key []byte - command byte - destination M.Socksaddr - requestWritten bool - responseRead bool -} - -func (c *Conn) Read(b []byte) (n int, err error) { - if !c.responseRead { - err = ReadResponse(c.Conn) - if err != nil { - return - } - c.responseRead = true - } - return c.Conn.Read(b) -} - -func (c *Conn) Write(b []byte) (n int, err error) { - if !c.requestWritten { - err = WriteRequest(c.Conn, Request{c.key, c.command, c.destination}, b) - if err == nil { - n = len(b) - } - c.requestWritten = true - return - } - return c.Conn.Write(b) -} - -func (c *Conn) Upstream() any { - return c.Conn -} - -type PacketConn struct { - net.Conn - key []byte - destination M.Socksaddr - requestWritten bool - responseRead bool -} - -func (c *PacketConn) Read(b []byte) (n int, err error) { - if !c.responseRead { - err = ReadResponse(c.Conn) - if err != nil { - return - } - c.responseRead = true - } - var length uint16 - err = binary.Read(c.Conn, binary.BigEndian, &length) - if err != nil { - return - } - if cap(b) < int(length) { - return 0, io.ErrShortBuffer - } - return io.ReadFull(c.Conn, b[:length]) -} - -func (c *PacketConn) Write(b []byte) (n int, err error) { - if !c.requestWritten { - err = WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination}, b) - if err == nil { - n = len(b) - } - c.requestWritten = true - return - } - err = binary.Write(c.Conn, binary.BigEndian, uint16(len(b))) - if err != nil { - return - } - return c.Conn.Write(b) -} - -func (c *PacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { - defer buffer.Release() - dataLen := buffer.Len() - binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(dataLen)) - if !c.requestWritten { - err := WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination}, buffer.Bytes()) - c.requestWritten = true - return err - } - return common.Error(c.Conn.Write(buffer.Bytes())) -} - -func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - n, err = c.Read(p) - return -} - -func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { - return c.Write(p) -} - -func (c *PacketConn) FrontHeadroom() int { - return 2 -} - -func (c *PacketConn) Upstream() any { - return c.Conn -} diff --git a/transport/vless/protocol.go b/transport/vless/protocol.go deleted file mode 100644 index 7913e989..00000000 --- a/transport/vless/protocol.go +++ /dev/null @@ -1,98 +0,0 @@ -package vless - -import ( - "encoding/binary" - "io" - - "github.com/sagernet/sing-vmess" - "github.com/sagernet/sing/common" - "github.com/sagernet/sing/common/buf" - E "github.com/sagernet/sing/common/exceptions" - M "github.com/sagernet/sing/common/metadata" - "github.com/sagernet/sing/common/rw" -) - -const Version = 0 - -type Request struct { - UUID []byte - Command byte - Destination M.Socksaddr -} - -func WriteRequest(writer io.Writer, request Request, payload []byte) error { - var requestLen int - requestLen += 1 // version - requestLen += 16 // uuid - requestLen += 1 // protobuf length - requestLen += 1 // command - if request.Command != vmess.CommandMux { - requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination) - } - requestLen += len(payload) - _buffer := buf.StackNewSize(requestLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - defer buffer.Release() - common.Must( - buffer.WriteByte(Version), - common.Error(buffer.Write(request.UUID)), - buffer.WriteByte(0), - buffer.WriteByte(request.Command), - ) - - if request.Command != vmess.CommandMux { - common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)) - } - - common.Must1(buffer.Write(payload)) - return common.Error(writer.Write(buffer.Bytes())) -} - -func WritePacketRequest(writer io.Writer, request Request, payload []byte) error { - var requestLen int - requestLen += 1 // version - requestLen += 16 // uuid - requestLen += 1 // protobuf length - requestLen += 1 // command - requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination) - if len(payload) > 0 { - requestLen += 2 - requestLen += len(payload) - } - _buffer := buf.StackNewSize(requestLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - defer buffer.Release() - common.Must( - buffer.WriteByte(Version), - common.Error(buffer.Write(request.UUID)), - buffer.WriteByte(0), - buffer.WriteByte(vmess.CommandUDP), - vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination), - binary.Write(buffer, binary.BigEndian, uint16(len(payload))), - common.Error(buffer.Write(payload)), - ) - return common.Error(writer.Write(buffer.Bytes())) -} - -func ReadResponse(reader io.Reader) error { - version, err := rw.ReadByte(reader) - if err != nil { - return err - } - if version != Version { - return E.New("unknown version: ", version) - } - protobufLength, err := rw.ReadByte(reader) - if err != nil { - return err - } - if protobufLength > 0 { - err = rw.SkipN(reader, int(protobufLength)) - if err != nil { - return err - } - } - return nil -}