Merge VLESS to library

This commit is contained in:
世界 2022-09-21 22:11:11 +08:00
parent c18c545798
commit d0b467671a
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
5 changed files with 11 additions and 255 deletions

4
go.mod
View file

@ -27,7 +27,7 @@ require (
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617 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/smux v0.0.0-20220831015742-e0f1988e3195
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
github.com/spf13/cobra v1.5.0 github.com/spf13/cobra v1.5.0
@ -35,7 +35,7 @@ require (
go.etcd.io/bbolt v1.3.6 go.etcd.io/bbolt v1.3.6
go.uber.org/atomic v1.10.0 go.uber.org/atomic v1.10.0
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d 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/net v0.0.0-20220909164309-bea034e7d591
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc golang.org/x/sys v0.0.0-20220913120320-3275c407cedc
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b

8
go.sum
View file

@ -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-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 h1:fNTNmylhB/UjoBLusmrFu2B1fat4OCkDkQXTgrE7ZsE=
github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM= 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-20220921140858-b6a1bdee672f h1:xyJ3Wbibcug4DxLi/FCHX2Td667SfieyZv645b8+eEE=
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/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 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= 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= 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-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-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-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-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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-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 h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=

View file

@ -11,9 +11,9 @@ import (
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/transport/v2ray" "github.com/sagernet/sing-box/transport/v2ray"
"github.com/sagernet/sing-box/transport/vless"
"github.com/sagernet/sing-dns" "github.com/sagernet/sing-dns"
"github.com/sagernet/sing-vmess/packetaddr" "github.com/sagernet/sing-vmess/packetaddr"
"github.com/sagernet/sing-vmess/vless"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" 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 return h.client.DialEarlyConn(conn, destination), nil
case N.NetworkUDP: case N.NetworkUDP:
h.logger.InfoContext(ctx, "outbound packet connection to ", destination) h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
return h.client.DialPacketConn(conn, destination), nil return h.client.DialEarlyPacketConn(conn, destination), nil
default: default:
return nil, E.Extend(N.ErrUnknownNetwork, network) 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 return nil, err
} }
if h.xudp { if h.xudp {
return h.client.DialXUDPPacketConn(conn, destination), nil return h.client.DialEarlyXUDPPacketConn(conn, destination), nil
} else if h.packetAddr { } 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 { } else {
return h.client.DialPacketConn(conn, destination), nil return h.client.DialEarlyPacketConn(conn, destination), nil
} }
} }

View file

@ -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
}

View file

@ -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
}